问题总结
这是 Linux 计算机上的路由表:
root@computer:~# ip route show
default via 192.168.1.1 dev eth0
10.0.0.200 dev tun0 proto kernel scope link src 10.0.0.100
发送到该计算机上的 tun0 的目标 IP 为 1.2.3.5 的数据包不会从 eth0 发送出去。
我正在尝试构建的内容的详细描述
该项目的目标是为我的一台计算机(以及以后的更多计算机)提供一个公共 IP 地址。有两个要求:
- 这台计算机位于我无法控制的 NAT 后面。
- 我不希望 LAN 上的其他计算机需要通过(相对)较慢的互联网来访问它。
建筑学
电脑:
- A:互联网上的一台随机计算机想要连接到计算机 F。
- B:有一个额外的IP(1.2.3.5)我想通过E路由到F。
- C:不受我控制。
- D:我的路由器,它有一个静态路由:1.2.3.5 ---> 192.168.1.3
- E:与 B 建立 SSH TUN,将目的地为 1.2.3.5 的传入数据包路由到其默认网关 D。
- F:我希望所有其他计算机(无论是在我的 LAN 上还是在 Internet 上)都可以通过 1.2.4.5 访问的服务器
设置
在 B、E、F 上设置 IP 转发:
echo 1 > /proc/sys/net/ipv4/ip_forward
/etc/sysctl.conf 修改为E:
net.ipv4.conf.default.rp_filter=0
net.ipv4.conf.all.rp_filter=0
在 E 上建立 SSH TUN:
ssh -w 0:0 1.2.3.4
在 E 上启动 tun0 接口:
ip link set tun0 up
ip addr add 10.0.0.100/32 peer 10.0.0.200 dev tun0
在 B 上启动 tun0 接口:
ip link set tun0 up
ip addr add 10.0.0.200/32 peer 10.0.0.100 dev tun0
我现在可以使用以下命令成功从 B ping E:
ping 10.0.0.100
使用以下命令从 B 上的接口中删除 IP 1.2.3.5: ifconfig venet0:1 0.0.0.0
添加到 B 的路由: ip route add 1.2.3.5/32 via 10.0.0.100 dev tun0
使用以下命令将 IP 添加到 F 上的接口: ip addr add 1.2.3.5 dev eth0
测试
在A上运行以下命令测试发送数据包:
netcat -u 1.2.3.5 4444
在 E 上运行以下命令以查看是否收到数据包:
root@computer:~$ tcpdump -n -i tun0 port 4444
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on tun0, link-type RAW (Raw IP), capture size 262144 bytes
13:48:21.034003 IP 4.3.2.1.44312 > 1.2.3.5.4444: UDP, length 5
root@computer:~$ tcpdump -n -i eth0 port 4444
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
13:48:21.034061 IP 4.3.2.1.44312 > 1.2.3.5.4444: UDP, length 5
在E上运行以下命令:
root@computer:~# netcat -u 1.2.3.5 4444
test
在F上同时运行以下命令:
root@computer:~# nc -ul 4444
test
问题
我面临的问题是其中一台计算机 (E) 正在接收某个 IP (1.2.3.5) 的 IP 数据包,但没有将它们转发到其默认网关。
我相信我缺少的是 E 上的一条命令,该命令会将 tun0 接口上的传入数据包路由到 eth0 接口上的默认网关。
有谁知道我可能缺少什么命令?
答案1
路由问题已通过 Celada 的建议禁用来解决反向路径过滤通过修改文件/etc/sysctl.conf
net.ipv4.conf.default.rp_filter=0
net.ipv4.conf.all.rp_filter=0
尽管我现在意识到,为了完成此设置,我还需要通过 E 和 B 返回数据包的路由,以避免我的 ISP 进行上游反向路径过滤。