안경잡이개발자

728x90
반응형

※ IPtables 소개 ※


  IPtables는 UFW와 마찬가지로 우분투(Ubuntu) 서버에 포함되어 있는 기본적인 방화벽 도구(Tool)입니다. IPtables를 이용하면 매우 다양한 방화벽 설정이 가능하다는 점에서 활용도가 매우 높습니다. 우리는 방화벽 설정을 할 때 매우 많이 고민한 뒤에 적용해야 합니다. 특히 클라우드 서비스를 이용하지 않는 경우 자기가 직접 서버의 방화벽 설정을 해야합니다. 또한 자칫 잘못 관리하면 사용자들이 접속조차 불가능할 수 있기 때문에 많은 부분을 고려하면서 방화벽 설정을 진행해야 합니다.


  일단 IPtables를 이용하기 전에 UFW를 사용 중인 상태라면 UFW를 사용하지 않도록 처리합니다.


▶ UFW 비활성화: ufw disable


  그리고 IPtables를 이용할 때는 IPtables의 현재 설정 정보를 확인할 때는 --list 옵션을 사용합니다.


▶ IPtables 규칙 확인: iptables --list


  또한 기본적으로 방화벽 설정은 순차적으로 실행됩니다. 따라서 먼저 등록된 부분의 효력이 우선시 되기 때문에, 순서에 대해서 고려해야 합니다. 예를 들어 한 번 모든 패킷을 거부하는 설정이 진행되면 이후에 패킷을 허용하는 설정을 진행해도 의미가 없습니다.


  그리고 기본적으로 방화벽 설정은 입력하자마자 바로 적용되기 때문에 많은 고민을 한 뒤에 명령어를 입력해야 합니다. 더불어 방화벽 설정이 수정되었으면, 이를 실제로 적용하기 위해서 규칙을 저장해주는 것을 잊으시면 안 됩니다. 규칙을 저장(Save)하지 않으면 서버를 재부팅하면 설정이 초기화됩니다.


▶ 규칙 저장: service iptables save


  뿐만 아니라 규칙을 저장(Save)해 준 뒤에도 서버를 재부팅하면 규칙이 초기화 될 수 있습니다. 최신 버전의 우분투(Ubuntu)에서 자주 보이는 현상이며 이럴 때는 iptables-persistent 패키지를 이용하면 됩니다.


[ iptables-persistent 패키지 이용하기 ]


▶ 패키지 설치: sudo apt-get install iptables-persistent netfilter-persistent

▶ 저장: netfilter-persistent save

▶ 다시 로드: netfilter-persistent start


  위 저장 및 로드 명령어를 IPtables의 저장(Save) 명령 이후에 수행해주시면 됩니다. 그러면 서버를 재부팅해도 그대로 IPtables 규칙 설정 정보가 남아 있습니다.


※ IPtables 주요 명령어 ※


-A: 새로운 규칙을 추가합니다.

-D: 기존의 규칙을 삭제합니다.

-R: 새로운 규칙으로 대체합니다.

-P: 기존의 규칙을 변경합니다.

-F: 모든 규칙을 삭제합니다.


※ IPtables 주요 옵션 ※  


-p: 패킷의 포트 번호 혹은 프로토콜을 명시합니다.

-j: 패킷을 어떻게 처리할 지 명시합니다. (ACCEPT, DROP, LOG, REJECT)

-m: 확장 모듈을 활성화합니다. (ex) recent 모듈: 특정 시간 동안 특정 개수 이상의 패킷을 받았을 때를 처리할 수 있음

--dport: 패킷의 도착 포트 번호를 명시합니다.

--sport: 패킷의 발신 포트 번호를 명시합니다.


※ 자주 사용되는 예제 ※


1. 차단과 삭제


▶ 80번 포트 차단: iptables -A INPUT -p tcp --dport 80 -j DROP

▶ 80번 포트 차단 규칙 삭제: iptables -D INPUT -p tcp --dport 80 -j DROP

▶ 세 번째 라인의 규칙 삭제: iptables -D INPUT 3


2. 전체 방화벽 설정 초기화


iptables -P INPUT ACCEPT

iptables -P OUTPUT ACCEPT

iptables -P FORWARD ACCEPT

iptables -F


3. 방화벽 서비스 부팅 관련 명령


▶ 서비스 시작: service iptables start

▶ 서비스 정지: service iptables stop

▶ 서비스 재시작: service iptables restart

▶ 서비스 저장: service iptables save


※ DoS 공격 차단 시나리오 ※


  일반적으로 1초 동안 80번 포트에 똑같은 IP로 10번 이상의 SYN이 들어오는 경우는 적습니다. 따라서 10번 이상의 SYN이 들어오는 경우 이를 공격 시도로 판단할 수 있습니다. 그래서 그 이상의 패킷이 반복적으로 들어오는 경우 DROP 할 수 있도록 처리하는 경우가 많습니다. 이 때는 다음과 같은 명령어를 이용할 수 있습니다. (SSL이 적용된 서비스인 경우 443으로 설정해야 합니다.)


▶ 1초에 10번 이상 접근 저장 목적의 리스트 생성iptables -A INPUT -p tcp --dport 80 -m recent --set --name HTTP_Flood

▶ 1초에 10번 이상 접근 로깅iptables -A INPUT -p tcp --dport 80 -m recent --update --seconds 1 --hitcount 10 --name HTTP_Flood -j LOG --log-prefix "[Attack Detected]"

▶ 1초에 10번 이상 접근 차단: iptables -A INPUT -p tcp --dport 80 -m recent --update --seconds 1 --hitcount 10 --name HTTP_Flood -j DROP

▶ IPtables 규칙 확인: iptables --list

▶ 서비스 저장: service iptables save


  위 명령어가 수행되면, 각 IP를 가지는 사용자가 1초에 10번 이상 서버에 접근했을 때 해당 IP를 차단하게 됩니다. 차단된 IP에 대한 정보는 로그로 남게 되며 마지막으로 차단된 시간으로부터 1초 뒤에는 다시 접속이 가능합니다. 또한 경우에 따라서 HTTPS 포트(443번 포트)에 대한 방화벽 설정이 필요할 수 있습니다. 본인이 이용하고 있는 서비스를 잘 확인하는 것이 중요합니다.


[ HTTPS 예제 코드 ]


  동일 IP에서 1초에 25번 이상의 HTTP 및 HTTPS의 접근이 발생하면 차단하는 예제입니다.


iptables -A INPUT -p tcp --dport 80 -m recent --set --name HTTP_Flood

iptables -A INPUT -p tcp --dport 80 -m recent --update --seconds 1 --hitcount 25 --name HTTP_Flood -j LOG --log-prefix "[Flood Attack Detected]"

iptables -A INPUT -p tcp --dport 80 -m recent --update --seconds 1 --hitcount 25 --name HTTP_Flood -j DROP

iptables -A INPUT -p tcp --dport 443 -m recent --set --name HTTPS_Flood

iptables -A INPUT -p tcp --dport 443 -m recent --update --seconds 1 --hitcount 25 --name HTTPS_Flood -j LOG --log-prefix "[Flood Attack Detected]"

iptables -A INPUT -p tcp --dport 443 -m recent --update --seconds 1 --hitcount 25 --name HTTPS_Flood -j DROP

iptables --list

service iptables save

netfilter-persistent save

netfilter-persistent start


  [ Tip ] 포트를 잘 확인하세요! CloudFlare를 이용하여 인증서가 없는 경우 80번 포트로 방화벽을 설정해야 합니다. 또한 1초에 2번 이상의 접근을 막는다는 것은 사실상 아예 접근을 못하게 한다는 것과 같습니다. 1초에 10회 이상의 정도로 막는 것이 좋습니다.


[ 저장된 로그 확인 ]


  우분투(Ubuntu)에서 기본적으로 IPtables 관련 로그는 /var/log/kern.log의 위치에 저장됩니다. 따라서 일반적으로 다음과 같은 명령어로 로그에 기록되어 있는 공격 시도 패킷을 확인할 수 있습니다.


grep -r "Attack Detected" /var/log/kern.log

728x90
반응형