다음 토폴로지를 사용합니다.
HostA(virbr0: 192.168.122.1) -- TAP 인터페이스 -- (eth0: 192.168.122.85) gw (eth1: 192.168.3.51) --- (LAN: 192.168.3.0/24)
gw
: QEMU VM 게스트, 다른 QEMU VM 게스트에 대한 게이트웨이 역할을 하며 eth1
인터페이스를 통해 연결합니다. gw
인터페이스를 사용하여 Linux TAP 인터페이스를 통해 QEMU 호스트에 연결합니다 eth0
. TAB 인터페이스는 IP를 동적으로 할당합니다 eth0
.
hostA
: QEMU 가상 머신 호스트
root@hostA:~$ ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.16.254.134 netmask 255.255.255.0 broadcast 172.16.254.255
inet6 fe80::20c:29ff:fe25:1670 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:25:16:70 txqueuelen 1000 (Ethernet)
RX packets 18116 bytes 1361094 (1.3 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 14579 bytes 5334119 (5.3 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
gns3tap0-0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet6 fe80::50bd:d3ff:fe1a:e55 prefixlen 64 scopeid 0x20<link>
ether 52:bd:d3:1a:0e:55 txqueuelen 1000 (Ethernet)
RX packets 353 bytes 28543 (28.5 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 3348 bytes 183399 (183.3 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 662311 bytes 99203163 (99.2 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 662311 bytes 99203163 (99.2 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
virbr0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.122.1 netmask 255.255.255.0 broadcast 192.168.122.255
ether 52:54:00:62:0a:c5 txqueuelen 1000 (Ethernet)
RX packets 353 bytes 23601 (23.6 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 379 bytes 28629 (28.6 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
gw:~# ifconfig
eth0 Link encap:Ethernet HWaddr 0C:FE:27:0C:E4:00
inet addr:192.168.122.85 Bcast:192.168.122.255 Mask:255.255.255.0
inet6 addr: fe80::efe:27ff:fe0c:e400/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:379 errors:3150 dropped:0 overruns:0 frame:3150
TX packets:353 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:31851 (31.1 KiB) TX bytes:28543 (27.8 KiB)
eth1 Link encap:Ethernet HWaddr 0C:FE:27:0C:E4:01
inet addr:192.168.3.51 Bcast:0.0.0.0 Mask:255.255.255.0
inet6 addr: fe80::efe:27ff:fe0c:e401/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:302 errors:0 dropped:0 overruns:0 frame:0
TX packets:300 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:25796 (25.1 KiB) TX bytes:24782 (24.2 KiB)
gw:~# netstat -nr
Kernel IP routing table
Destination Gateway Genmask Flags MSS Window irtt Iface
0.0.0.0 192.168.122.1 0.0.0.0 UG 0 0 0 eth0
192.168.3.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1
192.168.122.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
목표는 내부 LAN의 호스트 A에서 가상 머신 192.168.3.0/24로의 연결 가능성입니다.
다음 라우팅 구성이 작동 중입니다.
root@hostA:~$ sudo route add -net 192.168.3.0 netmask 255.255.255.0 gw 192.168.122.85
root@hostA:~$ netstat -nr
Kernel IP routing table
Destination Gateway Genmask Flags MSS Window irtt Iface
0.0.0.0 172.16.254.2 0.0.0.0 UG 0 0 0 eth0
172.16.254.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0
192.168.3.0 192.168.122.85 255.255.255.0 UG 0 0 0 virbr0
192.168.122.0 0.0.0.0 255.255.255.0 U 0 0 0 virbr0
root@hostA:~$ ping 192.168.3.102
PING 192.168.3.102 (192.168.3.102) 56(84) bytes of data.
64 bytes from 192.168.3.102: icmp_seq=1 ttl=63 time=3.07 ms
^C
--- 192.168.3.102 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 3.071/3.071/3.071/0.000 ms
root@hostA:~$ ping 192.168.3.103
PING 192.168.3.103 (192.168.3.103) 56(84) bytes of data.
64 bytes from 192.168.3.103: icmp_seq=1 ttl=63 time=3.03 ms
64 bytes from 192.168.3.103: icmp_seq=2 ttl=63 time=2.99 ms
^C
--- 192.168.3.103 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1002ms
rtt min/avg/max/mdev = 2.997/3.014/3.032/0.057 ms
그러나 Linux TAP는 IP를 동적으로 할당하므로 eth0
라우팅이 필요하며 다음 라우터의 IP 주소를 다음 홉으로 사용하지 않고 대신 다음과 유사한 종료 인터페이스의 로컬 IP를 사용합니다.
root@hostA:~$ route add -net 192.168.0.0 netmask 255.255.0.0 gw 192.168.122.1 dev virbr0
root@hostA:~$ netstat -nr
Kernel IP routing table
Destination Gateway Genmask Flags MSS Window irtt Iface
0.0.0.0 172.16.254.2 0.0.0.0 UG 0 0 0 eth0
172.16.254.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0
192.168.0.0 192.168.122.1 255.255.0.0 UG 0 0 0 virbr0
192.168.122.0 0.0.0.0 255.255.255.0 U 0 0 0 virbr
root@hostA:~$ ping -c 1 192.168.122.85
PING 192.168.122.85 (192.168.122.85) 56(84) bytes of data.
64 bytes from 192.168.122.85: icmp_seq=1 ttl=64 time=0.585 ms
--- 192.168.122.85 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.585/0.585/0.585/0.000 ms
root@hostA:~$ ping -c 1 192.168.3.51
PING 192.168.3.51 (192.168.3.51) 56(84) bytes of data.
64 bytes from 192.168.3.51: icmp_seq=1 ttl=64 time=0.956 ms
--- 192.168.3.51 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.956/0.956/0.956/0.000 ms
root@hostA:~$ ping -c 1 192.168.3.102
PING 192.168.3.102 (192.168.3.102) 56(84) bytes of data.
From 192.168.122.1 icmp_seq=1 Destination Host Unreachable
--- 192.168.3.102 ping statistics ---
1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0ms
root@hostA:~$ ping -c 1 192.168.3.103
PING 192.168.3.103 (192.168.3.103) 56(84) bytes of data.
From 192.168.122.1 icmp_seq=1 Destination Host Unreachable
--- 192.168.3.103 ping statistics ---
1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0ms
그림에 표시된 것처럼 위의 라우팅 구성을 사용하면 hostA
인터페이스 eth1
에 연결할 수 있지만 내부 LAN(192.168.3.0/24)에 있는 다른 가상 머신에는 연결할 수 없습니다. 그러나 내부 LAN 호스트 자체는 호스트A에 도달할 수 있습니다.
iptables
구성은 다음 과 같습니다 .
root@hostA:~$ sudo iptables -nvL FORWARD
Chain FORWARD (policy ACCEPT 21 packets, 1624 bytes)
pkts bytes target prot opt in out source destination
197 15616 DOCKER-USER all -- * * 0.0.0.0/0 0.0.0.0/0
197 15616 DOCKER-ISOLATION-STAGE-1 all -- * * 0.0.0.0/0 0.0.0.0/0
0 0 ACCEPT all -- * docker0 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED
0 0 DOCKER all -- * docker0 0.0.0.0/0 0.0.0.0/0
0 0 ACCEPT all -- docker0 !docker0 0.0.0.0/0 0.0.0.0/0
0 0 ACCEPT all -- docker0 docker0 0.0.0.0/0 0.0.0.0/0
88 7346 ACCEPT all -- * virbr0 0.0.0.0/0 192.168.122.0/24 ctstate RELATED,ESTABLISHED
88 6646 ACCEPT all -- virbr0 * 192.168.122.0/24 0.0.0.0/0
0 0 ACCEPT all -- virbr0 virbr0 0.0.0.0/0 0.0.0.0/0
gw:~# iptables -nvL FORWARD
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all -- eth1 eth0 192.168.122.0/24 0.0.0.0/0 ctstate NEW
0 0 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED
gw:~# sysctl -a | grep ipv4.ip_forward
net.ipv4.ip_forward = 1
dns:~# ifconfig
eth0 Link encap:Ethernet HWaddr 0C:FE:27:0C:76:00
inet addr:192.168.3.103 Bcast:0.0.0.0 Mask:255.255.255.0
inet6 addr: fe80::efe:27ff:fe0c:7600/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:18638 errors:0 dropped:0 overruns:0 frame:0
TX packets:18634 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:1543312 (1.4 MiB) TX bytes:1705846 (1.6 MiB)
dns:~# netstat -nr
Kernel IP routing table
Destination Gateway Genmask Flags MSS Window irtt Iface
0.0.0.0 192.168.3.51 0.0.0.0 UG 0 0 0 eth0
192.168.3.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
질문:
구성에 뭔가 빠졌나요?
출구 인터페이스의 로컬 IP를 다음 홉 IP로 사용하는 작동하는 라우팅 항목을 구성하는 방법이 있습니까?
답변1
두세 가지 별도의 질문이 있습니다.
동적 게이트웨이 IP
이를 위해 라우팅 프로토콜을 사용하는 것은 과잉입니다(다른 이유로 이미 라우팅 프로토콜을 사용하고 있지 않는 한). gw/eth0 구성을 정적으로 변경해 보겠습니다. 이것이 가능하지 않은 경우 해당 네트워크에 대한 경로를 설정할 수 있는 권한을 얻을 수 gw
있는 사용자를 생성할 수 있습니다 . 새 IP를 얻을 때 마다 SSH를 통해 연결 하고 명령을 실행할 수 있습니다(아마도 를 통해 ).hostA
sudo
gw
hostA
ForcedCommand
GW에서 라우팅
에 경로가 (올바르게) 구성되지 않았습니다 gw
. net.ipv4.ip_forward = 0
( )을 통해 활성화 man sysctl
하고 방화벽에서 해당 연결을 허용해야 합니다 iptables -nvL FORWARD
. 을 참조하세요.
192.168.3.0의 가상 머신 경로
연결하는 가상 머신은 기본 게이트웨이로 구성되어야 gw/eth1
합니다 . gw
그렇지 않은 경우에는 해당 네트워크에서 ( )를 수행 gw
해야 합니다 .SNAT
iptables