o tráfego multicast é capaz de introduzir um buraco no sistema de rastreamento de conexão do netfilter

2

Eu tenho uma solução de IPTV em casa, onde o ISP me envia centenas de grandes datagramas UDP por segundo de 10.4.4.5 port 10 para 239.3.5.3 port 10 , ou seja, ele está usando multicast. Minha configuração atual de iptables para o tráfego de ingresso é muito simples:

~# iptables -L INPUT -v -n --line-numbers
Chain INPUT (policy DROP 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1       19   845 ACCEPT     all  --  lo     *       0.0.0.0/0            0.0.0.0/0           
2     1146  275K ACCEPT     all  --  eth0   *       0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED /* established/related connections */
# 

Regras no formato iptables-save :

# iptables-save -c
# Generated by iptables-save v1.6.0 on Sun Aug 26 12:51:11 2018
*nat
:PREROUTING ACCEPT [44137:4586148]
:INPUT ACCEPT [6290:1120016]
:OUTPUT ACCEPT [419:75595]
:POSTROUTING ACCEPT [98:8415]
[26464:2006874] -A POSTROUTING -o eth0 -m comment --comment SNAT -j MASQUERADE
COMMIT
# Completed on Sun Aug 26 12:51:11 2018
# Generated by iptables-save v1.6.0 on Sun Aug 26 12:51:11 2018
*filter
:INPUT DROP [72447:97366152]
:FORWARD ACCEPT [77426:101131642]
:OUTPUT ACCEPT [148:17652]
[17:787] -A INPUT -i lo -j ACCEPT
[333:78556] -A INPUT -i eth0 -m conntrack --ctstate RELATED,ESTABLISHED -m comment --comment "established/related connections" -j ACCEPT
COMMIT
# Completed on Sun Aug 26 12:51:11 2018
# 

eth0 visto acima é o NIC voltado para ISP. Agora, a parte estranha é que, embora esse tráfego multicast seja descartado de acordo com os contadores (o contador de política padrão de cadeia aumenta vários MB / s), então, na verdade, recebo em mplayer . A razão para isso é que o tráfego multicast parece criar um buraco no sistema de rastreamento de conexão do netfilter. Eu posso verificar isso com conntrack -L . Exemplo:

# conntrack -L | grep --color 239.3.
udp      17 29 src=10.4.4.5 dst=239.3.5.3 sport=10 dport=10 [UNREPLIED] src=239.3.5.3 dst=10.4.4.5 sport=10 dport=10 mark=0 use=1
conntrack v1.4.4 (conntrack-tools): 130 flow entries have been shown.
# 

Mesmo se eu executar conntrack -F , essa entrada acima reaparecerá e eu poderei ver o fluxo de vídeo em mplayer . No entanto, eventualmente (após ~ 5 minutos) essa entrada desaparece e também imediatamente o fluxo é interrompido.

Apenas para informação, este roteador baseado em Linux tem 9 interfaces físicas:

# ip -br link
lo               UNKNOWN        00:00:00:00:00:00 <LOOPBACK,UP,LOWER_UP> 
eth2             DOWN           00:a0:c9:77:96:bd <NO-CARRIER,BROADCAST,MULTICAST,UP> 
eth1             UP             00:14:bf:5f:de:71 <BROADCAST,MULTICAST,UP,LOWER_UP> 
eth0             UNKNOWN        00:50:8d:d1:4f:ee <BROADCAST,MULTICAST,UP,LOWER_UP> 
eth3             DOWN           00:a0:c9:4b:21:a0 <NO-CARRIER,BROADCAST,MULTICAST,UP> 
eth4             UP             00:20:e2:1e:2e:64 <BROADCAST,MULTICAST,UP,LOWER_UP> 
eth5             DOWN           00:20:fc:1e:2e:65 <NO-CARRIER,BROADCAST,MULTICAST,UP> 
eth6             DOWN           00:20:fc:1e:2e:8e <NO-CARRIER,BROADCAST,MULTICAST,UP> 
eth7             UP             00:20:fc:1e:2f:67 <BROADCAST,MULTICAST,UP,LOWER_UP> 
wlan0            UP             00:21:91:e3:20:20 <BROADCAST,MULTICAST,UP,LOWER_UP> 
br0              UP             00:14:bf:5e:da:71 <BROADCAST,MULTICAST,UP,LOWER_UP> 
# ip -br address
lo               UNKNOWN        127.0.0.1/8 
eth2             DOWN           
eth1             UP             
eth0             UNKNOWN        192.0.2.79/24
eth3             DOWN           
eth4             UP             
eth5             DOWN           
eth6             DOWN           
eth7             UP             
wlan0            UP             
br0              UP             192.168.0.1/24
# 

Como eu disse, eth0 está conectado ao ISP. eth1 to eth7 plus wlan0 fazem parte da ponte denominada br0 . A tabela de roteamento se parece com isso:

# ip -4 r
default via 192.0.2.1 dev eth0 
192.0.2.0/24 dev eth0 proto kernel scope link src 192.0.2.79 
192.168.0.0/24 dev br0 proto kernel scope link src 192.168.0.1 
# 

Vários parâmetros de rede para todas as interfaces podem ser vistos aqui:

# ip -4 netconf 
ipv4 dev lo forwarding on rp_filter off mc_forwarding off proxy_neigh off ignore_routes_with_linkdown off 
ipv4 dev eth2 forwarding on rp_filter off mc_forwarding off proxy_neigh off ignore_routes_with_linkdown off 
ipv4 dev eth1 forwarding on rp_filter off mc_forwarding off proxy_neigh off ignore_routes_with_linkdown off 
ipv4 dev eth0 forwarding on rp_filter off mc_forwarding on proxy_neigh off ignore_routes_with_linkdown off 
ipv4 dev eth3 forwarding on rp_filter off mc_forwarding off proxy_neigh off ignore_routes_with_linkdown off 
ipv4 dev eth4 forwarding on rp_filter off mc_forwarding off proxy_neigh off ignore_routes_with_linkdown off 
ipv4 dev eth5 forwarding on rp_filter off mc_forwarding off proxy_neigh off ignore_routes_with_linkdown off 
ipv4 dev eth6 forwarding on rp_filter off mc_forwarding off proxy_neigh off ignore_routes_with_linkdown off 
ipv4 dev eth7 forwarding on rp_filter off mc_forwarding off proxy_neigh off ignore_routes_with_linkdown off 
ipv4 dev wlan0 forwarding on rp_filter off mc_forwarding off proxy_neigh off ignore_routes_with_linkdown off 
ipv4 dev br0 forwarding on rp_filter off mc_forwarding on proxy_neigh off ignore_routes_with_linkdown off 
ipv4 all forwarding on rp_filter off mc_forwarding on proxy_neigh off ignore_routes_with_linkdown off 
ipv4 default forwarding on rp_filter off mc_forwarding off proxy_neigh off ignore_routes_with_linkdown off 
# 

Este é um comportamento esperado? Meu primeiro pensamento foi que o módulo conntrack é capaz de inspecionar as mensagens "relatório de associação" do IGMP e, portanto, permite o tráfego para 239.3.5.3 , mas isso não explica como o tráfego é permitido mesmo após conntrack -F .

    
por Martin 25.08.2018 / 00:31

1 resposta

2

Depois de tentar uma configuração semelhante usando pimd , só posso concluir que :

  • pacotes multicast normais (dados) são encaminhados, portanto, estão sujeitos a filter/FORWARD , desde que o roteamento multicast esteja habilitado para esse fluxo. A entrada conntrack udp 17 29 src=10.4.4.5 dst=239.3.5.3 sport=10 dport=10 [UNREPLIED] src=239.3.5.3 dst=10.4.4.5 sport=10 dport=10 mark=0 use=1 é um fluxo encaminhado e também aumentará os contadores nat/PREROUTING e nat/POSTROUTING por (apenas) um: o pacote NOVO que acionou essa entrada de contração.
  • pacotes multicast link-locais (pacotes IGMP para 224.0.0. {1,22} e PIMv2 para 224.0.0.13) são interrompidos por filter/INPUT .
  • Se o fluxo foi ativado antes, o roteador de multidifusão ativará o encaminhamento desse destino multicast específico por um tempo. Quando ocorrer um tempo limite configurado, durante o qual ele não recebeu nenhum relatório IGMP da LAN ou do PIMv2 da WAN devido ao firewall, ele considerará que não há mais cliente ou nenhum fluxo válido e deixará de encaminhar o fluxo multicast correspondente.

No final, você deve permitir que o roteador linux receba:

  • Pacotes IGMP vindos da LAN, para permitir que o roteador continue sabendo quais clientes de multicast estão ouvindo:

    iptables -A INPUT -i br0 -p igmp -j ACCEPT
    
  • Minha configuração específica está usando pimd e PIMv2, não sei se esse protocolo é sempre usado ou não, mas tive que permitir que o protocolo PIM funcionasse mantendo a política DROP, quando o IP de origem não foi apenas 192.0.2.1 (mas 10.4.4.5):

    iptables -A INPUT -s 192.0.2.1 -i eth0 -p pim -j ACCEPT
    
  • Pode ser necessário permitir pacotes IGMP do roteador do ISP, mas minha configuração específica não os exige:

    iptables -A INPUT -s 192.0.2.1 -i eth0 -p igmp -j ACCEPT
    

ATUALIZAÇÃO:

Observe que a política DROP da cadeia filter/INPUT ainda mostrará ocorrências: os pacotes IGMP e PIMv2 do roteador linux, sendo multicast, são retornados em loop ao sistema local quando enviados para fora e, portanto, são (inofensivamente) descartados, pois não são ativados por as regras acima. Depois de adicionar as regras correspondentes, eu acertei um comportamento estranho para o PIMv2 e no final tive que marcar os pacotes em filter/OUTPUT para permitir sua cópia em loopback em filter/INPUT . Enquanto isso eu também restringi a regra nat. No final, com as seguintes regras, o contador de políticas DROP de filter/INPUT sempre ficava em [0: 0] enquanto encaminhava o tráfego multicast:

# Generated by iptables-save v1.6.2 on Mon Aug 27 01:01:48 2018
*nat
:PREROUTING ACCEPT [1:56]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [1:56]
[0:0] -A POSTROUTING -s 192.168.0.0/24 -o eth0 -m comment --comment SNAT -j MASQUERADE
COMMIT
# Completed on Mon Aug 27 01:01:48 2018
# Generated by iptables-save v1.6.2 on Mon Aug 27 01:01:48 2018
*filter
:INPUT DROP [0:0]
:FORWARD ACCEPT [1533311:325676232]
:OUTPUT ACCEPT [75:3724]
[0:0] -A INPUT -i lo -j ACCEPT
[1:56] -A INPUT -i eth0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
[40:1800] -A INPUT -i br0 -p igmp -j ACCEPT
[14:774] -A INPUT -s 192.0.2.1/32 -i eth0 -p pim -j ACCEPT
[28:1288] -A INPUT -s 192.0.2.1/32 -i eth0 -p igmp -j ACCEPT
[17:932] -A INPUT -s 192.0.2.79/32 -i eth0 -p igmp -j ACCEPT
[28:1392] -A INPUT -m mark --mark 0x1 -j ACCEPT
[28:1392] -A OUTPUT -p pim -j MARK --set-xmark 0x1/0xffffffff
COMMIT
# Completed on Mon Aug 27 01:01:48 2018

Você pode simular um cliente de multidifusão e fazer o dump para o stdout com socat ( especifique o IP local se mais de uma interface):

socat -u UDP4-RECV:10,ip-add-membership=239.3.5.3:0.0.0.0 -
    
por 27.08.2018 / 00:07