この項は上述の説明からもれたすべての情報と FAQ 集があります。
この問題にはある種の方針が必要です。速度を最適化(最も普通のパケットに対するルールチェックを最小限にとどめる)して構築するか、管理性を高めて構築することもできます。
PPP リンクと言う間欠的なリンクを使っているなら、起動時に
input チェインの最初のルールを
`-i ppp0 -jDENY'
に設定したいと思うかもしれません。
その場合は、 ip-up
スクリプトファイルで次のようにします。
(訳注: デバイス ppp0 からのパケットを破棄する。ダイヤルアップ回線などからの侵入を防止した場合に設定する。)
# `ppp-in' チェインを再生成する。
ipchains-restore -f < ppp-in.firewall
# ppp-handling チェインに割り込んで DENY ルールを置き換える。
ipchains -R input 1 -i ppp0 -j ppp-in
ip-down
は次のようになります。
ipchains -R input 1 -i ppp0 -j DENY
必要でないパケットをフィルタリングで破棄する前に注意しておかなければいけない事があります。
ICMP パケットは、(TCP や UDP のような)別のプロトコルに対して、失敗を表示 (その他数あるもののなかで) するのに使われています。 とりわけ `目的地に到達しない' パケットを表示します。 これらのパケットをブロックすると、 `ホストに到達しません' や `ホストへの経路がありません' というエラーを受け取ることができなくなります。 どのような接続も来るはずのない返答を待つだけになります。 これはいらいらしますが致命的ではありません。
さらに悪いことは MTU 検出での ICMP パケットの役割です。 すべての良好な TCP の実装(Linux を含めた)は、分割されない状態で(分割されるとパフォーマンスを低下させ、とりわけ、ときどき分割された断片が失われるとさらに低下します)目的地に到達する最大のパケットサイズを割り出すために MTU 検出を使っています。 MTU 検出は、まずパケットを "分割不可" のビットを設定して送り、 '分割が必要だが分割しない設定(DF)をしている'というエラーを示す ICMP パケットを受け取ったら、先ほどのものより小さいサイズのパケットを送り直す、というやりかたで動作します。 これは、`目的地へ到達不能' パケットのタイプで、もし受けないなら、ローカルホストは MTU を低下させないで、実行はひどく悪くなるか、存在しないことになるでしょう。
訳注:
IP 相互接続ネットワーク内のノードでエラー通達、診断、制御のための メッセージを送るプロトコル
ネットワークインターフェースが一度に送ることができる最大のデータ量
すべての ICMP 経路変更要求メッセージ(type 5)をブロックするのは普通だということに注意して下さい。 これらは、経路を手動設定する為に使うことが出来ますが(良好な IP スタックは安全装置を持っています)、しばしばやや危険だと知られています。
外向きの TCP 接続をブロックするようにしているなら、 DNS はいつも UDP を使わないことに注意して下さい。 サーバからの返答が 512 バイトを越えると、クライアントはデータを得るのに TCP 接続(やはり 53 番ポート番号) を使います。
訳注:
データパケットの転送を行うプログラム。UDP は TCP に比べると高速で すが、信頼性が低く、パケットの到達順序が保証されません。
TCP 転送を禁止していても、 DNS が `ほとんど動く' のでハマリます。 そのようにしているなら、不可解な長い遅延やその他のときどき発生する DNS の問題を経験することになるでしょう。
DNS の問い合わせが、いつも同一の外部のソース(/etc/resolv.conf
に書かれた行のネームサーバ
を直接使うか、フォワードモードでキャッシュのネームサーバーを使うかのどちらか)にしているなら、(キャッシュを使っているなら)ローカル domain
ポートから、 /etc/resolv.conf
を使っているならハイポート(>1023)から、そのネームサーバの domain
ポートへの TCP 接続を許可する必要だけでかまいません。
訳注: domain は /etc/services に次の項目が定義されているかを確認しておきます。 次のようにして調べることができます。
$ grep domain /etc/services
domain 53/tcp nameserver # name-domain server
domain 53/udp nameserver
典型的なパケットフィルタリングの問題は FTP です。FTP には2つのモードがあります。 伝統的なものは アクティブモード と言われるもので、より最近のものは、 パッシブモード と言われます。 Web ブラウザは通常パッシブモードがデフォルトですが、コマンドの FTP プログラムは通常アクティブモードがデフォルトです。
アクティブモードでは、リモートホストがファイルを送信したいとき(あるいは、 ls
や dir
コマンドの結果でさえ)、ローカルマシンへの TCP 接続をオープンしようとします。
これはアクティブ FTP を切断しないなら、これらの TCP 接続を排除できないということです。
パッシブモードを使うオプションがあるなら、良いことです。 パッシブモードは入力データに対しても、クライアントからサーバにデータ接続を作ります。 パッシブモードが使えないなら、TCP 接続に 1024 を越え、6000 から 6010 の範囲に無いポートに対して TCP 接続を許可することを推奨します。(6000 は X-Window System に使われています。)
Linux マシンはいまや有名な Ping of Death を心配することはありません。 Ping of Death は不法に大きな ICMP パケットを送信し、それは受け取り側で TCP スタックにあるバッファーを溢れさせ、破壊の原因になります。
脆弱なマシンを保護するなら、単純に ICMP フラグメントをブロックできます。 通常の ICMP パケットは分割を要求するほど大きくはありませんから、大きな ping を排除する以外他には影響を与えません。 (不確かですが)私は、ICMP フラグメントを落すために、サイズオーバーの ICMP パケットの最後のフラグメントだけを要求し、その結果、最初のフラグメントだけをブロックするシステムがあるという報告を聞いたことがありますが、最初のフラグメントだけをブロックするようなシステムはお勧めできません。
私は ICMP を使うすべてのプログラムを見てきましたが、TCP や UDP フラグメント(あるいは不明のプロトコル)は、このような攻撃に対して使うことができないという理由がないので、 ICMP フラグメントをブロックするのは、間に合わせの解決でしかありません。
Teardrop と Bonk と言われるものは、重複するフラグメントを目的にしている 2種類の攻撃(おもにMicrosoft Windows NT マシンに対して)です。 Linux ルータがデフラグ機能を持っているか、攻撃されやすいマシンにすべてのフラグメントを禁止するのは別のオプションです。
信頼性の低い TCP スタックは、パケットが多数のフラグメントになっていて、それらをすべて受信できないとき、大量のフラグメントを扱うのに問題を持っているものがあると言われています。 Linux はこのような問題がありません。 フラグメントを破棄(正当に使用されたものも壊すかもしれません)するか、または、 `IP: always defragment' を `Y' と(あなたの Linux マシンがこれらのパケットに対して唯一取り得る経路である場合のみ)選択したカーネルをコンパイルすることで排除できます。
ファイアウォールルールを変更するとき、タイミングの問題があります。 不手際があると、変更の途中でにパケットを通してしまいます。 安易なやりかたとしては次のような方法があります:
# ipchains -I input 1 -j DENY
# ipchains -I output 1 -j DENY
# ipchains -I forward 1 -j DENY
. 変更します ...
# ipchains -D input 1
# ipchains -D output 1
# ipchains -D forward 1
#
変更している間、すべてのパケットが破棄されます。
変更が単一のチェインに限定されたものなら、新しいルールで新しいチェインを作りたいかもしれません。 新しいチェインを示すものと、古いチェインを示すルールを置き換えます(`-R')。 そうすれば、古いチェインを削除できます。 この置き換えはアトミックに(他のものには影響しないで)行われます。
IP 偽装は、ホストが別のホストから請求されるパケットを送り出す技術です。 パケットフィルタリングは、このソースアドレスをもとに判定するので、 IP 偽装はパケットフィルターをごまかすために使うものです。 SYN 攻撃やしずく(Teardrop)、また命取りの Ping(Ping of Death) やそれに似たもの(それらが何者かを知らないなら心配は不用です)を使っている攻撃者の身元を隠すためにもまた使われます。
IP 偽装を防御するもっともよい方法は、ソースアドレス認証(Source Address Verification)と言われるもので、それはルーティングコードによって行われるもので、全くファイアウォールではありません。
/proc/sys/net/ipv4/conf/all/rp_filter
というファイルを探して下さい。
これがあるなら、始動するたびにソースアドレス認証(Source Address Verification)を有効することが正しい解決になります。
このようにするため、いずれかのネットワークインターフェースが初期化される前に、お使いの init スクリプトのどこかに次の行を加えます。
# これがもっとも良い方法です: ソースアドレス認証
# (Source Address Verification) を有効にし、現在あるものとこれから
# 使うすべてのインターフェースに偽装保護をします。
if [ -e /proc/sys/net/ipv4/conf/all/rp_filter ]; then
echo -n "Setting up IP spoofing protection..."
for f in /proc/sys/net/ipv4/conf/*/rp_filter; do
echo 1 > $f
done
echo "done."
else
echo PROBLEMS SETTING UP IP SPOOFING PROTECTION. BE WORRIED.
echo "CONTROL-D will exit from this shell and continue system startup."
echo
# コンソール上でシングルユーザシェルを起動します。
/sbin/sulogin $CONSOLE
fi
これができないなら、すべてのインターフェースを保護するために手動でルールを書き加えます。
この場合はそれぞれのインターフェースについての知識が必要です。
カーネル 2.1 は自動的に127.* のアドレス(ローカルループバックインターフェース lo
に予約されたもの)から要求するパケットを拒否します。
例えば eth0
, eth1
そして ppp0
の 3つのインター
フェースがあります。
インターフェースのアドレスとネットマスクを知るために ifconfig
を使うことができます。
例えば、 eth0
がネットマスク 255.255.255.0 のネットワーク 192.168.1.0 にアタッチされ、 eth1
はネットマスク 255.0.0.0 のネットワーク 10.0.0.0 にアタッチされ、 ppp0
がインターネット(予約されたプライベート IP アド
レスを除いて、どんなアドレスでも許されます)。次のようなルールを加えるとよいでしょう。
# ipchains -A input -i eth0 -s ! 192.168.1.0/255.255.255.0 -j DENY
# ipchains -A input -i ! eth0 -s 192.168.1.0/255.255.255.0 -j DENY
# ipchains -A input -i eth1 -s ! 10.0.0.0/255.0.0.0 -j DENY
# ipchains -A input -i ! eth1 -s 10.0.0.0/255.0.0.0 -j DENY
#
この方法はお使いのネットワークが変わると、いままでのその状態を維持するためにあなたはファイアウォールルールを変更しなければいけないので、ソースアドレス認証(Source Address Verification)で行うほど良くありません。
2.0 系のカーネルをお使いなら、次に示すようなルールを使って、ループバックインターフェースもまた保護したいかもしれません。 次のようにルールを使います:
# ipchains -A input -i ! lo -s 127.0.0.0/255.0.0.0 -j DENY
#
私はユーザスペースライブラリを書いており、それは`libfw' と呼ばれるソースディストリビューションを含んでいます。 それは ipchains のバージョン 1.3 以上の能力を使用して(IP_FIREWALL_NETLINK のコンフィグオプションを使って)ユーザスペースにパケットをコピーします。
マーク値はパケットのための Service の質 (QoS) パラメータを決めるために使うか、あるいは、パケットがどのようにポートに中継されるかを決めるために使うことができます。 私はどちらも利用していませんが、あなたがそれについて書いてみようと思うなら、どうぞ私に連絡をして下さい。
状態観察(stateful inspection)(私はダイナミックファイアウォールという言葉を提唱します)のようなことは、このライブラリを使うユーザスペースで実装されるでしょう。 その他の素晴らしいアイディアは、ユーザスペースデーモンで探すことでユーザごとの基盤上でパケットをコントロールします。 これはとても簡単でなければなりません。
ftp://ftp.interlinx.bc.ca/pub/spf 上記は、 Brian Murrell の SPF プロジェクトのサイトで、それはユーザスペースで接続の追跡をします。 低バンド幅のサイトに重要なセキュリティを追加しています。
現在、SPF についての文書はほとんどありませんが、次のものは Brian が質問に答えたものをメーリングリストに投稿したものです。
> それこそが正に私の望むことを行なうと信じています。
> 外部への要求のレスポンスとしてパケットを通すように
> 一時的な''逆流(backward)''のルールをインストールしています。
はい、その通りです。
プロトコルについて理解すればするほど、 "逆流(backward)" のルールはもっと正しくなります。
今のところは、 (覚えで書いています、エラーや手抜かりがあっても許して下さい)
FTP(アクティブとパッシブ、内側と外側の両方)、RealAudio、 traceroute、
ICMP そして初歩的な ICQ( ICQ サーバから入るもの、そして、直接的な TCP 接続からのもの、しかしながらファイル転送のようなことに関する第2 の直接的な TCP 接続などはまだありませんが)をサポートしています。
> SPF は ipchains を置き換えるのですか、それとも補足するのですか。
補足するものです。
ipchains は Linux マシンを越えて伝わるパケットを許可したり、防いだりする道具です。
SPF はドライバであり、トラフィックをたえず監視して、どのように変更するかを ipchains に伝え、 ipchains は、変更をトラフィックパターンに伝えます。
SuSE の Michael Hasenstein は ipchains に ftp 接続の追跡機能を追加するカーネルパッチを書いています。 次のところにあります。 http://www.suse.de/~mha/patch.ftp-data-2.gz
ファイアウォールと NAT は 2.4 で再設計されています。 計画と議論は netfilter のメーリングリストで利用できます。 ( http://lists.samba.orgを見て下さい) このような強化は多くの利便性の問題を解決し、(実際、ファイアウォールやマスカレードはこのような困難 はないはずです)、そしてもっとはるかに柔軟性のあるファイアウォールの発展を促すはずです。