Add resolve-deny directive to reject DNS-resolved IPs matching CIDR blocklist
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Aptitud para principiantes
- 40/100
- Tipo de issue
- Nueva funcionalidad
- Claridad
- Bastante claro
- Estado de actividad
- Tranquilo
- Stack tecnológico
- c
- Área
- networking
Línea de trabajo
Start in the resolvers section parser where resolve-prefer and dns-accept-family are handled (src/resolvers.c, doc/configuration.txt), following issue #508 as the precedent for a resolver-level option. Then trace how resolved addresses are selected for backend servers, so the deny list can skip a matching IP before a connection is attempted. Done looks like: resolve-deny <cidr> parses under resolvers, rejects matching IPv4 and IPv6 ranges, is documented, and has a reg-test. The issue explicitly asks for design feedback and has had no replies in 94 days, so confirm the approach with maintainers before coding.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Your Feature Request
Add a resolve-deny directive to the resolvers section that rejects DNS-resolved IP addresses matching configured CIDR ranges. When a DNS response contains an IP matching a deny rule, the address is skipped during selection.
Example configuration:
resolvers my_resolvers
parse-resolv-conf
resolve-deny 127.0.0.0/8
resolve-deny ::1/128
resolve-deny 169.254.0.0/16
resolve-deny fe80::/10
resolve-deny 224.0.0.0/4
resolve-deny ff00::/8
resolve-deny 168.63.129.16/32
resolve-deny fd00:ec2::254/128
The existing resolve-prefer and dns-accept-family control address family selection but cannot filter by address value. ACLs operate on client source IPs or request headers, not on resolved backend destination IPs. There is currently no way to prevent HAProxy from connecting to a restricted IP that was returned by DNS.
Related: #508 (dns-accept-family: precedent for resolver-level filtering)
What are you trying to do?
In OpenShift, HAProxy is used as the ingress router. Backend server hostnames can be derived from untrusted user input — users with EndpointSlice write access can inject FQDN-typed endpoints that HAProxy resolves at runtime.
An attacker can create a hostname that resolves to 169.254.169.254 (AWS IMDS), 168.63.129.16 (Azure wireserver), or 127.0.0.1 (loopback). HAProxy resolves the hostname and routes traffic to these restricted addresses, enabling SSRF that can leak cloud credentials and instance metadata.
We considered handling this outside HAProxy, but each alternative has significant drawbacks:
- iptables: Requires elevated privileges in the process, and blocking loopback or link-local globally can interfere with HAProxy's own stats socket, health checks, and agent communication
- Pre-resolving in our config generator: Loses HAProxy's DNS lifecycle: TTL-based re-resolution, async resolution, graceful retry on failure. DNS freshness degrades from TTL-driven (seconds) to our config regeneration cycle (minutes).
- DNS-level filtering (CoreDNS): Can't be scoped to HAProxy traffic only.
A resolver-level deny list feel like the cleanest solution. It preserves HAProxy's existing DNS lifecycle while rejecting restricted addresses at the point of resolution. Curious to hear feedback on this approach.
Output of haproxy -vv
HAProxy version 2.8.18-ae90be6 2025/12/25 - https://haproxy.org/
Status: long-term supported branch - will stop receiving fixes around Q2 2028.
Known bugs: http://www.haproxy.org/bugs/bugs-2.8.18.html
Running on: Linux 6.19.9-200.fc43.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Mar 19 21:34:56 UTC 2026 x86_64
Build options :
TARGET = linux-glibc
CPU = generic
CC = cc
CFLAGS = -O2 -g -Wall -Wextra -Wundef -Wdeclaration-after-statement -Wfatal-errors -Wtype-limits -Wshift-negative-value -Wshift-overflow=2 -Wduplicated-cond -Wnull-dereference -fwrapv -Wno-address-of-packed-member -Wno-unused-label -Wno-sign-compare -Wno-unused-parameter -Wno-clobbered -Wno-missing-field-initializers -Wno-cast-function-type -Wno-string-plus-int -Wno-atomic-alignment
OPTIONS = USE_LINUX_TPROXY=1 USE_CRYPT_H=1 USE_GETADDRINFO=1 USE_OPENSSL=1 USE_ZLIB=1 USE_PCRE=1
DEBUG = -DDEBUG_STRICT -DDEBUG_MEMORY_POOLS
Feature list : -51DEGREES +ACCEPT4 +BACKTRACE -CLOSEFROM +CPU_AFFINITY +CRYPT_H -DEVICEATLAS +DL -ENGINE +EPOLL -EVPORTS +GETADDRINFO -KQUEUE -LIBATOMIC +LIBCRYPT +LINUX_CAP +LINUX_SPLICE +LINUX_TPROXY -LUA -MATH -MEMORY_PROFILING +NETFILTER +NS -OBSOLETE_LINKER +OPENSSL -OPENSSL_WOLFSSL -OT +PCRE -PCRE2 -PCRE2_JIT -PCRE_JIT +POLL +PRCTL -PROCCTL -PROMEX -PTHREAD_EMULATION -QUIC -QUIC_OPENSSL_COMPAT +RT +SHM_OPEN -SLZ +SSL -STATIC_PCRE -STATIC_PCRE2 -SYSTEMD +TFO +THREAD +THREAD_DUMP +TPROXY -WURFL +ZLIB
Default settings :
bufsize = 16384, maxrewrite = 1024, maxpollevents = 200
Built with multi-threading support (MAX_TGROUPS=16, MAX_THREADS=256, default=12).
Built with OpenSSL version : OpenSSL 3.5.5 27 Jan 2026
Running on OpenSSL version : OpenSSL 3.5.4 30 Sep 2025
OpenSSL library supports TLS extensions : yes
OpenSSL library supports SNI : yes
OpenSSL library supports : TLSv1.0 TLSv1.1 TLSv1.2 TLSv1.3
OpenSSL providers loaded : default
Built with network namespace support.
Built with zlib version : 1.2.11
Running on zlib version : 1.3.1.zlib-ng
Compression algorithms supported : identity("identity"), deflate("deflate"), raw-deflate("deflate"), gzip("gzip")
Built with transparent proxy support using: IP_TRANSPARENT IPV6_TRANSPARENT IP_FREEBIND
Built with PCRE version : 8.44 2020-02-12
Running on PCRE version : 8.45 2021-06-15
PCRE library supports JIT : no (USE_PCRE_JIT not set)
Encrypted password support via crypt(3): yes
Built with gcc compiler version 11.5.0 20240719 (Red Hat 11.5.0-14)
Available polling systems :
epoll : pref=300, test result OK
poll : pref=200, test result OK
select : pref=150, test result OK
Total: 3 (3 usable), will use epoll.
Available multiplexer protocols :
(protocols marked as <default> cannot be specified using 'proto' keyword)
h2 : mode=HTTP side=FE|BE mux=H2 flags=HTX|HOL_RISK|NO_UPG
fcgi : mode=HTTP side=BE mux=FCGI flags=HTX|HOL_RISK|NO_UPG
h1 : mode=HTTP side=FE|BE mux=H1 flags=HTX|NO_UPG
<default> : mode=HTTP side=FE|BE mux=H1 flags=HTX
none : mode=TCP side=FE|BE mux=PASS flags=NO_UPG
<default> : mode=TCP side=FE|BE mux=PASS flags=
Available services : none
Available filters :
[BWLIM] bwlim-in
[BWLIM] bwlim-out
[CACHE] cache
[COMP] compression
[FCGI] fcgi-app
[SPOE] spoe
[TRACE] trace
- Lenguaje dominante
- C
- Estrellas
- 6.9k
- Forks
- 976
- Métricas de merge de PR
- Sin PR fusionados en 30 d
Preparar el entorno
Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de haproxy/haproxy
-
type: feature
Dificultad 1/5 Menos de una hora Aptitud para principiantes 77/100
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
-
type: code-report
Dificultad 2/5 1-3 horas Aptitud para principiantes 74/100
-
type: code-report
Dificultad 1/5 Menos de una hora Aptitud para principiantes 82/100
Todos los issues de haproxy/haproxy
Issues similares
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 62/100
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
fluent/fluent-bit#12579 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
obsproject/obs-studio#14036 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
Los mantenedores suelen responder en 1 día
-
Dificultad 1/5 Menos de una hora Aptitud para principiantes 72/100