連載
» 2010年02月09日 00時00分 公開

natテーブルを利用したLinuxルータの作成iptablesテンプレート集 改訂版(3)(2/3 ページ)

[鶴長鎮一,@IT]

テンプレート5
IPマスカレードによるLinuxルータ

サーバとして
 受信パケットは破棄。ただしステートフル性を確認し、サーバから送信されたパケットに関連するものは許可
 送信パケットは基本的にすべて許可
 ループバックアドレスに関してはすべて許可
 メンテナンスホスト(内部)からのping、メンテナンスホストへのpingを許可
 メンテナンスホスト(内部)からのssh(TCP 22)を許可

ルータとして
 Linuxサーバを経由して外部へ出ていくパケットのソースアドレスを変換
 内部アドレスやプライベートアドレスが外部に漏れないようにブロック
 Windowsファイル/プリンタ共有パケット(TCP/UDP 137〜139、445)の転送をブロック
 その他転送パケットで、内部ネット→外部ネットのものは許可。外部ネット→内部ネットへの転送パケットはステートフル性を確認できたものだけ許可

 このテンプレートでは、市販のブロードバンドルータと同等な働きをするLinuxルータを作ります。Linuxサーバに2枚のネットワークインターフェイスを組み込み、一方にはプロバイダなどから与えられたグローバルアドレス、もう一方にはプライベートアドレスを設定します(以下、グローバルアドレス側を外部ネット、プライベートアドレス側を内部ネットとします)。

 1    #! /bin/sh
 2
 3    trusthost='192.168.0.20'
 4    internal_net='192.168.0.0/24'
 5    my_internal_ip='192.168.0.1'
 6
 7    echo 1 > /proc/sys/net/ipv4/ip_forward
 8
 9    ##############
10    #Flush & Reset
11    ##############
12    /sbin/iptables -F
13    /sbin/iptables -t nat -F
14    /sbin/iptables -X
15
16    ##############
17    #Deafult Rule
18    ##############
19    /sbin/iptables -P INPUT DROP
20    /sbin/iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
21
22    /sbin/iptables -P OUTPUT ACCEPT
23
24    /sbin/iptables -P FORWARD DROP
25    /sbin/iptables -A FORWARD -i eth1 -o eth0 -s $internal_net -j ACCEPT
26    /sbin/iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
27
28    #########
29    #loopback
30    #########
31    /sbin/iptables -A INPUT -i lo -j ACCEPT
32
33    ###############################
34    #ICMP trusthost->my_internal_ip
35    ###############################
36    /sbin/iptables -A INPUT -p icmp --icmp-type echo-request -s $trusthost -d $my_internal_ip -j ACCEPT
37    ###############################
38    #ICMP my_internal_ip->trusthost
39    ###############################
40    /sbin/iptables -A INPUT -p icmp --icmp-type echo-reply -s $trusthost -d $my_internal_ip -j ACCEPT
41    ###############################
42    #ssh trusthost-> my_internal_ip
43    ###############################
44    /sbin/iptables -A INPUT -p tcp --syn -m state --state NEW -s $trusthost -d $my_internal_ip --dport 22 -j ACCEPT
45    #################
46    #SNAT(masquerade)
47    #################
48    /sbin/iptables -t nat -A POSTROUTING -o eth0 -s $internal_net -j MASQUERADE
49
50    ################################################
51    #Blocking Private Address
52    ################################################
53    /sbin/iptables -A OUTPUT -o eth0 -d 10.0.0.0/8 -j DROP
54    /sbin/iptables -A OUTPUT -o eth0 -d 172.16.0.0/12 -j DROP
55    /sbin/iptables -A OUTPUT -o eth0 -d 192.168.0.0/16 -j DROP
56    /sbin/iptables -A OUTPUT -o eth0 -d 127.0.0.0/8 -j DROP
57
58    #########
59    #logging
60    #########
61    /sbin/iptables -N LOGGING
62    /sbin/iptables -A LOGGING -j LOG --log-level warning --log-prefix "DROP:" -m limit
63    /sbin/iptables -A LOGGING -j DROP
64    /sbin/iptables -A INPUT -j LOGGING
65    /sbin/iptables -A FORWARD -j LOGGING
66
テンプレート5

テンプレート5の解説

 ルータとして機能させると同時に、サーバとしても機能させます。サーバとしてのiptablesの設定はテンプレート4をベースしています。

 3〜7行目で環境に合わせた値を設定します。メンテナンスホストが外部ネット側にある場合は、テンプレートの修正が必要になるので注意が必要です。その方法は後述します。

    $trusthost       メンテナンスホストのIPアドレス
    $internal_net    内部ネットワークアドレス
    $my_internal_ip  Linuxルータの内部ネット側IPアドレス

 Linuxをルータとして機能させるには、IPパケットを内部→外部、または外部→内部に転送(フォワーディング)する必要があります。そこで、7行目のように「ip_forward」に1を設定します。「ip_forward」の設定は、Linux起動中に一度だけ行えば十分です。

7 echo 1 > /proc/sys/net/ipv4/ip_forward

 12〜14行目でiptablesの初期化を行います。テンプレート4までで使用した内容に、今回は13行目を新たに追加し、natテーブルの初期化を実行しています。

13 iptables -t nat -F

 「-t nat」でnatテーブルを指定し、「-F」で初期化を行います。このように、テーブルの指定には「-t」オプションを使用します。

 19〜26行目でデフォルトルールを設定します。基本は破棄(DROP)ですが、テンプレート4同様、Linuxサーバから送信されるパケット(OUTPUT)には制限を設けず許可し(ACCEPT)、Linuxサーバが受信するパケット(INPUT)に関しては、ステートフル性を確認し、「--state ESTABLISHED,RELATED」となっているものに通過許可(ACCEPT)を与えます。

 今回は、Linuxルータ自身が処理するパケットだけでなく、転送するパケットについてもデフォルトルールを設ける必要があります。内部ネットから外部ネットへの接続、つまり「eth1から入ってeth0へ転送されるパケット」は制限なしとし、25行目を追加します。それに合わせて、26行目で「eth0からeth1へ転送されるパケット」もステートフル性を確認できたものだけ許可するようにします。

25 /sbin/iptables -A FORWARD -i eth1 -o eth0 -s $internal_net -j ACCEPT
26 /sbin/iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT

 ここからがテンプレート5の要、IPマスカレードの設定です。基本は48行目です。

    48 /sbin/iptables -t nat -A POSTROUTING -o eth0 -s $internal_net -j MASQUERADE
        -t nat            natテーブルを使用
        -A POSTROUTING    POSTROUTINGチェインを使用し、内部ネットから外部ネットへ出ていくパケットのソースIPを書き換える 
        -o eth0           パケットが出ていくインターフェイス(eth0)を指定 
        -s $internal_net  ソース側ネットワークアドレス(192.168.0.0/24) 
        -j MASQUERADE	    IPマスカレードを行う

 内部ネット発のパケットが外部ネットでルーティングされるには、出ていくパケットのソースアドレスを、プライベートアドレスからLinuxルータの外部ネット側(eth0)のアドレスに書き換える必要があります(SNAT)。そのためにPOSTROUTINGチェインを使用し、同時に「-j MASQUERADE」を指定し、複数のパケットが1つの外部アドレスを共有できるようにIPマスカレードを使用します。この1行でブロードバンドルータの役割のほとんどをこなしています。

 53〜56行目では、内部アドレスやプライベートアドレスが外部ネットワークに漏れないようにブロックしています。

   53	/sbin/iptables -A OUTPUT -o eth0 -d 10.0.0.0/8 -j DROP
    54	/sbin/iptables -A OUTPUT -o eth0 -d 176.16.0.0/12 -j DROP
    55	/sbin/iptables -A OUTPUT -o eth0 -d 192.168.0.0/16 -j DROP
    56	/sbin/iptables -A OUTPUT -o eth0 -d 127.0.0.0/8 -j DROP

 「-t テーブル名」の指定がないことからも分かるように、filterテーブルを使って、パケットフィルタリングを実施しています。マナーとして、プライベートアドレスを外部に漏出しないのは当然として、最近ではIPスプーフィングでソースIPにプライベートアドレスを使用するケースもあるため、そうしたパケットを垂れ流すネットワークと見なされないように設定します。

 61〜65行目までが、テンプレート4と同じく破棄されるパケットのロギングです。FORWARDチェインに対してもロギングを設定します。

    61	/sbin/iptables -N LOGGING
    62	/sbin/iptables -A LOGGING -j LOG --log-level warning --log-prefix "DROP:" -m limit
    63	/sbin/iptables -A LOGGING -j DROP
    64	/sbin/iptables -A INPUT -j LOGGING
    65	/sbin/iptables -A FORWARD -j LOGGING

 shスクリプトの用意ができたら、前回までのようにshスクリプトを実行して動作を確認します。iptablesでnatテーブルの状態を確認するには、次のようにします。

# iptables -nL #filterテーブルの設定確認
# iptables -t nat -nL #natテーブルの設定確認

改造のヒント:メンテナンスホストが外部ネット側にある場合

 テンプレート5では、Linuxサーバのメンテナンスを内部ネットの端末から行えるようパケットフィルタリングを解除しました。自宅や外出先からメンテナンスを行うには、インターネット(外部)からサーバに接続する必要があります。メンテナンスホストが外部ネット側にある場合を想定し、テンプレート5を改造します。

 33〜50行目はテンプレート5と同じですが、環境によっては、つまり前述した「メンテナンスホストが外部ネット側にある場合」には見直しが必要になります。メンテナンスホストからのssh接続を許可している44行目を見てみましょう。

 外部ネットワークのメンテナンスホストからSSHで接続できるようにするには、テンプレート5の44行目を次のように修正します。

    44	/sbin/iptables -A INPUT -p tcp --syn -m state --state NEW -s $trusthost -d $外部ネット側IPアドレス --dport 22  -j ACCEPT

 メンテナンスホストが内部にある場合、SSHの接続先は、サーバの内部ネット側のアドレス「$my_internal_ip」になりますが、メンテナンスホストが外部ネットにある場合は、サーバの外部ネット側のIPアドレスに接続します。パケットフィルタリングを解除する場合も、サーバの外部ネット側のIPアドレスに対する接続を許可するようにします。

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。