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

브리지(bridge) 방화벽 룰 예제

작성자 정보

  • 관리자 작성
  • 작성일

컨텐츠 정보

본문

브리지(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와 같이 방화벽 자체를 향하는 패킷과 브리지 내부의 서버에 대한

# 패킷을 필터링하여야 하므로 INPUTFORWARDDROP한다.

# 하지만 OUTPUTACCEPT할 경우 룰이 단순해지고 관리가 쉬우므로 허용하는 것이 좋다.

$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 패킷 중 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(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.4080() 접속은 모두 허용하고 있다.

 

 

 

 

 

$IPTABLES -A FORWARD -p TCP --sport 1024: -d 211.47.64.40 --dport 80 -m state --state NEW -j ACCEPT

 

# 내부에서 메일 서버를 운영할 경우 외부에서 오는 메일을 모두 수신하여야 하므로

# 외부에서 211.47.64.4025번으로 향하는 트래픽을 허용한다.

$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

 

 

 

 

 

 

 

 

 

관련자료

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

공지사항


뉴스광장


  • 현재 회원수 :  60,157 명
  • 현재 강좌수 :  36,514 개
  • 현재 접속자 :  268 명