我有一台具有一个外部 IP 地址的服务器(例如1.2.3.4
)。在该服务器上,我使用 libvirt 运行虚拟机。现在我想port 1234
从外部通过 ssh()访问主机上的虚拟服务器。
eth0
在我的主机系统上,我有一个连接到我的外部 IP()的网络接口1.2.3.4
。
virbr0
我的虚拟机通过使用 ip调用的 nat 接口连接到主机192.168.122.235
。
由于我需要转发端口,因此我执行以下操作iptable
iptables -t nat -A PREROUTING -p tcp -i eth0 --dport 1234 -j DNAT --to-destination 192.168.122.235:1234
iptables -A FORWARD -p tcp -d 192.168.122.235 --dport 1234 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
对于基本网络,我还在UFW
主机上运行了以下允许port 1234
:
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), allow (routed)
New profiles: skip
To Action From
-- ------ ----
[SOMEOTHERPORTS]
1234/tcp ALLOW IN Anywhere
1234/tcp (v6) ALLOW IN Anywhere (v6)
我确保所有涉及的网络接口都允许转发:
user@someserver ~ # cat /proc/sys/net/ipv4/conf/virbr0/forwarding
1
user@someserver ~ # cat /proc/sys/net/ipv4/conf/eth0/forwarding
1
当我尝试从外部网络通过 ssh 连接到服务器时,1.2.3.4
我得到:
ssh: connect to host 1.2.3.4 port 1234: Connection refused
我检查了来自主机的 ssh 连接,它运行正常。
- 我在这里做错了什么?
- UFW 会干扰 iptables 吗?
- 我怎样才能让它工作?
- 有没有更简单的方法使用 libvirt / virt-manager 进行端口转发?(我试过这个: http://secomputing.co.uk/2012/02/21/Forwarding-ports-to-KVM-clients/ 这也不起作用,因为当更改为 / 时 XML 无效,它确实验证了,但如果我将其放在“网络”上则不起作用)
答案1
我几乎遇到了同样的问题。我想将端口 22 从主机转发到同样运行 KVM 的 VM,并使用 NAT 网络。
我找到了这个帖子:https://ubuntuforums.org/showthread.php?t=2261173&p=13210545#post13210545
其中有答案给我。
总结
192.168.1.161 是我的内部网络上的服务器 IP。192.168.122.2 是我的主机上的虚拟机 IP。
iptables -t nat -I PREROUTING -p tcp -d 192.168.1.161 --dport 22 -j DNAT --to-destination 192.168.122.2:22
iptables -I FORWARD -m state -d 192.168.122.2/24 --state NEW,RELATED,ESTABLISHED -j ACCEPT
免责声明。我不知道这到底是做什么的。它看起来和我找到的许多其他答案一样,只是一些参数标签略有不同。
答案2
我们应该考虑一些事情。
我在这里做错了什么?
让我们看看当前的 iptables 配置,然后我们可以检查它。
UFW 会干扰 iptables 吗?
UFW 是 iptables 的命令行前端,但它缺少 iptables 的许多功能。通过 iptables 配置,我们可以了解 UFW 根据您输入的命令执行了哪些操作。但是,您不应该在同一台计算机上同时使用这两者创建规则。这会带来麻烦。如果您要在 UFW 中输入命令,那没问题,但应该禁用 iptables 脚本。如果您要在 iptables 中输入命令,则应删除 UFW。
我怎样才能让它工作?
尝试这个。
iptables -t nat -I PREROUTING -p tcp -i eth0 --dport 1234 -j DNAT --to 192.168.122.235:1234
iptables -A FORWARD -i eth0 -o vibr0 -p tcp --dport 1234 -j ACCEPT
但请记住,客户机使用适配器的 NAT 连接到主机。因此这可能行不通。
您真正应该考虑的是将适配器类型从 NAT 更改为桥接。
答案3
我认为你也应该使用桥接连接:
尝试找出您的网络名称:
virsh net-edit <network name>
您可以在 Virt Manager 中看到的网络名称。通常为默认名称:
virsh net-edit default
从 NAT 更改为桥接(也是您在 Virt Manager 中找到的桥接名称)
<network>
<name>default</name>
<uuid>cc45a671-e8d8-4149-a6a5-8d5547551a58</uuid>
<forward mode='route'/>
<bridge name='virbr0' stp='on' delay='0'/>
<mac address='AA:CC:DD:86:53:54'/>
<ip address='192.168.122.1' netmask='255.255.255.0'>
<dhcp>
<range start='192.168.122.2' end='192.168.122.254'/>
</dhcp>
</ip>
</network>
评论:
在示例中,我们使用 DHCP 为虚拟机命名。您也可以进行静态设置
如果你使用 ifconfig 你应该得到:
virbr0 链路封装:以太网 硬件地址 AA:VV:CC:86:53:54
inet 地址:192.168.122.1 广播:192.168.122.255 掩码:255.255.255.0 上行广播运行多播 MTU:1500 度量:1 RX 数据包:127 故障:0 发送:0 概述:0 窗口:0 TX 数据包:44 故障:0 发送:0 概述:0 中继:0 阻塞:0 发送间隔:0 RX 字节:13032 (13.0 KB) TX 字节:4707 (4.7 KB)基本上你应该使用端口 22 进行 ssh
尝试使用:
sudo iptables -t nat -A POSTROUTING -s 192.168.122.235 -j SNAT --to-source 1.2.3.4
这样您就可以确定问题是否出在端口上。实际上,您可以使用 Gufw 关闭虚拟机上的端口。
答案4
这些就是我的转发规则,相当不错。
-A POSTROUTING -s 192.168.122.0/24 -d 224.0.0.0/24 -j RETURN
-A POSTROUTING -s 192.168.122.0/24 -d 255.255.255.255/32 -j RETURN
-A POSTROUTING -s 192.168.122.0/24 ! -d 192.168.122.0/24 -p tcp -j MASQUERADE --to-ports 1024-65535
-A POSTROUTING -s 192.168.122.0/24 ! -d 192.168.122.0/24 -p udp -j MASQUERADE --to-ports 1024-65535
-A POSTROUTING -s 192.168.122.0/24 ! -d 192.168.122.0/24 -j MASQUERADE
-A POSTROUTING -s 192.168.122.0/24 -o br1 -j MASQUERADE
-A INPUT -s 192.168.122.0/24 -j ACCEPT
-A FORWARD -d 192.168.122.0/24 -o virbr0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -s 192.168.122.0/24 -i virbr0 -j ACCEPT
-A FORWARD -i virbr0 -o virbr0 -j ACCEPT
-A FORWARD -o virbr0 -j REJECT --reject-with icmp-port-unreachable
-A FORWARD -i virbr0 -j REJECT --reject-with icmp-port-unreachable
-A FORWARD -i virbr0 -j ACCEPT
-A FORWARD -i br1 -o virbr0 -j ACCEPT