NAT 방화벽 룰 예제
작성자 정보
- 관리자 작성
- 작성일
컨텐츠 정보
- 2,204 조회
- 0 추천
- 목록
본문
NAT 방화벽 룰 예제
아래는 NAT 방화벽에 설정하여 사용할 수 있는 실제 룰 예제이다.
룰을 볼 때는 먼저 각 룰의 개개 의미를 살펴보고, 전체적인 흐름에서 다시 한 번 살펴보아야 한다.
그리고 눈으로만 보지 말고 직접 적용해서 실행해 보기 바란다.
이 예에서는 eth0에 공인 IP로 211.47.64.2가 할당되어 있고, 내부의 사설 대역에는 192.168.1.0/24 대역을 사용하며 게이트웨이는 eth1의 IP 주소를 사용한다고 가정한다.
#!/bin/sh
#iptables 실행파일의 경로를 정의한다.
IPTABLES="/usr/local/sbin/iptables"
SERVICE_IP="211.47.64.2" # 방화벽에서 사용할 공인 IP는 211.47.64.2로 지정한다. # 위 IP 대신 각자 자신의 공인 IP를 설정하기 바란다.
/bin/echo "1" >/proc/sys/net/ipv4/ip_forward # NAT를 사용하므로 반드시 ip_forward는 on으로 작동하여야 한다. # 여기에서 1은 on을 의미한다.
# filter 테이블의 기본정책을 설정한다. # 여기에서 INPUT과 FORWARD는 기본정책으로 DROP하고 # OUTPUT은 ACCEPT로 하는 것이 좋다.
$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_IP인 211.47.64.2, 포트는 21번으로 향하는 트래픽은 192.168.1.1의 # 21번으로 NAT설정(포워딩)한다.
따라서 외부에서 211.47.64.2의 21번으로 접속하면 # 192.168.1.1의 21번 포트에 접속할 수 있다.
$IPTABLES -t nat -A PREROUTING -d $SERVICE_IP -p TCP --dport 21 -j DNAT --to 192.168.1.1:21
# 목적지 SERVICE_IP인 211.47.64.2, 포트는 747 번으로 향하는 트래픽은 192.168.1.12 # 의 80번으로 NAT설정(포워딩)한다.
따라서 외부에서 211.47.64.2의 747번으로 접속 # 하면 192.168.1.12의 80번 포트에 접속할 수 있다.
$IPTABLES -t nat -A PREROUTING -d $SERVICE_IP -p TCP --dport 747 -j DNAT --to 192.168.1.12:80
# 목적지 SERVICE_IP인 211.47.64.2, 포트는 1232번으로 향하는 트래픽은 # 192.168.1.10의 3389번으로 NAT설정(포워딩)한다.
따라서 외부에서 211.47.64.2의 # 1232번으로 접속하면 192.168.1.10의 3389번 포트(터미널 서비스)에 접속할 수 있다.
$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 패킷 중 SYN과 FIN 비트를 살펴보아 SYN과 FIN비트가 함께 설정된 패킷은 차단한다.
$IPTABLES -A CHECK_FLAGS -p TCP --tcp-flags SYN,FIN SYN,FIN -j DROP
# TCP 패킷 중 SYN과 RST 비트를 살펴보아 SYN과 RST비트가 함께 설정된 패킷은 차단한다.
$IPTABLES -A CHECK_FLAGS -p TCP --tcp-flags SYN,RST SYN,RST -j DROP
# TCP 패킷 중 FIN과 RST 비트를 살펴보아 FIN과 RST 비트가 함께 설정된 패킷은 차단한다.
$IPTABLES -A CHECK_FLAGS -p TCP --tcp-flags FIN,RST FIN,RST -j DROP
# TCP 패킷 중 ACK와 FIN 비트를 살펴보아 ACK는 설정되지 않고 FIN 비트만 설정된 # 패킷은 차단한다.
$IPTABLES -A CHECK_FLAGS -p TCP --tcp-flags ACK,FIN FIN -j DROP
# TCP 패킷 중 ACK와 PSH 비트를 살펴보아 ACK는 설정되지 않고 PSH 비트만 설정된 # 패킷은 차단한다.
$IPTABLES -A CHECK_FLAGS -p TCP --tcp-flags ACK,PSH PSH -j DROP
# TCP 패킷 중 ACK와 URG 비트를 살펴보아 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 패킷 중 모든 비트를 살펴보아 다른 비트는 설정되지 않고 PSH와 FIN 비트만 설정된 # 패킷은 차단한다.
$IPTABLES -A CHECK_FLAGS -p TCP --tcp-flags ALL PSH,FIN -j DROP
# TCP 패킷 중 모든 비트를 살펴보아 다른 비트는 설정되지 않고 URG와 PSH, 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을 생성하지 않을 경우에는 INPUT과 FORWARD에 대해 같은 룰을 # 반복적으로 생성하여야 한다.
$IPTABLES -A INPUT -p tcp -j CHECK_FLAGS $IPTABLES -A FORWARD -p tcp -j CHECK_FLAGS
# 앞에서 nat 설정한 트래픽에 대해 filter 테이블에서 허용할 차례이다. # 공인 IP의 747번 포트를 향하는 tcp 트래픽, 즉 192.168.1.12의 80번으로 향하는 # 웹 트래픽을 허용해 주는 설정이다.
단, patch-o-matic을 통해 time 패치를 하였다고 # 가정하고 접근을 허용하는 시간대를 오전 8시 30분부터 오후 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
|
관련자료
-
이전
-
다음