一、测试环境
nginx version: openretsy/1.19.9.1
二、开启Nginx IPv6透明代理
开启Nginx IPv6透明代理,首先需要开启socket的IP_TRANSPARENT选项。示例代码如下:
// file: openresty-1.19.9.1/bundle/nginx-1.19.9/src/core/ngx_connection.c
ngx_int_t ngx_open_listening_sockets(ngx_cycle_t *clcle)
{
...
int transparent = 1;
setsockopt(s, IPPROTO_IPV6, IPV6_TRANSPARENT, (const void *) &transparent, sizeof(int));
...
}
除了开启nginx socket的IP_TRANSPARENT选项,还要配置iptables的TRPOXY规则。TRPOXY只能工作在PREROUTING链。假设nginx的监听端口为[::1]:58969,那么,iptable的命令为:
ip6tables -t mangle -A PREROUTING -i any -p tcp -j TPROXY --on-ip ::1 --on-port 58969
需要注意的是,ipv6对应的命令时ip6tables,而不是iptables。
理论上,在上述两个步骤之后,该nginx就可以透明代理ipv6数据包了。
三、验证Nginx IPv6透明代理
想要验证Nginx IPv6透明代理,可以随意指定一个IPv6地址,然后在nignx所在的机器访问它。假设选择1:1:1:1:1:1:1:1作为访问目标,通过curl命令发起访问。此时,查看Nginx访问日志,不会发现任何相关记录。因为,从机器上发出的数据包并不会触发PREROUTING链的规则,自然也不会透明代理到nginx。为了使机器发出的数据包经过PREROUTING链,还需要额外做一些配置。
ip6tables -t mangle -A OUTPUT -p tcp -d 1:1:1:1:1:1:1:1 -j MARK --set-xmark 20
ip -6 rule ad#d(敏感词) fwmark 20 table 1920
ip -6 route ad#d(敏感词) local default dev lo table 1920
先通过iptables OUTPUT链对机器发出的数据包打上标记,再通过ip rule将标记数据包发送到到lo网卡。这样机器发出的数据包就能触发PREROUTING链的TPROXY规则,透明代理到nginx。
再次执行curl对1:1:1:1:1:1:1:1进行访问,并查看Nginx访问日志,可以发现相关记录,说明开启了Nginx IPv6透明代理。