O roteamento baseado em política OpenVPN não está funcionando corretamente

0

Estou tentando configurar um cliente OpenVPN no ArchLinux com o PrivateInternetAccess. Por padrão, o PIA envia rotas de forma que o tráfego all passe pela VPN. Eu só quero que alguns aplicativos usem a VPN.

Para fazer isso, estou usando o "roteamento baseado em política". Eu criei uma nova tabela de roteamento chamada "vpn" e selecionarei seletivamente os usuários para essa tabela de roteamento.

Após esses comandos, o usuário "media" será roteado para a tabela de roteamento "vpn":

$ echo 100 vpn >> /etc/iproute2/rt_tables
$ iptables -t mangle -I OUTPUT -m owner --uid-owner media -j MARK --set-mark 0x1
$ ip rule add fwmark 0x1 table vpn

Eu também modifiquei a configuração do meu cliente OpenVPN para que minhas tabelas de roteamento sejam preenchidas corretamente:

$ cat /etc/openvpn/client.conf
    client
    dev tun
    proto udp
    remote us-newyorkcity.privateinternetaccess.com 1194
    resolv-retry infinite
    nobind
    persist-key
    persist-tun
    ca /etc/openvpn/ca.crt
    tls-client
    remote-cert-tls server
    auth-user-pass /etc/openvpn/login.conf
    comp-lzo
    verb 1
    reneg-sec 0
    crl-verify /etc/openvpn/crl.pem

    # This will override PIA so that traffic will route through our normal gateway
    route 0.0.0.0 192.0.0.0 net_gateway
    route 64.0.0.0 192.0.0.0 net_gateway
    route 128.0.0.0 192.0.0.0 net_gateway
    route 192.0.0.0 192.0.0.0 net_gateway

    # Calling these scripts will add the PIA routes to the vpn table
    script-security 2
    up /etc/openvpn/up.sh
    down /etc/openvpn/down.sh

$ cat /etc/openvpn/up.sh
    #!/bin/sh
    ip route add table vpn default via $ifconfig_remote

$ cat /etc/openvpn/down.sh
    #!/bin/sh
    ip route flush table vpn

Aqui estão minhas tabelas de roteamento depois de executar openvpn /etc/openvpn/client.conf :

$ ip route show table main
    0.0.0.0/2 via 192.168.1.1 dev eth0
    0.0.0.0/1 via 10.197.1.5 dev tun0
    default via 192.168.1.1 dev eth0  src 192.168.1.124  metric 202
    10.197.1.1 via 10.197.1.5 dev tun0
    10.197.1.5 dev tun0  proto kernel  scope link  src 10.197.1.6
    64.0.0.0/2 via 192.168.1.1 dev eth0
    128.0.0.0/2 via 192.168.1.1 dev eth0
    128.0.0.0/1 via 10.197.1.5 dev tun0
    192.0.0.0/2 via 192.168.1.1 dev eth0
    192.168.1.0/24 dev eth0  proto kernel  scope link  src 192.168.1.124  metric 202
    209.95.50.86 via 192.168.1.1 dev eth0

$ ip route show table vpn
    default via 10.197.1.5 dev tun0

As coisas são executadas normalmente como um usuário que NÃO é roteado para a tabela "vpn":

$ whoami
    jordan

$ ping -c 2 8.8.8.8
    PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
    64 bytes from 8.8.8.8: icmp_seq=1 ttl=46 time=38.9 ms
    64 bytes from 8.8.8.8: icmp_seq=2 ttl=46 time=39.0 ms

    --- 8.8.8.8 ping statistics ---
    2 packets transmitted, 2 received, 0% packet loss, time 1001ms
    rtt min/avg/max/mdev = 38.952/38.999/39.047/0.203 ms

No entanto, as coisas estão falhando para um usuário que é roteado para a tabela "vpn":

$ whoami
media

$ ping -c 2 8.8.8.8
    PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.

    --- 8.8.8.8 ping statistics ---
    2 packets transmitted, 0 received, 100% packet loss, time 999ms

Eu dei uma olhada em tcpdump -i tun0 para ver o que está acontecendo. Parece que o icmp request está saindo via tun0, mas não vai voltar ?

$ tcpdump -i tun0
    listening on tun0, link-type RAW (Raw IP), capture size 262144 bytes
    15:37:30.134399 IP keep > google-public-dns-a.google.com: ICMP echo request, id 10256, seq 1, length 64
    15:37:31.143217 IP keep > google-public-dns-a.google.com: ICMP echo request, id 10256, seq 2, length 64

Pensamentos? : (

==== EDIT # 1 ====

Como uma verificação de integridade, se enviarmos todo tráfego através da VPN (removendo as linhas "route xxxx 192.0.0.0 net_gateway" em /etc/openvpn/client.conf), obtemos icmp respostas muito bem:

$ tcpdump -i tun0
    listening on tun0, link-type RAW (Raw IP), capture size 262144 bytes
    16:26:54.401732 IP keep > google-public-dns-a.google.com: ICMP echo request, id 10480, seq 1, length 64
    16:26:54.483122 IP google-public-dns-a.google.com > keep: ICMP echo reply, id 10480, seq 1, length 64
    16:26:55.403465 IP keep > google-public-dns-a.google.com: ICMP echo request, id 10480, seq 2, length 64
    16:26:55.485068 IP google-public-dns-a.google.com > keep: ICMP echo reply, id 10480, seq 2, length 64

==== EDIT # 2 ====

Seguindo o conselho da MariusMatutiae, tentei usar o --route-noexec flag para definir manualmente as rotas em /etc/openvpn/up.sh . Também desabilitamos a filtragem de caminho inverso em /etc/openvpn/up.sh e reativamos em /etc/openvpn/down.sh :

$ cat /etc/openvpn/up.sh
    #!/bin/sh
    ip route add table vpn 0.0.0.0/1 via $ifconfig_remote
    ip route add table vpn 128.0.0.0/1 via $ifconfig_remote
    ip route add table vpn $route_network_1 via $ifconfig_remote
    ip route add table vpn $trusted_ip via $route_net_gateway

    ip route add table vpn $ifconfig_remote dev tun0 proto kernel src $ifconfig_local
    ip route add table vpn 192.168.1.0/24 dev eth0 proto kernel src 192.168.1.124 metric 202

    ip route del table main $ifconfig_remote

    # Disable reverse path filtering
    for f in /proc/sys/net/ipv4/conf/*/rp_filter; do
            echo 0 > $f;
    done

$ cat /etc/openvpn/down.sh
    #!/bin/sh
    ip route flush table vpn

    # Re-enable reverse path filtering
    for f in /proc/sys/net/ipv4/conf/*/rp_filter; do
            echo 1 > $f;
    done

Depois, minhas tabelas de roteamento são assim:

$ ip route show table main
    default via 192.168.1.1 dev eth0  src 192.168.1.124  metric 202
    192.168.1.0/24 dev eth0  proto kernel  scope link  src 192.168.1.124  metric 202

$ ip route show table vpn
    0.0.0.0/1 via 10.173.1.5 dev tun0
    10.173.1.1 via 10.173.1.5 dev tun0
    10.173.1.5 dev tun0  proto kernel  scope link  src 10.173.1.6
    128.0.0.0/1 via 10.173.1.5 dev tun0
    192.168.1.0/24 dev eth0  proto kernel  scope link  src 192.168.1.124  metric 202
    209.95.50.133 via 192.168.1.1 dev eth0

No entanto, a "mídia" do usuário ainda não consegue ping 8.8.8.8 . tcpdump -i tun0 ainda relata que nenhuma resposta está voltando: (

    
por user1161657 06.04.2016 / 00:39

2 respostas

1

Você particionou incorretamente suas rotas através de suas duas tabelas de roteamento. As seguintes rotas, que aparecem na tabela main , pertencem à tabela vpn :

0.0.0.0/1 via 10.197.1.5 dev tun0
128.0.0.0/1 via 10.197.1.5 dev tun0
10.197.1.1 via 10.197.1.5 dev tun0     
10.197.1.5 dev tun0  proto kernel  scope link  src 10.197.1.6
209.95.50.86 via 192.168.1.1 dev eth0

A rota a seguir pertence a ambas as tabelas:

192.168.1.0/24 dev eth0  proto kernel  scope link  src 192.168.1.124  metric 202

A razão para isto é que: as primeiras quatro regras envolvem a interface tun0 , o NIC virtual criado pelo OpenVPN, que claramente não tem nada a ver com a tabela main . A quinta regra ensina ao seu kernel como chegar ao seu servidor PIA. A última regra permite que ambas as tabelas tenham acesso a computadores locais, como impressoras, NAS e assim por diante.

Quanto a como configurá-lo automaticamente, isso se torna um pouco complexo pelo fato de seu servidor OpenVPN poder atribuir a você um endereço IP tun0 que difere toda vez: como você não controla o servidor, você não pode configurar para atribuir à sua interface tun0 um endereço estático.

Então, o que você precisa fazer é aprender a usar, primeiro, a opção --route-no-exec . O Manual declara:

--route-no-exec

Don't add or remove routes automatically. Instead pass routes to --route-up script using environmental variables.

Depois, você deve aprender a usar as Variáveis Ambientais (há uma seção inteira no final do Manual acima), especialmente aquelas chamadas ifconfig-- something.

Além disso, você achará necessário desabilitar a filtragem de caminho reverso pelo kernel,

for f in /proc/sys/net/ipv4/conf/*/rp_filter; do echo 0 > $f; done

Eu colocaria esse comando em seu script up e o reverso

for f in /proc/sys/net/ipv4/conf/*/rp_filter; do echo 1 > $f; done

no seu script down . Isso é necessário porque você tem um gateway padrão na tabela principal, o que significa que, quando o kernel verifica se há algum spoofing, qualquer pacote any é sinalizado.

Alternativamente, e mais facilmente, você pode considerar mudar a função das duas tabelas: deixar o OpenVPN fazer automaticamente, configurar as rotas para a tabela de roteamento main e configurar uma nova tabela de roteamento chamada non-vpn , que tem sua configuração usual,

# ip route show
  default via 192.168.0.1 dev eth0  proto static 
  192.168.0.0/24 dev eth0  proto kernel  scope link  src 192.168.0.74  metric 1 

(ou algo assim) para os pacotes não correspondentes à MARK acima. Isso é muito mais fácil de configurar.

    
por 06.04.2016 / 07:43
0

Desisti de fazer o roteamento baseado em políticas funcionar. Em vez disso, acabei usando namespaces de rede para atingir meu objetivo. Um bom guia para começar pode ser encontrado aqui link

Agradecimentos especiais a MariusMatutiae por toda a ajuda!

    
por 07.04.2016 / 03:06