Linha de comando KVM nat

Linha de comando KVM nat

Qual é a maneira correta de configurar a rede NAT entre KVM vm e host?

KVM vm:

Nenhum firewall 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

Hospedar:

:~$ ip r

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......

O host não consegue executar ping em 10.0.2.2

Nenhum firewall ativado

Testado

$ 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

O NAT pode funcionar sem virsh?

O NAT pode ser corrigido apenas na linha de comando?

Atualizar:

$ 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

que funciona para conectar o escravo eth0 ao kvm - o vm pode executar ping em outros computadores na rede. mas não a resposta do anfitrião @Tom Yan combinada comarchlinux-Network_bridgecriados acima comandos que podem executar ping em outros IPs da rede

Então tentei alterar a conexão da ponte de trabalho para permitir que o host e o kvm conversassem.

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

mas kvm$ping 10.0.2.1

Destination Host Unreachable

host $ ping 10.0.2.2

(just hangs)

Prefira a linha de comando para testar a resiliência do esqueleto do processo/sistema em comparação com muitos scripts que podem representar mais vulnerabilidade a falhas. - a linha de comando funciona ou não e os erros são mais facilmente rastreados, isolados e reproduzíveis. Dependendo do tipo de Linux, certos scripts/partes de scripts (como aqueles incorporados nas soluções alternativas xml oferecidas) podem funcionar ou não. Se a ponte com o kvm puder ser reproduzida em qualquer versão do Linux seguindo os comandos acima... então parece possível que o kvm NAT também possa ser alcançado usando comandos cli - apenas para esclarecer o ponto desta postagem, as etapas do cli para NAT kvm serão mais padronizado, então preferível.

geralmente a resposta de @NikitaKipriyanov era o caminho correto, esta era a resposta, mas exigia um ajuste no comando

$ sudo kvm -m 3G -hdb /dev/sde -net nic -net user,hostfwd=tcp::1810-:22

usando o comando tweak vm pode se comunicar com a internet como padrão e também se comunicar com o host via ssh. crédito a @NikitaKipriyanov e @cnst pelo ajustehttps://stackoverflow.com/a/54120040

O usuário precisará fazer ssh usando a porta 1810 usando o endereço localhost

$ ssh p@localhost -p 1810

Responder1

A ideia comum do NAT é que vocênão vemosendereços traduzidos. Você não tem rotas para eles. Eles não existem para você. Você vê apenas os endereços para os quais eles estão traduzidos.

O caso do QEMU não é nada diferente. Neste caso, seu host está "fora", sua VM está "dentro", então a VM nunca poderá ser acessada pelo endereço ao qual está atribuída. Você tem o endereço 10.0.2.2/24 da VM, mas quando chega à Internet, seus pacotes são traduzidos para 192.168.1.172pelo processo QEMU, então o host considera esses pacotes como criados pelo processo QEMU e os trata como quaisquer outros pacotes, digamos, de um navegador da Web executado localmente ou algo parecido.

Como acessar uma VM do host? Quando temos NAT, para alcançar hosts ocultos atrás dele, instalamosDNATregras. E novamente, o caso do QEMU não é diferente, você deve configurar algumas regras nele, e então você pode se comunicar com a VM a partir do host (ou de outros hosts, se desejar) enviando pacotes para portas selecionadas dohospedarendereço.

De acordo comDocumentação do QEMU, para configurar regras de DNAT em seu NAT de modo de usuário, você usa a hostfwdcláusula. Vamos introduzir o seguinte em sua linha de comando:

    -netdev user,id=usernet0,hostfwd=tcp::11111-:22 \
    -device virtio-net-pci,netdev=usernet0,mac=08:00:27:92:B0:51

Então, a porta tcp 11111 será ocupada pelo qemu-system-x86_64processo na minha máquina, e se você conectar aohost localporta 11111, a conexão será feita na porta 22 da VM.

A forma geral é hostfwd=hostip:hostport-guestip:guestport, mas se você omitir hostip, será localhost e, se omitir guestip, será o primeiro endereço "não gateway" dentro da rede convidada.

Notei que você foi mencionado virsh. Estás a correr libvirt? Então a pergunta é duplicada; Ver comentários.

Responder2

Você pode usar uma ponte sem escravizar nenhuma de suas interfaces Ethernet físicas no host da VM.

Digamos que optemos pela escolha da sub-rede 10.0.2.0/24(o que NÃO é necessário):

# ip l add natbr0 type bridge
# ip a add 10.0.2.1/24 dev natbr0

Em seguida, crie o seguinte arquivo:

$ echo 'allow natbr0' | sudo tee /etc/qemu/bridge.conf 
allow natbr0

Em seguida, inicie o qemu com, por exemplo, -nic bridge,br=natbr0ou -netdev bridge,br=natbr0,id=nb0 -device virtio-net,netdev=nb0, que conectará tapsua VM à ponte de maneira dinâmica (ou seja, a tapinterface será removida assim que a VM for desligada).

Você também precisará configurar o IP estático na VM:

# ip a add 10.0.2.2/24 dev ens3
# ip r add default via 10.0.2.1

A menos que você também configure um servidor DHCP (por exemplo, dnsmasq) no host. Não se esqueça de configurar o servidor DNS para usar também dentro da VM.

Observe que as VMs que fazem uso da mesma ponte podem se comunicar entre si, a menos que você bloqueie tal comunicação por algum meio (por exemplo, ebtables).

A defaultrota (e o servidor DNS a utilizar) só são necessários se quiser que a VM consiga chegar ao "exterior". Se você só precisa dele para se comunicar com o host da VM, você deve pular o segundo comando e parar de ler. (Bem, leia o P.S.)


Provavelmente seria melhor configurar, por exemplo, dnsmasq no host para ser um encaminhador de DNS se você não quiser usar um servidor DNS "público" específico na VM, embora usar DNAT para encaminhar solicitações de DNS, por exemplo, 192.168.1.1deva funcionar para os básicos .

Então você precisará ativar o encaminhamento de IP:

# sysctl -w net.ipv4.ip_forward=1
net.ipv4.ip_forward = 1

Se você quiser evitar o encaminhamento de IP de/para determinada interface de rede (por exemplo tun0) por motivos de segurança, você precisará configurar um firewall.Por exemplo:

# iptables -A FORWARD -i tun0 -j DROP
# iptables -A FORWARD -o tun0 -j DROP

Como você possui rotas de túnel (VPN) que praticamente substituem a defaultrota, o tráfego da VM para a Internet também irá para o túnel (a menos que você tenha adicionado as regras de exemplo acima). Se você quiser que o tráfego passe, por exemplo, pelo seu roteador, você precisará de roteamento de política. Por exemplo:

# 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

Você também pode impedir que suas VMs alcancem seus hosts LAN:

# iptables -A FORWARD -i natbr0 -d 192.168.1.0/24 -j DROP

Faça exceções (observe o -I) se for redirecionar solicitações de DNS para o seu roteador:

# 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

Por fim, configure o iptables para executar SNAT dinamicamente (conforme a interface de saída) para sua sub-rede VM:

# iptables -t nat -A POSTROUTING -s 10.0.2.0/24 -j MASQUERADE

Observe que isso NÃO se destina e não impedirá exatamente que certos tráfegos "externos" (seus hosts físicos da LAN ou a Internet; o host da VM não conta) possam alcançar suas VMs. Apenas interrompe a comunicação como efeito colateral quando o endereço de origem dos tráfegos de resposta das VMs é alterado antes de serem encaminhados. Para um isolamento adequado, você precisará de regras apropriadas (adicionais) na FORWARDcadeia. Considere ter uma configuração "com estado" se você precisar.

Além disso, você pode redirecionar solicitações de DNS para o host das VMs para o seu roteador:

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

O que mais ou menos permitirá que você use 10.0.2.1como servidor DNS na VM.


PS Todas as manipulações acima (exceto a criação de /write to /etc/qemu/bridge.conf) são voláteis, ou seja, elas desaparecerão assim que você reiniciar (a menos que sua distro faça algo bobo). Não vou me aprofundar em como você pode torná-los persistentes, já que existem diferentes formas/abordagens e isso pode ser específico da distribuição.

informação relacionada