Por que há tráfego não-127.x.x.x no meu dispositivo de loopback?

1

Eu tenho um problema que me causou uma grande dor de cabeça e encontrei a solução, mas não consigo entender por que o problema estava acontecendo em primeiro lugar.

Eu tenho um proxy reverso nginx que está encaminhando solicitações para 1 de 3 servidores. Todos são servidores de nós, dois deles são expressos e um é customizado.

O problema: quando meu firewall está ativo , a solicitação primeiro no total de tempo de atividade dos dois servidores express sofre um 504: Tempo limite do gateway . Depois disso, os arquivos são exibidos rapidamente e sem problemas, mesmo durante vários dias.

Consegui restringir o problema ao firewall, percebendo que o problema desaparece quando eu derrubar completamente o firewall. Meu servidor está executando o FreeBSD, usando o PF como um firewall. Aqui está o pf.conf relevante:

iface = "vtnet0"
loopback = "lo0"
public_ip = "132.148.77.28/32"
localnet = "127.0.0.1"

nat on $iface from any to any -> $public_ip # added by cloud server provider
pass out quick on $iface proto { tcp udp } from port ntp keep state
block log all
pass in on $iface proto tcp from $localnet to port mail
pass in log on $iface proto tcp to $public_ip port { ssh http } keep state
pass in log on $loopback proto tcp to $localnet port { 5555 5556 5557 } keep state
pass out log all keep state

Compreendo que qualquer tráfego no dispositivo vtnet0 será traduzido para o uso do ip público.

Eu executei um tcpdump com o seguinte comando: sudo tcpdump -c 10 -vvv -t -i pflog0 -e -n tcp

Capturei 10 pacotes, com verbosidade tripla, suprimindo o timestamp, em pflog0, imprimindo a regra pf que permitia ou bloqueava o pacote, deixando endereços IP e portas como números, e capturando somente tráfego usando tcp.

Aqui estão os resultados interessantes da primeira solicitação, junto com os resultados das solicitações subsequentes:

$ sudo tcpdump -c 10 -vvv -t -i pflog0 -e -n tcp
tcpdump: WARNING: pflog0: no IPv4 address assigned
tcpdump: listening on pflog0, link-type PFLOG (OpenBSD pflog file), capture size 65535 bytes

rule 8..16777216/0(match): pass in on vtnet0: (tos 0x0, ttl 52, id 53488, offset 0, flags [DF], proto TCP (6), length 60)
    67.197.156.119.45274 > 132.148.77.28.80: Flags [S], cksum 0x76df (correct), seq 356096480, win 29200, options [mss 1460,sackOK,TS val 63916304 ecr 0,nop,wscale 7], length 0

rule 9..16777216/0(match): pass out on lo0: (tos 0x0, ttl 64, id 2406, offset 0, flags [DF], proto TCP (6), length 60)
    127.0.0.1.28850 > 127.0.0.1.5556: Flags [S], cksum 0xfe30 (incorrect -> 0x180a), seq 2069090201, win 65535, options [mss 16344,nop,wscale 6,sackOK,TS val 33367168 ecr 0], length 0

rule 5..16777216/0(match): pass in on lo0: (tos 0x0, ttl 64, id 2406, offset 0, flags [DF], proto TCP (6), length 60, bad cksum 0 (->3354)!)
    127.0.0.1.28850 > 127.0.0.1.5556: Flags [S], cksum 0xfe30 (incorrect -> 0x180a), seq 2069090201, win 65535, options [mss 16344,nop,wscale 6,sackOK,TS val 33367168 ecr 0], length 0

rule 9..16777216/0(match): pass out on lo0: (tos 0x0, ttl 64, id 2414, offset 0, flags [DF], proto TCP (6), length 60)
    132.148.77.28.48488 > 132.148.77.28.80: Flags [S], cksum 0xa38f (incorrect -> 0x1728), seq 3973611725, win 65535, options [mss 16344,nop,wscale 6,sackOK,TS val 33367544 ecr 0], length 0

rule 2..16777216/0(match): **block in on lo0**: (tos 0x0, ttl 64, id 2414, offset 0, flags [DF], proto TCP (6), length 60, bad cksum 0 (->8ded)!)
    132.148.77.28.48488 > 132.148.77.28.80: Flags [S], cksum 0xa38f (incorrect -> 0x1728), seq 3973611725, win 65535, options [mss 16344,nop,wscale 6,sackOK,TS val 33367544 ecr 0], length 0

rule 2..16777216/0(match): **block in on lo0**: (tos 0x0, ttl 64, id 2416, offset 0, flags [DF], proto TCP (6), length 60, bad cksum 0 (->8deb)!)
    132.148.77.28.48488 > 132.148.77.28.80: Flags [S], cksum 0xa38f (incorrect -> 0x0b6a), seq 3973611725, win 65535, options [mss 16344,nop,wscale 6,sackOK,TS val 33370550 ecr 0], length 0

rule 2..16777216/0(match): **block in on lo0**: (tos 0x0, ttl 64, id 2418, offset 0, flags [DF], proto TCP (6), length 60, bad cksum 0 (->8de9)!)
    132.148.77.28.48488 > 132.148.77.28.80: Flags [S], cksum 0xa38f (incorrect -> 0xfee6), seq 3973611725, win 65535, options [mss 16344,nop,wscale 6,sackOK,TS val 33373753 ecr 0], length 0

rule 2..16777216/0(match): **block in on lo0**: (tos 0x0, ttl 64, id 2420, offset 0, flags [DF], proto TCP (6), length 60, bad cksum 0 (->8de7)!)
    132.148.77.28.48488 > 132.148.77.28.80: Flags [S], cksum 0xa38f (incorrect -> 0xf265), seq 3973611725, win 65535, options [mss 16344,nop,wscale 6,sackOK,TS val 33376954 ecr 0], length 0

rule 2..16777216/0(match): **block in on lo0**: (tos 0x0, ttl 64, id 2422, offset 0, flags [DF], proto TCP (6), length 60, bad cksum 0 (->8de5)!)
    132.148.77.28.48488 > 132.148.77.28.80: Flags [S], cksum 0xa38f (incorrect -> 0xe5c8), seq 3973611725, win 65535, options [mss 16344,nop,wscale 6,sackOK,TS val 33380183 ecr 0], length 0

rule 2..16777216/0(match): **block in on lo0**: (tos 0x0, ttl 64, id 2424, offset 0, flags [DF], proto TCP (6), length 60, bad cksum 0 (->8de3)!)
    132.148.77.28.48488 > 132.148.77.28.80: Flags [S], cksum 0xa38f (incorrect -> 0xd943), seq 3973611725, win 65535, options [mss 16344,nop,wscale 6,sackOK,TS val 33383388 ecr 0], length 0
10 packets captured
11 packets received by filter
0 packets dropped by kernel

$ sudo tcpdump -c 10 -vvv -t -i pflog0 -e -n tcp
tcpdump: WARNING: pflog0: no IPv4 address assigned
tcpdump: listening on pflog0, link-type PFLOG (OpenBSD pflog file), capture size 65535 bytes

rule 8..16777216/0(match): pass in on vtnet0: (tos 0x0, ttl 52, id 408, offset 0, flags [DF], proto TCP (6), length 60)
    67.197.156.119.45482 > 132.148.77.28.80: Flags [S], cksum 0x2e49 (correct), seq 3314040182, win 29200, options [mss 1460,sackOK,TS val 64109806 ecr 0,nop,wscale 7], length 0

rule 9..16777216/0(match): pass out on lo0: (tos 0x0, ttl 64, id 2446, offset 0, flags [DF], proto TCP (6), length 60)
    127.0.0.1.19450 > 127.0.0.1.5556: Flags [S], cksum 0xfe30 (incorrect -> 0x603e), seq 629617255, win 65535, options [mss 16344,nop,wscale 6,sackOK,TS val 34141175 ecr 0], length 0

rule 5..16777216/0(match): pass in on lo0: (tos 0x0, ttl 64, id 2446, offset 0, flags [DF], proto TCP (6), length 60, bad cksum 0 (->332c)!)
    127.0.0.1.19450 > 127.0.0.1.5556: Flags [S], cksum 0xfe30 (incorrect -> 0x603e), seq 629617255, win 65535, options [mss 16344,nop,wscale 6,sackOK,TS val 34141175 ecr 0], length 0

rule 9..16777216/0(match): pass out on lo0: (tos 0x0, ttl 64, id 2459, offset 0, flags [DF], proto TCP (6), length 60)
    127.0.0.1.54320 > 127.0.0.1.5556: Flags [S], cksum 0xfe30 (incorrect -> 0x8ec2), seq 2137792783, win 65535, options [mss 16344,nop,wscale 6,sackOK,TS val 34141359 ecr 0], length 0

rule 5..16777216/0(match): pass in on lo0: (tos 0x0, ttl 64, id 2459, offset 0, flags [DF], proto TCP (6), length 60, bad cksum 0 (->331f)!)
    127.0.0.1.54320 > 127.0.0.1.5556: Flags [S], cksum 0xfe30 (incorrect -> 0x8ec2), seq 2137792783, win 65535, options [mss 16344,nop,wscale 6,sackOK,TS val 34141359 ecr 0], length 0

rule 8..16777216/0(match): pass in on vtnet0: (tos 0x0, ttl 52, id 13349, offset 0, flags [DF], proto TCP (6), length 60)
    67.197.156.119.45484 > 132.148.77.28.80: Flags [S], cksum 0x9e57 (correct), seq 2310473985, win 29200, options [mss 1460,sackOK,TS val 64109860 ecr 0,nop,wscale 7], length 0

rule 8..16777216/0(match): pass in on vtnet0: (tos 0x0, ttl 52, id 32739, offset 0, flags [DF], proto TCP (6), length 60)
    67.197.156.119.45486 > 132.148.77.28.80: Flags [S], cksum 0x5b67 (correct), seq 2464105159, win 29200, options [mss 1460,sackOK,TS val 64109860 ecr 0,nop,wscale 7], length 0

rule 8..16777216/0(match): pass in on vtnet0: (tos 0x0, ttl 52, id 55497, offset 0, flags [DF], proto TCP (6), length 60)
    67.197.156.119.45488 > 132.148.77.28.80: Flags [S], cksum 0x832f (correct), seq 3354322413, win 29200, options [mss 1460,sackOK,TS val 64109860 ecr 0,nop,wscale 7], length 0

rule 9..16777216/0(match): pass out on lo0: (tos 0x0, ttl 64, id 2474, offset 0, flags [DF], proto TCP (6), length 60)
    127.0.0.1.60189 > 127.0.0.1.5556: Flags [S], cksum 0xfe30 (incorrect -> 0xe2c0), seq 1589892785, win 65535, options [mss 16344,nop,wscale 6,sackOK,TS val 34141386 ecr 0], length 0

rule 5..16777216/0(match): pass in on lo0: (tos 0x0, ttl 64, id 2474, offset 0, flags [DF], proto TCP (6), length 60, bad cksum 0 (->3310)!)
    127.0.0.1.60189 > 127.0.0.1.5556: Flags [S], cksum 0xfe30 (incorrect -> 0xe2c0), seq 1589892785, win 65535, options [mss 16344,nop,wscale 6,sackOK,TS val 34141386 ecr 0], length 0
10 packets captured
14 packets received by filter
0 packets dropped by kernel

Eu adicionei novas linhas entre as informações do pacote para melhor legibilidade. Você notará no primeiro dump onde a "regra 2" está bloqueando os pacotes, o que acontece apenas na primeira requisição depois que o servidor upstream é iniciado novamente.

O que dá? Você notará também que esses pacotes bloqueados estão na interface de loopback, mas eles vêm e vão para o endereço IP público. Eu acho que eles não deveriam ser NAT porque eles não estão na interface vtnet0. Ainda assim, por que as solicitações subseqüentes estão tomando um caminho diferente para facilitar a comunicação do nginx para o servidor upstream?

A correção que encontrei foi alterar a seguinte linha do meu pf.conf: %código% para: pass in log on $iface proto tcp to $public_ip port { ssh http } keep state

Eu removi a parte pass in log proto tcp to $public_ip port { ssh http } keep state para que o firewall deixasse passar até os pacotes para $ public_ip port 80 na interface de loopback. Também tenho preocupações moderadas sobre as implicações de segurança do afrouxamento dessa regra - que são leves apenas porque não entendo mais como o tráfego está operando entre essas diferentes interfaces de rede.

Neste ponto, eu nem tenho certeza se o problema é com o meu firewall ou com o nginx, só que quando o firewall está desabilitado, o problema desaparece.

Observe que o nginx é on $iface 'das solicitações em três blocos proxy_pass diferentes para server , onde a porta é uma das 5555, 5556 ou 5557.

    
por user305964 11.02.2017 / 17:18

1 resposta

1

Depois de muita pesquisa, a correção correta para o meu problema, em vez de modificar a linha que mencionei, foi remover essa linha completamente e adicionar um set skip on lo0 no bloco Options do pf.conf (após as macros e antes as regras de filtragem de pacotes). Isso impede que a interface de loopback seja tocada por pf.

No que diz respeito a não 127.x.x.x ip aparecer no dispositivo de loopback, eu tenho uma teoria. Como o @Richard Smith sugeriu, eu corri netstat -rn e notei as duas linhas seguintes:

Destination      Gateway Flags Netif
132.148.77.28    link#1  UHS   lo0 
132.148.77.28/32 link#1  U     vtnet0

Eu fiz algumas pesquisas e descobri que essas duas entradas foram adicionadas como um alias, via ifconfig , à primeira interface ethernet listada na saída do ifconfig: vtnet0. Então, naturalmente parece que o tráfego realmente poderia ser roteado através do loopback para 132.148.77.28, conforme demonstrado por esta rota. Significa apenas que usaria vtnet0 como o gateway para fazer isso. Agora, eu não tenho certeza se o que aconteceu é que quando chegou a vtnet0 como o gateway, ficou NAT pela regra pf - mas então eu não tenho certeza porque o tcpdump ainda mostraria a interface antiga (lo0) da qual ele veio. Ainda parece estranho para mim que o servidor upstream que está escutando em 127.0.0.1 escolheria abrir uma porta em 132.148.77.28 para tentar responder ao servidor proxy pela primeira vez e, em seguida, em solicitações subseqüentes, basta usar 127.0. 0.1 e ter o proxy reverso "descer ao seu nível" para a comunicação. Minha teoria é que o algoritmo de roteamento "lembrou" que o caminho anterior era ruim (ou seja, ficar bloqueado), e assim tentou uma abordagem diferente. Não vou marcar minha resposta como a resposta aceita porque realmente preciso de um profissional com um olho altamente treinado para verificar se minhas teorias leves têm alguma validade.

    
por 12.02.2017 / 03:35