Estou tentando fazer com que o Linux funcione em uma VPN (GRE-TAP). O engraçado é que ele só funciona quando eu tenho tcpdump
rodando em ambos os hosts, mas mais sobre isso depois ...
Existem duas máquinas, chamadas pxn1
e pxn2
. Eles estão conectados juntos usando um simples switch via eth1.
pxn1 has IP address 10.1.1.197
pxn2 has IP address 10.1.1.199
IPsec
Para obter uma conexão segura, todo o tráfego IP é criptografado usando o IPsec. Isso funciona , eu posso pingar entre as duas máquinas sem nenhum problema e tcpdump
mostra apenas pacotes criptografados.
GRE-TAP
Um GRE-TAP ( túneis A interface de quadros Ethernet sobre IP ) é então configurada em ambas as direções, porque eu precisarei de uma interface de rede virtual mais adiante:
ip link add vpn_gre_pxn2 type gretap local 10.1.1.197 remote 10.1.1.199 dev eth1
ifconfig mostra:
vpn_gre_pxn2 Link encap:Ethernet HWaddr 1a:73:32:7f:36:5f
inet6 addr: fe80::1873:32ff:fe7f:365f/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1462 Metric:1
RX packets:19 errors:0 dropped:0 overruns:0 frame:0
TX packets:26 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:1294 (1.2 KiB) TX bytes:1916 (1.8 KiB)
Isso está em pxn1
. No outro host, a mesma interface é configurada na outra direção.
Ponte
É configurada uma ponte que atualmente usa apenas o dispositivo GRE-TAP.
Eu preciso da bridge porque mais tarde eu quero adicionar mais máquinas (meu plano é unir todos os túneis GRE juntos). O resultado final deve se tornar uma rede de malha VPN (com uma interface GRE-TAP dedicada para cada combinação host-host). Mas desde então, estou apenas fazendo um primeiro teste com duas máquinas, a ponte é, naturalmente, um pouco inútil, mas ainda assim importante para o teste em si.
brctl addbr vpn_br
brctl addif vpn_br vpn_gre_pxn2
A ponte funciona porque quando eu ativo a interface vpn_br
e configuro alguns endereços IP (apenas para testar a bridge), os PINGs ICMP funcionam perfeitamente.
vpn_br Link encap:Ethernet HWaddr 02:00:0a:01:01:c5
UP BROADCAST RUNNING SLAVE MULTICAST MTU:1462 Metric:1
RX packets:11 errors:0 dropped:0 overruns:0 frame:0
TX packets:6 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:448 (448.0 B) TX bytes:468 (468.0 B)
Colagem
Uma interface Linux Bonding está agora configurada. Mais uma vez, uma vez que esta é apenas uma primeira prova de teste de conceito, adicionarei apenas um único escravo ao vínculo.
Mais tarde, haverá também uma NIC Gbit real separada com um switch dedicado que funcionará como o escravo primário (com a VPN sendo apenas um backup), mas por enquanto a interface de ligação usará somente a VPN.
modprobe bonding mode=1 miimon=1000
ifconfig bond0 hw ether 02:00:0a:01:01:c5 # some dummy MAC
ifconfig bond0 up
ifconfig bond0 mtu 1462
ifenslave bond0 vpn_br # as said, only a single slive at the moment
ifconfig bond0 172.16.1.2/24 up
O outro host é configurado como 172.16.1.1/24 com HWaddr 02: 00: 0a: 01: 01: c7.
Isso resulta em uma interface de ligação em funcionamento teoricamente:
bond0 Link encap:Ethernet HWaddr 02:00:0a:01:01:c5
inet addr:172.16.1.2 Bcast:172.16.1.255 Mask:255.255.255.0
inet6 addr: fe80::aff:fe01:1c5/64 Scope:Link
UP BROADCAST RUNNING MASTER MULTICAST MTU:1462 Metric:1
RX packets:11 errors:0 dropped:0 overruns:0 frame:0
TX packets:6 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:448 (448.0 B) TX bytes:468 (468.0 B)
O status também parece bom para mim:
# cat /proc/net/bonding/bond0
Ethernet Channel Bonding Driver: v3.6.0 (September 26, 2009)
Bonding Mode: fault-tolerance (active-backup)
Primary Slave: None
Currently Active Slave: vpn_br
MII Status: up
MII Polling Interval (ms): 1000
Up Delay (ms): 0
Down Delay (ms): 0
Slave Interface: vpn_br
MII Status: up
Speed: Unknown
Duplex: Unknown
Link Failure Count: 0
Permanent HW addr: 1a:73:32:7f:36:5f
Slave queue ID: 0
... assim como a tabela de roteamento:
# ip route show
192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.2
172.16.1.0/24 dev bond0 proto kernel scope link src 172.16.1.2
10.1.1.0/24 dev eth1 proto kernel scope link src 10.1.1.197
default via 10.1.1.11 dev eth1
NB: eht0
é uma NIC ativa separada (Ethernet cross cable), mas isso não deve importar IMHO.
O problema
A configuração parece boa para mim, no entanto, o PING não funciona (isso foi executado em pxn1
):
# ping 172.16.1.1
PING 172.16.1.1 (172.16.1.1) 56(84) bytes of data.
From 172.16.1.2 icmp_seq=2 Destination Host Unreachable
From 172.16.1.2 icmp_seq=3 Destination Host Unreachable
From 172.16.1.2 icmp_seq=4 Destination Host Unreachable
Durante o ping, tcpdump
na outra máquina ( pxn2
) diz:
# tcpdump -n -i bond0
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on bond0, link-type EN10MB (Ethernet), capture size 65535 bytes
17:45:13.013791 ARP, Request who-has 172.16.1.1 tell 172.16.1.2, length 28
17:45:13.013835 ARP, Reply 172.16.1.1 is-at 02:00:0a:01:01:c7, length 28
17:45:14.013858 ARP, Request who-has 172.16.1.1 tell 172.16.1.2, length 28
17:45:14.013875 ARP, Reply 172.16.1.1 is-at 02:00:0a:01:01:c7, length 28
17:45:15.013870 ARP, Request who-has 172.16.1.1 tell 172.16.1.2, length 28
17:45:15.013888 ARP, Reply 172.16.1.1 is-at 02:00:0a:01:01:c7, length 28
No entanto, quando também executo tcpdump
on pxn1
em um terminal separado, de repente recebo minhas respostas de ICMP!
...
From 172.16.1.2 icmp_seq=19 Destination Host Unreachable
From 172.16.1.2 icmp_seq=20 Destination Host Unreachable
64 bytes from 172.16.1.1: icmp_req=32 ttl=64 time=0.965 ms
64 bytes from 172.16.1.1: icmp_req=33 ttl=64 time=0.731 ms
64 bytes from 172.16.1.1: icmp_req=34 ttl=64 time=1.00 ms
64 bytes from 172.16.1.1: icmp_req=35 ttl=64 time=0.776 ms
64 bytes from 172.16.1.1: icmp_req=36 ttl=64 time=1.00 ms
Isso só funciona enquanto ambas as máquinas tiverem tcpdump
em execução. Eu posso iniciar / parar tcpdump
e consistentemente ver apenas respostas enquanto o programa está sendo executado em ambas as máquinas ao mesmo tempo. Não importa em qual máquina eu tentei.
Este é um bug do kernel ou (mais provável) tem algum problema na minha configuração?
É normal que a interface bridge e bonding mostrem o mesmo endereço MAC? Eu só configuro manualmente para a interface de ligação, que aparentemente muda também a ponte ..
FYI, visão geral da configuração:
Atualizar
Eu recebo uma configuração de trabalho quando configuro a interface da bridge em modo promíscuo ( ifconfig vpn_br promisc
). Não tenho certeza se isso é normalmente necessário. OTOH eu não acho que tem quaisquer desvantagens ...
BTW, existe um Relatório de erros RedHat similar, mas definindo bond0
down / up não não ajuda no meu caso ..