[리눅스/Linux] 방화벽 구성 - iptables
용도) 방화벽 구성
- 방화벽 사용방법에 대해 기술
OS기준) CentOS
[설치방법 (yum)]
- 레드햇 계열) CentOS7 이상인 경우 이후로는 firewalld가 기본 방화벽으로 변경되어 별도 설치요구
yum install iptables-services -y
[iptables 설명]
- 규칙은 위에서부터 순서대로 적용됨
- 적용된 규칙이 없다면 최종적으로 테이블의 정책에 따라 결정
- 명령어 입력 시 옵션은 붙여 쓸 수 있으며, 특정 명령어는 따로 써야 함 (ex: iptables -nvL --line-number)
※ 방화벽 테이블 종류 ※
INPUT) 외부 → 내부로 들어오는 패킷 처리
OUTPUT) 내부 → 외부로 들어오는 패킷 처리
FORWARD) 외부 → 호스트 → 외부로 경유하여 넘기는 패킷 처리
PREROUTING) INPUT 으로 들어오기 전에 IP와 포트를 변경 처리
POSTROUTING) OUTPUT 으로 나간 후 IP와 포트를 변경 처리
※ iptables 화면 설명 ※
[root@linux ~]# iptables -nvL --line-number
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
1 1027 523K ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
2 0 0 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0
3 0 0 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0
4 1 52 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22
5 64 7530 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
1 0 0 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
Chain OUTPUT (policy ACCEPT 658 packets, 264K bytes)
num pkts bytes target prot opt in out source destination
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
- Chain INPUT : 테이블명 (INPUT/OUTPUT/FORWARD)
- policy ACCEPT : 테이블별 설정된 정책 (ACCEPT/DROP). 규칙이 적용된 게 없다면 테이블 정책에 따라 처리됨
- 0 packets, 0 bytes : 테이블에 사용된 패킷수/패킷크기 통계
※ 필드설명 ※
▷ num : 테이블별 규칙번호
▷ pkts : 규칙에 대한 패킷수 통계값
▷ bytes : 규칙에 대한 패킷크기 통계값 (단위 : byte)
▷ target : 규칙에 대한 처리여부 (ACCEPT/REJECT/DROP/LOG)
▷ prot : 사용된 프로토콜
▷ opt
▷ in/out : 규칙에 대해 설정된 in/out 인터페이스명
▷ source/destination : 출발지/목적지 주소. 0.0.0.0/0 은 모든 주소를 뜻함
▷ 그 외 설정된 내역 표시
[명령어 사용방법(iptables)]
적용된 방화벽 보기
- iptables -nL
[root@linux ~]# iptables -nL
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
ACCEPT icmp -- 0.0.0.0/0 0.0.0.0/0
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22
REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
Chain FORWARD (policy ACCEPT)
target prot opt source destination
REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
※ L 옵션이 보여주는 것이며, n 옵션을 넣어야 빠르게 출력됨 (IP 주소를 DNS에서 변환하는 과정이 생략됨)
※ 주의) 붙여서 옵션 주는 순서는 L 뒤에 넣으면 에러가 발생하므로 반드시 L 앞쪽에 넣어줘야 함
[root@linux ~]# iptables -Ln
iptables: No chain/target/match by that name.
※ 옵션 ※
-t, --table table | 테이블명 (생략 가능) - 생략시 filter 테이블이 기본 - 테이블(filter) : INPUT/OUTPUT/FORWARD 정책 표시 - 테이블(mangle) : INPUT/OUTPUT/FORWARD/PREROUTING/POSTROUTING 정책 표시 - 테이블(nat) : PREROUTING/POSTROUTING/OUTPUT 정책 표시 - 테이블(raw) : PREROUTING/OUTPUT 정책 표시 |
-L, --list [chain] | 적용 방화벽 리스트 보기 - chain 은 테이블명이며 생략가능 (INPUT, OUTPUT, FORWARD) iptables -nL INPUT - INPUT 테이블 규칙만 보기 |
-n, --numeric | IP주소를 DNS를 통해 변환하지 않음 |
-v, --verbose | 규칙별 통계값 확인 (패킷량, 패킷수) Chain INPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 1639 561K ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 |
--line-number | 테이블별 규칙 순서 번호 표시 |
영구 저장된 상태의 방화벽 보기)
- 레드햇 계열) /etc/sysconfig/iptables
[root@linux ~]# cat /etc/sysconfig/iptables
# Firewall configuration written by system-config-firewall
# Manual customization of this file is not recommended.
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT
정책 추가)
- -A 또는 -I 를 사용하여 추가
▷ 테이블 마지막에 추가 : -A 테이블명
▷ 테이블 임의의 라인에 추가 : -I 테이블명 (추가할 라인숫자)
▷ 특정 라인에 추가시 --line-number 옵션을 이용해 조회를 하고 추가
- 방화벽은 바로 적용되지만, 저장은 되지 않으니 별도 저장 명령을 내려야 함
- 일부 옵션은 not 논리 연산 가능 (iptables 명령으로 조회시 ! 표시가 있다면 'not' 을 의미)
예를 들면 아래와 같이 표기됨 (UDP를 제외한 TCP/ICMP 허용)
[root@linux ~]# iptables -A INPUT ! -p udp -j ACCEPT
[root@linux ~]# iptables -nL INPUT
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT !udp -- 0.0.0.0/0 0.0.0.0/0
[root@linux ~]# iptables -A INPUT -p tcp -j ACCEPT
[root@linux ~]# iptables -nL INPUT
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT !udp -- 0.0.0.0/0 0.0.0.0/0
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0
[root@linux ~]# iptables -I INPUT 2 -p icmp -j ACCEPT
[root@linux ~]# iptables -nL INPUT
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT !udp -- 0.0.0.0/0 0.0.0.0/0
ACCEPT icmp -- 0.0.0.0/0 0.0.0.0/0
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0
※ 옵션 ※
[!] -p, --protocol protocol not 선언 가능 |
통신 프로토콜 (생략시 all) - tcp, udp, udplite, icmp, esp, ah, sctp or all 예제) -p tcp ! -p tcp |
[!] -s, --source address[/mask][,...] [!] -d, --destination address[/mask][,...] not 선언 가능 |
출발지/목적지 주소 (생략시 모두로 선언 : 0.0.0.0/0) 예제) -s 1.1.1.1 ! -s 1.1.1.1 -s 1.1.1.1 -d 2.2.2.2 |
[!] --source-port,--sport port[:port] [!] --destination-port,--dport port[:port] not 선언 가능 |
출발지/목적지 포트 (생략시 모든 포트로 선언 : 1:65535) TCP/UDP 등의 포트가 있는 프로토콜에 해당 m 옵션에서 1개의 규칙에 여러 포트 선언도 가능 (최대 15개) 예제) --sport 10000:10010 --dport 21 -m multiport --dport 22,80,137:139,443,445 |
[!] -i, --in-interface name [!] -o, --out-interface name |
인터페이스 선택 (인바운드/아웃바운드. 생략시 모든 인터페이스) 예제) -i eth0 |
-m (매치명) | 일반적인 방화벽 기능 외에 특정 기능 호출시 사용 기능이 많아 아는것만 표기해둠 - comment : 방화벽 주석 달기 - conntrack : 통신상태 추적 - multiport : TCP/UDP에서 포트 선언시 다중포트 선언 (최대 15개) - state : TCP 통신 상태 ▷ NEW (신규 패킷), ESTABLISHED (연결된 상태), RELATED (관련된 패킷. FTP), INVALID (올바르지 않은 연결) 예제) -m comment --comment "SSH" ▷ 규칙 주석에 SSH 라고 표기 -m conntrack --state INVALID ▷ 통신 상태가 올바르지 않은 것 -m multiport --dport 22,80,137:139,443,445 ▷ 한 규칙에 다중 포트 선언 -m state --state RELATED,ESTABLISHED ▷ 통신 상태가 연결되었거나 관련된 것들 -m state --state NEW -m comment --comment "client" ▷ 여러 매치 혼합 (주석설과 신규 패킷) |
-j, --jump target | 패킷을 어떻게 처리할지 결정 - ACCEPT, REJECT, DROP, (chain명) - 'chain' 의 경우 규칙 모음 같은건데, 일부 규칙들을 공유하게 한다면 편리하게 사용가능 예제) -j ACCEPT ▷ 규칙 허용 -j REJECT ▷ 규칙 거부 (상대에게 알림) -j DROP ▷ 규칙 차단 (상대에게 알리지 않음) -j BLACK_LIST ▷ BLACK_LIST chain 으로 이동 |
-N, --new-chain chain -X, --delete-chain [chain] |
chain (규칙모음) 의 생성/삭제 예제) -N BLACK_LIST ▷ BLACK_LIST 라는 chain 을 생성 -X BLACK_LIST ▷ BLACK_LIST 라는 chain 을 삭제 |
※ jump 옵션 및 chain 설명 ※
-j 옵션은 패킷의 처리여부를 결정한다. 이외 다른 chain (일종의 규칙모음) 으로 규칙 처리순서를 바꿀 수도 있다 (아래 예제로 참조)
/etc/sysconfig/iptables
*filter :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] :WHITE_LIST - ACCEPT [0:0] -A INPUT -p icmp -j ACCEPT -A INPUT -i lo -j ACCEPT -A WHITE_LIST -s 10.0.0.0/24 -j ACCEPT -A WHITE_LIST -s 172.30.1.0/24 -j ACCEPT -A WHITE_LIST -s 192.168.1.0/24 -j ACCEPT -A WHITE_LIST -j DROP A INPUT -p tcp --dport 80 -m comment --comment "WEB" -j WHITE_LIST A INPUT -p tcp --dport 443 -m comment --comment "WEB" -j WHITE_LIST -A INPUT -j DROP COMMIT |
▷ 'INPUT' 으로 80/443 패킷이 들어온다면
▷ 80/443 규칙들은 'WHITE_LIST'로 넘어감 (-j WHITE_LIST)
▷ 10.0.0.0/24 172.30.1.0/24 192.168.1.0/24 규칙을 순서대로 확인하고 마지막 규칙 (-A WHITE_LIST -j DROP) 에 따라 DROP 처리
정책 삭제)
- -D 를 사용하여 추가
▷ 규칙명을 정확하게 입력 (-D 테이블명 조건)
▷ 규칙 순서 번호를 입력 (-D 테이블명 숫자)
▷ 특정 라인 삭제 시--line-number 옵션을 이용해 조회를 하고 삭제하기를 권장
- 방화벽은 바로 적용되지만, 저장은 되지 않으니 별도 저장 명령을 내려야 함
[root@linux ~]# iptables -nL INPUT
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT !udp -- 0.0.0.0/0 0.0.0.0/0
ACCEPT icmp -- 0.0.0.0/0 0.0.0.0/0
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0
[root@linux ~]# iptables -D INPUT 2
[root@linux ~]# iptables -nL INPUT
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT !udp -- 0.0.0.0/0 0.0.0.0/0
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0
[root@linux ~]# iptables -D INPUT -p tcp -j ACCEPT
[root@linux ~]# iptables -nL INPUT
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT !udp -- 0.0.0.0/0 0.0.0.0/0
[iptables 운영관리]
기동 관련
수행작업 | 레드햇 계열 (CentOS 6 이하) | 레드햇 계열 (CentOS 7 이상) |
기동 | service iptables start | systemctl start iptables |
정지 | service iptables stop | systemctl stop iptables |
재시작 설정 다시 불러오기 - 현재 방화벽 규칙이 사라지고 다시 읽어오니 작업해둔게 있다면 미리 저장할것 |
service iptables restart iptables-restore < /etc/sysconfig/iptables |
systemctl restart iptables iptables-restore < /etc/sysconfig/iptables |
저장 | service iptables save 또는 iptables-save > /etc/sysconfig/iptables |
service iptables save 또는 iptables-save > /etc/sysconfig/iptables |
부팅시 자동기동 확인 | runlevel chkconfig --list | grep iptables 현재 runlevel(부팅방법)에 따른 자동기동 여부 확인 |
systemctl is-enabled iptables |
부팅시 자동기동 ON/OFF | 켜기) chkconfig iptables --level 2345 on 끄기) chkconfig iptables --level 2345 off |
systemctl enable iptables systemctl disable iptables |
주요 파일들
- 규칙) /etc/sysconfig/iptables
- 프로그램 설정) /etc/sysconfig/iptables-config
- 서비스 파일)
▷ CentOS 6 이하 : /etc/rc.d/init.d/iptables
▷ CentOS 7 이상 : /usr/lib/systemd/system/iptables.service
-rw-------. 1 root root 470 May 15 15:31 /etc/sysconfig/iptables
-rw-------. 1 root root 2116 Oct 2 2020 /etc/sysconfig/iptables-config
-rwxr-xr-x. 1 root root 11123 Jun 20 2018 /etc/rc.d/init.d/iptables
-rw-r--r--. 1 root root 517 Oct 2 2020 /usr/lib/systemd/system/iptables.service
정책관리
- 주석관리 철저히 (이 규칙이 어떤 건지 구분하기 위함 또는 관리자가 변경되면 인수인계를 위함)
▷ -m comment --comment 옵션을 사용
▷ 직접 파일에 주석 넣기 (라인 첫 글자가 # 이 들어가면 주석으로 인식)
/etc/sysconfig/iptables
####################
# ----- HOST ----- #
####################
-A INPUT -p icmp ! -s 172.30.1.0/24 -j DROP
####################
# ----- Port ----- #
####################
-A INPUT -p tcp --dport 80 -m comment --comment "WEB" -j ACCEPT
- 정책의 추가/삭제처리를 간편하게 하기에는 명령어 보다 vi 등으로 규칙파일을 편집 후 방화벽을 재기동하는 방법을 많이 사용
- 정책백업 (rsync 등을 이용)
정책순서
- 정책이 다수 존재한다면 정책의 순서를 고려해야 함
- 고객사 별로 나누는 것이 아닌 목적별로 나눈다면 정책 순서 관리는 개인이 생각하여 적은 거니 참고할 것
1) 차단
- 차단할 규칙이 있다면 차단을 먼저 하고 나머지 패킷을 통과시켜야 방화벽 부하 경감 및 규칙이 올바르게 동작
2) 로컬통신
3) host 단위
4) 네트워크 IP 범위 단위
5) 모든 포트 허용
6) 해당하는 규칙이 없다면 모든 통신 차단
- 모든 통신을 차단하는 방법이 2가지가 있는데 전자는 규칙에 선언을 하여 차단하는 것이고, 후자는 테이블 정책을 차단으로 선언
- 경험상 안정성은 전자, 보안성은 후자 (개인적으로 전자를 더 선호함)
전자를 선호하는 이유는 방화벽이 정책이 순수하게 삭제되었을 때 장애가 발생되지 않기 위함이다
- 만약 모든 통신 차단을 테이블 정책으로 구성하였다면, 정책만 삭제되는 경우 통신 자체가 되지 않는다 (규칙이 없으니 최종적으로 테이블 정책을 따르니 테이블 정책이 '차단'이라면 아무 작업도 할 수 없다)
- /etc/sysconfig/iptables
*mangle
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
(...정책들...)
-A INPUT -j DROP <- 모든통신 차단
위처럼 규칙이 존재하다가 규칙만 삭제되는 경우 기본 정책이 ACCEPT(허용) 이므로 원격 통신이 가능하다. 물론 누구나 들어올 수 있는 상태이므로 바로 조치는 해줘야 한다
만약 후자였다면
- /etc/sysconfig/iptables
*mangle
:PREROUTING DROP [0:0] <- 모든통신 차단
:INPUT DROP [0:0] <- 모든통신 차단
:FORWARD DROP [0:0] <- 모든통신 차단
:OUTPUT DROP [0:0] <- 모든통신 차단
:POSTROUTING DROP [0:0] <- 모든통신 차단
(...정책들...)
방화벽이 켜진 상태에서 규칙만 삭제된 경우 통신 자체가 불가능해진다
굳이 이런 상황이 발생될 수 있느냐인데, 있다..
경험상으로
1) 인적 장애
- 관리자가 잘못하여 규칙만 삭제하여 통신이 불가능해지는 사태 발생
2) 해킹
- 리눅스 해킹 중 방화벽 정책을 삭제해 버리는 케이스가 있었음
3) 방화벽 재기동 영향
- 방화벽 재기동을 하면 [방화벽 정책 정리] → [방화벽 정지] → [방화벽 기동] → [방화벽 정책 불러오기] 등의 절차를 거치는데 [방화벽 정책 정리] → [방화벽 정지] 과정에서 테이블 정책이 '차단'이라면 통신량이 많은 경우 일부 패킷이 차단될 수 있다 (드물지만 안정성을 생각한다면 고민해봐야 한다)
최종 선택은 운영자 몫이다
업데이트) 2023.5.15
홈페이지) https://www.netfilter.org
라이센스) 무료 (GNU GPLv2)
첨부파일) iptables 기본 설정 / 서비스 파일