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 br0
e anexei enp7s0
a 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 vnet5
dispositivo 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-manager
e 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 br0
também poderia criar regras de roteamento entre br0
e enp7s0
.
Com VPN e a tun0
interface
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 enp7s0
novamente 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 tun0
adicionar 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 noprefixroute
opçã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:
- entregue a moldura ao específico do dispositivomanipulador de recebimento, caso existam,
- 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, vnet5
també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 tun0
interface
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
vnet5
pelo 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
tun0
criados 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 tun0
no final.
Se a VM puder ser confiável e reconfigurada, pode-se manter br0
como acima, aplicar qualquer configuração OpenVPN baseada em br0
(substituindo qualquer enp7s0
referê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 tun0
porque 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 vnet5
semvnet5
definir 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
virbr0
com 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:
br0
etun0
. Como sempre, envolve algumas duplicações e alterações de rotas existentes em uma tabela de roteamento alternativa. Aquitun0
presume-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
tun0
destinados 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).