序章

優れたファイアウォールを設定することは、最新のオペレーティングシステムを保護するための重要なステップです。 ほとんどのLinuxディストリビューションには、ファイアウォールの構成に使用できるいくつかの異なるファイアウォールツールが付属しています。 このガイドでは、iptablesファイアウォールについて説明します。

Iptablesは、ほとんどのLinuxディストリビューションにデフォルトで含まれている標準のファイアウォールです(nftablesと呼ばれる最新のバリアントがそれに置き換わり始めます)。 これは実際には、Linuxネットワークスタックを操作できるカーネルレベルのnetfilterフックのフロントエンドです。 これは、ネットワークインターフェイスを通過する各パケットを一連のルールと照合して、何を行うかを決定することで機能します。

前のガイドでは、iptablesルールが不要なトラフィックをブロックするためにどのように機能するかを学びました。 このガイドでは、Ubuntu14.04サーバーの基本的なルールセットを作成する方法を示す実際の例に移ります。 結果として得られるファイアウォールは、SSHおよびHTTPトラフィックを許可します。

注:このチュートリアルでは、IPv4セキュリティについて説明します。 Linuxでは、IPv6のセキュリティはIPv4とは別に維持されます。 たとえば、「iptables」はIPv4アドレスのファイアウォールルールのみを維持しますが、「ip6tables」と呼ばれるIPv6の対応物があり、IPv6ネットワークアドレスのファイアウォールルールを維持するために使用できます。

VPSがIPv6用に構成されている場合は、IPv4とIPv6の両方のネットワークインターフェイスを適切なツールで保護することを忘れないでください。 IPv6ツールの詳細については、次のガイドを参照してください。LinuxVPSでIPv6を使用するようにツールを構成する方法

前提条件

このチュートリアルの使用を開始する前に、root以外の別のスーパーユーザーアカウント(sudo権限を持つユーザー)をサーバーに設定する必要があります。 これを設定する必要がある場合は、次のガイドに従ってください: Ubuntu14.04を使用したサーバーの初期設定。

基本的なiptablesコマンド

iptablesの概念を十分に理解したので、複雑なルールセットを形成し、一般的なiptablesインターフェイスを管理するために使用される基本的なコマンドについて説明します。

まず、iptablesコマンドはroot権限で実行する必要があることに注意してください。 つまり、rootとしてログインするか、suまたはsudo -iを使用してルートシェルを取得するか、すべてのコマンドの前にsudoを付ける必要があります。 このガイドではsudoを使用します。これは、Ubuntuシステムで推奨される方法だからです。

良い出発点は、iptables用に構成されている現在のルールをリストすることです。 -Lフラグを使用してこれを行うことができます。

  1. sudo iptables -L
Output:
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

ご覧のとおり、3つのデフォルトチェーン(INPUT、OUTPUT、FORWARD)があります。 また、各チェーンのデフォルトポリシーを確認できます(各チェーンにはデフォルトポリシーとしてACCEPTがあります)。 一部の列ヘッダーも表示されますが、実際のルールは表示されません。 これは、Ubuntuにはデフォルトのルールセットが付属していないためです。

代わりに-Sフラグを使用することにより、各ルールとポリシーを有効にするために必要なコマンドを反映した形式で出力を確認できます。

  1. sudo iptables -S
Output:
-P INPUT ACCEPT -P FORWARD ACCEPT -P OUTPUT ACCEPT

構成を複製するには、sudo iptablesと入力し、その後に出力の各行を入力するだけです。 (構成によっては、リモートで接続している場合は実際には少し複雑になる可能性があるため、現在の接続をキャッチして許可するルールを設定する前にデフォルトのドロップポリシーを設定しません。)

do にルールがあり、それらを破棄して最初からやり直したい場合は、次のように入力して現在のルールをフラッシュできます。

  1. sudo iptables -F

ここでも、デフォルトのポリシーが重要です。これは、すべてのルールがチェーンから削除されている間、デフォルトのポリシーはこのコマンドで変更されないためです。 つまり、リモートで接続している場合は、ルールをフラッシュする前に、INPUTチェーンとOUTPUTチェーンのデフォルトポリシーがACCEPTに設定されていることを確認する必要があります。 これを行うには、次のように入力します。

  1. sudo iptables -P INPUT ACCEPT
  2. sudo iptables -P OUTPUT ACCEPT
  3. sudo iptables -F

接続を明示的に許可するルールを確立した後、デフォルトのドロップポリシーをDROPに戻すことができます。 その方法については、後ほど説明します。

最初のルールを作る

ファイアウォールポリシーの作成を開始します。 上で述べたように、INPUTチェーンは着信トラフィックが送信されるファネルであるため、INPUTチェーンを使用します。 少し上で説明したルール、つまり現在のSSH接続を明示的に受け入れるルールから始めます。

必要な完全なルールは次のとおりです。

  1. sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

これは非常に複雑に見えるかもしれませんが、コンポーネントを調べると、そのほとんどが理にかなっています。

  • -入力-Aフラグは、チェーンの最後にルールを追加します。 これは、新しいルールを追加すること、そのルールをチェーンの最後に追加すること、操作するチェーンがINPUTチェーンであることをiptablesに通知するコマンドの部分です。

  • -m conntrack :iptablesには一連のコア機能がありますが、追加機能を提供する一連の拡張機能またはモジュールもあります。

    コマンドのこの部分では、conntrackモジュールによって提供される機能にアクセスしたいと述べています。 このモジュールは、パケットと以前の接続との関係に基づいて決定を下すために使用できるコマンドへのアクセスを提供します。

  • –ctstate :これは、conntrackモジュールを呼び出すことによって使用可能になるコマンドの1つです。 このコマンドを使用すると、以前に見たパケットとの関連性に基づいてパケットを照合できます。

    ESTABLISHEDの値を渡して、既存の接続の一部であるパケットを許可します。 RELATEDの値を渡して、確立された接続に関連付けられているパケットを許可します。 これは、現在のSSHセッションに一致するルールの部分です。

  • -j ACCEPT :一致するパケットのターゲットを指定します。 ここでは、前述の基準に一致するパケットを受け入れて許可する必要があることをiptablesに通知します。

DROPルールに到達する前に、すでに使用している接続が一致し、受け入れられ、チェーンから引き出されていることを確認する必要があるため、このルールを最初に配置します。

ルールをリストすると、変更を確認できます。

  1. sudo iptables -L
Output:
Chain INPUT (policy ACCEPT) target prot opt source destination ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED Chain FORWARD (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination

一般的な構文がわかったので、接続を受け入れたい場合をさらにいくつか追加していきましょう。

その他の必要な接続を受け入れる

iptablesに、すでに開いている接続を開いたままにし、それらの接続に関連する新しい接続を許可するように指示しました。 ただし、これらの基準を満たさない新しい接続をいつ受け入れるかを確立するために、いくつかのルールを作成する必要があります。

特に2つのポートを開いたままにしておきます。 SSHポートを開いたままにしておきます(このガイドでは、これがデフォルトの22であると想定します。 SSH構成でこれを変更した場合は、ここで値を変更してください)。 また、このコンピューターはデフォルトのポート80でWebサーバーを実行していると想定します。 そうでない場合は、そのルールを追加する必要はありません。

これらのルールを追加するために使用する2行は次のとおりです。

  1. sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
  2. sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT

ご覧のとおり、これらは最初のルールと非常に似ていますが、おそらくもっと単純です。 新しいオプションは次のとおりです。

  • -p tcp :使用されているプロトコルがTCPの場合、このオプションはパケットに一致します。 これは、信頼性の高い通信を可能にするため、ほとんどのアプリケーションで使用される接続ベースのプロトコルです。
  • –dport :このオプションは、-p tcpフラグが指定されている場合に使用できます。 一致するパケットの宛先ポートを一致させるという追加の要件があります。 最初のルールはポート22宛てのTCPパケットに一致し、2番目のルールはポート80に向けられたTCPトラフィックに一致します。

サーバーが正しく機能することを保証するために必要なもう1つの受け入れルールがあります。 多くの場合、コンピュータ上のサービスは、ネットワークパケットを相互に送信することによって相互に通信します。 これは、loopback deviceと呼ばれる疑似ネットワークインターフェイスを利用して行います。このインターフェイスは、トラフィックを他のコンピューターではなく、それ自体に転送します。

したがって、あるサービスがポート4555で接続をリッスンしている別のサービスと通信する場合、ループバックデバイスのポート4555にパケットを送信できます。 多くのプログラムを正しく動作させるために不可欠であるため、この種の動作を許可する必要があります。

追加する必要のあるルールは次のとおりです。

  1. sudo iptables -I INPUT 1 -i lo -j ACCEPT

これは、他のコマンドとは少し異なります。 それが何をしているのかを見てみましょう:

  • -I INPUT 1 -Iフラグは、iptablesにinsertルールを指示します。 これは、最後にルールを追加する-Aフラグとは異なります。 -Iフラグは、チェーンと、新しいルールを挿入するルールの位置を取ります。

    この場合、このルールをINPUTチェーンの最初のルールとして追加します。 これにより、残りのルールが適用されなくなります。 これは基本的なものであり、後続のルールの影響を受けないため、これを一番上に配置する必要があります。

  • -i lo :パケットが使用しているインターフェースが「lo」インターフェースである場合、ルールのこのコンポーネントは一致します。 「lo」インターフェイスは、ループバックデバイスの別名です。 これは、そのインターフェースを使用して通信するすべてのパケット(サーバー上で生成されたパケット、サーバー用)を受け入れる必要があることを意味します。

現在のルールを確認するには、-Sフラグを使用する必要があります。 これは、-Lフラグに、ルールが関連付けられているインターフェイスなどの情報が含まれていないためです。これは、先ほど追加したルールの重要な部分です。

  1. sudo iptables -S
Output:
-P INPUT ACCEPT -P FORWARD ACCEPT -P OUTPUT ACCEPT -A INPUT -i lo -j ACCEPT -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT

ドロップルールの実装

現在、特定の基準に基づいてパケットを明示的に受け入れる4つの個別のルールがあります。 ただし、現在、ファイアウォールはすべてをブロックしていません。

パケットがINPUTチェーンに入り、作成した4つのルールのいずれにも一致しない場合、パケットはデフォルトのポリシーに渡されます。これは、とにかくパケットを受け入れることです。 これを変更する必要があります。

これを行うには2つの異なる方法がありますが、いくつかの非常に重要な違いがあります。

これを行う最初の方法は、INPUTチェーンのデフォルトポリシーを変更することです。 これを行うには、次のように入力します。

  1. sudo iptables -P INPUT DROP

これにより、INPUTチェーンを通過するすべてのパケットがキャッチされ、ドロップされます。 これは、デフォルトのドロップポリシーと呼ばれるものです。 このタイプの設計の意味の1つは、ルールがフラッシュされた場合にパケットのドロップにフォールバックすることです。

これはより安全かもしれませんが、サーバーにアクセスする別の方法がない場合、深刻な結果をもたらす可能性もあります。 DigitalOceanを使用すると、Webコンソールからログインして、これが発生した場合にサーバーにアクセスできます。 Webコンソールは仮想ローカル接続として機能するため、iptablesルールはそれに影響しません。

ルールがダンプされた場合に、サーバーがすべての接続を自動的にドロップするようにしたい場合があります。 これにより、サーバーが大きく開いたままになるのを防ぐことができます。 これは、必要に応じてパケットをドロップしながら、チェーンの最下部にルールを簡単に追加できることも意味します。

別のアプローチは、チェーンのデフォルトポリシーを受け入れとして保持し、残りのすべてのパケットをチェーン自体の最下部にドロップするルールを追加することです。

上記のINPUTチェーンのデフォルトのポリシーを変更した場合は、次のように入力することで、従うように元に戻すことができます。

  1. sudo iptables -P INPUT ACCEPT

これで、残りのパケットをドロップするルールをチェーンの最下部に追加できます。

  1. sudo iptables -A INPUT -j DROP

通常の動作条件下での結果は、デフォルトのドロップポリシーとまったく同じです。 このルールは、それに到達するすべての残りのパケットを照合することによって機能します。 これにより、パケットがこれまででチェーン全体にドロップして、デフォルトのポリシーに到達するのを防ぎます。

基本的に、これはトラフィックを受け入れるためのデフォルトのポリシーを維持するために使用されます。 そうすれば、問題が発生してルールがフラッシュされた場合でも、ネットワーク経由でマシンにアクセスできます。 これは、空のチェーンに適用されるポリシーを変更せずにデフォルトのアクションを実装する方法です。

もちろん、これは、チェーンの最後に追加する追加のルールをドロップルールの前に追加する必要があることも意味します。 これを行うには、ドロップルールを一時的に削除します。

  1. sudo iptables -D INPUT -j DROP
  2. sudo iptables -A INPUT new_rule_here
  3. sudo iptables -A INPUT -j DROP

または、行番号を指定して、チェーンの最後(ただしドロップの前)に必要なルールを挿入できます。 行番号4にルールを挿入するには、次のように入力します。

  1. sudo iptables -I INPUT 4 new_rule_here

各ルールの行番号がわからない場合は、次のように入力して、iptablesにルールに番号を付けるように指示できます。

  1. sudo iptables -L --line-numbers
Output:
Chain INPUT (policy DROP) num target prot opt source destination 1 ACCEPT all -- anywhere anywhere 2 ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED 3 ACCEPT tcp -- anywhere anywhere tcp dpt:ssh 4 ACCEPT tcp -- anywhere anywhere tcp dpt:http Chain FORWARD (policy ACCEPT) num target prot opt source destination Chain OUTPUT (policy ACCEPT) num target prot opt source destination

これは、ルールを適切な位置に追加していることを確認するのに役立ちます。

Iptablesルールの一覧表示と削除

iptablesルールの一覧表示と削除の詳細については、次のチュートリアルをご覧ください:Iptablesファイアウォールルールの一覧表示と削除方法

Iptables構成の保存

デフォルトでは、iptablesに追加するルールは一時的なものです。 これは、サーバーを再起動すると、iptablesルールが失われることを意味します。

これは実際には一部のユーザーにとっての機能です。これは、サーバーから誤ってロックアウトした場合に戻る手段を提供するためです。 ただし、ほとんどのユーザーは、作成したルールを自動的に保存し、サーバーの起動時にそれらをロードする方法を望んでいます。

これを行うにはいくつかの方法がありますが、最も簡単な方法はiptables-persistentパッケージを使用することです。 これは、Ubuntuのデフォルトのリポジトリからダウンロードできます。

  1. sudo apt-get update
  2. sudo apt-get install iptables-persistent

インストール中に、現在のルールを保存して自動的にロードするかどうかを尋ねられます。 現在の構成に満足している場合(および独立したSSH接続を作成する機能をテストした場合は、現在のルールを保存することを選択できます。

また、構成したIPv6ルールを保存するかどうかも尋ねられます。 これらは、IPv6パケットのフローをほぼ同じ方法で制御するip6tablesと呼ばれる別のユーティリティを介して構成されます。

インストールが完了すると、起動時に実行するように構成されたiptables-persistentという新しいサービスが作成されます。 このサービスはルールをロードし、サーバーの起動時にそれらを適用します。

更新の保存

ファイアウォールを更新して変更を保持したい場合は、iptablesルールを保存して永続化する必要があります。

次のコマンドでファイアウォールルールを保存します。

  1. sudo invoke-rc.d iptables-persistent save

結論

これで、ニーズに対応するファイアウォールを開発するための良い出発点ができました。 他にも多くのファイアウォールユーティリティがあり、いくつかはもっと簡単かもしれませんが、iptablesは、基盤となるnetfilter構造の一部を公開し、非常に多くのシステムに存在するという理由だけで、優れた学習ツールです。

iptablesを使用してネットワークを保護する方法の詳細については、次のチュートリアルをご覧ください。