Roteamento da política do Linux - pacotes não retornam [fechados]

2

Estou tentando configurar o roteamento de políticas no meu servidor doméstico. Minha rede é assim:

Host routed          VPN gateway          Internet link
through VPN

192.168.0.35/24 ---> 192.168.0.5/24   ---> 192.168.0.1 DSL router
                     10.200.2.235/22  ....             .... 10.200.0.1  VPN server

O tráfego de 192.168.0.32/27 deve ser e é roteado através de VPN. Eu queria definir algumas políticas de roteamento para encaminhar algum tráfego de 192.168.0.5 através de VPN também - para início - do usuário com o uid 2000. O roteamento de política é feito usando iptables mark target e ip rule fwmark.

O problema:

Ao conectar usando o usuário 2000 do 192.168.0.5, o tcpdump mostra pacotes de saída, mas nada volta. Tráfego de 192.168.0.35 funciona bem (aqui eu não estou usando fwmark, mas a política src).

Aqui está a configuração do meu gateway de VPN:

# uname -a
Linux placebo 3.2.0-34-generic #53-Ubuntu SMP Thu Nov 15 10:49:02 UTC 2012 i686 i686 i386 GNU/Linux
# iptables -V
iptables v1.4.12
# ip -V
ip utility, iproute2-ss111117

Regras de IPtables (todas as políticas no filtro de tabela são ACCEPT)

# iptables -t mangle -nvL
Chain PREROUTING (policy ACCEPT 770K packets, 314M bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain INPUT (policy ACCEPT 767K packets, 312M bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain FORWARD (policy ACCEPT 5520 packets, 1920K bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 782K packets, 901M bytes)
 pkts bytes target     prot opt in     out     source               destination         
   74  4707 MARK       all  --  *      *       0.0.0.0/0            0.0.0.0/0            owner UID match 2000 MARK set 0x3

Chain POSTROUTING (policy ACCEPT 788K packets, 903M bytes)
 pkts bytes target     prot opt in     out     source               destination         


# iptables -t nat -nvL
Chain PREROUTING (policy ACCEPT 996 packets, 51172 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain INPUT (policy ACCEPT 7 packets, 432 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 1364 packets, 112K bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain POSTROUTING (policy ACCEPT 2302 packets, 160K bytes)
 pkts bytes target     prot opt in     out     source               destination         
  119  7588 MASQUERADE  all  --  *      vpn  0.0.0.0/0            0.0.0.0/0           

Roteamento:

# ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master lan state UNKNOWN qlen 1000
    link/ether 00:40:63:f9:c3:8f brd ff:ff:ff:ff:ff:ff
       valid_lft forever preferred_lft forever
3: lan: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP 
    link/ether 00:40:63:f9:c3:8f brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.5/24 brd 192.168.0.255 scope global lan
    inet6 fe80::240:63ff:fef9:c38f/64 scope link 
       valid_lft forever preferred_lft forever
4: vpn: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 100
    link/none 
    inet 10.200.2.235/22 brd 10.200.3.255 scope global vpn

# ip rule show
0:  from all lookup local 
32764:  from all fwmark 0x3 lookup VPN 
32765:  from 192.168.0.32/27 lookup VPN 
32766:  from all lookup main 
32767:  from all lookup default 

# ip route show table VPN
default via 10.200.0.1 dev vpn 
10.200.0.0/22 dev vpn  proto kernel  scope link  src 10.200.2.235 
192.168.0.0/24 dev lan  proto kernel  scope link  src 192.168.0.5

# ip route show
default via 192.168.0.1 dev lan  metric 100 
10.200.0.0/22 dev vpn  proto kernel  scope link  src 10.200.2.235 
192.168.0.0/24 dev lan  proto kernel  scope link  src 192.168.0.5 

TCP dump mostrando nenhum tráfego voltando quando a conexão é feita a partir do 192.168.0.5 usuário 2000

# tcpdump -i vpn
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on vpn, link-type RAW (Raw IP), capture size 65535 bytes
### Traffic from user 2000 on 192.168.0.5 ###
10:19:05.629985 IP 10.200.2.235.37291 > 10.100-78-194.akamai.com.http: Flags [S], seq 2868799562, win 14600, options [mss 1460,sackOK,TS val 6887764 ecr 0,nop,wscale 4], length 0
10:19:21.678001 IP 10.200.2.235.37291 > 10.100-78-194.akamai.com.http: Flags [S], seq 2868799562, win 14600, options [mss 1460,sackOK,TS val 6891776 ecr 0,nop,wscale 4], length 0
### Traffic from 192.168.0.35 ###
10:23:12.066174 IP 10.200.2.235.49247 > 10.100-78-194.akamai.com.http: Flags [S], seq 2294159276, win 65535, options [mss 1460,nop,wscale 4,nop,nop,TS val 557451322 ecr 0,sackOK,eol], length 0
10:23:12.265640 IP 10.100-78-194.akamai.com.http > 10.200.2.235.49247: Flags [S.], seq 2521908813, ack 2294159277, win 14480, options [mss 1367,sackOK,TS val 388565772 ecr 557451322,nop,wscale 1], length 0
10:23:12.276573 IP 10.200.2.235.49247 > 10.100-78-194.akamai.com.http: Flags [.], ack 1, win 8214, options [nop,nop,TS val 557451534 ecr 388565772], length 0
10:23:12.293030 IP 10.200.2.235.49247 > 10.100-78-194.akamai.com.http: Flags [P.], seq 1:480, ack 1, win 8214, options [nop,nop,TS val 557451552 ecr 388565772], length 479
10:23:12.574773 IP 10.100-78-194.akamai.com.http > 10.200.2.235.49247: Flags [.], ack 480, win 7776, options [nop,nop,TS val 388566081 ecr 557451552], length 0

UPDATE:

Eu fiz o que o @BatchyX sugeriu:

# iptables -t mangle -nvL
Chain PREROUTING (policy ACCEPT 3 packets, 179 bytes)
 pkts bytes target     prot opt in     out     source               destination         
  173 15993 CONNMARK   all  --  *      *       0.0.0.0/0            0.0.0.0/0            CONNMARK restore

Chain INPUT (policy ACCEPT 3 packets, 179 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain FORWARD (policy ACCEPT 1 packets, 67 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 1 packets, 60 bytes)
 pkts bytes target     prot opt in     out     source               destination         
   83  5247 MARK       all  --  *      *       0.0.0.0/0            0.0.0.0/0            owner UID match 2000 MARK set 0x3
  166 16053 CONNMARK   all  --  *      *       0.0.0.0/0            0.0.0.0/0            CONNMARK save

Chain POSTROUTING (policy ACCEPT 2 packets, 127 bytes)
 pkts bytes target     prot opt in     out     source               destination        

Além disso, desativei rp_filter para vpn

# echo 0 > /proc/sys/net/ipv4/conf/vpn/rp_filter

É melhor agora - estou recebendo pacotes SYN, ACK, mas o handshake não parece ser concluído. Também a soma de verificação dos pacotes de saída parece estar errada ...

Assim como um indício - é um cenário duplo de NAT - estou enviando pacotes NAT para VPN e os meus provedores de VPN NAT antes de enviá-los para o mundo.

# tcpdump -vvi vpn
tcpdump: listening on vpn, link-type RAW (Raw IP), capture size 65535 bytes
16:27:56.308479 IP (tos 0x10, ttl 64, id 49013, offset 0, flags [DF], proto TCP (6), length 60)
    10.200.2.235.58020 > wi-in-f104.1e100.net.http: Flags [S], cksum 0xff0b (incorrect -> 0x9790), seq 3580181028, win 14600, options [mss 1460,sackOK,TS val 12420433 ecr 0,nop,wscale 4], length 0
16:27:56.488691 IP (tos 0x0, ttl 46, id 44196, offset 0, flags [none], proto TCP (6), length 60)
    wi-in-f104.1e100.net.http > 10.200.2.235.58020: Flags [S.], cksum 0x12a2 (correct), seq 3226424033, ack 3580181029, win 14180, options [mss 1367,sackOK,TS val 1968045661 ecr 12420433,nop,wscale 6], length 0
16:27:56.799066 IP (tos 0x0, ttl 46, id 44197, offset 0, flags [none], proto TCP (6), length 60)
    wi-in-f104.1e100.net.http > 10.200.2.235.58020: Flags [S.], cksum 0x116c (correct), seq 3226424033, ack 3580181029, win 14180, options [mss 1367,sackOK,TS val 1968045971 ecr 12420433,nop,wscale 6], length 0

Atualização 2:

Como dito anteriormente, estou recebendo SYN, ACK agora, mas não consigo concluir o handshake com o pacote ACK. Então, se eu telnet da conta do usuário roteado eu recebo:

routed@placebo ~ # telnet 85.214.204.92 80
Trying 85.214.204.92...
telnet: Unable to connect to remote host: Connection timed out

E o tcpdump correspondente:

# tcpdump -vvi vpn
tcpdump: listening on vpn, link-type RAW (Raw IP), capture size 65535 bytes
20:33:51.940151 IP (tos 0x10, ttl 64, id 65041, offset 0, flags [DF], proto TCP (6), length 60)
    10.200.2.235.60547 > korn.vibfolks.eu.http: Flags [S], cksum 0x3014 (incorrect -> 0xe817), seq 151728396, win 14600, options [mss 1460,sackOK,TS val 16109341 ecr 0,nop,wscale 4], length 0
20:33:52.142823 IP (tos 0x0, ttl 50, id 0, offset 0, flags [DF], proto TCP (6), length 60)
    korn.vibfolks.eu.http > 10.200.2.235.60547: Flags [S.], cksum 0xf897 (correct), seq 986246473, ack 151728397, win 14480, options [mss 1367,sackOK,TS val 62899312 ecr 16109341,nop,wscale 6], length 0
20:33:52.937974 IP (tos 0x10, ttl 64, id 65042, offset 0, flags [DF], proto TCP (6), length 60)
    10.200.2.235.60547 > korn.vibfolks.eu.http: Flags [S], cksum 0x3014 (incorrect -> 0xe71d), seq 151728396, win 14600, options [mss 1460,sackOK,TS val 16109591 ecr 0,nop,wscale 4], length 0
20:33:53.140728 IP (tos 0x0, ttl 50, id 0, offset 0, flags [DF], proto TCP (6), length 60)
    korn.vibfolks.eu.http > 10.200.2.235.60547: Flags [S.], cksum 0xf79e (correct), seq 986246473, ack 151728397, win 14480, options [mss 1367,sackOK,TS val 62899561 ecr 16109341,nop,wscale 6], length 0
20:33:53.341764 IP (tos 0x0, ttl 50, id 0, offset 0, flags [DF], proto TCP (6), length 60)
    korn.vibfolks.eu.http > 10.200.2.235.60547: Flags [S.], cksum 0xf76b (correct), seq 986246473, ack 151728397, win 14480, options [mss 1367,sackOK,TS val 62899612 ecr 16109341,nop,wscale 6], length 0

Mas o usuário não roteado se conecta sem problemas:

nonrouted@placebo ~ $ telnet 85.214.204.92 80
Trying 85.214.204.92...
Connected to 85.214.204.92.
Escape character is '^]'.
^]

telnet> quit
Connection closed.

Atualização 3

Eu adicionei regras de registro nas tabelas mangle e nat para descobrir onde os pacotes se perdem.

Faço login no mangle antes e depois da marcação (com base no uid), in nat pós-outing (baseado no iface) no manger pré-outing (baseado no iface) e no mangle input e forward (baseado no restaurado mark)

Dec  9 01:00:55 placebo kernel: [80760.497780] [VPN mangle OUTPUT pre] IN= OUT=lan SRC=192.168.0.5 DST=85.214.204.137 LEN=60 TOS=0x10 PREC=0x00 TTL=64 ID=30041 DF PROTO=TCP SPT=48700 DPT=80 SEQ=3158481901 ACK=0 WINDOW=14600 RES=0x00 SYN URGP=0 OPT (020405B40402080A0132EEB40000000001030304) 
Dec  9 01:00:55 placebo kernel: [80760.497819] [VPN mangle OUTPUT post] IN= OUT=lan SRC=192.168.0.5 DST=85.214.204.137 LEN=60 TOS=0x10 PREC=0x00 TTL=64 ID=30041 DF PROTO=TCP SPT=48700 DPT=80 SEQ=3158481901 ACK=0 WINDOW=14600 RES=0x00 SYN URGP=0 OPT (020405B40402080A0132EEB40000000001030304) MARK=0x3 
Dec  9 01:00:55 placebo kernel: [80760.497875] [VPN nat POSTROUTING] IN= OUT=vpn SRC=192.168.0.5 DST=85.214.204.137 LEN=60 TOS=0x10 PREC=0x00 TTL=64 ID=30041 DF PROTO=TCP SPT=48700 DPT=80 SEQ=3158481901 ACK=0 WINDOW=14600 RES=0x00 SYN URGP=0 OPT (020405B40402080A0132EEB40000000001030304) MARK=0x3 
Dec  9 01:00:55 placebo kernel: [80760.695265] [VPN mangle PREROUTING pre] IN=vpn OUT= MAC= SRC=85.214.204.137 DST=10.200.2.235 LEN=60 TOS=0x00 PREC=0x00 TTL=50 ID=0 DF PROTO=TCP SPT=80 DPT=48700 SEQ=3597895441 ACK=3158481902 WINDOW=14480 RES=0x00 ACK SYN URGP=0 OPT (020405570402080A03FCE5720132EEB401030306) 
Dec  9 01:00:55 placebo kernel: [80760.695305] [VPN mangle PREROUTING post] IN=vpn OUT= MAC= SRC=85.214.204.137 DST=10.200.2.235 LEN=60 TOS=0x00 PREC=0x00 TTL=50 ID=0 DF PROTO=TCP SPT=80 DPT=48700 SEQ=3597895441 ACK=3158481902 WINDOW=14480 RES=0x00 ACK SYN URGP=0 OPT (020405570402080A03FCE5720132EEB401030306) MARK=0x3

Conntrack mostra:

# conntrack -L --output extended | grep 85.214.204.137 | grep tcp
ipv4     2 tcp      6 59 SYN_RECV src=192.168.0.5 dst=85.214.204.137 sport=48724 dport=80 src=85.214.204.137 dst=10.200.2.235 sport=80 dport=48724 mark=3 use=1

Conclusão - os pacotes nunca chegam ao INPUT ... por quê? roteamento ruim?

    
por Bugsik 08.12.2012 / 11:11

3 respostas

2

Certifique-se de que seu roteamento seja simétrico ou desative a filtragem de caminho inverso (somente se você souber o que está fazendo, pois a correção de seu roteamento é sempre uma opção melhor).

Vamos fazer o teste, com o tráfego vindo de 192.168.0.33:

192.168.0.33 - > 192.178.100.10 iif eth0

A filtragem de caminho inverso é ativada por padrão no Ubuntu. Ele inverte o endereço de origem e destino e tenta selecionar uma rota como se tivesse um pacote com esses endereços de origem e destino. Se a interface não corresponder à interface na qual o pacote foi recebido, o pacote é considerado falsificado.

Assim, o kernel tenta rotear 192.178.100.10 - > 192.168.0.33 ... it lookups table main ... encontra a entrada 192.168.0.0/24 via eth0, que também é a interface na qual o pacote foi recebido, então o pacote não é descartado.

para que você NAT e enviar 10.200.2.235 - > 192.178.100.10 na interface da VPN. o programa VPN encapsula isso e envia isto como 192.168.0.5 - > remotevpn. Agora você recebe uma resposta do seu vpn da mesma interface. A filtragem de caminho reverso obviamente passará aqui. a VPN decapsula os resultados (192.178.100.10 - > 10.200.2.235), então NAT ocorrerá, mutilando o pacote para restaurar o endereço de destino original. Então você tem uma filtragem de caminho reverso acontecendo no pacote resultante:

192.178.100.10 - > 192.168.0.33 iff vpn

Vamos tentar rotear 192.168.0.33 para 192.178.100.10 ... VPN de tabela de consulta ... padrão via 10.200.0.1 que está em dev vpn: PASS.

Agora você quer fazer coisas do seu host, como 192.168.0.5 ou como 10.200.2.235 com a marca 3. Você envia isso para a sua VPN, que envia isso de 192.168.0.5 para o controle remoto da vpn. Você obtém uma resposta da mesma forma, então a VPN decapsulará (192.178.100.10 - > 192.168.0.5 (ou 10.200.2.235)), e a filtragem de caminho reverso ocorrerá.

192.168.0.5 ou 10.200.2.235 - > 192.178.100.10 ... não procura tabela VPN (não tem marca e não vem de 192.168.0.32/27) então acaba na tabela main, que diz para usar a interface eth0. A filtragem de caminho inverso falha, de modo que o pacote é descartado como uma tentativa de falsificação de origem de IP. Assim você não vê os resultados.

Por que o tcpdump não mostra esses pacotes ... talvez haja um problema de roteamento no ponto de extremidade VPN também.

Quanto a uma solução, no seu caso, eu usaria a marca de conexão do conntrack e definiria a marca do pacote de entrada para a marca da conexão do conntrack:

# keep that rule
OUTPUT -m owner .... -j MARK 0x3
# add this one after the previous one: it saves the current mark into connmark
OUTPUT -j CONNMARK --save-mark

# and add this one (in mangle), which sets the mark to the connmark
# if conntrack determines that it is from the same connection.
PREROUTING -j CONNMARK --restore-mark

EDIT:

Você não deve ter que desabilitar a filtragem de caminho reverso para fazer esta solução iptables funcionar. desabilitar o rp_filter desnecessariamente não é uma boa maneira de resolver problemas, apenas os oculta.

Agora, para ideias aleatórias:

  • Eu continuo fazendo suposições sobre qual endereço IP é usado pelos seus programas. Encontre um programa que realmente imprima qual endereço IP de origem ele está usando. Isso ou dizer telnet para ligar para 192.168.0.35 ou 10.200.2.235. O tcpdump mostrará apenas o pacote de saída, uma vez que ele é NAT, e mostrará apenas o pacote de entrada antes de ser unNATed, por isso não lhe diz qual é realmente usado. Como uma solução especializada, você também pode tentar colocar o nflog em uma cadeia e examinar com o tcpdump o que acontece nessa cadeia.

  • Não faça o disfarce de tudo que sai para a vpn, apenas coisas que não vêm do IP ou sub-rede de vpn . Mascarar seu próprio tráfego como seu próprio tráfego parece inútil. Talvez conntrack esteja confuso com isso.

por 08.12.2012 / 13:28
0

OK funcionou ... Eu ainda não sei o que estou fazendo de errado antes. De qualquer forma, para que funcione eu usei:

iptables -t mangle -A OUTPUT -m owner --uid-owner 2000 -j MARK --set-mark 3
iptables -t nat -A POSTROUTING -o vpn -j MASQUERADE

ip rule add fwmark 3 lookup VPN
ip route add default via x.x.x.x table VPN

sysctl -w net.ipv4.conf.vpn.rp_filter=2

Espero que ajude os outros também.

    
por 09.12.2012 / 15:22
-1

Eu acho que o que precisa ser esclarecido são os papéis de: veja p116 de Gheorghe's "Projetando e implementando firewalls e QoS linux ...")

cadeia INPUT de nat: (nunca mencionada na página man do Fedora 18)
e
Cadeia INPUT do mangle: (para pacotes que entram na própria caixa de acordo com a página man do iptables)

qual é a relação deles com a ENTRADA da tabela de filtros ?

e
Cadeia FORWARD do mangle e cadeia FORWARD do filtro.
Qual é a diferença entre as duas cadeias FORWARD?
(Ok, eu encontrei uma resposta, mas alguém poderia verificar isso: link Ch14 : _ Linux_Firewalls_Using_iptables # .UMUF0HTqOIU )

    
por 09.12.2012 / 20:29