nginx作为tcp7层代理的时候并不是直接转发流量而是建立一个新的连接,而某些软件对7层的协议支持并不完整比如proxy_protocol
协议,导致显示的IP来源都是127.0.0.1或者干脆不能正常工作。所以我们现在要支持tcp 4层转发,让数据包直接去到后端。
我们可以在百度里看到各种文章,里面大部分都是在
stream {
server {
proxy_protocol on;#在这里加上这个配置
但是这个配置我觉得不是特别友好,特别是对于不支持7层的后端来说,你的来源全部都是127.0.0.1,很多分析无法进行。所以我们要用下面这个配置(一般在/etc/nginx/nginx.conf)
user root;#原来这里是www-data或者nginx的
worker_processes auto;
这些配置一般会跟你的ssl preread配置在一起
stream {
server {
listen 443;
listen [::]:443;
proxy_bind $remote_addr transparent; #加上这条
现在我们要创建IP透明代理路由。并且代理和后端要跑在一同台服务器上。如果你能看到这篇文章的话估计你已经找了很多类似文章了。通常文档都是介绍代理和后端不是在同一台服务器上的。
系统一般不允许将具有非本地源的数据包发送到环回地址,除非启用了route_localnet,如果具有环回地址的伪造数据包可能到达公共接口,这会产生安全问题。
但是这个限制仅适用于127/8地址范围,我们可以为环回接口分配别的的地址。从而绕过这个限制
ip addr add 192.168.127.1/24 dev lo scope host
debian系也可以在/etc/network/interfaces里改成这样。RH系很久没操作了,就用上面这个凑活吧,你们自己找持久化方法。
auto lo lo:10
iface lo inet loopback
iface lo:10 inet static
address 192.168.127.40
netmask 255.255.255.0
network 192.168.127.0
这样,我们给回环地址分配一个192.168.127.40的地址和一个192.168.127.0/24的可达网段。
为了匹配返回数据包,我们需要查看OUTPUT链而不是PREROUTING链。
在不是同一主机的方案里,我们会用PREROUTING去匹配。就像别的教程里
iptables -t mangle -N DIVERT
iptables -t mangle -A PREROUTING -p tcp -m socket -j DIVERT
iptables -t mangle -A DIVERT -j MARK --set-mark 1
iptables -t mangle -A DIVERT -j ACCEPT
ip rule add fwmark 1 lookup 100
ip route add local 0.0.0.0/0 dev lo table 100
但是,由于我们的流量来自本地主机,并且可以通过源地址轻松识别,因此我们可以放弃整个iptables匹配和基于标记的路由规则,将其替换为基于源的简单路由规则。
ip rule add from 192.168.127.0/24 lookup 100
ip route add local 0.0.0.0/0 dev lo table 100
debian系可以用以下持久化方法
iface lo:10 inet static
address 192.168.127.40
netmask 255.255.255.0
network 192.168.127.0
up ip rule add from 192.168.127.0/24 lookup 100 #新增这两条1
up ip route add local 0.0.0.0/0 dev lo table 100 #新增这两条2
然后可以nginx/trojan服务器行以连接到在此新地址范围上侦听的本地服务。
必须注意将环回接口用于透明代理连接,否则数据包将无法传递。 这是通过使用新的本地地址做为监听地址而不是*或者0.0.0.0来完成的。
nginx配置---stream部分
stream {
根据sni分流
map $ssl_preread_server_name $backend_name {
yourname.com trojan;
default web;
}
# web
upstream web {
server 192.168.127.40:444;
}
# trojan
upstream trojan {
server 192.168.127.40:445;
}
server {
listen 443;
listen [::]:443;
proxy_pass $backend_name;
proxy_bind $remote_addr transparent;#4层转发模式
ssl_preread on;
}
}
nginx-server虚拟服务器部分,也就是你正常网站的部分
server {
listen 444 http2 ssl;
listen 192.168.127.40:444 http2 ssl;
listen [::]:444 http2 ssl;
server_name balabalayourname.com;
}
某些不能完整支持7层协议的软件,也一定要指定监听192.168.127.40或者特定IP,你指定*或者0.0.0.0是不管用的。
END
大部分主机会分配私有 IP,如 10.2.0.2 之类的,其实这个 IP 就可以当作是博主说的 192.168* 是吗?
对的。
把这个配置到lo上就行。
博主的评论配置是不是出故障了,提交了三次,第一要我返回重新提交,第二次提示没填验证码(实际上没有弹出要填),第三次提示已经评论过了。。。
是坏了,主题很久没更新了。而且一直懒得修,国内备案的站有点怕说错话。
其实我还是不太懂博主的意思,以 Tj 为例,把 Tj 作为前端,是可以获取到 IP 的,当不匹配时 Tj 会路由至后端网站,这时后端网站获取到的 IP 是 127.0.0.1 而不是真实 IP,博主文章是解决这个问题吗?
因为按照博主的配置,路由至 Tj 后,Tj 没有匹配成功,会再路由到真实网站,此时真实网站获取到的仍然是本地地址
“nginx作为tcp7层代理的时候并不是直接转发流量而是建立一个新的连接”是nginx在前的。