> 邮箱运维 > 邮件系统实现IP透传:Proxy Protocol方案(适用于SMTP/POP3/IMAP/HTTP协议)
1. Proxy Protocol简介
PROXY Protocol提供了一种方便的方法,可以安全地在多层 NAT 或 TCP 代理之间传输连接信息,如客户端的地址。该协议的设计目的是尽量减少对现有组件的更改,并将传输信息的处理对性能的影响降到最低。
HAProxy的作者Willy Tarreau于2010年开发和设计的一个Internet协议,通过为tcp添加一个很小的头信息,来方便的传递客户端信息(协议栈、源IP、目的IP、源端口、目的端口等),在网络情况复杂又需要获取用户真实IP时非常有用。其本质是在三次握手结束后由代理在连接中插入了一个携带了原始连接四元组信息的数据包。
2. Proxy Protocol版本
Proxy Protocol 有两个版本:
2.1 Human-readable header format (Version 1)
V1版本采用可阅读的报头格式,每个字段中间为空格(\x20)。
格式:
PROXY TCP4/6 源IP地址 目标IP地址 源端口 目标端口\r\n
示例:
// PROXY AF L3_SADDR L3_DADDR L4_SADDR L4_DADDR\r\n
PROXY TCP4 202.112.144.236 10.210.12.10 5678 80\r\n
PROXY TCP6 2001:da8:205::100 2400:89c0:2110:1::21 6324 80\r\n
PROXY UKNOWN\r\n
详细说明可以参考官方文档:The PROXY protocol Versions 1 & 2
2.2 Binary header format (version 2)
V2版本采用二进制格式,兼容V1版本。具体报头格式可以参考官方文档:The PROXY protocol Versions 1 & 2
3. SMTP/POP3/IMAP协议如何启用Proxy Protocol
并不是所有邮件系统都支持Proxy Protocol,据不完全统计,支持Proxy Protocol的邮件系统或组件包括:
以Coremail为代表的国产邮件系统已经支持Proxy Protocol协议,相关配置方法可以咨询官方客户或关注公众号咨询小编。开源邮件系统可以查阅官方文档了解启用Proxy Protocol方法。
4. 负载均衡如何启用Proxy Protocol
4.1. F5 BIG-IP负载均衡
添加 iRule脚本,示例如下:
when CLIENT_ACCEPTED {
set proxyheader "PROXY TCP[IP::version][IP::remote_addr][IP::local_addr] [TCP::remote_port] [TCP::local_port]\r\n"
}
when SERVER_CONNECTED {
TCP::respond $proxyheader
}
4.2 深信服负载均衡
添加IPro脚本,示例如下:
local proxyheader = nil
event CLIENT_ACCEPT {
proxyheader = 'PROXY TCP'..'4'..' '..TCP.remoteaddr()..' '..TCP.localaddr()..' '..TCP.remoteport()..' '..TCP.localport()..' \r\n'
TCP.release(0)
}
event SERVER_CONNECTED {
TCP.respond(proxyheader)
}
4.3 Nginx负载均衡
确保你的 NGINX 安装包含 HTTP 和 Stream Real-IP 模块:
nginx -V 2>&1 | grep -- 'http_realip_module'
nginx -V 2>&1 | grep -- 'stream_realip_module'
如果通过Nginx反向代理SMTP、POP3、IMAP协议,需要在stream中启用proxy protocol:
stream {
server {
listen 25;
proxy_pass example.com:25;
proxy_protocol on;
}
}
如果通过Nginx反向代理HTTP协议,需要在server配置段中做相关配置。当然,也可以选择通过X-FORWARDED-FOR做IP透传。
http {
log_format combined '$proxy_protocol_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';
#...
server {
server_name localhost;
listen 80 proxy_protocol;
listen 443 ssl proxy_protocol;
ssl_certificate /etc/nginx/ssl/public.example.com.pem;
ssl_certificate_key /etc/nginx/ssl/public.example.com.key;
location /app/ {
proxy_pass http://backend1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $proxy_protocol_addr;
proxy_set_header X-Forwarded-For $proxy_protocol_addr;
}
}
}
关于Nginx启用proxy protocol可以参考官方文档:Accepting the PROXY Protocol | NGINX Documentation
未标注来源的文章均为原创作品,版权所有,转载请注明出处。非原创文章均已标注来源,如有侵权请告知。
如您喜欢本站,可以收藏加关注(扫码关注右上角微信公众号mailabc)。