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

iptables를 이용한 standalone 방화벽서버구축 룰

작성자 정보

  • 관리자 작성
  • 작성일

컨텐츠 정보

본문

iptables를 이용한 standalone 방화벽서버구축 룰

 

 

 

 

실제 서비스 중인 서버에 iptables 설정을 통해 방화벽을 탑재해 보자. 웹 서버든 메일 서버든 아니면 여러 서비스를 함께 제공하는 서버든 관계없이 이용 가능하므로 각자의 상황에 맞게 적당히 수정해서 사용하기 바란다.

 

 

 

 

지금까지 살펴본 룰을 정리하는 의미에서 한번 살펴보는 것도 좋을 것이다.

 

 

 

 

참고로 필자의 경우 필자가 관리하는 거의 모든 리눅스 서버에 아래와 같은 룰을 이용하여 패킷을 차단하고 있는데, 접속이 많은 서버에도 속도저하도 없고 안정적으로 운영되고 있다.

 

 

 

 

 

 

#!/bin/sh

 

#iptables 실행 파일의 경로를 정의한다.

 

 

 

 

 

IPTABLES="/usr/local/sbin/iptables"

 

# 기존에 설정되어 있는 룰을 모두 초기화한다.

$IPTABLES -F

 

# standalone 형태이므로 INPUT 은 기본적으로 DROP한다.

# FORWARD는 사용할 필요가 없으므로 역시 기본 정책으로 DROP한다.

# 하지만 룰을 단순화하기 위해 OUTPUTACCEPT한다.

 

 

 

 

어쨌든 INPUT에서는

# 기본적으로 DROP 하였으므로 OUTPUT에서 허용을 해도 관계없다.

 

 

 

 

 

 

$IPTABLES -P INPUT DROP

$IPTABLES -P FORWARD DROP

$IPTABLES -P OUTPUT ACCEPT

 

# 내부 트래픽인 루프백 트래픽은 허용한다.

 

 

 

 

 

$IPTABLES -A INPUT -i lo -j ACCEPT

$IPTABLES -A OUTPUT -o lo -j ACCEPT

 

# INPUT chain에서 필터링 설정한다.

# RFC 1918에 정의된 사설IP 및 공인 네트워크에서 라우팅 될 수 없는 IP 대역을 소스로

# 한 패킷이 서버를 향하는 패킷을 차단한다.

 

 

 

 

라우터가 있다면 라우터에서 차단하는 것도

# 좋은 방법이며 인터페이스로 eth0만 사용한다면 아래와 같이 인터페이스는 지정하지 않아도

# 된다.

 

 

 

 

 

 

$IPTABLES -A INPUT -i eth0 -s 10.0.0.0/8 -j DROP

$IPTABLES -A INPUT -i eth0 -s 255.255.255.255/32 -j DROP

$IPTABLES -A INPUT -i eth0 -s 0.0.0.0/8 -j DROP

$IPTABLES -A INPUT -i eth0 -s 169.254.0.0/16 -j DROP

$IPTABLES -A INPUT -i eth0 -s 172.16.0.0/12 -j DROP

$IPTABLES -A INPUT -i eth0 -s 192.0.2.0/24 -j DROP

$IPTABLES -A INPUT -i eth0 -s 192.168.0.0/16 -j DROP

$IPTABLES -A INPUT -i eth0 -s 224.0.0.0/4 -j DROP

$IPTABLES -A INPUT -i eth0 -s 240.0.0.0/5 -j DROP

$IPTABLES -A INPUT -i eth0 -s 248.0.0.0/5 -j DROP

 

# OUTPUT chain에서 필터링 설정한다.

# RFC 1918에 정의된 사설IP 및 공인 네트워크에서 라우팅 될 수 없는 IP 대역을 목적지로 한

# 패킷이 서버에서 외부 네트워크로 나가는 것을 차단한다.

 

 

 

 

FORWARD는 어떠한 트래픽도

# 허용하지 않았으므로 별도로 지정할 필요가 없다.

 

$IPTABLES -A OUTPUT -d 10.0.0.0/8 -j DROP

$IPTABLES -A OUTPUT -d 255.255.255.255/32 -j DROP

$IPTABLES -A OUTPUT -d 0.0.0.0/8 -j DROP

$IPTABLES -A OUTPUT -d 169.254.0.0/16 -j DROP

$IPTABLES -A OUTPUT -d 172.16.0.0/12 -j DROP

$IPTABLES -A OUTPUT -d 192.0.2.0/24 -j DROP

$IPTABLES -A OUTPUT -d 192.168.0.0/16 -j DROP

$IPTABLES -A OUTPUT -d 224.0.0.0/4 -j DROP

$IPTABLES -A OUTPUT -d 240.0.0.0/5 -j DROP

$IPTABLES -A OUTPUT -d 248.0.0.0/5 -j DROP

 

# 이미 세션을 맺어 상태추적 테이블 목록에 있는 ESTABLISHED,RELATED 패킷은 허용한다.

# 이 룰을 앞쪽에 설정하면 할수록 이미 허용된 트래픽에 대해 불필요하게 각 패킷마다 일일이

# 룰을 매칭하지 않으므로 방화벽의 성능을 높일 수 있다.

 

 

 

 

 

 

$IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

$IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

 

# 서버를 향해 들어오는 패킷 중 포트 스캔이라 의심되는 패킷이 있을 경우 해당 정보를

# 1분에 1개꼴로 로그에 남기도록 한다.

 

 

 

 

psd 사용 시 정상접속도 필터링 되어 느릴 수 있다.

 

$IPTABLES -A INPUT -m psd -m limit --limit 1/minute -j LOG

 

# 로그에 남긴 이후에는 포트 스캔 패킷을 차단한다.

 

$IPTABLES -A INPUT -m psd -j DROP

 

# 방화벽을 향해 들어오는 tcp 패킷 중 상태추적 테이블에는 NEW이면서 syn 비트를 달지

# 않고 들어오는 패킷은 차단한다.

 

 

 

 

tcp 패킷 중 상태추적 테이블에 NEW라면 반드시 syn 비트가

# 설정된 패킷이어야 할 것이며 이외의 패킷은 모두 위조된 패킷이므로 차단한다.

 

 

 

 

 

 

$IPTABLES -A INPUT -i eth0 -p TCP ! --syn -m state --state NEW -j DROP

 

# 상태추적 테이블에서 INVALID인 패킷은 차단한다.

# -p ALL로 설정하면 tcp, udp, icmp 등 모든 프로토콜에 해당한다.

 

 

 

 

 

 

$IPTABLES -A INPUT -i eth0 -p ALL -m state --state INVALID -j DROP

 

# 이번에는 tcp-flag에 대한 설정으로 포트스캔 등에 민감하지 않다면 설정하지 않아도 된다.

 

 

 

 

# NMAP등을 이용한 FIN/URG/PSH 스캔을 차단하기 위해 모든 비트를 살펴보아

# FIN,URG,PSH가 설정된 패킷은 1분에 5개 비율로 로그에 남긴 후 차단하도록 한다.

# 로그를 남길 때는 로그 정보의 앞에 "NMAP-XMAS:"가 추가되도록 한다.

 

 

 

 

 

 

$IPTABLES -A INPUT -p tcp --tcp-flags ALL FIN,URG,PSH -m limit --limit 5/minute -j LOG --log-prefix "NMAP-XMAS:"

$IPTABLES -A INPUT -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP

 

# tcp 패킷 중 SYNFIN 비트를 살펴보아 SYNFIN비트가 함께 설정된 패킷은

# 비정상이므로 차단한다.

 

 

 

 

 

 

$IPTABLES -A INPUT -p TCP --tcp-flags SYN,FIN SYN,FIN -j DROP

 

# tcp 패킷 중 SYNRST 비트를 살펴보아 SYNRST비트가 함께 설정된 패킷은

# 차단한다.

 

 

 

 

 

$IPTABLES -A INPUT -p TCP --tcp-flags SYN,RST SYN,RST -j DROP

 

# tcp 패킷 중 FINRST 비트를 살펴보아 FINRST비트가 함께 설정된 패킷은 차단한다.

 

$IPTABLES -A INPUT -p TCP --tcp-flags FIN,RST FIN,RST -j DROP

 

# tcp 패킷 중 ACKFIN 비트를 살펴보아 ACK는 설정되지 않고 FIN 비트만 설정된

# 패킷은 차단한다.

 

 

 

 

 

 

$IPTABLES -A INPUT -p TCP --tcp-flags ACK,FIN FIN -j DROP

 

# tcp 패킷 중 ACKPSH 비트를 살펴보아 ACK는 설정되지 않고 PSH 비트만 설정된

# 패킷은 차단한다.

 

 

 

 

 

 

$IPTABLES -A INPUT -p TCP --tcp-flags ACK,PSH PSH -j DROP

 

# tcp 패킷 중 ACKURG 비트를 살펴보아 ACK는 설정되지 않고 URG 비트만 설정된

# 패킷은 차단한다.

 

 

 

 

 

 

$IPTABLES -A INPUT -p TCP --tcp-flags ACK,URG URG -j DROP

 

# tcp패킷 중 모든 비트를 살펴보아 다른 비트는 설정되지 않고 FIN 비트만 설정된

# 패킷은 차단한다.

 

 

 

 

 

 

$IPTABLES -A INPUT -p TCP --tcp-flags ALL FIN -j DROP

 

# tcp 패킷 중 모든 비트를 살펴보아 아무런 비트도 설정되지 않은 패킷은 차단한다.

 

 

 

 

 

 

$IPTABLES -A INPUT -p TCP --tcp-flags ALL NONE -j DROP

 

# tcp 패킷 중 모든 비트를 살펴보아 다른 비트는 설정되지 않고 PSHFIN 비트만 설정

# 된 패킷은 차단한다.

 

 

 

 

 

 

$IPTABLES -A INPUT -p TCP --tcp-flags ALL PSH,FIN -j DROP

 

# 웹 서비스를 제공하기 위해 80번으로 향하는 초기(NEW) 패킷은 허용한다.

# 이후 OUTPUT은 모두 허용하였고, 응답 패킷 등은 앞에서 ESTABLISHED로 허용하였으므로

# 이 한 줄만으로도 웹 서비스가 허용된다.

 

$IPTABLES -A INPUT -i eth0 -p TCP --sport 1024: --dport 80 -m state --state NEW -j ACCEPT

 

# 특정한 IP 대역에서만 ftp 서비스를 허용하기 위해 211.47.64.0/24 대역에서 21번으로

# 향하는 초기(NEW) 패킷은 허용한다.

 

 

 

 

이후 응답 패킷 등은 앞에서 ESTABLISHED

# RELATED로 허용하였으므로 이 한 줄만으로도 active/ passive 관계없이 FTP 서비스가

# 허용된다.

 

 

 

 

소스포트에서 1024:1024:65535는 동일한 의미이다.

 

 

 

 

 

 

$IPTABLES -A INPUT -i eth0 -p TCP -s 211.47.64.0/24 --sport 1024: --dport 21 -m state --state NEW -j ACCEPT

 

# SSH 서비스를 허용하기 위해 211.47.64.0/24 대역에서 22번으로 향하는 초기(NEW) 패킷을

# 허용한다.

 

 

 

 

이후 응답 패킷 등은 앞에서 ESTABLISHED로 허용하였으므로 이 한 줄만으로

# SSH 서비스가 허용된다.

 

$IPTABLES -A INPUT -i eth0 -p TCP -s 211.47.64.0/24 --sport 1024: --dport 22 -m state --state NEW -j ACCEPT

 

# SMTP 서비스를 허용하기 위해 25번으로 향하는 초기(NEW) 패킷은 허용한다.

# 이후 응답 패킷 등은 앞에서 ESTABLISHED로 허용하였으므로 이 한 줄만으로도

# SMTP 서비스가 허용된다.

 

 

 

 

SMTP 서비스를 제공한다면 외부에서 들어오는 메일을 서버에서

# 받아야 하므로 25번은 열려 있어야 한다.

 

 

 

 

 

 

$IPTABLES -A INPUT -i eth0 -p TCP --sport 1024: --dport 25 -m state --state NEW -j ACCEPT

 

# POP3 서비스를 허용하기 위해 211.47.64.0/24 대역에서 110번으로 향하는 초기(NEW)

# 패킷은 허용한다.

 

 

 

 

이후 응답 패킷 등은 앞에서 ESTABLISHED로 허용하였으므로 이 한

# 줄만으로도 POP3 서버에 접속하여 메일을 받아올 수 있도록 서비스가 허용된다.

 

 

 

 

물론

# 지정한 대역에서만 접근 가능하며 다른 대역에서는 접근이 불가능하다.

 

$IPTABLES -A INPUT -i eth0 -p TCP -s 211.47.64.0/24 --sport 1024: --dport 110 -m state --state NEW -j ACCEPT

 

# 서버에 snmpd를 설치하여 mrtg등으로 트래픽을 모니터링 할 경우 mrtg가 설치된

# 서버에서의 161/udp 트래픽을 허용하여야 한다.

 

 

 

 

 

 

$IPTABLES -A INPUT -i eth0 -p UDP -s 211.47.64.5 --sport 1024: --dport 161 -m state --state NEW -j ACCEPT

 

# 외부에서 서버로 traceroute를 허용하도록 한다.

 

 

 

 

 

 

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

 

# icmp 패킷 중 ping 요청에 대한 응답 즉, echo-reply를 허용한다.

 

 

 

 

 

 

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

 

# icmp 패킷 중 network-unreachable을 허용한다.

 

 

 

 

서비스거부로 악용될 수 있으므로

# limit를 지정하여 초당 1회씩만 허용한다.

 

 

 

 

 

 

$IPTABLES -A INPUT -p ICMP --icmp-type network-unreachable -m limit --limit 1/s --limit-burst 5 -j ACCEPT

 

# icmp 패킷 중 host-unreachable을 허용한다.

 

 

 

 

서비스거부로 악용될 수 있으므로

# limit를 지정하여 초당 1회씩만 허용한다.

 

 

 

 

 

 

$IPTABLES -A INPUT -p ICMP --icmp-type host-unreachable -m limit --limit 1/s --limit-burst 5 -j ACCEPT

 

# icmp 패킷 중 port-unreachable을 허용한다.

 

 

 

 

서비스거부로 악용될 수 있으므로

# limit를 지정하여 초당 1회씩만 허용한다.

 

 

 

 

 

 

$IPTABLES -A INPUT -p ICMP --icmp-type port-unreachable -m limit --limit 1/s --limit-burst 5 -j ACCEPT

 

# icmp 패킷 중 fragmentation-needed을 허용한다.

 

 

 

 

서비스거부로 악용될 수 있으므로

# limit를 지정하여 초당 1회씩만 허용한다.

 

$IPTABLES -A INPUT -p ICMP --icmp-type fragmentation-needed -m limit --limit 1/s --limit-burst 5 -j ACCEPT

 

# icmp 패킷 중 time-exceeded를 허용한다.

 

 

 

 

서비스거부로 악용될 수 있으므로

# limit를 지정하여 초당 1회씩만 허용한다.

 

$IPTABLES -A INPUT -p ICMP --icmp-type time-exceeded -m limit --limit 1/s --limit-burst 5 -j ACCEPT

 

# tcp 패킷 중 identd (113/tcp)서비스를 향하는 패킷은 거부하되, DROP 하지 말고

# RST 비트를 설정하여 REJECT로 응답하도록 한다.

 

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

 

 

만약 위의 룰을 스크립트로 실행하는 것이 아니라 원격에서 한 줄씩 천천히 copy & paste로 실행한다면 중간에 네트워크가 끊기게 될 것이다.

 

 

 

 

왜냐하면 룰의 시작부터 $IPTABLES -P INPUT DROP 과 같이 차단하도록 설정하였기 때문이다.

 

 

 

 

따라서 네트워크가 끊어지지 않기 위해서는 허용된 트래픽 외에 모두 차단하는 기본정책(default policy)은 제일 뒤에 선언하는 것이 맞을 것이다.

 

 

 

 

그러나 이 룰을 실행 시 네트워크가 끊어지지 않는 것은 실행 후 즉시 특정 접속을 허용하는 룰이 실행되기 때문이다.

 

 

 

 

, 룰이 실행 시에는 즉시 적용되는 것이 아니라 일정시간(2-3초정도) 텀이 있다고 생각하면 된다.

 

 

 

 

 

 

만약 다른 서비스와 마찬가지로 방화벽의 시작/멈춤을 편하게 하려면 스크립트의 앞에 아래와 같이 추가하면 된다.

 

 

 

 

 

#!/bin/sh

IPTABLES="/usr/local/sbin/iptables"

 

. /etc/rc.d/init.d/functions

 

case "$1" in

"start" )

echo ""

action "Starting Firewall....:" echo

echo ""

;;

 

"stop" )

echo ""

action "Stopping Firewall....:" echo

echo ""

$IPTABLES -F

$IPTABLES -X

$IPTABLES -P INPUT ACCEPT

$IPTABLES -P FORWARD ACCEPT

$IPTABLES -P OUTPUT ACCEPT

exit

;;

* )

 

$ECHO "You can use following command line args:"

$ECHO

$ECHO " start .............. Bring up the firewall."

$ECHO " stop .............. Disable the firewall."

$ECHO

$ECHO

 

exit;;

esac

 

iptables 룰에 대한 더 많은 예제는 http://www.linuxguruz.com/iptables/을 참고하기 바란다.

 

 

 

 

이 사이트에는 많은 스크립트 예제가 있으므로 여러 스크립트를 반복하여 살펴보고

익숙하게 만들기 바란다.

 

 

 

 

 

cd748e8935a013f3cf536af9b9b6806b_1683618510_4296.png
 

[그림] linuxguruz 홈페이지



 

 

위와 같은 룰 대신 아래와 같은 간단한 스크립트를 이용할 수도 있다.

 

 

 

 

아래의 룰은 25/80에 대해서는 모든 IP에 대해 오픈하고, 22110에 대해서는 특정 IP에 대해서만 오픈한 것을 알 수 있다.

 

 

 

 

제일 마지막의 “iptables -A INPUT -j DROP” 부분은 제일 마지막에 선언되었으므로 "iptables -P INPUT DROP"로 해도 동일한 의미가 된다.

 

 

 

 

 

 

#!/bin/sh

 

iptables -P INPUT ACCEPT

iptables -P OUTPUT ACCEPT

iptables -F

iptables -A INPUT -p tcp -m mport --dports 25,80 -j ACCEPT

iptables -A INPUT -p tcp -s 192.168.1.0/24 -m mport --dports 22,110 -j ACCEPT

iptables -A INPUT -j DROP

 

 

 

관련자료

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

공지사항


뉴스광장


  • 현재 회원수 :  60,043 명
  • 현재 강좌수 :  35,853 개
  • 현재 접속자 :  76 명