我有三台电脑,名字分别是:laptop、vds 和 home;
vds 是 openvpn 服务器;home 是 openvpn 客户端。我有一个 ipv6 网络 2a01:dead:beef::/64
vds 有地址2a01:dead:beef::311
hometun0
有地址2a01:dead:beef::312
laptoptun0
有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"
所以家里的tun0
IPv6 路由变成了默认路由:
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::312
,2a01: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
我将传出接口从 更改tun0
为eth0
因为我想匹配传出到外部的数据包,而不是内部的数据包。
我仍然很困惑,这怎么能起作用呢,如果您知道如何做的话,请改进这个答案。