Configurando br0, sem VPN

Configurando br0, sem VPN

Estou tentando forçar todo o tráfego de um convidado (Windows ou Linux) a passar pela VPN do host (Linux). Para garantir que um convidado não tenha acesso à Internet fora da VPN, estabeleço a conexão no sistema host, o que cria uma nova interface tun0. O túnel VPN funciona bem no host.

Configurando br0, sem VPN

Para obter internet sem VPN no convidado, eu crio um dispositivo bridge br0e anexei enp7s0a ele. Dessa forma, a internet funciona no hóspede.

ip link add name br0 type bridge
ip link set br0 up
ip link set enp7s0 master br0

No host, um vnet5dispositivo foi adicionado e conectado em ponte br0. Mas, ao mesmo tempo, fazer ping do host para um controle remoto não funciona mais.

## On the Host
sudo ip a
# ...
# 14: vnet5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br0 state UNKNOWN group default qlen 1000
# link/ether ab:ab:ab:ab:ab:ab brd ff:ff:ff:ff:ff:ff
# inet6 fe80::fc54:ff:fe92:5aa9/64 scope link
# valid_lft forever preferred_lft forever
ping www.google.com
# ping: www.google.com: Temporary failure in name resolution
ping 8.8.8.8
# From 192.168.1.100 icmp_seq=1 Destination Host Unreachable

Então eu inicio a VM virt-managere verifico a conexão. O hóspede tem internet:

## On the Guest
ip a
# 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
# ...
# 2: enp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
#     link/ether 52:54:00:92:5a:a9 brd ff:ff:ff:ff:ff:ff
#     inet 192.168.1.221/24 brd 192.168.1.255 scope global dynamic noprefixroute enp1s0
#        valid_lft 67432sec preferred_lft 67432sec
ping www.google.ch
# PING www.google.ch (172.217.168.35) 56(84) bytes of data.
# 64 bytes from zrh04s14-in-f3.1e100.net (172.217.168.35): icmp_seq=1 ttl=117 time=2.47 ms

Acho que, em vez de definir, ip link set enp7s0 master br0também poderia criar regras de roteamento entre br0e enp7s0.

Com VPN e a tun0interface

Quando estabeleço uma conexão VPN, tun0é criada uma interface que não pode ser atribuída a uma ponte. Portanto, eu precisaria criar regras de roteamento de qualquer maneira. Então acho que a situação é semelhante ao caso acima. Primeiro, removo enp7s0novamente do br0.

ip link set enp7s0 nomaster
sudo openvpn my_vpn_tcp.ovpn
# ...
# Initialization Sequence Completed
sudo ip a
# ...
# 3: enp7s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
# link/ether ab:ab:ab:ab:ab:ab brd ff:ff:ff:ff:ff:ff permaddr ab:ab:ab:ab:ab:ab
# inet 192.168.1.100/24 brd 192.168.1.255 scope global dynamic noprefixroute enp7s0
# valid_lft 82702sec preferred_lft 82702sec
# ...
# 10: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 500
# link/none
# inet 10.7.7.5/24 scope global tun0
# valid_lft forever preferred_lft forever
# ...
# 12: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
# link/ether 72:eb:06:e5:1e:5a brd ff:ff:ff:ff:ff:ff
# inet6 fe80::70eb:6ff:fee5:1e5a/64 scope link
# valid_lft forever preferred_lft forever

Sem mais nada, a conexão VPN é usada no host, o que está OK.

ping www.google.com
# PING www.google.com (172.217.168.3) 56(84) bytes of data.
# 64 bytes from lala.net (172.217.168.3): icmp_seq=1 ttl=117 time=9.64 ms
# ...
ping www.google.com -I tun0
# PING www.google.com (172.217.168.3) from 10.7.7.5 tun0: 56(84) bytes of data.
# 64 bytes from lala.net (172.217.168.3): icmp_seq=2 ttl=117 time=10.0 ms
# ...
ping www.google.com -I enp7s0
# PING www.google.com (172.217.168.3) from 192.168.1.100 enp7s0: 56(84) bytes of data.
# 64 bytes from lala.net (172.217.168.3): icmp_seq=1 ttl=115 time=4.59 ms
# ...

Mas como já foi dito, não posso tun0adicionar br0. E por conta disso, também o hóspede não tem internet.

sudo ip link set tun0 master br0
# RTNETLINK answers: Invalid argument

Procurei soluções, mas não encontrei algo que funcionasse ou meu caso é um pouco diferente, o que exigiria mais conhecimento sobre redes que não tenho. Por exemploesse(que não fez o trabalho) ouesse(isso não se encaixa exatamente no meu caso).

Responder1

Existem duas questões na mesma questão e, na verdade, não dependem uma da outra. Ainda responderei ambos.

Além disso, a noprefixrouteopção de endereço indica que parte da configuração da rede é gerenciada por alguma ferramenta adicional (como NetworkManager) para adicionar rotas. Esta resposta não tentará lidar com a integração em ferramentas de rede. Isso inclui lidar com a configuração do DHCP, que pode substituir as alterações posteriormente se não for reconfigurada corretamente. Muitas configurações desaparecem quando a interface é desativada ou excluída e precisam ser feitas novamente, portanto, é melhor fazer isso em vários ganchos de várias ferramentas de rede responsáveis.

Configurando br0, sem VPN

Uma interface definida como porta bridge perde sua participação no roteamento

Uma vez definida como porta de ponte, as rotas associadas à interface são ignoradas. Ainda podem existir efeitos colaterais prejudiciais ao deixar o endereço nele. Detalhes podem ser encontrados no blogIsolamento adequado de uma ponte Linux:

  1. entregue a moldura ao específico do dispositivomanipulador de recebimento, caso existam,
  2. entregar o quadro para um global ou específico do dispositivomanipulador de protocolo(por exemplo, IPv4, ARP, IPv6).

Para uma interface em ponte,o kernel configurou um manipulador de recebimento específico do dispositivo, br_handle_frame(). Esta função não permitirá nenhum processamento adicional no contexto da interface de entrada, exceto para quadros STP e LLDP, ou se o “brouting” estiver habilitado. Portanto,o manipuladores de protocolo nunca são executadosnesse caso.

O endereço IP definido em uma interface que se tornou uma porta de ponte deve ser movido para a própria interface da ponte especial ( br0: a própria ponte), que é a única capaz de participar do roteamento (existem outras opções, mas vamos simplificar). O mesmo se aplica às rotas relevantes.

Suponhamos que o gateway padrão do OP seja 192.168.1.1/24. Vamos reescrever isso para o primeiro caso:

ip link add name br0 up type bridge
ip link set dev enp7s0 master br0

ip address flush dev enp7s0
# previous command will also have removed all associated routes as a side effect
ip address add 192.168.1.100/24 dev br0
# previous command added the LAN route too as a side effect (no noprefixroute here)
ip route add default via 192.168.1.1

Com isso, tanto o host quanto a VM podem acessar a Internet.

Observe que para a parte VM, vnet5também é uma porta bridge e também não participa do roteamento. O host está apenas alternando quadros entre VM e roteador (192.168.1.1): nenhum roteamento envolvido.

Com VPN e a tun0interface

OpenVPN depende do driver TUN/TAP (fornecido no Linux pelo módulo do kerneltun). O motorista pode fornecer:

  • ou uma interface TAP de camada 2

    Ele se comporta como um dispositivo Ethernet e pode ser configurado como uma porta ponte Ethernet: criada vnet5pelo hipervisor VM.

  • ou uma interface TUN de camada 3

    Não inclui informações de quadro (endereço MAC Ethernet) nem lida com quadros, mas lida apenas com protocolos na camada 3 ou acima: IPv4 ou IPv6. Portanto, não pode ser definida como uma porta ponte Ethernet. Esses são os OPs tun0criados pelo OpenVPN no modo TUN.

OpenVPN também pode usar o modo TAP que pode ser conectado em ponte, mas isso requer reconfigurar o controle remotoservidorlado também e todo o layout da rede: o servidor remoto também faria parte da LAN 192.168.1.0/24. OP não parece ter controle sobre isso.

Então vamos considerar o que pode ser feito com a interface TUN do OP: isso será feito na camada 3: roteamento, e não na camada 2.

Reutilizando a configuração anterior somente para VMs confiáveis

Se o host não incluir firewall avançado, incluindo restrições de firewall e/ou alterações no caminho da ponte, ele não poderá forçar uma VM a se usar como gateway: uma VM com ponte como anteriormente pode simplesmente ignorar o host e manter 192.168.1.1 como gateway e fazer com que seu tráfego não utilize a interface do host tun0no final.

Se a VM puder ser confiável e reconfigurada, pode-se manter br0como acima, aplicar qualquer configuração OpenVPN baseada em br0(substituindo qualquer enp7s0referência por br0) e fazer isso quando a VM estiver em execução (com endereço 192.168.1.221) e a VPN estiver ativa:

  • no anfitrião

    Usandoroteamento baseado em política/fontepara selecionar um resultado de rota diferente para esta origem específica:

    ip rule add from 192.168.1.221 lookup 1000
    ip rule add iif tun0 lookup 1000
    ip route add 192.168.1.0/24 dev br0 table 1000
    ip route add default dev tun0 table 1000
    

    Definir como roteador:

    sysctl -w net.ipv4.ip_forward=1
    

E caso nenhuma regra NAT semelhante já lide com este caso:

  iptables -t nat -A POSTROUTING -s 192.168.1.221 -o tun0 -j MASQUERADE
  • na VM (Linux), use o host como gateway em vez do roteador do host

    ip route flush to default
    ip route add default via 192.168.1.100
    

Recomendado para VMs não confiáveis: não defina a interface principal do host como porta de ponte

Isso torna mais fácil impor o tráfego da VM tun0porque ela não terá visualização das partes da rede que não deve adulterar.

  • alterar as configurações da VM para usar sua própria rede IP

    Exemplo: 192.168.100.0/24 e um IP estático 192.168.100.2/24 (em vez do DHCP da rede do host), com gateway padrão 192.168.100.1. Em uma VM Linux:

    ip address add 192.168.100.2/24 dev enp1s0
    ip route add default via 192.168.100.1
    
  • No host, comece a partir da configuração inicial (sem ponte enp7s0)

    Pode-se até fazer com a ponte zero abaixo (ou seja: diretamente ip address add 192.168.100.1/24 dev vnet5sem vnet5definir como porta da ponte), maslibvirtpode tornar isso mais difícil.

    Basta ter uma bridge dedicada para VMs (aqui usando o endereço 192.168.100.1/24, embora normalmentelibvirtfornece uma ponte padrão virbr0com 192.168.122.1/24):

    ip link add name br0 up type bridge
    ip address add 192.168.100.1/24 dev br0
    ip link set dev vnet5 master br0
    

    E também usarroteamento de políticaalterar o comportamento do tráfego relacionado à(s) VM(s) para as duas interfaces envolvidas: br0e tun0. Como sempre, envolve algumas duplicações e alterações de rotas existentes em uma tabela de roteamento alternativa. Aqui tun0presume-se que atenda apenas o host e sua(s) VM(s). O objetivo final é: tudo o que vem do lado da VM é roteado para o lado do tun, tudo o que vem do lado do TUN é roteado para o lado da VM, desconsiderando qualquer lado não necessário.

    ip rule add iif br0 lookup 2000
    ip rule add iif tun0 lookup 2000
    ip route add 192.168.100.0/24 dev br0 table 2000
    ip route add default dev tun0 table 2000 # layer 3 interfaces don't need a gateway
    

    Nota: os pacotes recebidos tun0destinados ao host (ou seja: não roteados) já são tratados pelolocaltabela de roteamento e não precisa de nenhuma rota adicional na tabela 2000.

    Definir como roteador:

    sysctl -w net.ipv4.ip_forward=1
    

    Em seguida, complete com NAT, pois o servidor OpenVPN remoto não conhece 192.168.100.0/24:

    iptables -t nat -A POSTROUTING -s 192.168.100.0/24 -o tun0 -j MASQUERADE
    

Se a VM ainda conseguir acessar a LAN 192.168.1.0/24:

  • atualize novamente a tabela 2000 para acomodar isso

    Duplique a rota LAN da tabela principal para a tabela 2000:

    ip route add 192.168.1.0/24 dev enp7s0 table 2000
    
  • e adicione novamente uma regra MASQUERADE adequada

    ... já que a VM agora está em uma LAN diferente que outros sistemas não conhecem:

    iptables -t nat -A POSTROUTING -s 192.168.100.0/24 -o enp7s0 -j MASQUERADE
    

    (Algumas fatorações de regras do iptables poderiam ser feitas).

informação relacionada