¿Cuál es la forma correcta de configurar la red NAT entre KVM vm y el host?
Máquina virtual KVM:
No hay cortafuegos instalado
$ sudo arp-scan -r 5 -t 1000 --interface=eth0 --localnet
10.0.2.2 52:55:0a:00:02:02 locally administered
10.0.2.3 52:55:0a:00:02:03 locally administered
$ ip r
default via 10.0.2.2 dev eth0 proto dhcp metric 100
10.0.2.0/24 dev eth0 proto kernel scope link src 10.0.2.15 metric 100
ifconfig
eth0: inet 10.0.2.15 netmask 255.255.255.0 broacast 10.0.2.255
ether 52:54:00:12:34:56
lo: inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1
Anfitrión:
:~$ipr
0.0.0.0/1 via 10.211.1.10 dev tun0
default via 192.168.1.1 dev wlan0 proto dhcp metric 600
10.21xxxxxxxx dev tun0 proto kernel scope link src 10.21xxxxx
xxxxxxxxxxxx dev wlan0
128.0.0.0/1 via 10.211.1.10 dev tun0
192.168.1.0/24 dev wlan0 proto kernel scope link src 192.168.1.172 metric 600
192.168.4.0/22 dev eth0 proto kernel scope link src 192.168.4.8 metric 100
:~$ ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.0.2.3 netmask 255.0.0.0 broadcast 10.255.255.255
inet6 fe80::76c8:79b4:88d4:7f5c prefixlen 64 scopeid 0x20<link>
ether ec:8e:b5:71:33:6e txqueuelen 1000 (Ethernet)
RX packets 1700 bytes 194730 (190.1 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 2862 bytes 246108 (240.3 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
device interrupt 16 memory 0xe1000000-e1020000
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 13251 bytes 7933624 (7.5 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 13251 bytes 7933624 (7.5 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
tun0: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST> mtu 1500
inet 10.211.1.69 netmask 255.255.255.255 destination 10.211.1.70
inet6 fe80::a920:941c:ffa8:5579 prefixlen 64 scopeid 0x20<link>
unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 txqueuelen 100 (UNSPEC)
RX packets 4348 bytes 2242726 (2.1 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 3823 bytes 404190 (394.7 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
wlan0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.1.172 netmask 255.255.255.0 broadcast 192.168.1.255
inet6 fe80::651b:5014:7929:9ba3 prefixlen 64 scopeid 0x20<link>
ether d8:55:a3:d5:d1:30 txqueuelen 1000 (Ethernet)
RX packets 114455 bytes 117950099 (112.4 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 67169 bytes 14855011 (14.1 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
~$ sudo arp-scan -r 5 -t 1000 --localnet
just hangs......
El host no puede hacer ping 10.0.2.2
No hay firewall habilitado
Intentó
$ sudo ip route add default via 10.0.2.0
$ sudo ip route add default via 10.0.2.2
$ sudo ip route add default via 10.0.2.0/24
¿Puede NAT funcionar sin virsh?
¿Se puede arreglar NAT solo desde la línea de comando?
Actualizar:
$ sudo ip link add natbr0 type bridge
$ sudo ip link set dev natbr0 up
$ sudo ip link set dev eth0 up
$ sudo ip link set dev eth0 master natbr0
eso funciona para unir el esclavo eth0 a kvm: vm puede hacer ping a otras computadoras en la red. pero no la respuesta del anfitrión @Tom Yan combinada conarchlinux-Network_bridgeComandos creados anteriormente que pueden hacer ping a otras IP de red.
Así que intenté cambiar la conexión del puente en funcionamiento para permitir que el host y kvm hablen.
Goal: host$ ping kvm
$ sudo ip link add natbr0 type bridge
$ sudo ip link set dev natbr0 up
$ sudo ip a add 10.0.2.1/24 dev natbr0
$ sudo kvm -m 3G -hdb /dev/sde -nic bridge,br=natbr0
kvm$ sudo ip link add natbr0 type bridge
kvm$ sudo ip a add 10.0.2.2
kvm$ sudo ip link set dev natbr0 up
kvm can ping it self
$ping 10.0.2.2
PING 10.0.2.2 (10.0.2.2) 56(84) bytes of data
64 bytes from 10.0.2.2: icmp_seq=1 ttl=64 time=0.027 ms
pero kvm$ping 10.0.2.1
Destination Host Unreachable
anfitrión $ ping 10.0.2.2
(just hangs)
Prefiera la línea de comando para probar la resistencia del proceso/sistema básico frente a muchos scripts que pueden presentar una mayor vulnerabilidad a fallas. - La línea de comando funciona o no y los errores se rastrean, aíslan y reproducen más fácilmente. Dependiendo del tipo de Linux, ciertos scripts/partes de scripts (como los incorporados en las soluciones alternativas xml ofrecidas) pueden funcionar o no. Si el puente con kvm se puede reproducir en cualquier versión de Linux siguiendo los comandos anteriores... entonces parece posible que kvm NAT también se pueda lograr usando los comandos cli; solo para aclarar el punto de esta publicación, los pasos de cli para NAT kvm serán más estandarizado, por lo que es preferible.
en general, la respuesta de @NikitaKipriyanov fue el camino correcto, esta fue la respuesta pero requirió un ajuste para ordenar
$ sudo kvm -m 3G -hdb /dev/sde -net nic -net usuario,hostfwd=tcp::1810-:22
El uso del comando tweak vm puede comunicarse con Internet de forma predeterminada y también comunicarse con el host a través de ssh. crédito a @NikitaKipriyanov y @cnst por el ajustehttps://stackoverflow.com/a/54120040
El usuario deberá realizar ssh utilizando el puerto 1810 utilizando la dirección de host local
$ ssh p@localhost -p 1810
Respuesta1
La idea común de NAT es que ustedno veodirecciones traducidas. No tienes rutas hacia ellos. No existen para ti. Solo verá las direcciones a las que estén traducidas.
El caso QEMU no es diferente. En este caso, su host está "afuera", su VM está "adentro", por lo que nunca se podrá acceder a la VM mediante la dirección a la que está asignada. Tiene la dirección 10.0.2.2/24 de la VM, pero cuando llega a Internet, sus paquetes se traducen a 192.168.1.172por el proceso QEMU, por lo que el host considera esos paquetes creados por el proceso QEMU y los trata como cualquier otro paquete, por ejemplo, desde un navegador web que se ejecuta localmente o algo así.
¿Cómo acceder a una VM desde el host? Cuando tenemos NAT, para llegar a los hosts ocultos detrás de él, instalamosADNTnormas. Y nuevamente, el caso de QEMU no es diferente, debe configurar algunas reglas en él y luego puede comunicarse con la VM desde el host (o desde otros hosts, si lo desea) enviando paquetes a puertos seleccionados delanfitriónDIRECCIÓN.
De acuerdo con laDocumentación QEMU, para configurar las reglas DNAT en su NAT en modo de usuario, utilice la hostfwd
cláusula. Introduzcamos lo siguiente en su línea de comando:
-netdev user,id=usernet0,hostfwd=tcp::11111-:22 \
-device virtio-net-pci,netdev=usernet0,mac=08:00:27:92:B0:51
Entonces, el puerto tcp 11111 estará ocupado por el qemu-system-x86_64
proceso en mi máquina, y si se conecta alservidor localpuerto 11111, la conexión se realizará al puerto 22 de la VM.
La forma general es hostfwd=hostip:hostport-guestip:guestport
, pero si omite hostip
, será localhost, y si omite guestip
, será la primera dirección "no de puerta de enlace" dentro de la red de invitados.
Noté que te mencionan virsh
. Estas corriendo libvirt
? Entonces la pregunta está duplicada; ver comentarios.
Respuesta2
Puede utilizar un puente sin esclavizar ninguna de sus interfaces Ethernet físicas en el host de VM.
Digamos que nos quedamos con la elección de la subred 10.0.2.0/24
(que NO es necesaria):
# ip l add natbr0 type bridge
# ip a add 10.0.2.1/24 dev natbr0
Luego cree el siguiente archivo:
$ echo 'allow natbr0' | sudo tee /etc/qemu/bridge.conf
allow natbr0
Luego inicie qemu con, por ejemplo, -nic bridge,br=natbr0
o -netdev bridge,br=natbr0,id=nb0 -device virtio-net,netdev=nb0
, que conectará tap
su VM al puente de forma dinámica (es decir, la tap
interfaz se eliminará una vez que se apague la VM).
También necesitarás configurar la IP estática en la VM:
# ip a add 10.0.2.2/24 dev ens3
# ip r add default via 10.0.2.1
A menos que también configure un servidor DHCP (con, por ejemplo, dnsmasq) en el host. No olvide configurar el servidor DNS para usarlo también dentro de la VM.
Tenga en cuenta que las máquinas virtuales que utilizan el mismo puente pueden comunicarse entre sí a menos que bloquee dicha comunicación por algún medio (por ejemplo, ebtables).
La default
ruta (y el servidor DNS a utilizar) sólo son necesarios si desea que la VM pueda llegar al "exterior". Si solo lo necesita para poder comunicarse con el host de VM, debe omitir el segundo comando y dejar de leer. (Bueno, lee el P.S.
)
Probablemente sería mejor configurar, por ejemplo, dnsmasq en el host para que sea un reenviador de DNS si no desea utilizar un servidor DNS "público" específico en la máquina virtual, aunque usar DNAT para reenviar solicitudes de DNS, por ejemplo, 192.168.1.1
debería funcionar para las básicas. .
Luego deberás habilitar el reenvío de IP:
# sysctl -w net.ipv4.ip_forward=1
net.ipv4.ip_forward = 1
Si desea evitar el reenvío de IP desde/hacia cierta interfaz de red (p.ej tun0
) por razones de seguridad, necesitarás configurar un firewall.Por ejemplo:
# iptables -A FORWARD -i tun0 -j DROP
# iptables -A FORWARD -o tun0 -j DROP
Dado que tiene rutas de túnel (VPN) que prácticamente anulan la default
ruta, el tráfico de la máquina virtual a Internet también ingresará al túnel (a menos que haya agregado las reglas de ejemplo anteriores). Si desea que el tráfico vaya, por ejemplo, a través de su enrutador, necesitará una política de enrutamiento. Por ejemplo:
# ip ru add iif natbr0 lookup table 123
# ip r add 192.168.1.1 dev wlan0 table 123 # probably optional
# ip r add default via 192.168.1.1 table 123
También puede evitar que sus máquinas virtuales puedan llegar a sus hosts LAN:
# iptables -A FORWARD -i natbr0 -d 192.168.1.0/24 -j DROP
Haga excepciones (tenga en cuenta -I
) si va a redirigir las solicitudes de DNS a su enrutador:
# iptables -I FORWARD -i natbr0 -d 192.168.1.1 -p tcp --dport 53 -j ACCEPT
# iptables -I FORWARD -i natbr0 -d 192.168.1.1 -p udp --dport 53 -j ACCEPT
Finalmente, configure iptables para realizar SNAT dinámicamente (según la interfaz de salida) para su subred de VM:
# iptables -t nat -A POSTROUTING -s 10.0.2.0/24 -j MASQUERADE
Tenga en cuenta que esto NO tiene como objetivo ni impedirá exactamente que ciertos tráficos desde el "exterior" (sus hosts LAN físicos o Internet; el host de VM no cuenta) puedan llegar a sus VM. Simplemente se interrumpe la comunicación como efecto secundario cuando la dirección de origen de los tráficos de respuesta de las máquinas virtuales se cambia antes de reenviarse. Para un aislamiento adecuado, necesitará reglas apropiadas (adicionales) en la FORWARD
cadena. Considere tener una configuración "con estado" allí si es necesario.
Además, puede redirigir las solicitudes de DNS al host desde las máquinas virtuales a su enrutador:
iptables -t nat -A PREROUTING -d 10.0.2.1 -p udp --dport 53 -j DNAT --to-destination 192.168.1.1
iptables -t nat -A PREROUTING -d 10.0.2.1 -p tcp --dport 53 -j DNAT --to-destination 192.168.1.1
Lo que más o menos le permitirá usarlo 10.0.2.1
como servidor DNS en la VM.
PD: Todas las manipulaciones anteriores (excepto la creación de / write to /etc/qemu/bridge.conf
) son volátiles, es decir, desaparecerán una vez que reinicies (a menos que tu distribución haga algo tonto). No voy a profundizar en cómo puedes hacerlos persistentes, ya que hay diferentes formas/enfoques y puede ser específico de la distribución.