ip6tables snat 无法正常工作

ip6tables snat 无法正常工作

我有三台电脑,名字分别是:laptop、vds 和 home;

vds 是 openvpn 服务器;home 是 openvpn 客户端。我有一个 ipv6 网络 2a01:dead:beef::/64
vds 有地址2a01:dead:beef::311hometun0
有地址2a01:dead:beef::312laptoptun0
2a01:beef:beef::666地址en3

我希望通过 vds 从笔记本电脑访问家里的网络,因此我在 vds 上做了一些配置:
在 vds 上我添加了一个附加地址2a01:dead:beef::2ea,并制定了以下 iptables 规则:

ip6tables -t nat -A PREROUTING -i eth0 -d 2a01:dead:beef::2ea -j DNAT --to-destination 2a01:dead:beef::312
ip6tables -t nat -A POSTROUTING -s 2a01:dead:beef::312 -o tun0 -j SNAT --to-source 2a01:dead:beef::2ea 

我已经改变了 vds 上的路线:

vds:~/>ip -6 r
2a01:dead:beef::312 dev tun0  metric 1
2a01:dead:beef::/64 dev eth0  proto kernel  metric 256
2a01:dead:beef::/64 dev tun0  proto kernel  metric 256
fe80::/64 dev eth0  proto kernel  metric 256
default via 2a01:dead:beef::1 dev eth0  metric 1024

并且在 openvpn 服务器配置中我添加了

push "route-ipv6 2000::/3"

所以家里的tun0IPv6 路由变成了默认路由:

home:~/>ip -6 r
2a01:dead:beef::/64 dev tun0  proto kernel  metric 256
2000::/3 dev tun0  metric 1
fe80::/64 dev mlan0  proto kernel  metric 256
fe80::/64 dev eth11  proto kernel  metric 256
fe80::/64 dev tun0  proto kernel  metric 256

现在,如果我从我的笔记本电脑 ping 2a01:dead:beef::2ea,DNAT 和 SNAT 可以正常工作,并且我得到了 ping 信息:

laptop:~/>ping6 2a01:dead:beef::2ea
PING6(56=40+8+8 bytes) 2a01:beef:beef::666 --> 2a01:dead:beef::2ea
16 bytes from 2a01:dead:beef::2ea, icmp_seq=0 hlim=55 time=108.618 ms
16 bytes from 2a01:dead:beef::2ea, icmp_seq=1 hlim=55 time=108.752 ms

但是,如果我从家里 ping 我的笔记本电脑,则无法 ping 通:

home:~/>ping6 2a01:beef:beef::666
PING 2a01:beef:beef::666 (2a01:beef:beef:0:0:0:0:666) 56 data bytes
^C
--- 2a01:beef:beef::666 ping statistics ---
8 packets transmitted, 0 received, 100% packet loss, time 6999ms

我在笔记本电脑上启动了 tcpdump,我看到的是:

laptop:~/>sudo /usr/sbin/tcpdump -i en3 -n -nn -ttt "ip6[40]=128 or ip6[40]=129"
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on en3, link-type EN10MB (Ethernet), capture size 65535 bytes
00:00:00.000000 IP6 2a01:dead:beef::312 > 2a01:beef:beef::666: ICMP6, echo request, seq 1, length 64
00:00:00.000050 IP6 2a01:beef:beef::666 > 2a01:dead:beef::312: ICMP6, echo reply, seq 1, length 64
00:00:00.999054 IP6 2a01:dead:beef::312 > 2a01:beef:beef::666: ICMP6, echo request, seq 2, length 64
00:00:00.000045 IP6 2a01:beef:beef::666 > 2a01:dead:beef::312: ICMP6, echo reply, seq 2, length 64
00:00:00.999858 IP6 2a01:dead:beef::312 > 2a01:beef:beef::666: ICMP6, echo request, seq 3, length 64
00:00:00.000038 IP6 2a01:beef:beef::666 > 2a01:dead:beef::312: ICMP6, echo reply, seq 3, length 64
00:00:00.999968 IP6 2a01:dead:beef::312 > 2a01:beef:beef::666: ICMP6, echo request, seq 4, length 64
00:00:00.000158 IP6 2a01:beef:beef::666 > 2a01:dead:beef::312: ICMP6, echo reply, seq 4, length 64

因此,回显请求来自2a01:dead:beef::3122a01:dead:beef::2ea这意味着,SNAT 这次不会改变源地址。

伙计们,你们能告诉我,我在这里做错了什么吗?

答案1

我搞错了这里的 SNAT 规则。正确的规则是

ip6tables -t nat -A POSTROUTING -s 2a01:230:2:6::312 -o eth0 -j SNAT --to-source 2a01:230:2:6::2ea

我将传出接口从 更改tun0eth0因为我想匹配传出到外部的数据包,而不是内部的数据包。

我仍然很困惑,这怎么能起作用呢,如果您知道如何做的话,请改进这个答案。

相关内容