kvz*_*kvz 6 ssl haproxy packet-capture
使用 HAProxy 1.6 和一个聪明的 hack,我现在有一个 HAProxy tcp 模式前端,它检测浏览器是否支持 SNI,并基于此,路由到一个强加密的 SSL 终止后端,或更弱的一个。这确保了 SSL 实验室的 A+ 等级,同时仍然允许除 IE6 之外的所有浏览器使用 SSL。
这是我的配置。它有一些模板变量应该是不言自明的,但不在与我的问题相关的领域:
frontend https_incoming
bind 0.0.0.0:443
mode tcp
option tcplog
tcp-request inspect-delay 5s
tcp-request content accept if { req.ssl_hello_type 1 }
use_backend https_strong if { req.ssl_sni -m end .transloadit.com }
default_backend https_weak
backend https_strong
mode tcp
option tcplog
server https_strong 127.0.0.1:1665
frontend https_strong
bind 127.0.0.1:1665 ssl crt ${DM_ROOT_DIR}/envs/ssl/haproxy-dh2048.pem no-sslv3 no-tls-tickets ciphers ${strongCiphers}
mode http
option httplog
option httpclose
option forwardfor if-none except 127.0.0.1
http-response add-header Strict-Transport-Security max-age=31536000
reqadd X-Forwarded-Proto:\ https
reqadd FRONT_END_HTTPS:\ on
use_backend http_incoming
backend https_weak
mode tcp
option tcplog
server https_weak 127.0.0.1:1667
frontend https_weak
bind 127.0.0.1:1667 ssl crt ${DM_ROOT_DIR}/envs/ssl/haproxy.pem no-sslv3 ciphers ${weakCiphers}
mode http
option httplog
option httpclose
option forwardfor if-none except 127.0.0.1
http-response add-header Strict-Transport-Security max-age=31536000
reqadd X-Forwarded-Proto:\ https
reqadd FRONT_END_HTTPS:\ on
use_backend http_incoming
Run Code Online (Sandbox Code Playgroud)
问题:https_incoming
前端知道客户端 IP,但由于它在 中mode tcp
,因此无法将此信息保存在mode http
X-Forwarded-For
标头中。option forwardfor
在 TCP 模式下无效。
从另一个关于 serverfault 的问题 我已经发现我可以使用:
因此,据X-Forwarded-For
我所知,甚至不再需要标头,在 LVS 的情况下:数据包被欺骗,因此源成为客户端 IP,而在 PROXY 的情况下:数据包被封装以携带客户端 IP。
这两个似乎都可以工作。然而,LVS 对我们来说似乎是一种心脏手术,可能会产生副作用,而 PROXY 的缺点是代理/应用程序上游/下游,可能尚不完全兼容。
我真的希望有更轻量级的东西,那时我发现了HAProxy 1.6的新“捕获”功能,因为它提到:
您可以声明捕获槽,在其中存储数据并在会话期间随时使用它。
它继续显示以下示例:
defaults
mode http
frontend f_myapp
bind :9001
declare capture request len 32 # id=0 to store Host header
declare capture request len 64 # id=1 to store User-Agent header
http-request capture req.hdr(Host) id 0
http-request capture req.hdr(User-Agent) id 1
default_backend b_myapp
backend b_myapp
http-response set-header Your-Host %[capture.req.hdr(0)]
http-response set-header Your-User-Agent %[capture.req.hdr(1)]
server s1 10.0.0.3:4444 check
Run Code Online (Sandbox Code Playgroud)
在我看来,信息存储在前端,然后在后端使用,所以也许我可以在 TCP 模式下获取客户端 IP,保存它,然后稍后使用它,可能像这样:
http-response set-header X-Forwarded-For %[capture.req.hdr(0)]
Run Code Online (Sandbox Code Playgroud)
我查看了捕获文档,似乎捕获更面向 http 模式标头,但后来我还看到一个邮件列表对话成功演示了tcp-request capture
.
我尝试了几件事,其中包括:
tcp-request capture req.hdr(RemoteAddr) id 0
# or
tcp-request content capture req.hdr(RemoteHost) id 0
Run Code Online (Sandbox Code Playgroud)
但是正如您所看到的,我不知道语法应该是什么以及该信息在哪个键下可用,我也无法在(我认为)相关文档中找到它。
问题:是否可以在 TCP 模式下捕获客户端 IP,然后X-Forwarded-For
在 HTTP 模式下将此信息写入标头?如果是这样,它的语法是什么?
要回答我自己的问题,这似乎不可能,因为流量“离开”HAProxy:
TCP HTTP
frontend->backend (->leaving->) frontend->backend
Run Code Online (Sandbox Code Playgroud)
因此上下文丢失并且捕获无法保留。相反,正如“PiBa-NL”昨天在 Freenode 的 #haproxy 上的 IRC 上建议的那样:
[5:29pm] PiBa-NL: kvz, use proxy-protocol between back and front
[5:54pm] kvz: PiBa-NL: Thanks, does this mean my app also needs to understand
the proxy protocol, or will it be 'stripped' once it reaches the
backend. I don't think my node.js server could handle it without
significant changes to its stack
[6:07pm] kvz: Or let me rephrase: could I enable the proxy protocol on the first
frontend, then 'unwrap' it in the second frontend, taking the client ip
and putting it into the http header - so that my app would not have to
be proxy protocol compatible, and it would just be means to carry the
client ip from first frontend to the second?
[6:49pm] PiBa-NL: kvz, the last part you can still use the x-forwarded-for header
[6:50pm] PiBa-NL: but between haproxy backend and frontend you would use the
proxyprotocol to make the second frontent 'know' the original client ip
[6:50pm] PiBa-NL: server https_strong 127.0.0.1:1665 send-proxy
[6:50pm] PiBa-NL: bind 127.0.0.1:1665 ssl crt .... accept-proxy
[6:52pm] PiBa-NL: the second frontend can then still use the
'option forwardfor', and it should insert the wanted header
[6:53pm] PiBa-NL: so basically 'yes'
Run Code Online (Sandbox Code Playgroud)
这意味着 PROXY 协议仅用于将两个前端粘合在一起,封装客户端 IP,但第二个前端将其解开并将其保存在 header X-Forwarded-For
via中option forwardfor
,以便其后端可以向我的应用程序发送无 PROXY 协议的请求服务器,这意味着我不必担心上/下游的兼容性问题。
归档时间: |
|
查看次数: |
4057 次 |
最近记录: |