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

NAT 방화벽 룰 예제

작성자 정보

  • 관리자 작성
  • 작성일

컨텐츠 정보

본문

NAT 방화벽 룰 예제






 

아래는 NAT 방화벽에 설정하여 사용할 수 있는 실제 룰 예제이다.

 

 

 

 

룰을 볼 때는 먼저 각 룰의 개개 의미를 살펴보고, 전체적인 흐름에서 다시 한 번 살펴보아야 한다.

 

 

 

 

그리고 눈으로만 보지 말고 직접 적용해서 실행해 보기 바란다.

 

 

 

 

이 예에서는 eth0에 공인 IP211.47.64.2가 할당되어 있고, 내부의 사설 대역에는 192.168.1.0/24 대역을 사용하며 게이트웨이는 eth1IP 주소를 사용한다고 가정한다.

 

 

 

 

 

#!/bin/sh

 

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

 

 

 

 

 

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

 

SERVICE_IP="211.47.64.2"

# 방화벽에서 사용할 공인 IP211.47.64.2로 지정한다.

# IP 대신 각자 자신의 공인 IP를 설정하기 바란다.

 

/bin/echo "1" >/proc/sys/net/ipv4/ip_forward

# NAT를 사용하므로 반드시 ip_forwardon으로 작동하여야 한다.

# 여기에서 1on을 의미한다.

 

 

 

 

 

 

# filter 테이블의 기본정책을 설정한다.

# 여기에서 INPUTFORWARD는 기본정책으로 DROP하고

# OUTPUTACCEPT로 하는 것이 좋다.

 

 

 

 

 

$IPTABLES -P INPUT DROP

$IPTABLES -P FORWARD DROP

$IPTABLES -P OUTPUT ACCEPT

 

# 각 테이블에서 기존에 설정되어 있는 룰을 모두 초기화(flush)한다.

$IPTABLES -t nat -F

$IPTABLES -t mangle -F

$IPTABLES -t filter -F

 

# 방화벽 자체의 루프백 트래픽은 허용한다.

 

 

 

 

 

$IPTABLES -A INPUT -i lo -j ACCEPT

$IPTABLES -A OUTPUT -o lo -j ACCEPT

 

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

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

# IP 대역을 소스로 한 패킷이 방화벽을 향하는 패킷을 차단한다.

$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

 

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

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

# IP 대역을 소스로 한 패킷이 방화벽 내부의 네트워크로 포워딩 되는 것을 차단한다.

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

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

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

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

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

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

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

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

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

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

 

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

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

# IP 대역을 목적지로 한 패킷이 방화벽에서 외부 네트워크로 나가는 것을 차단한다.

$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

 

# 내부의 사설 대역인 192.168,1.0/24 대역에서 사설 인터페이스인 eth1 인터페이스를

# 통해 들어오는 패킷은 내부 네트워크에서의 정상 트래픽이므로 허용한다.

$IPTABLES -A FORWARD -i eth1 -s 192.168.1.0/24 -j ACCEPT

 

# 내부에서 192.168.1.0/24 대역을 사용할 경우 eth1을 경유하여 eth0으로

# 나갈 때 SERVICE_IP에서 지정한 공인IP로 변환되어 나가도록 한다.

 

 

 

 

 

$IPTABLES -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j SNAT --to $SERVICE_IP

 

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

# 한다.

 

 

 

 

이 룰을 앞쪽에 설정할수록 방화벽의 성능을 높일 수 있다.

 

 

 

 

그리고 OUTPUT

# 기본적으로 허용이므로 없어도 관계없다.

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

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

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

 

# 포트 스캔에 대비하기 위해 직접 방화벽을 향해 들어오는 패킷 중 포트 스캔이 감지되었을

# 경우 1분에 3개꼴로 로그에 관련 정보를 남기도록 한다.

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

 

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

 

 

 

 

 

$IPTABLES -A INPUT -m psd -j DROP

 

# 포트 스캔에 대비하기 위해 방화벽 내부의 서버를 향해 들어오는 패킷 중 포트 스캔이

# 감지되었을 경우 1분에 3개꼴로 로그에 관련 정보를 남기도록 한다.

# ftp등 이용 시에는 파일 전송이 잘 되지 않을 수도 있으니 적용시 주의하기 바란다.

 

 

 

 

 

$IPTABLES -A FORWARD -m psd -m limit --limit 3/minute -j LOG

 

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

$IPTABLES -A FORWARD -m psd -j DROP

 

# 포트 포워딩(port forwarding) 설정이다.

# 목적지 SERVICE_IP211.47.64.2, 포트는 21번으로 향하는 트래픽은 192.168.1.1

# 21번으로 NAT설정(포워딩)한다.

 

 

 

 

따라서 외부에서 211.47.64.221번으로 접속하면

# 192.168.1.121번 포트에 접속할 수 있다.

 

 

 

 

 

$IPTABLES -t nat -A PREROUTING -d $SERVICE_IP -p TCP --dport 21 -j DNAT --to 192.168.1.1:21

 

# 목적지 SERVICE_IP211.47.64.2, 포트는 747 번으로 향하는 트래픽은 192.168.1.12

# 80번으로 NAT설정(포워딩)한다.

 

 

 

 

따라서 외부에서 211.47.64.2747번으로 접속

# 하면 192.168.1.1280번 포트에 접속할 수 있다.

 

 

 

 

 

$IPTABLES -t nat -A PREROUTING -d $SERVICE_IP -p TCP --dport 747 -j DNAT --to 192.168.1.12:80

 

# 목적지 SERVICE_IP211.47.64.2, 포트는 1232번으로 향하는 트래픽은

# 192.168.1.103389번으로 NAT설정(포워딩)한다.

 

 

 

 

따라서 외부에서 211.47.64.2

# 1232번으로 접속하면 192.168.1.103389번 포트(터미널 서비스)에 접속할 수 있다.

 

 

 

 

 

$IPTABLES -t nat -A PREROUTING -d $SERVICE_IP -p TCP --dport 1232 -j DNAT --to 192.168.1.10:3389

 

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

# 들어오는 패킷은 위조된 패킷이므로 차단한다.

 

 

 

 

tcp 패킷 중 상태추적 테이블에 NEW라면

# 반드시 syn 비트가 설정된 패킷이어야 할 것이다.

 

 

 

 

 

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

 

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

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

 

 

 

 

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

# syn 비트가 설정된 패킷이어야 한다.

 

 

 

 

 

$IPTABLES -A FORWARD -p TCP ! --syn -m state --state NEW -j DROP

 

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

# -p ALL로 설정하면 tcp, udp, icmp등 모든 프로토콜에 해당하는데, 프로토콜을 명시하지

# 않아도 관계는 없다.

 

 

 

 

 

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

$IPTABLES -A FORWARD -p ALL -m state --state INVALID -j DROP

$IPTABLES -A OUTPUT -p ALL -m state --state INVALID -j DROP

 

# 이번에는 tcp-flag에 대한 설정이다.

 

 

 

 

 

# INPUT, FORWARD에 대해 각각 동일한 룰을 설정하여야 하는데, 이러한 경우 반복적으로 룰이 # 생성되므로 간소화하기 위해 CHECK_FLAGS이라는 별도의 chain을 생성하고 초기화하였다.

 

 

 

 

 

# chain 이름은 어떤 것이든 관계없다.

 

 

 

 

그리고 성능을 우선시한다면 이 부분은 빼도 된다.

 

 

 

 

 

$IPTABLES -N CHECK_FLAGS

$IPTABLES -F CHECK_FLAGS

 

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

 

 

 

 

 

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

 

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

 

 

 

 

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

 

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

 

 

 

 

 

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

 

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

# 패킷은 차단한다.

 

 

 

 

 

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

 

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

# 패킷은 차단한다.

 

 

 

 

 

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

 

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

# 패킷은 차단한다.

 

 

 

 

 

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

 

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

# 패킷은 차단한다.

 

 

 

 

 

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

 

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

 

 

 

 

 

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

 

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

# 패킷은 차단한다.

 

 

 

 

 

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

 

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

# 설정된 패킷은 차단한다.

 

 

 

 

 

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

 

# TCP 패킷 중 identd 서비스를 향하는 패킷은 거부하되, DROP하지 않고 RST 비트를

# 설정하여 바로 응답하도록 한다.

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

 

# 방화벽을 향하거나(INPUT) 방화벽을 통과하는(FORWARD) TCP 패킷은 모두

# CHECK_FLAGS chain으로 보내어 위의 tcp-flag를 살펴보도록 한다.

 

 

 

 

만약 위와 같이

# 별도의 chain을 생성하지 않을 경우에는 INPUTFORWARD에 대해 같은 룰을

# 반복적으로 생성하여야 한다.

 

 

 

 

 

 

$IPTABLES -A INPUT -p tcp -j CHECK_FLAGS

$IPTABLES -A FORWARD -p tcp -j CHECK_FLAGS

 

# 앞에서 nat 설정한 트래픽에 대해 filter 테이블에서 허용할 차례이다.

# 공인 IP747번 포트를 향하는 tcp 트래픽, 192.168.1.1280번으로 향하는

# 웹 트래픽을 허용해 주는 설정이다.

 

 

 

 

, patch-o-matic을 통해 time 패치를 하였다고

# 가정하고 접근을 허용하는 시간대를 오전 830분부터 오후 10시까지로 지정하였다.

# 이외의 시간에는 접속이 차단된다.

 

 

 

 

요일은 일주일 모두를 지정하여 요일에 관계없이 접속

# 가능하다.

 

 

 

 

time을 사용할 때는 반드시 요일도 명기해 주어야 한다.

 

 

 

 

 

$IPTABLES -A FORWARD -p TCP --sport 1024:65535 --dport 747 -m time --timestart 08:30 --timestop 22:00 --days Mon,Tue,Wed,Thu,Fri,Sat,Sun -m state --state NEW -j ACCEPT

 

# 앞에서 NAT 설정한 21번과 1232번에 대해 포트 포워딩을 허용한다.

 

 

 

 

 

# patch-o-matic을 통해 multi-port 패치를 하여 허용한 포트를 한 줄에 표현하였다.

# 만약 multi-port 패치를 하지 않았다면 두 줄로 표현하여야 한다.

$IPTABLES -A FORWARD -p TCP -m mport --ports 21,1232 -m state --state NEW -j ACCEPT

 

# 211.47.64.5에서 방화벽으로의 ssh 로그인을 허용한다.

 

 

 

 

 

$IPTABLES -A INPUT -p TCP -s 211.47.64.5 --sport 1024: --dport 22 -m state --state NEW -j ACCEPT

 

# 방화벽을 향하는 또는 내부의 서버를 향하는 traceroute를 허용하기 위해 traceroute

# 사용하는 udp 포트를 허용해 주었다.

 

 

 

 

물론 내부에서는 사설을 사용하므로 traceroute에서

# 사용하는 포트들을 일일이 nat 설정해 주지 않는 이상 FORWARD에서 허용하는 것은

# 사실상 의미가 없다.

 

 

 

 

 

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

$IPTABLES -A FORWARD -m state --state NEW -p udp --dport 33000:38000 -j ACCEPT

 

# icmp 트래픽에 대한 설정이다.

 

 

 

 

 

# INPUT, FORWARD에 대해 각각 동일한 룰을 설정하여야 하는데, 이러한 경우 반복적으로

# 룰이 생성되므로 간소화하기 위해 ICMP_HANDLE이라는 별도의 chain을 생성 하고

# 초기화하였다.

 

 

 

 

chain 이름은 어떤 것이든 관계없다.

 

 

 

 

 

$IPTABLES -N ICMP_HANDLE

$IPTABLES -F ICMP_HANDLE

 

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

 

 

 

 

 

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

 

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

 

 

 

 

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

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

 

 

 

 

 

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

 

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

 

 

 

 

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

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

 

 

 

 

 

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

 

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

 

 

 

 

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

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

 

 

 

 

 

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

 

# ICMP 패킷 중 fragmentation-needed를 허용한다.

 

 

 

 

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

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

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

 

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

 

 

 

 

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

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

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

 

# INPUT, FORWARD되는 패킷 중 ICMP라면 ICMP_HANDLE chain에 보낸다.

$IPTABLES -A INPUT -p ICMP -j ICMP_HANDLE

$IPTABLES -A FORWARD -p ICMP -j ICMP_HANDLE

 

 

 

 

 

관련자료

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

공지사항


뉴스광장


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