브리지(bridge) 방화벽 룰 예제
작성자 정보
- 관리자 작성
- 작성일
컨텐츠 정보
- 1,664 조회
- 0 추천
- 목록
본문
브리지(bridge) 방화벽 룰 예제
이제 브리지에 대한 준비 작업이 끝났고, 실제 iptables를 이용하여 방화벽을 설정할 차례이다.
브리지 방식이라고 해서 특별할 것이 없으며, 오히려 룰 자체는 NAT보다 설정 방법이 더 쉽고 간단하다.
브리지는 NAT처럼 FORWARD chain만으로 설정하면 되고 공인 IP를 그대로 사용하므로 NAT를 고려하지 않아도 된다.
아래 실제 스크립트를 보면서 NAT와 비교하여 살펴보기 바란다.
#!/bin/sh
# 기존에 설정되어 있는 룰을 초기화(flush) 한다. $IPTABLES -t mangle -F $IPTABLES -t nat -F $IPTABLES -t filter -F
# 브리지에서는 NAT와 같이 방화벽 자체를 향하는 패킷과 브리지 내부의 서버에 대한 # 패킷을 필터링하여야 하므로 INPUT과 FORWARD는 DROP한다. # 하지만 OUTPUT을 ACCEPT할 경우 룰이 단순해지고 관리가 쉬우므로 허용하는 것이 좋다. $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 대역을 소스로 # 한 패킷을 차단한다. $IPTABLES -A INPUT -s 10.0.0.0/8 -j DROP $IPTABLES -A INPUT -s 255.255.255.255/32 -j DROP $IPTABLES -A INPUT -s 0.0.0.0/8 -j DROP $IPTABLES -A INPUT -s 169.254.0.0/16 -j DROP $IPTABLES -A INPUT -s 172.16.0.0/12 -j DROP $IPTABLES -A INPUT -s 192.0.2.0/24 -j DROP $IPTABLES -A INPUT -s 192.168.0.0/16 -j DROP $IPTABLES -A INPUT -s 224.0.0.0/4 -j DROP $IPTABLES -A INPUT -s 240.0.0.0/5 -j DROP $IPTABLES -A INPUT -s 248.0.0.0/5 -j DROP
# FORWARD chain에서 필터링 설정한다. # RFC 1918에 정의된 사설IP 및 공인 네트워크에서 라우팅 될 수 없는 IP 대역을 소스로 # 한 패킷이 방화벽 내부의 서버를 향하는 경우 차단한다. $IPTABLES -A FORWARD -s 10.0.0.0/8 -j DROP $IPTABLES -A FORWARD -s 255.255.255.255/32 -j DROP $IPTABLES -A FORWARD -s 0.0.0.0/8 -j DROP $IPTABLES -A FORWARD -s 169.254.0.0/16 -j DROP $IPTABLES -A FORWARD -s 172.16.0.0/12 -j DROP $IPTABLES -A FORWARD -s 192.0.2.0/24 -j DROP $IPTABLES -A FORWARD -s 192.168.0.0/16 -j DROP $IPTABLES -A FORWARD -s 224.0.0.0/4 -j DROP $IPTABLES -A FORWARD -s 240.0.0.0/5 -j DROP $IPTABLES -A FORWARD -s 248.0.0.0/5 -j DROP
# 브리지 방화벽 내부의 서버에 대해서 각각 아래와 같이 해당 서버를 소스로 한 패킷을 # 허용해 주어야 한다.
만약 이 설정을 해 주지 않으면 외부에서 방화벽을 통해 서버에 # 접속하는 서비스에는 문제가 없으나 내부의 서버들이 외부로 인터넷 접속을 할 수가 없 # 게 된다.
앞에서 언급한 바와 같이 브리지 방화벽을 통해 서비스하는 IP 대역은 같은 # VLAN 구간이기만 하면 관계없으며 netmask등이 달라도 관계없다.(통상적으로 하나의 # VLAN에서는 동일한 netmask를 사용하지만 하나의 VLAN에서 여러 netmask를 사용하 # 는 곳도 있다.) 아래의 경우 브리지 방화벽 내부에 211.47.64.40, 211.47.73.142, # 211.47.75.93이 설치된 경우이며 내부에서는 외부로 모든 접속이 가능한데 만약 특정한 # 접속만 가능하도록 설정하려면 각각에 프로토콜과 포트번호를 지정해 주면 된다. # 이를테면 "-p tcp --dport 80"일 경우 내부에서는 외부로 웹 접속만 가능할 것이다.
$IPTABLES -A FORWARD -s 211.47.64.40 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -s 211.47.73.142 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -s 211.47.75.93 -m state --state NEW -j ACCEPT
# 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
# 허용된 룰에 따라 이미 세션을 맺어 상태추적 테이블 목록에 있는 ESTABLISHED,RELATED # 패킷은 허용한다.
이 룰을 앞쪽에 설정할수록 방화벽의 성능을 높일 수 있다.
$IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
# 포트 스캔에 대비하기 위해 방화벽 자체를 향해 들어오는 패킷 중 포트 스캔이 감지되었을 # 경우 1분에 1개꼴로 로그에 남기도록 한다. $IPTABLES -A INPUT -m psd -m limit --limit 1/minute -j LOG # 이후 포트 스캔에 해당하는 패킷을 차단한다. $IPTABLES -A INPUT -m psd -j DROP
# 포트 스캔에 대비하기 위해 방화벽 내부의 서버를 향해 들어오는 패킷 중 포트 스캔이 # 감지되었을 경우 1분에 1개꼴로 로그에 남기도록 한다. $IPTABLES -A FORWARD -m psd -m limit --limit 1/minute -j LOG # 이후 포트 스캔에 해당하는 패킷을 차단한다.
ftp를 통해 파일 전송 시에는 차단될 수 있으므로 # 적용 시에는 주의하기 바란다.
$IPTABLES -A FORWARD -m psd -j DROP
# 방화벽을 향해 들어오는 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(113/tcp) 서비스를 향하는 패킷은 거부하되, DROP하지 않고 RST 비트로 # 응답하게 함으로써 접속 속도를 빠르게 한다. $IPTABLES -A CHECK_FLAGS -p TCP --syn --dport 113 -j REJECT --reject-with tcp-reset
# 방화벽을 향하거나 방화벽 내부를 향하는 TCP 패킷은 모두 CHECK_FLAGS chain으로 보내어 # 위의 tcp-flag를 살펴보도록 한다. $IPTABLES -A INPUT -p tcp -j CHECK_FLAGS $IPTABLES -A FORWARD -p tcp -j CHECK_FLAGS
# 서버에 snmpd를 설치하여 mrtg를 이용하여 트래픽을 모니터링 할 경우 해당 mrtg 서버 # (여기에서는 211.47.64.5라 가정)를 소스로 하는 161/udp 트래픽을 허용하여야 한다.
# 방화벽 자체의 트래픽을 측정하고자 할 경우에는 INPUT, 방화벽 내부의 서버에 대한 트래픽을 # 측정하고자 할 경우에는 FORWARD에서 각각 161/udp를 허용하면 되는데, 만약 # 특정한 서버에 대해서만 snmp를 허용하려면 두 번째 룰에서 -d를 지정해 주면된다.
$IPTABLES -A INPUT -p UDP -s 211.47.64.5 --sport 1024: --dport 161 -m state --state NEW -j ACCEPT $IPTABLES -A FORWARD -p UDP -s 211.47.64.5 --sport 1024: --dport 161 -m state --state NEW -j ACCEPT
# 방화벽 내부의 서버들에 대해 FORWARD를 이용하여 각각의 서버에서 허용할 서비스를 # 정의해 주도록 한다.
# 211.47.64.40의 80번(웹) 접속은 모두 허용하고 있다.
$IPTABLES -A FORWARD -p TCP --sport 1024: -d 211.47.64.40 --dport 80 -m state --state NEW -j ACCEPT
# 내부에서 메일 서버를 운영할 경우 외부에서 오는 메일을 모두 수신하여야 하므로 # 외부에서 211.47.64.40의 25번으로 향하는 트래픽을 허용한다. $IPTABLES -A FORWARD -p TCP --sport 1024: -d 211.47.64.40 --dport 25 -m state --state NEW -j ACCEPT
# 211.47.64.5에서 211.47.64.40으로 향하는 FTP 접속을 허용한다.
$IPTABLES -A FORWARD -p TCP -s 211.47.64.5 --sport 1024: -d 211.47.64.40 --dport 21 -m state --state NEW -j ACCEPT
# 211.47.73.142에 대한 80번(웹) 접속은 허용하고 있다.
$IPTABLES -A FORWARD -p TCP --sport 1024:65535 -d 211.47.73.142 --dport 80 -m state --state NEW -j ACCEPT
# 211.47.75.93에 대한 80번(웹) 접속은 허용하고 있다.
$IPTABLES -A FORWARD -p TCP --sport 1024:65535 -d 211.47.75.93 --dport 80 -m state --state NEW -j ACCEPT
# 관리를 위해 211.47.64.50에서 방화벽으로의 ssh 접속은 허용하고 있다.
방화벽 자체이므로 # INPUT을 사용하여야 한다.
$IPTABLES -A INPUT -p TCP -s 211.47.64.50 --sport 1024: --dport 22 -m state --state NEW -j ACCEPT
# 방화벽을 향하는 또는 내부의 서버를 향하는 traceroute를 허용하기 위해 traceroute가 # 사용하는 udp 포트를 허용해 주었다.
여기에서는 TRACEROUTE라는 chain을 생성하였으나 # 별도로 생성하지 않고 INPUT, FORWARD에 대해 각각 설정해 주어도 된다. $IPTABLES -N TRACEROUTE $IPTABLES -F TRACEROUTE
$IPTABLES -A TRACEROUTE -m state --state NEW -p udp --dport 33000:38000 -j ACCEPT
$IPTABLES -A INPUT -p udp -j TRACEROUTE $IPTABLES -A FORWARD -p udp -j TRACEROUTE
# 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 -j ACCEPT
# INPUT, FORWARD 되는 패킷중 ICMP라면 ICMP_HANDLE chain에 보낸다. $IPTABLES -A INPUT -p ICMP -j ICMP_HANDLE $IPTABLES -A FORWARD -p ICMP -j ICMP_HANDLE
|
이렇게 해서 브리지 방화벽의 룰이 끝났다.
스크립트의 앞부분과 뒷부분은 다른 방화벽과 동일하고 단지 허용하고자 하는 트래픽에 대해서는 FORWARD만 잘 쓰면 브리지 방화벽은 NAT에 비해 매우 쉽다는 것을 알 수 있다.
그리고 브리지 모드를 설정한 후 dmesg를 실행하면 다음과 같은 메시지가 보이게 될 것이다.
이는 브리지를 통해 네트워크를 구성하는 과정이며 네트워크를 인식하면서 바로 작동하는 것이 아니라 실제 작동하기 까지 네트워크 루핑을 막는 spanning tree때문에 listening -> learning -> forwarding 과정을 거치며 약 30여초 정도 이후에 네트워크가 연결되기 때문이다.
device eth0 entered promiscuous mode
device eth1 entered promiscuous mode
br0: port 2(eth1) entering listening state
br0: port 1(eth0) entering listening state
Ddevice br0 entered promiscuous mode
br0: port 2(eth1) entering learning state
br0: port 1(eth0) entering learning state
br0: port 2(eth1) entering forwarding state
br0: port 1(eth0) entering forwarding state
관련자료
-
이전
-
다음