![如何让 Linux VM 充当路由器](https://linux22.com/image/698482/%E5%A6%82%E4%BD%95%E8%AE%A9%20Linux%20VM%20%E5%85%85%E5%BD%93%E8%B7%AF%E7%94%B1%E5%99%A8.png)
我可以访问 openstack 帐户,在那里我可以创建 Linux 14.04 VM。我已经创建了两个网络接口。
通过路由器连接到互联网的“public-net”
不暴露在互联网上的“私人网络”
现在,我创建了一个名为“GATEWAY”的虚拟机,它连接到两个网络接口,并且在 eth0(10.70.0.6)和 eth1(10.90.0.1)上有两个互联网地址。eth0 暴露给互联网,eth1 用于私有网络。GATEWAY 虚拟机在 eth0 上有一个公共 IP 地址。
现在我在私有网络接口上创建了另一个虚拟机,名为“AGENT”。IP 地址为 10.90.0.7,并将默认网关设为 10.90.0.1(GATEWAY 虚拟机)
由于私有虚拟机未暴露给任何路由器,因此我们无法访问虚拟机的互联网。为了启用互联网访问,我在 GATEWAY 虚拟机上添加了一条 NAT 规则,如下所示:
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
这会将离开主机 GATEWAY 的所有互联网数据包的源地址更改为 GATEWAY 机器的地址。此外,在 GATEWAY 机器中设置 ipv4 数据包转发 = 1。
我可以从 GATEWAY 机器 ping 任何外部地址,但不能从内部代理机器 ping 任何外部地址。更不用说这台私有 AGENT 机器也无法访问互联网。
谁能帮我设置网关虚拟机,以便我可以将其用作路由器并为私人机器提供互联网访问。
这是我的路由表在 AGENT 机器中的样子:
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 10.90.0.1 0.0.0.0 UG 0 0 0 eth0
10.90.0.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
169.254.169.254 10.90.0.2 255.255.255.255 UGH 0 0 0 eth0
192.168.122.0 0.0.0.0 255.255.255.0 U 0 0 0 virbr0
这里我在两个接口上添加了用于 icmp ping 的 tcpdump。
eth1:连接私网的接口。
18:43:39.309771 IP host-10-90-0-7.openstacklocal > 172.217.3.14: ICMP echo request, id 2395, seq 1, length 64
18:43:39.355430 IP 172.217.3.14 > host-10-90-0-7.openstacklocal: ICMP echo reply, id 2395, seq 1, length 64
18:43:40.318637 IP host-10-90-0-7.openstacklocal > 172.217.3.14: ICMP echo request, id 2395, seq 2, length 64
18:43:40.364178 IP 172.217.3.14 > host-10-90-0-7.openstacklocal: ICMP echo reply, id 2395, seq 2, length 64
eth0:连接互联网的接口。
18:43:39.309796 IP host-10-70-0-6.openstacklocal > 172.217.3.14: ICMP echo request, id 2395, seq 1, length 64
18:43:39.355396 IP 172.217.3.14 > host-10-70-0-6.openstacklocal: ICMP echo reply, id 2395, seq 1, length 64
18:43:40.318679 IP host-10-70-0-6.openstacklocal > 172.217.3.14: ICMP echo request, id 2395, seq 2, length 64
18:43:40.364154 IP 172.217.3.14 > host-10-70-0-6.openstacklocal: ICMP echo reply, id 2395, seq 2, length 64
18:43:41.326618 IP host-10-70-0-6.openstacklocal > 172.217.3.14: ICMP echo request, id 2395, seq 3, length 64
在这里我可以看到,ping 响应来自外部地址,并且正在两个接口之间传输。尽管它被 eth1 接收到私有 VM,但它显示 ping 丢失了 100% 的数据包。
--------- ------------------- ------------- ------------
INTERNET |----| openstack-router| --10.70.0.1 --------10.70.0.6(NIC eth0) --| GATEWAY-VM |-- 10.90.0.1(NIC eth1) ---------10.90.0.7(NIC eth0) --| AGENT-VM |
--------- ------------------- ------------- ------------
答案1
您的防火墙规则是正确的。我采用“老式”方法 - 编写脚本,将其放入 /etc 并从 /etc/rc.local 调用它。无论您喜欢如何操作,以下方法对我来说都有效。
操作系统是通过 netinstall 的 Debian Jessie 64 位,在 taskel 时只选择了“标准系统实用程序”,在 Mint 桌面上的 VirtualBox 中运行。eth0 通过桥接接口和 DHCP 连接到我的 LAN。eth1 是我用于实验的 VM 计算机网络的 LAN 端。将防火墙脚本复制/粘贴到 /etc/rc.firewall,使其可执行,然后在 /etc/rc.local 中调用它。
#!/bin/bash
# copyright me, licensed to you freely
# a very simple set of iptables commands
# to allow forwarding between ethernet
# devices
# make sure forwarding is enabled in the kernel
echo 1 > /proc/sys/net/ipv4/ip_forward
# where is iptables located?
iptables=`which iptables`
# flush all existing rules
$iptables -F
# this is for NAT
# enable masquerading
/sbin/iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
# don't forward packets from off-lan to lan if
# they are a brand new connection being initiated
$iptables -A FORWARD -i eth0 -o eth1 -m state --state NEW -j REJECT
# if the packets come from off-lan but they are
# related to a connection that was established from
# within the lan, go ahead and forward them
$iptables -A FORWARD -i eth0 -o eth1 -m state --state RELATED,ESTABLISHED -j ACCEPT
# whatever traffic comes from the lan to go to
# the world allow thru
$iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT
当所有操作完成并运行后,你应该能够看到类似
root@router:~# ifconfig eth0
eth0 Link encap:Ethernet HWaddr 08:00:27:e6:43:df
inet addr:192.168.1.126 Bcast:192.168.1.255 Mask:255.255.255.0
inet6 addr: fe80::a00:27ff:fee6:43df/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:729 errors:0 dropped:0 overruns:0 frame:0
TX packets:382 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:61777 (60.3 KiB) TX bytes:46468 (45.3 KiB)
root@router:~# ifconfig eth1
eth1 Link encap:Ethernet HWaddr 08:00:27:af:50:e2
inet addr:10.99.99.1 Bcast:10.99.99.255 Mask:255.255.255.0
inet6 addr: fe80::a00:27ff:feaf:50e2/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:10 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:828 (828.0 B)
root@router:~# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.1.1 0.0.0.0 UG 0 0 0 eth0
10.99.99.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1
192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
root@router:~# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
REJECT all -- anywhere anywhere state NEW reject-with icmp-port-unreachable
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
ACCEPT all -- anywhere anywhere
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
root@router:~# cat /proc/sys/net/ipv4/ip_forward
1
root@router:~#