一、前置任务
1.注意nginx编译时需要加上stream模块及http_realip_module、stream_realip_module模块
2.stream模块用来四层负载(proxy_protocol),http_realip_module、stream_realip_module模块用来获取客户端真实IP(real_ip_header)
3.开启透传功能proxy_protocol on,用于将连接信息从请求连接的源传递到请求连接到的目标
#nginx是否包含以下模块
nginx -V 2>&1 | grep -- 'http_realip_module'
nginx -V 2>&1 | grep -- 'stream_realip_module'
关于nginx编译详见:宝塔面板自定义编译安装nginx模块
二、配置stream转发服务
以ssh(sftp)和https共用同一端口【Nginx根据TLS分流】文章中的配置ssh和https共用同一端口为例:
在nginx.conf
只需要增加proxy_protocol on;
即可
stream {
upstream ssh {
server ssh.example.com:22;
}
upstream web {
server tls.example.com:443;
}
map $ssl_preread_protocol $upstream {
"" ssh;
default web;
}
# SSH and SSL on the same port
server {
listen 443;
listen [::]:443;
proxy_pass $upstream;
ssl_preread on;
proxy_protocol on;
}
}
三、配置http服务
1.配置nginx.conf
中的http{}内容,获取真实IP
此时所有站点均能获取真实IP,无需逐一配置
http {
#……巴拉巴拉
set_real_ip_from 127.0.0.1;# 从Proxy protocol获取真实IP
#set_real_ip_from 0.0.0.0/0;# 懂?
real_ip_header proxy_protocol;
#……巴拉巴拉
}
此时访问站点可能会存在无法访问的情况,如遇到ERR_PROTOCOL_ERROR
等错误
2.配置网站的conf
,加入proxy_protocol
单个站点同样可以通过配置set_real_ip_from
和real_ip_header
实现获取真实IP
server
{
listen 443 ssl http2 proxy_protocol;
listen [::]:443 ssl http2 proxy_protocol;
#……巴拉巴拉
#set_real_ip_from 127.0.0.1;# 从Proxy protocol获取真实IP
#real_ip_header proxy_protocol;
#……巴拉巴拉
}
在 1.25.1 版本后的 nginx 运行日志中,可能会发现以下警告信息:
nginx: [warn] the “listen … http2” directive is deprecated, use the “http2” directive instead in etc/nginx/nginx.conf
需要修改为
server { listen 443 ssl proxy_protocol; listen [::]:443 ssl proxy_protocol; http2 on; #……巴拉巴拉 #set_real_ip_from 127.0.0.1;# 从Proxy protocol获取真实IP #real_ip_header proxy_protocol; #……巴拉巴拉 }
3.效果图
可以发现日志中的IP已从127.0.0.1变为客户端的公网IP了
参考文章:
Changing the Load Balancer’s IP Address To the Client IP Address
评论区