강좌
클라우드/리눅스에 관한 강좌입니다.
해킹&보안 분류

리눅스서버 보안 iptables 완벽 사용법

작성자 정보

  • 관리자 작성
  • 작성일

컨텐츠 정보

본문

리눅스서버 보안 iptables 완벽사용법

 

 

 

패킷필터링 기능을 포함하여 커널 컴파일도 하고, iptables도 설치하였다면 이제 본격적으로 iptables의 명령어 사용방법, rule을 설정하는 방법에 대해 알아보자.

 

 

iptables의 기본적인 명령어 용법은 다음과 같다.

 

 

사용형식 : iptables [-t table] 명령어 [매칭옵션] [타겟]

 

지금부터 iptables에서 사용하는 table, iptables명령어, 매칭옵션, 타겟 등에 대해서 자세히 알아보도록 하겠다.

 

 

 

 

 

 

(1) iptablestable

 

제일 먼저 지정할 것은 사용할 table명을 설정하는 것인데, 앞에서 언급한 바와 같이 별도로 table명을 지정하지 않을 경우에는 기본적으로 filter 테이블이 사용된다.

 

 

 

 

, 패킷을 필터링하기 위해 filter 테이블을 사용한다면 -t filter와 같이 지정하여도 되고, 별도로 지정하지 않아도 무방하다는 것이다.(일반적으로 지정하지 않는다.)

 

 

 

그러나 natmangle 기능을 이용하려면 반드시 -t nat, -t mangle과 같이 각각의 해당 테이블 명을 명시하여야 하며 지정하지 않으면 filter 테이블로 기본 인식하게 되어 제대로 작동하지 않게 된다.

 

 

 

 

그리고 테이블 명 다음에는 매칭 옵션을 현재 테이블에 추가할 것인지(append 또는 insert) 삭제할 것인지(delete)등의 명령어를 지정하게 된다.

 

 

 

 

다음으로는 어떠한 패킷을 필터링하거나 nat할 것인지 매칭 옵션을 지정할 수 있는데, 이를테면 어떠한 IP 주소를 소스로 한 패킷인지, 어떠한 인터페이스를 통과하는지 또는 정책을 설정할 패킷이 tcp인지, udp인지 등이 그것이다.

 

 

 

 

일반적으로 매칭 옵션이 길어지면 길어질수록 좀 더 세부적인 패킷을 나타내게 된다.

 

 

 

 

이를테면 "-p tcp"이면 단순한 tcp 패킷을 뜻하지만 “-p tcp --dport 80”이면 목적지 포트가 80으로 향하는 tcp 패킷을 뜻하는 것이다.

 

 

 

 

마지막으로 이 룰에 매칭 되는 즉 이 룰에 합당하는 패킷이 있을 경우 이 패킷을 어떻게 처리할 것인지(패킷을 통과시킬 것인지, 거부할 것인지 등)를 타겟(target)에서 지정할 수 있다.

 

 

 

 

 

 

(2) iptables 명령어

이제 본격적으로 iptables에서 사용할 수 있는 명령어들에 대하여 알아보도록 하자. 여기에서 설명하는 모든 명령어나 옵션을 외우거나 기억하고 있을 필요는 없다.

 

 

 

 

필요할 때마다 찾아보고 참고하기만 하면 되므로 설명을 보고 아 이런 것이 있구나라고 이해만 하면 되겠다.

 

 

 

 

물론 자주 사용되는 옵션 정도는 기억해 두는 것도 좋을 것이다.

 

 

 

 

 

 

-A, --append 명령어

 

: iptables -A INPUT ...

 

-A 또는 --append를 이용하여 룰을 입력하면 해당 chain의 제일 마지막에 추가된다.

 

 

 

 

방화벽뿐만 아니라 라우터에서 사용하는 access-list등과 같은 패킷 필터링에서는 어떤 정책을 먼저 설정했는가에 따라 방화벽 정책이 결정될 정도로 룰의 순서가 매우 중요한데, 이를테면 tcp를 모두 허용하는 룰을 먼저 설정한 후 특정 tcp 패킷을 거부하는 룰을 설정했다면 tcp 패킷은 이미 허용되었으므로 뒤에서 차단하는 룰을 추가해도 허용될 것이다.

 

 

 

 

여기에서 -A는 실행한 순서대로 제일 마지막에 추가된다는 점에 주의하기 바란다.

 

 

 

 

만약 룰의 제일 앞에 설정하기를 원한다면 -A 대신 insert의 의미인 -I를 입력하면 된다.

 

 

 

 

또 한 가지 주의할 것은 대소문자의 구별인데, -A를 사용할 때에는 반드시 대문자를 사용하여야 하며 --append보다는 -A를 주로 사용하므로 -A를 사용하기 바란다.

 

 

 

 

특히 ipchains와는 대소문자가 차이가 있으므로 ipchains에 익숙한 사용자는 주의하기 바란다.

 

 

 

-D, --delete 명령어

 

) iptables -D INPUT -p tcp --dport 80 -j DROP

iptables -D INPUT 1

 

-D 또는 --delete를 이용하여 룰을 잘못 입력했거나 필터링 정책이 변경되었을 경우 이미 입력한 룰을 테이블에서 삭제하는 명령어이다.

 

 

 

 

-D는 두 가지로 이용할 수 있는데, 첫 번째

예제처럼 룰을 추가할 때 사용했던 것과 같이 완전한 룰을 지정하는 방법도 있고(이때는 다른 부분은 동일하고 단지 -A 대신 -D를 쓰면 된다.) 두 번째 예제처럼 입력한 룰의 순서대로 지정된 번호를 이용하는 방법도 있다.

 

 

 

 

두 번째 방법을 사용할 때에는 각각 chain의 위에서부터 차례대로 숫자가 매겨지는데, 첫 번째 룰은 1번이 될 것이다.

 

 

 

 

각 룰의 번호는

#iptables -L --line을 실행하여 첫 번째 열을 보면 확인할 수 있다.

 

 

 

 

일반적으로 두 번째 방법보다는 첫 번째 방법을 많이 이용한다.

 

ce66ec756e45f2946147457ac3966ce9_1680068887_7461.png
 

[그림] iptables -L --line시 룰순서

 

 

 

-I, --insert 명령어

 

)iptables -I INPUT -p tcp --dport 80 -j ACCEPT

 

-I 또는 --insert-A와 같이 룰을 추가하는 것이긴 하지만 -Achain의 제일 마지막에 추가되는 것과는 달리 -Ichain의 제일 처음에 추가된다는 차이가 있다.

 

 

 

 

룰의 순서는 명령어를 입력한 순서대로 설정되는데, 패킷 역시 룰의 순서대로 검사되므로 여러 룰을 지정할 경우 순서는 매우 중요하다.

 

 

 

 

또한 아무리 전문가라 하더라도 가끔 실수하는 경우가 있으므로 방화벽 룰을 설정할 경우에는 일일이 터미널 상에서 입력하지 말고, 룰 스크립트 파일을 만들어서 파일을 수정 후 스크립트를 실행하는 방법으로 작업하는 습관을 들이는 것이 좋다.

 

 

 

 

-I는 일반적으로 먼저 룰이 적용된 상태에서 새로운 룰을 테스트하고자 할 때 또는 임시로 특정한 룰을 적용하고자 할 때 사용된다.

 

 

 

 

 

 

-L, --list 명령어

 

)iptables -L INPUT

 

-L은 지정한 chain의 모든 룰 목록을 보여준다.

 

 

 

 

예제의 경우 INPUT chain의 모든 룰을

보여주게 되는데, 이때 -n과 함께 사용하지 않으면 모든 IP및 포트 번호에 대해 reverse lookup(IP를 호스트이름으로, 포트번호를 포트이름으로 역질의)을 하여 출력 속도가 느리게 되므로 -n 옵션과 함께 사용하는 것이 좋다.

 

 

 

 

, -L만 사용하였을 경우에는 다음과 같이 보이게 되지만,

 

ACCEPT tcp -- u210-181-168-192.thrunet.com anywhere tcp spts:kdm:65535 dpt:http

 

-L -n과 같이 -n을 함께 사용하였을 경우에는 다음과 같이 보이게 된다.

 

 

 

 

 

 

ACCEPT tcp -- 192.168.181.210 0.0.0.0/0 tcp spts:1024:65535 dpt:80

 

참고로, 위의 룰은 iptables -A INPUT -p tcp -s 192.168.181.210 --sport 1024:65535 --dport 80 -j ACCEPT를 실행하였을 경우 보이게 되는 목록이다.

 

 

 

 

 

또한 -v와 함께 사용하면 해당 룰에 매칭된 패킷의 개수(pkts)와 바이트(bytes)등 세부적인 정보를 함께 볼 수 있다.

 

 

 

 

-F, --flush 명령어

 

 

) iptables -F INPUT

 

-F는 모든 룰을 플러싱(flushing) 또는 삭제하는 명령어이다.

 

 

 

 

-D가 룰을 한 개씩 삭제하는 것과는 달리 -F는 모든 룰을 한꺼번에 삭제하는 명령어이다.

 

 

 

 

위 예와 같이 -F 다음에 INPUT을 지정할 경우에는 INPUT chain의 모든 룰을 삭제하게 되고, 아무것도 입력하지 않을 경우에는 filter 테이블 내 모든 룰을 삭제하게 된다.

 

 

 

 

따라서 natmangle 테이블에 있는 룰을 초기화하려면 "-F -t nat""-F -t mangle"과 같이 테이블 명을 지정해 주어야 한다.

 

 

 

 

-F는 새롭게 룰을 생성하고자 할 때 혹시 남아있을지 모르는 룰을 깨끗하게 삭제하기 위해 주로 사용되는데, 주의할 점은 이때 -P로 지정한 기본 정책은 변경되지 않는다는 것이다.

 

 

 

 

, INPUT의 기본정책을 DROP으로 설정한 후 특정 IP에서의 접속을 허용하는 룰을 생성하였을 경우 -F로 룰을 초기화하게 되면 허용하는 룰은 삭제되고 기본정책인 DROP은 그대로 남게 되므로 일체의 모든 접속이 거부되는 것이다.

 

 

 

 

필자도 이 때문에 가끔 실수를 하는데, -F를 사용할 때는 먼저 기본정책(-P)을 허용하도록 한 후 적용하도록 주의하기 바란다.

 

 

 

-N, --new-chain 명령어

 

 

 

) iptables -N TEST

 

-N은 새로운 chain을 생성하는 명령어이다.

 

 

 

 

앞에서 언급한 것처럼 새로운 chain을 생성할 수는 있지만 새로운 table은 생성할 수 없다.

 

 

 

 

일반적으로 룰이 단순하다면 굳이 chain을 생성할 필요는 없지만 복잡하다면 생성해서 사용하는 것이 효율적이다.

 

 

 

 

 

 

 

-X, --delete-chain 명령어

 

) iptables -X TEST

 

-X는 지정한 chain을 삭제하는 명령어이다.

 

 

 

 

 

아래는 TEST chain을 생성한 후 삭제하는 예를 보여주고 있다.

 

 

 

 

 

 

# iptables -N TEST

# iptables -L

Chain INPUT (policy ACCEPT)

target prot opt source destination

 

Chain FORWARD (policy ACCEPT)

target prot opt source destination

 

Chain OUTPUT (policy ACCEPT)

target prot opt source destination

 

Chain TEST (0 references)

target prot opt source destination

 

# iptables -X TEST

 

 

 

 

그러나 아래와 같이 INPUT chain을 삭제하려고 하였으나 INPUT chain은 삭제되지 않는 것을 알 수 있다.

 

 

 

 

왜냐하면 INPUT, FORWARD, OUTPUT chainfilter 테이블에서 반드시 있어야 할 기본 chain이기 때문이다.

 

 

 

 

 

# iptables -X INPUT

 

iptables: Can't delete built-in chain

 

-P, --policy 명령어

 

 

 

) iptables -P INPUT DROP

 

-P는 앞에서 잠깐 언급했듯이 지정한 chain에 대한 기본정책(default policy)을 의미한다.

 

 

 

 

이를테면 방화벽으로 들어오는 패킷은 INPUT 테이블에서 지정된 룰 순서대로 매칭이 되는지 점검하게 되는데, 만약 INPUT 테이블에 있는 모든 룰에 매칭 되지 않을 경우에는 기본정책인 -P에서 지정된 정책이 적용되는 것이다.

 

 

 

 

 

일반적으로 기본 정책에서는 DROP을 설정하고(REJECT는 지원하지 않는다.) 세부 룰에서 특정한 패킷을 허용(ACCEPT)하는 정책을 설정한다.

 

 

 

 

물론 정책에 따라 그 반대도 있을 수 있을 것이다.

 

 

 

 

 

기본정책을 설정할 때는 -j를 사용하지 않으므로 “iptables -P INPUT -j DROP”과 같이 사용하지 않도록 주의하기 바란다.

 

 

 

 

 

 

 

(3) iptables 매칭 옵션

 

 

다음으로는 iptables의 매칭 옵션에 대해 알아보자. 앞에서 언급한 바와 같이 매칭 옵션을 많이 지정하면 할수록 좀 더 세부적인 패킷을 지정하게 된다.

 

 

 

 

 

 

-p, --protocol 옵션

 

 

) iptables -A INPUT -p tcp

 

-p 옵션은 tcpudp, icmp처럼 매칭 되는 프로토콜(protocol)을 지정하는데, not의 의미인 ! 를 함께 사용할 수도 있다.

 

 

 

 

, -p ! tcptcp가 아닌 즉 udpicmp를 의미한다.

 

 

 

 

또한 all을 사용할 수도 있는데, 이는 모든 프로토콜을 의미하며 이러한 경우 굳이 입력하지 않아도 된다.

 

 

 

 

그리고 /etc/protocols 파일에 정의된 대로 tcp, udp, icmp와 같은 프로토콜 명 대신 각각 6, 17, 1 과 같이 프로토콜 number로 지정해도 된다.

 

 

 

 

 

소문자인 -pprotocol을 의미하는 대신, 대문자인 -P는 기본정책을 의미한다는 점에 주의하기 바란다.

 

 

 

-s, --source 옵션

 

 

) iptables -A INPUT -s 192.168.1.0/24

 

-s 옵션은 패킷의 소스IP 주소를 뜻하는데, 192.168.1.1과 같이 단일한 하나의 IP 주소를 지정할 수도 있고, 192.168.1.0/255.255.255.0이나 192.168.1.0/24와 같이 넷마스크나 CIDR를 사용하여 IP 대역을 지정하여 사용할 수도 있다.

 

 

 

 

물론 단일한 IP를 지정할 경우 netmask255.255.255.255로 사용하거나 CIDR/32를 지정해도 된다.

 

 

 

 

만약 위의 예와 같이 사용할 경우에는 192.168.1.x 대역의 모든 IP 주소 대역에서 들어오는 패킷을 뜻하게 되며 -s를 지정하지 않을 경우에는 IP와 관계없이 모든 곳으로부터 들어오는 패킷을 뜻하게 된다.

 

 

 

 

모든 IP는 통상적으로 "0/0”으로 사용하나 “any/0"이나 ”0/0“, ”anywhere", "0.0.0.0/0.0.0.0"등을 사용해도 된다.

 

 

 

-d, --destination 옵션

 

) iptables -A INPUT -d 192.168.1.2

 

-s 옵션이 패킷의 소스 주소를 의미하는데 반해 -d 옵션은 목적지 주소를 뜻한다.

 

 

 

 

문법은 -s와 동일하며 -d를 지정하지 않으면 모든 목적지에 대한 매칭이므로 자기 자신을 통과하는 모든 패킷을 뜻하게 된다.

 

 

 

 

만약 위와 같이 -s없이 -d만 지정되어 있다면 192.168.1.2로 향하는 모든 패킷을 뜻하지만 “-s 192.168.1.1 -d 192.168.1.2”와 같은 경우 소스 IP192.168.1.1이면서 목적지 IP192.168.1.2인 패킷을 뜻한다.

 

 

 

 

여기에서 이면서는 그리고(and)의 개념이지 또는(or)의 개념이 아니라는 점에 주의하기 바란다.

 

 

 

 

-i, -o 옵션

 

) iptables -A INPUT -i eth0

 

이는 어떤 인터페이스에서 들어오고 나가는 패킷인지 지정한다.

 

 

 

 

-iin으로서 들어오는 인터페이스를 의미하는 반면 -oout으로서 나가는 인터페이스를 의미한다.

 

 

 

 

따라서 당연한 이야기이지만 INPUT chain에서 -o를 사용할 수 없고, OUTPUT chain에서는 -i를 사용할 수 없다.

 

 

 

 

복잡한 네트워크에서 방화벽에 여러 인터페이스를 설치하여 사용할 경우 지정하면 유용하게 사용할 수 있는데, 만약 eth0과 같이 1개의 인터페이스만 설정되어 있다면 어차피 인터페이스는 하나이므로 굳이 인터페이스를 지정할 필요가 없다.

 

 

 

 

또한 별도의 인터페이스를 지정하지 않으면 모든 인터페이스에 해당하는 룰이 된다.

 

 

 

 

 

--sport , --dport 옵션

 

) iptables -A INPUT -i eth0 -p TCP -s 192.168.5.3 --sport 1024:65535 --dport 161

 

--sport는 패킷의 소스포트를, --dport는 목적지 포트를 의미하는데, 이 옵션을 사용할 때에는 “-p tcp”“-p udp”와 같이 tcp인지 udp인지 명시하여야 한다.

 

 

 

 

아울러 앞에서 살펴본 IP 주소의 경우에는 -s, -d와 같이 -1개이지만 지금 살펴볼 포트번호의 경우에는 --sport, --dport와 같이 -2개라는 점에 주의하기 바란다.

 

--sport--dport는 위의 예와 같이 함께 사용할 수도 있고, --sport 또는 --dport 하나만 사용할 수도 있다.

 

 

 

 

물론 지정하지 않을 경우에는 모든 포트를 뜻하게 되므로

"-s 192.168.5.3 --sport 1024:65535"와 같은 경우에는 목적지 포트와는 관계없이 소스 IP192.168.5.3이면서 소스 포트는 1024부터 65535까지인 패킷을 뜻하게 된다.

 

 

 

 

 

 

또한 사용할 때에는 --dport 161과 같이 특정 포트를 지정할 수도 있고 --sport 1024:65535와 같이 특정 포트의 대역을 지정할 수도 있다.

 

 

 

 

만약 1024:만 지정하였을 경우에는 1024부터 65535까지를 의미하며 :1024만 입력하였을 경우에는 1024 이하 즉 0부터 1024까지를 의미한다.

 

 

 

 

그리고 not의 의미인 !을 함께 이용할 수도 있는데 ! 1024:65535 1024부터 65535까지가 아니므로 0:1023의 의미와 동일하다.

 

 

 

 

--tcp-flags 옵션

 

)iptables -A INPUT -p TCP --tcp-flags ACK,FIN FIN

 

tcpudpicmp와 달리 패킷의 특성상 SYN, ACK, FIN, PSH, URG, RST6개의 tcp-flags 라는 것을 가지고 있다.

 

 

 

 

이를테면 접속을 요청하는 tcp 패킷의 경우 패킷에 SYN 비트가 설정되고, 요청에 대해 응답을 할 경우에는 ACK, 접속을 종료할 경우에는 FIN 비트가 설정되는 것이 그 예이다.

 

 

 

 

iptables에서는 이를 명시적으로 지정하여 특정한 패킷에 대한 매칭을 시킬 수 있는데, tcp-flags 사이의 빈 공간(blank)을 기준으로 좌측의 tcp-flags는 체크할 tcp-flags를 우측의 tcp-flags는 체크한 항목 중 매칭되는 tcp-flags을 의미한다.

 

 

 

 

, 위의 예에 있는 룰은 INPUT chain을 통하여 들어오는 tcp 패킷에서 6개의 tcp-flags 가운데 모두 살펴 볼 필요 없이 ACKFIN 부분만 살펴보아서(공란을 기준으로 앞쪽에 있는 ACK,FIN부분) ACK는 없이 FIN만 설정되어 있는 패킷(공란을 기준으로 뒤쪽에 있는 FIN)을 뜻한다.

 

 

 

 

, ACK 비트가 없는 FIN 패킷을 의미하는 것이다.

 

 

 

 

그리고 여기에서는 ACKFIN만 체크하였으므로 SYN 비트나 PSH등 다른 tcp-flags가 있거나 또는 없어도 관계는 없다.

 

 

 

 

이외 ALL은 모든 tcp-flags를 의미하며, NONE는 아무런 tcp-flags가 없는 것을 뜻한다.

 

 

 

 

뒤에서는 실제 패킷 필터링 룰 적용 시 이러한 tcp-flags의 특징을 이용하여 비정상적인 tcp 패킷을 필터링하는 방법을 알아보도록 하겠다.

 

 

 

 

 

--syn 옵션

 

) iptables -A INPUT -p tcp --syn -j DROP

 

tcp에서 syn 비트가 설정된 패킷의 의미는 남다르다.

 

 

 

 

왜냐하면 syn 패킷은 tcp 연결을 맺기 위해 제일 먼저 보내어지는 접속 요청 패킷이기 때문이다.

 

 

 

 

만약 위의 예와 같이 들어오는 tcp 패킷 중 SYN 비트가 설정된 패킷을 거부하였다면 모든 tcp 접속 연결 요청은 거부될 것이다.

 

 

 

 

그러나 방화벽 내부에서 외부로 접속 요청하였을 경우에는 OUTPUT에서는 SYN이지만 INPUT에서는 SYN 패킷이 아니라 SYN 패킷에 대한 응답으로 SYN/ACK 비트가 설정된 패킷이 들어오게 되므로 내부에서는 외부로 tcp 접속을 할 수 있게 된다.

 

 

 

 

--syn !과 함께 사용하여 ‘! --syn’과 같이 사용될 수 있는데, 이때에는 위조된 패킷이 아니라면 이미 접속된 tcp 연결을 의미하게 된다.

 

 

 

 

물론 --syn은 앞에서 살펴본 tcp-flags를 사용해서도 표현할 수 있지만 syn 패킷의 남다른 의미가 있어 예외적으로 syn 패킷에 대해서만 별도의 명령어를 제공한다.

 

 

 

 

 

--icmp-type 옵션

 

) iptables -A INPUT -s 192.168.1.1 -p ICMP --icmp-type echo-request

 

tcpudp는 포트번호로 어떤 서비스인지 구별한다.

 

 

 

 

, 같은 tcp라도 23번은 telnet, 80번은 http, 110번은 pop3인 것이 그것이다.

 

 

 

 

그러나 icmp 프로토콜은 tcpudp와 달리 port 의 개념이 없으며 대신 icmp-typecode라는 것을 사용한다.

 

 

 

 

icmp-type을 지정할 때에는 정확한 type 이름을 써도 되고 해당이름에 대한 번호를 지정해도 된다.

 

 

 

 

마찬가지로 tcpudp의 경우도 포트이름(:http)을 써도 되고 포트번호(:80)를 써도 되지만 tcpudp는 포트번호로, icmptype 이름을 설정하는 것이 더욱 명료하다 왜냐하면 포트번호는 /etc/services에 지정된 이름으로 매칭 하는데, 이는 서버마다 이름이 다소 다르거나 변경될 수 있기 때문이다.

 

 

 

 

반면 icmp-typeiptables 안에 지정되어 있으므로 번호보다는 좀 더 직관적이기 때문이다.

 

 

 

 

 

icmp-typecode에 대해서는 http://www.iana.org/assignments/icmp-parameters를 참고하기 바라며 iptables -p icmp -h를 실행하면 iptables에서 지원하는 icmp type을 확인할 수 있다.

 

 

 

 

위 예의 경우 INPUT chain을 통해 들어오는 패킷 중 소스 주소가 192.168.1.1이면서 icmp-typeecho-requesticmp 패킷을 의미하는 것이다.

 

 

 

 

192.168.1.1에서의 ping 요청을 뜻하는 것이다.

 

 

 

 

여기에서 -p 다음의 icmp는 위와 같이 대문자로 써도 되고 소문자로 써도 된다.

 

 

 

 

--limit 옵션

 

) iptables -A INPUT -s 192.168.1.0/24 -p icmp -m limit --limit 5/minute

 

--limit는 지정한 시간 동안의 최대 매칭 횟수를 정의하는 것으로 서비스거부 공격을 차단하는데 사용될 수 있다.

 

 

 

 

지정한 시간은 /second /minute /hour /day등이 있으며 위 예의 경우 패킷의 소스주소가 192.168.1.0/24 대역인 icmp 패킷 중 1분 동안에 최대 5번 매칭되는 것을 의미한다.

 

 

 

 

--limit 명령어는 주로 룰에 매칭 되는 패킷에 대한 로그 메시지를 남기도록 지정해 놓고, 로그 메시지에 저장하는 횟수를 제한할 때 유용하게 사용할 수 있는데, 이를테면 들어오는 icmp 패킷에 대해 로그를 남기도록 했을 때 특별한 제한이 없으면 모든 icmp 패킷에 대해 로그를 남기게 되므로 위와 같이 --limit를 이용하여 제한을 하였을 경우에는 제한된 시간동안 제한된 로그만 남도록 할 수 있다.

 

 

 

 

-m limit 후 특정한 횟수/시간단위를 지정하지 않을 경우에는 기본 값인 시간당 3회로 적용된다.

 

 

 

 

--limit-burst를 지정할 경우 --limit를 적용하기 전까지 적용할 횟수를 지정할 수 있다.

 

 

 

 

, -p icmp -m limit --limit 5/minute --limit-burst 10인 경우 먼저 10개의 icmp 패킷이 매칭 된 다음, 분당 5개씩으로 제한된다.

 

 

 

 

 

-m state 옵션

 

) iptables -A INPUT -p TCP ! --syn -m state --state NEW

 

-m state는 상태 추적(Connection State)을 할 때 사용된다.

 

 

 

 

상태 추적을 할 때 기본적으로 연결형 프로토콜인 tcp는 물론이고 비 연결형 프로토콜인 udpicmp 패킷도 추적이 가능하다.

 

 

 

 

현재 NEW, ESTABLISHED, RELATED 그리고 INVALID 이렇게 4가지의 상태추적을 제공하는데, newNeW와 같이 대소문자에 관계없이 사용할 수 있지만 일반적으로 대문자를 사용하므로 대문자를 사용할 것을 권장한다.

 

 

 

 

또한 실제 룰에서 각각을 NEW, ESTABLISHED, RELATED 그리고 INVALID 대신 N,E,R,I와 같이 첫 글자만 사용할 수도 있지만 정확한 이해를 위해 정확하게 입력하는 것이 더 좋다.

 

여기에서 NEW는 새롭게 연결을 시작하려 하거나 이전의 연결추적 테이블에 보이지 않는 패킷을 의미한다.

 

 

 

 

tcp의 경우 연결을 맺기 위한 정상적인 syn 패킷이 여기에 해당할 것이다.

 

 

 

 

 

 

ESTABLISHED는 클라이언트의 연결 시도 후 서버에서 응답하여 이미 연결되어 있는 상태를 의미하며 연결이 맺어진 이후의 tcp ack 메시지나 이미 데이터가 오고간 udp 또는 icmp echo-request에 대한 icmp echo reply 메시지 등이 이에 해당한다.

 

 

 

 

tcp 연결에서 3 way handshake가 성립되었을 때 netstat에 보이는 ESTABLISHED와 다소 개념 차이가 있으므로 주의하기 바란다.

 

 

 

 

 

 

RELATED는 새롭게 연결을 시작하려고 하나 이미 연결추적 테이블에 접속과 관련 있는 ESTABLISHED 테이블이 있는 경우를 뜻한다.

 

 

 

 

주로 icmp 에러 메시지가 여기에 속하며 ftp 접속 시 사용하는 두 번째 포트인 ftp-data(tcp 20번 등)가 대표적인 경우이다.

 

 

 

 

특히 ftp의 경우 서버 쪽에서 단일한 포트를 사용한다면 이미 세션이 성립된 패킷에 대해서는 ESTABLISHED를 사용하면 되겠지만, ftp의 경우 21/tcpftp 연결이 된 후 데이터를 전송하기 위해서는 20/tcp1024이후의 포트를 사용하는 ftp-data가 사용되기 때문에 기존의 ESTABLISHED로는 매칭 할 수 없는 것이다.

 

 

 

 

자세한 내용은 뒤에서 살펴보기로 한다.

 

마지막으로 INVALID는 연결 상태를 알 수 없거나 잘못된 헤더를 가지고 있는 경우를 뜻한다.

 

 

 

 

이를테면 icmp echo request를 보낸 적이 없는데, icmp echo reply 메시지를 수신하는 경우가 여기에 해당한다.

 

 

 

 

 

 

특히 상태 추적에서 tcp-flagsyn 패킷과 상태 추적의 NEW를 혼동하지 않기를 바란다.

 

 

 

 

syn 패킷은 단순히 tcp 패킷 중 syn flag가 설정된 패킷을 뜻하며 상태추적의 NEW는 기존의 상태추적 테이블 목록에 없는 패킷을 뜻한다.

 

 

 

 

이는 물론 tcp의 경우 정상적인 상황이라면 syn 패킷이 해당할 것이고, 기존에 접속이 없었는데도 마치 기존의 접속인 것처럼 위장하기 위하여 ACK flagFIN flagtcp-flag을 임의로 설정하여 발송하는 것도 결국은 기존의 테이블 목록에 없으므로 NEW가 될 것이다.

 

 

 

 

위의 룰 예는 들어오는(INPUT) tcp 패킷 중 syn flag가 설정된 패킷이 아니면서 연결 추적 테이블에는 처음 보이는 패킷을 의미한다.

 

 

 

 

연결 추적 테이블에 처음 보이는 tcp 패킷이라면 syn 패킷 이외는 없을 것이므로 따라서 위의 룰에 매칭되는 패킷은 분명 위조된 패킷이나 비정상적인 패킷이므로 필터링하여야 할 것이다.

 

 

 

 

이외 UNCLEAN이라는 것도 있는데, 이는 아직 개발 중인 기능이므로 서비스에 직접 적용하지는 말기 바란다.

 

 

 

 

상태추적은 고급 방화벽에서는 매우 중요한 개념이므로 반드시 이해하여야 하는데 이에 대한 더 상세한 내용은 차후에 별도로 알아보도록 하자.  

 

 

 

 

 

(4) iptables 타겟(target)

 

iptables 명령어의 제일 마지막 부분인 타겟에 대한 설정 부분이다.

 

 

 

 

지금까지는 이러이러한 조건에 맞는 패킷을 지정하는 부분이었고 타겟은 이러한 룰에 매칭 되는 패킷이 있을 경우 어떻게 처리할 것인지를 지정하는 부분으로 ‘-j 타겟형식으로 지정하면 된다.

 

여기에서 -jjump의 의미이며 해당하는 패킷을 어떻게 처리하겠다는 의미이다.

 

 

 

 

타겟에는 ACCEPT, DROP 또는 LOG, SNAT, DNAT 등이 올 수 있다.

 

 

 

 

ACCEPT는 말 뜻 그대로 룰에 매칭 되는 패킷의 흐름을 허용한다는 의미이며, DROP은 패킷을 필터링(거부)하는 것을 뜻한다.

 

 

 

 

LOG는 단지 해당하는 룰에 매칭 되는 패킷 정보를 로그에 남긴다는 의미이며 그 자체로 로그만 남길 뿐 다른 액션을 취하지는 않는다.

 

 

 

 

따라서 로그에 남긴 이후 해당 패킷을 허용할 것인지 거부할 것인지 별도로 지정하여야 한다.

 

 

 

 

아울러 SNATDNATNAT , 주소 변환을 한다는 것을 의미한다.

 

 

 

 

이외 자주 사용되는 몇 가지 타겟에 대해 알아보자.

 

 

LOG 타겟

 

매칭 되는 패킷을 LOG 타겟으로 보내면 패킷의 IP 주소 및 기타 유용한 정보를 로그에 남기도록 하며, 이 정보는 dmesg등의 명령어나 /var/log/messages 파일 또는 임의로 지정한 다른 파일에서 확인할 수 있는데, 주로 룰을 디버그 할 때나 방화벽에서 필터링 된 패킷의 로그를 보고자 할 때 사용된다.

 

 

 

 

이를테면 룰이 제대로 작동하는지 100% 확신할 수 없을 때는 DROP을 하기 전에 LOG를 사용하여 테스트 해 볼 수 있을 것이다.

 

 

 

 

LOG에서 주로 사용하는 옵션은 --log-level--log-prefix가 있는데, --log-level에서는 syslogd에서 제공하는 것처럼 debug, info, notice, warning(warn), error(err), crit, alert 그리고 emerg(panic)등을 이용하여 어떠한 로깅 레벨을 사용할 것인지 정할 수 있다.

 

 

 

 

그리고 --log-prefix를 이용하면 매칭 되는 패킷에 대해 로그정보를 남길 때 로그 앞에 어떤 메시지(일종의 말머리)를 남길 것인지 지정할 수 있다.

 

 

 

 

 

 

이를테면 iptables -A INPUT -p tcp -j LOG --log-prefix "INPUT tcp packets"와 같이 지정할 때 이 룰에 매칭 되어 저장되는 모든 로깅 정보 앞에는 “INPUT tcp packets”이라는 문자열이 붙게 되는 것이다.

 

 

 

 

아래는 dmesg로 확인하였을 때 보이는 로그의 한 예이다.

 

ILLEGAL-SYN/FIN:IN=eth0 OUT= MAC=00:01:02:54:c3:55:00:02:fc:08:c4:a0:08:00 SRC=151.189.46.70 DST=211.1.22.50 LEN=40 TOS=0x00 PREC=0x00 TTL=27 ID=39426 PROTO=TCP SPT=22 DPT=22 WINDOW=1028 RES=0x00 SYN FIN

 

 

 

이는 룰에 매칭 되는 패킷에 대해 “ILLEGAL-SYN:FIN”이라는 --log-prefix가 설정되어 있는 것을 추측할 수 있으며, eth0 인터페이스를 통해 들어오는(IN=eth0) 패킷이었다.

 

 

 

 

“OUT=“부분이 비어있는 것으로 보아 이 패킷이 INPUT에서 DROP되어 OUT으로 나가지 못했다는 것을 알 수 있다.

 

 

 

 

그리고 MAC은 각각 패킷 목적지의 MAC(00:01:02:54:c3:55) 과 패킷 송신지의 MAC(00:02:fc:08:c4:a0), 그리고 마지막의 08:00은 이더넷 프레임을 뜻한다.

 

 

 

 

이 패킷의 소스 주소는 151.189.46.70이고(SRC=151.189.46.70) 목적지 주소는 211.1.22.50(DST=211.1.22.50)인 것을 알 수 있으며 LEN=40으로 보아 IP 패킷의 길이가 40byte 라는 것을 알 수 있다.

 

 

 

 

또한 TOStype 필드는 0x00이며(TOS=0x00) 선행 필드는 0x00(PREC=0x00), TTL값은 27이라는 것도 알 수 있으며 패킷이 단편화(fragmentation)되었을 때 분절된 서로의 패킷을 인식하기 위해 사용하는 단편화 ID39426이라는 것을 알 수 있다.

 

 

(ID=39426) 또한 이 패킷은 tcp이며(PROTO=TCP) 소스 포트는 22(SPT=22) 목적지 포트도 22(DPT=22)이며 Windows 사이즈는 1028(WINDOW=1028)이다

 

 

 

그리고 RES=0x00는 예약된(reserved) 비트를 뜻하며 SYNFIN tcp-flags가 설정되어 있는 것(SYN FIN)을 알 수 있다.

 

 

 

참고로, 이 패킷은 소스 포트와 목적지 포트가 모두 동일한 Privileged 포트인 22를 사용하였으며 접속을 요청하는 SYN 비트와 접속을 끊는 FIN 비트가 함께 설정되어 있어 비정상적인 위조된 패킷임을 알 수 있다.

 

 

 

 

 

REJECT 타겟

 

REJECTDROP과 같이 룰에 매칭 되는 패킷을 거부하지만 중요한 차이점이 하나 있다.

 

 

 

 

그것은 바로 DROP이 패킷을 거부한 후 어떠한 추가적인 동작이 없는 반면 REJECT는 패킷 거부와 함께 패킷의 소스 주소로 패킷이 거부되었다는 에러 메시지를 발송한다는 점이다.

 

 

 

 

패킷을 REJECT할 때는 프로토콜에 따라 다른데, 만약 tcp인 경우에는 RST 비트가 설정된 tcp 패킷으로 또는 icmp 패킷으로 응답하고 이외 udp등의 패킷일 경우에는 icmp 패킷으로 응답한다.

 

 

 

 

특히 icmp 패킷으로 응답하도록 할 경우에는 icmp 타입을 함께 지정할 수 있는데, icmp-net-unreachable, icmp-host-unreachable, icmp-port-unreachable, icmp-proto-unreachable, icmp-net-prohibited 또는 icmp-host-prohibited등을 지정할 수 있다.

 

 

 

 

만약 별도로 지정하지 않을 경우 기본적인 에러 메시지는 port-unreachable이 된다.

 

 

 

 

아래는 REJECTDROP할 때의 결과를 tcpdump로 캡처한 결과인데, 보는 바와 같이 REJECT의 경우 ‘port unreachable’이라는 icmp 패킷으로 바로 응답하지만 DROP할 경우에는 아무런 반응이 없는 것을 알 수 있다.

 

 

 

REJECT

 

10:00:32.581924 eth0 > 192.168.1.2.59693 > 192.168.1.4.auth: S 3663506555:3663506555(0) win 5840 <mss 1460> (DF)

10:00:32.584036 eth0 < 192.168.1.4 > 192.168.1.2: icmp: 192.168.1.4 tcp port auth unreachable (DF) [tos 0xc0]

 

 

DROP

 

10:00:32.581924 eth0 > 192.168.1.2.59693 > 192.168.1.4.auth: S 3663506555:3663506555(0) win 5840 <mss 1460> (DF)

 

 

이후에 아무런 메시지가 없다.

 

 

 

 

 

 

REJECT할 것인가? DROP할 것인가?

 

 

 

그렇다면 거부하여야 할 패킷이 있을 때 타겟을 REJECT하는 것이 좋을까 아니면 DROP 하는 것이 좋을까? 이에 대해서는 보안 전문가들 사이에서도 다소 이견이 있는데, 결론부터 이야기한다면 DROP하는 것이 좋으며 실제 대부분의 방화벽에서도 DROP을 하고 있다.

 

 

 

 

왜냐하면 REJECT를 할 경우에는 거부되는 패킷에 대해 일일이 거부되었다는 응답을 보내주어야 하므로 이로 인하여 다음과 같은 부작용이 발생할 수 있기 때문이다.

 

 

 

- 불필요한 네트워크 트래픽을 늘리게 된다.

 

 

 

- 요청할 때마다 응답한다면 만약 동시에 많은 요청을 할 경우 그만큼 응답하여야 하므로 이는 역으로 서비스 거부 공격으로 악용될 수 있는 가능성도 있다.

 

 

 

 

 

 

- 또한 비록 에러 메시지라 할지라도 어떠한 응답이든 그 자체로 공격자에게 유용한 정보가 될 수도 있기 때문에 거부하여야 할 패킷은 DROP을 함으로써 아예 응답하지 않도록 하는 것이 좋다.

 

 

 

 

물론 대부분의 서비스에 대해서는 DROP하는 것이 좋으나 반드시 모든 서비스에 대해 DROP이 권장되는 것은 아니다.

 

 

 

 

왜냐하면 DROP을 할 경우에는 서버 쪽에서 패킷을 거부한 후에도 추가적인 아무런 메시지를 보내지 않기 때문에 아무 메시지도 받지 못하는 송신자 쪽에서는 연결시도가 timeout이 될 때까지 기다려야 하므로 속도 저하의 원인이 될 수 있기 때문이다.

 

 

 

 

그 대표적인 것이 tcp 113번을 사용하는 identd 서비스이다.

 

 

 

 

identd는 대부분 보안을 위해 서비스를 제공하지 않지만 특정 응용 프로그램에서는 접속을 요청한 사용자를 인증하기 위해 클라이언트의 identd에 요청을 하도록 되어 있다.

 

 

 

 

그런데, 이 포트(113/tcp)DROP으로 차단되어 있을 경우에는 아무런 응답을 하지 않으므로 응용 프로그램에서는 timeout이 될 때까지 기다린 후 다음 프로세스가 진행되기 때문에 상당한 속도 저하가 생기게 되므로 이때에는 REJECT로 바로 응답하도록 하는 것이 좋다.

 

) 실제 DROPREJECT를 설정하였을 때 어떤 차이가 있는지 살펴보자.

 

 

 

* DROP으로 차단되어 있는 경우에는 접속 요청 후 한참이 지난 후에야 연결시간 초과 메시지가 떨어지고 프롬프트가 떨어진다.

 

 

 

 

아래의 경우 drop.linux.com 서버가 DROP으로 차단되어 있는 경우이다.

 

[root@www /root]# telnet drop.linux.com 23

Trying 192.168.1.3...

 

한참 후에 다음과 같은 메시지가 떨어진다.

 

 

 

 

 

telnet: connect to address 192.168.1.3: 연결 시간 초과

 

* REJECT로 차단되어 있는 경우 접속 요청 후 RST가 설정된 tcp 패킷 또는 icmp 패킷을 수신하므로 바로 프럼프트가 떨어진다.

 

 

 

 

 

아래의 경우 reject.linux.com 서버가 REJECT로 차단되어 있거나 아예 방화벽이 설정되어 있지 않은 시스템에서 113/tcp가 리슨하지 않는 경우이다.

 

 

 

[root@www /root]# telnet reject.linux.com 113

Trying 192.168.1.3...

telnet: connect to address 192.168.1.3: 연결이 거부됨

 

REJECT를 사용할 때 tcp 패킷을 필터링할 경우에는 icmp 메시지 대신 tcp reset 메시지를 보내도록 할 수도 있다.

 

 

 

 

이는 tcp 프로토콜에 대해 차단하고자 할 때 유용한데, 특히 아래와 같이 identd(113/tcp) 요청에 대해서는 tcp reset을 보내는 것이 좋다.

 

 

 

 

만약 아래와 같은 설정을 하지 않고 DROP을 할 경우 내부 서버에서 외부로 telnet이나 ftp 또는 pop3, smtp등 중간 프로세스에서 identd를 사용하는 프로토콜 접속 시 현저한 속도저하를 느끼게 된다.

 

 

 

 

 

 

iptables -A INPUT -p TCP --syn --dport 113 -j REJECT --reject-with tcp-reset

 

 

참고로, ident1장에서 언급한 바와 같이 클라이언트에서 서버로 요청하는 것이 아니라 접속 요청을 받은 telnet이나 smtp등의 서버에서 클라이언트로 요청하는 것이므로 위의 설정은 외부에서 내부 서버로 접속하는 속도와는 관계가 없다.

 

 

 

 

만약, 외부에서 서버로 접속할 때 ident 때문에 느리다면 해당 데몬에서 아예 ident 질의를 하지 않도록 설정하는 것이 좋다.

 

 

 

 

이를테면, proftpd에서 identd 질의를 하지 않도록 하려면, IdentLookupsoff로 하고, sendmail에서는 sendmail.cf에서 O Timeout.ident=0s와 같이 설정하면 된다.

 

 

 

아래는 icmp 대신 tcp reset 메시지로 응답하도록 설정한 후의 결과이다.

 

 

 

 

앞에서처럼 단지 REJECT하였을 때의 결과와 비교해 보기 바란다.

 

09:52:59.268146 eth0 > 192.168.1.2.59692 > 192.168.1.4.auth: S 3200680897:3200680897(0) win 5840 <mss 1460> (DF)

09:52:59.268431 eth0 < 192.168.1.4.auth > 192.168.1.2.59692: R 0:0(0) ack 3200680898 win 0 (DF)

 

 

 

 

 

 

NAT에서의 타겟

 

NAT를 이용하면 크게 두 가지 용도로 활용할 수 있다.

 

 

 

첫 번째는 방화벽이 마치 라우터와 같은 역할을 하여 내부 네트워크에서는 사설 IP를 사용하면서 NAT방화벽을 통과하여 외부 네트워크로 나갈 때는 공인 IP를 소스로 한 주소로 변환되어 사용하는 경우로서 통상적으로 많이 사용되는 인터넷 공유기(NAPT)를 생각하면 된다.

 

 

 

 

실제로 리눅스의 iptables를 이용하면 일반 공유기 제품보다 훨씬 고성능이면서도 다양한 기능을 구현할 수 있다.

 

 

 

첫 번째의 경우가 내부에서 외부로 나갈 때 내부의 사설 IP가 공인 IP로 변경되는 경우라면, 두 번째는 반대의 경우로서 외부에서 공인IP로 들어오는 접속요청이 내부의 사설IP로 변경되는 경우이다.

 

 

 

 

웹 서버 등을 구축하여 외부에 인터넷 서비스를 제공할 때 실제서버들은 사설 IP를 운영하면서 서버 앞단에 설치되어 있는 방화벽에서 공인 IP로 들어온 요청을 내부의 사설 IP의 특정 포트로 포워딩을 하는 경우이다.

 

 

 

 

 

 

NAT에서는 공인 IP와 사설 IP간에 라우팅의 역할을 하므로 NAT로 사용되는 리눅스에는 eth0eth1 이렇게 최소한 두 개의 인터페이스가 연결되어 있어야하며, 각각의 인터페이스에서는 사설 IP 대역과 공인 IP 대역이 각각 셋팅되어 있어야 한다.

 

 

 

 

좀 더 정확하게 이야기하면 NATIP 주소 간 변환이므로 반드시 공인<->사설일 필요는 없으며 사설<->사설, 공인<->공인이어도 관계는 없다.

 

 

 

 

단지 일반적으로 공인<->사설로 활용되는 경우가 흔하기 때문에 이 부분에 맞추어 설명한 것뿐이다.

 

 

NAT에서는 Source NAT(SNAT), Destination NAT(DNAT), 마스커레이드(MASQUERADE), REDIRECT 이렇게 네 가지 종류의 타겟을 지원하며 이 타겟을 사용하려면 NAT 테이블임을 명시하기 위해 “-t nat”을 반드시 함께 사용하여야 한다.

 

 

 

 

아울러 NAT 방화벽을 통과하는 패킷을 공인에서 사설 또는 사설에서 공인 등 다른 서버나 장비로 포워딩해 주어야 하므로 방화벽이 설치된 시스템에서는 커널 파라미터인 net.ipv4.ip_forward 가 반드시 1로 설정되어 있어야 한다.

 

 

 

 

여기에서 1on의 의미로서 포워딩을 제공한다는 의미이며, 0off로 포워딩을 하지 않는다는 의미이다.

 

 

 

 

이 값을 1로 설정하려면 “echo 1 >/proc/sys/net/ipv4/ip_forward” 또는 “sysctl -w net.ipv4.ip_forward=1”을 실행하면 된다.

 

 

 

 

NAT를 설정할 때 이 부분을 깜빡 잊고 실행하지 않아 NAT가 작동하지 않는 경우가 가끔 있는데, 아예 부팅 시 자동으로 실행되도록 /etc/sysctl.conf/etc/rc.d/rc.local에 설정해 두는 것이 좋다.

 

 

 

 

왜냐하면 소프트레벨 커널 튜닝의 경우 재부팅 후에는 이 값이 원래의 값(0)으로 초기화되기 때문이다.

 

 

 

 

실제로 필자는 리눅스로 NAT방화벽을 구축하여 어떤 업체의 사내 방화벽으로 납품한 적이 있었는데, 줄곧 잘 사용하다가 어느 날 사무실이 정전되어 방화벽이 재부팅 된 이후부터는 방화벽 때문에 인터넷이 안 된다고 해서 확인해 보니 이 값이 부팅 스크립트에 설정되지 않았기 때문이었다.

 

 

 

 

자주 실수하는 부분이므로 NAT를 구현한다면 아예 부팅 스크립트에 미리 지정해 두기 바란다.

 

 

 

 

 

 

SNAT 타겟

 

 

 

SNAT 타겟은 소스(Source) 주소를 NAT로 변환할 때 사용하는데, 이는 패킷의 IP 헤더에서 소스주소를 변환하는 것을 뜻한다.

 

 

 

 

이를테면 SNAT는 사내의 많은 컴퓨터에서 사설 IP를 이용하면서 인터넷 공유를 이용하여 외부 네트워크인 인터넷 등으로 연결할 때에 인터넷에 연결된 하나 또는 여러 개의 공인 IP로 변환하여 사용하는 것이 그 예이다.

 

 

 

 

이렇듯 SNAT 타겟은 내부의 LAN에서 발송된 패킷이 마치 방화벽에 설정된 특정한 하나의 IP 또는 여러 개의 IP에서 발송된 것처럼 보이는 IP 변환을 담당한다.

 

 

 

 

여기에서, 인터넷을 하려면 왜 굳이 공인 IP로 변환되어야 할까 의구심을 가질 수 있다.

 

 

 

 

그 이유는 사설 IP 자체로는 내부의 네트워크 간 통신은 할 수 있어도 공인 네트워크인 인터넷에는 접근할 수 없기 때문이다.

 

 

 

 

SNATnat 테이블에 있는 POSTROUTING chain에서만 의미가 있다.

 

 

 

 

 

) iptables -t nat -A POSTROUTING -o eth0 -s 192.168.1.2 -j SNAT --to 211.47.64.2

 

 

 

위와 같은 경우 내부 LAN 네트워크에서 소스 주소가 사설 IP192.168.1.2이라면 방화벽의 공인 IP가 설정된 eth0 인터페이스를 통과하면서 SNAT 타겟에 의해 소스 주소가 공인 IP211.47.64.2로 바뀌게 된다.

 

 

 

 

물론 이때 211.47.64.2는 임의의 공인 IP 주소를 지정하는 것이 아니라 반드시 eth0 인터페이스에 설정되어 있거나 eth0:0등과 같이 알리아싱(aliasing) 설정되어 있어야 한다.

 

 

 

 

또한 공인IP를 여러 개 설정하여 패킷의 소스IP뿐만 아니라 목적지IP나 목적지 포트에 따라 변경될 공인IP를 다르게 할 수도 있을 것이다.

 

 

 

 

DNAT 타겟

 

 

 

DNATSNAT과는 반대로 목적지 주소를 NAT 변환할 때 사용하는데, 이는 패킷의 IP 헤더에서 목적지 주소를 변환하는 것을 뜻한다.

 

 

 

 

LAN 구간에서 사설 IP로 서버를 운영할 경우 외부에서 직접 접근이 불가능하므로 이러한 경우에는 DNAT를 이용하여 방화벽에서 특정 공인 IP를 목적지로 하는 패킷을 방화벽 내부의 사설 IP가 설정된 서버로 포워딩 할 때 유용하게 사용될 수 있다.

 

 

 

 

또한 DNAT를 응용하면 다소 초보적인 수준이지만 간단한 로드 발랜싱도 구현할 수 있다.

DNATnat 테이블에 있는 PREROUTING 또는 OUTPUT chain에서 의미가 있다.

 

 

 

) iptables -t nat -A PREROUTING -p tcp -d 211.47.64.2 --dport 80 -j DNAT --to-destination 192.168.1.1-192.168.1.10

 

 

위 예의 경우 목적지 IP211.47.64.2이면서 목적지 포트 80번으로 향하는 tcp 트래픽을 방화벽 내부에 있는 192.168.1.1부터 192.168.1.10까지 10대의 서버에 순서대로 포워딩 하게 된다는 의미이다.

 

 

 

 

물론 이때 iptables는 로드발랜서처럼 10대의 서버가 서비스 중인지 다운되었는지를 모니터링 하는 기능은 없다.

 

 

 

 

MASQUERADE(마스커레이드) 타겟

 

 

 

MASQUERADE 타겟은 SNAT 타겟과 동일하지만 SNATmyip등 고정된 IP가 있을 경우 사용하는데 비해 MASQUERADE는 다이얼업이나 DHCP(adsl)IP가 바뀌는 유동IP 환경에서 사용한다.

 

 

 

 

따라서 SNAT와 달리 --to-source 옵션을 사용하지 않는데, 이는 정확히 고정된 IP를 사용하지 않기 때문이다.

 

 

 

 

따라서 고정된 IP를 사용한다면 SNAT, 유동 IP라면 MASQUERADE를 사용하면 된다.

 

 

 

 

물론 고정IP 환경에서도 SNAT 대신 MASQUERADE를 사용할 수 있지만, 이러한 경우에는 불필요한 오버 헤드를 유발할 수 있으므로 SNAT를 사용하는 것이 좋다.

 

 

 

 

MASQUERADESNAT처럼 nat 테이블에 있는 POSTROUTING chain에서 의미가 있다.

 

 

 

 

 

 

REDIRECT 타겟

 

 

 

REDIRECT 타겟은 특별한 DNAT의 예로서 SNATDNAT와 달리 패킷을 다른 서버의 특정 포트로 포워딩 하지 않고 자기 자신(localhost)의 다른 포트로 포워딩 하고자 할 때 사용한다.

 

 

 

 

이를테면 80번 포트로 향하는 패킷을 투명하게 자기 자신의 8080포트로 포워딩 하는 것 등이 그 예이다.

 

 

 

 

이는 주로 게이트웨이에서 투명한(transparent) 프록시를 사용하여 내부의 사용자들이 프록시의 존재를 알 수 없도록 할 때 유용하게 사용된다.

 

 

 

 

이를테면 내부에서 외부의 웹 접속 시 게임등 유해한 사이트를 차단하고자 할 때 게이트웨이에 Squid 와 같은 프록시 서버를 설정하여 모든 외부 접속 시 프록시를 강제로 경유하도록 할 수 있는데,(Squid8080에서 리슨하고 있다고 가정) 목적지가 80으로 향하는 모든 패킷을 REDIRECT를 이용하여 로컬의 8080으로 포워딩 하도록 함으로써 반드시 Squid를 거치도록 하는 것이다.

 

 

 

 

물론 접속 요청을 받은 Squid는 내부의 설정에 따라 허용된 접속의 경우 외부로 포워딩 할 것이다.

 

 

 

 

 

 

REDIRECTnat 테이블의 PREROUTING이나 OUTPUT chain에서 의미가 있다.

 

)iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080

 

 

 

위와 같은 경우 tcp 80번 포트로 향하는 패킷을 투명하게 8080번 포트로 포워딩 하도록 설정한다.

 

 

 

 

따라서 내부에서 외부의 80번 포트로 나가는 모든 접속은 Squid 프록시를 경유하여 나가게 된다.

 

????[유용한 팁]

 

 

이 방법을 활용한다면 다양한 응용이 가능한데, 이를테면 사내방화벽의 용도로 사용할 경우 사내에서 직원들이 어떤 사이트를 접속하는지에 대한 통계나 자세한 내용을 모니터링 할 수도 있다.

 

 

 

 

, 위와 같이 iptables를 이용하여 80번으로 나가는 패킷을 투명하게 8080번으로 REDIRECT 하도록 설정하고, squid(http://www.squid-cache.org/)8080번에서 리슨하도록 설정한 후 squid.conf에서 로그파일을 생성하도록 설정하면 로그 파일에 사용자들이 접속한 url이 로그 파일에 남게 된다.

 

 

 

 

이후에는 생성되는 로그 파일을 분석하여야 하는데, 이러한 프로그램으로는 아래의 URL을 참고하면 된다.

 

 

 

 

아래의 프로그램은 웹로그 분석 프로그램처럼 일정시간마다 로그를 분석해서 결과를 보여주도록 cron등에 설정하면 된다.

 

 

 

 

 

 

yalsp : http://www.andreamarangoni.it/yalsp/index.htm

 

리포트 예)

ce66ec756e45f2946147457ac3966ce9_1680068789_4229.png
 

[그림] 클라이언트별 통계

 

ce66ec756e45f2946147457ac3966ce9_1680068824_8893.png
 

[그림] 접속한 사이트 통계

 

프로그램은 그리 복잡하지 않으므로 조금만 수정한다면 다양한 기능을 추가할 수 있을 것이다.

 

 

 

관련자료

댓글 0
등록된 댓글이 없습니다.

공지사항


뉴스광장


  • 현재 회원수 :  60,039 명
  • 현재 강좌수 :  35,848 개
  • 현재 접속자 :  77 명