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

ICMP 트래픽 허용을 위한 iptables 룰 설정

작성자 정보

  • 관리자 작성
  • 작성일

컨텐츠 정보

본문

ICMP 트래픽 허용을 위한 iptables 룰 설정

 





ICMP(Internet Control Message Protocol) 패킷에 대한 허용여부를 iptables룰로 설정할 차례이다.

 

 

 

 

앞에서 언급한 것처럼 icmptcpudp와는 달리 포트(port)를 사용하지 않고 icmp-typecode를 사용하는데, 모든 icmp를 차단하고 허용해 주어야 할 특정한 타입만을 허용해주면 된다.



 

icmp의 타입과 코드에 대해서는 http://www.iana.org/assignments/icmp-parameters를 참고하기 바란다.

 

 

 

 

상태추적의 관점에서 ICMP 메시지 중 아래 4가지 icmp 타입의 경우, NEW 에 대한 응답은 ESTABLISHED이며 이외의 것은 모두 NEW에 대한 응답은 RELATED가 된다.

 

 

 

 

그러나 통상적으로 icmp는 상태추적을 사용하지 않아도 된다.

 

- Echo request (ping, 8) , echo reply (pong, 0).


- Timestamp request (13) reply (14).


- Information request (15) reply (16).


- Address mask request (17) reply (18).



 

icmp flooding등 기존의 프로토콜을 악용하는 사례가 있어 일부에서 icmp는 불필요한 프로토콜이라 판단하고 모두 차단해 버리는 경우가 있는데, 반드시 그렇지는 않으며 특정한 상황에서는 일부 서비스에 문제가 발생할 수도 있다.

 

 

 

 

따라서 일부 서비스에 대해서는 허용해 주는 것이 좋다.

 

 

 

 

 

외부로의 ping 허용

 

방화벽에서 외부 호스트로의 ping을 허용하기 위해 먼저 OUTPUT 트래픽에서 ping 요청에

해당하는 icmp-typeecho-request를 허용하였다.

 

 

 

 

그리고 이에 대한 응답도 허용하여야 하므로 이번에는 INPUT 트래픽에서 icmp-typeecho-replyICMP 트래픽을 허용하였다.

 

$IPTABLES -A OUTPUT -p ICMP --icmp-type echo-request -m state --state NEW -j ACCEPT

$IPTABLES -A INPUT -p ICMP --icmp-type echo-reply -m state --state ESTABLISHED -j ACCEPT

 




source-quench 허용

 

source-quench는 중간에 있는 라우터의 버퍼가 꽉 차서 더 이상 자료를 받을 수 없을 때 자료를 보내는 소스 호스트에게 보내는 메시지인데, 인터넷에서는 자주 사용되지는 않지만 필요하므로 허용한다.

 

 

 

 

앞에서 언급한 것처럼 source-quenchNEW에 대한 응답으로 ESTABLISHED 대신 RELATED가 된다.

 

$IPTABLES -A INPUT -p ICMP --icmp-type source-quench -m state --state NEW -j ACCEPT

$IPTABLES -A OUTPUT -p ICMP --icmp-type source-quench -m state --state RELATED -j ACEPT

 




 

destination-unreachable 허용

 

destination-unreachable은 네트워크 경로를 추적할 때 사용하는 traceroute를 허용하고자 할 때 필요하다.

 

 

 

 

방화벽 내부에서 다른 네트워크로 traceroute를 할 때는 icmp destination-unreachable 메시지를 받게 되므로 INPUT chain에서 허용해 주면 내부에서 외부로 traceroute를 할 수 있고, OUTPUT chain에서 허용해 주면 외부에서 내부로의 traceroute를 허용하게 된다.

 

 

 

 

 

$IPTABLES -A INPUT -p ICMP --icmp-type destination-unreachable -j ACCEPT

$IPTABLES -A OUTPUT -p ICMP --icmp-type destination-unreachable -j ACCEPT

 

traceroute를 할 경우 목적지 서버의 udp 33434번부터 38000번까지의 포트에 접속 시도를 하므로 외부에서 서버로의 traceroute를 허용하려면 다음과 같이 이 포트로의 udp 접속도 허용하여야 한다.

 

 

 

 

 

$IPTABLES -A INPUT -m state --state NEW -p udp --dport 33434:38000 -j ACCEPT

 




fragmentation-needed 허용

 

양 단간의 네트워크 사이에서 데이터 통신을 할 때 패킷이 너무 커서 하나의 단일한 단위로 이더넷(ethernet)등을 통과할 수 없을 경우, 즉 패킷의 사이즈가 중간 경유 라우터의 MTU 값보다 큰 경우 라우터에서는 패킷을 Fragmentation(단편화 또는 조각화)하여 몇 개의 부분으로 나누어 수신자에게 패킷을 전달하게 되고, 수신자는 이 조각을 모두 수신한 후 재조립하게 된다.

 

 

 

 

그러나 패킷을 발송할 때 패킷 헤더에 DF(Don't Fragment) 비트가 설정되어 있을 경우 설사 라우터의 MTU 값이 작아서 단편화를 하여야 할지라도 단편화 하지 말라는 설정이다.

 

 

 

 

이 패킷을 받은 라우터에서는 이 패킷을 drop하고 'can't fragment'라는 ICMP 에러 메시지를 발송자에게 전송한다.

 

 

 

 

그런데, 만약 송신자 쪽에서 라우터나 방화벽에서 inbound되는 이 ICMP 패킷을 필터링한다면 이러한 경우 송신자 쪽에서 DF 비트를 설정한 채 MTU 값을 초과하는 패킷을 발송하더라도 수신자 쪽의 라우터에서 패킷이 너무 커서 전송할 수 없다는 'Can't Fragment' ICMP 에러 메시지를 받을 수 없게 되어 계속적으로 큰 사이즈의 패킷을 보내게 되고 수신자는 계속 필터링하게 되어 네트워크의 성능이 크게 떨어지게 된다.

 

 

 

 

따라서 MTU보다 작은 데이터는 통과하게 되고 큰 데이터는 drop되어 전달되지 않는 현상이 발생하게 되므로 이 icmp-type을 허용하여야 한다.

 

$IPTABLES -A INPUT -p ICMP --icmp-type fragmentation-needed -j ACCEPT

$IPTABLES -A OUTPUT -p ICMP --icmp-type fragmentation-needed -j ACCEPT







cd748e8935a013f3cf536af9b9b6806b_1683596802_6766.png
 

[그림] 중간의 라우터에서 단편화가 발생한다.

 

 

 

 

 

 

time-exceeded 허용

 

time-exceeded는 내부에서 다른 네트워크로 traceroute를 할 때 최대 홉 숫자(TTL-, 통과하는 라우터 개수)가 초과되었을 경우 중간 라우터에서 발송하는 icmp 에러 메시지로서 라우터가 아닐 경우에는 나가는 패킷을 허용해 줄 필요가 없으며 라우터에서 발송되는 icmp 메시지를 받기만 하면 되므로 들어오는 패킷을 허용해주면 된다.

 

 

 

 

 

$IPTABLES -A INPUT -p ICMP --icmp-type time-exceeded -j ACCEPT

 

parameter-problem 허용

 

parameter-problem은 수신한 패킷 헤더에 비정상적이거나 예상치 못한 데이터가 있을 경우 송신자에게 전송하는 icmp 에러메시지로서 이 패킷도 허용하여야 한다.

 

 

 

 

INPUT, OUTPUT 모두 허용하도록 한다.

 

$IPTABLES -A INPUT -p ICMP --icmp-type parameter-problem -j ACCEPT

$IPTABLES -A OUTPUT -p ICMP --icmp-type parameter-problem -j ACCEPT

 

이렇게 해서 서버에 직접 설치하는 독립실행형(standalone) 방화벽의 룰 설정을 끝냈다.

 

 

 

 

위와 같이 각자의 특성에 맞게 룰 스크립트를 /etc/rc.d/rc.firewall.sh와 같은 파일에 설정한 후에는 실행할 수 있는 퍼미션을 설정한 후 매번 부팅할 때마다 스크립트가 자동 실행될 수 있도록 /etc/rc.d/rc.local 파일에 “sh /etc/rc.d/rc.firewall.sh”를 추가하면 된다.

 

 

 

 

 

 

???? [필자경험담]

방화벽을 설치할 때에는 특정한 IP에서만 접근할 수 있도록 설정할 경우 보안을 극대화할 수 있다.

 

 

 

 

그러나 사무실 등에서 ADSL과 같은 유동 IP를 사용하는 환경일 때에는 어떻게 하여야 할까? 이러한 경우 네 가지 해결방안이 있을 수 있다.

 

첫 번째는 http://www.no-ip.com/이나 http://www.dydns.com/과 같은 dynamic dns를 이용하는 방법으로 별로 권장하지는 않지만 -s IP 주소대신 office.no-ip.com과 같은 호스트명을 사용하면 된다.

 

 

 

 

, ssh 접속을 허용하려면

 

$IPTABLES -A INPUT -p -tcp -s office.no-ip.com --sport 1024: --dport 22 -m state --state NEW -j ACCEPT

 

와 같이 하면 될 것이다.

 

 

 

 

 

 

두 번째는 별도의 포워딩(경유) 서버를 이용하는 방법으로 방화벽에서는 해당 포워딩 서버에서의 접근만 허용하도록 설정한 후 포워딩 서버에서는 아래와 같이 xinetdredirect를 이용하면 된다.

 

 

 

 

xinetd.conf에 아래와 같이 설정한 후 xinetd를 재가동하면 포워딩 서버에는 777/tcp가 리슨하고 있는 것을 확인할 수 있을 것이다.

 

 

 

 

따라서 사무실에서는 이 포워딩 서버의 777번으로 접속하면 211.47.64.322ssh에 접속할 수 있을 것이다.

 

 

 

 

결국 특정한 서버의 특정한 포트를 알아야만 해당 서비스에 접속할 수 있게 되는 것이므로 완전히 22번 포트를 열어두는 것에 비해서 보안을 강화할 수 있게 된다.

 

 

 

 

만약 포워딩이 작동하지 않으면 특정 버전에서는 잘 작동하지 않으므로 xinetd 실행 파일의 버전을 바꾸어서 실행해 보기 바란다.

service 777

{

flags = REUSE

socket_type = stream

protocol = tcp

wait = no

user = root

port = 777

groups = yes

redirect = 211.47.64.3 22

}

 

이렇게 sshtelnet, http, pop3, terminal service(3389/tcp), ms-sql(1433/tcp)등 단일한 포트를 사용하는 서비스는 xinetdredirect를 이용하면 훌륭한 포워딩 기능을 이용할 수 있게 될 것이다.

 

 

 

 

그런데, 2개의 포트를 사용하는 ftp는 어떻게 하여야 할까? 물론 ftp 대신 ssh의 파일 전송 기능을 사용하라고 해도 되겠지만 반드시 ftp를 사용하여야 하는 경우가 있을 수 있을 것이다.

 

 

 

 

ftp는 특별한 프로토콜이기 때문에 ftp 프로토콜을 포워딩하려면 ftp를 이해할 수 있는 별도의 프로그램이 있어야 하는데 권장하는 프로그램으로는 ftpproxyredir이라는 것이 있다.

먼저 ftpproxy는 홈페이지(http://www.ftpproxy.org/)에서 소스를 다운로드하여 설치하면 되고, 이후 xinetd.conf에 아래와 같이 설정하면 된다.

 

 

 

 

이렇게 되면 서버의 ip2111/tcpftp 접속하면 192.168.68.1762121번으로 접속하게 되는 것이다.

 

 

 

 

만약 기본 포트인 21번을 사용하면 :21 부분은 빼도 된다.

 

 

 

 

 

 

service 2111

{

type = UNLISTED

flags = REUSE

socket_type = stream

protocol = tcp

port = 2111

wait = no

user = nobody

groups = yes

server = /usr/local/sbin/ftp.proxy

server_args = 192.168.68.176:2121

}

 

다음으로는 redir(http://sammy.net/~sammy/hacks/redir-2.2.1.tar.gz)을 살펴보자.

redir을 실행하면 사용할 수 있는 옵션이 많이 있는데, 일반적으로 아래와 같은 방법으로 많이 사용한다.

 

 

 

 

 

 

redir --lport=648 --cport=21 --ftp=both --caddr=211.47.64.3

 

위의 설정은 포워딩 서버의 648/tcp번을 리슨하면서 이 포트로 들어오는 접속을 211.47.64.321번으로 포워딩한다는 뜻이며 이때 active/passive 모두 지원한다는 의미이다.

포워딩 서버를 이용할 때의 방화벽 룰은 아래와 같을 것이다.

 

$IPTABLES -A INPUT -p -tcp -s 211.47.64.100 --sport 1024: -d 211.47.64.3 --dport 21 -m state --state NEW -j ACCEPT

 

위에서 211.47.64.100은 포워딩서버를 의미한다.

세 번째는 port knocking이라는 방식으로 iptablesrecent 모듈을 이용하여 클라이언트가 특정 행위를 하여야 dynamic하게 특정 포트가 오픈되는 것인데 자세한 내용은 뒤에서 살펴보도록 하겠다.

 

 

 

 

 

네 번째는 VPN을 이용하는 방법인데 이에 대해서는 9장에서 살펴보도록 하겠다.

 

 

관련자료

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

공지사항


뉴스광장


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