[보안] Bridge 를 이용한 방화벽 구축

사무실을 이전하면서 오래전부터 생각하고 있던 방화벽을 구축하게 되었습니다.

저와 같이 삽질을 준비하시는 분들께 참고 삼아 보시라고 올려봅니다.

[1] 밑그림.

아래는 계획하고 있는 네트웍의 간략한 구성도 입니다.

인터넷

|

|

+——+

|라우터|

+——+

|

| <— 크로스케이블

|

+———–+

|eth0…….|

|외부 방화벽| <— redzone brideg firewall 서버

|eth1…….|

+———–+

|

|

|———————————————> 이부분이 DMZ임.

| | | |

| FTP serv web serv dns serv

|

|

+———–+

|eth0…….|

|내부 방화벽| <— bluezone firewall 서버

|eth1…….|

+———–+

|

|

|——————————————> 이부분이 LAN임.

| | | |

win 2000 win NT win ME MAC

간단히 설명하자면

위 구성은 크게 세부분으로 나누어집니다. WAN, DMZ, LAN 으로…

DMZ는 211.11.11.64부터 211.11.11.127까지 이고 LAN은 211.11.11.0부터

211.11.11.63까지 입니다. 라우팅을 위해 넷마스크 255.255.255.192로

네트웍을 2개로 분리,재구성한 것입니다.

DMZ의 gateway는 라우터인 211.11.11.126이 되고(외부방화벽이 아님!!!)

LAN의 gateway는 내부 방화벽인 211.11.11.62가 됩니다.

인터넷으로의 접속은 외부 방화벽(redzone 서버)에 의해 제어되며 회사에서

제공하는 기본적인 서비스들은 DMZ라는 지역에 위치하고 있습니다.

사무실 내부의 랜 환경은 내부 방화벽(bluezone 서버)에 의해 제어됩니다.

그럼 조금 더 자세히 볼까요.

사무실 내부의 네트웍은 ‘bluezone’이라고 부르기로 했습니다.

bluezone은 bluezone firewall 서버에 의해 필터링 됩니다.

외부의 모든 트래픽은 bluezone firewall 서버를 거쳐야하기 때문에

이곳에서 패킷 필터링을 하면 강력한 보안정책으로 사무실 내부 네트웍인

bluezone을 보호할 수 있습니다. bluezone에서 나가는 모든 트래픽은

211.11.11.124라는 IP로 마스커레이딩 될 것입니다. 외부에서는 사무실

내부에 대한 어떠한 정보 수집도, 접속도 거부될 것입니다.

redzone bridge firewall 서버와 bluezone firewall 서버에 의해 구분되는

네트웍은 ‘DMZ’라 부르기로 했습니다. 홈페이지, ftp 서버, 메일 서버,

네임 서버 등이 이곳에 위치합니다. 사무실 내부 네트웍보다는 좀 더

완화된 보안정책을 적용합니다. 그러나 DMZ도 redzone bridge firewall

서버에 의해 보호될 것입니다.

기본적으로 방화벽 서버인 redzone서버와 bluezone서버에서는 보안을 위해

어떠한 서비스도 제공하지 않습니다. redzone서버와 bluezone서버에 대한

접속은 모두 거부될 것입니다.

그럼 이제부터 하나씩 살펴보기로 하겠습니다.

[2] 라우터

WAN과는 라우터를 통해 연결됩니다.

라우터는 코넷에서 제공하는 한아라우터 입니다.(rustle 4501기종)

참고로 저희회사는 T1(1.544M) 라인을 사용하고 있습니다.

workstation급 이런 저런 서버들이 10여대쯤 되고 사무실 내부에서 사용

하는 PC들이 30여대쯤 됩니다.

라우터의 설정입니다.

IP : 211.11.11.126

network : 211.11.11.0

subnetmask : 255.255.255.128

라우터의 설정에 대해서는 다루지 않겠습니다. 궁금하신 분들은 한아라우터

홈페이지의 자료실에서 메뉴얼을 구하십시요.

[3] 외부 방화벽(redzone bridge firewall server)

외부 방화벽에 대한 설정입니다.

외부 방화벽은 브릿지로 구성하였습니다.

아래의 글들을 읽어보시면 왜 브릿지로 했는지를 아실겁니다. 반드시 먼저

아래의 글들을 읽어보세요.

1.정정화님의 Bridge Firewall

–> http://kldp.org/KoreanDoc/Bridge_Firewall-KLDP

2.정정화님의 실제 IP를 사용하는 방화벽 및 포워딩 머쉰 구축

–> http://kldp.org/KoreanDoc/Firewall-KLDP

3.유천님의 실제 IP를 이용한 Bridge Firewall TIP

–> http://kltp.kldp.org/stories.php?story=01/04/21/4352223

제가 작업한 많은 부분은 위의 내용과 같습니다. 위와 중복되는 부분의 설명은

하지 않을 것이니 반드시 위 글들을 읽어야 합니다.

브릿지는 아이피를 가지지 않습니다. 브릿지의 eth0, eth1에는 IP를 부여하지

않는다는 말입니다. 다만 브릿지 자체의 인터페이스에만 IP를 부여합니다.

외부 브릿지 방화벽의 설정입니다.

시스템 : P3 667(?), 512RAM, 3C905b 2장.

커널 : 데비안 포테이토(커널만 업글해서 2.2.19)

eth0 IP : 없음

eth1 IP : 없음

bridge IP : 211.11.11.125

bridge network : 211.11.11.64

bridge subnetmask : 255.255.255.192

bridge broadcast : 211.11.11.127

bridge gateway : 211.11.11.126

시스템은 P3 667쯤 됩니다. 램은 512고, 모든 내부 트래픽이 이부분을 통과

하기 때문에 랜카드는 좋은 걸로 했습니다.

o. Linux BRIDGE -STP -HOWTO

–>http://www.bnhof.de/~uwe/bridge-stp-howto/BRIDGE-STP-HOWTO

o. Linux BRIDGE Homepage

–>http://www.math.leidenuniv.nl/~buytenh/bridge

위의 싸이트에 가보심 아시겠지만 브릿지방화벽은 2.2.x대의 커널에서 안정화

되어 있습니다. 그래서 데비안 포테이토 깔고 브릿지 방화벽용 패치하고

커널 컴팔 다시 했습니다. 커널 컴파일과 패치하는 법은 위의 글들에 너무도

잘 설명되어 있으므로 전 설명하지 않고 바로 제가 세팅한 부분으로 넘어가서…

아래는 /etc/network/interface 의 내용입니다.

————————————————————————–

# /etc/network/interfaces — configuration file for ifup(8), ifdown(8)

# The loopback interface

iface lo inet loopback

————————————————————————–

여기서는 아무런 설정도 하지 않고 아래의 파일에서 설정을 합니다.

아래는 /etc/rc.boot/brideg@redzone 의 내용입니다.

————————————————————————–

#!/bin/bash

################################################################

echo “”

echo “Setting bridging …. start”

/usr/sbin/brctl addbr dev-br

/usr/sbin/brctl stp dev-br off

/usr/sbin/brctl addif dev-br eth0

/usr/sbin/brctl addif dev-br eth1

/sbin/ifconfig eth0 0.0.0.0

/sbin/ifconfig eth1 0.0.0.0

/sbin/ifconfig dev-br 211.11.11.125 broadcast 211.11.11.127 netmask 255.255.255.192 up

/sbin/route add default gw 211.104.131.126

echo “Setting bridging …. done”

echo “”

################################################################

————————————————————————–

유천님의 설정을 조금 수정한 정도입니다.(유천님께 감사드립니다 ^^.)

브릿지 자체의 인터페이스에만 IP 211.11.11.125를 부여합니다. 사실 브릿지

방화벽자체에서 ftp나 telnet 등의 서비스를 제공하지 않는다면 IP를 부여하지

않아도 됩니다.

아래는 redzone bridge firewall 서버의 방화벽 스크립트 파일인

/etc/rc.boot/firewall@redzone 의 내용입니다.

————————————————————————–

#!/bin/bash

#

# TOS(Type of Service)

# minimum delay 0x10

# maximum throughput 0x08

# maximum reliability 0x04

# minimum cost 0x02

# nomarl service 0x00

################################################################

echo “”

echo “Setting BRIDGE – FireWall … start ”

# 체인 추가

# input, output, forward는 ipchain의 기본 체인임.

# dev-br은 브릿지를 관통하는(forward되는) 체인임.

# waninput은 wan에서 redzone 서버로 들어오는 체인임.

# laninput은 lan에서 reazone 서버로 들어오는 체인임.

# br_out은 redzone 서버에서 외부로 나가는 체인임.

/sbin/ipchains -P input ACCEPT

/sbin/ipchains -P output ACCEPT

/sbin/ipchains -P forward DENY

/sbin/ipchains -N dev-br

/sbin/ipchains -N waninput

/sbin/ipchains -N laninput

/sbin/ipchains -N br_out

## Wan—>Lan

## wan에서 lan으로의 접속 패킷인 경우

##

/sbin/ipchains -N wantolan

/sbin/ipchains -A dev-br -s ! 211.11.11.64/26 -d 211.11.11.64/26 -j wantolan

/sbin/ipchains -A wantolan -p icmp -j ACCEPT

/sbin/ipchains -A wantolan -p icmp -d 211.11.11.127 -j DENY # smurf 예방

/sbin/ipchains -A wantolan -p tcp -d 211.11.11.64/26 137:139 -j DENY # netbios-ns 거부

/sbin/ipchains -A wantolan -p udp -d 211.11.11.64/26 137:139 -j DENY # netbios-ns 거부

/sbin/ipchains -A wantolan -p tcp ! -y -j ACCEPT

# 68은 ftp 서비스를 위해 허용.

/sbin/ipchains -A wantolan -p tcp -d 211.104.131.68 -j ACCEPT # ftp 서버 허용

# 65에서는 http, mail, dns 등의 서비스를 제공하고 있다.

/sbin/ipchains -A wantolan -p tcp -d 211.11.11.65 25 -j ACCEPT # mail server

/sbin/ipchains -A wantolan -p tcp -d 211.11.11.65 53 -j ACCEPT # name server

/sbin/ipchains -A wantolan -p udp -d 211.11.11.65 53 -j ACCEPT # name server

/sbin/ipchains -A wantolan -p udp -s 0/0 53 -d 211.11.11.65 1023: -j ACCEPT # name server

/sbin/ipchains -A wantolan -p tcp -d 211.11.11.64/26 80 -j ACCEPT # http

/sbin/ipchains -A wantolan -p tcp -d 211.11.11.65 110 -j ACCEPT # pop3

/sbin/ipchains -A wantolan -p tcp -d 211.11.11.65 220 -j ACCEPT # imap3

/sbin/ipchains -A wantolan -p tcp -d 211.11.11.65 520 -j ACCEPT # route

# 내부 방화벽으로의 접속은 모두 허용. 이건 내부 방화벽에서 필터링할 것임.

/sbin/ipchains -A wantolan -d 211.11.11.124 -j ACCEPT # bluezone 허용

/sbin/ipchains -A wantolan -j DENY

## Lan—>Wan

## lan에서 wan로의 접속 패킷은 모두 허용함.

##

/sbin/ipchains -N lantowan

/sbin/ipchains -A dev-br -s 211.11.11.64/26 -d ! 211.11.11.64/26 -j lantowan

/sbin/ipchains -A lantowan -p tcp -d 0/0 telnet -t 0x01 0x10

/sbin/ipchains -A lantowan -p tcp -d 0/0 ftp -t 0x01 0x10

/sbin/ipchains -A lantowan -p tcp -d 0/0 ftp-data -t 0x01 0x08

/sbin/ipchains -A lantowan -p udp -d 0/0 snmp -t 0x01 0x04

/sbin/ipchains -A lantowan -p tcp -d 0/0 nntp -t 0x01 0x02

/sbin/ipchains -A lantowan -p tcp -d 0/0 smtp -t 0x01 0x02

/sbin/ipchains -A lantowan -p tcp -d 0/0 pop-3 -t 0x01 0x02

/sbin/ipchains -A lantowan -p tcp -s 211.11.11.64/26 137:139 -j DENY # netbios-ns 거부

/sbin/ipchains -A lantowan -p udp -s 211.11.11.64/26 137:139 -j DENY # netbios-ns 거부

/sbin/ipchains -A lantowan -j ACCEPT

## Lan—>Lan

## lan에서 lan로의 접속 패킷은 모두 허용함.

##

/sbin/ipchains -N lantolan

/sbin/ipchains -A dev-br -s 211.11.11.64/26 -d 211.11.11.64/26 -j lantolan

/sbin/ipchains -A lantolan -j ACCEPT

## Wan—>redzone server

## wan에서 redzone 서버로의 접속 패킷은 거부함.

##

/sbin/ipchains -A input -i dev-br -s ! 211.11.11.64/26 -d 211.11.11.125 -j waninput

/sbin/ipchains -A waninput -p icmp -j ACCEPT

/sbin/ipchains -A waninput -p tcp ! -y -j ACCEPT

/sbin/ipchains -A waninput -j DENY

#/sbin/ipchains -A waninput -j ACCEPT

## Lan—>redzone server

## lan에서 redzone 서버로의 접속 패킷은 거부함.

##

/sbin/ipchains -A input -i dev-br -s 211.11.11.64/26 -d 211.11.11.125 -j laninput

/sbin/ipchains -A laninput -p icmp -j ACCEPT

/sbin/ipchains -A laninput -p tcp ! -y -j ACCEPT

#/sbin/ipchains -A laninput -s 211.11.11.124 -j ACCEPT

/sbin/ipchains -A laninput -j DENY

#/sbin/ipchains -A laninput -j ACCEPT

## local output

## 방화벽 자체에서 나가는 패킷.

##

/sbin/ipchains -A output -i dev-br -j br_out

/sbin/ipchains -A output -p tcp -d 0/0 telnet -t 0x01 0x10

/sbin/ipchains -A output -p tcp -d 0/0 ftp -t 0x01 0x10

/sbin/ipchains -A output -p tcp -d 0/0 ftp-data -t 0x01 0x08

/sbin/ipchains -A output -p udp -d 0/0 snmp -t 0x01 0x04

/sbin/ipchains -A output -p tcp -d 0/0 nntp -t 0x01 0x02

/sbin/ipchains -A output -p tcp -d 0/0 smtp -t 0x01 0x02

/sbin/ipchains -A output -p tcp -d 0/0 pop-3 -t 0x01 0x02

/sbin/ipchains -A br_out -j ACCEPT

echo “Setting BRIDGE – FireWall … done”

echo “”

##################################################################

————————————————————————–

유천님의 설정을 조금 수정한 정도입니다.(유천님께 감사드립니다 ^^.)

bridge 설정에 대한 자세한 내용은 유천님의 글을 보세요.

필터링 규칙은 각자의 네떡 환경에 맞게 수정하셔야 합니다.

기본 체인인 input, output, forward 외에 패킷의 성격에 따라 몇개의 체인을

더 추가하였습니다. 각자의 환경에 맞게 세팅을 고쳐주셔야 합니다. 아래의

문서를 참고하시기 바랍니다.

ㅇ IPCHAINS 하우투

ㅇ 리눅스 2.4 패킷 필터링 하우투

ㅇ 리눅스 2.4 NAT 하우투

—> http://kldp.org

저의 경우 DMZ에서 여러 웹서버와 네임서버, 메일서버, ftp 서버를 운영중입니다.

redzone 자체로의 접속은 보안을 위해 극히 제한되어 있습니다.

내부 방화벽인 bluezone firewall 서버에 대한 패킷은 모두 허용하며 이 패킷들은

bluezone firewall 서버에서 필터링될 것입니다.

211.11.11.68번은 ftp서버를 위해, 211.11.11.65번은 웹서비스, 네임서비스, 메일

서비스를 위해 허용된 것입니다.

DMZ에 위치한 서버들은 외부방화벽만 믿어선 안됩니다. redzone에 위치한 웹서버,

ftp서버, 메일서버, 네임서버 등도 자체적으로 보안 설정을 해야만 합니다.

redzone은 bluezone보다는 상대적으로 위험하기 때문에 TCPWRAPER, ipchain,

iptables 등으로 자체적인 보안 설정을 꼭 하시는 것이 좋습니다.

redzone(DMZ)에 위치한 서버들에 대한 설정입니다.

IP : 211.11.11.70

network : 211.11.11.64

subnetmask : 255.255.255.192

broadcast : 211.11.11.127

gateway : 211.11.11.126 (외부방화벽이 아닌 라우터임!!!)

여기까지가 외부방화벽인 redzone bridge firewall 서버와 DMZ에 대한 설정

입니다. ipchain보다 iptable이 좀 더 세부적인 필터링을 제공하지만 브릿지

방화벽을 이용하기 위해서는 ipchain을 사용해야만 합니다. 빠른 시일내에

iptables도 지원되기를 빌어봅니다.

[4] bluezone firewall server

다음은 사무실 내부의 네트웍을 보호하는 bluezone firewall 서버에 대해서 입니다.

시스템 : P3 600, 512 RAM, Realtek 8139b 2장.

커널 : 와우리눅스 파란 업그레이드판(커널 2.4.2)

eth0 IP : 211.11.11.124

eth0 network : 211.11.11.64

eth0 subnetmask : 255.255.255.192

eth0 broadcast : 211.11.11.127

eth0 gateway : 211.11.11.126

eth1 IP : 211.11.11.62

eth1 network : 211.11.11.0

eth1 subnetmask : 255.255.255.192

eth1 broadcast : 211.11.11.63

eth1 gateway : 없음

eth0은 외부로 나가는 인터페이스이고 eth1은 내부 랜환경과 연결되는 인터페이스

입니다.

eth0인 211.11.11.124는 211.11.11.64 네트웍을 라우팅하고 eth1인 211.11.11.62는

211.11.11.0네트웍을 라우팅하도록 설정해야 합니다.

아래는 /etc/sysconfig/network-scripts/ifcfg-eth0의 내용입니다.

————————————————————————–

DEVICE=eth0

BOOTPROTO=static

BROADCAST=211.104.131.127

IPADDR=211.104.131.124

NETMASK=255.255.255.192

NETWORK=211.104.131.64

GATEWAY=211.104.131.126

GATEWAYDEV=eth0

ONBOOT=yes

————————————————————————–

아래는 /etc/sysconfig/network-scripts/ifcfg-eth1의 내용입니다.

————————————————————————–

DEVICE=eth1

BOOTPROTO=static

FORWARD_IPV4=yes

BROADCAST=211.104.131.127

IPADDR=211.104.131.62

NETMASK=255.255.255.192

NETWORK=211.104.131.0

ONBOOT=yes

————————————————————————–

아래는 bluezone firewall 서버의 방화벽 스크립트 파일인

/etc/rc.boot/firewall@bluezone 의 내용입니다.

이 훌륭한 iptables 방화벽 스크립트 파일의 원 출처는 아래 입니다.

—> http://monmotha.mplug.org/firewall/index.php

제가 작업할 당시엔 최신 버전이 2.3.7-pre4 였으며 이문서를 작업하면서 살펴보니

2.3.7-pre7이 최신 버전이군요. 커널 2.4로 바뀌면서 기존의 방화벽코드들을 한데

모아 작성한 iptables의 풍부한 기능을 잘 살린 스크립트 입니다.

스크립트에 DMZ에 관한 부분이 있으나 이 스크립트에서 구현한 개념과 제가 생각한

개념은 사뭇 틀리기에 전 DMZ에 관한 부분은 사용하지 않았습니다.

#은 원문의 주석이며 #!!은 제가 추가한 코드와 주석 입니다.

————————————————————————–

#!/bin/bash

# ———————————————————————-|

# This is it…MonMotha’s Firewall 2.3.7-pre4! |

# All your hackers are belong to Linux/Netfilter! |

# ———————————————————————-|

# 2.3 RELEASE NOTES: This is the 2.2 series with some extra stuff, |

# including MAC address matching, stateful matching, port forwarding, |

# per-proto accept behavior, and some other stuff that I might think |

# about adding later. |

# ———————————————————————-|

# COMMENTS from MonMotha: |

# |

# Before e-mailing me, please check the distribution site (which can be |

# found at http://freshmeat.net/projects/mothafirewall as it changes |

# sometimes) for a new version. |

# –MonMotha |

# |

# Please…PLEASE give me feedback on your experiences with this script |

# I would really like to know what everyone wants, what works, and |

# about the inevitable bugs present in anything. |

# |

# Direct all feedback to: bvmopen@usa.net |

# –MonMotha |

# |

# When e-mailing with problems, please include firewall script version, |

# iptables version, kernel version, and GNU BASH version. If you think |

# your problem might be related to kernel configuration, please attach |

# the .config file for your kernel. |

# –MonMotha |

# |

# ———————————————————————-|

# SYSTEM REQUIREMENTS: You must have either compiled the appropriate |

# iptables support into your 2.4 kernel or have loaded all the |

# applicable modules BEFORE you run this script. This script will not |

# load modules for you. |

# |

# You will need (at least) the following kernel options to use |

# this firewall: CONFIG_NETFILTER, CONFIG_IP_NF_IPTABLES, |

# CONFIG_IP_NF_FILTER, CONFIG_IP_NF_MATCH_STATE and |

# CONFIG_IP_NF_TARGET_REJECT. |

# To use the masquerading you will also need (at least): |

# CONFIG_IP_NF_CONNTRACK, CONFIG_IP_NF_NAT, CONFIG_IP_NF_NAT_NEEDED |

# and CONFIG_IP_NF_TARGET_MASQUERADE. |

# Additional options may be needed to use other features. |

# |

# You need iptables. Get it at “http://netfilter.filewatcher.org”. |

# |

# This script was written (and partially tested) with iptables 1.2 |

# and kernel 2.4.x (non testing) in mind. |

# |

# Also, this is a BASH shell script…any 2.x version of GNU BASH |

# should work. |

# |

# SED should no longer be required since builtins are now used. |

# ———————————————————————-|

# |

# This is distributed under the modified BSD liscense: |

# |

# Redistribution and use in source and binary forms, with or without |

# modification, are permitted provided that the following conditions |

# are met: |

# |

# 1.Redistributions of source code must retain the above copyright |

# notice, this list of conditions and the following disclaimer. |

# 2.Redistributions in binary form must reproduce the above |

# copyright notice, this list of conditions and the following |

# disclaimer in the documentation and/or other materials provided |

# with the distribution. |

# 3.The name of the author may not be used to endorse or promote |

# products derived from this software without specific prior |

# written permission. |

# |

# THIS SOFTWARE IS PROVIDED BY THE AUTHOR “AS IS” AND ANY EXPRESS OR |

# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |

# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |

# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY |

# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |

# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE |

# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |

# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER |

# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR |

# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN |

# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE |

# |

# While this may be used freely for commercial use, I do REQUEST that |

# any commercial users please tell me via e-mail at bvmopen@usa.net |

# that they are using it, why they chose it, how well it works, etc. |

# |

# ———————————————————————-|

# IMPORTANT: This firewall is currently in beta! It may be too |

# restrictive or insecure. |

# ———————————————————————-|

# CHANGELOG: (Since 2.3.0-pre1a only) |

# version 2.3.7-pre4: Line 414, missing subnet match caused all |

# packets from anywhere to be allowed. |

# Fixed. |

# version 2.3.7-pre3: Fix missing fi (fatal syntax error) |

# Fix logging in TCPACCEPT chain |

# version 2.3.7-pre2: Add route verification (thanks to Jeremy |

# Frank) |

# Add blackhole directive |

# Updated configuration sanity checks |

# Ripped out SSH Stuff as it isn’t needed |

# True default DROP on INPUT |

# Don’t run the INTERNAL_LAN loop if no nets |

# Upped the default SYN limit as large |

# numbers of small FTP transfers would |

# overload it quickly |

# Form cleanups |

# version 2.3.7-pre1: Maybe the FTP will work now (fixes for the |

# RELATED state) |

# Now works with both LAN and DMZ iface null |

# Moved static NAT to stable options |

# Change parser to /bin/bash not /bin/sh |

# version 2.3.6: Add TTL mangling |

# Added some more EFNet servers to the list |

# Fix in the DMZOUT chain |

# Fix FTP stuff |

# version 2.3.5: Fixes to make port forwarding work again |

# version 2.3.4: USE_MASQ has been changed to MASQ_LAN in port fw |

# Fix syntax error in TCP port forwards |

# General cleanup |

# Fixes in port forwarding |

# It’s LTREJECT, not TLREJECT |

# More TOS mangling |

# version 2.3.3: Fatal syntax error in IP forward detect fix |

# Don’t bail on no IP forward for no LAN |

# version 2.3.3-pre1: Reject with tcp-reset for TCP option |

# Removed the huge list of censorship |

# Moved the port forwards to stable options |

# Moved the TOS mangling to stable options |

# Check before enabling IP Forwarding and |

# IP SynCookies |

# Don’t run censorship loop if no rules |

# Request low latency TOS on UDP packets for |

# games on ports 4000-7000 (Diablo II) |

# Fix bad syntax in the port forwarding loops |

# Reversed DMZIN and DMZOUT fixed |

# Various syntax fixes |

# Stateful inspection on forward chain |

# Other stateful matching changes |

# version 2.3.2: Fixed bad syntax in DMZ_IFACE loop |

# version 2.3.2-pre2: Put a real liscense on it (BSD liscense) |

# Changed format of ALLOW_HOSTWISE and |

# DENY_HOSTWISE to be less confusing |

# (the “:” was changed to “>”) |

# Added LOG_FLOOD option to tweak log limit |

# Added SYN_FLOOD option to tweak SYN limit |

# Added PING_FLOOD option to tweak PING limit |

# version 2.3.2-pre1: Stateful matching on active FTP and SSH |

# rules (thanks to Len Padilla) |

# Fixed a minor bug in chain creation order |

# (thanks to Peter Lindman) |

# TOS Optimizations (thanks to vesa alatalo) |

# Begin DMZ Support |

# Proofread comments and correct |

# Use BASH builtins instead of sed |

# (thanks to Craig Ludington) |

# Fixed “USE_SNAT” bug in port forwarding |

# (has been changed to “SNAT_LAN”) |

# (thanks to Fr??ic Marchand) |

# Tuned down default TCP allows (remove POP3) |

# version 2.3.1: Option for 1:1 or subnet:1 static NAT |

# Internet censorship options |

# version 2.3.1-pre2: Added option to deny specific ports from |

# specific hosts |

# Added limiting to logging chains to prevent |

# log DoSing |

# Spiffed up comments |

# Changed the “AUTH_ALLOW” and “DNS” options |

# to be more generic and flexible |

# version 2.3.1-pre1: Updated comments for new kernel version |

# Removed double drop setting |

# Updated for iptables-1.2 |

# Began a kernel option list |

# version 2.3.0: No changes from pre1g |

# version 2.3.0-pre1g: Tuned down default TCP allows |

# Restructure to SSH loop |

# Status Reporting Fixes (newlines, etc.) |

# Fix log prefix length on accept loops |

# version 2.3.0-pre1f: Moved the ICMP echo-request limit to where |

# it should have been |

# Allows the rest of the ICMP like it should |

# Remove the interface matching from ICMP |

# echo-request (not needed) |

# version 2.3.0-pre1e: Fixed an issue in the invalid matching |

# version 2.3.0-pre1d: Spiffed up comments |

# Port Forwarding |

# Moved the deny setting to normal options |

# version 2.3.0-pre1c: Minor fixes that don’t (currently) affect |

# functionality |

# version 2.3.0-pre1b: Security fix documented in 2.1.13 |

# Slight logic change in TCP_ALLOW loop |

# Don’t print allow messages if nothign is |

# allowed by that loop |

# Changed IPTables download URL |

# version 2.3.0-pre1a: Initial branch from 2.1.12 |

# Add stuff in release notes except port fw |

# ———————————————————————-|

# USE AT YOUR OWN RISK! THIS IS WITHOUT ANY WARRANTY STATED OR IMPLIED! |

# That means NONE whatsoever, not even fitfullness for purpose! |

# ———————————————————————-|

# You NEED to set this! |

# Configuration follows: |

# |

# Notes about configuration: |

# Some things take more than one option; separate with spaces. |

# You probably don’t want all the ports I have under here open, portscan|

# yourself to find what you want open. |

# If you want to used host-based identd allowing, do NOT put 113 in |

# TCP_ALLOW and DO set ALLOW_TCP_HOSTWISE (using 113 as the port).|

# Of course, you can also put 113 in TCP_ALLOW to allow anyone. |

# The same applies to DNS zone transfers (only use port 53 and UDP). |

# MAC_MASQ is ONLY used to the purposes of masquerading and it will |

# override the MASQ_LAN setting for masquerading. However, you |

# must still define MASQ_LAN properly. |

# INTERNAL_LAN must always be properly defined. |

# You can use hostnames anywhere, but you’ll need to have access to the |

# DNS server when the script runs and you might not get the expected |

# results since the DNS lookup is only done once. |

# You can mix and match hosts with public IPs and masqueraded hosts in |

# INTERNAL_LAN as long as you define the ones to use NAT later. |

# DMZ support can currently be considered (at best) PREALPHA. |

# It should work without a LAN, leave it blank, but this isn’t tested |

#!!

echo “”

echo “—Starting Firewall …—”

echo “set variables:”

# Main configuration, modify to suit your setup

#!! 실행파일 위치.

IPTABLES=”/sbin/iptables” # set to your iptables location, must be set

#!! 포트별 서비스

#!! 20=ftp-data, 21=ftp, 22=ssh, 23=telnet, 25=mail(SMTP), 53=dns,

#!! http=80, 109=pop2, 110=pop3, 137=netbios-ns, 143=imap2, 194=ircd, imap3=220,

#!! hppts=443, 520=route, 540=uucp, 901=swat, 3306=mysql

#!! 51200:51201(udp),51210(tcp)=다이얼패드, 9001:9004(udp)=소리바다, 4000-5000=irc-dcc,

#!! 6901(tcp)=msn, 6891:6900(tcp)=msn-dcc

#!! bluezone firewall 서버에서 허용할 서비스 지정.

#!! TCP_ALLOW=”22″ # TCP ports to allow

TCP_ALLOW=”” # TCP ports to allow

#!! UDP_ALLOW=”6112 6119 4000″ # UDP ports to allow

UDP_ALLOW=”” # UDP ports to allow

#!! 외부 인터페이스.

#!! INET_IFACE=”eth1″ # the interface your internet’s on (one only), must be set

INET_IFACE=”eth0″ # the interface your internet’s on (one only), must be set

INET_IFACE_IP=”211.11.11.124″

#!! 내부 인터페이스.

#!! LAN_IFACE=”eth0″ # the interface your LAN’s on (one only)

LAN_IFACE=”eth1″ # the interface your LAN’s on (one only)

LAN_IFACE_IP=”211.11.11.62″

#!! 내부 네트웍.

#!! INTERNAL_LAN=”192.168.0.0/24 192.168.1.0/24″# The internal LAN (Including DMZs but not censored hosts)

INTERNAL_LAN=”211.11.11.0/255.255.255.192″ # The internal LAN (Including DMZs but not censored hosts)

#!! 마스커레이딩할 네트웍

#!! MASQ_LAN=”192.168.0.0/24 192.168.1.0/24″ # the internal network(s) to be masqueraded (this is overridden by MAC_MASQ)

MASQ_LAN=”” # the internal network(s) to be masqueraded (this is overridden by MAC_MASQ)

#!! 출발지 IP를 특정 IP로 마스커레이딩 할 경우.

#!! SNAT_LAN=”” # Internal networks/hosts to use static NAT (format is <internal ip or network>:<external ip>) (this is overridden by MAC_SNAT)

SNAT_LAN=”211.11.11.0/255.255.255.192:211.11.11.124″ # Internal networks/hosts to use static NAT (format is <internal ip or network>:<external ip>) (this is overridden by MAC_SNAT)

#!! 드롭시 행동

#!!DROP=”TREJECT” # What to do with packets we don’t want: DROP, REJECT, TREJECT (Reject with tcp-reset for TCP), LDROP (log and drop), LREJECT (log and reject), LTREJECT (log and reject with tcp-reset)

DROP=”LTREJECT” # What to do with packets we don’t want: DROP, REJECT, TREJECT (Reject with tcp-reset for TCP), LDROP (log and drop), LREJECT (log and reject), LTREJECT (log and reject with tcp-reset)

#!! DMZ에서 들어오는 패킷중 모두 거부할 호스트.

DENY_ALL=”” # Internet hosts to explicitly deny from accessing your system at all

#!! DMZ에서 들어오는 패킷중 TCP만 거부할 특정 호스트.

DENY_HOSTWISE_TCP=”” # Specific hosts to deny access to specific TCP ports; format is “IP>PORT”

#!! DMZ에서 들어오는 패킷중 UDP만 거부할 특정 호스트.

DENY_HOSTWISE_UDP=”” # Specific hosts to deny access to specific UDP ports; format is “IP>PORT”

#!! 이 주소로 들어오는 것에 대한 모든 패킷을 조용히 버린다.

BLACKHOLE=”” # People you don’t want to have anything to do with (equivlent of my old TK_DROP). This is a bidirectional drop.

BLACKHOLE_DROP=”DROP” # What to do for the blackholes (same options as DROP directive above)

#!! DMZ에서 들어오는 패킷중 TCP만 허용할 특정 호스트.

ALLOW_HOSTWISE_TCP=”” # Specific hosts allowed access to specific TCP ports; format is “IP>PORT”

#!! DMZ에서 들어오는 패킷중 UDP만 허용할 특정 호스트.

ALLOW_HOSTWISE_UDP=”” # Specific hosts allowed access to specific UDP ports; format is “IP>PORT”

ALLOW_OUT_TCP=”” # Internal hosts allowed to be forwarded out on TCP (internet censorship!) (do not put this/these host/s in INTERNAL_LAN, but do define their method of access [snat, masq] if not a public ip)

#!! 포트 포워딩 서비스

TCP_FW=”” # TCP port forwards, form is “SPORT:DPORT>IP”

UDP_FW=”” # UDP port forwards, form is “SPORT:DPORT>IP”

#!! 최적화 옵션

MANGLE_TOS_OPTIMIZE=”TRUE” # TOS Optimizations on or off (TRUE/FALSE toggle)

#!! 수정을 한 경우 Y로 세팅

#!! ENABLE=”N” # Set to ‘Y’ when it’s configured

ENABLE=”Y” # Set to ‘Y’ when it’s configured

# Only modify these if you have a genuine need, the defaults should be fine for a personal firewall

LOG_FLOOD=”2/s” # Limit on logging (for LTREJECT, LREJECT and LDROP, the packet will always take the policy regardless of logging)

SYN_FLOOD=”10/s” # GLOBAL limit on SYN packets (will probably need increased for a server since this matches ALL SYN packets)

PING_FLOOD=”1/s” # Limit on icmp-echo requests to reply to

# Below here is experimental (I can’t really test these so please report your successes/failures)

MAC_MASQ=”” # MAC addresses permitted to use masquerading, leave blank to not use

MAC_SNAT=”” # MAC addresses permitted to use static NAT, leave blank to not use (format is <MAC Address>:<external ip>)

TTL_SAFE=”” # How many hops packets need to make once they get on your LAN (null disables the mangling) (requires patch from patch-o-matic)

#!! 방화벽 인터페이스, 내부 인터페이스(LAN_IFACE=”eth1″)와 동일해선 안된다.

# Only touch these if you’re daring (PREALPHA stuff, as in basically non-functional)

DMZ_IFACE=”” # Interface your DMZ is on (leave blank if you don’t have one) MUST DEFINE LAN_IFACE IF YOU USE THIS!

# ———————————————————————-|

# Do not modify this |

# ———————————————————————-|

#!! INETIN : eth0(DMZ)에서 들어오는 체인.

#!! INETOUT : eth0(DMZ)으로 나가는 체인.

#!! DMZIN : eth1(내부)로 들어가는 체인.

#!! DMZOUT : eth1(내부)에서 나오는 체인.

#!! TCPACCEPT : 허용한 TCP에 대한 체인.

#!! UDPACCEPT : 허용한 UDP에 대한 체인.

#!! LDROP, LREJECT, TREJECT, LTREJECT : DROP에 관한 체인.

FILTER_CHAINS=”INETIN INETOUT DMZIN DMZOUT TCPACCEPT UDPACCEPT LDROP LREJECT TREJECT LTREJECT”

# ———————————————————————-|

# You shouldn’t need to modify anything below here |

# Main Script Starts |

# ———————————————————————-|

# Let’s load it!

echo “”

echo “—Loading iptables firewall…—”

# Configuration Sanity Checks

#!! iptables 실행 파일 검사.

echo “Checking configuration:”

if ! [ -x $IPTABLES ] ; then

echo “”

echo “ERROR IN CONFIGURATION: IPTABLES doesn’t exist or isn’t executable!”

exit 1

fi

#!! 인터페이스 동일 여부 검사. DMZ인터페이스와 LAN인터페이스는 동일해선 안된다.

if [ “$DMZ_IFACE” = “$LAN_IFACE” ] && [ “$LAN_IFACE” != “” ]; then

echo “”

echo “ERROR IN CONFIGURATION: DMZ_IFACE and LAN_IFACE can’t be the same!”

exit 1

fi

#!! DROP에 관한 정책 검사.

if [ “$DROP” = “” ] ; then

echo “”

echo “There needs to be a DROP policy (try TREJECT)!”

exit 1

fi

if [ “$DROP” = “ACCEPT” ] ; then

echo “”

echo “The DROP policy is set to ACCEPT; there is no point in loading the firewall as there wouldn’t be one.”

exit 2

fi

#!! 무조건 버릴 패킷에 관한 검사.

if [ “$BLACKHOLE” != “” ] && [ “$BLACKHOLE_DROP” = “” ] ; then

echo “”

echo “You can’t use blackholes and not have a policy for them!”

exit 1

fi

if ! [ “$ENABLE” = “Y” ] ; then

echo “”

echo “You need to edit your configuration and set ENABLE to Y!”

exit 99

fi

echo “passed”

# Turn on IP forwarding

#!! 포워딩을 하기 위해 설정.

echo -n “Checking IP Forwarding…”

if [ -e /proc/sys/net/ipv4/ip_forward ] ; then

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

echo “enabled.”

else

echo “support not found! This will probably cause problems!”

fi

# Enable TCP Syncookies

#!! TCP-SYN을 이용한 DOS공격을 예방하기 위해 설정.

echo -n “Checking IP SynCookies…”

if [ -e /proc/sys/net/ipv4/tcp_syncookies ] ; then

echo 1 > /proc/sys/net/ipv4/tcp_syncookies

echo “enabled.”

else

echo “support not found, but that’s OK.”

fi

# Enable Route Verification

echo -n “Checking Route Verification…”

if [ “$INET_IFACE” != “” ] ; then

if [ -e /proc/sys/net/ipv4/conf/$INET_IFACE/rp_filter ] ; then

echo 1 > /proc/sys/net/ipv4/conf/$INET_IFACE/rp_filter

echo -n “activated:${INET_IFACE} ”

else

echo “not found:${INET_IFACE} ”

fi

fi

if [ “$LAN_IFACE” != “” ] ; then

if [ -e /proc/sys/net/ipv4/conf/$LAN_IFACE/rp_filter ] ; then

echo 1 > /proc/sys/net/ipv4/conf/$LAN_IFACE/rp_filter

echo -n “activated:${LAN_IFACE} ”

else

echo “not found:${LAN_IFACE} ”

fi

fi

if [ “$DMZ_IFACE” != “” ] ; then

if [ -e /proc/sys/net/ipv4/conf/$DMZ_IFACE/rp_filter ] ; then

echo 1 > /proc/sys/net/ipv4/conf/$DMZ_IFACE/rp_filter

echo -n “activated:${DMZ_IFACE} ”

else

echo “not found:${DMZ_IFACE} ”

fi

fi

echo “”

# Flush everything

# If you need compatability, you can comment some or all of these out,

# but remember, if you re-run it, it’ll just add the new rules in, it

# won’t remove the old ones for you then, this is how it removes them.

#!! 일단 기존의 모든 정책을 깨끗하게 한다.

echo “Flush: ”

${IPTABLES} -t filter -F INPUT

echo -n “INPUT ”

${IPTABLES} -t filter -F OUTPUT

echo -n “OUTPUT1 ”

${IPTABLES} -t filter -F FORWARD

echo -n “FORWARD ”

${IPTABLES} -t nat -F PREROUTING

echo -n “PREROUTING1 ”

${IPTABLES} -t nat -F OUTPUT

echo -n “OUTPUT2 ”

${IPTABLES} -t nat -F POSTROUTING

echo -n “POSTROUTING ”

${IPTABLES} -t mangle -F PREROUTING

echo -n “PREROUTING2 ”

${IPTABLES} -t mangle -F OUTPUT

echo -n “OUTPUT3”

echo “”

# Create new chains

# Output to /dev/null in case they don’t exist from a previous invocation

#!! 위에서 정의한 새로운 체인을 만든다.

echo “Creating chains: ”

for chain in ${FILTER_CHAINS} ; do

${IPTABLES} -t filter -F ${chain} > /dev/null 2>&1

${IPTABLES} -t filter -X ${chain} > /dev/null 2>&1

${IPTABLES} -t filter -N ${chain}

echo -n “${chain} ”

done

echo “”

# Default Policies

# INPUT is still ACCEPT, the INETIN chain (defined above and jumped to later)

# is given a policy of DROP at the end

# Policy can’t be reject becuase of kernel limitations

#!! 기본 정책 수립.

echo “Default Policies: ”

${IPTABLES} -t filter -P INPUT ACCEPT

echo -n “INPUT:DROP ”

${IPTABLES} -t filter -P OUTPUT ACCEPT

echo -n “OUTPUT:ACCEPT ”

${IPTABLES} -t filter -P FORWARD DROP

echo -n “FORWARD:DROP ”

echo “”

# Local traffic to internet or crossing subnets

# This should cover what we need if we don’t use masquerading

# Unfortunately, MAC address matching isn’t bidirectional (for

# obvious reasons), so IP based matching is done here

echo “—Set Iptables…—”

if [ “$INTERNAL_LAN” != “” ] ; then

echo -n “Local Traffic Rules: ”

for subnet in ${INTERNAL_LAN} ; do

#!! ${IPTABLES} -t filter -A FORWARD -s ${subnet} -j ACCEPT

#!! ${IPTABLES} -t filter -A FORWARD -d ${subnet} -j ACCEPT

#!! ${IPTABLES} -t filter -A INPUT -s ${subnet} -j ACCEPT

#!! 본인의 환경에 맞게 변경한다.

#!! DMZ에서 들어오는 패킷중 시작주소가 내부주소이면 spoofing 이므로 걸러낸다.

${IPTABLES} -t filter -A FORWARD -s ${subnet} -i ${INET_IFACE} -j ${DROP}

${IPTABLES} -t filter -A FORWARD -s ${INET_IFACE_IP} -i ${INET_IFACE} -j ${DROP}

${IPTABLES} -t filter -A FORWARD -s ${LAN_IFACE_IP} -i ${INET_IFACE} -j ${DROP}

${IPTABLES} -t filter -A FORWARD -s ${subnet} -i ${LAN_IFACE} -j ACCEPT

${IPTABLES} -t filter -A FORWARD -d ${subnet} -i ${INET_IFACE} -p tcp –syn –dport 44000:45000 -j ACCEPT # irc-dcc

${IPTABLES} -t filter -A FORWARD -d ${subnet} -i ${INET_IFACE} -p tcp –syn –dport 6891:6901 -j ACCEPT # msn-dcc

#!! syn 패킷은 거부한다.

${IPTABLES} -t filter -A FORWARD -d ${subnet} -i ${INET_IFACE} -p tcp –syn -j ${DROP}

${IPTABLES} -t filter -A FORWARD -d ${subnet} -i ${INET_IFACE} -m state –state INVALID -j ${DROP}

${IPTABLES} -t filter -A FORWARD -d ${subnet} -i ${INET_IFACE} -p tcp ! –syn -j ACCEPT

${IPTABLES} -t filter -A FORWARD -d ${subnet} -i ${INET_IFACE} -m state –state ESTABLISHED -j ACCEPT

${IPTABLES} -t filter -A FORWARD -d ${subnet} -i ${INET_IFACE} -m state –state RELATED -j ACCEPT

#!! spoofing 예방.

${IPTABLES} -t filter -A INPUT -s ${subnet} -i ${INET_IFACE} -j ${DROP}

${IPTABLES} -t filter -A INPUT -s ${INET_IFACE_IP} -i ${INET_IFACE} -j ${DROP}

${IPTABLES} -t filter -A INPUT -s ${LAN_IFACE_IP} -i ${INET_IFACE} -j ${DROP}

${IPTABLES} -t filter -A INPUT -s ${subnet} -i ${LAN_IFACE} -j ACCEPT

#!! syn 패킷은 거부한다.

${IPTABLES} -t filter -A INPUT -d ${subnet} -i ${INET_IFACE} -p tcp –syn -j ${DROP}

${IPTABLES} -t filter -A INPUT -d ${subnet} -i ${INET_IFACE} -m state –state NEW -j ${DROP}

${IPTABLES} -t filter -A INPUT -d ${subnet} -i ${INET_IFACE} -m state –state INVALID -j ${DROP}

${IPTABLES} -t filter -A INPUT -d ${subnet} -i ${INET_IFACE} -p tcp ! –syn -j ACCEPT

${IPTABLES} -t filter -A INPUT -d ${subnet} -i ${INET_IFACE} -m state –state ESTABLISHED -j ACCEPT

${IPTABLES} -t filter -A INPUT -d ${subnet} -i ${INET_IFACE} -m state –state RELATED -j ACCEPT

echo -n “${subnet}:ACCEPT ”

done

echo

fi

#!!

if [ “$ALLOW_OUT_TCP” != “” ] ; then

echo -n “Internet censorship TCP allows: ”

for rule in ${ALLOW_OUT_TCP} ; do

echo “$rule” | {

IFS=’:’ read intip destip

${IPTABLES} -t filter -A FORWARD -s ${intip} -d ${destip} -o ${INET_IFACE} -j ACCEPT

${IPTABLES} -t filter -A FORWARD -d ${intip} -s ${destip} -i ${INET_IFACE} -j ACCEPT

echo -n “${intip}:${destip} ”

}

done

echo

fi

# Set up basic NAT if the user wants it

#!! 인터넷으로 나가는 패킷중 masquerading 할 것들에 대한 처리.

if [ “$MASQ_LAN” != “” ] ; then

echo -n “Setting up masquerading: ”

if [ “$MAC_MASQ” = “” ] ; then

for subnet in ${MASQ_LAN} ; do

${IPTABLES} -t nat -A POSTROUTING -s ${subnet} -o ${INET_IFACE} -j MASQUERADE

echo -n “${subnet}:MASQUERADE ”

done

else

for address in ${MAC_MASQ} ; do

${IPTABLES} -t nat -A POSTROUTING -m mac –mac-source ${address} -o ${INET_IFACE} -j MASQUERADE

echo -n “${address}:MASQUERADE ”

done

fi

echo

fi

#!! 인터넷으로 나가는 패킷중 static nat 할 것들에 대한 처리.

if [ “$SNAT_LAN” != “” ] ; then #Static NAT used

echo -n “Setting up static NAT: ”

if [ “$MAC_SNAT” = “” ] ; then

for rule in ${SNAT_LAN} ; do

echo “$rule” | {

IFS=’:’ read host destip

${IPTABLES} -t nat -A POSTROUTING -s ${host} -o ${INET_IFACE} -j SNAT –to-source ${destip}

echo -n “${subnet}:SNAT ”

}

done

else

for rule in ${MAC_SNAT} ; do

echo “$rule” | {

IFS=’:’ read address destip

${IPTABLES} -t nat -A POSTROUTING -m mac –mac-source ${address} -o ${INET_IFACE} -j SNAT –to-source ${destip}

echo -n “${address}:SNAT ”

}

done

fi

echo

fi

# TCP Port-Forwards

#!! 포트 포워딩할 것들에 대한 처리.

if [ “$TCP_FW” != “” ] ; then

echo -n “TCP Port Forwards: ”

for rule in ${TCP_FW} ; do

echo “$rule” | {

IFS=’:>’ read srcport destport host

${IPTABLES} -t nat -A PREROUTING -p tcp -i ${INET_IFACE} –dport ${srcport} -j DNAT –to-destination ${host}:${destport}

${IPTABLES} -t filter -A FORWARD -p tcp -d ${host} –dport ${destport} -j ACCEPT

echo -n “${rule} ”

}

done

echo

fi

#!! SNAT를 적용했기 때문에 이에 대한 처리를 해야 한다.

#!!

#!! 포트별 서비스

#!! 51200:51201(udp),51210(tcp)=다이얼패드, 9001:9004(udp)=소리바다, 4000-5000=irc-dcc, 6901(tcp)=msn, 6891:6900(tcp)=msn-dcc

#!!

#!! 51210(tcp) 51200-51201(udp) : 다이얼패드(prerouting, 모든 client에 동일 port 할당)

#!! 9000-9999(udp) : 소리바다(prerouting, … port 4개씩 할당)

#!! 44000-45000(udp/tcp) : irc-dcc(prerouting output, …)(Max remotely requested dcc Sends 의 갯수를 잘 보고 포트의 범위를 정해야한다. 모자랄 경우 파일이 깨진다.)

#!! 6901(tcp) : msn, 6891:6900(tcp) : msn-dcc

#!!

#!! 현재 다이얼패드를 사용하는 내부 사용자는 없으므로 비활성화 함.

#!! ${IPTABLES} -t nat -A PREROUTING -p tcp -i ${INET_IFACE} –dport 51210 -j DNAT –to-destination 211.11.11.1-211.11.11.59:51210

#!! IRC를 이용하는 내부사용자가 여러명인 경우…

#!! ${IPTABLES} -t nat -A PREROUTING -p tcp -i ${INET_IFACE} –dport 44000:45000 -j DNAT –to-destination 211.11.11.1-211.11.131.59:44000-45000

#!! 현재 IRC를 이용하는 내부 사용자는 한명뿐이기 때문에…

${IPTABLES} -t nat -A PREROUTING -p tcp -i ${INET_IFACE} –dport 44000:45000 -j DNAT –to-destination 211.11.11.51:44000-45000

#!! MSN-DCC를 위한 설정.—> 그러나 MSN-DCC는 제대로 작동하지 않았당 -,.-?;;;

${IPTABLES} -t nat -A PREROUTING -p tcp -i ${INET_IFACE} –dport 6891:6901 -j DNAT –to-destination 211.11.11.1-211.11.11.59:6891-6901

#UDP Port Forwards

if [ “$UDP_FW” != “” ] ; then

echo -n “UDP Port Forwards: ”

for rule in ${UDP_FW} ; do

echo “$rule” | {

IFS=’:>’ read srcport destport host

${IPTABLES} -t nat -A PREROUTING -p udp -i ${INET_IFACE} –dport ${srcport} -j DNAT –to-destination ${host}:${destport}

${IPTABLES} -t filter -A FORWARD -p udp -d ${host} –dport ${destport} -j ACCEPT

echo -n “${rule} ”

}

done

echo

fi

#!! SNAT를 적용했기 때문에 이에 대한 처리를 해야 한다.

#!!

#!! 포트별 서비스

#!! 51200:51201(udp),51210(tcp)=다이얼패드, 9001:9004(udp)=소리바다, 4000-5000=irc-dcc, 6901(tcp)=msn, 6891:6900(tcp)=msn-dcc

#!!

#!! 51210(tcp) 51200-51201(udp) : 다이얼패드(prerouting, 모든 client에 동일 port 할당)

#!! 9000-9999(udp) : 소리바다(prerouting, … port 4개씩 할당)

#!! 44000-45000(udp/tcp) : irc-dcc(prerouting output, …)(Max remotely requested dcc Sends 의 갯수를 잘 보고 포트의 범위를 정해야한다. 모자랄 경우 파일이 깨진다.)

#!! 6901(tcp) : msn, 6891:6900(tcp) : msn-dcc

#!!

#!! 현재 다이얼패드를 사용하는 내부 사용자는 없으므로 비활성화 함.

#!! ${IPTABLES} -t nat -A PREROUTING -p udp -i ${INET_IFACE} –dport 51200:51201 -j DNAT –to-destination 211.11.11.1-211.104.131.59:51200-51201

#!! 소리바다를 위한 설정.

${IPTABLES} -t nat -A PREROUTING -p udp -i ${INET_IFACE} –dport 9001:9004 -j DNAT –to-destination 211.11.11.1-211.11.131.59:9001-9004

#!! IRC-DCC를 위한 설정.

${IPTABLES} -t nat -A PREROUTING -p udp -i ${INET_IFACE} –dport 44000:45000 -j DNAT –to-destination 211.11.11.51:44000-45000

#!! MSN-DCC를 위한 설정.

${IPTABLES} -t nat -A PREROUTING -p udp -i ${INET_IFACE} –dport 6891:6900 -j DNAT –to-destination 211.11.11.1-211.11.11.59:6891-6900

# ===============================================

# ——-Chain setup before jumping to them——

# ===============================================

# Set up INET chains

echo -n “Setting up INET chains: ”

${IPTABLES} -t filter -A INPUT -i ${INET_IFACE} -j INETIN

echo -n “INETIN ”

${IPTABLES} -t filter -A OUTPUT -o ${INET_IFACE} -j INETOUT

echo -n “INETOUT ”

echo

# For now we’ll subject the DMZ to the same rules as the internet when going onto the trusted LAN

# And we’ll let it go anywhere on the internet

#!! 현재 DMZ로 나가는 패킷은 인터넷에서 들어오는 패킷과 동일한 규칙 적용.

#!! 현재 DMZ에서 들어오는 패킷은 무엇이든 허용함.

if [ “$DMZ_IFACE” != “” ] ; then

echo -n “Setting up DMZ Chains: ”

${IPTABLES} -A OUTPUT -o ${DMZ_IFACE} -j DMZOUT

echo -n “DMZOUT ”

${IPTABLES} -A INPUT -i ${DMZ_IFACE} -j DMZIN

echo -n “DMZIN ”

echo

echo -n “DMZ for LAN Forwarding to INETIN…”

${IPTABLES} -A DMZOUT -o ${LAN_IFACE} -j INETIN

echo “done”

echo -n “DMZ for Internet Forwarding to INETOUT…”

${IPTABLES} -A DMZOUT -o ${INET_IFACE} -j INETOUT

echo -n “done”

fi

#These logging chains are valid to specify in DROP= above

#Set up LDROP

echo -n “Setting up drop chains chains: ”

${IPTABLES} -t filter -A LDROP -p tcp -m limit –limit ${LOG_FLOOD} -j LOG –log-level info –log-prefix “TCP Dropped ”

${IPTABLES} -t filter -A LDROP -p udp -m limit –limit ${LOG_FLOOD} -j LOG –log-level info –log-prefix “UDP Dropped ”

${IPTABLES} -t filter -A LDROP -p icmp -m limit –limit ${LOG_FLOOD} -j LOG –log-level info –log-prefix “ICMP Dropped ”

${IPTABLES} -t filter -A LDROP -f -m limit –limit ${LOG_FLOOD} -j LOG –log-level warning –log-prefix “FRAGMENT Dropped ”

${IPTABLES} -t filter -A LDROP -j DROP

echo -n “LDROP ”

#And LREJECT too

${IPTABLES} -t filter -A LREJECT -p tcp -m limit –limit ${LOG_FLOOD} -j LOG –log-level info –log-prefix “TCP Rejected ”

${IPTABLES} -t filter -A LREJECT -p udp -m limit –limit ${LOG_FLOOD} -j LOG –log-level info –log-prefix “UDP Rejected ”

${IPTABLES} -t filter -A LREJECT -p icmp -m limit –limit ${LOG_FLOOD} -j LOG –log-level info –log-prefix “ICMP Dropped ”

${IPTABLES} -t filter -A LREJECT -f -m limit –limit ${LOG_FLOOD} -j LOG –log-level warning –log-prefix “FRAGMENT Rejected ”

${IPTABLES} -t filter -A LREJECT -j REJECT

echo -n “LREJECT ”

#Don’t forget TREJECT

${IPTABLES} -t filter -A TREJECT -p tcp -j REJECT –reject-with tcp-reset

${IPTABLES} -t filter -A TREJECT -p ! tcp -j REJECT –reject-with icmp-port-unreachable

${IPTABLES} -t filter -A TREJECT -j REJECT

echo -n “TREJECT ”

#And LTREJECT

${IPTABLES} -t filter -A LTREJECT -p tcp -m limit –limit ${LOG_FLOOD} -j LOG –log-level info –log-prefix “TCP Rejected ”

${IPTABLES} -t filter -A LTREJECT -p udp -m limit –limit ${LOG_FLOOD} -j LOG –log-level info –log-prefix “UDP Rejected ”

${IPTABLES} -t filter -A LTREJECT -p icmp -m limit –limit ${LOG_FLOOD} -j LOG –log-level info –log-prefix “ICMP Dropped ”

${IPTABLES} -t filter -A LTREJECT -f -m limit –limit ${LOG_FLOOD} -j LOG –log-level warning –log-prefix “FRAGMENT Rejected ”

${IPTABLES} -t filter -A LTREJECT -p tcp -j REJECT –reject-with tcp-reset

${IPTABLES} -t filter -A LTREJECT -p ! tcp -j REJECT –reject-with icmp-port-unreachable

${IPTABLES} -t filter -A LTREJECT -j REJECT

echo -n “LTREJECT ”

#newline

echo

# Set up the per-proto ACCEPT chains

#!! 허용한 TCP와 UDP에 대한 최종 세팅 부분임. 허용된 모든 TCP와 UDP는 마지막으로 이체인을 통과함.

echo -n “Setting up per-proto ACCEPT: ”

# TCPACCEPT

# SYN Flood Protection

${IPTABLES} -t filter -A TCPACCEPT -p tcp –syn -m limit –limit ${SYN_FLOOD} -j ACCEPT

${IPTABLES} -t filter -A TCPACCEPT -p tcp –syn -m limit –limit ${LOG_FLOOD} -j LOG –log-prefix “Possible SynFlood ”

${IPTABLES} -t filter -A TCPACCEPT -p tcp –syn -j ${DROP}

${IPTABLES} -t filter -A TCPACCEPT -p tcp ! –syn -j ACCEPT

# Log anything that hasn’t matched yet and ${DROP} it since it isn’t TCP and shouldn’t be here

${IPTABLES} -t filter -A TCPACCEPT -m limit –limit ${LOG_FLOOD} -j LOG –log-prefix “Mismatch in TCPACCEPT ”

${IPTABLES} -t filter -A TCPACCEPT -j ${DROP}

echo -n “TCPACCEPT ”

# UDPACCEPT

${IPTABLES} -t filter -A UDPACCEPT -p udp -j ACCEPT

# Log anything not UDP and ${DROP} it since it’s not supposed to be here

${IPTABLES} -t filter -A UDPACCEPT -m limit –limit ${LOG_FLOOD} -j LOG –log-prefix “Mismatch on UDPACCEPT ”

${IPTABLES} -t filter -A UDPACCEPT -j ${DROP}

echo -n “UDPACCEPT ”

#Done

echo

# ————————————————-

# ==================TTL Mangling===================

# ————————————————-

if [ “$TTL_SAFE” != “” ] ; then

${IPTABLES} -t mangle -A PREROUTING -i ${INET_IFACE} -j TTL –ttl-set ${TTL_SAFE}

fi

# ————————————————-

# ================EXPLICIT DENIES==================

# ————————————————-

if [ “$DENY_ALL” != “” ] ; then

echo -n “Denying hosts: ”

for host in ${DENY_ALL} ; do

${IPTABLES} -t filter -A INETIN -s ${host} -j ${DROP}

echo -n “${host}:${DROP}”

done

echo

fi

if [ “$DENY_HOSTWISE_TCP” != “” ] ; then

echo -n “Hostwise TCP Denies: ”

for rule in ${DENY_HOSTWISE_TCP} ; do

echo “$rule” | {

IFS=’>’ read host port

${IPTABLES} -t filter -A INETIN -p tcp -s ${host} –dport ${port} -j ${DROP}

echo -n “${rule} ”

}

done

echo

fi

if [ “$DENY_HOSTWISE_UDP” != “” ] ; then

echo -n “Hostwise UDP Denies: ”

for rule in ${DENY_HOSTWISE_UDP} ; do

echo “$rule” | {

IFS=’>’ read host port

${IPTABLES} -t filter -A INETIN -p udp -s ${host} –dport ${port} -j ${DROP}

echo -n “${rule} ”

}

done

echo

fi

if [ “$BLACKHOLE” != “” ] ; then

echo -n “Blackholes: ”

for host in ${BLACKHOLE} ; do

${IPTABLES} -t filter -A INPUT -s ${host} -j ${BLACKHOLE_DROP}

${IPTABLES} -t filter -A OUTPUT -d ${host} -j ${BLACKHOLE_DROP}

echo -n “${host} ”

done

echo

fi

#Invalid packets are always annoying

echo -n “${DROP}ing invalid packets…”

${IPTABLES} -t filter -A INETIN -m state –state INVALID -j ${DROP}

echo “done”

# ================================================================

# ————Allow stuff we have chosen to allow in————–

# ================================================================

# Flood “security”

# You’ll still respond to these if they comply with the limits

# Default limits are 1/sec for ICMP pings

# SYN Flood is on a per-port basis because it’s a security hole to put it here!

# This is just a packet limit, you still get the packets on the interface and

# still may experience lag if the flood is heavy enough

echo -n “Flood limiting: ”

# Ping Floods (ICMP echo-request)

${IPTABLES} -t filter -A INETIN -p icmp –icmp-type echo-request -m limit –limit ${PING_FLOOD} -j ACCEPT

echo -n “ICMP-PING ”

echo

echo -n “Allowing the rest of the ICMP messages in…”

${IPTABLES} -t filter -A INETIN -p icmp –icmp-type ! echo-request -j ACCEPT

echo -n “done”

#!! 인터넷에서 들어오는 TCP 패킷 중 허용된 것.

if [ “$TCP_ALLOW” != “” ] ; then

echo -n “TCP Input Allow: ”

for port in ${TCP_ALLOW} ; do

${IPTABLES} -t filter -A INETIN -p tcp –dport ${port} -j TCPACCEPT

echo -n “${port} ”

done

echo

fi

#!! 인터넷에서 들어오는 UDP 패킷 중 허용된 것.

if [ “$UDP_ALLOW” != “” ] ; then

echo -n “UDP Input Allow: ”

for port in ${UDP_ALLOW} ; do

${IPTABLES} -t filter -A INETIN -p udp –dport ${port} -j UDPACCEPT

echo -n “${port} ”

done

echo

fi

# Hostwise allows

#!! 인터넷에서 들어오는 TCP 패킷 중 특정호스트에 허용된 것.

if [ “$ALLOW_HOSTWISE_TCP” != “” ] ; then

echo -n “Hostwise TCP Allows: ”

for rule in ${ALLOW_HOSTWISE_TCP} ; do

echo “$rule” | {

IFS=’>’ read host port

${IPTABLES} -t filter -A INETIN -p tcp -s ${host} –dport ${port} -j ACCEPT

echo -n “${rule} ”

}

done

echo

fi

#!! 인터넷에서 들어오는 UDP 패킷 중 특정호스트에 허용된 것.

if [ “$ALLOW_HOSTWISE_UDP” != “” ] ; then

echo -n “Hostwise UDP Allows: ”

for rule in ${ALLOW_HOSTWISE_UDP} ; do

echo “$rule” | {

IFS=’>’ read host port

${IPTABLES} -t filter -A INETIN -p udp -s ${host} –dport ${port} -j ACCEPT

echo -n “${rule} ”

}

done

echo

fi

echo -n “Allowing established outbound connections back in…”

#!! 인터넷에서 들어오는 패킷중 이미 연결이 성립된 것에 대해서는 허용함.

${IPTABLES} -t filter -A INETIN -m state –state ESTABLISHED -j ACCEPT

echo “done”

# RELATED on high ports only for security (only winbloze would be stupid enough to use privilaged ports for this)

echo -n “Allowing related inbound connections…”

#!! 인터넷에서 들어오는 패킷중 이미 연결이 성립되었고 기존의 연결과 연관된 것에 대해서는 허용함.

${IPTABLES} -t filter -A INETIN -p tcp –dport 1024:65535 -m state –state RELATED -j TCPACCEPT

${IPTABLES} -t filter -A INETIN -p udp –dport 1024:65535 -m state –state RELATED -j UDPACCEPT

echo “done”

# Type of Service mangle optimizations (the ACTIVE FTP one will only work for uploads)

#!! 성능 향상을 위한 부분.

#!! 텔넷(23), ssh(22)등은 최소 지연. ftp(21, 20(data)) 등은 최대 성능.

#!! TOS target v1.1.2 options:

#!! –set-tos value Set Type of Service field to one of the

#!! following numeric or descriptive values:

#!! Minimize-Delay 16 (0x10)

#!! Maximize-Throughput 8 (0x08)

#!! Maximize-Reliability 4 (0x04)

#!! Minimize-Cost 2 (0x02)

#!! Normal-Service 0 (0x00)

if [ “$MANGLE_TOS_OPTIMIZE” = “TRUE” ] ; then

echo -n “Optimizing traffic: ”

${IPTABLES} -t mangle -A OUTPUT -p tcp –dport 23 -j TOS –set-tos Minimize-Delay

echo -n “telnet ”

${IPTABLES} -t mangle -A OUTPUT -p tcp –dport 22 -j TOS –set-tos Minimize-Delay

echo -n “ssh ”

${IPTABLES} -t mangle -A OUTPUT -p tcp –dport 20 -j TOS –set-tos Minimize-Cost

echo -n “ftp-data ”

${IPTABLES} -t mangle -A OUTPUT -p tcp –dport 21 -j TOS –set-tos Minimize-Delay

echo -n “ftp-control ”

${IPTABLES} -t mangle -A OUTPUT -p udp –dport 4000:7000 -j TOS –set-tos Minimize-Delay

echo -n “diablo2 ”

echo

fi

#What to do on those INET chains when we hit the end

echo -n “Setting up INET policies: ”

#Drop if we cant find a valid inbound rule.

${IPTABLES} -t filter -A INETIN -j ${DROP}

echo -n “INETIN:${DROP} ”

#We can send what we want to the internet

${IPTABLES} -t filter -A INETOUT -j ACCEPT

echo -n “INETOUT:ACCEPT ”

echo

#All done!

echo “—Done loading the firewall!—”

echo “”

————————————————————————–

여기까지 입니다. 상당히 긴 스크립트 파일입니다.

저의 경우 bluezone firewall 서버에서는 서비스를 제공하지 않습니다. 또한 내부

내트웍은 SNAT를 적용했으며 소리바다, 다이얼패드, ICQ, IRC, MSN 등을 지원하기

위해 노력했습니다. 허나 불행히도 MSN의 파일 보내기가 안되는군요. 파일 받기는

잘 작동할 것입니다. 혹 이거 해결하시면 저에게도 꼭 좀 알려주시기 바랍니다.

소리바다, 다이얼패드, 메신저에 대한 코드는 이미 여러분들께서 웹에 공개한

코드를 제가 조금 수정한 것입니다. 코드를 올려주신 분들께 감사드립니다.

아래는 firewall하에서 서비스가 원할하게 이루어지도록 사무실 내부의 랜 사용자들이

반드시 설정해 주셔야 할 부분입니다.

<소리바다>

소리바다는 파일 주고 받기에 연속된 특정 포트 4개를 이용합니다.

9001, 9002, 9003, 9004 식으로…

포트 넘버는 사용자마다 각각 다르게 설정되어야 하고 물론 firewall에서도 해당

포트에 대한 처리를 해줘야 합니다.

소리바다를 실행하시고 Option창에서 해당 포트 번호를 설정하시고, ‘랜덤 포트

사용’을 disable로 설정하시면 됩니다.

<다이얼 패드>

다이얼 패드는 firewall 서버에서의 설정만으로도 잘 작동될 것입니다.

개인적으로 설정할 사항은 없습니다.

<메신저 이용하기>

모든 메신저의 채팅모드는 기본설정만으로도 가능합니다.

문제는 메신저의 부가기능 중 하나인 파일 주고 받기 기능입니다.

1. IRC

테스트한 IRC클라이언트중 xircon는 작동하지 않았으며 mirc는 잘 작동했습니다.

물론 채팅 기능은 잘 작동합니다.

IRC-DCC를 이용해 파일 주고 받기를 하는 경우 Option 메뉴의 DCC 세팅창에서

포트 번호를 44000-45000 식으로 설정 합니다.

2. ICQ

채팅 기능은 잘 작동합니다.

파일 주고 받기를 하는 경우 Prefernece 설정창에서

1) connection탭 -> General -> connetion type -> permanent

2) connection탭 -> General -> Firewall IP setting -> always use internal IP

3) connection탭 -> Server -> proxy setting -> using firewall -> not using proxy

4) Security & Privacy 탭 -> Direct connection -> allow direct connection with user listed on your connection list

위의 네가지를 설정해 주면 파일 주고 받기도 잘 작동할 것입니다.

3. MSN

채팅 기능은 잘 작동합니다.

MSN-DCC를 이용한 파일 받기 기능은 잘 작동합니다.

MSN-DCC를 이용한 파일 보내기 기능은 작동하지 않습니다.

아직까지 파일 보내기에 대한 부분은 해결되지 않았습니다. 앞으로도 해결되지

않을 가능성을 높습니다.

MSN의 공식 입장은 “방화벽 내부에서 파일 주고 받기가 안될 수도 있다”

입니다.-,.-;;;

요렇게 조렇게 하면 될지도 모른다…는 말은 어디에서도 찾아볼 수 없었습니다.

그 외의 메신저는 테스트 해보지 않았습니다.

<FTP 이용에 관하여>

방화벽 내부에서 FTP를 이용하기 위해서는 PASSIVE MODE 로 설정을 해야 합니다.

syn 패킷은 거부되기 때문에 반드시 pass mode로 해야 합니다.

cuteftp, wsftp 등의 프로그램 Option 창에서 passive mode, 또는 pass mode라고

된 부분을 enable로 해야만 방화벽 내부에서 ftp를 이용할 수 있습니다.

[5] 사무실 내부 환경

사무실 내부 PC들의 설정은 아래와 같습니다.

OS : win nt, 2000, me, MAC, linux …

Gateway : 211.104.131.62

Network : 211.104.131.0

Subnet mask : 255.255.255.192

[6] 마치며

코드를 포함하다보니 상당히 긴 글이 되었네요. 처음 작성해보는 방화벽 코드

이다보니 상당한 논리적 오류가 있을 수 있으며 좀 더 명확한 표현을 위해 간혹

중복되는 코드도 있습니다. 그저 참고정도만 하시고 개인의 환경에 맞게 잘

커스터마이징해서 사용하셔야 할 것입니다.

더 자세히 공부해 보고 싶으신 분들께 다음의 책을 권해드립니다.

출판사 : O’reilly

제목 : TCP/IP 네트워크 관리,

인터넷 방화벽 구축하기(번역이 쫌 이상한듯하지만…^^;)

서진우

슈퍼컴퓨팅 전문 기업 클루닉스/ 상무(기술이사)/ 정보시스템감리사/ 시스존 블로그 운영자

You may also like...

1 Response

  1. 2022년 2월 4일

    charles town races

페이스북/트위트/구글 계정으로 댓글 가능합니다.