iptables은 강력한 패킷필터링 툴입니다.
기존의 iptables에 관한 자세한 문서들이 많이 나와있지만
이 문서는 리눅스 환경을 전제로 하며 iptables의 초심자들을 위해 설명을 하고자 합니다.
오타나 틀린 내용이 있으면 홈페이지에 관련부분을 기제해주기바랍니다.
작성일 2002.10.13
작성자 : 김창현 [CTCquatre] http://www.eyetolife.com
[ 패킷필터링 지식 ]
패킷필터링이란?
패킷필터링은 지나가는 패킷의 해더를 보고 그 전체 패킷의 운명을 결정하는 것을 말한다.
(iptables의 경우 많은 개발중인 기능에서 헤더에 그치지 않고 data의 내용을 검토하기도 한다. 가장 대표적인것이 string match기능이다.)
*:(일반적으로 패킷은 헤더와 데이타를 가진다. 헤더에 필터링할 정보인 출발지IP:PORT,도착지 IP:PORT, checksum,프로토콜 옵셋등을 가지며 데이터는 각각의 전송데이터가 들어간다.)
리눅스 박스의 패킷필터링의 역사
리눅스는 커널 1.1버젼 부터 패킷필터링을 포함하기 시작했다.
제 1세대는 BSD의 ipfw을 기본으로 하였고
2.0버젼에서 ipfwadm이 사용되었으며
1998년에 2.2기반 패킷필터링툴인 ipchains를 내놓았다.
그리고 이글에서 논의하고자 하는 제 4세대 필터링툴인 iptables이 2.4커널을 위해
만들어졌다.
netfilter?
일반 iptables사용자들이 가장간과하기 쉬운부분중 한 부분이다.
iptables이 패킷을 필터링 하는것이 아니다.
패킷필터링은 커널에 탑제된 netfilter기능으로 하며
iptables은 단지 netfilter의 룰을 세워줄 뿐이다.
즉 다시 말하자면 iptables은 룰셋구축 툴이라는 말이다.
[ 패킷필터링 ]
iptables에 대해
iptable에 기본 Chain은 아래와 같다.
INPUT chain
FORWARD chain
OUTPUT chain
위의 3가지가 기본 체인이다. 체인들의 모식도는 아래와 같다.
------>INPUT------> Linux Box ------>OUTPUT--------->
---------↕----------------------------↕
---------└--------- FORWARD ----------┘
여러분의 Linux box를 도착지로 삼는 모든패킷은 INPUT Chain을 통과하게 되며
여러분의 Linux box에서 생성되 외부로 보내지는 모든패킷은 OUTPUT Chain을
통과하게 된다.
Forward chain은 *엄밀히 말하자면 도착지가 여러분의 Linux box가 아닌 패킷이 통과하게 되는 체인이다.
*:(다음문서에 다루게 될 Masqurading시에 패킷의 destnationIP정보는 여러분의 Linux box이지만 패킷의 최종도착지는 내부네트워크의 어떠한 컴퓨터일것이다)
지금 커맨드라인에 아래와 같이 쳐보기 바란다.
# iptables -A INPUT -j DROP
엔터키를 누르는 즉시 여러분의 Linux box로 오는 패킷은 모두 거부당할것이다. 즉 모든 통신이 끊어진다.
위의 룰을 굳이 말로 옮기자면
-A:룰을 추가한다
INPUT: 패킷이 들어오는 체인에
-j:패킷의 운명을 결정한다.
DROP: 패킷을 버려라.
즉, INPUT체인으로 들어오는 패킷을 모두 버리는 룰을 추가하는 명령이다.
적용시킨 룰을 보고 싶다면
# iptables -L
이라는 명령을 치면된다.
-A와 같은 위치에 있는 옵션은 아래와 같다.
체인에 새로운 규칙을 추가하기 (-A)
체인의 어떤 지점에 규칙을 삽입하기 (-I)
체인의 어떤 지점의 규칙을 교환하기 (-R)
체인의 어떤 지점의 규칙을 제거하기 (-D)
체인에서 일치하는 첫번째 규칙을 제거하기 (-D)
이제 위에서 내린 룰을 지워 통신이 되게 하자.
아래와 같이 명령을 내리면 된다.
# iptables -D INPUT 1
또는
# iptables -D INPUT -j DROP 하면 될것이다.
첫번째 방법은 index(룰의 순서)를 지정해서 지우는 방법이고, 두번째는 룰의 내용으로 지우는것이다.
-I,-R은 첫번째 방법과 유사하게 쓸수있다.
룰을 다시 세우고 목록을 보자.
# iptables -A INPUT -j DROP
# iptables -L
살펴보면
Chanin INPUT (policy ACCEPT)
위와 같은 줄을 볼수있을것이다.
저 줄 밑에는 여러분들이 세운 룰의 정보를 볼수있을것이다.
(policy ACCEPT)를 설명하자면 여러분들이 세운룰에 해당되지 않을때
마지막으로 기본정책을 따라 패킷의 운명을 결정하게 된다. 여기서는 ACCEPT이므로
패킷은 받아드려질것이다. 아지만 이것을 DROP으로하면 패킷은 버려질것이다.
그리고 패킷필터링을 알아가면서 여러룰들을 세울것이다.
기본적으로 룰은 세워진 순서대로 패킷을 검사한다.
이제 기본정책을 바꾸어 보자.
# iptables -P INPUT DROP
위의 명령을 내리고 다시 iptables -L을 하면
Chanin INPUT (policy DROP)으로 된걸 볼수있다.
-P와 동등 위치의 옵션은 아래와 같다.
새로운 체인 만들기 (-N).
비어있는 체인을 제거하기 (-X).
※ 이 두옵션은 직접체인을 만들었을경우와 제어할경우에 해당된다. 기본체인(INPUT,OUTPUT,FORWARD) 에는 해당되지 않는다.
미리 만들어진 체인의 정책을 바꾸기 (-P)
어떤 체인의 규칙들을 나열하기 (-L)
체인으로부터 규칙들을 지우기 (-F)
체인내의 모든 규칙들의 패킷과 바이트의 카운드를 0 으로 만들기 (-Z)
[ 패킷의 목적지또는 출처 제어 ]
패킷출처 제어옵션 -s
# iptables -A INPUT -s 192.168.10.10 -j DROP
위에 같은 명령을 내렸다면 192.168.10.10으로 부터 온 패킷은 모두 버려지게 된다.
-s(--source,--src와 같은 옵션이다.) : 패킷의 출처 IP 지정
목적지 제어옵션 -d
# iptables -A INPUt -d 192.168.10.12 -j DROP
위와 같은 명령을 내렸다면 192.168.10.12의 IP를 도착지로 가지고있는 패킷은 모두 버려지게된다.
-d(--destination,--dst와 같은 옵션이다.): 패킷의 도착지 IP지정
※ IP지정 이외에 몇 가지 방법이 더 존재한다.
-s www.xxxx.com : 도메인으로 제어
-s 192.168.10.0/24 : 네트워크 또는 집단으로 제어
-s 192.168.10.0/255.255.255.0 :위와 동일
※ 보통 프로그래밍 약속기호처럼 !는 역('not')이라는 것을 표시한다.
ex) -s ! 192.168.10.10 이라고 하면 "출발지가 192.168.10.10이 아닌" 이라는 뜻이된다.
[ 프로토콜 제어 ]
프로토콜제어 옵션은 -p이다
-p옵션의 인자는 TCP,UDP,ICMP가 될수있다.
# iptables -A INPUT -p TCP -j ACCEPT
라는 명령을 내렸다면 tcp프로토콜을 쓰는 모든 패킷은 ACCEPT에 의해 허락될것이다.
※ -p의 인자로 TCP,UDP,ICMP의 프로토콜번호를 알고있다면 번호를 써도 상관없다.
포트 제어
포트제어 옵션은 --sport와 --dport이다
--sport는 패킷의 출발지 포트이다.( --source-port와 같은 옵션이다.)
--dport는 패킷의 도착지 포트이다.( --destination-port와 같은 옵션이다.)
# iptables -A INPUT -p tcp --dport 80 -j DROP
위와 같은 명령은 tcp프로토콜의 80(www:웹서버포트)번 포트를 목적지로 하는 패킷을
버리는 것이다.
※ --dport나 --sport의 인자로 서비스이름을 적어도 된다.
ex) --dport www
※ 여러 포트를 지정해야 된다면 --dport 1024:65535 와 같이 지정할수있다.
뜻은 1024 부터 65535번까지라는 뜻이다.
[ 인터페이스 지정 ]
인터페이스는 -i (input interface), -o (output interface)로 지정할수있다.
# iptables -A INPUT -i eth0 -p tcp --dport 80 -j DROP
위의 명령은 -i eth0옵션을 빼고는 port지정 예와 같다.
-i eth0는 eth0로 들오는 모든 패킷을 뜻한다.
보통 리눅스 박스처럼 인터넷과 연결된 디바이스가 1개라면 필요없는 옵션이 되겠지만
만약 eth0, eth1등 2개이상의 인터페이스가 인터넷과 연결되어있다면 위의 옵션은 유용하게 쓰일것이다.
※ INPUT 체인은 -i 옵션만 쓸수 있고, OUTPUT 체인에는 -o옵션만 쓸쑤있다.
반면에 FORWARD 체인은 -i,-o 옵션 두가지 다 쓸쑤있다. 이유는 다음문서에서 다루겠다.
총괄적인 예:
# iptables -A INPUT -i eth0 -d 192.168.10.10 -p tcp --dport 80 -j DROP
해설: INPUT 체인에 - 입력인터페이스가 eth0이고 도착지가 192.168.10.10이고
프로토콜은 tcp이며 도착 포트는 80(www)인 패킷은 DROP시켜라.
이제까지는 별 다른 지식이 없이도 이해할수있는 부분이었다.
하지만 지금부터 나오게될 내용은 tcp/ip의 기반적인 지식을 가지고있어야
이해하기 쉬울것이다.
tcp/ip지식이 필요한 옵션에 대해서는 그에따른 자세한 설명을 하겠지만
이해가 되지 않는 부분은 다른 문서나 책을 찾아보길 바란다.
[ 패킷의 행동 유형에 따른 필터링(--tcp-flags,m state --state) ]
! 주의 : 밑에 나오는 모든옵션은 TCP프로토콜옵션(-p TCP)가 먼저
선행되어 있어야 적용되는 옵션이다.
1)
--tcp-flags 옵션은 상태에 따라 유용하게 설정할수있다.
이 옵션을 설정하는 가장 큰 예는 한방향으로만 통신이 되게끔설정하기 위해
많이 사용한다.
tcp/ip는 3핸드쉐이크의 접속방식이다.
즉. 접속요청패킷,접속허가 패킷,확인패킷
접속 단계를 좀더 자세하게 보면
C: Client S:Server
1) C --------- syn -------▷ S
2) C ◁------- syn ack ----- S
3) C --------- ack -------▷ S
이런식으로 접속절차가 이루어진다.
syn패킷은 접속요청 플래그(syn)가 설정된 패킷이므로 syn패킷만 막으면 상대편에서 접속을 할수 없다는 것이다.
※ Dos공격의 일종인 Syn Flooding이 서버에 위에서 말한 syn형패킷을 무수히 많이
보내는 것이다.
이제 본격적으로 --tcp-flags옵션으로 syn 접속형 패킷을 막는것을 하겠다.
# iptables -A INPUT -p TCP --tcp-flags SYN,RST,ACK SYN -j DROP
--tcp-flags에 첫번째 인자는 검사할 리스트 마스크이다.
두번째 인자는 설정되어있어야할 플래그다.
즉 syn,rst,ack플래그중 syn이 set이 1로 되어있으면 위의 --tcp-flags설정에
해당이 되므로 패킷은 DROP된다.
위의 옵션과 같은 뜻을 가진것이 있는데 그것은 --syn이다.
--syn은 '--tcp-flags SYN,RST,ACK SYN'의 뜻을 가지고 있다.
2)
--tcp-flags보다 더 간단하게 설정하는 방법이 있다.
바로 tcp의 상태천이 다이아그램을 축소시켜 놓은듯한 느낌을 받는 상태에 따른 패킷분류를 iptables은 지원한다.
이것은 확장기능이므로 -m 플래그로 설정은 한다.
사용옵선은 -m state --state 이다.
인자값으로 들어가야할 상태에따른 리스트는 아래와 같다.
NEW : 새로운 접속을 만드는 패킷
ESTABLISHED :존재하는 접속에 속하는 패킷 (즉, 응답 패킷을 가졌던 것)
즉 접속이 허가되고 통신하면서 발생되는 패킷이다.
RELATED :기존의 접속의 부분은 아니지만 연관성을 가진 패킷으로 .
ICMP 에러 나 (FTP 모듈이 삽입 되어있으면) ftp 데이터
접속을 형성하는 패킷.
INVALID :어떤 이유로 확인할 수 없는 패킷. 알려진 접속과 부합하지 않는 ICMP 에러와
'out of memory' 등을 포함한다. 보통 이런 패킷은 DROP 된다.
이제 이 state 옵션을 사용해보자
위의 --tcp-flags옵션에서 예제와 같은 작용을 하는 룰을 만들어보겠다.
# iptables -A INPUT -p TCP -m state --state NEW -j DROP
왜 룰이 이렇게 되는지 차근차근 읽어보았다면 쉽게 이해가 될것이다.
일반적으로 서버는
# iptables -A INPUT -p TCP --dport 특정포트 -m state --state NEW,ESTABLISHED -j ACCEPT
이렇게 룰을 많이 세운다.
뜻은 tcp 특정 포트에 new:접속패킷과,established:통신패킷(정확히 쉽게 설명할
단어가 생각나지 않아 부적절하지만 통신패킷이라 부른다)을 허용하라.
그리고 클라이언트 측에서는 위의 state상태에서 NEW를 빼고 사용한다.
# iptables -A INPUT -p TCP --sport 특정포트 -m state --state ESTABLISHED -j ACCEPT
왜 NEW를 뺄까? 그 이유는
그 이유는 클라이언트입장에서 보면 접속을 허가해달라는 패킷이 필요없다는것이다.
더 쉽게 말하자면 클라이언트는 접속허가를 요청하는 위치이지 요청받는
위치가 아니라는 말이다.
그러므로 ESTABLISHED만 있으면 일반적으로 통신하는데 아무런 문제가 없다
그리고 주의깊게 본 사람이라면 위에 --sport가 쓰여진것을 볼수있을것이다.
왜 서버에서는 --dport로 제어를 하면서 클라이언트는 --sport로 제어를 할까?
지금 리눅스 박스라면 wget을 쓰던지 x-windows에서 브라우져를 쓰던지 아무런 웹사이트에 접속을 하고 바로 콘솔에서 'netstat -nat'라는 명령을 내려보자.
무슨말인지 알겠는가?
서비스를 한번이라도 해본적있는 사람이면 알겠지만 서버는 특정PORT를 열어놓고 접속을 기다린다.
클라이언트는 특정 서버에 접속을 하기 위해 별도로 포트를 생성하고 접속을 시도한다.
이때 클라이언트가 생성하는 포트번호는 1024이후의 랜덤값이다. 이런이유로 클라이언트입장에서는
--dport로 제어를 하지않는게 보통이다. 제어를 하더라도 상관없다. 하지만 그것은
상당한 비효율적인 룰이 될것이다.
[ftp를 위한 상태천이를 이용해 룰 설정]
ftp는 참 유별난 프로토콜이다. 특히 마스커레이드때 쓰이는 nat과 잘 맞지도 않을뿐더러.
ftp서버에서 passive모드로 운영을 할시 iptables로 제어하고 싶다면 따로 모듈이 필요하다.
passive로 1025:65535까지 임이의 데이타 전송포트를 쓸때
상태천이로 제어를 하자면,보안상 NEW를 사용하지 않는다.
즉,새로운 접속을 허가하지 않고
RELATED로 기존접속에 관련된것만 접속을 허용한다.
즉 실제 룰을 보면 아래와 같다
# iptables -A INPUT -p tcp --dport 1024:65535
-m state --state ESTABLISHED,RELATED -j ACCEPT
※ 만약 NEW를 사용한다면 방화벽 구실을 못할것이다.
왜그런지는 직접 생각해보라 위에서 이미 충분히 설명하였다.
ftp에서 위처럼 RELATED로 방화벽룰을 설정했다면
ip_conntrack_ftp라는 모듈없이 연결이 제대로 되지 않을것이다.
ip_conntrack_ftp는 ftp서버의 ftp접속 추적 모듈이다.
[ 조각(Fragments) 처리하기 ]
때때로 하나의 패킷이 한 번에 한 회선을 통과하기에는 너무 큰 경우가 발생한다.
이 때는 패킷이 `조각'으로 나뉘어 여러 개의 패킷으로 전송된다.
받는 쪽에서는 이 조각을 모아 하나의 패킷으로 재구성한다.
패킷 필터링 HOWTO에서는 nat이나 접속추적을 할때에는 분절패킷이 하나의 패킷으로
재구성되어 필터링되기때문에 해당되지 않는다고 명시되어 있다.
하지만 위와 같은 상황이 아니라면 조각을 처리해야하나 안전성을 이유로 처리하지
않는 것을 권장하고 있다. 그 이유는 아래에 설명할것이다.
일반적으로 패킷이 분절(토막)될때 필터링을 할 정보인 특히 발신지 포트,
목적지 포트, ICMP 유형, ICMP 코드 또는 TCP SYN 플래그등은 첫번쩨 패킷의
헤더에 밖에 포함되지 않는다. 즉 두번째 분절패킷부터는 그 정보가 없다는 말이다.
이를 위해서 우리는 분절된 패킷을 처리하기 위해 -f 옵션을 사용한다.
하지만 -f옵션을 권장하지 않는다. 왜냐하면 첫번째 필터링정보가 담긴 헤더를 보고
필터링을 할때 그 패킷이 거부하는 룰에 적용되어 거부되면 분절된 패킷이 거부되지
않고 오더라도 그것은 하나의 패킷으로 재구성 되지 않고 버려지기 때문이다.
사용법은
# iptables -A OUTPUT -f -d 192.168.1.1 -j DROP
처럼 사용한다.
위의 뜻은 192.168.1.1을 항해 나가는 분절된 패킷은 모두 버린다 이다.
다시 한번 말하지만 꼭 필요한경우를 제외하고 이 옵션은 권정하지 않는다.
이정도로 iptables의 기본 사용법에 대해 마치고자 한다.
이문서에서는 방화벽설정에서 자주 사용하게 되는 옵션에 대해서만 언급했다.
아니 이정도 옵션들이면 어느정도 방화벽은 구성할수 있을것이다.
나머지 옵션들은 man패이지나 패킷필터링 HOWTO에서 찾아보기 바란다
[IPTABLES] MASQ and FORWARD and MANGLE이 문서는 기본사용법에 이어 이번에는 Masquerading과 Foreward체인에 대해 다룹니다.
오타나 틀린 내용이 있으면 홈페이지에 관련부분을 기제해주기바랍니다.
작성일 2002.10.13
작성자 : 김창현 [CTCquatre] http://www.eyetolife.com
[Masquerading이란?]
IP 마스커레이드는 리눅스의 네트워킹 기능으로, 상용 방화벽(firewall)이나 네트웍 라우터(network router)에서 흔히 볼 수 있는 1 대 다(one-to-many) 방식의 NAT(Network Address Translation: 네트웍 주소 해석)와 유사하다. 쉽게 설명하자면 REAL IP 하나로 가상아이피를 가진 여러개의 컴퓨터,네트워크를 꾸밀수있다.
※ Masquerading는 본문에서 이하 MASQ라고 부르겠다.
[MASQ의 기본동작원리]
MASQ를 자세하게 설명하자면 아래와 같다.
INTERNET-------MASQ머신-----내부내트워크
인터넷과 내부네트워크 사이에 위치하여 주소를 변환하여 패킷을 통과시키는 역할을 하는것이 바로 MASQ머신이다.
이해를 쉽게 하기위해 하나의 상황을 꾸며보자.
내부네트워크에 일단 컴퓨터가 2대밖에 없다고 가정하고, 내부 네트워크주소는 192.168.1.0을 쓴다고 하며, MASQ머신의 실제 IP는 1.1.1.1이라고 하자.
그럼 모식도는 아래와 같을것이다.
INTERNET-------MASQ머신---------------- COM1 (192.168.1.2)
------------실제(1.1.1.1)----------|
------------가상(192.168.1.1)------└----- COM2 (192.168.1.3)
MASQ 머신에는 아미 마스커레이딩룰을 다 세팅한후이며, COM1,COM2역시 네트워크정보(IP와 게이트워이등)을 세팅한후다. 자세한 룰구축과 네트워크설정은 뒤에서 다룬다 다만 여기서는 먼저 MASQ의 기본개념과 상세한 동작원리를 설명하기 위해서 이렇게 한다.
이제 COM1이 웹브라우져로 어떤사이트에 접속을 한다고 하자. COM1에서 전송을 주고받을 임이의 포트를 연다.그 포트가 10000번이라고 하자. 그리고 패킷에는 다음과 같은 정보가 들어간다
도착지:웹사이트IP 도착포트:80
출발지:192.168.1.2 출발포트:10000
그리고는 게이트워이인 192.168.1.1(MASQ머신)으로 보내어 진다.
자 이제부터 MASQ머신이 일을 할차례이다.
MASQ머신은 우선 192.168.1.2에서 보내온 패킷을 받고 살펴본다.
그리고 난후 MASQ머신의 임이의 포트(여기서 일반 임이의포트를 5000번이라고 하자) 를 192.168.1.2의 IP,10000포트에 대해 매칭한다.
※ 일반적인 포트개념과는 조금은 다르다. 그래서 통신이 될때, netstat -nat 해도 MASQ머신에서는 포트가 보이지 않는다. 그리고 패킷을 변조한다.
도착지:웹사이트IP 도착포트:80
출발지:1.1.1.1 출발포트:5000
위와 같이 변조하고 인터넷으로 보내어 버린다. 그러면 웹서버에서 응답이 온다.
어디로? 바로 1.1.1.1의 주소에 5000번 포트로.
왜? 바로 MASQ머신에서 출발지 주소를 변조해버렸기때문이다.
자.기다리던 응답이 왔다.
패킷을 보면
도착지:1.1.1.1 도착포트:5000
출발지:웹사이트IP 출발포트:80
분명 COM1이 접속하고자 한 웹사이트에서 응답이 왔는걸을 위에서 보면 알수있다.
자 이제 이 패킷을 받은 MASQ머신은 다시 COM1에게 이 패킷을 전달해주기 위해 또다시 변조작업을 해야한다.
아래와 같이 변조한다. 이미 위에서 5000번 포트를 192.168.1.2의 10000포트로 매칭을 하고 MASQ머신은 똑똑하게 그것을 기억하고 있다. 그러므로 아래와 같이 변조된다.
도착지:192.168.1.2 도착포트:10000
출발지 웹사이트IP 출발포트:80
이렇게 하고 변조된 패킷은 내부 네트워크로 보내어진다.
그 다음 결과는 불보듯 뻔할것이다. COM1은 이 패킷을 받게 될것이고. 마치 웹사이트와 직접연결되어 패킷을 주고 받은것처럼 이패킷을 처리할것이다. 그리고 COM1이 바라던대로 웹프라우져에 접속한 웹사이트가 뜰껏이다. 재미있지 않은가?
MASQ머신이 하는일은 위와같다. 자 이제는 직접 MASQ머신을 꾸며 볼 차례이다.
우선 MASQ에 필요한 테이블은 아래와 같다.
FORWARD체인에 속해있는 PREROUTING과 POSTROUIING 테이블이 바로 우리가 룰을 세울 테이블이다. 한번 직접 보자
#iptables -t nat -L
위와 같이 치면 지금 룰이 텅텅비어있는 테이블을 보게될것이다.
iptables기본사용법 문서에서 다루었지만 위의 명령을 설명하면
-t(타겟지정옵션) nat(바로 패킷변조작업을 할 테이블)
-L 목록출력
※우선 FORWARD체인부터 설명해야겠지만 이 글을 읽고 있는 여러분은 MASQ에 더 관심이 있을줄 알고 POSTROUTING과 PREROUTING에 대해 먼저 설명을 한다.
POSTROUING? PREROUTING?
이름으로부터 벌써 추측을 할수 있을것이다.
POSTROUTING = 패킷을 변조후 보내는 룰을 세우는 테이블
PREROUTING = 패킷을 받아 변조시키는것인데 MASQ시에 포워딩부분에서 사용한다.
즉 앞에 문서에서 설명한 MASQ의 기능에서는 이 테이블이 쓰인적이없다. 나중에 포워딩부분에서 이 테이블을 다룰것이다.
우선 하나의 룰을 예로 들며 설명하겠다.
# iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to 1.1.1.1
위의 명령을 말로 풀어보자면
-t(타겟) nat(주소변환테이블 이곳에 POSTROUTING과 PREROUTING이 속해있음)
-A 룰추가
POSTROUTING 테이블에
-o eth0 ouput디바이스가 eth0 라면
-j SNAT 출발지 주소를 변환하라.( SNAT은 source NAT이라고 생각하면 된다.)
--to 1.1.1.1 IP가 1.1.1.1로
중요!:바로 이부분이 우리가 가진 MASQ머신의 실제IP를 적는 곳이다. 왜 이곳에 적는지는 SNAT으로 충분히 설명이 된다. 이곳에 적은 IP는 MASQ머신이 인터넷으로 보낼때 이곳 IP로 출발지를 변조해서 보낼것이다.
한문장으로 합치면 "nat테이블에 있는 POSTROUING테이블에 output디바이가 eth0이면 출발지 주소를 1.2.3.4로 변환하는 룰을 추가하라" 라는 말이된다.
※ --to 1.1.1.1 이외에 여라가지 방법으로 주소를 설정할수있다.
ex) --to 1.1.1.1-1.1.1.10 여러가지 변환이 필요할때.
위의 명령은 출발지 주소를 1.1.1.1부터 1.1.1.10까지 랜덤하게 바꾼다.
ex) --to 1.1.1.1:1-1024
위의 명령은 출발지 주소를 1.1.1.1로 하되 포트번호를 1번에서 1024번까지 해라는 명령이지만 잘 사용하지 않는다. 포트제한이 꼭 필요한경우라면 사용해야하겠지만, 절대 권장하지 않는다.
위의 예제 룰 한줄이면 앞장에서 설명한 MASQ의 주소변조 작업을 수행할수있다. 하지만 더 세밀하게 할수도 있다.
우리가 iptables 기본사용법 문서에서 사용한 옵션의 일부를 여기서 사용할수있다. 아래와 같이.
-s, -d, -p, --dport를 옵션을 쓸수있다.(--dport는 SNAT에서 잘 쓰이지 않는다.)
이제 조금 더 세밀한 MASQ룰 을 세워보자
# iptables -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j SNAT --to 1.1.1.1
이 번에는 -s옵션을 추가하였다. 물론 위쪽룰과 이 룰은 같은것이다. 다만 -s(출발지 옵션을 추가한것 뿐이다.) 그리고 -p옵션을 사용하지 않았는데 보통 이것은 사용하지 않는다. 왜냐면 우리는 통신에 tcp,udp 프로토콜을 같이 쓰기때문에 틀정 프로토콜을 정할수도 있겠지만 그렇게 하지 않는게 보통이다. 이정도면 충분히 MASQ머신을 만들수 있을것이다.
[포워딩]
자 이번에는 포워딩을 해보자. MASQ머신의 단점이 될수도 있고 장점이 될수있는 부분은은 내부에서 외부로밖에 접속을 할수없다는 것이다. 반대로 외부에서 내부는 접속이 전혀 되지 않는다.
외부에서 접속을 하려고 한다치자.
그러나 외부에서는 절대 내부를 볼수없다. 왜? 인터넷으로 나오는 패킷은 전부 MASQ머신이 보낸 패킷처럼 출발지 IP를 변조시켜 보내니까. 즉 외부에서 보기에는 MASQ만 보일뿐 어떤 내부컴퓨터도 볼수없다.
※ 이것이 장점이 될수있고 단점도 될수있는 부분이다. 내부로 연결은 밑에서 설명할 룰을 세워야만 가능하다. 룰없이는 불가능하다. 즉 내부로 연결하자면 조금 번거로울수있다(?). 소리바다 및 구루구루, MSN파일전송을 위해 설정하는것도 이러한 이유다. 하지만 이것은 다른면에서 보면 자동으로 보안을 강화시킬수 있는 장점이 되기도 한다.
그러면 어떻게 masq를 거쳐 내부컴으로 연결을 할수있을까?
바로 앞에서 잠시 말한 PREROUTING테이블에 룰을 세우면 이것을 할수있다.
다음과 같은 명령을 보자.
# iptables -t nat -A PREROUTING -p tcp -d 1.1.1.1 --dport 80 -j DNAT --to 192.168.1.2:80
이번에는 PREROUTING과 DNAT(destination NAT 이라고 보면됨)이 쓰였다. 이것이 포워딩에 쓰이는것이다. 즉 도착지를 다른곳으로 변경시켜 주는것이다.
위의 룰을 설명하면
-A PREROUTING : PRETOURING 테이블에 룰을 추가해라.
-p tcp : tcp프로토콜이고
-d 1.1.1.1 : 도착지가 1.1.1.1이며
--dport 80 : 80번포트로 접속을 하면
-j DNAT 목적지를 변환시켜라
--to 192.168.1.2:80 : 192.168.1.2 의 80번 포트로
즉 tcp프로토콜이고 도착지가 1.1.1.1이고 도착포트가 80번(www)이면 그 패킷은 192.168.1.2의 80번포트로 보내라. 자 이러면 우리가 외부에서 1.1.1.1번의 80번 포트로 접속을 할수있는것이다.
외 부에서 보기에는 1.1.1.1의 컴에서 (80번 포트이므로 웹서버라 하겠다.) 웹서비스를 하고 있는걸로 보이지만 사실은 1.1.1.1은 패킷을 다른곳으로 보내줄뿐이고 사실상 웹서비스를 하고 있는 컴퓨터는 내부의 192.168.1.2번 컴퓨터이다.
udp또한 -p옵션으로 설정을해 포워딩을 시킬수 있다.
이번에는 특정 주소로 오는것을 전부다 포워딩을 시켜보자.
# iptables -t nat -A PREROUTING -d 1.1.1.1 -j DNAT --to 192.168.1.2
위의 명령은 프로토콜에 상관없이 도착지가 1.1.1.1이면 무조건 포워딩시켜버린다.
자 이제 실제 MASQ를 꾸미는 예를 보자.
우선 MASQ머신에 이더넷 카드 두장이상이 필요하다. 외부를 연결할 디바이스와 내부를 연결한 디바이스이다. 그리고 eth1과 eth0 의 네트워크 설정을 해주기 바란다.
일반적으로 eth1를 내부와 연결할경우 내부컴퓨터들의 게이트웨이는 eth1의 IP가 된다.
그런 다음 간단하게 다음과 같이 명령을 내리자.
패킷을 forwarding가능하게 하기위해 다음과같이 커널파라이터를 고친다. 부팅시 기본은 원래 0으로 되어있다. 다음과 같이 명령을 내리자.
# ehco 1 > /proc/sys/net/ipv4/ip_forward
그리고 난뒤 룰을 올리자. eth0의 IP가 1.1.1.1이고 내부 네트워크가 192.168.1.0이라면
# iptables -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j SNAT --to 1.1.1.1
이 한줄이면 끝이다. 이 명령을 세우고 내부 컴에서 인터넷을 해보라. 잘 될것이다.
그리고 난 내부 컴에서 웹서버와 ftp서버를 돌리고 싶다.아래와 같이 하라. 내부 웹서버 IP가 192.168.1.2이고 포트는 80번이이면 밑과의 룰로 될것이다.
# iptables -t nat -A PREROUTING -p tcp -d 1.1.1.1 --dport 80 -j DNAT --to 192.168.1.2:80
그리고 ftp서버는 192.168.1.3번이고 21번 포트를 쓴다. ftp서버가 active모드로 돌아간다면 data전송을 위해 20번포트를 쓰니까
# iptables -t nat -A PREROUTING -p tcp -d 1.1.1.1 --dport 21 -j DNAT --to 192.168.1.3:21
# iptables -t nat -A PREROUTING -p tcp -d 1.1.1.1 --dport 20 -j DNAT --to 192.168.1.3:20
위와 같이 내린다.
하 지만 위는 예일뿐 실제 ftp는 MASQ하에 돌리지 않는다. 그이유는 속도측면에서의 손해와 passive모드(ftp 문서를 찾아보기 바란다)등이며 ftp는 절대적으로 NAT(즉, MASQ) 와 별로 친하지 않다. 따로 모듈을 올려줘야 한다. 그러한 이유등에서 ftp서버를 nat안에 두지 않는걸 적극 권장한다.
아! 그리고 중요한게 한가지 더 있다.
내부에서 ftp서버를 돌리든 돌리지 않든 내부 컴에서 ftp 클라이언트를 안정적으로 이용하려려면 MASQ머신에 ip_nat_ftp.o 이 모듈을 꼭 올려줘야만 한다. ip_nat_ftp는 nat의 ftp접속추적모듈이다.
이로써 MASQUERADING부분이 끝났다. 이정도면 충분히 마스커레이딩을 할수있고, 부족하다면 관련 문서를 찾아보며 조금만 공부를 하면 될것이다.
이번에는 FORWARD체인과 Mangle테이블에 대해 다루어 보자
[FORWARD]
FORWARD체인은 nat을 포함하고 있다. nat은 PREROUTING,POSTROUTING을 포함하고 있다.
즉 FORWARD체인이 가장 상위의 체인이다. 설사 nat의 PREROUTING이나 POSTROUTING에서 먼저 룰을 세웠더라도 FORWARD에 룰을 세우면 이것은 가장먼저 적용된다. FORWARD체인의 룰셋은 INPUT과 OUTPUT과 동일하다. 하지만 틀린점이 있다면 -i,-o등 양쪽 인터페이스를 다 지정할수있다. 실제로 예를 들어보이겠다.
#iptables -A FORWARD -p tcp --dport 80 -i eth0 -o eth1 -j DROP
명령 풀이에 더이상 -p나 --dport등 이미 자주설명해왔던것들은 생략하겠다.
-i eth0 : eth0으로 들어오는
-o eth1 : 그리고 eth1로 나가는 패킷은
-j DROP : 버려라
이 룰이 일단 세워지면 아무리 PREROUTING에서 80번 포트 포워딩을 세웠더라도 우선 FORWARD룰이 먼저 적용되기때문에 적용패킷은 버려질것이다.
이것이 FORWARD의 내가 사용하는 전부이다.
물론 더 있겠지만 실제로 쓰고, 많이 언급되고 있는 전부라는 것이다.
[Mangle]
이번에는 Mangle테이블을 보자. Mangle테이블은 패킷필터링 룰을 세우는 곳이 아니다.
Mangle 테이블은 성능향샹을 위한 TOS를 설정하는 것이다. TOS를 알고 싶다면 tcp/ip관련 문서나 책에서 찾아보기 바란다. 매우 고급적이 내용이므로 확실하게 이해하지 않는경우 그대로 두기 바란다. 잘못 설정할 경우 네트워크에 심각한 상황을 초래할수도 있다.
그래도 한번 해보고 싶은 사람이 있다면 큰맘 먹고 해보면 된다. 사실 리부팅하면 모든 룰이 그러하듯이 다 없어진다 :)
TOS코드
이름 CODE[HEXCODE] 설명
Minimize-Delay 16[0x10] 최소지연
Maximize-Throughput 8[0x08] 최대 전송률
Maximize-Reliability 4[0x04] 최대 안정성
Minimize-Cost 2[0x02] 최소 경로
Normal=service 0[0x00] 일반서비스
telnet과 ssh는 최소 지연을 사용하고, ftp는 최대 전송률을 사용하게끔 세팅을 해보자
INPUT 체인
# iptables -t mangle -A INPUT -p tcp --dport 22
-j TOS --set-tox 0x10 // ssh
# iptables -t mangle -A INPUT -p tcp --dport 23
-j TOS --set-tox 0x10 // telnet
# iptables -t mangle -A INPUT -p tcp --dport 21
-j TOS --set-tox 0x10 // ftp 커맨드 전송포트
# iptables -t mangle -A INPUT -p tcp --dport 20
-j TOS --set-tox 0x08 // ftp-data전송포트
OUTPUT 체인
# iptables -t mangle -A OUTPUT -p tcp --dport 22
-j TOS --set-tox 0x10 // ssh
# iptables -t mangle -A OUTPUT -p tcp --dport 23
-j TOS --set-tox 0x10 // telnet
# iptables -t mangle -A OUTPUT -p tcp --dport 21
-j TOS --set-tox 0x10 // ftp 커맨드 전송포트
# iptables -t mangle -A OUTPUT -p tcp --dport 20
-j TOS --set-tox 0x08 // ftp-data전송포트
위에 설정한 그대로다 이제 일일이 설명하지 않아도 iptables 기본사용법과 이문서를 차근차근 본 문서라면, 또 이까지 별문제 없이 온사용자라면 위 문장만 봐도 충분히 이해가 가리라 믿는다.
[IPTABLES] LOG
이 문서에서는 iptables의 log부분에 대해 다룹니다.
오타나 틀린 내용이 있으면 홈페이지에 관련부분을 기제해주기바랍니다.
작성일 2002.10.13
작성자 : 김창현 [CTCquatre] http://www.eyetolife.com
LOG의 대한 부분을 다루고자 이문서를 추가한다.
LOG는 크게 다룰것이 없다고 생각한다.
타겟 LOG와 --log-prefix 옵션만 알면
거의 해결되는것과 같다.
iptables의 LOG는 확장 타겟이며 커널레벨의 로그를 제공한다.
syslogd에 의해 처리된다.
옵션은 --log-lever,과 --log-prefix가 있다.
일반적으로 --log-lever은 실제로 꼭 필요한 경우를 제외하고
룰에 잘 명시하지 않으며 기본값인 warning을 쓴다.
loglevel은 총 7가지 옵션이 프로퍼티가 있는테
유효한 이름은 (상황에 따라 다르다)
'debug' 'info', 'notice', 'warning', 'err', 'crit', 'alert', 'emerg' 이고 이것 은 각각 숫자 7 에서 0 에 대응한다.
이런 레벨에 대한 설명은 syslog.conf 의 man 페이지를 보라.
그 다음 --log-prefix옵션이다.
--log-prefix옵셔은
14자 까지의 별도의 문자로 로그메세지에 선행될 수있다.
ex)
iptables -A INPUT -i eth0 -p tcp -J LOG --log-prefix="IPTABLES TCP:"
위와 같이 설정을 하면 INPUT 체인의 인터페이스 eth0에 대해여 tcp프로토콜일때
로그를 남기되 선행되는 메세지는 'IPTABLES TCP:로그내용' 이된다.
주의할것은 로그는 패킷의 운명을 결정하지 않으며 적용되든 되지않든 다음 룰을
검사하게 한다.
그리고 LOG는 LOG를 남기고자 하는 정책 위에 세워져야 한다.
예는 다음과 같다.
# iptables -A INPUT -p tcp --syn -j LOG --log-prefix 'SYN refuse'
# iptables -A INPUT -p tcp --syn -j REJECT
위와 같이 설정한다면 만약 tcp의 접속형 패킷의 로그를 남기고 패킷을 거절한다.
만약 해당룰에 대한 로그를 설정하고 운영중 로그파일(보통 /var/log/messages)
에서 iptables해당로그가 너무 많다거나 또는 너무 없어서(?) 조절하고 싶으면
limit모듈을 사용하면 효과적이다.
※ limit모듈은 기본값으로 한시간에 3번의 로그를 남긴다.
limit모듈은 '-m limit'로 사용할수 있다.
이것은 적용검사의 속도를 제한하는데 로그메세지와 함께쓰일경우
로그메세지를 남기는 속도를 제어하게된다.
예를 보자
# iptables -A INPUT -p tcp -m limit -j LOG
위와 같이 한다면 한시간에 3번 로그를 남길것이다.
limit는 위에도 말했듯이 기본적으로 한시간에 3번의 로그를 남긴다
이를 조정할려면 --limit옵션을 사용하여
조절할수있다.
--limit
숫자가 따라온다 : 초당 평균 최대 적용 검사 수를 지정한다.
숫자뒤 에 시간단위를 지어할 수 도 있다.
('/second', '/minute', '/hour', '/day'형태이다. 예로, '5/second' 또는 '5/s'가 가능하다)
# iptables -A IPUT -p tcp -m limit --limit '5/minute' -j LOG
위와 같이 설정한다면 1분에 평균 5번의 로그를 쓸것이다.
로그는 syslogd에서 kernel message를 다른곳으로 남기지 않게 한 이상은
/var/log/messages에 남게 된다.
세밀한 로그정책을 세울려면 더 세세하게 설정하는 확장옵션들이 있으나
이정도면 충분히 로그정책을 수립할수있을것이다.
나의 iptables에 대한 문서는 여기까지 이다.
이정도 설명이면 iptables에 대해서 정말 충분하게 설명한거라
생각한다.
하지만 iptables의 기능은 참으로 대단하다.
여러 확장기능이 그러하다.
확장기능을 공부하다 보면 실제로 상상도 못한 기능들이
많이 숨어 있을것이다.
마지막으로 이 글을 읽는 여러분께 부탁이 있다면
이문서에 부족한 부분을 지적해주셨으면 한다.
그러면 다음에 그 글을 읽는 사람은 더욱많은것을
얻어갈수있을것이다.
이 문서가 부디 많은 iptables 초보자께 유용한 문서가
되길 바라는 마음으로 이문의 끝을 맺는다.
댓글을 달아 주세요