답변:
#!/bin/bash
WHITELIST=/whitelist.txt
BLACKLIST=/blacklist.txt
#THIS WILL CLEAR ALL EXISTING RULES!
echo 'Clearing all rules'
iptables -F
#
## Whitelist
#
for x in `grep -v ^# $WHITELIST | awk '{print $1}'`; do
echo "Permitting $x..."
$IPTABLES -A INPUT -t filter -s $x -j ACCEPT
done
#
## Blacklist
#
for x in `grep -v ^# $BLACKLIST | awk '{print $1}'`; do
echo "Denying $x..."
$IPTABLES -A INPUT -t filter -s $x -j DROP
done
#!/bin/bash
ALLOWEDTCP="80 3128 3784"
ALLOWEDUDP="3128 3784"
#
## Permitted Ports
#
for port in $ALLOWEDTCP; do
echo "Accepting port TCP $port..."
$IPTABLES -A INPUT -t filter -p tcp --dport $port -j ACCEPT
done
for port in $ALLOWEDUDP; do
echo "Accepting port UDP $port..."
$IPTABLES -A INPUT -t filter -p udp --dport $port -j ACCEPT
done
# Attempt to block portscans
# Anyone who tried to portscan us is locked out for an entire day.
iptables -A INPUT -m recent --name portscan --rcheck --seconds 86400 -j DROP
iptables -A FORWARD -m recent --name portscan --rcheck --seconds 86400 -j DROP
# Once the day has passed, remove them from the portscan list
iptables -A INPUT -m recent --name portscan --remove
iptables -A FORWARD -m recent --name portscan --remove
# These rules add scanners to the portscan list, and log the attempt.
iptables -A INPUT -p tcp -m tcp --dport 139 -m recent --name portscan --set -j LOG --log-prefix "Portscan:"
iptables -A INPUT -p tcp -m tcp --dport 139 -m recent --name portscan --set -j DROP
iptables -A FORWARD -p tcp -m tcp --dport 139 -m recent --name portscan --set -j LOG --log-prefix "Portscan:"
iptables -A FORWARD -p tcp -m tcp --dport 139 -m recent --name portscan --set -j DROP
# Reject spoofed packets
# These adresses are mostly used for LAN's, so if these would come to a WAN-only server, drop them.
iptables -A INPUT -s 10.0.0.0/8 -j DROP
iptables -A INPUT -s 169.254.0.0/16 -j DROP
iptables -A INPUT -s 172.16.0.0/12 -j DROP
iptables -A INPUT -s 127.0.0.0/8 -j DROP
#Multicast-adresses.
iptables -A INPUT -s 224.0.0.0/4 -j DROP
iptables -A INPUT -d 224.0.0.0/4 -j DROP
iptables -A INPUT -s 240.0.0.0/5 -j DROP
iptables -A INPUT -d 240.0.0.0/5 -j DROP
iptables -A INPUT -s 0.0.0.0/8 -j DROP
iptables -A INPUT -d 0.0.0.0/8 -j DROP
iptables -A INPUT -d 239.255.255.0/24 -j DROP
iptables -A INPUT -d 255.255.255.255 -j DROP
# Drop all invalid packets
iptables -A INPUT -m state --state INVALID -j DROP
iptables -A FORWARD -m state --state INVALID -j DROP
iptables -A OUTPUT -m state --state INVALID -j DROP
# Stop smurf attacks
iptables -A INPUT -p icmp -m icmp --icmp-type address-mask-request -j DROP
iptables -A INPUT -p icmp -m icmp --icmp-type timestamp-request -j DROP
iptables -A INPUT -p icmp -m icmp -j DROP
# Drop excessive RST packets to avoid smurf attacks
iptables -A INPUT -p tcp -m tcp --tcp-flags RST RST -m limit --limit 2/second --limit-burst 2 -j ACCEPT
# Don't allow pings through
iptables -A INPUT -p icmp -m icmp --icmp-type 8 -j DROP
iptables
다음 라인 (8)에, 그리고 $IPTABLES
나중에. iptables
어디에서나 사용하기에 충분 합니까? 그렇지 않으면 IPTABLES=/sbin/iptables
오른쪽 과 같은 것을 할당해야한다고 생각 합니까?
ipset
단순한 IP, 포트 또는 둘 모두를 기반으로 많은 유사한 규칙 을 작성하는 경우 ipset
netfilter 성능을 최적화 하는 데 사용하는 것이 좋습니다.
예를 들면 다음과 같습니다.
iptables -s 192.168.1.11 -j ACCEPT
iptables -s 192.168.1.27 -j ACCEPT
iptables -s 192.168.1.44 -j ACCEPT
... hundreds of similar rules ...
iptables -s 192.168.251.177 -j ACCEPT
즉, 소스 주소가 192.168.251.177 인 패킷 은 ACCEPT의 판정을 받기 전에 먼저 수백 개의 규칙을 통과해야합니다 .
물론 숙련 된 sysadmin은 규칙을 서브넷별로 분할합니다. 그러나 그것은 여전히 수백 가지 규칙을 의미합니다.
ipset
구조에!
먼저 다음 ipmap
유형 의 IP 세트를 정의하십시오 .
ipset -N Allowed_Hosts ipmap --network 192.168.0.0/16
그런 다음 주소로 채우십시오.
for ip in $LIST_OF_ALLOWED_IP; do ipset -A Allowed_Hosts $ip; done
마지막으로, 위의 수백 가지 iptables 규칙을 하나의 규칙 으로 바꾸십시오 .
iptables -m set --match-set Allowed_Hosts src -j ACCEPT
패킷이 도착하면 netfilter는 IP 세트 에 대한 패킷 소스 (src) IP에 대한 매우 빠른 비트 맵 검색을 수행합니다 Allowed_Hosts
. 192.168.0.0/16에서 오는 모든 패킷에는 하나의 규칙이 적용됩니다. 비트 맵을 검색하는 것이 수백 개의 iptables 규칙 검사를 수행하는 것보다 적어도 2 배 빠릅니다.
ipset
IP 주소로 제한되지 않습니다. 또한 포트, IP 포트 튜플, 네트워크 / 서브넷 주소, IP-MAC 튜플 등을 기반으로 일치시킬 수 있습니다. 그리고이 기준을 소스 또는 대상 또는 둘의 혼합으로 일치시킬 수 있습니다 (튜플의 경우).
마지막 ipset
으로 IP 주소를 블랙리스트 / 화이트리스트에 자동으로 넣을 수 있습니다. 이러한 블랙리스트 / 화이트리스트는 '연령'될 수 있으므로 구성 가능한 시간이 지난 후 IP 주소를 자동으로 삭제합니다.
자세한 내용은 ipset
의 매뉴얼 페이지 를 참조하십시오.
일부 Linux 배포판 은 ' 즉석에서 '지원 하지 않을 수 있습니다 ipset
(예 : Ubuntu 10.04에이 문제가 있음). 이러한 시스템에서 한 가지 방법은 ipset
소스 코드에서 설치 하는 것입니다.
대신 ipset
웹 사이트 ( http://ipset.netfilter.org/install.html) 에서 소스를 다운로드하십시오 .
또는을 사용 xtables-addons
하면 ipset 이 해당 소스에 포함됩니다. http://xtables-addons.sourceforge.net/
다음 규칙을 추가하십시오. -t raw -A PREROUTING
-p tcp --tcp-flags FIN,SYN FIN,SYN -j DROP
-p tcp --tcp-flags SYN,RST SYN,RST -j DROP
-p tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN,PSH,URG -j DROP
-p tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN -j DROP
-p tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -j DROP
-p tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN,SYN,RST,PSH,ACK,URG -j DROP
차단되는 공격은 각각 다음과 같습니다.
(위의 공격 이름을 자유롭게 편집하십시오)
-p tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN,SYN,RST,PSH,ACK,URG -j DROP
(가)와 같이 제거 될 수 -p tcp --tcp-flags FIN,SYN FIN,SYN -j DROP
는 차단할 수있는 모든 패킷을 잡을 것입니다.
echo 1 > /proc/sys/net/ipv4/ip_forward
/sbin/iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
1 단계는 ip 전달을 허용하도록 커널 매개 변수를 설정하고 2 단계는 인터페이스 eth0에서 NAT를 사용 가능하게하는 iptables 규칙을 설정합니다.
/etc/sysctl.conf
net.ipv4.ip_forward = 1
. (Red Hat 또는 파생 상품을 가정합니다.)
다음 규칙을 추가하십시오. -t raw -A PREROUTING
-p icmp -m u32 ! --u32 "4&0x3FFF=0" -j DROP
-p icmp -m length --length 1492:65535 -j DROP
첫 번째 규칙 블록 그의 모든 ICMP 패킷은 "분열 플래그가"0 아닌 (ICMP이해야 결코 분열되지 그들은 작은 페이로드를 운반한다)
두 번째 규칙은 크기가 큰 조각화되지 않은 ICMP 패킷을 차단합니다.
FireHOL 사용 -편리한 iptables 래퍼
직접 iptables 명령보다 훨씬 직관적이라는 것을 알았습니다. 특히 다른 방화벽에 대한 경험이있는 사람들에게 :
FireHOL은 Linux 호스트 및 라우터에서 네트워크 인터페이스, 경로 수, 서비스 수, 서비스 변형 사이의 복잡성 (긍정적 및 부정적 포함)이있는 상태 저장 IPtables 패킷 필터링 방화벽을 생성하는 iptables 방화벽 생성기입니다. 식).
(내 iptables_tricks.txt 파일에서 많은 장소에서 다시 컴파일 : P)
포트 22 (SSH)의 동일한 IP에서 새 연결간에 iptables가 15 초 동안 대기하도록합니다.
iptables -A INPUT -p tcp -i eth0 -m state --state NEW --dport 22 -m recent --update --seconds 15 -j DROP
iptables -A INPUT -p tcp -i eth0 -m state --state NEW --dport 22 -m recent --set -j ACCEPT
-A INPUT -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH
-A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 5 --rttl --name SSH -j DROP
IPTABLES 비디오 자습서
에피소드 1 http://www.youtube.com/watch?v=ldB8kDEtTZA&feature=player_embedded
에피소드 2 http://www.youtube.com/watch?v=aDaEXxRHeXY&feature=related
마지막 에피소드
http://www.youtube.com/watch?v=JojqHKcSxpo&feature=player_embedded
초보자에게는 좋은 출발점이 될 것입니다.
IP 세트에 대한 답변이 이미 있습니다. 그러나 고전적인 규칙에 비해 성능이 향상되고 IP 세트가 CIDR 표기법의 서브넷으로 쉽게 표현할 수없는 많은 개별 IP 주소로 인해 발생하는 문제를 완화한다는 사실에 중점을 둔다는 점에서 다소 일차원 적입니다.
들어 ipset
나는 표기 읽을 사용 ipset restore
에 의해 작성을 ipset save
.
상응 위해 iptables
(그리고 ip6tables
읽을로) 규칙 나는 표기법을 사용 iptables-restore
하고 작성한 iptables-save
. 이것은 더 짧은 표기법을 만들고 잠재적 인 IPv4 전용 (접두사 -4
) 또는 IPv6 전용 (접두사 -6
) 규칙 을 강조 할 수있게합니다 .
일부 예에서는 패킷 흐름을 다른 체인으로 전환합니다. 체인은 해당 시점에 존재한다고 가정되므로 체인을 생성하는 선은 생성되지 않습니다 (표 이름이나 언급 된 명령도 없음 COMMIT
).
IP 세트는 다른 답변 에서 언급 한 것보다 훨씬 많은 작업을 수행 할 수 있으므로 여기에 간단한 항목 ipset(8)
과 함께 IP 세트 설명서 ( )를 반드시 읽어야합니다 iptables-extensions(8)
.
예를 들어, 주로 세 가지 유형 ( hash:ip
, hash:net
및) 에 중점을 list:set
두지 만 그 이상의 유형 이 있으며 모두 유효한 사용 사례가 있습니다.
예를 들어 IP 주소뿐만 아니라 포트 번호 도 일치시킬 수 있습니다 .
iptables-save
하고iptables-restore
IP 세트 선언을 대량으로 작성하고로 파이프하여 가져올 수 있습니다 ipset restore
. 기존 항목에 대해 명령의 복원성을 높이려면을 사용하십시오 ipset -exist restore
.
규칙이 파일이라는 파일에있는 경우 다음을 default.set
사용하십시오.
ipset -exist restore < default.set
이와 같은 파일에는 create
설정할 add
항목 과 항목을 포함 할 수 있습니다 . 그러나 일반적으로 명령 행의 대부분의 명령은 파일에 해당 버전이있는 것 같습니다. 예 (DNS 서버 세트 작성) :
create dns4 hash:ip family inet
create dns6 hash:ip family inet6
# Google DNS servers
add dns4 8.8.8.8
add dns4 8.8.4.4
add dns6 2001:4860:4860::8888
add dns6 2001:4860:4860::8844
여기서는 IPv4 ( dns4
) 용 세트 와 IPv6 ( dns6
) 용 세트가 생성됩니다 .
IP 세트의 시간 초과는 세트당 및 항목별로 기본값으로 설정할 수 있습니다. 이는 누군가를 일시적으로 차단하려는 시나리오 (예 : 포트 스캔 또는 SSH 서버 무차별 강제 시도)에 매우 유용합니다.
작동 방식은 다음과 같습니다 (IP 세트 작성 중 기본값).
create ssh_loggedon4 hash:ip family inet timeout 5400
create ssh_loggedon6 hash:ip family inet6 timeout 5400
create ssh_dynblock4 hash:ip family inet timeout 1800
create ssh_dynblock6 hash:ip family inet6 timeout 1800
우리는 아래의 특정 세트로 돌아가서 왜 그들이 원래대로 설정되었는지에 대한 이론적 근거로 돌아갑니다.
특정 IP 주소에 대한 시간 초과를 설정하려면 간단히 다음과 같이 말할 수 있습니다.
add ssh_dynblock4 1.2.3.4 timeout 7200
기본 설정된 30 분 대신 2 시간 동안 IP 1.2.3.4를 차단합니다.
당신이 그 본다면 ipset save ssh_dynblock4
잠시 후, 당신의 라인을 따라 뭔가를 볼 것입니다 :
create ssh_dynblock4 hash:ip family inet hashsize 1024 maxelem 65536 timeout 1800
add ssh_dynblock4 1.2.3.4 timeout 6954
Kernel error received: Unknown error -1
됩니다.sudo ipset add ssh_dynblock4 1.2.3.4 timeout $((120*60))
스크립트 내에서 항목이 이미 존재하는지 확인하는 것이 유용 할 수 있습니다. 이것은 ipset test
항목이 존재하면 0을 리턴하고 그렇지 않으면 0이 아닌 값을 리턴 하여 달성 될 수 있습니다 . 따라서 일반적인 검사를 스크립트에 적용 할 수 있습니다.
if ipset test dns4 8.8.8.8; then
echo "Google DNS is in the set"
fi
그러나 대부분의 경우 기존 항목에 대해 불평하지 않도록 -exist
스위치를 사용하는 것이 좋습니다 ipset
.
iptables
규칙 에서 IP 세트 채우기내 생각에 이것은 IP 세트의 킬러 기능 중 하나입니다. IP 세트의 항목과 일치 할 수있을뿐만 아니라 기존 IP 세트에 새 항목을 추가 할 수도 있습니다.
예를 들어이 질문에 대한 이 답변 에는 다음이 있습니다.
-A INPUT -p tcp -i eth0 -m state --state NEW --dport 22 -m recent --update --seconds 15 -j DROP
-A INPUT -p tcp -i eth0 -m state --state NEW --dport 22 -m recent --set -j ACCEPT
... SSH (TCP 포트 22)에 대한 연결 시도를 속도 제한하려는 의도로. 사용 된 모듈 recent
은 최근 연결 시도를 추적합니다. 그러나 state
모듈 대신 모듈을 선호합니다 conntrack
.
# Say on your input chain of the filter table you have
-A INPUT -i eth+ -p tcp --dport ssh -j SSH
# Then inside the SSH chain you can
# 1. create an entry in the recent list on new connections
-A SSH -m conntrack --ctstate NEW -m recent --set --name tarpit
# 2. check whether 3 connection attempts were made within 2 minutes
# and if so add or update an entry in the ssh_dynblock4 IP set
-4 -A SSH -m conntrack --ctstate NEW -m recent --rcheck --seconds 120 --hitcount 3 --name tarpit -j SET --add-set ssh_dynblock4 src --exist
-6 -A SSH -m conntrack --ctstate NEW -m recent --rcheck --seconds 120 --hitcount 3 --name tarpit -j SET --add-set ssh_dynblock6 src --exist
# 3. last but not least reject the packets if the source IP is in our
# IP set
-4 -A SSH -m set --match-set ssh_dynblock4 src -j REJECT
-6 -A SSH -m set --match-set ssh_dynblock6 src -j REJECT
이 경우 흐름을 SSH
체인으로 리디렉션하여 -p tcp --dport ssh
모든 단일 규칙마다 반복 할 필요가 없습니다 .
반복해서 :
-m set
만드는 iptables
우리가에서 스위치를 사용하고 있는지 알고 set
(이이 IP 세트를 처리) 모듈--match-set ssh_dynblock4 src
소스 ( ) 주소를 명명 된 세트 ( )
iptables
와 일치 시키도록 지시 합니다.src
ssh_dynblock4
sudo ipset test ssh_dynblock4 $IP
( $IP
패킷의 소스 IP 주소를 포함)에 해당합니다.-j SET --add-set ssh_dynblock4 src --exist
추가하거나 업데이트 소스 ( src
는 IP 세트로 패킷에서) 주소를 ssh_dynblock4
. 항목이 있으면 ( --exist
) 간단히 업데이트됩니다.
sudo ipset -exist add ssh_dynblock4 $IP
( $IP
패킷의 소스 IP 주소를 포함)에 해당합니다.대신 대상 / 목적지 주소를 일치 시키려면 dst
대신을 사용하십시오 src
. 추가 옵션에 대해서는 설명서를 참조하십시오.
IP 세트는 다른 세트를 포함 할 수 있습니다. 이제 여기까지 기사를 따라 가면 세트를 결합 할 수 있는지 궁금 할 것입니다. 물론 그렇습니다. 위의 IP 세트의 경우 두 개의 조인트 세트를 작성 ssh_dynblock
하고 ssh_loggedon
각각 IPv4 전용 및 IPv6 전용 세트를 포함 할 수 있습니다 .
create ssh_loggedon4 hash:ip family inet timeout 5400
create ssh_loggedon6 hash:ip family inet6 timeout 5400
create ssh_dynblock4 hash:ip family inet timeout 1800
create ssh_dynblock6 hash:ip family inet6 timeout 1800
# Sets of sets
create ssh_loggedon list:set
create ssh_dynblock list:set
# Populate the sets of sets
add ssh_loggedon ssh_loggedon4
add ssh_loggedon ssh_loggedon6
add ssh_dynblock ssh_dynblock4
add ssh_dynblock ssh_dynblock6
그리고 다음 질문 은 IP 버전에 관계없이 IP 세트 를 일치 시키고 조작 할 수 있는지 여부 입니다.
그리고 그것에 대한 대답은 소리입니다 : 예! (아아, 이것은 내가 마지막으로 확인했을 때 명시 적으로 문서화되지 않았습니다)
결과적으로 이전 섹션의 규칙을 다시 작성하여 읽을 수 있습니다.
-A INPUT -i eth+ -p tcp --dport ssh -j SSH
-A SSH -m conntrack --ctstate NEW -m recent --set --name tarpit
-A SSH -m conntrack --ctstate NEW -m recent --rcheck --seconds 120 --hitcount 3 --name tarpit -j SET --add-set ssh_dynblock src --exist
-A SSH -m set --match-set ssh_dynblock src -j REJECT
훨씬 간결합니다. 그리고 네, 이것은 시도되고 테스트되었으며 매력처럼 작동합니다.
내 서버 cron
에는 많은 호스트 이름을 가져 와서이를 IP 주소로 확인한 다음 "신뢰할 수있는 호스트"에 대한 IP 세트로 공급 하는 작업 으로 스크립트 실행이 있습니다. 아이디어는 신뢰할 수있는 호스트가 서버에 더 많은 로그인을 시도하고 다른 사람만큼 차단 될 필요는 없다는 것입니다.
반대로 신뢰할 수있는 호스트 (예 : 규칙 순서)를 제외한 (잠재적 인) 예외를 제외하고 전체 국가에서 SSH 서버에 연결하는 것을 차단했습니다.
그러나 그것은 독자의 연습으로 남아 있습니다. 여기에 ssh_loggedon
후속 연결 시도를 처리하고 다른 패킷과 동일한 검사를받지 않도록 세트에 포함 된 세트를 사용하는 깔끔한 솔루션을 추가하고 싶습니다 .
다음 규칙 ssh_loggedon
을 볼 ssh_dynblock
때 기본 시간 제한은 90 분 및 30 분입니다 iptables
.
-A INPUT -i eth+ -p tcp --dport ssh -j SSH
-A SSH -m set --match-set ssh_loggedon src -j ACCEPT
-A SSH -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A SSH -m conntrack --ctstate NEW -m recent --set --name tarpit
-A SSH -m conntrack --ctstate NEW -m recent --rcheck --seconds 120 --hitcount 3 --name tarpit -j SET --add-set ssh_dynblock src --exist
-A SSH -m set --match-set ssh_dynblock src -j REJECT
이제 연결 IP 주소가 ssh_loggedon
하위 세트 에서 어떻게 끝나는 지 스스로에게 물어야 합니다. 그래서 읽어보십시오 ...
sshrc
친구 와 실험을했다면 그 단점에 대해 알게 될 것입니다. 그러나 PAM이 구출되었습니다. 명명 된 모듈을 pam_exec.so
사용하면 SSH 로그온 중에 사용자가 입장했음을 알 수있는 지점에서 스크립트를 호출 할 수 있습니다.
에서 /etc/pam.d/sshd
다음 pam_env
과 pam_selinux
항목은 다음 줄을 추가합니다 :
session optional pam_exec.so stdout /path/to/your/script
스크립트 버전 ( /path/to/your/script
위)이 존재하고 실행 가능한지 확인하십시오 .
PAM은 환경 변수를 사용하여 진행중인 작업을 전달하므로 다음과 같은 간단한 스크립트를 사용할 수 있습니다.
#!/bin/bash
# When called via pam_exec.so ...
SETNAME=ssh_loggedon
if [[ "$PAM_TYPE" == "open_session" ]] && [[ -n "$PAM_RHOST" ]]; then
[[ "x$PAM_RHOST" != "x${PAM_RHOST//:/}" ]] && SETNAME="${SETNAME}6" || SETNAME="${SETNAME}4"
ipset -exist add $SETNAME "$PAM_RHOST"
fi
불행히도이 ipset
유틸리티에는 내장형 netfilter가없는 것 같습니다. 따라서 항목을 추가 할 때 IPv4와 IPv6 IP 세트를 구별해야합니다. 그렇지 않으면 IP 대신 ipset
다른 세트 를 세트 세트 에 추가한다고 가정 합니다. 물론 IP의 이름을 딴 세트가있을 가능성은 거의 없습니다. :)
그래서 우리 :
는 IP 주소를 확인 6
하고 그러한 경우와 4
그렇지 않으면 세트 이름에 추가 합니다 .
끝.
iptables를 구성하는 데 사용할 수있는 또 다른 GUI는 Firewall Builder 입니다. 사용자는 데이터베이스에서 규칙 요소를 개체로 만든 다음 이러한 개체를 규칙 편집기로 끌어서 놓아 원하는 방화벽 정책을 만들 수 있습니다. 그런 다음 응용 프로그램은 규칙을 구현하는 데 필요한 모든 iptables 명령으로 스크립트 파일을 생성합니다.
한 번에 하나의 iptables 구성 만 관리 할 수있는 다른 iptables GUI 솔루션과 달리 Firewall Builder를 사용하면 단일 애플리케이션에서 많은 수의 iptables 구성을 관리 할 수 있습니다. Firewall Builder는 Linux, Windows 및 Mac OS X에서 실행되며 10 년 이상 사용되어 왔으며 전 세계에 수천 명의 활동중인 사용자가 있습니다.
전체 공개-저는 방화벽 빌더를 개발하는 회사 인 NetCitadel의 공동 설립자입니다.
uid로 나가는 연결 로그
iptables -A OUTPUT -m state --state NEW -m tcp -p tcp -m limit --limit 5/m -j LOG --log-uid --log-prefix="outgoing connection: "
포트 / 연결 전달 :
iptables -A PREROUTING -t nat -i eth1 -p tcp --dport 80 -j DNAT --to 10.0.1.7:80
iptables -A INPUT -p tcp -m state --state NEW --dport 80 -i eth1 -j ACCEPT
NFLOG
목표를 선호한다 . 더 긴 줄 접두어를 허용하고 사용자 모드 데몬도 데이터베이스에 기록 할 수 있습니다.
예 : 당신이 eth0
와 eth1
그들 사이의 트래픽을 허용 하시겠습니까?
iptables -A FORWARD -i eth+ -o eth+ -j ACCEPT
veth<something>
LXC에 의해 동적으로 생성되고 명명 된 인터페이스 와 일치시키기 위해 과거에 이것을 사용했습니다 . 한 번에와 일치시킬 수 있습니다 veth+
.
또한 의도적으로 약간의 인터페이스 이름 _<something>
에 대해 일치하기 위해 _+
.
iptables -t mangle -A PREROUTING -p tcp \
-m conntrack --ctstate NEW -m tcpmss ! --mss 536:65535 -j DROP
이 대상의 목적은 SYN 패킷을 보낸 호스트가 연결을 설정했는지 또는 SYN 연결을 시작한 후 아무것도 수행하지 않는지 확인하는 것입니다. 아무 것도하지 않으면 최소한의 노력으로 패킷을 버립니다.
원시 테이블의 연결 추적 테이블로 syn 패킷 설정
iptables -t raw -A PREROUTING -p tcp -m tcp --dport 80 --syn -j CT --notrack
http 서버에 대해 synproxy를 사용하십시오.
iptables -A INPUT -p tcp -m tcp --dport 80 -m conntrack --ctstate INVALID,UNTRACKED \
-j SYNPROXY --sack-perm --timestamp --wscale 7 --mss 1460
리소스 : RHEL 블로그의 SYNPROXY 대상
IP 세트를 사용하여 모든 개별 IP 주소를 아웃 바운드 대역폭 할당량으로 제한
ISP의 측정 된 대역폭 할당량에 대한 대역폭 사용 공격을 반영하거나 회피하기 위해 매월 각 개별 IP 15GiByte 대역폭 사용 만 허용하도록 서버를 구성 할 수 있습니다. 다음과 같이 수행 할 수 있습니다.
먼저 IPv4 및 IPv6에 대한 IP 세트를 작성하십시오.
ipset create IP_QUOTA_SET_OUT hash:ip timeout 345600 counters
ipset create IP_QUOTA_SET_OUT_INET6 hash:ip timeout 345600 counters family inet6
이제 iptables 규칙을 추가하십시오. 첫 번째 줄은 IP가없는 경우 세트에 IP를 추가합니다. 세트의 IP에 대해 전송 된 바이트가 지정된 양보다 큰 경우 두 번째 행은 일치하지 않습니다. 그런 다음 IPv6에서도 동일하게 수행됩니다.
iptables -I OUTPUT -m set ! --match-set IP_QUOTA_SET_OUT dst -j SET --add-set IP_QUOTA_SET_OUT dst --timeout 345600
iptables -I OUTPUT -m set --match-set IP_QUOTA_SET_OUT dst --bytes-gt 16106127360 -j DROP
ip6tables -I OUTPUT -m set ! --match-set IP_QUOTA_SET_OUT_INET6 src -j SET --add-set IP_QUOTA_SET_OUT_INET6 src --timeout 345600
ip6tables -I OUTPUT -m set --match-set IP_QUOTA_SET_OUT_INET6 src --bytes-gt 16106127360 -j DROP
이렇게하면 사용자가 웹 서버에서 오랫동안 큰 파일을 요청하거나 해당 문제에 대한 서비스와 같은 공격을 막을 수 있습니다. INPUT 체인에 대해서도 동일하게 수행 할 수 있습니다.
더 우아한 솔루션에 대한 무지 때문에 주로해야 할 일은 4 시간마다 Nginx 로그를 수동으로 확인하고 메일 서버 로그는 2 분마다 개별 IP로 과도한 액세스를하는 것입니다. 나는 몇 가지 스크립트를 함께 실행합니다.
access.log
서버에 적중 횟수를 기준으로 상위 10 개 IP 구성iptables.save
그 모습은 다음과 같습니다.
autoBanIPs_mail.sh#!/bin/bash
# This script checks the last 2 minutes of log entries to see if any
# IP has made over 99 connections
now=$(date +"%m_%d_%Y")
/root/bin/checkBadIPs_mail.sh > /home/ipChecker/ipcheckMAIL_$now.txt
cat /home/ipChecker/ipcheckMAIL_$now.txt | \
grep " \\(\\([9][9]\\)\\|\\([0-9][0-9][0-9]\\+\\)\\) " | \
awk '{print $2}' > /home/ipChecker/badMailIPs_$now.sh
sed -i "s/^/\/usr\/local\/sbin\/blockIP /g" /home/ipChecker/badMailIPs_$now.sh
/bin/bash /home/ipChecker/badMailIPs_$now.sh
cat /home/ipChecker/ipcheckMAIL_$now.txt >> /home/ipChecker/ipcheckMAIL_$now.log
rm /home/ipChecker/ipcheckMAIL_$now.txt
rm /home/ipChecker/badMailIPs_$now.sh
checkBadIPs_mail.sh
여기서 주목해야 할 중요한 사항 중 하나는 화이트리스트를 설정해야하거나 다른 로그에서 많은 전자 메일을 받거나 다른 로그의 경우 IP에서 정당한 이유로 서버에 많은 피해를 입 힙니다. 내 화이트리스트는 방금 grep 파이프를 추가하여이 스크립트에 내장되었습니다. | grep ']' | 즉,이 같은 것을 보면 "127.0 -v 그렙 |" .
트래픽이 많은 IP 중 어느 것이 합법적이고 그렇지 않은지를 서버에 알려주려면 시간이 필요합니다. 나에게 이것은 첫 주를 보내야 두 시간마다 수동으로 로그를 확인하고 iplocation.net에서 트래픽이 많은 IP를 찾은 다음 amazon, box.com 또는 심지어 내 집 / 사무실과 같은 합법적 인 IP를 추가해야했습니다. IP 범위는이 화이트리스트입니다. 그렇지 않으면 자신의 서버에서 차단되거나 합법적 인 메일 / 웹 서버 차단을 시작하여 전자 메일 또는 트래픽이 중단 될 수 있습니다.
cat /var/log/mail.log | awk \
-v d1="$(date --date="-2 min" "+%b %_d %H:%M")" \
-v d2="$(date "+%b %_d %H:%M")" \
'$0 > d1 && $0 < d2 || $0 ~ d2' | \
grep '\[' | grep '\]' | \
grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | grep -v 127.0 | \
awk '{print $1}' | sort | uniq -c | sort -n | tail -10
BlockIP
#!/bin/bash
sudo iptables -I INPUT -s $1 -j DROP
sudo bash -c "iptables-save > /etc/network/iptables.save"
다시 한 번 나는 이것이 지옥처럼 조잡하다는 것을 알고 있으며 아마도이 모든 것을하는 좋은 깨끗하고 효율적인 프로토콜이있을 것입니다.하지만 그것에 대해 몰랐습니다. 이것은 1 ~ 2 년 동안 진행되어 나쁜 사람들을 막아줍니다. 제가 매우 심각하게 추천하는 한 가지는 메인 서버에 액세스하는 데 사용할 수있는 프록시 또는 다른 서버가 있다는 것입니다. 그 이유는 웹 개발을 하루 종일 웹 개발을하고 있다면 프록시를 제외하고는 어떤 방법으로도 막을 수있는 몇 가지 테스트에 대해 5 시간 동안 2000 번 자신을 핑 (ping)합니다.
당신은에서 볼 수 있습니다 checkBadIPs.sh
업데이트하는 것을 잊지, 내가 그렙 -v 127.0 내 실제 파일에 넣었습니다 난 내 자신의 IP의 규칙 및 기타 신뢰할 수있는 IP 범위하지만 때로는 사용자의 IP 변경 사항을 무시의 톤을 가지고 있고 당신은 잠겨있어 자신의 서버에서.
어쨌든 도움이되기를 바랍니다.
몇 시간마다 점검하는 대신 2 분마다 몇 가지 로그를 확인하도록 주로 ssh 인증 로그와 메일 로그가 두들겨 졌을 때 :(.
로그를 검사하고 싶을 때 직접 사용하는 수동 스크립트로는 충분하지만 각 로그 파일에 대해 특정 스크립트를 설정했습니다. 다음과 같습니다 :
#!/bin/bash
log=$1 time=$2
cat /var/log/${log} | awk \
-v d1="$(date --date="-${time} min" "+%b %_d %H:%M")" \
-v d2="$(date "+%b %_d %H:%M")" \
'$0 > d1 && $0 < d2 || $0 ~ d2' | \
grep '\[' | grep '\]' | \
grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | \
sort | uniq -c | sort -n | tail -10
실행시 두 개의 입력, 스캔하려는 로그 파일 및 스캔하려는 과거로의 거리가 필요합니다.
그래서 ip 카운트에 대해 mail.log를 확인하고 싶다면 75 분이 지나야합니다.
$ sudo script.sh mail.log 75
ipset
iptables 체인을 늘리는 대신 사용 하지만 아이디어는 훌륭하므로 프로덕션 서버에 적용 할 것이라고 생각합니다. 공유해 주셔서 감사합니다!
ipsets 및 tcp 플래그에 대한 의견에 동의하지만 여전히 많은 부분이 누락되었습니다.
국가 목록에는 ipsets 대신 xtables-addons geoip match를 사용하십시오. 적어도 한 달에 한 번은 geoip 데이터를 정기적으로 업데이트하십시오. 데이터는 fire-and-getget ipset 목록보다 더 동적입니다.
tcp 플래그로 연결 상태 추적을 고려하십시오. 예를 들어, tcp RST 또는 ACK는 설정된 연결에만 의미가 있습니다. SYN은 새 연결 및 관련 연결에만 적합합니다. 설정된 연결에 대한 SYN은 SYN + ACK가 유실되었거나 해킹 시도를 의미하며 연결의 양쪽이 상태에 동의하지 않기 때문에 재설정되어야합니다.
SYN + RST와 FIN + RST는 모두 잘못된 조합이지만 SYN + FIN은 현재 TCP 빠른 열기 (TCP 옵션 34), 특히 DNS에서 유효합니다. SYN 패킷은 빠른 열림에도 불구하고 조각화되어서는 안됩니다. PSH 및 URG 플래그가있는 규칙은 유용하다고 생각하지 않습니다. 연결 추적 상태와 TCP 상태를 혼동하지 마십시오. SYN 패킷에 대한 RST 응답은 추적 목적으로 설정됩니다.
SYNPROXY는 전달 된 패킷을위한 것으로, syncookie 지원 이외의 로컬로 전달 된 패킷에는 아무것도 추가하지 않습니다.
ICMP 오류 패킷은 항상 관련 상태이며 길이가 48 : 576 인 경우 유효합니다. IPv6의 경우 길이 84 : 1280 다른 모든 것은 무시해야합니다. 최대 크기도 최소 MTU이므로 조각화해서는 안됩니다. ICMP 요청 (핑, 타임 스탬프 등)은 항상 새로운 것이며 응답이 설정됩니다. 다른 상태에서는 ICMP 패킷을 삭제하십시오.
최근 목록이 있고 후속 SYN 패킷 만 수락하는 SSH 예제와 마찬가지로 SMTP에서도 동일하게 수행해야하며 IP 주소 데이텀 만 "그레이리스트"와 유사합니다.
필터 테이블에서 입력 및 출력 체인의 첫 번째 (또는 설정된 상태 패킷을 먼저 수락하는 경우 두 번째) 규칙은 루프백 인터페이스의 모든 항목을 수락해야합니다. 내부 패킷을 신뢰해야합니다. 당신이 할 수 없다면, 당신은 방화벽 솔루션보다 더 큰 문제가 있습니다.
마지막으로, 규칙을 실제로 이해하지 않으면 맹목적으로 복사하지 마십시오. 많은 유사한 규칙 목록이 그렇게하며 대부분의 경우 결과는 웃기게됩니다.
#!/bin/bash
# The following iptables/ip6tables configurations have
# been kindly shared with us from ArckWiki. There are
# a few additions apart from what has been defined.
#
#=================Flush current definitions==============
iptables -F
ip6tables -F
iptables -X
ip6tables -X
#
#=================Chains=================================
#
#----Define chains for opened ports
iptables -N TCP
ip6tables -N TCP
iptables -N UDP
ip6tables -N UDP
#
#----Setting up the filter table for NAT
# iptables -N fw-interfaces
# ip6tables -N fw-interfaces
# iptables -N fw-open
# ip6tables -N fw-open
#
#================Default Chain reactions=================
#
#----Default FORWARD reaction
iptables -P FORWARD DROP
ip6tables -P FORWARD DROP
#
#----Default OUTPUT reaction
iptables -P OUTPUT ACCEPT
ip6tables -P OUTPUT ACCEPT
#
#----Shellshock
iptables -A INPUT -m string --algo bm --hex-string '|28 29 20 7B|' -j DROP
ip6tables -A INPUT -m string --algo bm --hex-string '|28 29 20 7B|' -j DROP
#
#----Default INPUT reaction
iptables -P INPUT DROP
ip6tables -P INPUT DROP
#
#----Drop spoofing packets
iptables -A INPUT -i eth0 -s 127.0.0.0/8 -j DROP
iptables -A INPUT -i wlan0 -s 127.0.0.0/8 -j DROP
iptables -A INPUT -i wlan1 -s 127.0.0.0/8 -j DROP
iptables -A INPUT -s 10.0.0.0/8 -j DROP
iptables -A INPUT -s 169.254.0.0/16 -j DROP
iptables -A INPUT -s 172.16.0.0/12 -j DROP
iptables -A INPUT -s 224.0.0.0/4 -j DROP
iptables -A INPUT -d 224.0.0.0/4 -j DROP
iptables -A INPUT -s 240.0.0.0/5 -j DROP
iptables -A INPUT -d 240.0.0.0/5 -j DROP
iptables -A INPUT -s 0.0.0.0/8 -j DROP
iptables -A INPUT -d 0.0.0.0/8 -j DROP
iptables -A INPUT -d 239.255.255.0/24 -j DROP
iptables -A INPUT -d 255.255.255.255 -j DROP
#
#================Ping rate limiting globally=============
iptables -A INPUT -p icmp --icmp-type 8 -m limit --limit 30/min --limit-burst 8 -j ACCEPT
ip6tables -A INPUT -p icmpv6 --icmpv6-type 8 --match limit --limit-burst 8 -j ACCEPT
iptables -A INPUT -p icmp --icmp-type 8 -j DROP
ip6tables -A INPUT -p icmpv6 --icmpv6-type 8 -j DROP
#
#----flooding RST packets, smurf attack Rejection
iptables -A INPUT -p tcp -m tcp --tcp-flags RST RST -m limit --limit 2/second --limit-burst 2 -j ACCEPT
ip6tables -A INPUT -p tcp -m tcp --tcp-flags RST RST -m limit --limit 2/second --limit-burst 2 -j ACCEPT
#
#----Bogus packet DROP
iptables -A INPUT -p tcp -m tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
ip6tables -A INPUT -p tcp -m tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
iptables -A INPUT -p tcp -m tcp --tcp-flags SYN,RST SYN,RST -j DROP
ip6tables -A INPUT -p tcp -m tcp --tcp-flags SYN,RST SYN,RST -j DROP
#
#================RELATED,ESTABLISHED reaction============
iptables -A INPUT --match conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
ip6tables -A INPUT --match conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
#
#================unfetered loopback======================
iptables -A INPUT -i lo -j ACCEPT
ip6tables -A INPUT -i lo -j ACCEPT
#
#================INVALID catagory of packets=============
iptables -A INPUT -p 41 -j ACCEPT
iptables -A INPUT --match conntrack --ctstate INVALID -j DROP
ip6tables -A INPUT --match conntrack --ctstate INVALID -j DROP
#
#================IPv6 reactions and definitions==========
ip6tables -A INPUT -s fe80::/10 -p icmpv6 -j ACCEPT
ip6tables -t raw -A PREROUTING -p icmpv6 -s fe80::/10 -j ACCEPT
ip6tables -t raw -A PREROUTING --match rpfilter -j ACCEPT
ip6tables -t raw -A PREROUTING -j DROP
#
#=======Acceptable INVALIDs and a curteous response======
iptables -A INPUT -p udp --match conntrack --ctstate NEW -j UDP
ip6tables -A INPUT -p udp --match conntrack --ctstate NEW -j UDP
iptables -A INPUT -p tcp --syn --match conntrack --ctstate NEW -j TCP
ip6tables -A INPUT -p tcp --syn --match conntrack --ctstate NEW -j TCP
#
#================Defining the TCP and UDP chains
#
#########################################################
# Notes for port open definitions #
# It is important to note that this should be config- #
# ured differently if you're providing any routing #
# activity for any purpose. it is up to you to actively #
# define what suites your needs to get the job done. #
# In this example, I'm exempting IPv6 from being able #
# to interact with SSH protocols for two reasons. The #
# first is because it is generally easier and more com- #
# for internal networks to be deployed with IPv4. The #
# second reason is, IPv6 can be deployed globally. #
#########################################################
#
#----SSH configured for eth0
iptables -A TCP -i eth0 -p tcp --dport ssh -j ACCEPT
#!---Blocking SSH interactions in IPv6
ip6tables -A TCP -p tcp --dport ssh -j DROP
#!---Leave commented for end service device
# iptables -A TCP -p tcp --dport 80 -j ACCEPT
# ip6tables -A TCP -p tcp --dport 80 -j ACCEPT
# iptables -A TCP -p tcp --dport 443 -j ACCEPT
# ip6tables -A TCP -p tcp --dport 443 -j ACCEPT
#
#!---Uncomment for remote service to this device
# iptables -A TCP -p tcp --dport 22 -j ACCEPT
# ip6tables -A TCP -p tcp --dport 22 -j ACCEPT
#
#!---Uncomment if you're providing routing services
# iptables -A UDP -p udp 53 -j ACCEPT
# ip6tables -A UDP -p udp 53 -j ACCEPT
#
#=================Tricking port scanners=================
#
#----SYN scans
iptables -I TCP -p tcp --match recent --update --seconds 60 --name TCP-PORTSCAN -j DROP
ip6tables -I TCP -p tcp --match recent --update --seconds 60 --name TCP-PORTSCAN -j DROP
iptables -A INPUT -p tcp --match recent --set --name TCP-PORTSCAN -j DROP
ip6tables -A INPUT -p tcp --match recent --set --name TCP-PORTSCAN -j DROP
#
#----UDP scans
iptables -I UDP -p udp --match recent --update --seconds 60 --name UDP-PORTSCAN -j DROP
ip6tables -I UDP -p udp --match recent --update --seconds 60 --name UDP-PORTSCAN -j DROP
iptables -A INPUT -p udp --match recent --set --name UDP-PORTSCAN -j DROP
ip6tables -A INPUT -p udp --match recent --set --name UDP-PORTSCAN -j DROP
#
#----For SMURF attack protection
iptables -A INPUT -p icmp -m icmp --icmp-type address-mask-request -j DROP
iptables -A INPUT -p icmp -m icmp --icmp-type timestamp-request -j DROP
iptables -A INPUT -p icmp -m limit --limit 2/second --limit-burst 2 -j ACCEPT
ip6tables -A INPUT -p icmpv6 -m limit --limit 2/second --limit-burst 2 -j ACCEPT
#
#----Ending all other undefined connections
iptables -A INPUT -j DROP
ip6tables -A INPUT -j DROP
#
#=======Defining the IN_SSH chain for bruteforce of SSH==
#
#!---I've elected to keep IPv6 out of this realm for
#!---ease of use
iptables -N IN_SSH
iptables -A INPUT -p tcp --dport ssh --match conntrack --ctstate NEW -j IN_SSH
iptables -A IN_SSH --match recent --name sshbf --rttl --rcheck --hitcount 3 --seconds 10 -j DROP
iptables -A IN_SSH --match recent --name sshbf --rttl --rcheck --hitcount 4 --seconds 1800 -j DROP
iptables -A IN_SSH --match recent --name sshbf --set -j ACCEPT
iptables -A INPUT -p tcp --dport ssh -m conntrack --ctstate NEW -j IN_SSH
#
#==================Setting up a NAT gateway==============
#
#########################################################
# #
# I commented this half out because it's not something #
# that will apply to all setups. Make note of all par- #
# tinate interfaces and what exactly is going on. #
# #
#########################################################
#
#----Setting up the FORWARD chain
# iptables -A FORWARD --match conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
# ip6tables -A FORWARD --match conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
#
#
#----Defining the fw-interfaces/open chains for FORWARD
# iptables -A FORWARD -j fw-interfaces
# ip6tables -A FORWARD -j fw-interfaces
# iptables -A FORWARD -j fw-open
# ip6tables -A FORWARD -j fw-open
# iptables -A FORWARD -j DROP # Should be REJECT. But, fuck them
# ip6tables -A FORWARD -j DROP
# iptables -P FORWARD DROP
# ip6tables -P FORWARD DROP
#
#
#----Setting up the nat table
# iptables -A fw-interfaces -i ### -j ACCEPT
# ip6tables -A fw-interfaces -i ### -j ACCEPT
# iptables -t nat -A POSTROUTING -s w.x.y.z/S -o ppp0 -j MASQUERADE
# ip6tables -t nat -A POSTROUTING -s fe::/10 -o ppp0 -j MASQUERADE
#----The above lines should be repeated specifically for EACH interface
#
#----Setting up the PREROUTING chain
#
#######################################################
# #
# The PREROUTING chain will redirect either port #
# targets to be redirected. This can also redirect #
# traffic inbound to your network from the gateway #
# to this machine. This can be useful if you're using #
# a honeypot or have any service within your network #
# that you want to be pointed to a specific device. #
# #
#######################################################
#
#----SSH honeypot server
# iptables -A fw-open -d HONEYPOT_IP -p tcp --dport 22 -j ACCEPT
# ip6tables -A fw-open -d HONEYPOT_IP -p tcp --dport 22 -j ACCEPT
#----With intuition, you can configure the above to also direct specific
#----requests to other devices providing those services. The bellow will
#----be for a squid server
# iptables -A fw-open -d SQUID_IP -p tcp --dport 80 -j ACCEPT
# ip6tables -A fw-open -d SQUID_IP -p tcp --dport 80 -j ACCEPT
# iptables -t nat -A PREROUTING -i ppp0 -p tcp --dport 8000 -j DNAT --to SQUID_IP
# ip6tables -t nat -A PREROUTING -i ppp0 -p tcp --dport 8000 -j DNAT --to SQUID_IP
#
#===============Declare configurations=================
iptables -nvL
ip6tables -nvL