haproxy-IP透传

IP透传

web服务器中需要记录客户端的真实IP地址,用于做访问统计、安全防护、行为分析、区域排行等场景。

layer 4 与 layer 7

四层:IP+PORT转发

七层:协议+内容交换

haproxy-IP透传插图

四层负载

在四层负载设备中,把client发送的报文目标地址(原来是负载均衡设备的IP地址),根据均衡设备设置的选择web服务器的规则选择对应的web服务器IP地址,这样client就可以直接跟此服务器建立TCP连接并发送数据,而四层负载自身不参与建立连接,而和LVS不同,haproxy是伪四层负载均衡,因为haproxy 需要分别和前端客户端及后端服务器建立连接

七层代理

七层负载均衡服务器起了一个反向代理服务器的作用,服务器建立一次TCP连接要三次握手,而client要访问webserver要先与七层负载设备进行三次握手后建立TCP连接,把要访问的报文信息发送给七层负载均衡;然后七层负载均衡再根据设置的均衡规则选择特定的webserver,然后通过三次握手与此台webserver建立TCP连接,然后webserver把需要的数据发送给七层负载均衡设备,负载均衡设备再把数据发送给client;所以,七层负载均衡设备起到了代理服务器的作用,七层代理需要和Client和后端服务器分别建立连接

[root@haproxy ~]#tcpdump  tcp  -i eth0   -nn port ! 22  -w dump-tcp.pcap  -v
[root@haproxy ~]#tcpdump  tcp  -i eth1   -nn port ! 22  -w dump-tcp2.pcap -v

haproxy-IP透传插图(1)
haproxy-IP透传插图(2)

四层IP透传

#haproxy 配置:
listen  web_prot_http_nodes
    bind  172.16.0.100:80
    mode  tcp
    balance roundrobin
    server web1 www.wangxiaochun.com:80  send-proxy  check inter 3000 fall 3 rise 5

#nginx配置:变量proxy_protocol_addr 记录透传过来的客户端IP
http {
log_format  main  'remote_addr - remote_user [time_local] "request" "proxy_protocol_addr"'
       server {
            listen       80 proxy_protocol; #启用此项,将无法直接访问此网站,只能通过四层代理访问
            server_name www.wangxiaochun.com;
......

抓包可以看到continuation信息中带有客户端的源IP

haproxy-IP透传插图(3)

#nginx在开启proxy_protocol前
[root@internet ~]#curl 172.16.0.100
<html>
<head><title>400 Bad Request</title></head>
<body>
<center><h1>400 Bad Request</h1></center>
<hr><center>nginx</center>
</body>
</html>

[root@VM_0_10_centos ~]# tail -f /apps/nginx/logs/nginx.access.log
111.199.187.69 - - [09/Apr/2020:20:48:51 +0800] "PROXY TCP4 10.0.0.100 58.87.87.99 35948 80" sendfileon
111.199.187.69 - - [09/Apr/2020:20:48:54 +0800] "PROXY TCP4 10.0.0.100 58.87.87.99 35952 80" sendfileon
111.199.187.69 - - [09/Apr/2020:20:48:57 +0800] "PROXY TCP4 10.0.0.100 58.87.87.99 35954 80" sendfileon

#在nginx服务器上开启日志格式和proxy_protocal
[root@VM_0_10_centos ~]# vim /apps/nginx/conf/nginx.conf
http {
.......
log_format  main  'remote_addr -remote_user [time_local] "request" "$proxy_protocol_addr"'
    sendfile        on;
    keepalive_timeout  65;
    client_max_body_size 100m;
    server {
        listen       80 default_server proxy_protocol ;
......

#nginx在开启proxy_protocol后,可以看客户端真实源IP
[root@VM_0_10_centos ~]# tail -f /apps/nginx/logs/nginx.access.log
111.199.187.69 - - [09/Apr/2020:20:52:52 +0800] "GET / HTTP/1.1" "172.16.0.200"sendfileon

七层IP透传

当haproxy工作在七层的时候,如何透传客户端真实IP至后端服务器

HAProxy配置

在由haproxy发往后端主机的请求报文中添加“X-Forwarded-For”首部,其值为前端客户端的地址;用于向后端主发送真实的客户端IP

option forwardfor [ except <network> ] [ header <name> ] [ if-none ]
[ except <network> ]:请求报请来自此处指定的网络时不予添加此首部,如haproxy自身所在网络
[ header <name> ]:使用自定义的首部名称,而非“X-Forwarded-For”,示例:X-client
[ if-none ]  如果没有首部才添加首部,如果有使用默认值

范例:

#haproxy 配置
defaults

option  forwardfor   #此为默认值,首部字段默为:X-Forwarded-For
#或者自定义首部为X-client:
option forwardfor except 127.0.0.0/8 header X-client 

#listen配置
listen  web_host
  bind 10.0.0.7:80
  mode http
  log global
  balance  random
  server web1 10.0.0.17:80 weight 1  check inter 3000 fall 2 rise 5
  server web2 10.0.0.27:80 weight 1  check inter 3000 fall 2 rise 5

web服务器日志格式配置

配置web服务器,记录负载均衡透传的客户端IP地址

#apache 配置:
LogFormat "%{X-Forwarded-For}i %a  %l %u %t /"%r/" %>s %b /"%{Referer}i/" /"%{User-Agent}i/"" combined

#nginx 日志格式:
proxy_add_x_forwarded_for:包括客户端IP和中间经过的所有代理的IPhttp_x_forwarded_For:只有客户端IP

log_format  main  '"proxy_add_x_forwarded_for" -remote_user [time_local] "request" '
                      'statusbody_bytes_sent "http_referer" '
                      '"http_user_agent" $http_x_forwarded_For';

[root@centos8 ~]#tail /var/log/nginx/access.log
"172.16.0.200, 10.0.0.100" 10.0.0.100 - - [09/Apr/2020:19:10:16 +0800] "GET / HTTP/1.1" 200 4057 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.27.1 zlib/1.2.3 libidn/1.18 libssh2/1.4.2" "172.16.0.200" 

#tomcat 配置:conf目录下的server.xml
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
   prefix="localhost_access_log" suffix=".txt"
   pattern="%{X-Forwarded-For}i %h %l %u %t "%r" %s %b" />     

验证客户端IP地址

apache日志:

[root@centos7 ~]#vim /etc/httpd/conf/httpd.conf 
LogFormat "%{X-Forwarded-For}i %h %l %u %t /"%r/" %>s %b /"%{Referer}i/" /"%{User-Agent}i/"" combined
[root@centos7 ~]#systemctl restart httpd

[root@centos6 ~]#hostname -I
10.0.0.6 
[root@centos6 ~]#curl   http://10.0.0.7
10.0.0.17
[root@centos7 ~]#tail -f /var/log/httpd/access_log 
10.0.0.6 10.0.0.7 - - [01/Apr/2020:01:08:31 +0800] "GET / HTTP/1.1" 200 10 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.27.1 zlib/1.2.3 libidn/1.18 libssh2/1.4.2"
10.0.0.6 10.0.0.7 - - [01/Apr/2020:01:08:33 +0800] "GET / HTTP/1.1" 200 10 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.27.1 zlib/1.2.3 libidn/1.18 libssh2/1.4.2"

本文链接:http://www.yunweipai.com/35283.html

原创文章,作者:Maggie-Hunter,如若转载,请注明出处:https://blog.ytso.com/tech/courses/52700.html

(0)
上一篇 2021年8月6日 16:44
下一篇 2021年8月6日 16:44

相关推荐

发表回复

登录后才能评论