連載
» 2003年02月11日 00時00分 UPDATE

Linuxで作るIPv6ネットワーク環境(3):IPv6ネットワーク構築とパケットフィルタリング (1/3)

IPv6環境の構築も大詰め。最後にip6tablesを使ったパケットフィルタリングでセキュリティ対策を行う。そのマシンをルータとすることで、IPv4とIPv6が共存したネットワークとなる。

[みやもとくにお,@IT]

前編中編で、

  • LinuxマシンのIPv6化
  • インターネットサービスのIPv6化

について解説しました。後編では、それらの環境をベースにしてIPv6ネットワークの構築について解説します。また、中編で解説しそびれたsshのIPv6対応についても紹介します。

共存可能なIPv4とIPv6

 IPv4とIPv6は、どちらもOSIモデルにおけるレイヤ3のプロトコルであり、その下に位置するイーサネットやIEEE802.11bをはじめとするレイヤ2のプロトコルとは独立した実装になります(図1)。

図1 OSI対比図 図1 OSI対比図

 例えば、イーサネット上ではIPv4パケットもIPv6パケットもイーサネットフレームに格納されるデータの構成要素であり(図2)、イーサネットレベルのデータ転送は変わるところがありません。

図2 イーサネットフレームの構造 図2 イーサネットフレームの構造

 イーサネットのフレーム自体は、IPアドレスとイーサネットアドレスの対応表に従い、デスティネーションに指定されたIPアドレスに対応するイーサネットアドレスを持つホストに送られます。もっとも、IPv4のプロトコルスタックしか持たないホストは、IPv6パケットが格納されたイーサネットフレームを受信したとしても、プロトコル自体を知らないためそのフレームを処理できません。

 ここではイーサネットを例に取って説明しましたが、基本的にはほかのレイヤ2のプロトコルでもこの部分については変わりません。

 このようなことから、同じネットワーク(LAN)の上をIPv4パケットとIPv6パケットが飛び交うこと自体はまったく問題ありません。そして、ほとんどの移行/共存において、既存のイーサネットベースのネットワーク上ではIPv4パケットがやりとりされているのが前提になります。ただし、トラフィックが増大することによる性能問題についてはプロトコルに関係なく発生し得るので、別途検討の余地が出てきます。

 以上の説明で、既存のLAN上にIPv6ネットワークを構築することは問題ないとご理解いただけたかと思います。本稿では、図3のようなネットワークを想定して、IPv6ホストを追加していきます。

図3 想定ネットワーク構成 図3 想定ネットワーク構成

 また、今回のIPv6ネットワークは、以下のような方針で構築します。

  • 作業は最小限にとどめる
    IPv4によるネットワーク構築と同様の作業は発生します。
  • USAGIマシン以外のホストも外部に接続できるようにする
    USAGIマシンを外部との接続用のルータにします。
  • ダイナミックルーティングは設定しない
    中編で紹介したzebraは使用しません。

IPv6環境におけるパケットフィルタリング

 図3のUSAGIマシンは、前編および中編で構築したホストです。このホストは、すでにIPv6-IPv4トンネルを実施できる環境です。具体的には、図4図5のような処理を行います。このマシンに対して、必要な設定を施していきましょう。

図4 USAGIルータの処理(LANから外部ネットワークへ) 図4 USAGIルータの処理(LANから外部ネットワークへ)
図5 USAGIルータの処理(外部ネットワークからLANへ) 図5 USAGIルータの処理(外部ネットワークからLANへ)

■パケットフィルタリング機能の追加

 外部から不審なパケットが入ってくるのは嫌なものです。そこで、パケットフィルタリング機能を有効にする必要があります。

 IPv6に対応したパケットフィルタリング機能を有効にするには、カーネルの再構築が必要です。前編の「カーネルの設定とコンパイル」の部分で、画面1から画面2へ移動し、「Network packet filtering (replaces ipchains)」のオプションを有効にします。後は、カーネルをコンパイルすればIPv6のパケットフィルタリング(ip6tables)に対応したカーネルが作成されます。LILOやGRUBなどのブートローダの設定を適切に行い、USAGIマシンを再起動すれば、新しく作成したカーネルの機能が使えるようになります。

画面1 「Networking options」を選択 画面1 「Networking options」を選択
画面2 「Network packet filtering (replaces ipchains)」を有効化 画面2 「Network packet filtering (replaces ipchains)」を有効化

 ここまでの作業で、カーネルはip6tablesの機能を獲得するわけですが、その機能を使用するにはiptablesコマンドのバージョンを新しくする必要があります。USAGIのアーカイブにもip6tablesは含まれていますが、ここではオリジナルのiptablesを入手して、そこからインストールしてみましょう。

 以下の手順を実行することで、ip6tablesのコマンドおよび必要なライブラリが/usr/local配下にインストールされます。

  • アーカイブの入手
    http://www.netfilter.org/から、iptablesの最新版をダウンロードする。原稿執筆時(2003年1月)の最新版は1.2.7a。
     
  • make
$ make KERNEL_DIR=[USAGIのカーネルソースのトップディレクトリ]
  • インストール
$ su root
# make install KERNEL_DIR=[USAGIのカーネルソースのトップディレクトリ]

 usagi-linux24-stable-20021007.tar.bz2を展開すると、カーネルソースは[アーカイブを展開したディレクトリ]/usagi/kernel/linux24に配置されます。筆者は、/home/wakatono/work/usagi配下にアーカイブを展開しているため、make時のコマンドラインは、

$ make KERNEL_DIR=/home/wakatono/work/usagi/usagi/kernel/linux24

となりました。

 make install時のコマンドラインも同様なので、この部分は各自の環境に合わせてください。

■パケットフィルタリングの設定

 ip6tablesコマンドが利用できるようになったところで、実際にフィルタを掛けてみましょう。しかしip6tablesは、現状ではiptablesのようにstateによるフィルタを設定することができません。これは、

iptables -A FORWARD -p tcp -j ACCEPT -m state --state ESTABLISHED

のように、例えばTCPコネクションが開設されている(ESTABLISHED)というような状態における処理がip6tablesで記述できないことを意味します。従って、

  • 内部ネットワークからの接続は通す
  • 外部ネットワークからの接続は許さない

というルールを容易に記述できません。そこで、フィルタとしては不完全ですが、以下のポリシーで作成してみましょう。

  • SYNフラグが立っていなければIPv6パケットは通過させる
  • SYN ACKフラグが立っていればIPv6パケットは通過させる
  • それ以外はDROP

 TCPプロトコルでは、コネクションを開設する際に、接続相手に対してSYNフラグが立ったパケットを送り、それに対応するACKフラグと自分向きのSYNフラグが立ったパケットを受け付けます。それが問題なければACKフラグが立ったパケットを相手に送り、受け付けられることでコネクションが確立されます()。

注:この一連の流れを「3wayハンドシェイク」と総称します。


 つまり、コネクションを開設する際はSYNフラグのみが立ったパケットを受け付けるわけなので、コネクションを受け付けたくないときはそのパケットを拒否すればよいことになります。ただし、SYNフラグと同時にACKフラグが立ったパケットは、自分からコネクションを開設しようとしている場合は必ず受け付けなくてはなりません(図6)。

図6 コネクション確立までの流れ(3wayハンドシェイク) 図6 コネクション確立までの流れ(3wayハンドシェイク)

 これらのポリシーをip6tablesのコマンドラインで表現してみましょう。

 以下のコマンドラインは筆者が実験用に作成したもので、INPUTチェインやFORWARDチェインのデフォルトポリシーの設定という形にはなっていません。実際に使用する場合は、各自の環境に合わせてパラメータやオプションを変更する必要があります。なお、以下の例ではTCP/80番ポートに対するアクセスを受け付けるようにしています。ほかのポートに対するアクセスを記述する場合は、この部分を増やしていけばよいでしょう。

# /usr/local/sbin/ip6tables -N ip6
# /usr/local/sbin/ip6tables -A ip6 -d 2001:2c0:418::/48 -p tcp --dport 80 -j ACCEPT
# /usr/local/sbin/ip6tables -A ip6 -d 2001:2c0:418::/48 -p tcp --tcp-flags ! FIN,SYN,RST,ACK SYN -j ACCEPT
# /usr/local/sbin/ip6tables -A ip6 -d 2001:2c0:418::/48 -p tcp --tcp-flags FIN,SYN,RST,ACK SYN,ACK -j ACCEPT
# /usr/local/sbin/ip6tables -A ip6 -j DROP
# /usr/local/sbin/ip6tables -A FORWARD -i tun6to4 -j ip6
# /usr/local/sbin/ip6tables -A INPUT -i tun6to4 -j ip6
リスト1 ip6tables使用例
1行目:
ip6チェインを新規に作成
2行目:2001:2c0:418::/48なネットワークについて、TCP/80番ポートに対するパケットを受け付ける
3行目:SYNフラグが立っていないTCPパケットを受け付ける
4行目:SYNフラグとACKフラグが立っているTCPパケットを受け付ける
5行目:すべてのパケットをDROPする
6行目:FORWARDチェインで、インターフェイスtun6to4から入ってくるパケットについて、ip6チェインのルールを適用する
7行目:INPUTチェインで、インターフェイスtun6to4から入ってくるパケットについて、ip6チェインのルールを適用する

 このコマンドラインが成功した時点で、OSに対して設定されるip6tablesの内容をリスト2に示します。

# ip6tables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ip6        all      anywhere             anywhere

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination
ip6        all      anywhere             anywhere

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Chain ip6 (2 references)
target     prot opt source               destination
ACCEPT     tcp      anywhere             2001:2c0:418::/48  tcp 
dpt:http
ACCEPT     tcp      anywhere             2001:2c0:418::/48  tcp 
flags:!FIN,SYN,RST,ACK/SYN
ACCEPT     tcp      anywhere             2001:2c0:418::/48  tcp 
flags:FIN,SYN,RST,ACK/SYN,ACK
DROP       all      anywhere             anywhere
リスト2 ip6tablesの設定状況

 なお、リスト1の5行目でパケットをDROPしていますが、筆者の環境ではREJECTにするとTCPによる接続要求が来た際にカーネルがハングアップする現象が多発したためです。DROPにしたところ、この不具合は発生しなくなりました()。

注:後日、REJECTに戻して再検証するとこの事象は発生しませんでした。それ以降、この事象の再現確認は行えていません。


■eth0に対するIPv6アドレスの付与

 中編で付与したIPv6アドレスは、どのイーサネットインターフェイスにも対応していません。これは、図7のようなインターフェイスが存在しているところにそれぞれのアドレスが設定されており、トンネルインターフェイスは物理的なインターフェイスとは対応しないものであるためです。実在するネットワークインターフェイスであるeth0に対するIPv6アドレスの付与が必要になります。

図7 eth0に対するIPv6アドレスの付与 図7 eth0に対するIPv6アドレスの付与

 また、付与するアドレスが所属するネットワークも割り出さなくてはなりません。今回の場合は、表1のような形でネットワークおよびアドレスを割り出しました。

   
ネットワークパラメータ
   
eth0
プリフィックス
tun6tu4
マシン種別 USAGIマシン 2001:2c0:418:1::1 2001:2c0:418:1 2001:2c0:418::11
(中編で付与済み)
IPv6クライアント 2001:2c0:418:1::2 (存在しない)
表1

 USAGIマシンのeth0は、以下のような形でネットワークアドレスを追加します。

$ su root
# /sbin/ifconfig eth0 add 2001:2c0:418:1::1/64 up

■パケット転送設定

 すでに設定されている場合もあるでしょうが、USAGIマシンに接続されたネットワーク間でパケットをやりとりできるようにするには、IPv6でのパケット転送を有効にする必要があります。具体的には、以下のような操作を行います。

$ su root
# echo 1 > /proc/sys/net/ipv6/conf/all/forwarding

 この設定を行わないと、USAGIマシンがIPv6パケットをほかのネットワークに転送(forwarding)しないため、結果としてこの後に設定する実験用IPv6マシンから外部のネットワークに対する接続が行えないので注意してください。


       1|2|3 次のページへ

Copyright© 2017 ITmedia, Inc. All Rights Reserved.

@IT Special

- PR -

TechTargetジャパン

この記事に関連するホワイトペーパー

RSSについて

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

メールマガジン登録

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