我目前正在以透明模式设置 HAProxy,因为它应该在不支持 PROXY 协议的软件节点之间进行平衡,想要自行终止 SSL 并执行自己的基于 IP 的安全性。
我已经查看了所有我能找到的关于如何设置透明模式的搜索结果和指南,虽然它看起来很简单,但它似乎根本不起作用。
基础是 CentOS 7 最小安装,HAProxy 以 root 身份运行。它是后端服务器的默认网关,已加载 TPROXY,并设置了必要的防火墙规则和网络。
使用tcpdump
,我可以看到所有往返后端服务器的流量都经过 HAProxy,但数据包中的源 IP 根本没有被替换。顺便说一句,据我所知,与后端的通信和负载平衡工作正常。
haproxy.cfg:
global
log 127.0.0.1 local0 debug
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
daemon
stats socket /var/lib/haproxy/stats uid hatop gid hatop mode 0600
defaults
mode tcp
log global
option tcplog
# option dontlognull
option redispatch
retries 3
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout check 10s
maxconn 3000
balance leastconn
frontend f_general_plain
bind 10.1.1.20:80 transparent # HTTP
bind 10.1.1.20:465 transparent # SMTP
bind 10.1.1.20:587 transparent # Submission
bind 10.1.1.20:143 transparent # IMAP
bind 10.1.1.20:5229 transparent # Groupware
bind 10.1.1.20:32002 transparent
bind 10.1.1.20:5222 transparent # XMPP
bind 10.1.1.20:5223 transparent
default_backend b_general_plain
backend b_general_plain
stick-table type ip size 1m expire 10h
stick on src
source 0.0.0.0 usesrc clientip
server iw1 10.1.1.16
server iw2 10.1.1.17
frontend f_general_ssl
bind 10.1.1.20:443 transparent # HTTPS
bind 10.1.1.20:465 transparent # SMTPS
bind 10.1.1.20:993 transparent # IMAPS
default_backend b_general_ssl
backend b_general_ssl
stick on src table b_general_plain
source 0.0.0.0 usesrc clientip
server iw1 10.1.1.16
server iw2 10.1.1.17
frontend f_smtp
bind 10.1.1.20:25 transparent
default_backend b_smtp
backend b_smtp
stick on src table b_general_plain
option smtpchk EHLO balancer.example.com
source 0.0.0.0 usesrc clientip
server iw1 10.1.1.16:25 check
server iw2 10.1.1.17:25 check
/etc/sysctl.conf
net.ipv4.ip_forward = 1
net.ipv4.ip_nonlocal_bind = 1
net.ipv4.conf.default.send_redirects = 1
net.ipv4.conf.all.accept_redirects = 1
net.ipv4.conf.default.rp_filter = 2
net.ipv4.conf.default.accept_source_route = 1
/etc/firewalld/direct.xml -firewalld 几乎没有设置任何其他内容,只是打开了必要的端口等。根据 iptables -t mangle -vL,DIVERT 链确实被使用。
<?xml version="1.0" encoding="utf-8"?>
<direct>
<chain ipv="ipv4" table="mangle" chain="DIVERT"/>
<rule ipv="ipv4" table="mangle" chain="PREROUTING" priority="0">-p tcp -m socket -j DIVERT</rule>
<rule ipv="ipv4" table="mangle" chain="DIVERT" priority="0">-j MARK --set-mark 1</rule>
<rule ipv="ipv4" table="mangle" chain="DIVERT" priority="1">-j ACCEPT</rule>
</direct>
ip 规则:
0: from all lookup local
32765: from all fwmark 0x1 lookup 100
32766: from all lookup main
32767: from all lookup default
ip 路由显示表 100:
local default dev lo scope host
lsmod | grep -i tproxy
xt_TPROXY 17327 0
nf_defrag_ipv6 35104 3 xt_socket,xt_TPROXY,nf_conntrack_ipv6
nf_defrag_ipv4 12729 3 xt_socket,xt_TPROXY,nf_conntrack_ipv4
uname -a
Linux balancer 3.10.0-957.12.1.el7.x86_64 #1 SMP Mon Apr 29 14:59:59 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
haproxy-vv
HA-Proxy version 1.5.18 2016/05/10
Copyright 2000-2016 Willy Tarreau <[email protected]>
Build options :
TARGET = linux2628
CPU = generic
CC = gcc
CFLAGS = -O2 -g -fno-strict-aliasing -DTCP_USER_TIMEOUT=18
OPTIONS = USE_LINUX_TPROXY=1 USE_GETADDRINFO=1 USE_ZLIB=1 USE_REGPARM=1 USE_OPENSSL=1 USE_PCRE=1
Default settings :
maxconn = 2000, bufsize = 16384, maxrewrite = 8192, maxpollevents = 200
Encrypted password support via crypt(3): yes
Built with zlib version : 1.2.7
Compression algorithms supported : identity, deflate, gzip
Built with OpenSSL version : OpenSSL 1.0.2k-fips 26 Jan 2017
Running on OpenSSL version : OpenSSL 1.0.2k-fips 26 Jan 2017
OpenSSL library supports TLS extensions : yes
OpenSSL library supports SNI : yes
OpenSSL library supports prefer-server-ciphers : yes
Built with PCRE version : 8.32 2012-11-30
PCRE library supports JIT : no (USE_PCRE_JIT not set)
Built with transparent proxy support using: IP_TRANSPARENT IPV6_TRANSPARENT IP_FREEBIND
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.
答案1
“这不是 iptables。”
“这不可能是 iptables。”
是 iptables。毕竟,省略的防火墙配置的其余部分有错误。不要因为压力而遵循随机指南来设置一些可以正常工作的东西。如果您发现此问题,请寻找类似的问题:上述配置对我来说工作得很好。
弄清楚这一点的一个很大的帮助是停止服务,在 shell 中运行相同的命令strace -f
并查看它做了什么。您应该看到一个bind()
带有您绑定到的 IP(clientip
或手动指定一个)的 ,其中包括一个套接字号。该套接字号随后应用于连接到后端服务器。