본문 바로가기

우분투리눅스

게이트웨이에서 패킷 제어하기(iptables)

IP주소 매스커레이드 - 게이트웨이 장치가 패킷의 출발지 IP주소를 사설IP 주소에서 자신에게 할당된 공인IP 주소로 바꿔서 인터넷으로 보내는 과정

 

SNAT(Source NAT) - IP주소 매스커레이드와 유사

 

DNAT(Destination NAT) - 외부에서 내부 사설IP로 접속하고자 할 때

 

사설IP주소를 동적으로 운영할 때는 매스커레이드를 사용하고 사설IP주소를 고정으로 운영할 때는 SNAT를 사용한다.

 

패킷필터링 - 허가된 접근을 허용하고 허가되지 않은 접근은 차단하는 기능으로 게이트웨이 장치는 패킷 필터링으로 네트워크 자원을 보호하기 위한 방화벽 역할을 수행한다.

 

iptables 의 제어규칙을 정의하는 기본단위를 사슬(Chain)이라고 하며 특정한 정책에 따라 사슬을 모아 테이블로 정의한다.

 

iptables의 기본 테이블로는 filter, nat, mangle 이 있다.

 

 

[ nat 테이블 ]

패킷의 주소변환 규칙을 정의하는 테이블로 PREROUTING 사슬과 POSTROUTING 사슬을 확인할 수 있다.

 

PREROUTING 사슬 - 패킷이 리눅스 서버에 전달되기 전 규칙을 정의

POSTROUTING 사슬 - 리눅스 서버에서 나가는 규칙을 정의

 

# sudo iptables -t nat -L

-L 옵션 : 사슬에 정의되어 있는 규칙을 보여준다.

 

IP 주소 매스커레이드는 nat 테이블의 POSTROUTING 사슬에 설정한다. 외부와 연결된 네트워크 인터페이스 eth0을 거쳐(-o eth0) 리눅스 서버에서 외부로 나가는 ㅡ패킷에 대해 매스 커레이드 규칙(-j MASQUERADE)을 POSTROUTING 사슬에 추가(-A POSTROUTING)

 

# sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

# sudo iptables -t nat -L

 

 

[ filter 테이블 ]  

 리눅스 서버의 방화벽 기능을 담당하는 테이블로써 패킷을 거르기 위한 규칙을 정의한다. -t 옵션을 생략하면 iptables는 기본적으로 filter 테이블을 대상으로 규칙을 설정한다. -L 옵션으로 filter 테이블을 확인하면 INPUT, FORWARD, OUTPUT 사슬에 적용된 규칙을 확인할 수 있다.

 

INPUT 사슬과 OUTPUT 사슬 - 리눅스 서버로 들어오거나 나가는 규칙을 정의

FORWARD 사슬 - 리눅스 서버를 거쳐 외부로 나가는 규칙을 정의

 

# sudo iptables -L

각 사슬의 기본정책을 확인

 

# sudo iptables -F

fileter 테이블에 설정되어 있는 규칙을 모두 초기화

 

# sudo iptables -P INPUT DROP

# sudo iptables -P FORWARD DROP

사슬의 기본 정책을 정의하는 -P 옵션으로 filter 테이블의 INPUT 사슬과 FORWARD 사슬의 기본 정책을 DROP(제한함)으로 변경

 

# sudo iptables -A INPUT -i eth1 -j ACCEPT

# sudo iptables -A INPUT -i eth2 -j ACCEPT

내부 네트워크에서 게이트웨이 장치로 전송되는 패킷을 허용함으로써 내부 네트워크와 연결된 네트워크 인터페이스로 들어오는 접근(-i eth1/eth2)을 허용(-j ACCEPT)하도록 INPUT 사슬에 규칙을 정의한다.(-A INPUT)

 

※ 사슬에 정의된 규칙을 삭제하는 옵션은 -D 이다. -D 이후에 정의했던 규칙을 그대로 입력해야 하당 규칙이 삭제된다. 규칙 삭제 후 iptables -L 로 확인

# sudo iptables -D INPUT -i eth1 -j ACCEPT

 

# sudo iptables -A FORWARD -i eth1 -j ACCEPT

# sudo iptables -A FORWARD -i eth2 -j ACCEPT

IP 주소 매스커레이드 기능을 유지하기 위해 내부 네트워크에서 게이트웨이 장치를 거쳐 외부로 전달되는 패킷 허용

 

 

iptables는 IP주소, 프로토콜, 포트에 대한 접근을 제어할 수 있다.

 

# sudo iptables -A FORWARD -d 10.0.0.2 -p tcp --dport 23 -j ACCEPT

test02서버로 전달(-d 10.0.0.2)되는 TCP 패킷(-p tcp) 중에서 텔넷 서버에 대한 접속 요청(--dport 23)을 허용(-j ACCEPT)하도록 FORWARD 사슬에 규칙을 정의(-A FORWARD)

 

# sudo iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT

iptables의 막강한 기능인 상태 기반 패킷 필터링 설정으로 텔넷 서버에 대한 접속 요청이 전달된 다음에는 패킷의 상태를 확인(-m state)해서, 텔넷 서버에서 클라이언트로 가는 응답 패킷(ESTABLISHED), 텔넷과 관련된 패킷(RELATED)들을 허용(-j ACCEPT)하도록 FORWARD 사슬에 규칙을 정의 (-A FORWARD)

 

※ TCP/IP 통신은 클라이언트와 서버가 서로 접속 요청(syn), 응답(syn ack), 확인(ack), 패킷을 주고받는 과정을 거쳐 시작된다.

ESTABLISHED : 3단계 접속 절차를 거쳐 접속이 허가된 패킷을 의미

RELATED : 해당 접속과 관련 있는 패킷을 의미

 

# sudo iptables -A INPUT  -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT

외부 네트워크와 연결된 네트워크 인터페이스(-i eth0)로 들어오는 패킷의 상태를 확인(-m state)한 다음, 요청에 대한 응답 패킷(ESTABLISHED)과 관련 패킷(RELATED)을 허용(-j ACCEPT)하도록 INPUT 사슬에 규칙을 정의(-A INPUT)

 

 

iptables 에서는 필터링 규칙이 매우 중요하다. iptables로 정의한 순서에 따라 규칙이 적용되기 때문.

-A 옵션 대신 -I 옵션으로 규칙을 정의하면 그 규칙은 위로 삽입되기 때문에 순서를 변경할 수 있다.

 

 

 ※ 사슬 제어 옵션

 -N

 새로운 사슬 만들기

 -L

 사슬의 규칙을 보여주기

 -X

 비어 있는 사슬을 제거하기

 -P

 사슬의 규칙을 바꾸기

 -F

 사슬에 있는 모든 규칙을 지우기

 

 

※ 규칙 제어 옵션

 -A

 사슬에 새로운 규칙을 추가하기

 -I

 사슬에 규칙을 삽입하기

 -R

 사슬에 있는 규칙을 다른 규칙과 교환하기

 -D

 사슬에 있는 규칙을 제거하기

 

 

※ 하위옵션

 -s

 출발지 주소(source address)

 -d

 목적지 주소(destination address)

 --sport

 출발지 포트 번호(source port)

 --dport

 목적지 포트 번호(destination port)

 -p

 프로토콜(protocol: tcp, udp, icmp 등)

 -i

 패킷이 들어오는 네트워크 인터페이스(inbound interface)

 -o

 패킷이 나가는 네트워크 인터페이스(outbound interface)

 -f

 분절된 패킷(fragment packet)

 -j

 규칙을 지정(jump)

 

 

iptables 명령어를 통해 규칙을 지정하고나서 시스템을 재시작하면 모두 사라진다. 그렇기에 반드시 iptables-save 명령을 사용해서 현재 정의해 놓은 규칙을 /etc/iptables.rules 파일로 저장해야 한다.

 

# sudo sh -c "iptables-save > /etc/iptables.rules"

# cat /etc/iptables.rules

 

 

[ 네트워크 인터페이스 관련 셸 스크립트 ]

 

# vi iptables-load

iptables-load라는 셸스크립트를 작성한다.

 

 

#!/bin/bash

/sbin/iptables-restore < /etc/iptables.rules

파일에 정의된 방화벽 규칙을 적용하는 명령은 iptables-restore 이다.

 

# vi iptables-reload

시스템 종료와 같은 이유 때문에 네트워크 인터페이스를 중지할 때 추가된 방화벽 규칙을 저장하도록 iptables-reload라는 셸 스크립트를 작성한다.

 

#!/bin/bash

/sbin/iptables-save > /etc/iptables.rules

iptables-save 명령을 이용해서 변경된 방화벽 규칙을 'iptables.rules'파일에 저장

 

# chmod +x iptables-load

# chmod +x iptables-reload

셸 스크립트를 실행시킬 수 있도록 두 파일의 허가권을 수정

 

# sudo cp iptables-load /etc/network/if-pre-up.d/

# sudo cp iptables-reload /etc/network/if-post-down.d/

방화벽 활성화 스크립트 iptables-load는 네트워크 인터페이스가 시작하기 전에 실행할 스크립트를 저장해두는 /etc/network/if-pre-up.d 폴더에 복사 그리고 방화벽 설정 저장 스크립트 iptables-reload는 네트워크 인터페이스를 중지하고 난 다음 실행할 스크립트를 저장해두는 /etc/network/if-post-down.d 폴더에 복사

 

# sudo reboot

시스템을 재시작하고 iptables-load 스크립트가 정상적으로 동작하는지 iptables -L 로 확인