Add resolve-deny directive to reject DNS-resolved IPs matching CIDR blocklist
还没有人认领这个 Issue。
评估
- 难度
- 4/5
- 预计耗时
- 3-5 天
- 新手友好度
- 40/100
- Issue 类型
- 功能
- 描述清晰度
- 基本清楚
- 活跃度
- 冷清
- 技术栈
- c
- 领域
- networking
调研方向
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.
由索引模型根据 Issue 内容生成。
描述
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
- 主要语言
- C
- 星标
- 6.9k
- 派生
- 976
- PR 合并指标
- 30 天内没有已合并 PR
环境准备
这个项目没有提供开发容器、Dockerfile 或贡献指南,环境需要你自己搭建:先看它的 README,通用步骤见我们的新手贡献指南。
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
haproxy/haproxy 的其他 Issue
-
type: feature
难度 1/5 1 小时以内 新手友好度 77/100
-
难度 2/5 1-3 小时 新手友好度 82/100
-
难度 2/5 1-3 小时 新手友好度 82/100
-
type: code-report
难度 2/5 1-3 小时 新手友好度 74/100
-
type: code-report
难度 1/5 1 小时以内 新手友好度 82/100
相似的 Issue
-
难度 2/5 1-3 小时 新手友好度 70/100
DaveGamble/cJSON#1100 ·
-
area:runtime-vm
难度 2/5 1-3 小时 新手友好度 72/100
InauguralSystems/EigenScript#1748 ·
维护者通常 1 天内回复
-
bug
难度 2/5 1-3 小时 新手友好度 76/100
leanprover/lean4#15677 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 72/100
维护者通常 2 天内回复
-
bug
难度 2/5 1-3 小时 新手友好度 68/100
wasm-micro-runtime/wasm-micro-runtime#5159 ·
维护者通常 7 天内回复