根据我之前的问题haproxy 后面的 SSHD 真实 IP - 我现在正尝试设置 HAProxy 透明地将 IP 传递给后端服务。
tproxy 模块已加载/并在 haproxy 中受支持(我使用 USE_LINUX_TPROXY=1 重新编译了 haproxy);
~$ uname -r
3.13.0-34-generic
~$ lsmod | grep -ie tprox
xt_TPROXY 17356 0
nf_defrag_ipv6 34768 2 xt_socket,xt_TPROXY
nf_defrag_ipv4 12758 2 xt_socket,xt_TPROXY
x_tables 34059 8 ip6table_filter,xt_mark,ip_tables,xt_socket,iptable_filter,xt_TPROXY,iptable_mangle,ip6_tables
~$ haproxy -vv
HA-Proxy version 1.5.3 2014/07/25
Copyright 2000-2014 Willy Tarreau <[email protected]>
Build options :
TARGET = linux2628
CPU = native
CC = gcc
CFLAGS = -O2 -march=native -g -fno-strict-aliasing
OPTIONS = USE_LINUX_TPROXY=1 USE_ZLIB=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.8
Compression algorithms supported : identity, deflate, gzip
Built with OpenSSL version : OpenSSL 1.0.1f 6 Jan 2014
Running on OpenSSL version : OpenSSL 1.0.1f 6 Jan 2014
OpenSSL library supports TLS extensions : yes
OpenSSL library supports SNI : yes
OpenSSL library supports prefer-server-ciphers : yes
Built with PCRE version : 8.31 2012-07-06
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.
服务器配置;
~$ cat haproxy-iptables.sh
#!/bin/bash
sudo iptables -t mangle -N DIVERT
sudo iptables -t mangle -A PREROUTING -p tcp -m socket -j DIVERT
sudo iptables -t mangle -A DIVERT -j MARK --set-mark 111
sudo iptables -t mangle -A DIVERT -j ACCEPT
sudo ip rule add fwmark 111 lookup 100
sudo ip route add local 0.0.0.0/0 dev lo table 100
sudo ip route flush cache
~$ cat /etc/sysctl.conf
net.ipv4.ip_forward=1
net.ipv4.ip_nonlocal_bind=1
net.ipv4.conf.lo.rp_filter=0
~$ cat /etc/haproxy/haproxy.cfg
frontend public
mode tcp
bind :80
redirect scheme https code 301 if !{ ssl_fc }
bind :443 ssl crt example.pem no-tls-tickets
tcp-request inspect-delay 5s
tcp-request content accept if HTTP
use_backend ssh if { ssl_fc_sni ssh.example.com }
backend ssh
mode tcp
source 0.0.0.0 usesrc clientip
server ssh 127.0.0.1:22
timeout server 2h
~$ tail -f /var/log/haproxy.log
Aug 18 16:07:44 localhost haproxy[3323]: 203.000.000.000:56914 [18/Aug/2014:16:07:24.233] public~ ssh/ssh 71/-1/20076 0 sC 0/0/0/0/3 0/0
如果没有source 0.0.0.0 usesrc clientip
haproxy.cfg 中的行,我得到的输出为/var/log/auth.log
Aug 18 16:20:23 localhost sshd[6532]: debug1: rexec start in 5 out 5 newsock 5 pipe 7 sock 8
Aug 18 16:20:23 localhost sshd[6532]: debug1: inetd sockets after dupping: 3, 3
Aug 18 16:20:23 localhost sshd[6532]: debug1: Connection refused by tcp wrapper
Aug 18 16:20:23 localhost sshd[6532]: refused connect from localhost (127.0.0.1)
当该行添加到 ssh 后端块时,没有任何内容被记录下来auth.log
- 数据包没有到达 sshd(它们仍然列在 中haproxy.log
)
我认为这可能与 net.ipv4 设置有关?
答案1
为了能够使用 TPROXY,您的 SSH 服务器必须使用 haproxy 盒作为路由器(嗯,haproxy 盒必须位于数据包的路径上,但这是最简单的方法)。
您还需要启用 send_redirects 内核参数:
echo 1 >/proc/sys/net/ipv4/conf/all/send_redirects
echo 1 >/proc/sys/net/ipv4/conf/eth0/send_redirects
答案2
我建议你看看代理服务器,这对我来说是最简单的设置方法。它对于特定守护进程来说是透明的,