今回の作業で私自身が一番悩んで一番時間を労したところです。ここの部分で悩んでいる方が多いのではないかと思い
なるべく解り易く懇切丁寧に書いたつもりです。また、個人的にはネットワークカード1枚がお勧めします。
2001年8月23日全面改装!!!!!、特にセキュリティー重視となっています。
Linux2.1.x と 2.2.x カーネルでは、IP マスカレーディングの設定には、IPFWADMは前世紀の遺物であることを覚えておいてください。(ディストリビューションには関係ない)
21世紀では、IPCHAINSツールを使います。また、以下の説明は少し難しいかもしれませんが、セュリティ重視の設定とします。 以下に記すように /etc/rc.d/rc.firewallのファイルを作成します。
注意 #1 - 2.2.16以前の Linux カーネルには、 TCP 接続でルート権限 を奪取される危険性があり、更に 2.2.11 以前のものには IPCHAINS の フラグメンテーションに関するバグがあ
ります。 このため、強固な IPCHAINS ルールセットを稼働させる際には、攻撃に対して 無防備です。 修正されたバージョンのカーネルを使ってください。
注意 #2 - もし、TCP/IPアドレスが PPP, ADSL, ケーブルモデムなどを 経由して ISP から動的に割り当てられる場合には、この強固なルールセットを 起動時に設定することはでき
ません。 このような場合には、IP アドレスが割り当てられる度にこの ファイアウォール・ルールセットを再度読み込ませるか、あるいは /ec/rc.d/rc.firewall ルールセットをもっとインテリ
ジェントに作る必要が あります。 PPP ユーザがこのルールセットを適用する場合には、後述する "Dynamic PPP IP fetch" と書かれた部分のコメントを注意深く適切に 外してください。
また、強固なルールセット及び動的に割り当てられる IP アドレスについての もっと詳しい解説は、 TrinityOS - Section 10 にあります。
#!/bin/sh
#
# /etc/rc.d/rc.firewall - やや強固な IPCHAINS ファイアウオール・ルールセット
#
PATH=/sbin:/bin:/usr/sbin:/usr/bin
# 必要なすべての IP マスカレードモジュールをロードする
#
# 注意 - 必要な IP マスカレードモジュールだけをロードします。すべての IP マスカレードモジュールが
# 以下に記述されていますが、ロードされないようにコメントとなっています。
# モジュールを最初にロードする時にまず必要
#
/sbin/depmod -a
# PORT 方式を使ってFTP ファイル転送における適切な IP マスカレードを提供します
#
/sbin/modprobe ip_masq_ftp
# UDP プロトコルを経由した、RealAudio のマスカレードを提供します。このモジュールがなくても
# RealAudio は TCP モードで動作しますが、音質は低下します。
#
/sbin/modprobe ip_masq_raudio
# IRC DCC ファイル転送のマスカレードを提供します
#
#/sbin/modprobe ip_masq_irc
# 以下の指定によって Quake と QuakeWorld をデフォルトで提供します。このモジュールは Linux
# の マスカレード・ボックスから内側の複数ユーザが存在する場合のためのものです。
# もし、Quake I, II, あるいは III を使いたいならば、2番目の例を使ってください。
#
# 注意 - もし、QUAKE モジュールのロード時にエラーが出た場合は、古いバグの
# ------ あるカーネルが動いています。
# その場合はより新しいカーネルに置き換えてください。
#
#Quake I / QuakeWorld (ports 26000 and 27000)
#/sbin/modprobe ip_masq_quake
#
#Quake I/II/III / QuakeWorld (ports 26000, 27000, 27910, 27960)
#/sbin/modprobe ip_masq_quake 26000,27000,27910,27960
# CuSeeme ビデオ会議ソフトウエアに対するマスカレードを提供
#
#/sbin/modprobe ip_masq_cuseeme
# VDO-Live ビデオ会議ソフトウエアに対するマスカレードを提供
#
#/sbin/modprobe ip_masq_vdolive
#非常に重要 - IP フォワーディングはデフォルトでは無効になっているので、有効にします。
#
# Redhat ユーザの場合は、/etc/sysconfig/network のオプション指定行を
#
# FORWARD_IPV4=false
# から
# FORWARD_IPV4=true
# に変更してください。
#
echo "1" > /proc/sys/net/ipv4/ip_forward
#非常に重要 - 2.2.x カーネルでは IP デフラグメンテーションのサポートはデフォルトでは無効です。
#
# コンパイル時の指定によるものですが、2.2.12 カーネル以降は変更されています。
# また、ディストリビューションによっては /proc テーブルから
# このオプションが除外されていることもありますので、その場合は
# /proc ディレクトリに存在しなければ気にしなくても構いません。
#
echo "1" > /proc/sys/net/ipv4/ip_always_defrag
# 動的に割り当てられる IP アドレスを使用するユーザ向け -
#
# IP アドレスを SLIP, PPP, DHCP などから動的に取得する場合は、次のオプションを有効にしてください。
# このオプションは、IP マスカレードで動的 IP アドレスの操作を許可し、Diald や同様なプログラムの
# 使用をより容易にするものです。
#echo "1" > /proc/sys/net/ipv4/ip_dynaddr
# インターネットを必要とする、いくつかのプログラムに対する LooseUDP パッチを有効にする
#
# IP マスカレードを経由してインターネットゲームを動かそうとしていて、どうしてもそれが動かないという
# のなら、このオプションを有効にしてみてください(以下の "#" を削除します)。UDP ポートスキャンに
# 対する脆弱性の可能性があるので、このオプションはデフォルトで禁止されています。
#
#echo "1" > /proc/sys/net/ipv4/ip_masq_udp_dloose
# あなたの静的な IP アドレスを以下に指定します
#
# 動的に割り当てられる IP アドレスを使用するなら、新しい IP アドレスが割り当てられるたびに適用
# するように、ルールセットを書き換えなければなりません。そのためには、、以下のような一行のスクリプトを
# 有効にする必要があります。(スクリプト例内の一重引用符と二重引用符の違いは意味を持ちますので注意)
#
#
# DHCP を利用する場合 -
# -----------
# TCP/IP アドレスを DHCP から取得する場合は、ppp セクションの下にある"#"でコメントアウトされた
# 部分を有効にし、"ppp0" とある部分を、インターネット接続用のインタフェースの名前に置き換えなければ
# なりません(たとえば、eth0 や eth1 などに)。
# DHCP は割り当てた IP アドレスを随時変更することに注意してください。この変更を正しく反映させるには
# DHCP リースが更新されるたびに、DHCP クライアントを再度実行してファイアウオールルールセットを反映
# させなければなりません。
#
# 注意 1 - いくつかの DHCP クライアントは古いバージョンの "pump" で(新しいバージョン
# では問題点は修正されています)、それはリース更新後にスクリプトを実行することが
# できないものです。その場合は、"dhcpcd" か "dhclient" に置き換えなければ
# なりません。
#
# 注意 2 - "dhcpcd" は最近のバージョンでは、コマンド文法が変わっています。
#
# 旧バージョンでの指定方法は、次のようなものでした -
# dhcpcd -c /etc/rc.d/rc.firewall eth0
#
# 新しいバージョンでは次のように指定します -
# dhcpcd eth0 /etc/rc.d/rc.firewall
#
#
# 注意 3 - Pump を使う場合、/etc/pump.conf ファイルに次の記述を追加してください。
#
# script /etc/rc.d/rc.firewall
#
# PPP を利用する場合 -
# ----------
# お気づきではないかもしれませんが、PPP 接続が行われるたびに、/etc/ppp/ip-up スクリプトが
# 常に動作します。このことを利用して、新しい IP アドレスの取得と強固なファイアウオール・ルール
# セットの再設定を行います。
#
# もし、/etc/ppp/ip-up がすでに存在しているなら、それを編集して"/etc/rc.d/rc.firewall"
# という記述を最後のあたりに追加するようにしてください。
#
# もし、/etc/ppp/ip-up スクリプトが存在しなかったなら、/etc/rc.d/rc.firewall スクリプト
# を実行するための次のようなリンクを作成する必要があります。
#
# ln -s /etc/rc.d/rc.firewall /etc/ppp/ip-up
#
# * 続いて、以下のコメントアウトされたシェルコマンドを必要に応じて有効にしてください *
#
# PPP 及び DHCP を利用する場合 -
# -------------------
# 次の行の "#" を削除して、その次の行の先頭に "#" を入れてください。
#extip="`/sbin/ifconfig ppp0 | grep 'inet addr' | awk '{print $2}' | sed -e
's/.*://'`"
# 静的な IP アドレスで PPP を使う場合 -
#
extip="your.static.PPP.address"
# PPP と DHCP を使う場合は、必ずこの部分に正しい外部インタフェースの名前を指定します
extint="ppp0"
# 内部の IP アドレスの割り当てを指定します
intint="eth0"
intnet="192.168.0.0/24"
# マスカレードのタイムアウト
#
# 2 時間= TCP セッション
# 10 秒 = TCP/IP の "FIN" パケットが受信されたあとのトラフィック
# 60 秒 = UDP トラフィック (マスカレードされた環境での ICQ 利用者は ICQ 自体の設定の中で
# 30秒のファイアウオールタイムアウトを指定しなければなりません)
#
#
ipchains -M -S 7200 10 60
#############################################################################
# 到着パケットについて、既存のルールを破棄し、初期ポリシーを
# 拒絶【訳注: reject】に設定。実際は、拒絶してログに記録する
# 最終ルールを用意するので、このポリシーは動作には無関係になる。
# 【訳注: ルールを REJECT にすると、ルールに合致したパケットを破棄して、
# "destination-unreachable" (目的地に到達しない) という ICMP パケットを
# 相手側 (送信元アドレスのマシン) に発信します。
# DENY にすると、"destination-unreachable" パケットも出さずに、受信した
# パケットを単に破棄します。
#
ipchains -F input
ipchains -P input REJECT
# ローカルマシン側からローカルインタフェースに入るパケットは、どこに
# 向かうものも有効とする。
#
ipchains -A input -i $intint -s $intnet -d 0.0.0.0/0 -j ACCEPT
# リモートインタフェース側から入って来る IP スプーフィング【訳注: IP 偽装】
# パケットや迷子パケットは、本来ならローカルマシンからであるべきものなので、
# 拒絶する。
#
ipchains -A input -i $extint -s $intnet -d 0.0.0.0/0 -l -j REJECT
# リモートインターフェースに入って来る、宛先アドレスが PPP アドレスの
# パケットは、どの発信元アドレスからのものも有効とする。
# 【訳注: 以下のコマンドの前に、
# ipchains -A input -i $extint -S 0/0 -d $extip/32 -p tcp -y -j DENY -l
# があるか、或は以下のコマンドが
# ipchains -A input -i $extint -S 0/0 -d $extip/32 -p tcp ! -y -j ACCEPT
# となっている方がより好ましいと思います。】
#
ipchains -A input -i $extint -s 0.0.0.0/0 -d $extip/32 -j ACCEPT
# ループバックインタフェースを有効とする
#
ipchains -A input -i lo -s 0.0.0.0/0 -d 0.0.0.0/0 -j ACCEPT
# 最終ルール。その他の到着パケットは拒絶され、ログに記録される。ポリシーには
# ログ記録のためのオプションがないため、これがその役割を代わりに果たすことに
# なる。
#
ipchains -A input -s 0.0.0.0/0 -d 0.0.0.0/0 -l -j REJECT
#############################################################################
# 送出パケットについて、既存のルールを破棄し、初期ポリシーを
# 拒絶【訳注: reject】に設定。実際は、拒絶してログに記録する最終ルールを
# 用意するので、このポリシーは動作には無関係になる。
#
ipchains -F output
ipchains -P output REJECT
# ローカルインタフェースから出力される、ローカルネットへ向かうパケットは
# どこからのものも有効とする。
#
ipchains -A output -i $intint -s 0.0.0.0/0 -d $intnet -j ACCEPT
# リモートインタフェース上でローカルネットへ送出されるパケットは、
# 偽装ルーティングなので、拒絶する。
#
ipchains -A output -i $extint -s 0.0.0.0/0 -d $intnet -l -j REJECT
# リモートインタフェース上でローカルネットから送出されるパケットは、
# あり得ないマスカレーディングなので、拒絶する。
#
ipchains -A output -i $extint -s $intnet -d 0.0.0.0/0 -l -j REJECT
# リモートインタフェースからのそれ以外の送出パケットは有効
#
ipchains -A output -i $extint -s $extip/32 -d 0.0.0.0/0 -j ACCEPT
# ループバックインタフェースを有効とする。
#
ipchains -A output -i lo -s 0.0.0.0/0 -d 0.0.0.0/0 -j ACCEPT
# 最終ルール。その他の送出パケットは拒絶され、ログに記録される。
# ポリシーにはログ記録のためのオプションはないため、これがその役割を
# 代わりに果たすことになる。
#
ipchains -A output -s 0.0.0.0/0 -d 0.0.0.0/0 -l -j REJECT
#############################################################################
# 転送パケットについて、既存のルールを破棄し、初期ポリシーを
# 否定【訳注: deny】に設定。実際は、否定してログに記録する最終ルールを
# 用意するので、このポリシーは動作には無関係になる。
#
ipchains -F forward
ipchains -P forward DENY
# ローカルインタフェースでのローカルネットからその他の宛先へのパケットをマスカレードする
#
ipchains -A forward -i $extint -s $intnet -d 0.0.0.0/0 -j MASQ
#
# 最終ルール。その他の転送パケットは拒絶され、ログに記録される。
# ポリシーにはログ記録のためのオプションはないため、これがその役割を
# 代わりに果たすことになる。
#
ipchains -A forward -s 0.0.0.0/0 -d 0.0.0.0/0 -l -j REJECT
# ファイルの終わり
|
さて、ファイアウォールのルールセットの準備が整いました。 これをリブート後に実行させる必要があります。 実行には、毎回手で行う方法 (苦痛です) か、ブートスクリプトに追加する方
法 があります。 以下に 2つの方法を記しておきました。
Redhat 及び Redhat から派生したディストリビューション
起動スクリプトのロードに関し、 Redhat には 2つの方法があります - /etc/rc.d/rc.local 或は /etc/rc.d/init.d/ の中にある init スクリプトです。 前者の方法が最も簡単です。
やるべきことは以下の行を /etc/rc.d/rc.local ファイルの最後に追加することです
echo "Loading the rc.firewall ruleset.." /etc/rc.d/rc.firewall
この手法の問題点は、強固なファイアウォールのルールセットを動作させようと する際に、ファイアウォールはブート終了に至るまで実行されない、という点に あります。 好ましい
手法としては、ネットワークサブシステムの設定がロードされた直後に、ファイアウォールの設定がロードされるようにすることです。 今の所、この HOWTO は /etc/rc.d/rc.local
の設定のみを扱っています。
Slackware
起動スクリプトのロードに関し、 Slackware には 2つの方法があります - /etc/rc.d/rc.local 或は /etc/rc.d/rc.inet2 ファイルを編集することです。 前者の方法が最も簡単で
す。やるべきことは以下の行を /etc/rc.d/rc.local ファイルの最後に追加することです
echo "Loading the rc.firewall ruleset.."
/etc/rc.d/rc.firewall
この手法の問題点は、強固なファイアウォールのルールセットを動作させようと する際に、ファイアウォールはブート終了に至るまで実行されない、という点に あります。 好ましい
手法としては、ネットワークサブシステムの設定がロードされた直後に、 ファイアウォールの設定がロードされるようにすることです。 今の所、この HOWTO は /etc/rc.d/rc.local
の設定のみを扱っています。
ここは、カーネル2.2.19では不要です。
/etc/lilo.confファイルにappend="ether=0,0,eth1"を追加します。
image = /vmlinuz |
ここでネットワークカードを追加した場合は必ず #lilo をしておいてください、
/etc/rc.d/rc.inet1の追加・変更、これによりifconfigおよびrouteコマンドが実行できるようになります。
#/etc/rc.d/rc.inet1に赤字の部分を追加、青色部分を変更しました。
#! /bin/sh
#
# rc.inet1 This shell script boots up the base INET system.
#
# Version: @(#)/etc/rc.d/rc.inet1 2.00 10/06/1999
#
HOSTNAME=`cat /etc/HOSTNAME`
# Attach the loopback device.
/sbin/ifconfig lo 127.0.0.1
/sbin/route add -net 127.0.0.0 netmask 255.0.0.0 lo
# IF YOU HAVE AN ETHERNET CONNECTION, use these lines below to configure the
# eth0 interface.
IPADDR="123.234.123.59" グローバルIPアドレス関連の指定
NETMASK="255.255.255.240"
NETWORK="210.234.123.45"
BROADCAST="210.234.123.60"
GATEWAY="210.234.123.46"
# Edit for your setup.
IPADDR1="192.168.0.1" # REPLACE with YOUR IP address! ローカルIPアドレス関連の指定
NETMASK1="255.255.255.0" # REPLACE with YOUR netmask!
NETWORK1="192.168.0.0" # REPLACE with YOUR network address!
BROADCAST1="192.168.0.255" # REPLACE with YOUR broadcast address, if you
# have one. If not, leave blank and edit below.
# To use DHCP instead of a static IP, set this value to "yes":
DHCP="no" # Use DHCP ("yes" or "no")
# OK, time to set up the interface:
if [ "$DHCP" = "yes" ]; then # use DHCP to set everything up:
echo "Attempting to configure eth0 by contacting a DHCP server..."
/sbin/dhcpcd
elif [ ! "$IPADDR" = "127.0.0.1" ]; then # set up IP statically:
# Set up the ethernet card:
echo "Configuring eth0 as ${IPADDR}..."
/sbin/ifconfig eth0 ${IPADDR} broadcast ${BROADCAST} netmask ${NETMASK} グローバルはeth0となります。
/sbin/ifconfig eth0:0 ${IPADDR1} broadcast ${BROADCAST1} netmask ${NETMASK1} ローカルはeth0:0となります。
# If that didn't succeed, give the system administrator some hints:
if [ ! $? = 0 ]; then
cat << EOF
Your ethernet card was not initialized properly. Here are some reasons why this
may have happened, and the solutions:
1. Your kernel does not contain support for your card. Including all the
network drivers in a Linux kernel can make it too large to even boot, and
sometimes including extra drivers can cause system hangs. To support your
ethernet, either edit /etc/rc.d/rc.modules to load the support at boottime,
or compile and install a kernel that contains support.
2. You don't have an ethernet card, in which case you should comment out this
section of /etc/rc.d/rc.inet1. (Unless you don't mind seeing this error...)
EOF
fi
# Older kernel versions need this to set up the eth0 routing table:
KVERSION=`uname -r | cut -f 1,2 -d .`
if [ "$KVERSION" = "1.0" -o "$KVERSION" = "1.1" \
-o "$KVERSION" = "1.2" -o "$KVERSION" = "2.0" -o "$KVERSION" = "" ]; then
/sbin/route add -net ${NETWORK} netmask ${NETMASK} eth0
fi
# If there is a gateway defined, then set it up:
if [ ! "$GATEWAY" = "" ]; then
/sbin/route add default gw ${GATEWAY} netmask 0.0.0.0 metric 1
fi
fi
# End of rc.inet1
|
#/etc/rc.d/rc.inet1に赤字の部分を追加、青色部分を変更しました。
#! /bin/sh
#
# rc.inet1 This shell script boots up the base INET system.
#
# Version: @(#)/etc/rc.d/rc.inet1 2.00 10/06/1999
#
HOSTNAME=`cat /etc/HOSTNAME`
# Attach the loopback device.
/sbin/ifconfig lo 127.0.0.1
/sbin/route add -net 127.0.0.0 netmask 255.0.0.0 lo
# IF YOU HAVE AN ETHERNET CONNECTION, use these lines below to configure the
# eth0 interface.
IPADDR="123.234.123.59" グローバルIPアドレス関連の指定
NETMASK="255.255.255.240"
NETWORK="123.234.123.45"
BROADCAST="123.234.123.60"
GATEWAY="123.234.123.46"
# Edit for your setup.
IPADDR1="192.168.0.1" # REPLACE with YOUR IP address! ローカルIPアドレス関連の指定
NETMASK1="255.255.255.0" # REPLACE with YOUR netmask!
NETWORK1="192.168.0.0" # REPLACE with YOUR network address!
BROADCAST1="192.168.0.255" # REPLACE with YOUR broadcast address, if you
# have one. If not, leave blank and edit below.
GATEWAY="" # REPLACE with YOUR gateway address!
# To use DHCP instead of a static IP, set this value to "yes":
DHCP="no" # Use DHCP ("yes" or "no")
# OK, time to set up the interface:
if [ "$DHCP" = "yes" ]; then # use DHCP to set everything up:
echo "Attempting to configure eth0 by contacting a DHCP server..."
/sbin/dhcpcd
elif [ ! "$IPADDR" = "127.0.0.1" ]; then # set up IP statically:
# Set up the ethernet card:
echo "Configuring eth0 as ${IPADDR}..."
/sbin/ifconfig eth0 ${IPADDR} broadcast ${BROADCAST} netmask ${NETMASK} グローバルはeth0となります。
/sbin/ifconfig eth1 ${IPADDR1} broadcast ${BROADCAST1} netmask ${NETMASK1} ローカルはeth1となります。
# If that didn't succeed, give the system administrator some hints:
if [ ! $? = 0 ]; then
cat << EOF
Your ethernet card was not initialized properly. Here are some reasons why this
may have happened, and the solutions:
1. Your kernel does not contain support for your card. Including all the
network drivers in a Linux kernel can make it too large to even boot, and
sometimes including extra drivers can cause system hangs. To support your
ethernet, either edit /etc/rc.d/rc.modules to load the support at boottime,
or compile and install a kernel that contains support.
2. You don't have an ethernet card, in which case you should comment out this
section of /etc/rc.d/rc.inet1. (Unless you don't mind seeing this error...)
EOF
fi
# Older kernel versions need this to set up the eth0 routing table:
KVERSION=`uname -r | cut -f 1,2 -d .`
if [ "$KVERSION" = "1.0" -o "$KVERSION" = "1.1" \
-o "$KVERSION" = "1.2" -o "$KVERSION" = "2.0" -o "$KVERSION" = "" ]; then
/sbin/route add -net ${NETWORK} netmask ${NETMASK} eth0
fi
# If there is a gateway defined, then set it up:
if [ ! "$GATEWAY" = "" ]; then
/sbin/route add default gw ${GATEWAY} netmask 0.0.0.0 metric 1
fi
fi
# End of rc.inet1
|
# ifconfigをrootから入力すると以下のように表示されます。赤色の部分を確認してください。
もし、不幸にして赤色の部分が違う場合は,/etc/rc.d/rc.inet1の/sbin/ifconfigが間違えています。
# ifconfig |
# routetを力すると以下のように表示されます。赤色の部分を確認してください。
もし、不幸にして赤色の部分が違う場合は,/etc/rc.d/rc.inet1の/sbin/routeが間違えています。
# route Kernel routing table Destinnation Gateway Genmask Flages Metric Ref Use Iface 210.234.123.59 * 255.255.255.240 U 0 0 0 eth0 localnet * 255.255.255.0 U 0 0 0 eth0:0 (カードが2枚の場合はeth1) loopback * 255.255.255.0 U 0 0 1 lo default 210.234.123.46 0.0.0.0 UG 1 0 0 eth0 |
# "netstat -rn" 以下のように表示されます。
Kernel IP routing table
Destination Gateway Genmask Flags MSS Window irtt Iface
192.168.0.1 0.0.0.0 255.255.255.255 UH 0 16384 0 eth1
12.13.14.15 0.0.0.0 255.255.255.255 UH 0 16384 0 eth0
12.13.14.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
192.168.0.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1
127.0.0.0 0.0.0.0 255.0.0.0 U 0 16384 0 lo
0.0.0.0 12.13.14.1 0.0.0.0 UG 0 16384 0 eth0
|
.
.
Chain forward (policy REJECT):
target prot opt source destination ports
MASQ all ------ 192.168.0.0/24 0.0.0.0/0 n/a
ACCEPT all ----l- 0.0.0.0/0 0.0.0.0/0 n/a
.
.
|