멀티캐스트 트래픽으로 인해 Netfilter 연결 추적 시스템에 구멍이 생길 수 있음

멀티캐스트 트래픽으로 인해 Netfilter 연결 추적 시스템에 구멍이 생길 수 있음

집에 IPTV 솔루션이 있고 ISP가 10.4.4.5포트 에서 포트 10로 초당 239.3.5.3수백 개의 대형 UDP 데이터그램을 보냅니다 10. 즉, 멀티캐스트를 사용합니다. 현재 iptables수신 트래픽 구성은 매우 간단합니다.

~# 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 */
# 

규칙 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위 사진은 ISP용 NIC 입니다. 이제 이상한 점은 이 멀티캐스트 트래픽이 카운터에 따라 삭제되고 있지만(체인 기본 정책 카운터는 몇 MB/s씩 증가함) 실제로는 mplayer멀티캐스트 트래픽이 원인인 것 같습니다. netfilter 연결 추적 시스템 허점에 문제가 있습니다. 이것을 확인하는 데 사용할 수 있습니다 conntrack -L. 예:

# 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.
# 

를 실행해도 conntrack -F위 항목이 다시 나타나며 에서 영상 스트림을 볼 수 있습니다 mplayer. 그러나 결국(약 5분 후) 항목이 사라지고 스트림이 즉시 중지됩니다.

참고로 이 Linux 기반 라우터에는 9개의 물리적 인터페이스가 있습니다.

# 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
# 

내가 말했듯이 eth0ISP에 연결되었습니다. eth1플러스는 eth7이름 wlan0이 붙은 브릿지의 일부입니다 br0. 라우팅 테이블은 다음과 같습니다.

# 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 
# 

모든 인터페이스에 대한 다양한 네트워크 매개변수는 여기에서 볼 수 있습니다.

# 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 
# 

이것이 예상되는 동작입니까? 내 첫 번째 생각은 conntrack 모듈이 IGMP "Membership Report" 메시지를 확인하여 트래픽이 도착하도록 허용할 수 있다는 것이 239.3.5.3었지만, 이후에도 트래픽이 어떻게 허용되는지는 설명되지 않습니다 conntrack -F.

답변1

비슷한 설정을 사용한 후pimd, 나는 다음과 같은 결론을 내릴 수 있습니다.

  • filter/FORWARD이 흐름에 대해 멀티캐스트 라우팅이 활성화되어 있는 한 일반(데이터) 멀티캐스트 패킷이 전달됩니다. 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은 전달된 흐름이며 또한 이 contrack 항목을 트리거하는 새 패킷인 1만큼 합계 nat/PREROUTING카운터를 증가시킵니다.nat/POSTROUTING
  • 링크-로컬 멀티캐스트 패킷(224.0.0.{1,22}에 대한 IGMP 패킷 및 224.0.0.13에 대한 PIMv2)이 중지됩니다 filter/INPUT.
  • 흐름이 이전에 활성화된 경우 멀티캐스트 라우터는 일정 기간 동안 해당 특정 멀티캐스트 대상에 대한 전달을 활성화합니다. 구성된 시간 초과가 발생하고 방화벽으로 인해 LAN에서 IGMP 보고서를 수신하지 못하거나 방화벽으로 인해 PIMv2를 수신하지 못하면 더 이상 수신 중인 클라이언트가 없거나 더 이상 유효한 흐름이 없는 것으로 간주하고 해당 멀티캐스트 전달을 중지합니다. 스트리밍.

마지막으로 Linux 라우터가 다음을 수신하도록 허용해야 합니다.

  • 라우터가 수신 중인 멀티캐스트 클라이언트를 알 수 있도록 하는 LAN의 IGMP 패킷:

    iptables -A INPUT -i br0 -p igmp -j ACCEPT
    
  • 내 특정 설정은 pimdPIMv2를 사용하고 있습니다. 해당 프로토콜이 항상 사용되는지는 모르겠지만 소스 IP가 192.0.0.1이 아닌 경우 DROP 정책을 유지하면서 PIM 프로토콜이 작동하도록 허용해야 합니다. 2.1(그러나 10.4.4.5):

    iptables -A INPUT -s 192.0.2.1 -i eth0 -p pim -j ACCEPT
    
  • ISP 라우터에서 IGMP 패킷을 허용해야 할 수도 있지만 내 특정 설정에서는 이를 필요로 하지 않습니다.

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

고쳐 쓰다:

체인의 DROP 정책 은 filter/INPUT여전히 ​​적중을 표시합니다. Linux 라우터의 자체 IGMP 및 PIMv2 패킷(멀티캐스트)은 외부로 전송될 때 로컬 시스템으로 루프백되므로 위의 Not Enabled 규칙으로 인해 (해를 끼치지 않고) 삭제됩니다. 적절한 규칙을 추가한 후 PIMv2에서 이상한 동작이 발생하여 .na 규칙도 filter/OUTPUT제한하도록 패킷을 표시해야 했습니다 filter/INPUT. 마지막으로, 다음 규칙을 사용하면 filter/INPUT멀티캐스트 트래픽을 전달할 때 DROP 정책 카운터가 항상 [0:0]으로 유지됩니다.

# 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

멀티캐스트 클라이언트를 시뮬레이션하고 표준 출력으로 덤프할 수 있습니다.socat(인터페이스가 여러 개인 경우 로컬 IP를 지정하십시오):

socat -u UDP4-RECV:10,ip-add-membership=239.3.5.3:0.0.0.0 -

관련 정보