ste*_*eh7 39 ubuntu nat port-forwarding libvirt kvm-virtualization
使用 NAT 时,如何将运行 libvirt/KVM 的服务器上的端口转发到 VM 上的指定端口?
例如,主机的公共 IP 为 1.2.3.4。我想将端口 80 转发到 10.0.0.1,将端口 22 转发到 10.0.0.2。
我假设我需要添加 iptables 规则,但我不确定在哪里合适以及应该指定什么。
iptables -L 的输出
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT udp -- anywhere anywhere udp dpt:domain
ACCEPT tcp -- anywhere anywhere tcp dpt:domain
ACCEPT udp -- anywhere anywhere udp dpt:bootps
ACCEPT tcp -- anywhere anywhere tcp dpt:bootps
Chain FORWARD (policy ACCEPT)
target prot opt source destination
ACCEPT all -- anywhere 10.0.0.0/24 state RELATED,ESTABLISHED
ACCEPT all -- 10.0.0.0/24 anywhere
ACCEPT all -- anywhere anywhere
REJECT all -- anywhere anywhere reject-with icmp-port-unreachable
REJECT all -- anywhere anywhere reject-with icmp-port-unreachable
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Run Code Online (Sandbox Code Playgroud)
ifconfig 的输出
eth0 Link encap:Ethernet HWaddr 00:1b:fc:46:73:b9
inet addr:192.168.1.14 Bcast:192.168.1.255 Mask:255.255.255.0
inet6 addr: fe80::21b:fcff:fe46:73b9/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:201 errors:0 dropped:0 overruns:0 frame:0
TX packets:85 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:31161 (31.1 KB) TX bytes:12090 (12.0 KB)
Interrupt:17
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
virbr1 Link encap:Ethernet HWaddr ca:70:d1:77:b2:48
inet addr:10.0.0.1 Bcast:10.0.0.255 Mask:255.255.255.0
inet6 addr: fe80::c870:d1ff:fe77:b248/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:6 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:468 (468.0 B)
Run Code Online (Sandbox Code Playgroud)
我正在使用 Ubuntu 10.04。
Isa*_*and 42
用于 Ubuntu 的 libvirt 的最新稳定版本是 0.7.5 版,它没有一些较新的功能(即脚本挂钩和网络过滤器),这些功能使自动网络配置更容易。也就是说,这里是如何在 Ubuntu 10.04 Lucid Lynx 上为 libvirt 0.7.5 启用端口转发。
这些 iptables 规则应该可以解决问题:
iptables -t nat -I PREROUTING -p tcp -d 1.2.3.4 --dport 80 -j DNAT --to-destination 10.0.0.1:80
iptables -t nat -I PREROUTING -p tcp -d 1.2.3.4 --dport 22 -j DNAT --to-destination 10.0.0.2:22
iptables -I FORWARD -m state -d 10.0.0.0/24 --state NEW,RELATED,ESTABLISHED -j ACCEPT
Run Code Online (Sandbox Code Playgroud)
默认的 KVM NAT 配置提供了一个类似于我上面给出的第三条规则,但它省略了 NEW 状态,这对于接受传入连接至关重要。
如果您编写启动脚本来添加这些规则并且您不小心,libvirt 0.7.5 会通过插入自己的规则来覆盖它们。因此,为了确保在启动时正确应用这些规则,您需要在插入规则之前确保 libvirt 已初始化。
将以下行添加到 /etc/rc.local 行之前exit 0:
(
# Make sure the libvirt has started and has initialized its network.
while [ `ps -e | grep -c libvirtd` -lt 1 ]; do
sleep 1
done
sleep 10
# Set up custom iptables rules.
iptables -t nat -I PREROUTING -p tcp -d 1.2.3.4 --dport 80 -j DNAT --to-destination 10.0.0.1:80
iptables -t nat -I PREROUTING -p tcp -d 1.2.3.4 --dport 22 -j DNAT --to-destination 10.0.0.2:22
iptables -I FORWARD -m state -d 10.0.0.0/24 --state NEW,RELATED,ESTABLISHED -j ACCEPT
) &
Run Code Online (Sandbox Code Playgroud)
在sleep 10上面的是一个黑客,以确保libvirt的守护进程有机会之前,我们添加自己的初始化它的iptables规则。我等不及他们为 Ubuntu 发布 libvirt 0.8.3 版。
Ada*_*ers 19
当来宾使用用户模式网络时,有一种方法可以即时设置端口重定向,我在这里写了博客:
http://blog.adamspiers.org/2012/01/23/port-redirection-from-kvm-host-to-guest/
你可以在那里看到细节,但为了方便起见,这是我想出的解决方案:
virsh qemu-monitor-command --hmp sles11 'hostfwd_add ::2222-:22'
Run Code Online (Sandbox Code Playgroud)
这种单行比其他答案容易得多,但仅适用于某些场景(用户模式网络堆栈)。
一种更“官方”[1] 的方法是创建一个钩子脚本,如 libvirt 网站所述:
http://wiki.libvirt.org/page/Networking#Forwarding_Incoming_Connections
...基本上这个脚本将在 KVM 来宾启动时被调用。脚本本身将添加适当的 iptable 规则(类似于上面 Isaac Sutherland 的回答),并正确添加了“新”连接状态。请注意,您必须使用正确的主机和端口值修改脚本。
[1] 尽管 libvirt 文档本身说这是一种黑客行为,但请看图
| 归档时间: |
|
| 查看次数: |
78793 次 |
| 最近记录: |