サーバとして
・受信パケットは破棄。ただしステートフル性を確認し、サーバから送信されたパケットに関連するものは許可
・送信パケットは基本的にすべて許可
・ループバックアドレスに関してはすべて許可
・メンテナンスホスト(内部)からの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
ルータとして機能させると同時に、サーバとしても機能させます。サーバとしての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.