iptablesでパケットフィルタリング 概要と実例

/ LPIC / Comment[0]

パケットフィルタリングはinput, output, forwardの3箇所で行いそれぞれをチェインと呼びます。チェインとはパケット検査のためのルールセットのことでチェインにルールを追加して設定します。

チェインのセットをテーブルといいます。

filter
デフォルトフィルタリングテーブル
INPUT, OUTPUT, FORWARD
nat
新しい接続パケットのテーブル
PREROUTING, POSTROUTING, OUTPUT
mangle
特別なパケット変換のテーブル
INPUT, OUTPUT, FORWARD, PREROUTING, POSTROUTING

iptablesの構文とオプション

iptablesの引数にはコマンドチェインターゲットルールオプションを指定して設定を行います。

以下はiptablesの主な構文例です

  • iptables [-t テーブル] {-A|-C|-D} チェイン ルール
  • iptables [-t テーブル] -I チェイン [ルール番号] ルール
  • iptables [-t テーブル] -P チェイン ターゲット
  • iptables [-LFNX] [チェイン]

コマンド

-A
指定したチェインの最後にルールを追加
-D
指定したチェインからルールを削除
-P
指定したチェインのデフォルトポリシーを変更
-L [チェイン]
ルールの一覧表示
-N チェイン
任意名のユーザ定義チェインを作成
-X チェイン
指定したユーザ定義チェインを削除
-l
ルール番号を指定してルールを挿入
-F チェイン
指定したチェイン内のルールを削除

チェイン

INPUT
入力パケット
OUTPUT
外向きパケット
FORWARD
自分を経由するパケット
PREROUTING
入力パケットを変換
POSTROUTING
外向きパケットを変換

ターゲット

ACCEPT
許可
DROP
破棄
REJECT
明示的に拒否
MASQUERADE
ソースIPアドレス,ポート番号の変換
SNAT
送信元IPアドレスの変換
DNAT
送信先IPアドレスの変換
LOG
ログに出力

ルール

-s
ソースIPアドレス
-d
宛先IPアドレス
--sport
ソースポート
--dport
宛先ポート
--to
宛先を指定
-j
適用されるターゲット
-p
プロトコル
-i
入力インターフェイス
-o
出力インターフェイス

オプション

  • -v 詳細表示
  • -n 数値で表示
  • --line-numbers ルール番号を表示

実例

ウェブブラウジングのみ許可

ウェブブラウジングで使うポートのみを許可する設定方法です。まずウェブブラウジングに必要なポートを挙げてみると以下の3つ。
HTTP:80/TCP, HTTPS:443/TCP, DNS:53/UDP これらを許可してやります。

始めにデフォルトのポリシーとして全パケットを拒否するように設定
# iptables -P INPUT DROP
# iptables -P OUTPUT DROP
# iptables -P FORWARD DROP

全パケットが拒否されました。次に80,443,53/udpを許可します。
# iptables -A INPUT -p tcp --sport 80 -j ACCEPT
# iptables -A INPUT -p tcp --sport 443 -j ACCEPT
# iptables -A INPUT -p udp --sport 53 -j ACCEPT
# iptables -A OUTPUT -p tcp --dport 80 -j ACCEPT
# iptables -A OUTPUT tcp --dport 443 -j ACCEPT
# iptables -A OUTPUT -p udp --dport 53 -j ACCEPT
これで完了です。ウェブブラウジングまたは80/TCP,443/TCPを使用するアプリケーションのみ利用できるようになりました。

ICMPパケットを破棄

ネットワーク疎通にICMPが使われますが、必要であればICMPを遮断することが可能です。ネットワーク疎通あるいはホストの生死を問うには他の方法がいくらでもあるので(ARPパケットを送ってみたり、開いているであろうポートにSYNやACKやFINを送るなど)これはあんまり意味はないのですが。

# iptables -A INPUT -p icmp -j DROP

ちなみにDROPとREJECTの違いは、破棄か拒否となっていますがこれはICMPエコーを送ってみるとわかりやすいです。

DROPの場合は応答が無い

$ ping 192.168.1.1
PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data.
^C
--- 192.168.1.1 ping statistics ---
5 packets transmitted, 0 received, 100% packet loss, time 3999ms

REJECTの場合は疎通出来ないという返答がある

$ ping 192.168.1.1
PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data.
From 192.168.1.1 icmp_seq=1 Destination Port Unreachable
From 192.168.1.1 icmp_seq=2 Destination Port Unreachable
From 192.168.1.1 icmp_seq=3 Destination Port Unreachable
^C
--- 192.168.1.1 ping statistics ---
3 packets transmitted, 0 received, +3 errors, 100% packet loss, time 1999ms

攻撃者に余計な情報を与えないためにDROPすることはいいことですが、DROPするということは攻撃者ではない仲間であってもタイムアウトまで待たせてしまうことになります。セキュリティとパフォーマンス両方を考えてDROPとREJECTを選択しましょう。

22/TCPの接続をログに出力

# iptables -A INPUT -p tcp --dport 22 -j LOG --log-prefix "SSH Trying: "

dmesgの出力

[ 3092.498637] SSH Trying: IN=eth0 OUT= MAC=bc:5f:f4:49:6d:35:00:22:cf:6b:64:f2:08:00 SRC=192.168.1.1 DST=192.168.1.3 LEN=52 TOS=0x00 PREC=0x00 TTL=64 ID=54085 DF PROTO=TCP SPT=34436 DPT=22 WINDOW=276 RES=0x00 ACK URGP=0 

ポート転送

自ホストの2222/TCPにパケットが来たら192.168.1.2の22ポートに転送する例です。

まずは転送を許可します。
# iptables -A FORWARD -d 192.168.1.2 -p tcp --dport 22 -j ACCEPT

次に、自ホストの2222/TCPにパケットが届いた場合に転送させる設定を行います。
# iptables -t nat -A PREROUTING -p tcp --dport 2222 -j DNAT --to 192.168.1.2:22

iptablesの設定の保存

iptablesの設定は再起動するとデフォルトに戻ってしまいます。次回起動時も設定を維持するためには以下のコマンドを実行します。
/etc/init.d/iptables save

保存されている設定を読み込むにはiptablesをリロードします。
/etc/init.d/iptables reload

Debian系では/etc/network/if-pre-up.d/以下に任意名でファイルを作成し、iptablesコマンドを記述しておきます。
iptables-saveというコマンドがありますが、これは保存するコマンドではなく現在の設定値を標準出力するものです。

ルーターの構築

実験環境ではeth0が外側ネットワーク10.0.1.1/16、eth1が内部ネットワーク192.168.1.1/24となっています。

IPマスカレード

プライベートアドレスとグローバルアドレスの相互変換を行う機能をIPマスカレードといいます。iptablesで実現するには以下のコマンドを実行します。
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

SNAT

外側のアドレスが固定されているのであればSNATで事足ります。
# iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j SNAT 10.0.1.1

関連記事

コメント

:
:
:
:
:
管理人のみ表示を許可