Ubuntu14.04でIptablesを使用して基本的なファイアウォールテンプレートを実装する方法
序章
ファイアウォールの実装は、サーバーを保護するための重要なステップです。 その大部分は、ネットワークにトラフィック制限を適用する個々のルールとポリシーを決定することです。 のようなファイアウォール iptables
また、ルールが適用される構造的フレームワークについて発言することもできます。
このガイドでは、より複雑なルールセットの基礎となるファイアウォールを構築します。 このファイアウォールは、主に合理的なデフォルトを提供し、簡単な拡張性を促進するフレームワークを確立することに重点を置いています。 これをUbuntu14.04サーバーでデモンストレーションします。
前提条件
始める前に、実装するファイアウォールポリシーの基本的な考え方を理解しておく必要があります。 このガイドに従って、考えるべきことのいくつかをよりよく理解することができます。
フォローするには、Ubuntu14.04サーバーにアクセスできる必要があります。 で構成されたroot以外のユーザーを使用します sudo
このガイド全体の特権。 このタイプのユーザーを構成する方法については、Ubuntu14.04初期サーバーセットアップガイドをご覧ください。
終了したら、以下に進みます。
永続ファイアウォールサービスのインストール
開始するには、をインストールする必要があります iptables-persistent
まだ行っていない場合はパッケージします。 これにより、ルールセットを保存し、起動時に自動的に適用できるようになります。
- sudo apt-get update
- sudo apt-get install iptables-persistent
インストール中に、現在のルールを保存するかどうかを尋ねられます。 ここで「はい」と言ってください。 生成されたルールファイルを一時的に編集します。
このガイドのIPv6に関する注意
始める前に、IPv4とIPv6について簡単に説明する必要があります。 The iptables
コマンドはIPv4トラフィックのみを処理します。 IPv6トラフィックの場合、別のコンパニオンツールと呼ばれる ip6tables
使用されている。 ルールは別々のテーブルとチェーンに保存されます。 為に iptables-persistent
、IPv4ルールの書き込みと読み取り /etc/iptables/rules.v4
IPv6ルールは保持されます /etc/iptables/rules.v6
.
このガイドは、サーバーでIPv6を積極的に使用していない
基本的なファイアウォールポリシーの実装(クイックウェイ)
できるだけ早く起動して実行するために、ルールファイルを直接編集して、完成したファイアウォールポリシーをコピーして貼り付ける方法を示します。 その後、一般的な戦略を説明し、これらのルールを使用して実装する方法を示します。 iptables
ファイルを変更する代わりにコマンド。
ファイアウォールポリシーとフレームワークを実装するために、 /etc/iptables/rules.v4
と /etc/iptables/rules.v6
ファイル。 を開きます rules.v4
テキストエディタのファイル sudo
特権:
- sudo nano /etc/iptables/rules.v4
内部には、次のようなファイルが表示されます。
# Generated by iptables-save v1.4.21 on Tue Jul 28 13:29:56 2015
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
COMMIT
# Completed on Tue Jul 28 13:29:56 2015
内容を次のように置き換えます。
*filter
# Allow all outgoing, but drop incoming and forwarding packets by default
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
# Custom per-protocol chains
:UDP - [0:0]
:TCP - [0:0]
:ICMP - [0:0]
# Acceptable UDP traffic
# Acceptable TCP traffic
-A TCP -p tcp --dport 22 -j ACCEPT
# Acceptable ICMP traffic
# Boilerplate acceptance policy
-A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
-A INPUT -i lo -j ACCEPT
# Drop invalid packets
-A INPUT -m conntrack --ctstate INVALID -j DROP
# Pass traffic to protocol-specific chains
## Only allow new connections (established and related should already be handled)
## For TCP, additionally only allow new SYN packets since that is the only valid
## method for establishing a new TCP connection
-A INPUT -p udp -m conntrack --ctstate NEW -j UDP
-A INPUT -p tcp --syn -m conntrack --ctstate NEW -j TCP
-A INPUT -p icmp -m conntrack --ctstate NEW -j ICMP
# Reject anything that's fallen through to this point
## Try to be protocol-specific w/ rejection message
-A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable
-A INPUT -p tcp -j REJECT --reject-with tcp-reset
-A INPUT -j REJECT --reject-with icmp-proto-unreachable
# Commit the changes
COMMIT
*raw
:PREROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
COMMIT
*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
COMMIT
*security
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
COMMIT
*mangle
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
COMMIT
ファイルを保存して閉じます。
このコマンドを入力すると、ファイルの構文エラーをテストできます。 続行する前に、これによって明らかになる構文エラーを修正してください。
- sudo iptables-restore -t /etc/iptables/rules.v4
次に、 /etc/iptables/rules.v6
IPv6ルールを変更するファイル:
- sudo nano /etc/iptables/rules.v6
ファイルの内容を次の構成に置き換えることで、すべてのIPv6トラフィックをブロックできます。
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT DROP [0:0]
COMMIT
*raw
:PREROUTING DROP [0:0]
:OUTPUT DROP [0:0]
COMMIT
*nat
:PREROUTING DROP [0:0]
:INPUT DROP [0:0]
:OUTPUT DROP [0:0]
:POSTROUTING DROP [0:0]
COMMIT
*security
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT DROP [0:0]
COMMIT
*mangle
:PREROUTING DROP [0:0]
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT DROP [0:0]
:POSTROUTING DROP [0:0]
COMMIT
ファイルを保存して閉じます。
このファイルの構文エラーをテストするには、 ip6tables-restore
とのコマンド -t
オプション:
- sudo ip6tables-restore -t /etc/iptables/rules.v6
両方のルールファイルで構文エラーが報告されていない場合は、次のように入力してルールを適用できます。
- sudo service iptables-persistent reload
これにより、ファイルに概説されているポリシーがすぐに実装されます。 これを確認するには、 iptables
現在使用されているルール:
- sudo iptables -S
- sudo ip6tables -S
これらのファイアウォールルールは、起動するたびに再適用されます。 引き続きログインできること、および他のすべてのアクセスがブロックされていることを確認するためにテストします。
一般的なファイアウォール戦略の説明
上記のルールを使用して構築した基本的なファイアウォールでは、ルールを追加または削除するために簡単に調整できる拡張可能なフレームワークを作成しました。 IPv4トラフィックの場合、主に INPUT
内のチェーン filter
テーブル。 このチェーンは、サーバー宛てのすべてのパケットを処理します。 また、すべての送信トラフィックを許可し、すべてのパケット転送を拒否しました。これは、このサーバーが他のホストのルーターとして機能している場合にのみ適切です。 このガイドではパケットのフィルタリングのみを目的としているため、他のすべてのテーブルでパケットを受け入れます。
一般に、私たちのルールは、デフォルトで着信トラフィックを拒否するファイアウォールを設定します。 次に、このポリシーから除外するサービスとトラフィックタイプの例外を作成します。
概して INPUT
チェーンでは、常に同じ方法で処理されると確信しているトラフィックの一般的なルールをいくつか追加しました。 たとえば、「無効」と見なされるパケットを常に拒否し、ローカルループバックインターフェイス上のトラフィックと確立された接続に関連付けられたデータを常に許可する必要があります。
その後、使用しているプロトコルに基づいてトラフィックを照合し、プロトコル固有のチェーンにシャッフルします。 これらのプロトコル固有のチェーンは、特定のサービスのトラフィックに一致して許可するルールを保持することを目的としています。 この例では、許可するサービスはSSHのみです。 TCP
鎖。 HTTP(S)サーバーなどの別のサービスを提供している場合は、ここにも例外を追加できます。 これらのチェーンは、ほとんどのカスタマイズの焦点になります。
プロトコル固有の汎用ルールまたはサービスルールに一致しないトラフィックは、 INPUT
鎖。 デフォルトのポリシーをに設定しました DROP
ルールを通過するパケットを拒否するファイアウォールの場合。 ただし、最後のルール INPUT
チェーンはパケットを拒否し、そのポートでサービスが実行されていない場合にサーバーがどのように応答するかを模倣したメッセージをクライアントに送信します。
IPv6トラフィックの場合、すべてのトラフィックをドロップするだけです。 私たちのサーバーはこのプロトコルを使用していないので、トラフィックにまったく関与しないのが最も安全です。
(オプション)ネームサーバーの更新
すべてのIPv6トラフィックをブロックすると、サーバーがインターネット上の問題を解決する方法が妨げられる可能性があります。 たとえば、これはAPTの使用方法に影響を与える可能性があります。
実行しようとしたときにこのようなエラーが発生した場合 apt-get update
:
Err http://security.ubuntu.com trusty-security InRelease
Err http://security.ubuntu.com trusty-security Release.gpg
Could not resolve 'security.ubuntu.com'
. . .
APTを再び機能させるには、このセクションに従う必要があります。
まず、ネームサーバーを外部のネームサーバーに設定します。 この例では、Googleのネームサーバーを使用しています。 開ける /etc/network/interfaces
編集用:
- sudo nano /etc/network/interfaces
を更新します dns-nameservers
示されている行:
. . .
iface eth0 inet6 static
address 2604:A880:0800:0010:0000:0000:00B2:0001
netmask 64
gateway 2604:A880:0800:0010:0000:0000:0000:0001
autoconf 0
dns-nameservers 8.8.8.8 8.8.4.4
ネットワーク設定を更新します。
- sudo ifdown eth0 && sudo ifup eth0
期待される出力は次のとおりです。
RTNETLINK answers: No such process
Waiting for DAD... Done
次に、新しいファイアウォールルールを作成して、IPv4が利用可能になったときにそれを強制します。 この新しいファイルを作成します。
- sudo nano /etc/apt/apt.conf.d/99force-ipv4
次の1行をファイルに追加します。
Acquire::ForceIPv4 "true";
ファイルを保存して閉じます。 これで、APTを使用できるようになります。
IPTablesコマンドを使用したファイアウォールの実装
作成したポリシーの背後にある一般的な考え方を理解したので、次を使用してこれらのルールを作成する方法について説明します。 iptables
コマンド。 上記で指定したものと同じルールが作成されますが、ルールを繰り返し追加してポリシーを作成します。 なぜなら iptables
各ルールをすぐに適用します。ルールの順序は非常に重要です(パケットを拒否するルールは最後まで残します)。
ファイアウォールをリセットする
コマンドラインからポリシーを構築する方法を確認できるように、ファイアウォールルールをリセットすることから始めます。 次のように入力すると、すべてのルールをフラッシュできます。
- sudo service iptables-persistent flush
次のように入力して、ルールがリセットされたことを確認できます。
- sudo iptables -S
のルールが filter
テーブルがなくなり、デフォルトのポリシーがに設定されている ACCEPT
すべてのチェーンで:
output-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
プロトコル固有のチェーンを作成する
まず、プロトコル固有のチェーンをすべて作成します。 これらは、公開するサービスの拒否ポリシーの例外を作成するルールを保持するために使用されます。 のために作成します UDP
トラフィック、1つ TCP
、および1つ ICMP
:
- sudo iptables -N UDP
- sudo iptables -N TCP
- sudo iptables -N ICMP
先に進み、SSHトラフィックの例外を追加できます。 SSHはTCPを使用するため、ポート22宛てのTCPトラフィックを受け入れるルールをTCPチェーンに追加します。
- sudo iptables -A TCP -p tcp --dport 22 -j ACCEPT
TCPサービスを追加したい場合は、ポート番号を置き換えてコマンドを繰り返すことで、これを行うことができます。
汎用の承認および拒否ルールを作成する
の中に INPUT
すべての着信トラフィックがフィルタリングを開始するチェーンでは、汎用ルールを追加する必要があります。 これらは、リスクの低いトラフィック(ローカルトラフィックと、すでにチェックした接続に関連付けられているトラフィック)を受け入れ、明らかに役に立たないトラフィック(無効なパケット)をドロップすることによってファイアウォールのベースラインを設定するいくつかの常識的なルールです。
まず、確立された接続の一部であるか、確立された接続に関連するすべてのトラフィックを受け入れるための例外を作成します。
- sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
このルールは conntrack
拡張機能。内部追跡を提供するため、 iptables
個別の無関係なパケットのストリームとしてではなく、より大きな接続の一部としてパケットを評価するために必要なコンテキストがあります。 TCPは接続ベースのプロトコルであるため、確立された接続はかなり明確に定義されています。 UDPおよびその他のコネクションレス型プロトコルの場合、確立された接続とは、応答があったトラフィックを指します(元のパケットの送信元が応答パケットの宛先になり、その逆も同様です)。 関連する接続とは、既存の接続に関連して開始された新しい接続を指します。 ここでの典型的な例は、FTPデータ転送接続です。これは、すでに確立されているFTP制御接続に関連しています。
また、ローカルループバックインターフェイスから発信されるすべてのトラフィックを許可する必要があります。 これは、サーバーによって生成され、サーバー宛てのトラフィックです。 これは、ホスト上のサービスが相互に通信するために使用します。
- sudo iptables -A INPUT -i lo -j ACCEPT
最後に、すべての無効なパケットを拒否します。 パケットは、いくつかの理由で無効になる可能性があります。 それらは、存在しない接続を参照する場合もあれば、存在しないインターフェース、アドレス、またはポートを宛先とする場合もあります。あるいは、単に不正な形式である場合もあります。 いずれの場合も、無効なパケットを処理する適切な方法がなく、悪意のあるアクティビティを表す可能性があるため、すべての無効なパケットをドロップします。
- sudo iptables -A INPUT -m conntrack --ctstate INVALID -j DROP
プロトコル固有のチェーンへのジャンプルールの作成
これまでのところ、いくつかの一般的なルールを作成しました INPUT
チェーンと、プロトコル固有のチェーン内の特定の受け入れ可能なサービスに関するいくつかのルール。 ただし、現在、トラフィックは INPUT
チェーンであり、プロトコル固有のチェーンに到達する方法はありません。
にトラフィックを誘導する必要があります INPUT
適切なプロトコル固有のチェーンにチェーンします。 プロトコルタイプを照合して、正しいチェーンに送信できます。 また、パケットが新しい接続を表していることを確認します(確立された接続または関連する接続はすべて以前に処理されている必要があります)。 TCPパケットの場合、パケットがSYNパケットであるという追加要件を追加します。これは、TCP接続を開始するための唯一の有効なタイプです。
- sudo iptables -A INPUT -p udp -m conntrack --ctstate NEW -j UDP
- sudo iptables -A INPUT -p tcp --syn -m conntrack --ctstate NEW -j TCP
- sudo iptables -A INPUT -p icmp -m conntrack --ctstate NEW -j ICMP
残りのトラフィックをすべて拒否する
プロトコル固有のチェーンに渡されたパケットが内のどのルールにも一致しなかった場合、制御はに戻されます。 INPUT
鎖。 このポイントに到達するものはすべて、ファイアウォールで許可されるべきではありません。
を使用してトラフィックを拒否します REJECT
ターゲット。クライアントに応答メッセージを送信します。 これにより、アウトバウンドメッセージングを指定できるため、クライアントが通常の閉じたポートにパケットを送信しようとした場合に返される応答を模倣できます。 応答は、クライアントが使用するプロトコルによって異なります。
閉じたUDPポートに到達しようとすると、ICMP「ポート到達不能」メッセージが表示されます。 次のように入力することで、これを模倣できます。
- sudo iptables -A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable
閉じたポートでTCP接続を確立しようとすると、TCPRST応答が発生します。
- sudo iptables -A INPUT -p tcp -j REJECT --reject-with tcp-reset
他のすべてのパケットについては、ICMPの「プロトコル到達不能」メッセージを送信して、サーバーがそのタイプのパケットに応答しないことを示すことができます。
- sudo iptables -A INPUT -j REJECT --reject-with icmp-proto-unreachable
デフォルトポリシーの調整
追加した最後の3つのルールは、 INPUT
鎖。 ただし、デフォルトのポリシーを次のように設定する必要があります DROP
予防措置として。 このポリシーは、 FORWARD
このサーバーが他のマシンへのルーターとして構成されていない場合は、チェーンします。
- sudo iptables -P INPUT DROP
- sudo iptables -P FORWARD DROP
警告
ポリシーをに設定して DROP
、あなたがあなたをクリアした場合 iptables
と sudo iptables -F
、現在のSSH接続は切断されます! でフラッシング sudo iptables-persistent flush
デフォルトのポリシーもリセットされるため、ルールをクリアするためのより良い方法です。
すべてのトラフィックをドロップするというIPv6ポリシーに一致させるために、次を使用できます。 ip6tables
コマンド:
- sudo ip6tables -P INPUT DROP
- sudo ip6tables -P FORWARD DROP
- sudo ip6tables -P OUTPUT DROP
これにより、ルールセットがかなり厳密に複製されます。
IPTablesルールの保存
この時点で、ファイアウォールルールをテストし、通常のアクセスを妨げずに、トラフィックを遮断したいブロックをそれらがカバーしていることを確認する必要があります。 ルールが正しく動作していることを確認したら、ルールを保存して、起動時にシステムに自動的に適用されるようにすることができます。
次のように入力して、現在のルール(IPv4とIPv6の両方)を保存します。
- sudo service iptables-persistent save
これはあなたの /etc/iptables/rules.v4
と /etc/iptables/rules.v6
コマンドラインで作成したポリシーを含むファイル。
結論
このガイドに従うことにより、ファイアウォールルールを構成ファイルに直接貼り付けるか、コマンドラインに手動で適用して保存することにより、適切な開始ファイアウォール構成を作成できました。 利用可能にしたいサービスへのアクセスを許可するには、個々のルールを追加する必要があります。
このガイドで確立されたフレームワークにより、簡単に調整を行うことができ、既存のポリシーを明確にするのに役立ちます。 他のガイドをチェックして、人気のあるサービスを使用してファイアウォールポリシーを構築する方法を確認してください。