ufw(Uncomplicated FireWall)は、Ubuntuで標準的に利用できる、「iptablesを簡単に設定するツール」です。ufwを利用することで、「外部からの接続は基本的に受け付けない」「sshだけは許す」などといった設定を、iptablesにくらべて格段に少ない操作で実現できます。
今回と次回の2回にわけて、ufwを使って、サーバーなどの設定を簡単に行うレシピを紹介します。
ufwの基本
ufwは、Canonicalの社員であり、Ubuntuのセキュリティ関連モジュールやセキュリティアップデートを主に担当しているJamie Strandboge氏が中心になって開発している、「iptablesのフロントエンド」となるツールです[1]。Ubuntuには8.04で取り込まれています。過去に本レシピでも、第45回でごく軽く内容を紹介しています。
今回はコマンドラインからufwを使う方法のうち、基礎的な部分を紹介します。次回はより実践的な設定の例と、gufwによるGUI設定の手順を紹介する予定です。
実際にufwを体験する前に、ufwとiptablesの違いを把握しておきましょう。
iptablesは、Linuxでファイアウォールを設定するための標準的なツールです。iptablesの各種モジュールを利用してNetFilterを設定した場合、ファイアウォールとして求められる、ほぼありとあらゆる設定を行うことができます。また、多くの設定方法が存在し、さらにその設定の自由度も高いものです。
ですが、iptablesはその自由度と機能の豊富さから、設定を行うのに専門の知識が必要になります。少なくとも、いきなりiptablesを利用して自由自在に設定を行うことは困難でしょう。たとえば以下はiptablesを用い、「30秒に5回、sshアクセスを試みてきたホストからの接続は300秒間拒絶する」という設定を行ったものです[2]。
正当な通信を通すための設定や、「sshへのアクセス回数をカウントする」「閾値を超えたらブロックする」「ログを残す」などといった機能が組み合わさり、すぐに読み取るのは困難なものとなっています。実現したいのは、単に「sshのポートへ一定回数接続が来たら拒否」ということだけですが、iptablesで実現しようとすると、非常に複雑な設定になってしまいます。
これをufwで設定するとどうなるのか、を端的に示すのが以下です。ufwで設定を行った場合、非常に単純に設定できることが分かるはずです[3]。
ufwは「ソフトウェアファイアウォールとしての機能を、できるだけ単純なインターフェースで設定する」(注4)、という設計思想に基づいたツールです。できないことも存在しますが、「できること」であれば、きわめて簡単に設定が可能です。ここからは実際にufwを用いて、接続の制限や許可を設定してみましょう。
ufwの基本的な使い方
前述の通り、ufwの一部の機能は第45回で紹介していますが、ここでは一からufwを使う方法を説明します。多くの場合はサーバーで役に立つ機能ですが、「デスクトップマシンにサーバー的な機能を導入しておき、それを他のマシンから利用する」などといった場合にはデスクトップ環境でも役に立つでしょう。
最初にすべての通信を無効にする
ufwの操作は、ターミナルから行います。[アプリケーション]→[アクセサリ]→[端末]を開いて操作を行ってください。ufwは基本的に、「デフォルトではあらゆる外部からの通信を拒否し、許可する通信を定義していく」形で設定を行います(「sudo ufw default ALLOW」を実行することで、「デフォルトでは全て通すが、不要な通信のみを落とす」設定にすることも可能です。ただし、この設定を使うことはあまりないでしょう)。
以下のように、「sudo ufw enable」と端末上で入力してください(図1)。
これでufwが有効になっています。ufwは一度有効化すると、システム起動時に自動的に有効になります。この状態を解除するには「sudo ufw disable」を行います(が、ほとんどの場合無効化する必要はないでしょう)。
ここから設定を行っていくことになりますが、ufwが有効になった時点で、まっさきに外部からの通信を受け付けないように設定しておきましょう。以下のように操作します。
この状態は、外部から見ると、接続を試みるとConnection Refusedが返るのではなく、単にタイムアウトする状態です。もしConnection Refusedを返したい場合は、「sudo ufw default REJECT」を実行してください。
これらの設定を行っても、「外部に出ていく」通信(アウトバウンド)は可能です。ufwはあくまで、「外からの」通信(インバウンド)だけを制御します[5]ので、たとえば、「トロイの木馬などに感染した場合に、想定していない通信をせき止める」といった用途に利用することはできません。
その時点でufwが動作しているかどうかは、「sudo ufw status」で確認できます(図2)。何も設定していない場合、「状態:アクティブ」とだけ表示されるはずです。無効になっている場合は、「状態:非アクティブ」です。
また、ufwのコマンド一覧は「sudo ufw help」で出力することができます(図3)。コマンドの引数を忘れてしまった場合は、これらを利用すると良いでしょう。
許可する通信を設定する
ufw enableを実行して全ての通信を遮断したら、「必要なポートを開く」作業を行います。以下ではSSHが利用する、TCP/UDPそれぞれのポート22を開いています。
この状態でufw statusを実行すると、図4のように、ポート22に対する許可が行われているのが分かるでしょう。
必要であれば以下のようにすることで、TCPのみに許可を与えることもできます(SSHを利用するにはTCP/UDP双方が必要です。この例のようにTCPだけを許可することは望ましくありません)。
不要になったルールは、次のように、追加のためのコマンドの頭に「delete」をつけて実行すれば削除できます。
また、ポート番号ではなく、サービス名で指定することも可能です。サービス名とポート番号の対応は、/etc/servicesに書かれたものが利用されます。「delete」を頭につけることで削除もできます。例は次のようになります。
接続頻度を制限する
SSHやIMAP、HTTPSのBASIC認証などの、パスワードによる認証を用いるサービスでは、「でたらめなパスワードを打ち込み続け、偶然正しいものと一致することを期待する」(ブルートフォース)攻撃への対策が必要です。
SSHでは公開鍵による認証を行うことで、パスワードよりも強固な、事実上ブルートフォース攻撃では破れない設定にすることも可能ですが、鍵の管理が面倒など、パスワード認証に比べて不便な点もあり、すべての場合で利用できるわけでもありません。
すでにufwとiptablesの比較のところでも触れたように、このような場合はufwの「接続頻度を制限する」機能が便利です。この指定はLIMITキーワードを用いて行います。以下のように操作しておくことで、「執拗に接続してくるアクセス」を拒否することが可能です。
許可・拒否のログを取る
このようにして「allow」を設定したルールに基づいて通信が許可された場合や、「limit」で接続が制限された場合、/var/log/syslogに以下のようなログが記録されます。
これらのログの出力は、ufwのLOGGING設定に依存します。わざわざufw allowルールによる接続許可をロギングしたくない場合、以下のようにレベル指定を「low」にします。
lowは、「default以外のルールによるブロック」を、流量制御しつつ出力します。以外のログの出力レベルには、off(完全に無効)、medium(流量制御ありでallow・denyにマッチしたもの+不正なパケット+新しいコネクションを出力。デフォルト値)、high(mediumの流量制御なし版)、full(すべてのログを記録)となっています。詳細は、man ufwかsudo ufw helpを参照してください。
ただし、ほとんどの場合はlowとmeduimを使い分ければ充分でしょう。また、highやfullを利用する場合、膨大なログが出力されるので、ディスク容量に注意してください。
「app」による指定
※この機能は、8.10以降のUbuntuで利用可能です。
ufwでは、ポート単位の指定だけでなく、「アプリケーションごと」に設定を行うことも可能になっています。たとえば、Sambaの接続許可を行う場合を考えてみましょう。
Samba Serverは名前解決やマスタブラウザの利用のために、4種類のポートを利用して動作します。これを8.04のufwを利用して許可する場合、以下のようにnetbios-ns(TCP/UDP 137)・netbios-dgm(TCP/UDP 138)・netbios-ssn・microsoft-ds(TCP/UDP 445)のそれぞれを許可する必要があります。
しかし、本来の目的は、「Sambaのサービスを許可する」ことであり、これら4種類のサービスを許可するのはあくまで手段でしかありません。そこでufwでは、/etc/ufw/application.d/ディレクトリにアプリケーション定義ファイルを置くことで、アプリケーション単位で接続の可否を設定できるようになっています。このディレクトリにアプリケーション定義ファイルを配置するのは、サーバーアプリケーションのパッケージ(cupsやsamba・postfixパッケージ)の仕事となっており、ユーザーがこれらを意識する必要はありません。この機能は、以下のように利用します。
まず、登録されている「アプリケーション」の一覧を調べます。図5のようにアプリケーションごとの定義の一覧が表示されるはずです。
あとは「allow」や「deny」の引数としてアプリケーション名を与えるだけです。
これにより、サービス単位(=ポート単位)で接続許可を行わなくても、一度に設定を行うことができます。
なお、これらのアプリケーション名は、/etc/servicesに登録されているサービス名と区別するため、先頭が大文字で始まることになっています。
引き続き、次回はufwのより詳しい操作方法や、GUIからの利用について説明します。