다중 포트 모듈은 iptables
여러 개별 규칙에 비해 성능 이점을 제공합니까? 즉, 이는 다음과 같습니다.
iptables -A INPUT -p tcp -m multiport --sports 1,2,3,4,5,6,7,8,9,10,11,12,13,14,80 -j ACCEPT
..이보다 더 효율적입니다.
iptables -A INPUT -p tcp --sport 1 -j ACCEPT
iptables -A INPUT -p tcp --sport 2 -j ACCEPT
iptables -A INPUT -p tcp --sport 3 -j ACCEPT
iptables -A INPUT -p tcp --sport 4 -j ACCEPT
iptables -A INPUT -p tcp --sport 5 -j ACCEPT
iptables -A INPUT -p tcp --sport 6 -j ACCEPT
iptables -A INPUT -p tcp --sport 7 -j ACCEPT
iptables -A INPUT -p tcp --sport 8 -j ACCEPT
iptables -A INPUT -p tcp --sport 9 -j ACCEPT
iptables -A INPUT -p tcp --sport 10 -j ACCEPT
iptables -A INPUT -p tcp --sport 11 -j ACCEPT
iptables -A INPUT -p tcp --sport 12 -j ACCEPT
iptables -A INPUT -p tcp --sport 13 -j ACCEPT
iptables -A INPUT -p tcp --sport 14 -j ACCEPT
iptables -A INPUT -p tcp --sport 80 -j ACCEPT
첫 번째 경우에는 각 패키지를 검사 tcp
하고 multiport
모듈도 검사하지만 규칙은 하나만 있습니다. 두 번째 경우에는 패키지별로 15개의 규칙을 검사하지만 각 규칙별로 tcp
모듈만 처리합니다.
다음과 같이 간단한 네트워크 토폴로지를 만들었습니다.
server1[eth2] <--> [enp0s31f6]server2
eth2
입출력 모두 1GigE 네트워크 어댑터 server1
이며 5m Cat5e 케이블을 통해 연결됩니다. 방화벽 규칙 없이 10000MiB 파일을 다운로드했을 때 처리량은 942Mbps였습니다. 그런 다음 다음과 같은 4369개의 규칙을 생성했습니다.enp0s31f6
server2
server1
server2
for i in {1..65535}; do if ((i%15 == 0)); then iptables -A INPUT -p tcp -m multiport --sports $p$i -j ACCEPT; p=; else p=$p$i,; fi; done
multiport
이는 각각 15개의 포트가 있는 4,369개의 규칙이 있음을 의미합니다 . 예를 들어:
# iptables -L INPUT 1 -v -n --line-numbers
1 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 multiport sports 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
# iptables -L INPUT 4369 -v -n --line-numbers
4369 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 multiport sports 65521,65522,65523,65524,65525,65526,65527,65528,65529,65530,65531,65532,65533,65534,65535
#
wget --report-speed=bits -4 -O /dev/null 10.10.10.1:65535
이제 에서 실행할 때 server2
놀랍게도 처리량은 여전히 942Mbps입니다. 다음으로 INPUT
체인을 새로 고치고 다음과 같이 65535개의 규칙을 생성했습니다.
for i in {1..65535}; do iptables -A INPUT -p tcp --sport $i -j ACCEPT; done
wget --report-speed=bits -4 -O /dev/null 10.10.10.1:65535
다시 실행했더니 server2
처리량이 580Mbps로 떨어졌습니다. 그럼 극단적인 경우에는 이 multiport
방법이 더 효과적이겠죠? 하지만 수만 개의 규칙이나 수십 Gbps의 트래픽이 없는 일반적인 상황에서는 실질적인 차이가 없습니까?
답변1
iptables는 종료 대상과 일치하는 항목을 찾을 때까지 테이블의 각 규칙을 반복하므로 규칙이 적을수록 CPU 사용량이 낮아집니다. 일부 규칙은 다른 규칙보다 빠르게 실행됩니다.다중 포트15포트 규칙은 동등한 포트 규칙보다 빠를 수 있습니다.놓다규칙 (예: Hauke Laging의답변). 따라서 규칙의 수뿐만 아니라 규칙의 유형도 중요합니다.
소스 코드는TCP/UDP,다중 포트그리고놓다일치 확장은 몇 가지 경험 법칙을 제공하지만 이후진행 속도가 어디까지 느려질지 예측하기 어렵습니다., 가능한 iptables 규칙 세트를 벤치마킹하여 어느 것이 더 빠른지 확인하는 것이 좋습니다. 예를 들어, 나는iperf33개의 포트만 포함된 목록전송 제어 프로토콜모듈 비율다중 포트그리고놓다유사한 처리량을 제공하는 모듈입니다.
아직도 마이크로벤치마킹에 관심이 있으시다면 이 프로그램을 실행하는 데 필요한 CPU 사이클을 계산해 봤습니다.ipt_do_table
매우 기본적인 커널 함수를 사용하세요시스템 클릭스크립트:
global call_cycles = 0
probe kernel.function("ipt_do_table@net/ipv4/netfilter/ip_tables.c").call {
call_cycles = get_cycles()
}
probe kernel.function("ipt_do_table@net/ipv4/netfilter/ip_tables.c").return {
delta = get_cycles() - call_cycles
printf(" <- delta = %d\n", delta)
}
Linux 4.15를 실행하는 가상 머신에서 모든 규칙의 패킷을 반복할 때의 결과는 다음과 같습니다.
기준 치수 | 포트 | 규칙 | 1 실행 | 실행 2 | 실행 3 | 실행 4 | 실행 5 |
---|---|---|---|---|---|---|---|
전송 제어 프로토콜 | 4500 | 4500 | 973148 | 1032564 | 856528 | 410894 | 854708 |
다중 포트 | 4500 | 300 | 89370 | 259250 | 99752 | 225275 | 182256 |
놓다 | 4500 | 1 | 28463 | 43494 | 28315 | 33589 | 40988 |
답변2
Linux가 opcode 수준에서 Netfilter 규칙을 어떻게 처리하는지 모르겠습니다. 그러나 다중 포트 접근 방식은 한 번의 작업으로 여러 검사를 수행할 수 있습니다.
1Gb/s는 CPU에 그리 많지 않기 때문에(느린 CPU라도) 극단적인 경우가 필요한 것은 놀라운 일이 아닙니다. 그러나 두 가지 방법은 동일한 처리량에서도 완전히 다른 부하를 생성할 수 있습니다. 이것은 커널이므로 아마도 작동하지 않을 것입니다 /proc/loadavg
. 따라서 동일한 시스템에서 CPU 집약적인 응용 프로그램을 실행하고 성능을 측정하여 실제 차이를 확인해야 합니다.
-p tcp
하지만 멀티 포트는 한 번 검사하는 반면 멀티 규칙은 동일한 검사를 65536번 수행하기 때문에 비교가 약간 불공평하다고 생각합니다. 그래서 당신은 이렇게 할 것입니다 :
iptables -N tcp_ports
iptables -A INPUT -p tcp -j tcp_ports
for ((i=1;i<65536;i++)); do iptables -A tcp_ports --sport $i ...
나는 TCP 검사를 있는 그대로 무시할 수 없다는 것을 깨달았습니다 --dport
. 그러나 이것이 다중 규칙 접근 방식이 더 느린 이유 중 하나입니다.
귀하와 같은 상황에서 멀티포팅이 작동하는지 잘 모르겠습니다. ipset
거대한 비교 목록이 생성되었습니다. 그래서 이것이 당신이 정말로 원하는 것일 수도 있습니다.
ipset create foo bitmap:port range tcp:10000-19999
ipset add foo tcp:10000-19999
iptables -A INPUT -p tcp -m set --match-set foo dst