今回は Linux(CentOS6系)にデフォルトで実装されているのファイアウォール(パケットフィルタリング)ソフトの「iptables」の設定および使用方法について解説します。
CentOS7 系の場合は firewalld を利用します。
iptables とは
iptables の機能です。
- パケットフィルタリング
- ネットワークアドレス変換(NAT)、IPマスカレード
iptables コマンド
iptables には、以下の3つのポリシーがあります。
- INPUT ← サーバーに入ってくる通信のポリシー
- OUTPUT ← サーバーから出て行く通信のポリシー
- FORWARD ← 受信したデータを他のサーバーへ転送する際に適用される設定
それぞれの通信の基本ポリシーを以下の3つのターゲットに設定できます。
■ターゲット
- DROP(拒否)
- REJECT(拒否)
- ACCEPT(許可)
iptables の注意点
iptables で一番失敗するパターンとしては「iptables コマンドと iptables ファイルの両方を考慮していない」場合に、実はブロックされてなかったとか、うまく機能しているように見えないなどのトラブルが発生するように思います。
そのため、iptables の設定をする際は、
- iptables コマンドからの設定
- /etc/sysconfig/iptables からの設定
の両方に注意します。
iptables 設定
■iptables 自動起動 ON 手順
# chkconfig iptables on |
■iptables 起動手順
# /etc/init.d/iptables start |
■現状確認手順
自動起動が off の場合
# chkconfig | grep iptables |
自動起動が on の場合
# chkconfig | grep iptables |
■iptables が起動していない場合
[root@CentOS6 ~]# iptables -L |
インバウンド拒否(ブロック)の設定
インバウンド(入ってくる方)のパケットをブロックする設定です。
■特定 IP アドレスからのアクセスを拒否する
例えば、192.168.1.13 からのアクセスを拒否する場合です。
その場合は、拒否したい IP アドレスを設定します。
# iptables -I INPUT -s 192.168.1.13 -j DROP |
設定したら「iptables -L」コマンドで設定状況を確認します。
[root@CentOS6 ~]# iptables -L |
ただし、ソース(source)が「ip-192-168-1-13.ap-northeast-1.compute.internal」になっています。
「ip-192-168-1-13.ap-northeast-1.compute.internal」ですが、自動的に名前解決をされてしまうので、「-n」オプションを付けます。
■オプション
- -n IP アドレスで表示します。
[root@CentOS6 ~]# iptables -L -n |
「192.168.1.13」からのアクセスは Ping も ssh もアクセス不可になります。
ルールを削除したい場合
ルールを削除したい場合は、iptables -L の一覧で表示されたライン番号を下記コマンドで指定します。
ちなみにライン番号を表示する場合は「–line-numbers」オプションを追加します。
[root@CentOS6 ~]# iptables -L -n –line-numbers |
ライン番号を利用して設定を削除します。
[root@CentOS6 ~]# iptables -D INPUT 1 |
結果を確認します。
[root@CentOS6 ~]# iptables -L -n |
iptables コマンド実行例
以下、iptables コマンド実行例を記載します。
■ネットワーク「192.168.1.0/24」からの SSH(22/TCP)アクセスを許可する設定
- -A ファイアウォールの設定を追加します。「-A INPUT」でインプットチェインに追加します。
- -s ソース IP アドレスを指定します。/24 などでネットワークセグメントを指定することもできます。
- -p プロトコルを指定します。
- -dport 受信側のポート番号を指定します。「-dport 22」で受信側の22番ポート(SSH)を指定します。
- -j ターゲットを指定します。ターゲット(DROP(拒否)、REJECT(拒否)、ACCEPT(許可)
[root@CentOS6 ~]# iptables -A INPUT -s 192.168.1.0/24 -p tcp –dport 22 -j ACCEPT |
■ネットワーク「192.168.1.0/24」への 3306/TCP へのアクセスを拒否する設定【アウトバウンドの拒否】
- -A OUTPUT OUTPUTに追加します。
- -d デスティネーション(送信先)の IP アドレスを指定します。
- 対象サーバ:192.0.2.0
- 対象ポート:3306
# iptables -A OUTPUT -p tcp -d 192.168.1.0/24 –dport 3306 -j REJECT |
DROP と REJECT の違い
- DROP ← エラーなどレスポンスが返って来ません。そのため、接続したクライアントはしばらく待たされます。
- REJECT ← 即時にエラーが返ってきます。クライアントは待たされません。「reject-with icmp-port-unreachable」のように送信元に対してエラーメッセージの通知を行います。その後DROPと同様にパケットの破棄を行います。
■DROP と REJECT どちらを選ぶべきなのか
REJECT の場合は、すぐにレスポンスを返すので、サーバーの存在を相手に知らせます。そのため、外部に公開している場合は、攻撃者に対して存在を知られてしまうリスクがあります。(ただし、今はサーバーを直接インターネットにさらすようなネットワーク構成を選択する企業はないと思いますが)
DROP の場合は、レスポンスが返ってこないため、サーバーの存在を相手から隠蔽することができます。
その代わり、ping を DROP するとサーバーが存在しているのか存在していないのか分からなくなるため、IP アドレスの重複など事故が起こりやすくなります。
REJECT の場合は、ping コマンドを実行した瞬間、以下のようなレスポンスが返ってきます。
From 192.168.1.23 icmp_seq=167 Destination Port Unreachable |
■ネットワーク「192.168.1.0/24」へのすべてのパケットを拒否する設定【アウトバウンドの拒否】
- 対象サーバ:10.10.50.0/24
- 対象パケット:全部
- -A ← OUTPUT チェインの末尾に追加します。
- -p ← プロトコルを指定します。
- -j REJECT ← ルールにマッチしたパケットを破棄します。
# iptables -A OUTPUT -p all -d 192.168.1.0/24 -j REJECT |
iptables コマンドを実行後に設定を反映させる
iptables コマンドを実行しただけでは、OS 再起動後に設定が消えてしまいます。
そのため OS 再起動後にも残るように、以下のように設定を反映させます。
iptables コマンドで 192.168.1.83/32 へのアクセスを拒否する設定をします。
# iptables -A OUTPUT -p all -d 192.168.1.83/32 -j REJECT |
save コマンドを実行します。
# /etc/init.d/iptables save ファイアウォールのルールを /etc/sysconfig/iptables に保存中: [ OK ] |
save コマンドを実行することで iptables ファイルに追加されます。
# cat /etc/sysconfig/iptables |
iptables -L コマンドでも設定が入っていることが確認できます。
# iptables -L |
iptables コマンドオプション
iptables のオプションです。
- -t, –table table ← このオプションは、このコマンドを適用するパケットマッチングテーブルを指定する。カーネルに自動モジュールローディングが設定されている場合、そのテーブルに対する適切なモジュールがまだロードされていなければ、そのモジュールがロードされる。
- -A, –append ← 選択されたチェインの最後に 1 つ以上のルールを追加する。送信元や送信先の名前が 1 つ以上のアドレスに解決された場合は、可能なアドレスの組合せそれぞれに対してルールが追加される。
- -D, –delete チェイン ルール番号 ← 選択されたチェインから 1 つ以上のルールを削除する。このコマンドには 2 つの使い方がある: チェインの中の番号 (最初のルールを 1 とする) を指定する場合と、マッチするルールを指定する場合である。
- -I, –insert チェイン [ルール番号] ルールの詳細 ← 選択されたチェインにルール番号を指定して 1 つ以上のルールを挿入する。ルール番号が 1 の場合、ルールはチェインの先頭に挿入される。これはルール番号が指定されない場合のデフォルトでもある。
- -R, –replace チェイン ルール番号 ルールの詳細 ← 選択されたチェインでルールを置換する。送信元や送信先の名前が 1 つ以上のアドレスに解決された場合は、このコマンドは失敗する。ルール番号は 1 からはじまる。
- -L, –list [チェイン] ← 選択されたチェインにある全てのルールを一覧表示する。チェインが指定されない場合、全てのチェインにあるリストが一覧表示される。他の各 iptables コマンドと同様に、指定されたテーブル (デフォルトは filter) に対して作用する。DNSの逆引きを避けるために、よく -n オプションと共に使用される。
- -F, –flush [チェイン] ← 選択されたチェイン(何も指定しなければテーブル内の全てのチェイン) の内容を全消去する。これは全てのルールを 1 個ずつ削除するのと同じである。
- -Z, –zero [チェイン] ← すべてのチェインのパケットカウンタとバイトカウンタをゼロにする。クリアされる直前のカウンタを見るために、-L, –list (一覧表示) オプションと同時に指定することもできる。
- -N, –new-chain チェイン ← 指定した名前でユーザー定義チェインを作成する。同じ名前のターゲットが既に存在してはならない。
- -X, –delete-chain [チェイン] ← 指定したユーザー定義チェインを削除する。そのチェインが参照されていてはならない。チェインを削除する前に、そのチェインを参照しているルールを削除するか置き換えるかしなければならない。引き数が与えられない場合、テーブルにあるチェインのうち組み込み済みチェインでないものを全て削除する。
- -P, –policy チェイン ターゲット ← チェインのポリシーを指定したターゲットに設定する。指定可能なターゲットは「ターゲット」の章を参照すること。 (ユーザー定義ではない)組み込み済みチェインにしかポリシーは設定できない。また、組み込み済みチェインもユーザー定義チェインもポリシーのターゲットに設定することはできない。
- -E, –rename-chain 旧チェイン名 新チェイン名 ← ユーザー定義チェインを指定した名前に変更する。これは見た目だけの変更なので、テーブルの構造には何も影響しない。
- -h ← ヘルプ。コマンド書式の説明を表示する。
- -p, –protocol [!] protocol ← ルールで使われるプロトコル、またはチェックされるパケットのプロトコル。指定できるプロトコルは、 tcp, udp, icmp, all のいずれか 1 つか、数値である。数値には、これらのプロトコルのどれかないし別のプロトコルを表す数値を指定することができる。 /etc/protocols にあるプロトコル名も指定できる。プロトコルの前に “!” を置くと、そのプロトコルを除外するという意味になる。数値 0 は all と等しい。プロトコル all は全てのプロトコルとマッチし、このオプションが省略された際のデフォルトである。
- -s, –source [!] address[/mask] ← 送信元の指定。 address はホスト名 (DNS のようなリモートへの問い合わせで解決する名前を指定するのは非常に良くない)・ネットワーク IP アドレス (/mask を指定する)・通常の IP アドレスのいずれかである。 mask はネットワークマスクか、ネットワークマスクの左側にある 1 の数を指定する数値である。つまり 24 という mask は 255.255.255.0 に等しい。アドレス指定の前に “!” を置くと、そのアドレスを除外するという意味になる。フラグ –src は、このオプションの別名である。
- -d, –destination [!] address[/mask] ← 送信先の指定。書式の詳しい説明については、-s (送信元) フラグの説明を参照。
- -j, –jump target ← ルールのターゲット、つまりパケットがマッチした場合にどうするかを指定する。ターゲットはユーザー定義チェイン (そのルール自身が入っているチェイン以外) でも、パケットの行方を即時に決定する特別な組み込み済みターゲットでも、拡張されたターゲット (以下の 「ターゲットの拡張」を参照) でもよい。このオプションがルールに指定されなかった場合は、ルールにマッチしてもパケットの行方に何も影響しないが、ルールのカウンタ は 1 つ加算される。
- -i, –in-interface [!] name ← パケットを受信することになるインターフェース名 (INPUT, FORWARD, PREROUTING チェインに入るパケットのみ)。インターフェース名の前に “!” を置くと、そのインターフェースを除外するという意味になる。インターフェース名が “+” で終っている場合、その名前で始まる任意のインターフェース名にマッチする。このオプションが省略された場合、任意のインターフェース名にマッチする。
- -o, –out-interface [!] name ← パケットを送信することになるインターフェース名 (FORWARD, OUTPUT, POSTROUTING チェインに入るパケットのみ)。インターフェース名の前に “!” を置くと、そのインターフェースを除外するという意味になる。インターフェース名が “+” で終っている場合、その名前で始まる任意のインターフェース名にマッチする。このオプションが省略された場合、任意のインターフェース名にマッチする。
- [!] -f, –fragment ← このオプションは、分割されたパケット(fragmented packet)のうち 2 番目以降のパケットだけを参照するルールであることを意味する。このようなパケット (または ICMP タイプのパケット)は送信元・送信先ポートを知る方法がないので、送信元や送信先を指定するようなルールにはマッチしない。 “-f” フラグの前に “!” を置くと、分割されたパケットのうち最初のものか、分割されていないパケットだけにマッチする。
- -c, –set-counters PKTS BYTES ← このオプションを使うと、(insert, append, replace 操作において) 管理者はパケットカウンタとバイトカウンタを初期化することができる。
- -v, –verbose ← 詳細な出力を行う。 list コマンドの際に、インターフェース名・(もしあれば)ルールのオプション・TOS マスクを表示させる。パケットとバイトカウンタも表示される。添字 ’K’, ’M’, ’G’は、それぞれ 1000, 1,000,000, 1,000,000,000 倍を表す (これを変更する -x フラグも見よ)。このオプションを append, insert, delete, replace コマンドに適用すると、ルールについての詳細な情報を表示する。
- -n, –numeric ← 数値による出力を行う。 IP アドレスやポート番号を数値によるフォーマットで表示する。デフォルトでは、iptables は (可能であれば) これらの情報をホスト名・ネットワーク名・サービス名で表示しようとする。
- -x, –exact ← 厳密な数値で表示する。パケットカウンタとバイトカウンタを K (1000 の何倍か)・M (1000K の何倍か)・G (1000M の何倍か)ではなく、厳密な値で表示する。このオプションは、-L コマンドとしか関係しない。
- –line-numbers ← ルールを一覧表示する際、そのルールがチェインのどの位置にあるかを表す行番号を各行の始めに付加する。
- –modprobe=command ← チェインにルールを追加または挿入する際に、(ターゲットやマッチングの拡張などで) 必要なモジュールをロードするために使う command を指定する。
コメント