我目前在具有桥接网络的专用服务器上安装了几个 KVM 客户机(这有效),并且我可以通过 ifconfig(在客户机中)成功 ping 我分配的外部 IP。
然而,由于我只有 5 个公共 ipv4 ip 地址,因此我想像这样转发端口服务:
hostip:端口 -> kvm_guest:端口
更新
我发现 KVM 带有“默认” NAT 接口,因此将虚拟 NIC 添加到 Guest virsh 配置中,然后在 Guest 中对其进行配置,它具有以下 IP 地址:
192.168.122.112
我可以成功 ping 192.168.122.112 并从 KVM 主机访问 192.168.122.112 上的所有端口,因此我尝试像这样进行端口转发:
iptables -t nat -I PREROUTING -p tcp --dport 5222 -j DNAT --to-destination 192.168.122.112:2521
iptables -I FORWARD -m state -d 192.168.122.0/24 --state NEW,RELATED,ESTABLISHED -j ACCEPT
telnet KVM_HOST_IP 5222
只是坚持“尝试”
telnet 192.168.122.112 2521
作品
[root@node1 ~]# tcpdump port 5222
tcpdump: WARNING: eth0: no IPv4 address assigned
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
23:43:47.216181 IP 1.152.245.247.51183 > null.xmpp-client: Flags [S], seq 1183303931, win 65535, options [mss 1400,nop,wscale 3,nop,nop,TS val 445777813 ecr 0,sackOK,eol], length 0
23:43:48.315747 IP 1.152.245.247.51183 > null.xmpp-client: Flags [S], seq 1183303931, win 65535, options [mss 1400,nop,wscale 3,nop,nop,TS val 445778912 ecr 0,sackOK,eol], length 0
23:43:49.415606 IP 1.152.245.247.51183 > null.xmpp-client: Flags [S], seq 1183303931, win 65535, options [mss 1400,nop,wscale 3,nop,nop,TS val 445780010 ecr 0,sackOK,eol], length 0
过滤器接收到 7 个数据包,内核丢弃 0 个数据包
[root@node1 ~]# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
ACCEPT all -- anywhere 192.168.122.0/24 state NEW,RELATED,ESTABLISHED
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
[root@node1 ~]# iptables -nvL
Chain INPUT (policy ACCEPT 976 packets, 57008 bytes)
pkts bytes target prot opt in out source destination
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
11 640 ACCEPT all -- * * 0.0.0.0/0 192.168.122.0/24 state NEW,RELATED,ESTABLISHED
Chain OUTPUT (policy ACCEPT 673 packets, 40901 bytes)
pkts bytes target prot opt in out source destination
[root@node1 ~]# iptables -nvL -t nat
Chain PREROUTING (policy ACCEPT 549 packets, 34067 bytes)
pkts bytes target prot opt in out source destination
1 64 DNAT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:5222 to:192.168.122.112:2521
3 192 DNAT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:5222 to:192.168.122.112:2521
1 64 DNAT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:5225 to:192.168.122.112:2521
1 64 DNAT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:5222 to:192.168.122.112:2521
Chain POSTROUTING (policy ACCEPT 45 packets, 3169 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 44 packets, 3105 bytes)
pkts bytes target prot opt in out source destination
非常感谢您的帮助。
谢谢。
答案1
如果你以这种方式运行 kvm:
kvm -drive... -net nic -net tap ....
您将获得一个名为 (其中 X 是数字) 的新接口(在根主机中)tapX
。此接口通常通过位于/etc
(中的某个脚本默认配置/etc/kvm/kvm-ifup
,/etc/qemu-ifup
或者)您可以使用以下命令更改它们:kvm -drive... -net nic -net tap,script=mynatbrigescript
...
从那里,必须在每个点上配置这个接口:
ifconfig tapX 192.168.124.1/30
在客户端操作系统中:
ifconfig eth0 192.168.124.2/30
因此如果你点击(在根主机上),你将看到一个新的本地网络(假设你的公共 IP 是 1.2.3.4):
ip r s
1.2.3.4 dev eth0 ...
192.168.124.0/30 dev tapX proto kernel scope link src 192.168.124.1
从那里,您必须能够从根主机 ping 到 192.168.124.2。然后您可以DNAT
使用以下命令接收传入的 tcp 数据包:
iptables -t nat -A PREROUTING -i eth0 -d 192.168.122.31 --dport 5222 -j DNAT --to-destination 192.168.124.2:2521
SNAT
另一个方向的应答数据包为:
iptables -t nat -A POSTROUTING -o eth0 -s 192.168.124.2 -j SNAT --to-source 192.168.122.31
现在如果对于根节点,这个工作:
telnet 192.168.124.2 2521
然后从您的本地域,必须执行相同的操作:
telnet 1.2.3.4 5222
总之,你的根主机必须转发 IP 数据包,这可以通过以下方式验证:
cat /proc/sys/net/ipv4/ip_forward
1
或者
sysctl net.ipv4.conf.all.forwarding
net.ipv4.conf.all.forwarding = 1
可以通过以下方式设置:
echo 1 > /proc/sys/net/ipv4/ip_forward
或者
sysctl net.ipv4.conf.all.forwarding=1
答案2
首先,您的 DNAT 规则应更新为包含 KVM 主机的目标 IP。这样一来,即使从虚拟机到互联网(在端口 5222 上)的流量也会被 DNAT 处理。
iptables -t nat -F PREROUTING
iptables -t nat -A PREROUTING 1 -d KVM_HOST_IP -p tcp --dport 5222 -j DNAT --to-destination 192.168.122.112:2521
除此之外,您的 iptables 配置似乎没问题。我唯一能建议的是确保您的系统允许 IP 转发:
sysctl -w net.ipv4.ip_forward=1
如果运行上述命令解决了问题,您应该进行更新,/etc/sysctl.conf
以便在重启后保留它。
正如其他人所建议的,tcpdump -nn -i any port 5222 or port 2521
在 KVM 主机上运行可以提示数据包是否被转发。当您尝试时,telnet KVM_HOST_IP 5222
您应该会看到两个数据包。一个去往KVM_HOST_IP.5222
,另一个去往192.168.122.112.2521
。