ily*_*rov 13 linux ip iptables route
我有一个自己编写的接口 tun0(基于TUN/TAP)输出它接收到的内容。
我需要系统的所有流量都流经这个接口。
接口的作用是:
正如您猜想的那样,我正在尝试构建一个反审查工具。
关于隧道的决定必须在 tun0 进程中进行,
因为只有在那里我们才能使用受信任的 DNS。
我需要你的帮助来告诉我如何让所有流量都通过一个自写的接口 tun0。如果 tun0 需要更改,我会要求您提供此类更改。
以下是我尝试使所有流量通过 tun0 并失败(ping 失败)的方法。
gcc tun0.csudo ./a.outsudo ip addr add 10.0.0.1/24 dev tun0创建表约翰
$ cat /etc/iproute2/rt_tables
#
# reserved values
#
255 local
254 main
253 default
0 unspec
#
# local
#
#1 inr.ruhep
200 John
Run Code Online (Sandbox Code Playgroud)顺序很重要:
sudo ip rule add from all lookup Johnsudo ip route add default dev tun0 table Johnsudo ip rule add iif tun0 lookup main priority 500
$ ip rule
0: from all lookup local
500: from all iif tun0 lookup main
32765: from all lookup John
32766: from all lookup main
35000: from all lookup default
Run Code Online (Sandbox Code Playgroud)sudo tcpdump -i wlp2s0 -qtln icmp然后ping -I tun0 8.8.8.8显示没有捕获到数据包,这意味着没有数据包通过iif tun0 lookup main规则从 tun0 传输到 wlp2s0 。
当我替换tun0为lo无处不在时,它对我有用。
rp_filter=0在/etc/sysctl.confiptables -I FORWARD -j LOG --log-prefix "filter/FORWARD "
iptables -t nat -I OUTPUT -j LOG --log-prefix "nat/OUTPUT "
iptables -t nat -I PREROUTING -j LOG --log-prefix "nat/PREROUTING "
iptables -t nat -I POSTROUTING -j LOG --log-prefix "nat/POSTROUTNG "
tail -f /var/log/syslog
Run Code Online (Sandbox Code Playgroud)
来自答案的修改来源也在这里。
tif*_*oft 10
因此,在您的配置中,您尝试发送到网络的所有数据包最初来自10.0.0.1(因为它们通过tun0接口并且其本地地址是10.0.0.1)。您捕获数据包,到目前为止一切都很好。
现在,tun0进一步发送数据包。源地址是10.0.0.1并且您希望数据包通过不同的接口离开(wlp2s0在您的情况下)。那是路由,所以让我们先启用路由:
sysctl -w net.ipv4.ip_forward=1
Run Code Online (Sandbox Code Playgroud)
在此之后,如果你看tcpdump的wlp2s0,你可以看到的数据包离开与源地址10.0.0.1,而不是与WLAN接口的源地址(你期望我猜的)。所以我们需要改变源地址,它被称为源 NAT。在 linux 中,借助netfilter/iptables很容易:
iptables -t nat -A POSTROUTING -o wlp2s0 -s 10.0.0.1 -j MASQUERADE
Run Code Online (Sandbox Code Playgroud)
另请检查您的FORWARD连锁店是否有ACCEPT政策,否则您需要允许使用以下内容进行转发:
iptables -A FORWARD -i tun0 -o wlp2s0 -s 10.0.0.1 -j ACCEPT
iptables -A FORWARD -i wlp2s0 -o tun0 -d 10.0.0.1 -j ACCEPT
Run Code Online (Sandbox Code Playgroud)
现在一切正常:Linux 内核执行路由,它将数据包从tun0接口移动到wlp2s0. netfilter应该将源 IP 更改10.0.0.1为您wlp2s0为输出数据包分配的接口地址。它记住所有连接,当回复数据包返回时(如果它们),它将wlp2s0接口分配地址的目标地址更改为10.0.0.1(“conntrack”功能)。
嗯,它应该但它没有。看起来,netfilter对这种复杂的路由配置以及同一个数据包首先通过OUTPUT链然后被路由并到达PREROUTING链的事实感到困惑。至少在 Debian 8 机器上它不起作用。
对netfilter进行故障排除的最佳方法是以下TRACE功能:
modprobe ipt_LOG
iptables -t raw -A OUTPUT -p icmp -j TRACE
iptables -t raw -A PREROUTING -p icmp -j TRACE
Run Code Online (Sandbox Code Playgroud)
我只对ICMP包启用跟踪,您可以使用其他过滤器进行调试。
它将显示数据包经过哪些表和链。而且我可以看到数据包没有在FORWARD链上走得更远(并且它没有被nat/POSTROUTING实际执行的链捕获SNAT)。
以下是实现这项工作的几种方法。
消除netfilter混淆的最佳方法是更改tun0.c应用程序中数据包的源 IP 地址。这也是最自然的方式。我们需要在向外的途中将 10.0.0.1 更改为 10.0.0.2,在返回的途中将 10.0.0.2 更改为 10.0.0.1。
我已经修改tun0.c了源地址更改代码。这是新文件,这是您的tun0.c. 对 IP 标头的更改还涉及校验和校正,因此我从OpenVPN 项目中获取了一些代码。这是我在干净重启和tun0_changeip.c启动后执行的命令的完整列表 :
ifconfig tun0 inet 10.0.0.1/30 up
sysctl -w net.ipv4.ip_forward=1
ip route add default dev tun0 table John
ip rule add from all lookup John
ip rule add from 10.0.0.2 lookup main priority 500
iptables -t nat -A POSTROUTING -o wlp2s0 -s 10.0.0.2 -j MASQUERADE
Run Code Online (Sandbox Code Playgroud)
请注意,在这种情况下您不需要关闭反向路径过滤,因为一切都是合法的 -tun0只接收和发送属于其子网的数据包。您也可以进行基于源的路由而不是基于接口的路由。
可以SNAT在数据包到达tun0接口之前进行。不过也不是很正确。在这种情况下,您肯定需要关闭反向路径过滤:
sysctl -w net.ipv4.conf.tun0.rp_filter=0
# It won't work without also changing the "all" value
sysctl -w net.ipv4.conf.all.rp_filter=0
Run Code Online (Sandbox Code Playgroud)
现在,执行SNAT: iptables -t nat -A POSTROUTING -o tun0 -s 10.0.0.1 -j SNAT --to-source ip.address.of.your.wlan.interface
在这里,我们在数据包到达设备之前更改源地址tun0。tun0.c代码“按原样”重新发送这些数据包(具有更改的源地址),并且它们通过 wlan 接口成功路由。但是您可能在 wlan 接口上有一个动态 IP 并且想要使用MASQUERADE(为了不明确指定接口地址)。以下是您可以使用的方法MASQUERADE:
iptables -t nat -A POSTROUTING -o tun0 -s 10.0.0.1 -j SNAT --to-source 10.0.55.1
iptables -t nat -A POSTROUTING -o wlp2s0 -s 10.0.55.1 -j MASQUERADE
Run Code Online (Sandbox Code Playgroud)
请注意“ 10.0.55.1” IP 地址 - 它是不同的。你可以在这里使用任何IP,没关系。如果我们之前更改源 IP,数据包会到达接口上的nat/POSTROUTING链wlp2s0。现在它不依赖于 wlan 接口的静态 IP。
您也可以使用fwmark. 这样你就不需要了,SNAT但你只会捕获传出的数据包:
首先,我们需要禁用反向路径过滤,tun0因为它会转发属于另一个网络的数据包:
sysctl -w net.ipv4.conf.tun0.rp_filter=0
# It won't work without also changing the "all" value
sysctl -w net.ipv4.conf.all.rp_filter=0
Now let's alter the routing rules a bit:
# Delete old rules
ip rule del iif tun0 lookup main
ip rule del from all lookup John
# Packets will start going from wlan interface so they will have source address of it
iptables -t mangle -A OUTPUT -o wlp2s0 -j MARK --set-mark 1
ip rule add fwmark 0x1 lookup John
Run Code Online (Sandbox Code Playgroud)
这是在我的 Debian 8 机器上工作的路由和netfilter的另一个“黑客” ,但我仍然建议采用第一种方法,因为它更自然并且不使用任何黑客。
您还可以考虑将您的应用程序构建为透明代理。我认为比分析来自 tun 设备的数据包要容易得多。
| 归档时间: |
|
| 查看次数: |
7362 次 |
| 最近记录: |