firewall
ファイアウォール

出席調査

出席確認として学生証を教室後ろの入り口近くの出席用PCのリーダにタッチせよ. 出席していない回の実験レポートは提出を認めず,0点として計算されるので 注意すること.

初期設定

システム設定→ ネットワーク→ 有線→ オプション→ IPv4設定で,「方式」を「自動」にして授業ページを読める状態にせよ.

講義

組織の内側と外側をまたぐ通信のうち, 危険な通信,必要のない通信を遮断する技術がファイアウォールである. セキュリティ関連の話題の中でも特に広く使われ,重要な技術の一つである. IP 層の通信はパケットを単位として行われるが,個々のパケットについて 通過させるものと拒否するものに振り分ける処理を パケットフィルタリングとよぶ. ファイアウォールはパケットフィルタリングを用いて 実装されるものをさすことが多い.

現在の Linux OS は OS の本体であるカーネルの機能として パケットフィルタリングを行う能力をもっている.この機能は iptables というコマンドで利用することができる. 現在はどの Linux ディストリビューションでも iptables コマンドを用いてファイアウォールの設定を行うことが 一般的である.

iptables を理解するにはテーブルチェーンの概念 を理解する必要がある.iptables にはいくつかのテーブルが用意されている. このうち,本実習では filter テーブルの利用を説明する. filter テーブルはどのパケットを通過させ,どのパケットを遮断 するかの設定を行う目的で使うテーブルである.

各テーブルには複数のチェーンが用意されている. チェーンによってパケットが処理される過程のどのタイミングで フィルタリングを行うかが異なる.今回説明するのは filter テーブルの INPUT チェーンと OUTPUT チェーンである. INPUT チェーンはホストにパケットが入った時に行うフィルタリングを 記述し,OUTPUT チェーンはホストからパケットが出て行く時に行う フィルタリングを記述する.

チェーンと呼ばれる理由はその処理手順による. チェーンではルールは一直線に並んでおり, 上から順に処理され,マッチした時点で処理が決まる. このため,チェーン内の複数のルールにマッチするような パケットがあったとしても最も上に記述されている ルールに従って処理される.これは プログラムにおける if, elseif, elseif ... を 上から順に書いた場合の処理と同様である. iptabes ではチェーンの任意の位置にルールを追加することができるが チェーンの最後に追加する命令のみを使うことが多い. 計画した順にルールを設定するには,その順で チェーンの最後に追加していくスクリプトを記述すると 設置されたルールの順序がわかりやすいからである.

個々のパケットについて, チェーンの上から順に条件にマッチするかをテストし, 最初にマッチしたルールに従って処理するが, チェーンの最後までテストしてもマッチしなかった パケットについてのデフォルトの処理を指定することができる. これをそのチェーンのポリシー と呼ぶ.

安全性を重視するため,各チェーンのポリシーは拒否(DROP) に設定しておき,必要なパケットだけをルールとして明示する 手法が一般的である.以下,実習を行いながら iptables の利用法を理解する.

実習

一口にインターネットからのアクセスといっても, web, ping などいろいろな種類のアクセスがある. 接続元の IP アドレスごとに許可するアクセスの種類を 変える設定を行い,動作を確認する.

実習0 前提条件の設定

今回の実習の前提条件となる物理的な接続,IP アドレス, サーバのインストールを行う.

実習0.1

物理的な接続と接続情報の設定を行う. 今回の実習で用いるネットワークの構成を図 10.1 に示す. 図に従って接続せよ.

FW実習

図10.1 ネットワーク構成

各班 1 から 4 号機の今回の実験での役割とIPアドレス,サブネットマスク, デフォルトルート(ゲートウェイ),DNSサーバは以下の通りとする. これに従って設定せよ.

1 号機(NAT内ホスト)

1 号機は班のケーブルで班のスイッチングハブと接続する. 設定は全班共通で,以下の通りとする.

IP アドレス/サブネットマスク
192.168.1.2/24
デフォルトルート
192.168.1.1
DNS サーバ
172.17.254.254

2 号機(NATサーバ,Webサーバ)

2 号機には USB LAN を接続し,班のスイッチングハブに 班のケーブルで接続する.IP アドレス他の設定は 以下の通りとする.2 号機には 2 個の有線 ネットワークデバイスがあるが,MAC アドレスが d8:d3:85 で始まるものが内蔵 LAN ポート,00:24:a5 で始まるものが USB LAN ポートである.

表 10.1 2 号機設定

内蔵 LAN
IPアドレス/サブネットマスク
内蔵 LAN
デフォルトルート
内蔵 LAN
DNS サーバ
USB LAN
IPアドレス/サブネットマスク
1 班 172.17.2.8/16 172.17.254.254 172.17.254.254 192.168.1.1/24
2 班 172.17.2.36/16 172.17.254.254 172.17.254.254 192.168.1.1/24
3 班 172.17.2.9/16 172.17.254.254 172.17.254.254 192.168.1.1/24
4 班 172.17.2.37/16 172.17.254.254 172.17.254.254 192.168.1.1/24
5 班 172.17.2.10/16 172.17.254.254 172.17.254.254 192.168.1.1/24
6 班 172.17.2.38/16 172.17.254.254 172.17.254.254 192.168.1.1/24
7 班 172.17.2.11/16 172.17.254.254 172.17.254.254 192.168.1.1/24
8 班 172.17.2.39/16 172.17.254.254 172.17.254.254 192.168.1.1/24
9 班 172.17.2.12/16 172.17.254.254 172.17.254.254 192.168.1.1/24
10 班 172.17.2.40/16 172.17.254.254 172.17.254.254 192.168.1.1/24
11 班 172.17.2.13/16 172.17.254.254 172.17.254.254 192.168.1.1/24
12 班 172.17.2.41/16 172.17.254.254 172.17.254.254 192.168.1.1/24
13 班 172.17.2.14/16 172.17.254.254 172.17.254.254 192.168.1.1/24
14 班 172.17.2.42/16 172.17.254.254 172.17.254.254 192.168.1.1/24

3 号機(NAT外メンテナンスホスト)

表 10.2 3 号機設定

IPアドレス/サブネットマスク デフォルトルート DNS サーバ
1 班 172.17.2.15/16 172.17.254.254 172.17.254.254
2 班 172.17.2.43/16 172.17.254.254 172.17.254.254
3 班 172.17.2.16/16 172.17.254.254 172.17.254.254
4 班 172.17.2.44/16 172.17.254.254 172.17.254.254
5 班 172.17.2.17/16 172.17.254.254 172.17.254.254
6 班 172.17.2.45/16 172.17.254.254 172.17.254.254
7 班 172.17.2.18/16 172.17.254.254 172.17.254.254
8 班 172.17.2.46/16 172.17.254.254 172.17.254.254
9 班 172.17.2.19/16 172.17.254.254 172.17.254.254
10 班 172.17.2.47/16 172.17.254.254 172.17.254.254
11 班 172.17.2.20/16 172.17.254.254 172.17.254.254
12 班 172.17.2.48/16 172.17.254.254 172.17.254.254
13 班 172.17.2.21/16 172.17.254.254 172.17.254.254
14 班 172.17.2.49/16 172.17.254.254 172.17.254.254

4 号機(NAT外一般ホスト)

表 10.3 4 号機設定

IPアドレス/サブネットマスク デフォルトルート DNS サーバ
1 班 172.17.2.22/16 172.17.254.254 172.17.254.254
2 班 172.17.2.50/16 172.17.254.254 172.17.254.254
3 班 172.17.2.23/16 172.17.254.254 172.17.254.254
4 班 172.17.2.51/16 172.17.254.254 172.17.254.254
5 班 172.17.2.24/16 172.17.254.254 172.17.254.254
6 班 172.17.2.52/16 172.17.254.254 172.17.254.254
7 班 172.17.2.25/16 172.17.254.254 172.17.254.254
8 班 172.17.2.53/16 172.17.254.254 172.17.254.254
9 班 172.17.2.26/16 172.17.254.254 172.17.254.254
10 班 172.17.2.54/16 172.17.254.254 172.17.254.254
11 班 172.17.2.27/16 172.17.254.254 172.17.254.254
12 班 172.17.2.55/16 172.17.254.254 172.17.254.254
13 班 172.17.2.28/16 172.17.254.254 172.17.254.254
14 班 172.17.2.56/16 172.17.254.254 172.17.254.254

設定が完了すると 3,4 号機から 2 号機の外部IPアドレス(内蔵LANに割り当てたIPアドレス) にping が通るはずなので確認せよ.通らない場合は 接続,設定を見直せ.

1 号機からは 2 号機の内部IPアドレス(USB LANに割り当てたIPアドレス) にping が通るはずなので確認せよ.通らない場合は 接続,設定を見直せ.

実習 0.2

第 5 回実習(NATの設定) を参考に 2 号機で NAPT を起動時から実行される ように設定せよ. 設定終了後 2 号機を再起動し, 1 号機が外部ウェブページが閲覧できる状態であることを確認せよ.

実習 0.3

第 9 回実習(ウェブ) で 2 号機にもウェブサーバがインストールされ, 実行されているはずである.全てのホストで FireFoxブラウザを起動し,URL 欄に 2 号機の外部IPアドレス(内蔵LANに割り当てたIPアドレス) でアクセスし,起動していることを確認せよ. ウェブサーバがインストールされていなければ インストールせよ.

実習 1 ブラックリストによるアクセスコントロール

一般に,基本ルールを「許可」とし,禁止する項目だけを 明記する手法をブラックリストを用いた手法という. セキュリティ上危険が生じやすい手法だがパケットフィルタリングの 動作を理解しやすいため,最初に ブラックリストの手法で 4 号機からの ping を禁止する実習を行う.

実習 1.1

実習 0 で3,4号機より 2 号機の外部IPアドレスへのウェブアクセス, ping が可能になっていることが前提である.

2号機での iptables の操作を行う. まず,2号機で以下のコマンドを実行し,iptable の初期状態を確認せよ.

user1@pc002:~$ sudo iptables -nL

初期状態では上のコマンドの結果は図 10.2 のようになるはずである.

図 10.2 iptables の初期状態

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

iptables は,デフォルトではテーブルとして filter テーブルを 指定したことになる. (第 5 回実習,NATの設定では nat テーブルを明示的に指定するため,-t オプションを用いて iptables -t nat としている) 図 10.2 よりfilter テーブルには 初期状態で INPUT, FORWARD, OUTPUT の 3 つのチェーンがあり, いずれもチェーンの内容が空で policy が ACCEPT であることから, すべてのパケットを通す設定になっていることがわかる.

例えば 2 号機の外部 IP アドレスが XXXX, 4号機の IP アドレスが YYYY だったとすると, YYYY からの ping を拒否するためには 以下のコマンドを実行すればよい.

user1@pc002:~$ sudo iptables -A INPUT -p icmp --icmp-type echo-request -s YYYY -d XXXX -j DROP

コマンドを実行し,sudo iptables -nL の結果を確認せよ.

iptables で間違ったルールを登録してしまった場合,登録したコマンドの "-A" の部分を "-D" に変えたコマンドを入力することで該当する ルールを消すことができる.(要管理者権限)

iptables -nL コマンドの結果より INPUT チェーンにルールが追加されていることがわかる.このように iptables -A ... というコマンドを実行するたびにチェーンの最後にルールが追加 されてゆく.ルールは上から実行され,マッチすると処理が実行される. どこにもマッチしないパケットは最後に policy に設定された処理を行う.

3,4 号機から 2 号機の外部IPアドレスへの ping と ウェブのアクセスを行い, 4 号機から 2 号機への ping だけが 通らなくなっていることを確認せよ.

実習 2 ホワイトリストによるアクセスコントロール

policy はデフォルトの処理といえる.セキュリティを重視した iptables の設定の基本方針は デフォルトを DROP(破棄)にしておき,必要なもののみを明示して許可するという ものである.この方針に従ってすべての policy を DROP に設定し, ping に必要なパケットを通過する設定を行う. このように基本ルールを「不許可」とし,許可する項目だけを 明示する手法を一般にホワイトリストを用いた手法という.

実習 2.1

まず 2 号機で iptables -nL を実行し, 現在の filter テーブルの状況を確認する.上で 設定したルールが INPUT チェーンに残っているので以下のコマンドでこれを 消去する.

user1@pc002:~$ sudo iptables -F

今回は必要ないが,初期状態に戻すには以下のコマンドで 自作のチェーンを作っていた場合のための破棄, iptables のカウンターのリセットも行う.

user1@pc002:~$ sudo iptables -X
user1@pc002:~$ sudo iptables -Z

ルールが消去されていることを iptables -nL で確認せよ.

この時点で 3, 4 号機から 2 号機へ ping が通るようになる. 確認せよ.

次にすべてのチェーン のポリシーを DROP に設定する. 以下のコマンドを順に入力すればよい.実行後, policy が DROP になっていることを iptables -nL で確認せよ.

user1@pc002:~$ sudo iptables -P INPUT DROP
user1@pc002:~$ sudo iptables -P FORWARD DROP
user1@pc002:~$ sudo iptables -P OUTPUT DROP

この時点で 3, 4 号機から 2 号機へ ping やウェブ すべての通信が通らなくなる.確認せよ. キャッシュが残っていると接続できたように見えるので, 3,4 号機のウェブブラウザの 「履歴」→「最近の履歴を消去」から「すべての履歴を消去」 を行い,履歴を消去してから 2 号機に アクセスを試みよ.

次に 3 号機から 2 号機へのping を認める明示的な設定を行う. 3 号機の IPアドレスを ZZZZ とする. ping は通信が往復するので 往路用と復路用の設定が必要になる. 下のコマンドを実行せよ.

user1@pc002:~$ sudo iptables -A INPUT -p icmp --icmp-type echo-request -s ZZZZ -d XXXX -j ACCEPT
user1@pc002:~$ sudo iptables -A OUTPUT -p icmp --icmp-type echo-reply -s XXXX -d ZZZZ -j ACCEPT

図10.3 3号機のping許可設定

iptables -nL で状況を確認し,もし間違ったルールを設定したら

user1@pc002:~$ sudo iptables -F

コマンドでルールを破棄し,図 10.3 の 2 つの iptables -A の作業をやり直せ. 設定が終れば実際に 3 号機から 2 号機外部IPアドレスへ ping が通ることを確認せよ.

毎回これらのことをタイプするのは大変なので iptables の設定は コマンドの系列をシェルスクリプトに書いておき.シェルスクリプトとして 実行することが一般的である.

設定が簡単になる方法として,自分から出て行くパケットが 対象の OUTPUT チェーンのポリシーを ACCEPT にしておき, 接続が確立されたパケットは INPUT と FORWARD を通過させるという方法がよく使われる. 上記のことを行うシェルスクリプトは以下の ようになる.ex2.sh という名前で保存せよ.この方法では OUTPUT を許可するルールは不要である.

#!/bin/sh

iptables -F
iptables -X
iptables -Z

iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -i lo -j ACCEPT

iptables -A FORWARD -i eth2 -o eth1 -s 192.168.1.0/24 -j ACCEPT
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT

#ICMP from trusted host
iptables -A INPUT -p icmp --icmp-type echo-request -s ZZZZ -d XXXX -j ACCEPT

図 10.4 ex2.sh (ZZZZからXXXXへの pingのみ許可)

ex2.sh では OUTPUT のポリシーを ACCEPT に設定した上で
iptables -A INPUT -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT
を実行している.これによりこちらから接続を確立させたパケットの 流入を許可している.

iptables -A INPUT -i lo -j ACCEPT
という設定はサーバー自身から自分へのパケットを 全て許可する設定で,lo はループバックアドレスと呼ばれ,自分自身を指す. 「受信側(-i)が自分自身(lo)のパケットが 入ってきたとき(INPUT)は受理(-j ACCEPT)」 という設定になる。

NAT のための設定として, FORWARD チェーンに関しても,内部インターフェース eth2 から外部 インターフェース eth1 へ出て行くパケットを許可し, こちらから接続を確立したパケットは全て許可している.

chmod 755 ex2.sh で実行属性をつけ sudo ./ex2.sh で実行せよ. iptables -nL による確認と,実際に 3 号機から 2 号機外部IPアドレスへ ping を行い,ping が通ることを確認せよ.

実習 2.2

設定の試行錯誤中,たびたびファイアウォールを全て通す状態に戻したいときが あるが,チェーンの消去,カウンターのリセット,ポリシーの変更を 行うコマンドを入力しなければならない. そのためのスクリプトを作っておくと便利である.以下のスクリプト を allaccept.sh として作成し.試してみよ.ルール,チェーンの破棄だけでは policy が初期化さないため,policy の再設定も必要なことに注意せよ.

#!/bin/sh

iptables -F
iptables -X
iptables -Z

iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT

図 10.5 allaccept.sh

実習 3 特定サービスの許可

実習 2 に追加して, すべてのアドレスからのウェブのアクセスを許可する設定を行う. これはex2.sh を改良して行う.

実習 3.1

まず,allaccept.sh を実行し,フィルタリングをおこなっていない 状態で 1,3,4 号機のウェブラウザのURI欄に 2 号機の外部IPアドレスを入力して ウェブサーバにアクセスし,アクセスが可能なことを確認せよ.

次に,2 号機で ex2.sh のフィルタリングを行った状態で, 1,3,4 号機のウェブブラウザから 2 号機のウェブページにアクセスできないことを 確認する. キャッシュが残っていると接続できたように見えるので, 1,3,4 号機のウェブブラウザの 「履歴」→「最近の履歴を消去」から「すべての履歴を消去」 を行い,履歴を消去してから 2 号機に アクセスを試みよ.

ウェブのアクセスを許可するには新規パケットの 80 番ポートを指定して アクセスを許可すればよい.また,DNS (53番ポート)も必要になるので それも許可する。 ex2.sh を ex3.sh という名前でコピーし(cpコマンド),ex3.sh の最後に 以下の行を追加し,保存せよ.下記のコマンド中の "0.0.0.0/0" は 全てのアドレスを意味する.

#HTTP
iptables -A INPUT -p tcp --syn -m state --state NEW -s 0.0.0.0/0 -d XXXX --dport 80 -j ACCEPT
#DNS
iptables -A INPUT -p udp -s 0.0.0.0/0 --sport 53 -d XXXX -j ACCEPT

2 号機で ex3.sh のフィルタリングを実行し,iptables -nL で確認し, 実際に 1,3,4 号機のウェブブラウザから 2 号機のウェブサイトにアクセスできることを確認せよ. 2 号機のウェブサーバのログ (第 9 回実習参照)のうち, このアクセスに対応するものを確認せよ.

ex3.sh が実行されている状態では, ウェブについては全ての IP アドレスから許可, ping については 3 号機からのみ許可という 設定になっている.4 号機からは ウェブは接続できるが ping が通らない状態になっているはずである.確認せよ.

実習 3.2

ex2.sh や ex3.sh では IP アドレスの値が 行の中に散らばって書かれている. このように定数をプログラム中に埋め込むことをハードコーディングといい, IP アドレスの部分を変更する場合など,作業性が悪い.

シェルスクリプトの変数を使えば IP アドレスの指定部分を スクリプトの最初に集めることができる.変数の値を 設定するには,たとえば #!/bin/sh の後, 最初のコマンドが始まる直前に

myhost='XXXX'
trusted='ZZZZ'
internal_net='192.168.1.0/24'
all='0.0.0.0/0' 

として IP アドレスの文字列を 3 つの変数に設定しておき, 以下のコマンドの IP アドレスの部分をこの変数を使う形に 書き換えれば良い.ex2.sh と ex3.sh をそれぞれ コピーして ex2_2.sh と ex3_2.sh を作成し,新しい スクリプトをこの形式に書き換えよ.

実習 4 SSH の利用

外部のネットワークを通ってサーバを遠隔操作する場合, 暗号化通信を行う SSH (secure shell) を用いる必要がある. SSH サーバソフトウェアは Ubuntu Linux では openssh-server というパッケージで提供されている. 2 号機で以下のコマンドで SSH サーバをインストールせよ.

user1@pc002:~$ sudo apt-get update
user1@pc002:~$ sudo apt-get install openssh-server

1,3,4号機から SSH を用いて 2 号機ログインする実習を行う. 以下の作業は 1,3,4 号機の担当者が行う.

班員全員の 2 号機のアカウントを確認するため, 2 号機に直接自分のログイン名とパスワードでログインできる ことを確認せよ.自分のアカウントがなければ 2 号機上で 管理者ユーザとして作成せよ. (ユーザーの追加参照)

インストールした時点で SSH サーバは動作しているが, 実習 3 終了時では iptables のポリシーが「拒否」に設定 されているので 他ホストからのアクセスができない状態になっている. 実習 2.2 で作成した allaccept.sh を実行してファイアウォールを 解除してから 1,3,4 号機で以下のコマンドを実行せよ. (XXXXは 2 号機の外部 IP アドレス)

user1@pc001:~$ ssh XXXX

現在自分がローカルホストでログインしているログイン名と 異なるログイン名でリモートホストにログインする 場合は -l オプションを使ってログインすることができる. 以下の例はリモートホストの user2 というユーザーに ログインする場合のコマンドである.

user1@pc001:~$ ssh -l user2 XXXX

ssh コマンドは最初に接続するときに警告

Are you sure you want to continue connecting (yes/no)?

を出すので yes を入力する.パスワードを聞かれるので 2号機でのパスワードを入力するとログインできる. ls, cd, hostname, ifconfig などでログインできていることを確認せよ.

ex3_2.sh をベースに ホワイトリスト方式で新規に入ってきた ssh を INPUT チェーンで許可する 設定を追加する. まず ex3_2.sh を ex4.sh という名前でコピーせよ.

ex3_2.sh では実習 3.2 において 3号機の IP アドレスを シェル変数 trusted に格納しているので IP アドレスを 直接書かなくても $trusted と書ける. 同様に $myhost として自分の IP 外部アドレスを書ける. sshのポート番号は 22 番なので ssh をメンテナンスホストである $trasted を対象に許可するためには,ex4.sh に以下の行を 追加すればよい.実際に追加作業を行え.

#SSH from trusted host 
iptables -A INPUT -p tcp --syn -m state --state NEW -s $trusted -d $myhost --dport 22 -j ACCEPT

ここまで実行した状態で,ssh による 2 号機へのログインは 外部メンテナンスホストである 3 号機からは可能で 単なる外部ホストとして設定されている 4 号機からは 不可能になっている.確認せよ.

今回は説明しなかったが, 実際に外部からアクセスできる形で SSH サーバを運用する場合は パスワードによるログインを禁止し, 公開鍵暗号を用いたログインのみ許可するように設定するべきである.

NAT の設定もiptables で行うので,両方の設定操作を行う シェルスクリプトを作成し, 起動時のNAPTの実行 の手順を利用することで起動時にファイアウォールと NAPT が動作するように設定できる.

課題

第 9 回課題「iptables」 を提出せよ.


Updated in July 4, 2010, index.html, Yamamoto Hiroshi