我通过路由器连接到互联网,并且想要将端口 3000 上的 UDP 数据包路由到 KVM 内的 VM。
┌──────────────────┐
│ router │
│ 54.0.0.1 (public)│
│ 192.168.0.1 │
└────────┬─────────┘
│
│
┌──────▼──────┐
│ pc │
│ 192.168.0.2 │
│ 10.0.0.1 │
│ ┌────────┐ │
│ │vm │ │
│ │10.0.0.2│ │
│ └────────┘ │
│ │
└─────────────┘
我已经在路由器上打开了端口 3000,并将所有 udp 数据包转发到 192.168.0.2:3000,然后从那里添加:
sudo iptables -t nat -A PREROUTING -d 192.168.0.2 -p UDP --dport 3000 -j DNAT --to 10.0.0.2:3000
然而,这并没有按预期工作,这意味着如果我运行:
# on VM
$ nc -l -u -p 3000
# from another machine
$ nc 54.0.0.1 3000 -u -v
我无法建立连接并交换数据。我最接近此工作的是处于output
以下阶段:
sudo iptables -t nat -A OUTPUT -d 192.168.0.2 -p UDP --dport 3000 -j DNAT --to 10.0.0.2:3000
然后如果nc 192.168.0.2 3000 -u -v
我当地的机器,我将连接到虚拟机。我已经可以看到tcpdump
来自外部网络的数据包确实被传送到了,192.168.0.2:3000
所以我不知道为什么这不能完全工作。(从互联网一直到虚拟机)
答案1
你是否启用 IPv4 转发在 PC 上?如果它停在那里,那可能就是原因。
另外,您不需要 iptables 中的 OUTPUT 链规则;PREROUTING 就足够了。
我基本上像这样复制了你的步骤:
┌──────────────────┐
│ Another Machine │
│ 192.168.146.129 │
└────────┬─────────┘
│
│
┌──────▼──────────┐
│ pc │
│ 192.168.146.132 │
│ 10.0.3.1 │
│ ┌──────────┐ │
│ │vm │ │
│ │10.0.3.100│ │
│ └──────────┘ │
│ │
└─────────────────┘
在虚拟机上:
# Start listener
nc -l -u -p 3000
在PC上:
# Add Port Forwarding rule
sudo iptables -t nat -A PREROUTING -d 192.168.146.132 -p udp --dport 3000 -j DNAT --to-destination 10.0.3.100:3000
# Enable IPv4 forwarding
sudo sysctl -w net.ipv4.ip_forward=1
# Monitor traffic
sudo tcpdump -nni any udp port 3000
在其他机器上:
# Connect
192.168.146.132 3000 -u -v
对我来说,这个效果很好:
nc 192.168.146.132 3000 -u -v
192.168.146.132: inverse host lookup failed: Unknown host
(UNKNOWN) [192.168.146.132] 3000 (?) open
^C