先週に引き続き、今回もufwを使いこなすためのレシピを紹介します。今回は実践編となりますので、先週の基礎操作編とあわせて利用してください。
特定のIPアドレスからの接続を許可する
ネットワークの構成上、「このIPアドレスからの接続は安全であると仮定してもいい」(そこには自分が普段使うマシンしかない)といったこともあるでしょう。このような場合は、次の構文を用います。
この設定は、「192.168.254.*に属するホストからのすべての通信を許す」というものです。個別のホスト単位にしたい場合は、次のようにIPアドレスを指定してください。以下では、192.168.254.10からのすべての通信を受け付けるように設定しています。
さらに、以下のようにポート単位で「そのホストからの接続を許可する」設定を書くことができます。以下は、SSHが利用するポート(=22)を、192.168.254.20というホストに対して許しています。
上記では/etc/servicesに書かれている「ssh」というサービス名での表記をしていますが、「22/tcp」などとすることも可能です。さらに、ここで行う指定でapp構文を利用することもできます。
以下は、「192.168.254.*のホストからのSamba関連の接続要求は許す」というものです。
ルールの組み合わせと入れ替え
前掲のLIMITキーワードによる指定を行った場合、scpによるコピーなど、「適切な通信にもかかわらず、ufwのLIMIT条件にマッチしてしまう」といった困った状態が起こりえます。
次のような環境を想定してみましょう。
- SSHサーバーは、外部のネットワークと内部のネットワークの双方に接続されている。
- 外部からのSSHブルートフォースを防ぎたい。
- 内部からは、192.168.254.10からscpを用いてコンテンツをアップロードしている。
- このscpは非常に頻繁に行われている。
このような環境では、そのままではsudo ufw limit sshを実行するわけにはいきません。scpによるコピーまでもLIMIT条件に引っかかってしまい、通信不能になってしまうおそれがあるからです。
このような場合は、「特定のIPアドレスからの接続を許可」し、「それ以外の接続はLIMIT」という設定が必要です。次のようにルールを組み合わせて設定します。
このように設定することで、192.168.254.10からのssh(=scp)接続は自由に行える一方、それ以外のホストからの接続はLIMITにより制限される、という状態になります(図1)。
ここで重要なのは、ルールの設定順です。
上記の設定手順では、「特定のIPアドレスからの接続を許可」した後に、「全ての接続をLIMIT」という順番でルールを指定しています。ufwのルールは上からチェックされますので、この順番が逆になると、「全ての接続をLIMIT」だけが有効になってしまいます。ufwは通常の動作では、「登録した順番で」ルールを評価します。このため、以下のように「全てのSSH接続のLIMIT」を先に設定してしまった場合、そちらの方が優先されてしまいます。
この状態でstatusを見ると、以下(図2)のように、「LIMIT」指定の方が上に来ているはずです。
このような状況で、正しい設定に戻すにはどうすればいいのでしょうか?
一つの方法は、単純に、「全てのSSH接続のLIMIT」指定を削除してから、再度追加することです。以下のように操作します。
この状態でstatusを見ると、正しい設定になっていることが確認できます(図3)。
ただし、必ずしも削除と追加だけで問題を解決できるわけではありません。より複雑な設定の場合、「設定ルールのこの場所に、新しいルールを追加したい」といった要望もありえます。たとえば、「192.168.254.10からのSSHは許し、192.168.254.20からのSSHはLIMITで限定的に許す。他のSSH接続は全て拒否」などといった場合です。
このような場合、sudo ufw status numberedとinsertキーワードを利用して、「指定した箇所にルールを追加」する操作を行います。
最初に、ufw status numberedで、ルールのナンバーを表示する状態で一覧します(図4)。
図4における、「1」、もしくは「2」の欄にLIMIT 192.168.254.20のルールが入れば良いわけです[1]。ufwの「insert」を使うことで、「1」の位置にルールを挿入することができます。insertで指定しない場合、常にルールの最後の位置に追加されることになります[2]。
この操作を実際に行った例は、図5のようになります。
gufwの利用
コマンドによる操作に抵抗がある場合、ufwには「gufw」というGUIフロントエンドが存在します(注3)。デフォルトではインストールされていませんが、Synapticからgufwパッケージをインストールするか、以下のコマンドで導入できます。
gufwは、[システム]→[システム管理]→[ファイアウォールの設定]から起動できます(図6)。
メインウインドウ(図7)で、ufwの有効/無効の切り替え(ufw enable・disable)、「外部からのトラフィックを拒否・許可する」(ufw default deny・default allow)、各種ルールの追加が可能です。
また、[編集]→[設定]から、gufwそのものの設定を変更することが可能です(図8)。
設定のうち、「ログイン時に自動起動する」には注意が必要です。これはufwの有効・無効の制御ではなく、「gufwそのものをログイン時に起動するかどうか」を制御します。ufwそのものの制御は、メイン画面の有効・無効の切り替えを用いてください。
たいていの環境では、「トレイアイコンを表示する」「閉じたらトレイアイコンに最小化する」「ログイン時に自動起動する」を有効にしておき、必要に応じてトレイアイコンから呼び出せるようにしておくと便利でしょう。
ufwによる設定のサンプル
ここまでに登場したものを含めて、ufwを利用したファイアウォール設定の実例(+サーバーソフトウェアの設定変更)を幾つか挙げておきます。
HTTPサービスを提供するマシン
Apache(apache2.2-*)を導入し、HTTPとHTTPSでコンテンツを配信するサーバーを考えてみましょう。日常的なメンテナンス作業にはSSHを利用するものとし、HTTPとHTTPS以外のサービスは存在しないものとします。
このような環境では、ufwを以下のように設定していきます。
まず、ufwのデフォルト指定はsudo ufw denyにしておきます。ポリシーによってはrejectにしても良いのですが、後述の理由でポートスキャンを容易に行われる状態を避けたいので[4]、denyの方が妥当でしょう。
この状態ではサービスに利用するポートも閉じられた状態ですので、HTTP・HTTPS関連のポートを開放します。apache2.2-commonパッケージにはufwのアプリケーションプロファイルとなる/etc/ufw/applications.d/apache2.2-commonが含まれていますので、次のようにufw app操作を用いることで、容易に設定することができます。
これでHTTP・HTTPSのそれぞれの待ち受けポートを開くことができました[5]。さらにSSHのポートを、「LIMIT」で開いておきましょう。
これで、「HTTP・HTTPS・SSHだけを開いたサーバー」が設定できました。……が、これだけではやや危険な状態です。SSHをport 22で待ち受ける状態にするのではなく、SSHの待ち受けポートを変更しておきましょう。多くのSSHブルートフォースアタックはport 22を狙いますので、ポートを変更しておくことで、攻撃を受ける機会そのものを減らすことができます[6]。
次のように設定を行います。
まず、SSHの設定ファイル/etc/ssh/sshd_configの、「Port 22」という設定項目を、「Port 4242」などに変更します。このポート番号はできるだけランダムな(推定しにくい)ものが良いでしょう。
設定を修正したら、SSHデーモンを再起動します。
これでSSHの待ち受けポートが、4242に変更されました。この状態のシステムにSSHでアクセスする場合、「ssh -p 4242 サーバ名」という形で、「-p 4242」をオプションとして追加します。また、scpの場合は「-P 4242」と、大文字Pで指定します。これにより、少なくともport 22を固定的に狙うSSHブルートフォースアタックについては回避することが可能です。
ただし、この状態では、ufwの「app」による指定が行えません。以下のようにポートを指定してLIMITを設定するのが一つの手です。
ですが、この状態でstatusを表示しても、以下のように表示されてしまいます。これでは、「4242とは何のポートなのか」というのが、すぐには分からなくなってしまうででしょう。一人の管理者が利用するシステムでは良いのですが、複数の管理者で共同管理しているようなシステムの場合、これは致命的です。
このような場合には、ufwのアプリケーションプロファイルを書いて解決することができます。アプリケーションプロファイルは非常に単純な構造になっていますから、修正は容易です。以下はデフォルトのOpenSSHのプロファイルです。
これをコピーして、今回の修正に合わせた、別のSSHプロファイルを作成しましょう。
エディタで「[OpenSSH]」の部分を「[OpenSSH Another]」へ、「ports=22/tcp」の箇所を「ports=4242/tcp」に修正してください。
この状態でアプリケーションプロファイルを確認すると、以下のように「OpenSSH Another」というプロファイルが追加されているはずです。
あとは、以下のように、「OpenSSH Another」プロファイルを用いてLIMITを設定するだけです。
この状態でstatusを表示すると、以下のように「OpenSSH Another」と表示されます[7]。複数の管理者が存在する場合でも、設定がそのまま意思表示になりますので、誤解による設定ミスが引き起こされる可能性を下げることができるでしょう。
といったところで、今週はここまで。来週は、Ubuntu Japanese Teamのリーダーである小林さんが担当する予定です。