本文へスキップ
BecomeCoder

サーバーコース · 第3章 サーバーを安全に整える · レッスン15

ファイアウォール ― 必要なポートだけ開ける

ブラウザで完結

導入

サーバーには、SSH(22番)・Web(80/443番)以外にも、実はたくさんの「窓口(ポート)」が存在し得ます。使ってもいないポートまで外に開けっぱなしにするのは、家の裏口も勝手口も全部無施錠にしているようなものです。「必要な窓口だけ開ける」——それを実現するのが ファイアウォール です。

説明

ファイアウォールは、サーバーに出入りするパケットを1つずつ検査し、ルールに従って 通す(ACCEPT)落とす(DROP) かを決める門番です。Linux の代表的な実装が iptables(新しい世代では後継の nft)です。

flowchart LR
    W["外部からの通信"] --> FW{"ファイアウォール<br/>iptables"}
    FW -->|"許可したポート<br/>(22/80/443など)"| S["サーバー内部へ"]
    FW -->|"許可していないポート"| X["破棄(DROP)"]

まずは iptables -L(list)で、今どんなルールが設定されているかを確認します。iptables の操作にはすべて root 権限が必要なので、sudo を付けます。

sudo iptables -L

INPUT チェイン(サーバーに入ってくる通信のルール)を見ると、22番(SSH)と80番(HTTP)が ACCEPT、23番(telnet・古くて危険なプロトコル)が DROP になっているのが分かります。

443番(HTTPS)はまだ許可されていません。新しくルールを 追加(Append) するには -A を使い、対象のチェイン・プロトコル・ポート・動作を指定します。

sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT
  • -A INPUTINPUT チェイン(入ってくる通信)にルールを追加
  • -p tcp … プロトコルは TCP
  • --dport 443 … 宛先ポートが443番
  • -j ACCEPT … 一致したら許可(DROPREJECT にすれば拒否)

追加できたか、もう一度 -L で確認しましょう。

sudo iptables -L

443番の許可ルールが増えているはずです。ルール1つひとつを積み上げていく代わりに、「許可したもの以外は最初から全部落とす」という既定ポリシーを設定するのが、より安全な考え方です。

sudo iptables -P INPUT DROP

-P(policy)は「どのルールにも一致しなかった通信」の扱いを決めます。DROP にしておけば、うっかり穴を開け忘れたポートがデフォルトで塞がっている状態になります。これを ホワイトリスト方式(許可したものだけ通す)と呼び、ブラックリスト方式(拒否したものだけ落とす)より安全とされています。

実務では ufw(Uncomplicated Firewall)のような、より扱いやすいラッパーツールもよく使われます。中身でやっていることは同じ——iptables のルールを、分かりやすいコマンドで組み立てているだけです。仕組みの本体を知っていれば、どのツールを渡されても迷いません。

やってみよう

sudo iptables -L で今のルール(22/80番はACCEPT、23番はDROP)を確認しましょう。sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT でHTTPS用のルールを追加し、もう一度 sudo iptables -L で443番が増えていることを確かめてください。最後に sudo iptables -P INPUT DROP で、既定を「拒否」にする発想も試してみましょう。

演習

443番ポート(HTTPS)への接続を許可するルールを、INPUT チェインに追加してください。

ヒント1を見る

ルールの追加は -A INPUT、プロトコルとポートは -p tcp --dport 443、許可は -j ACCEPT です。

ヒント2を見る

sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT

実際に動かしてみよう

本文のサンプルや演習のコードは、コードブロック右上の「コピー」ボタンでコピーして、下のエディタに貼り付ければそのまま実行できます。

Linux シェル(シミュレート)

ブラウザ内でコマンドを試せる仮想シェルを読み込みます(本物のLinuxカーネルではなく学習用の再現です)。
スクロールして表示された時点でも自動で読み込まれます。