본문 바로가기

Language&Configuration/[Liunx]

[Linux] iptables 명령어 사용법 - 리눅스 상에서 방화벽 설정하기

1. iptables ?

iptables는 리눅스상에서 방화벽을 설정하는 도구로서 커널 2.4 이전 버전에서 사용되던 ipchains를 대신하는 방화벽 도구이다. iptables는 커널상에서의 netfilter 패킷필터링 기능을 사용자 공간에서 제어하는 수준으로 사용할 수 있다.

패킷 필터링이란 지나가는 패킷의 해더를 보고 그 전체 패킷의 운명을 결정하는 것을 말한다. 일반적으로 패킷은 해더와 데이터를 가진다. 해더에 필터링할 정보인 출발지 IP:PORT, 도착지 IP:PORT, checksum, 프로토콜 옵션 등을 가지며 데이터는 각 각의 전송 데이터가 들어간다.


특정 조건을 가지고 있는 패킷에 대해 허용(ACCEPT)차단(DROP)등을 지정할 수 있으며, 특정 조건 등을 통해 다양한 방식의 패킷 필터링과 처리 방식을 지원한다.

iptables 정책은 여러 구분으로 나눠지며 중요한 부분은 Chain이다.
Chain은 패킷이 조작될 상태를 지정하며 iptables에 내장된 기본 Chain은 다음과 같다.
(기본 Chain은 영구적이며 삭제가 불가능하다. 이외에 -N 옵션으로 지정하는 사용자 정의 Chain이 있다.)

Filter Rule(Chain)

  • INPUT - 패킷이 서버로 들어오는 경우
  • OUTPUT - 서버에서 패킷이 외부로 나가는 경우
  • FORWARD - 패킷이 서버를 지나가는 경우(INPUT&OUTPUT)

NAT Rule(Chain)

  • PREROUTING - DNAT(Destination NAT) 룰 적용, 패킷의 도착지 주소를 변경
  • POSTROUTING - SNAT(Source NAT) 또는 masquerad 룰 적용, 패킷의 출발지 주소를 변경

Linux Server를 목적지로 삼는 모든 패킷은 INPUT Chain을 통과하고
Linux Server에서 생성되 외부로 보내지는 모든 패킷은 OUTPUT Chain을 통과하게 된다.
FORWARD Chain의 경우 현재의 Linux Server가 목적지가 아닌 패킷이 통과하는 Chain이다. (FORWARD Chain은 NAT(네트워크 공유) 기능 사용을 위해 사용된다.)

마스커레이드(Masquerade)

  • 내부 사설 IP의 PC들이 외부 인터넷이 연결 가능하도록 해주는 기능

NAT(Network Address Translation) : 네트워크 주소 변환 서비스

  • SNAT(Source NAT) : 내부 사설IP에서 외부로 나갈 때 공인IP로 변환 -> 마스커레이드와 비슷
  • DNAT(Destination NAT) : 외부에서 방화벽(외부IP)으로 요청되는 주소로 내부사설IP로 변환

 


2 iptables의 구조

iptables -A INPUT -s [발신지] --sport [발신지 포트] -d [목적지] --dport [목적지 포트] -j [정책]

1) 기본정책을 ACCEPT로 설정하는 법 :
# iptables -P INPUT ACCEPT

# iptables -P OUTPUT ACCEPT
# iptables -P FORWARD ACCEPT

2) 현재 자신의 방화벽 규칙을 볼 수 있는 명령 :
# iptables --list 또는 iptables -L

3) 규칙 추가 후에 저장하기 :
# service iptables save
-> /etc/sysconfig/iptables 에 저장됨

4) 현재 iptables 규칙을 초기화 하기 :
# iptables -F


3. [iptables 명령 및 옵션]

yum install iptables
#iptables가 내장되어 있다는 가정하에 시작 만약 설치가 안되어있다면 패키징 설치 필요

Iptables -L
#적용된 iptables 룰 확인

iptables 패킷의 상세 내역에 따른 제어 옵션 목록
  --tcp-flags : TCP 플래그에 따라 패킷을 제어한다. (첫 번째 인자를 검사하고 두 번째 인자는 설정이 되어야 함)
  -m state --state : 패킷의 상태와 목적에 따라 제어한다.

      -m state 명령어 상태리스트
NEW : 새로 접속을 시도하는 패킷
ESTABLISHED : 접속을 한 상태에 있는 패킷
INVALID : 유효하지 않은 패킷 ( 보통 DROP 된다. )
RELATED : 접속에 연관성을 가지는 패킷(e.g. FTP 접속 패킷, ICMP 에러 메세지)

iptables 패킷의 상세 내역 제어옵션 예제
* iptables -A INPUT -p TCP --tcp-flags SYN,RST,ACK,SYN -j DROP : SYN패킷의 set이 1이면 DROP시킨다
* iptables -A INPUT -p TCP -m state --state NEW -j DROP : 접속을 시도하는 SYN, ACK 플래크 패킷을 차단한다.

iptables -F #규칙 초기화
iptables -X #비어있는 체인 삭제
iptables -t nat -F #NAT 규칙 초기화
iptables -t nat -X #NAT 규칙 비어있는 체인 삭제

iptables -P INPUT ACCEPT #INPUT 체인 허용
iptables -P OUTPUT ACCEPT #OUTPUT 체인 허용
iptables -P FORWARD ACCEPT #FORWARD 체인 허용

 

iptables 기본정책 제어옵션

-L (--list) 적용 되어 있는 정책 목록 출력
-A (--append) 새로운 정책 추가(가장 낮은 순위로 추가됨)
-I (--insert) 새로운 정책 삽입(가장 높은 순위로 삽입됨)
-R (--replace) 새로운 정책 교체(기존의 정책을 교체)
-D (--delete) 해당 정책을 삭제
-N (--new-chain) 새로운 체인 생성(INPUT,OUTPUT,FORWARD 제외)
-P (--policy) 기본 정책 변경
-F (--flush) 체인에 설정된 규칙 초기화
-Z 체인의 모든 규칙들의 패킷과 바이트 카운터를 0 으로 만든다.
-X (--delete-chain) 비어있는 체인을 삭제
-E 체인이름 변경

 

iptables 제어 옵션

-s (--source) 출발지 주소
-d (--destination) 목적지 주소
--sport 출발지 포트
--dport 목적지 포트
-p (--protocol) 프로토콜(tcp,udp...)
-i (--in-interface) 패킷이 들어오는 네트워크 인터페이스 (inbound interface)
-o (--out-interface) 패킷이 나가는 네트워크 인터페이스 (outbound interface)
-f (--fragment) 나뉜 패킷
-j (--jump) 패킷 상태 제어

 

4. iptables 규칙 추가

**127.0.0.1 즉, 로컬에서 요청하는 모든 ICMP 패킷에 대해 무시하고자 할 때 어떻게 하면 될까?
ping 요청에 사용되는 프토토콜은 ICMP 프로토콜이며, 발신 주소는 127.0.0.1이다.
패킷 필터의 목표는 폐기(DROP)이며, 사용하는 프로그램은 ping이다.

# iptables -A INPUT -s 127.0.0.1 -p icmp -j DROP

 

5.iptables 규칙 제거

iptables의 체인 입력과 마찬가지로 삭제를 할 때에도 동일하게 입력하면 된다.

iptables -D INPUT -s [발신지] --sport [발신지 포트] -d [목적지] --dport [목적지 포트] -j [정책]

iptables -D INPUT [필터링 번호]
(필터링 번호는 service iptables stat을 통해 확인할 수 있다.)

iptables -F INPUT 을 입력할 경우 모든 체인이 삭제된다.

그러면 위에 입력했던 체인을 제거해보도록 하자.

# iptables -D INPUT 1
# iptables -D INPUT -s 127.0.0.1 -p icmp -j DROP를 사용해서 삭제할 수도 있다.

 

6. iptables 정책 순서


모든 방화벽은 순차적 실행이다.
즉 등록 순서에 있어서 먼저 등록한 부분에 대해서 효력이 유효하기 때문에 등록시에는 순서가 매우 중요하다.
모든 입출력 패킷에 대해 거부하는 설정이 먼저 등록되면 그 이후에 포트를 열어주는 설정을 하여도 효과가 없다.
그러므로 허용하는 정책을 먼저 정의한 다음 거부하는 정책을 설정해야 한다.

다음같이 설정하면 우선적으로 22번 포트가 열린 후 나중에 22번~30번 포트가 막히기 때문에 SSH 접속이 가능
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -p tcp --dport 22:30 -j DROP

다음같이 설정하면 우선적으로 22번~30번 포트가 막히기 때문에 뒤에서 아무리 22번 포트를 열어도 외부에서 SSH로 접속할 수 없게 된다.

※ iptables로 입력할 경우 바로 적용이 되기 때문에 원격에서 작업할 경우엔 주의하자.

iptables -A INPUT -p tcp --dport 22:30 -j DROP
iptables -A INPUT -p tcp --dport 22 -j ACCEPT

 

7. iptables의 확장


1초동안 80포트에 똑같은 IP가 10번 이상의 SYN가 들어오면 드랍시킨다.
(즉, 정상적인 요청이 아닌 웹서비스 공격으로 간주하여 요청패킷을 폐기시켜 응답하지 않도록 한다.)
# iptables -A INPUT -p tcp --dport 80 -m recent --update --seconds 1 --hitcount 10 --name HTTP -j DROP

 

8. iptables 활용 예

1) 소스 ip가 192.168.0.111 인 접속의 모든 접속 포트를 막아라.
# iptables -A INPUT -s 192.168.0.111 -j DROP

2) INPUT 사슬에 출발지 주소가 127.0.0.1(-s 127.0.0.1) 인 icmp 프로토콜(-p icmp) 패킷을 거부(-j DROP)하는 정책을 추가(-A)하라
# iptables -A INPUT -p icmp -s 127.0.0.1 -j DROP

3) INPUT 사슬에 목적지 포트가 23번(--dport23)인 tcp 프로토콜(-p tcp) 패킷을 거부하는(-j DROP)규칙을 추가(-A) 하라.
# iptables -A INPUT -p tcp --dport 23 -j DROP

4) INPUT 사슬에 목적지 포트 번호가 80번(--dport 80)인 tcp 프로토콜(-p tcp)패킷을 받아들이는(-j ACCEPT) 규칙을 추가(-A) 하라
# iptables -A INPUT -p tcp --dport 80 -j ACCEPT

5) INPUT 사슬에 목적지 포트번호가 1023번 보다 작은 모든 포트(--dport :1023)인 tcp프로토콜(-p tcp)패킷을 거부하는(-j DROP)규칙을 추가(-A)하라
# iptables -A INPUT -p tcp --dport :1023 -j DROP

6) ftp포트를 열어라
# iptables -I INPUT -p tcp --dport 21 -j ACCEPT

7) imap 서비스를 방화벽에서 열어라
# iptables -I INPUT -s 192.168.0.0/255.255.255.0 -p udp --dport 143 -j ACCEPT

8) 웹서버 방화벽 열어라
# iptables -I INPUT -p tcp --dport 80 -j ACCEPT

9) 웹서버 포트 80 -> 8880으로 교체하라( 웹서비스 포트 변경시 /etc/services 에서도 변경 해줘야 함)
# iptables -R INPUT 2 -p tcp --dport 8880 -j ACCEPT

10) domain-access_log 파일에 있는 모든 ip의 모든 접속 포트를 막아라(DOS공격 방어시 사용)
# cat domain-access_log |awk '{print $1}'|sort |uniq |awk '{print "iptables -A INPUT -s "$1" -j DROP"}'|/bin/bash