ファイアウォールの作成

iptablesスクリプト作成

習うより慣れろ・・・ということで、実際のiptablesの設定を見ていただきたいと思います。iptablesの設定は、特に設定ファイル書く
というよりは、shellスクリプトを書いて、実行させ、それをiptablesに記憶させるという方法をとります。以下は、そのshellスクリプトで
す。途中、for文などですっきりさせたつもりですが、不都合などございましたらご連絡ください。

#!/bin/bash

##########################################################################
# 変数の設定
##########################################################################
LAN_PORT=eth2
LAN_NET="192.168.20.0/24"
LAN_BASE="192.168.20.0"
LAN_BCAST="192.168.20.255"
LAN_IP="192.168.20.1"

DMZ_PORT=eth1
DMZ_NET="192.168.10.0/24"
DMZ_BASE="192.168.10.0"
DMZ_BCAST="192.168.10.255"
DMZ_SVR="192.168.10.2"
DMZ_IP="192.168.0.1"

WAN_PORT=ppp0
WAN_IP="218.45.162.31"

IPTABLES="/sbin/iptables"
MODPROBE="/sbin/modprobe"

# 通信すべきでないホストとネットワークのIPアドレス
SHUN=""

# ありえなさそうなIPアドレス
BADIP="$DMZ_BCAST $DMZ_BASE $LAN_BASE $LAN_BCAST 0.0.0.0/8 \
10.0.0.0/8 127.0.0.0/8 169.254.0.0/16 172.16.0.0/12 224.0.0.0/4 \
240.0.0.0/5 255.255.255.255"

#ログの出力のタイミング
LOGOPT="--log-level=3 -m limit --limit 3/minute --limit-burst 3"
#SYNFLOODと扱うしきい値
SYNOPT="-m limit --limit 10/second --limit-burst 20"
#pingを許可するネットワーク
PING="192.168.10.0/24 192.168.20.0/24"
##########################################################################
# モジュールの読み込み、カーネル動作の設定
##########################################################################
$MODPROBE ip_tables
$MODPROBE iptable_filter
$MODPROBE ip_conntrack
$MODPROBE iptable_nat
$MODPROBE ip_nat_ftp
$MODPROBE ip_conntrack_ftp
$MODPROBE ipt_state
$MODPROBE ipt_MASQUERADE
$MODPROBE ipt_LOG
$MODPROBE ipt_REJECT
$MODPROBE ipt_limit
# IPマスカレード許可
echo 1 > /proc/sys/net/ipv4/ip_forward
# pingのブロード/マルチキャストを無視
echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
# ソースアドレスの妥当性検査
for f in /proc/sys/net/ipv4/conf/*/rp_filter; do echo 1 > $f; done
# ありえないアドレスをログに記録
for f in /proc/sys/net/ipv4/conf/*/log_martians; do echo "1" > $f; done
# ICMP redirect messageを無視
for f in /proc/sys/net/ipv4/conf/*/accept_redirects; do echo 1 > $f; done
# SYN FLOOD攻撃対策
echo 1 > /proc/sys/net/ipv4/tcp_syncookies
# Smurf攻撃対策
echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts

##########################################################################
# DMZで公開するポート
##########################################################################

DMZ_SVC_TCP="ssh smtp domain http pop3"

DMZ_SVC_UDP="domain"

##########################################################################
# 既存のファイアウォールルールをクリアする
##########################################################################

if [ ! -x $IPTABLES ]
then
echo "firewall: can't execute $IPTABLES"
fi

$IPTABLES -P INPUT   DROP # デフォルトポリシーはDROP
$IPTABLES -P OUTPUT  DROP # デフォルトポリシーはDROP
$IPTABLES -P FORWARD DROP # デフォルトポリシーはDROP
$IPTABLES -F   # すべてのチェインをフラッシュ
$IPTABLES -X   # すべてのチェインをフラッシュ

#すべてのテーブルでルール、チェイン、カウンタをクリアする
for table in filter nat mangle
do
$IPTABLES -t $table -F  # ルールの削除
$IPTABLES -t $table -X  # チェインの削除
$IPTABLES -t $table -Z  # カウンタのクリア
done


##########################################################################
#ユーザ定義のチェイン。プログラムで言うところの自作した関数。
##########################################################################

#-------------------------------------------------------------------------
# BAD_IPチェイン。望ましくないIPのものはログを残して破棄。
#-------------------------------------------------------------------------

$IPTABLES -N BAD_IP
$IPTABLES -A BAD_IP -j LOG --log-prefix "IPTABLES BAD_IP: " $LOGOPT
$IPTABLES -A BAD_IP -j DROP

#-------------------------------------------------------------------------
# SHUNチェイン。敵対ホストのIPアドレスならBAD_IPチェインに渡す。
#-------------------------------------------------------------------------

$IPTABLES -N SHUN
for ip in $SHUN
do
$IPTABLES -A SHUN -s $ip -j BAD_IP
$IPTABLES -A SHUN -d $ip -j BAD_IP
done
#-------------------------------------------------------------------------
# IN_IP_CHECKチェイン。送信元IPアドレスがありえないものなら
# BAD_IPチェインに渡す
#-------------------------------------------------------------------------

$IPTABLES -N IN_IP_CHECK

#送信元IPアドレスが変数 BADIP にあるものならBAD_IPチエインに渡す
for sip in $BADIP
do
$IPTABLES -A IN_IP_CHECK -s $sip -j BAD_IP
done

#それぞれのポートから入るパケットで、ありえない送信元IPアドレスなら、
#BAD_IPチエインへ
$IPTABLES -A IN_IP_CHECK -i $WAN_PORT -s $DMZ_NET -j BAD_IP
$IPTABLES -A IN_IP_CHECK -i $WAN_PORT -s $LAN_NET -j BAD_IP
$IPTABLES -A IN_IP_CHECK -i $DMZ_PORT -s $WAN_IP  -j BAD_IP
$IPTABLES -A IN_IP_CHECK -i $DMZ_PORT -s $LAN_IP  -j BAD_IP
$IPTABLES -A IN_IP_CHECK -i $LAN_PORT -s $WAN_IP  -j BAD_IP
$IPTABLES -A IN_IP_CHECK -i $LAN_PORT -s $DMZ_NET -j BAD_IP

#------------------------------------------------------------------------
# OUT_IP_CHECKチェイン。送信先、送信元IPアドレスが正しくなければ
# BAD_IPチエインに渡す
#------------------------------------------------------------------------

$IPTABLES -N OUT_IP_CHECK

#送信先IPアドレスが変数 BADIP にあるものならBAD_IPチェインに渡す
for dip in $BADIP
do
$IPTABLES -A OUT_IP_CHECK -d $dip -j BAD_IP
done

#それぞれのポートから出るパケットで、送信元IPが正しければこのチェインは通過。
#正しくなければBAD_IPチェインに渡す
$IPTABLES -A OUT_IP_CHECK -o $WAN_PORT -s $WAN_IP  -j RETURN
$IPTABLES -A OUT_IP_CHECK -o $LAN_PORT -s $LAN_NET  -j RETURN
$IPTABLES -A OUT_IP_CHECK -o $DMZ_PORT -s $DMZ_NET  -j RETURN
$IPTABLES -A OUT_IP_CHECK -j BAD_IP


#------------------------------------------------------------------------
# CHKMSNETチェイン。Microsoftネットワーク関連のFORWARD拒否。
#------------------------------------------------------------------------

$IPTABLES -N CHKMSNET
$IPTABLES -A CHKMSNET -p tcp --dport 42 -j DROP # wins dup
$IPTABLES -A CHKMSNET -p tcp --dport 135 -j DROP # MS-RPC
$IPTABLES -A CHKMSNET -p udp --dport 135 -j DROP # MS-RPC
$IPTABLES -A CHKMSNET -p udp --dport 137:138 -j DROP # MS browse
$IPTABLES -A CHKMSNET -p udp --dport 137:138 -j DROP # MS browse
$IPTABLES -A CHKMSNET -p tcp --dport 139 -j DROP # SMB
$IPTABLES -A CHKMSNET -p tcp --dport 445 -j DROP # DHSMB

#------------------------------------------------------------------------
# BADFLAGSチェイン。望ましくないTCPフラグならばログに残して破棄。
#------------------------------------------------------------------------

$IPTABLES -N BADFLAGS< br />$IPTABLES -A BADFLAGS -j LOG --log-prefix "IPTABLES BADFLAGS: " $LOGOPT
$IPTABLES -A BADFLAGS -j DROP

#------------------------------------------------------------------------
# TCPフラグの検査。望ましくないTCPフラグならBADFLAGSチェインに渡す。
#------------------------------------------------------------------------
echo "tcp flag"
$IPTABLES -N TCP_FLAGS
$IPTABLES -A TCP_FLAGS -p tcp --tcp-flags ACK,FIN FIN -j BADFLAGS
$IPTABLES -A TCP_FLAGS -p tcp --tcp-flags ACK,PSH PSH -j BADFLAGS
$IPTABLES -A TCP_FLAGS -p tcp --tcp-flags ACK,URG URG -j BADFLAGS
$IPTABLES -A TCP_FLAGS -p tcp --tcp-flags FIN,RST FIN,RST -j BADFLAGS
$IPTABLES -A TCP_FLAGS -p tcp --tcp-flags SYN,FIN SYN,FIN -j BADFLAGS
$IPTABLES -A TCP_FLAGS -p tcp --tcp-flags SYN,RST SYN,RST -j BADFLAGS
$IPTABLES -A TCP_FLAGS -p tcp --tcp-flags ALL ALL -j BADFLAGS
$IPTABLES -A TCP_FLAGS -p tcp --tcp-flags ALL NONE -j BADFLAGS
$IPTABLES -A TCP_FLAGS -p tcp --tcp-flags ALL FIN,PSH,URG -j BADFLAGS
$IPTABLES -A TCP_FLAGS -p tcp --tcp-flags ALL SYN,FIN,PSH,URG -j BADFLAGS
$IPTABLES -A TCP_FLAGS -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j BADFLAGS

#------------------------------------------------------------------------
# SYN_FLOODチェイン。しきい値以上のタイミングでパケットがきたら
# SYNフラッド攻撃としてログに残した上で拒否する。
#------------------------------------------------------------------------
echo "syn flood"
$IPTABLES -N SYN_FLOOD
$IPTABLES -A SYN_FLOOD -p   tcp   --syn $SYNOPT -j RETURN
$IPTABLES -A SYN_FLOOD -p ! tcp                 -j RETURN
$IPTABLES -A SYN_FLOOD -p   tcp ! --syn         -j RETURN
$IPTABLES -A SYN_FLOOD -j LOG --log-prefix "IPTABLES SYN_FLOOD: " $LOGOPT
$IPTABLES -A SYN_FLOOD -j DROP

#------------------------------------------------------------------------
# IN_ICMPチェイン。入ってくるICMPが害のあるものならログに残して拒否
#------------------------------------------------------------------------
echo "inbound icmp"
$IPTABLES -N IN_ICMP

#変数 PING に指定されるネットワークからのpingには応答する。
for sip in $PING
do
$IPTABLES -A IN_ICMP  -p icmp --icmp-type echo-request -s $sip   -j ACCEPT
$IPTABLES -A FORWARD_FROM_WAN -o $DMZ_PORT -p tcp --dport $i -j ACCEPT
$IPTABLES -A IN_ICMP  -p icmp --icmp-type echo-reply   -s $sip   -j ACCEPT
done

#ネットワーク管理上必要なicmpパケットは許可する。ないものは拒否。
$IPTABLES -A IN_ICMP  -p icmp --icmp-type destination-unreachable  -j ACCEPT
$IPTABLES -A IN_ICMP  -p icmp --icmp-type source-quench            -j ACCEPT
$IPTABLES -A IN_ICMP  -p icmp --icmp-type time-exceeded            -j ACCEPT
$IPTABLES -A IN_ICMP  -p icmp --icmp-type parameter-problem        -j ACCEPT
$IPTABLES -A IN_ICMP -j LOG --log-prefix "IPTABLES In ICMP: " $LOGOPT
$IPTABLES -A IN_ICMP -j DROP

#------------------------------------------------------------------------------
# OUT_ICMPチェイン。出て行くICMPが害のあるものならログに残して拒否
#------------------------------------------------------------------------------
echo "outbound icmp"
$IPTABLES -N OUT_ICMP

#送信先が変数 PING に登録されていれば許可
for dip in $PING
do
$IPTABLES -A OUT_ICMP -p icmp --icmp-type echo-request -d $dip     -j ACCEPT
$IPTABLES -A OUT_ICMP -p icmp --icmp-type echo-reply   -d $dip     -j ACCEPT
done

#ネットワーク管理上必要なicmpパケットは許可する。ないものはログに残して拒否。
$IPTABLES -A OUT_ICMP -p icmp --icmp-type fragmentation-needed -j ACCEPT
$IPTABLES -A OUT_ICMP -p icmp --icmp-type source-quench            -j ACCEPT
$IPTABLES -A OUT_ICMP -p icmp --icmp-type parameter-problem        -j ACCEPT
$IPTABLES -A OUT_ICMP -j LOG --log-prefix "IPTABLES Out ICMP: " $LOGOPT
$IPTABLES -A OUT_ICMP -j DROP

#------------------------------------------------------------------------------
# DROPPACKETチェイン。不正なパケットをログに記録して破棄
#------------------------------------------------------------------------------
echo "droppacket"
$IPTABLES -N DROPPACKET # DROPPACKTチェインの作成
$IPTABLES -A DROPPACKET -j LOG --log-prefix "INVALID_PACKET: " $LOGOPT
$IPTABLES -A DROPPACKET -j DROP

#------------------------------------------------------------------------------
# FORWARD_BEFORE_CHECKチェイン。FORWARD前の不正なパケットでないかをチェック
#------------------------------------------------------------------------------
echo "checking before forward"
$IPTABLES -N FORWARD_BEFORE_CHECK

# LANから外部へフォワードされるMicrosoftネットワークのチェック
$IPTABLES -A FORWARD_BEFORE_CHECK -o $WAN_PORT -j CHKMSNET

# ブラックホールルータ対策
$IPTABLES -A FORWARD_BEFORE_CHECK -o $WAN_PORT -p tcp --tcp-flags SYN,RST \
SYN -j TCPMSS --clamp-mss-to-pmtu

# PINGについてのチェック
$IPTABLES -A FORWARD_BEFORE_CHECK -p icmp -j IN_ICMP
$IPTABLES -A FORWARD_BEFORE_CHECK -p icmp -j OUT_ICMP
# TCPのフラグが正しいかをチェック
$IPTABLES -A FORWARD_BEFORE_CHECK -p tcp -j TCP_FLAGS
# SYN_FLOOD攻撃でないかをチェック
$IPTABLES -A FORWARD_BEFORE_CHECK -p tcp --syn -j SYN_FLOOD

#------------------------------------------------------------------------------
# FORWARD_FROM_WANチェイン。WANポートから来たパケットのFORWARDについての設定
#------------------------------------------------------------------------------
echo "from wan port"
$IPTABLES -N FORWARD_FROM_WAN

# 外部からDMZへの接続で、接続済みのもののFORWARDを許可
$IPTABLES -A FORWARD_FROM_WAN -o $DMZ_PORT -m state --state \
ESTABLISHED,RELATED -j ACCEPT

for i in $DMZ_SVC_TCP
do
# 外部からDMZへの新規接続で、サービスをしているもののFORWARDを許可(tcp)
$IPTABLES -A FORWARD_FROM_WAN -o $DMZ_PORT -p tcp --dport $i -j ACCEPT
done

for i in $DMZ_SVC_UDP
do
# 外部からDMZへの新規接続で、サービスをしているもののFORWARDを許可(udp)
$IPTABLES -A FORWARD_FROM_WAN -o $DMZ_PORT -p udp --dport $i -j ACCEPT
done

# 外部からLANへの接続で、接続済みのもののFORWARDを許可 図5
$IPTABLES -A FORWARD_FROM_WAN -o $LAN_PORT -d $LAN_NET -m state --state \
ESTABLISHED,RELATED -j ACCEPT

#------------------------------------------------------------------------------
# FORWARD_FROM_DMZチェイン。DMZポートから来たパケットのFORWARDについての設定。
#------------------------------------------------------------------------------
echo "from dmz port"
$IPTABLES -N FORWARD_FROM_DMZ

#DMZから外部への接続を許可
$IPTABLES -A FORWARD_FROM_DMZ -o $WAN_PORT -s $DMZ_NET -m state --state \
NEW,ESTABLISHED,RELATED -j ACCEPT

#DMZからLANへの、接続済みのもののみ許可
$IPTABLES -A FORWARD_FROM_DMZ -o $LAN_PORT -s $DMZ_NET -m state --state \
ESTABLISHED,RELATED -j AC CEPT

#------------------------------------------------------------------------------
# FORWARD_FROM_LANチェイン。LANポートから来たパケットのFORWARDについての設定
#------------------------------------------------------------------------------
echo "from lan port"
$IPTABLES -N FORWARD_FROM_LAN

# LAN内からDMZへの接続を許可
$IPTABLES -A FORWARD_FROM_LAN -o $DMZ_PORT -s $LAN_NET -m state --state \
NEW,ESTABLISHED,RELATED -j ACCEPT
# LAN内から外部への接続を許可
$IPTABLES -A FORWARD_FROM_LAN -o $WAN_PORT -s $LAN_NET -m state --state \
NEW,ESTABLISHED,RELATED -j ACCEPT

#------------------------------------------------------------------------------
# INPUT_FIREWALLチェイン。INPUTチェインの基本的なルール。
#------------------------------------------------------------------------------
echo "input chain"
$IPTABLES -N INPUT_FIREWALL

#icmpのチェック
$IPTABLES -A INPUT_FIREWALL -p icmp -j IN_ICMP
#TCPフラグのチェック
$IPTABLES -A INPUT_FIREWALL -p tcp -j TCP_FLAGS
#SYNフラッド攻撃かをチェック
$IPTABLES -A INPUT_FIREWALL -p tcp --syn -j SYN_FLOOD
#IPアドレスが正当化をチェック
$IPTABLES -A INPUT_FIREWALL -j IN_IP_CHECK
# パケットの正当性チェック
$IPTABLES -A INPUT_FIREWALL -m state --state INVALID -j DROPPACKET
# 接続済みの入力を許可
$IPTABLES -A INPUT_FIREWALL -m state --state ESTABLISHED,RELATED -j ACCEPT
# AUTHリクエストを拒否
$IPTABLES -A INPUT_FIREWALL -p tcp --dport 113 -j REJECT --reject-with tcp-reset
#ログに残す
$IPTABLES -A INPUT_FIREWALL -j LOG --log-prefix "UNDEFIND_INPUT: " $LOGOPT

#------------------------------------------------------------------------------
# OUTPUT_FIREWALLチェイン。OUTPUTチェインの基本的なルール。
#------------------------------------------------------------------------------
echo "output chain"
$IPTABLES -N OUTPUT_FIREWALL
#icmpパケットのチェック
$IPTABLES -A OUTPUT_FIREWALL -p icmp -j OUT_ICMP
# TCPフラグのチェック
$IPTABLES -A OUTPUT_FIREWALL -p tcp -j TCP_FLAGS
#ipアドレスのチェック
$IPTABLES -A OUTPUT_FIREWALL -j OUT_IP_CHECK

# 出力を許可
$IPTABLES -A OUTPUT_FIREWALL -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT

# 上記以外のパケットはログに記録(デフォルトポリシーで破棄)
$IPTABLES -A OUTPUT_FIREWALL -j LOG --log-prefix "UNDEFIND_OUTPUT: " $LOGOPT

##########################################################################
# IPマスカレード
##########################################################################
echo "masquerade"
# DMZからの外部へのIPマスカレード(SNAT)の許可
$IPTABLES -t nat -A POSTROUTING -s $DMZ_NET -o $WAN_PORT -j MASQUERADE
# LANからの外部へのIPマスカレード(SNAT)の許可
$IPTABLES -t nat -A POSTROUTING -s $LAN_NET -o $WAN_PORT -j MASQUERADE

##########################################################################
# DMZへの転送~DNAT(静的NAT)
##########################################################################
echo "dnat"

for i in $DMZ_SVC_TCP # DMZで公開するポートの設定(tcp)
do
# WANからの接続要求をDMZに転送する(tcp)
$IPTABLES -t nat -A PREROUTING -i $WAN_PORT -p tcp --dport $i \
-j DNAT --to-destination $DMZ_SVR
done

for i in $DMZ_SVC_UDP # DMZで公開するポートの設定(tcp)
do
# WANからの接続要求をDMZに転送する(tcp)
$IPTABLES -t nat -A PREROUTING -i $WAN_PORT -p udp --dport $i \
-j DNAT --to-destination $DMZ_SVR
done

########################################################################
#メインのファイアウォールルール。プログラムで言うmain関数。
########################################################################
echo "main firewall -- forward"
$IPTABLES -A FORWARD                    -j FORWARD_BEFORE_CHECK
$IPTABLES -A FORWARD                    -j SHUN
$IPTABLES -A FORWARD -i $WAN_PORT -j FORWARD_FROM_WAN
$IPTABLES -A FORWARD -i $DMZ_PORT -j FORWARD_FROM_DMZ
$IPTABLES -A FORWARD -i $LAN_PORT -j FORWARD_FROM_LAN
$IPTABLES -A FORWARD -j LOG --log-prefix "IPTABLES DROP FORWARD: " $LOGOPT
$IPTABLES -A FORWARD -j DROP
echo "main firewall -- input"
$IPTABLES -A INPUT -i lo -j ACCEPT
$IPTABLES -A INPUT              -j SHUN
$IPTABLES -A INPUT -j INPUT_FIREWALL
$IPTABLES -A INPUT -j LOG --log-prefix "IPTABLES DROP INPUT: " $LOGOPT
$IPTABLES -A INPUT -j DROP
echo "main firewall -- output"
$IPTABLES -A OUTPUT -o lo -j ACCEPT
$IPTABLES -A OUTPUT         -j SHUN
$IPTABLES -A OUTPUT -j OUTPUT_FIREWALL
$IPTABLES -A OUTPUT -j LOG --log-prefix "IPTABLES DROP OUTPUT: " $LOGOPT
$IPTABLES -A OUTPUT -j DROP

ポートスキャンによるチェック

sygate online serviceから、「Quick Scan」を行って、サービスを提供しているものは「OPEN」、していないものは「BLOCKED」「CLOSED」になっているはずです。なっていなければ、早急にスクリプトを見直してみましょう。

設定を保存する

現在のiptablesの設定を保存することで、次回サーバ起動時に自動的に現在の設定を読まれます。

# /etc/init.d/iptables save

で、現在の設定(スクリプトの内容)が保存されます。また、「デスクトップ」→「管理」→「サービスの設定」で、iptablesを起動時にスタートするようにしましょう。

iptablesについて

ptablesのパケットパス

iptablesのパケットパス

下記では、それぞれの意味について説明します。左からそれぞれ転送される時のパス、入力されるときのパス、出力されるときのパスを示します。

テーブルとチェイン

iptablesには、

  • filter
  • nat
  • mangle

という3つのテーブルが用意されています。そして、それぞれのテーブルに、下記のようにチェインが備わっています。

  • filter
    • FORWARD
    • INPUT
    • OUTPUT
  • nat
    • PREROUTING
    • POSTROUTING
  • mangle
    • PREROUTING
    • OUTPUT

filterテーブル

パケットの内容をチェックして、パケットを受け入れたりブロックしたりします。FORWARDチェインはポートからポートへ転送されるときにパケッ
トをチェックします。INPUTチェインははローカルプロセスに入力されるとき、OUTPUTチェインはローカルプロセスからアウトプットされたときにパ
ケットをチェックします。

natテーブル

NAT(Network Address Translation)を実行します。WAN→DMZのあて先NATはPREROUTINGチェイン、IPマスカレードはPOSTROUTINGチェインで行われます。

mangleテーブル

ヘッダの変更や処理の最適化を行うテーブルです。あまり必要としませんので、説明を割愛します。

ユーザチェイン

iptablesはその処理の構造化を可能にするため、ユーザが特別なチェインを作成することができます。ユーザチェインは3つのテーブルのいずれかに関連付けられます。プログラムで言うところの、関数を作るようなイメージです。

これらiptablesの基本的な機能をうまく利用して、次のページでは実際にiptablesを用いたファイアウォールのルールを構築していきます。

セキュリティポリシの策定

ここでは、ルータに入るパケット、ルータから出るパケット、ルータを通過するパケットについてのルール(ポリシ)を決定します。

ルータに入るパケット

ルータに入るパケットというのは、「ルータ自体があて先で、ルータが処理すべきパケット」の事を指します。例を挙げると、現在構築中のルータについ
ているFirefoxブラウザで、外部にアクセスした際の、受け取るhtmlデータなどを指します。「通過する」ために入るパケットはここではなく、
「ルータを通過するパケット」のところでのルールが適用されます。

ここでは、

・不正な(攻撃に使われるような)パケットは拒否
・すでに接続が確立されているパケットであれば許可
・あとは拒否

とします。外部から新しく何かの接続を確立させよう、というものははじき、こちらからの応答のみ許可します。

ルータから出るパケット

ルータから出るパケットというのは、「ルータ自体が送信元のパケット」の事を指します。例を挙げると、現在構築中のルータについている
Firefoxブラウザで、外部にアクセスする際の、データ要求などを指します。「通過した」結果出るパケットはここではなく、「ルータを通過するパケッ
ト」のところでのルールが適用されます。

ここでは、

・不正な(攻撃に使われるような)パケットは拒否。
・あとは許可。

とします。

ルータを通過するパケット

ルータに、ルータ以外への、ほかへのあて先のパケットがきたときどう処理するかを決めます。ルータなので、ここが一番重要です。言わずもがな、ここではすべて

・不正な(攻撃に使われるような)パケットは拒否。

とします。

WAN→DMZ

・あて先ポートがDMZ内サーバのサービスに使用されているポートならば、
 送信先IPアドレスをDMZ内サーバ(192.168.10.2)に変換して通過させる。
・それ以外は拒否。

WAN→LAN

・すでに接続が確立されているパケットであれば、IPマスカレードのIP変換
 テーブルに基づいて、送信先IPアドレスをLAN内端末のIPアドレスに変換
 して通過させる。
・それ以外は拒否。

DMZ→WAN

・すべてIPマスカレードを実行して通過。

DMZ→LAN

・すでに接続が確立されているパケットであれば通過させる。
・それ以外は拒否。

LAN→WAN

・すべてIPマスカレードを実行して通過。

LAN→DMZ

・基本的にすべて通過。

ネットワークの設定

OSのインストールに成功し、ランレベル5で起動するとXが立ち上がります。ログイン後、設定を確認していきます。図のような前提で話を進めて生きたいと思います。

ルータ構築のネットワーク図

ファイアウォールの確認

「デスクトップ」→「管理」→「セキュリティレベルとファイアウォールの設定」で、「ファイアウォールのオプション」の「信頼できるサービス」のすべてのチェックボックスが外れていればOKです。

サービスを停止する

不要なサービスが開始されている場合があります。Fedora Core
5では、デフォルトでsendmailとsshがONになっている場合があるので、これらのサービスをストップしておきます。「デスクトップ」→「管理」
→「サービスの設定」で、「Background
Services」の不要なサービス、特にsshやsendmailのチェックをはずして、サーバ起動時に開始しないようにした後、「停止」を押して、
サービスを停止させます。

ppp0(WAN側ポート)の作成

さて、ppp0(WAN側ポート)の作成に入ります。プロバイダとの接続をするところです。

「デスクトップ」→「管理」→「ネットワークの設定」で、「デバイス」の「新規」をクリックします。「デバイスタイプ」では「xDSL接続」を選
択、「DSL接続の設定」では、「イーサネットデバイス」にeth0、プロバイダ名、ログイン名、パスワード(プロバイダから発行されたもの)を入力しま
す。設定が終了すると、「デバイス」の一覧にppp0が作成されます。

続けて、この作成された「ppp0」を選択し、「編集」をクリックします。「xDSL設定」という設定画面が出てきます。ニックネームには
「ppp0」「コンピュータの起動時にデバイスを起動」にチェック、「すべてのユーザに・・・」と「このインタフェース用にIPv6の設定・・・」の
チェックははずします。また、「固定のIPアドレス設定」をクリックし、プロバイダからもらっている固定IPを入力します。私の場合は、

アドレス                      :218.45.162.38
サブネットマスク              :255.255.255.255
デフォルトゲートウェイアドレス:218.45.162.38

としました。

設定を抜け、VDSLモデム(フレッツ光マンションタイプの場合)とeth0ポートを実際にストレートケーブルで接続し、先ほどの「デスクトップ」
→「管理」→「ネットワークの設定」画面でppp0を選択、「起動」をクリックします。状態が「起動中」となればppp0の設定は完了したことになりま
す。

カーネルモードPPPoE

PPPoEをカーネルの一部として起動させ、スループットをあげるための設定をします。

設定ファイルは /etc/sysconfig/networking/profiles/default/ifcfg-ppp0(ppp0の部分は、「xDSL設定」のニックネームに依存する)です。viなどのエディタで、このファイルの最終行に

LINUX_PLUGIN=/usr/lib/pppd/2.4.3/rp-pppoe.so

と入力します。この設定を有効にするため、「デスクトップ」→「管理」→「ネットワークの設定」画面でppp0を選択、「再起動」をクリックします。

アップデート

「アプリケーション」→「システムメニュー」→「Software Updater」で、「Apply updates」をクリックすると、アップデートが開始されます。

また、「デスクトップ」→「管理」→「サービスの設定」で、「yum」を起動するようにしておくと、自動でアップデート(デフォルトでは午前5時くらい)が行われるようになります。

eth1(DMZ)、eth2(LAN)ポートの設定

「デスクトップ」→「管理」→「ネットワークの設定」で、eth1またはeth2を選択し、「編集」を押します。そこで、「コンピュータの起動時にデバイスを起動」にのみチェックを入れ、さらに、「固定のIPアドレス設定」で、

eth1

アドレス        :192.168.10.1
サブネットマスク:255.255.255.0

eth2

アドレス        :192.168.20.1
サブネットマスク:255.255.255.0

とします。ここで、DMZのネットワークは192.168.10.0/24、LANのネットワークは192.168.20.0/24とします。また、デフォルトゲートウェイの設定はしません。

DNSの設定

ここでは、DMZに立てられているDNSサーバに名前解決を依頼します。ここでの「名前解決」という意味は、この「ルータ」が必要とする何らかの処
理のために必要な「名前解決」を意味します。例えば、ルータからブラウザを用いて外部にアクセスするために、ここで設定するDMZに立てられたDNSサー
バに名前解決しに行くということです。外部から来る名前解決を行う、ということではありません。/etc/resolv.confに、

nameserver 192.168.10.2

と書き加えます。ここで、DMZ上のDNSサーバのアドレスを192.168.10.2とします。複数、DNSサーバを指定したいときは、

nameserver 192.168.10.2
nameserver 211.***.**.1
nameserver 211.***.**.2

というふうに、列挙していきます。例えば、プロバイダのDNSなどを設定しておくと、DMZ内に何らかの理由でアクセスできなくなったときでもルータは名前解決できるようになります。

OSのインストール

OSは、今回は手軽さを考えてFedore Core 5を利用しました。もっとも、今回参考にさせていただいたネットワークマガジン2006年5月号がFedora Core 5だったって言うのもあるのですが。

それはともかく、Gentoo
Linuxと違って気をつけなくてはならない点は、「インストールが簡単=オートメーション=ブラックボックス化してしまう」ということです。サーバや
ルータは「必要なものはインストールしない」「インストールされているものが自分でわかっている」というのが、セキュリティホールを作らないうえで重要だ
からです。ですので、いくらインストールが簡単といっても気をつけなくてはならないいくつかの点がありますので述べていきます。

「ネットワークデバイス」では

NIC3枚挿しの場合、ちゃんと認識されていればeth0~eth2が表示されているはずです。とりあえずここでは「起動時にアクティブ」のチェックをはずし、起動時にはアクティブにしないようにします。

「Fedora Core のデフォルトのインストールは・・・」では

「必要のないものはインストールしない」という観点からはとりあえず「オフィスとプロダクティビティ」をチェックし、「即時カスタマイズ」をチェッ
クすることで、必要のあるもの、ないものを自分でカスタマイズ可能です。今回必要なものは「iptables」ぐらいなものです。時間がある方はこの部分
をしっかり閲覧して、どのようなものがインストールされるかをチェックしてください。面倒くさい方はある程度お任せでもいいかもしれませんが・・・。

「ファイアウォール」では

「Enabled」になっていることを確認し、すべての「Trusted Services」からチェックをはずします。

「システムユーザー」では

「root」以外のユーザを作ったほうがいいでしょう。作業用ユーザをお好みで作成してください。

ハードウェアの選定

特に電気屋さんで今売っているようなハイスペックな物は必要ありませんが、ルータなので攻撃に備えられるような、それなりの物をそろえたほうがいい
かも知れません。すぐにメモリが一杯になっちゃうようなスペックは控えられたほうが吉でしょう。私の使っているマシンのスペックを以下に示します。

  • CPU:AMD Duron(tm) processor 1.3GHz
  • MEM:256MB
  • HDD:20GB
  • NIC:VT6122(玄人志向のギガビットNIC) x 2 & M/BオンボードのNIC(100Mbps) x 1

すべて余りパーツでした。NICは計3枚です。WAN(M/BオンボードのNIC(100Mbps))、DMZ(玄人志向のギガビットNIC)、LAN(玄人志向のギガビットNIC)にそれぞれつながります。