iptables-persistent를 이용한 방화벽 설정 및 ip 차단
우선 어느 레벨에서 IP를 차단할 것인지는 세가지 선택이 있다.
- 1단계 Node.js (서비스) 단에서 IP 차단
- 2단계 Nginx (웹서버) 단에서 IP 차단
- 3단계 Ubuntu (운영체제/방화벽) 단에서 IP 차단
여기서 1, 2 단계는 결국 시스템 리소스를 사용하게 되는 것이다 (CPU 가동률이 올라가게 되고, 이는 클라우드와 같은 인프라를 활용하게 될 때 지갑에서 돈이 나가게 된다는 것을 의미한다) 가장 저비용으로 ip 밴을 처리할 수 있는 것은 운영체제 레벨에서 ip를 차단하는 것이다.(라고 팀원에게 들었다. 실제로 하기 전에 서비스가 망함 ㅜ)
1, 2 단계를 사용하고 싶다면 (http://keun.me/ip-filter/) 여기를 참고하자. 여기서는 Ubuntu 단에서 IP 차단하는 것을 알아보겠다.
- 우분투 기본 방화벽은 UFW.
- 간단한 방화벽 구성이 가능하나, 수준 높은 구성을 원하면 iptables 룰을 직접 사용해야함.
1. iptables 설치 및 세팅
우분투 서버에서 Iptables를 설정하기 전에 먼저 UFW를 사용 중지합니다.
ufw disable
그리고 UFW를 기반으로 설정되어 있는 방화벽 설정을 모두 초기화 시킵니다. 이는 UFW도 IPtables를 기본으로 활용하므로 아래와 같은 명령을 사용합니다.
iptables -F
IPtables이나 Fail2Ban과 같은 보안 프로그램들은 다시 시작하면 기존 설정이 초기화됩니다. IPtables도 마찬가지로 시스템을 다시 시작한다든지 다시 작하게되면 설정이 초기화됩니다.
최신 버전의 우분투(Ubuntu)에서 이는 특히 피할 수 없이 나타는 현상이므로 이를 해소할 수 있는 패키지를 설치합니다.
이러한 패키지로 추천되는 것이 바로 iptables-persistent입니다. 여기서는 이를 사용하도록 합니다.
그리고 netfilter-persistent도 같이 설치합니다. netfilter는 IPtabels를 이용하면서도 이를 뛰어넘을 솔루션으로 인기를 끌고 있다고 하네요.
apt-get install iptables-persistent netfilter-persistent
설치 도중에 ip4/ip6 저장 여부를 묻는데 yes를 선택합니다. 설정파일은 /etc/iptables 폴더에 저장됩니다.
2. IPtables 설정 변경 및 확인
우분투 Iptables 기본 설정
이제 안정적으로 IPtables를 사용할 수 있게되었기 때문에 본격적으로 방화벽을 설정해 보기로 하죠.
일반적으로 아래와 같은 기본 설정등을 합니다.
established and related 접속 허용
일반적으로 네트워크 트래픽은 양방으로 흘러야 합니다. 때문에 established and related 접속 허용합니다.
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
sudo iptables -A OUTPUT -m conntrack --ctstate ESTABLISHED -j ACCEPT
loopback 허용
일반적으로 많은 소프트웨어들이 localhost 어댑터와 통신이 되어야 하기때문에 필요합니다.
sudo iptables -A INPUT -i lo -j ACCEPT
핑을 허용
만약 핑(ping)을 허용하려면 아래 명령을 추가합니다.
sudo iptables -A INPUT -p icmp -j ACCEPT
HTTP/HTTPS 허용
80포트 및 443포트 허용
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT
SSL/SFTP용 포트
SSL/SFTP를 이용하기 위한 포트를 엽니다. 보통 22번이죠 SSL이면
sudo iptables -I INPUT -p tcp --dport (SSL/SFTP용 포트) -j ACCEPT
INPUT과 FORWARD 차단
위에서 기본적인 것을 허용했기 때문에 나머지는 차단합니다.
sudo iptables -P INPUT DROP
sudo iptables -P FORWARD DROP
어느 정도 기본 설정을 했으면 저장합니다.
netfilter-persistent save
※ 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
서버 재 가동시 iptables의 내용이 제대로 저장되는 지 확인해보기 위해서는 다음 명령어를 입력합니다.
iptables -S
리스트에 반영이 되었는지 확인해봅시다.
iptables --list or iptables -nL
Chain Input : 서버로 들어오는 기본 정책
Chain output : 서버에서 나가는 기본 정책
Chain forwad : 서버에서 forwarding 되는 기본 정책 (이 서버를 거쳐 패킷이 통과함. 서버가 통로 역할을 할 때)
sudo iptables -A INPUT -p tcp --dport 53 -j ACCEPT
날리면 다음이 추가됨. 최하단부부터 추가됨.
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:53
저장 및 적용
방화벽 설정이 수정되었으면, 이를 실제로 적용하기 위해서 규칙을 저장해주는 것을 잊으시면 안 됩니다. 규칙을 저장(Save)하지 않으면 서버를 재부팅하면 설정이 초기화됩니다.
또, 우리는 iptables-persistent를 사용 중이므로 persistent로 저장해줘야 합니다.
규칙 수정후 저장과 재로드는 다음과 같이 진행되겠네요
▶ IP 테이블 저장: sudo service iptables save
▶ persistent 저장: sudo netfilter-persistent save
▶ 다시 로드: sudo netfilter-persistent start
참고한 글