큰 iptables 규칙 파일을 로드하는 bash 스크립트가 있습니다. 이러한 모든 iptable 규칙은 모든 미국 IP 주소를 차단하도록 설계되었습니다. 파일 크기는 약 9MB입니다. 실행하려고 하면 실행하는데 40분정도 소요됩니다.
이 스크립트의 실행 속도를 높이는 방법이 있습니까?
# head -n 4 iptables_block_usa.sh
iptables -A INPUT -s 216.187.112.96/27 -j DROP
iptables -A INPUT -s 216.187.112.128/27 -j DROP
iptables -A INPUT -s 216.187.112.160/31 -j DROP
iptables -A INPUT -s 216.187.112.163/32 -j DROP
......
답변1
iptables는 개념상 한계가 있습니다. 언제iptables규칙을 어기면 실제로 일어나는 일은 다음과 같습니다.
- iptables커널에 물어보세요모두규칙 세트
- iptables(사용자 공간에서) 규칙 세트를 변경합니다. 일반적으로 다음을 추가합니다.하나입구
- iptables커널로 돌아가기모두규칙 세트
따라서 100,000개의 규칙으로 구성된 규칙 집합에 규칙을 추가하면 많은 CPU가 낭비되므로 이런 일이 발생하지 않도록 해야 합니다.
또한 규칙은 선형적으로 작성되므로 각 패킷(이를 돕기 위해 상태 저장 규칙을 사용하는 경우 새 상태의 패킷일 수 있음)은 이 목록에 없습니다.모두규칙을 반복하여 일치하지 않는 규칙을 찾아 수락합니다. 따라서 패킷 조회는 목록의 크기에 비례하는데 이는 좋지 않습니다.
하지 말아야 할 일:
- 여러 개를 병렬로 실행하려고 하지 마십시오
iptables
. 커널 잠금이 없으면 결국 규칙을 잃게 됩니다. (사용자 공간) 잠금을 사용iptables --wait
하지만 더 이상 병렬이 아닙니다.
문제를 해결하려면 다음 중 하나를 수행하세요.
사용
iptables-restore
전체 규칙 세트를 한 번에 로드합니다.bash 스크립트를 한 번 실행하고(그리고 기다려) 다음을 사용하여 최종
iptables-save
결과를 덤프합니다.iptables-restore
sed스크립트가 준비된iptables-restore
형식 파일을 가질 때까지 기다리십시오. 기본 필터 테이블인 경우 다음과 유사한 형식을 가져야 합니다.*filter :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] -A INPUT -s 216.187.112.96/27 -j DROP -A INPUT -s 216.187.112.128/27 -j DROP -A INPUT -s 216.187.112.160/31 -j DROP -A INPUT -s 216.187.112.163/32 -j DROP [...] -A INPUT -s 192.0.2.0/24 -j DROP COMMIT
그렇지 않으면 직접 사용하지 마십시오.iptables주소 목록을 로드하려면 해당 컴패니언을 사용하세요.IP 세트iptables처럼 먼저 목록을 요청하는 대신 해시 테이블을 사용하고 커널에 추가할 항목만 푸시하여 이를 처리하도록 최적화되어 있습니다.
네가 원한다면
- 여러 IP 주소 또는 포트 번호를 저장하고 한 번에 iptables 컬렉션과 일치시킵니다.
- IP 주소 또는 포트에 대한 iptables 규칙을 동적으로 업데이트합니다.성능 저하 없음;
- 단일 iptables 규칙을 사용하여 복잡한 IP 주소 및 포트 기반 규칙 세트를 표현하고 IP 세트 속도의 이점을 누리세요.
그렇다면 ipset이 귀하에게 적합한 도구일 수 있습니다.
최대 요소 수를 정의해야 합니다(기본값은 "만" 65536임). 해시 크기는 ipset에 의해 동적으로 크기가 조정되므로 필요하지 않습니다(또는
hashsize 65536
적어도 추가하는 것을 고려). 간단한 경우(소스 IP 네트워크만 해당) 다음을 수행할 수 있습니다.ipset create usa_ips hash:net maxelem 300000 hashsize 65536
이제 루프를 사용하여 목록을 반복합니다
ipset
. 목록은usa_ips.txt
다음과 같은 파일일 수 있습니다.216.187.112.96/27 216.187.112.128/27 216.187.112.160/31 216.187.112.163/32 [...]
이러한 루프는 아래와 같이 10분 정도 걸릴 수 있습니다.
while read net; do ipset add usa_ips $net done < usa_ips.txt
끝에서 또는 끝나기 전에 목록의 크기를 확인할 수 있습니다. 예를 들면 다음과 같습니다.
# ipset -t list usa_ips Name: usa_ips Type: hash:net Revision: 6 Header: family inet hashsize 65536 maxelem 300000 Size in memory: 3847384 References: 0 Number of entries: 131076
이제 이 싱글과 일치하는 항목을 삭제할 수 있습니다.iptables규칙:
iptables -A INPUT -m set --match-set usa_ips src -j DROP
이 설정됩니다인용하다위의 항목은 iptables가 사용하고 있기 때문에 1입니다.
ipset save usa_ips > ipset_usa_ips.txt
위에서 지정한 현재 설정을 사용하고 저장하고 다시 로드할 수 있습니다ipset restore usa_ips < ipset_usa_ips.txt
. 출력 형식을 보면 위와 같이 일회용 파일을 준비할 수도 있으며 훨씬 더 빠르다는 것을 알 수 있습니다.~130000개 항목을 로드하는 데 1초 미만 소요. 형식은 다음과 같습니다.업데이트: 실제로 세트가 현재 사용 중이므로 오류가 발생하므로
swap
사용 가능한 명령이 있습니다.IP 세트. 해당 목록을 대체 세트에 로드하고 이전 세트와 교체해야 합니다.create usa_ips_new hash:net family inet hashsize 65536 maxelem 300000 add usa_ips_new 216.187.112.96/27 add usa_ips_new 216.187.112.128/27 add usa_ips_new 216.187.112.160/31 add usa_ips_new 216.187.112.163/32 [...]
이전에 생성된 컬렉션을 다음으로 대체합니다.
# ipset restore < usa_ips_new.txt # ipset swap usa_ips usa_ips_new # ipset destroy usa_ips_new
로 전환nftables또는 최소한 iptables-over-nftables API(Debian 10 및 RHEL 8/CentOS 8의 기본값)
nftables이미 많은 버그를 해결하기 위해 만들어졌습니다.iptables. 규칙을 추가할 때 이 델타만 커널로 전송됩니다. 완료를 위해 전체 규칙 세트를 요청/편집/다시 보낼 필요가 없습니다.iptables. iptables-over-nftables 호환성 레이어는 nftables로 구현되기 때문에 동일한 작업을 수행합니다(주로 iptables의 특수 일치 및 타겟팅을 위한 호환성 레이어도 포함).IP 세트번역할 수 없습니다.)
여기서 멈추고 운동은 여러분께 맡기겠습니다. 최근에야 알았어nftables최근 커널에서 사용되는 기능은 다음과 같습니다.네이티브 세트 지원와 함께 사용하면
flags interval
(auto-merge
중복을 피할 수도 있음) 다음을 사용하여 완전히 대체할 수 있습니다.IP 세트당신의 경우에.
답변2
구분 기호로 구분하여 여러 소스를 지정할 수 있습니다.,
바라보다iptables(8)
[!] -s, --소스 주소[/mask][,...] 소스 사양. 주소는 네트워크 이름, 호스트 이름, 네트워크 IP 주소(/mask 사용) 또는 일반 IP 주소일 수 있습니다. 호스트 이름은 규칙이 커널에 제출되기 전에 한 번만 확인됩니다. 원격 쿼리(예: DNS)를 사용하여 확인할 이름을 지정하는 것은 매우 나쁜 생각입니다. 마스크는 ipv4 넷마스크(iptables의 경우)이거나 넷마스크 왼쪽에 1의 수를 지정하는 일반 숫자일 수 있습니다. 따라서 iptables 마스크 24는 255.255.255.0과 동일합니다. 주소 지정 앞에 있는 "!" 인수는 주소의 의미를 반전시킵니다. --src 플래그는 이 옵션의 별칭입니다. 여러 주소를 지정할 수 있지만 이렇게 하면 여러 규칙으로 확장되거나(-A를 추가하는 경우) 여러 규칙이 제거됩니다(-D와 함께 사용하는 경우).
그런 다음 운영 체제에 따라 달라질 수 있는 bash 명령줄의 최대 길이로 제한됩니다. 궁극의 달리기를 찾아보세요
getconf ARG_MAX
이렇게 하면 iptables 명령을 여러 번 실행하지 않아도 됩니다.
질문의 예는 다음과 같습니다.
iptables -A INPUT -s 216.187.112.96/27,216.187.112.128/27,216.187.112.160/31,216.187.112.163/32 -j DROP
더 읽기 쉽게 만들려면 다음과 같이 줄을 나눌 수 있어야 합니다.
iptables -A INPUT -s\
216.187.112.96/27,\
216.187.112.128/27,\
216.187.112.160/31,\
216.187.112.163/32 \
-j DROP
수학을 해보자:
- 파일 크기는 9MB입니다. 행 수는 대략 48B 정도입니다. 이는 대략
9 * 1024^2 / 48 ≈ between 190000 and 200000
적인 행 수입니다(1 행 = 1 iptables 호출). - 우분투에는 ARG_MAX 2097152가 있습니다.
9 * 1024^2 / 2097152 ≈ 5
좋아요