最終更新 2013年10月21日
OpenSWAN(with NETKEY)のパケットの流れを追ってみる
IPsecトンネルを実現するESPパケットの流れや、
そしてIPsecトンネルを出入りするプライベートアドレスを持ったパケットの流れについて、
通過するインターフェイスやチェインを手がかりに考察してみる。
ただし今回は、IPsecトンネルを出入りするパケットはさらにルーティングされない環境を扱っている。
すなわちそれらのパケットはOpenSWANの動作するマシン自身を終端としているものである。
また、今回は、プライベートネットワーク内に仮想的に構築した環境においてテストしているので、
ファイアーウォールについては一切考慮していない。
あくまで勝手な考察なので、間違っているかもしれないので、以下の内容については十分に吟味してください。
▲▽使用環境について▼△
・CentOS 6.4 ( 2.6.32-358.18.1.el6.x86_64 )
NICは「eth0」の一つだけ装備し
グローバルアドレスとして 2.2.2.2 を設定
している。
yum install openswan コマンドでOpenSWAN( 21.el6_4 )をインストールした。
次のコマンドを発行して、OpenSWANの動作に備えた。
# for f in /proc/sys/net/ipv4/conf/*/send_redirects ; do echo 0 > $f ; done
# for f in /proc/sys/net/ipv4/conf/*/accept_redirects ; do echo 0 > $f ; done
OpenSWANのチェックツールの結果は次の通りだった。
# ipsec verify
Checking your system to see if IPsec got installed and started correctly:
Version check and ipsec on-path [OK]
Linux Openswan U2.6.32/K2.6.32-358.18.1.el6.x86_64 (netkey)
Checking for IPsec support in kernel [OK]
SAref kernel support [N/A]
NETKEY: Testing for disabled ICMP send_redirects [OK]
NETKEY detected, testing for disabled ICMP accept_redirects [OK]
Checking that pluto is running [OK]
Pluto listening for IKE on udp 500 [OK]
Pluto listening for NAT-T on udp 4500 [OK]
Checking for 'ip' command [OK]
Checking /bin/sh is not /bin/dash [WARNING]
Checking for 'iptables' command [OK]
Opportunistic Encryption Support [DISABLED]
対向側(1.1.1.1)とのIPsecトンネルは設定が済み構築され、すでにトンネルを通ってpingが通じている。
(10.2.0.1)CentOS(2.2.2.2)===========IPsec===========(1.1.1.1)□(10.1.0.1)
2拠点にはトンネル内で有効なプライベートアドレスがOpenSWANにより設定され、
それぞれ、10.2.0.1、10.1.0.1 である。
■ESPパケットの流れを確認する■
○こちら側(ローカルアドレス:10.2.0.1、グローバルアドレス:2.2.2.2)で、ログを取る設定を行った。
INPUT OUTPUT FORWARDのチェインでESPパケットの通過をロギングする。
/sbin/iptables -F
/sbin/iptables -P INPUT ACCEPT
/sbin/iptables -P FORWARD ACCEPT
/sbin/iptables -P OUTPUT ACCEPT
/sbin/iptables -A INPUT -p esp -j LOG --log-prefix "INPUT"
/sbin/iptables -A OUTPUT -p esp -j LOG --log-prefix "OUTPUT"
/sbin/iptables -A FORWARD -p esp -j LOG --log-prefix "FORWARD"
○対向側(ローカルアドレス 10.1.0.1)からこちら側(ローカルアドレス 10.2.0.1)へpingを打ちつづけた。
# ping 10.2.0.1
10.2.0.1から受信: シーケンス番号=0 ttl=63 時間=1.059ミリ秒
10.2.0.1から受信: シーケンス番号=1 ttl=63 時間=1.225ミリ秒
10.2.0.1から受信: シーケンス番号=2 ttl=63 時間=1.168ミリ秒
10.2.0.1から受信: シーケンス番号=3 ttl=63 時間=1.334ミリ秒
10.2.0.1から受信: シーケンス番号=4 ttl=63 時間=1.216ミリ秒
10.2.0.1から受信: シーケンス番号=5 ttl=63 時間=1.159ミリ秒
…
○こちら側(ローカルアドレス 10.2.0.1)において、ログを確認した。
# tail /var/log/messages
Oct 2 00:53:38 localhost kernel:
INPUT
IN=eth0 OUT=
MAC=xx:xx:xx:xx:xx:xx: yy:yy:yy:yy:yy:yy: 08:00
SRC=1.1.1.1 DST=2.2.2.2 LEN=152 TOS=0x00 PREC=0x00 TTL=253 ID=21127
PROTO=ESP SPI=0x11111111
Oct 2 00:53:38 localhost kernel:
OUTPUT
IN= OUT=eth0
SRC=2.2.2.2 DST=1.1.1.1 LEN=152 TOS=0x00 PREC=0x00 TTL=64 ID=45901
PROTO=ESP SPI=0x22222222
Oct 2 00:53:39 localhost kernel:
INPUT
IN=eth0 OUT=
MAC=xx:xx:xx:xx:xx:xx: yy:yy:yy:yy:yy:yy: 08:00
SRC=1.1.1.1 DST=2.2.2.2 LEN=152 TOS=0x00 PREC=0x00 TTL=253 ID=21130
PROTO=ESP SPI=0x11111111
Oct 2 00:53:39 localhost kernel:
OUTPUT
IN= OUT=eth0
SRC=2.2.2.2 DST=1.1.1.1 LEN=152 TOS=0x00 PREC=0x00 TTL=64 ID=45902
PROTO=ESP SPI=0x22222222
Oct 2 00:53:40 localhost kernel:
INPUT
IN=eth0 OUT=
MAC=xx:xx:xx:xx:xx:xx: yy:yy:yy:yy:yy:yy: 08:00
SRC=1.1.1.1 DST=2.2.2.2 LEN=152 TOS=0x00 PREC=0x00 TTL=253 ID=21133
PROTO=ESP SPI=0x11111111
Oct 2 00:53:40 localhost kernel:
OUTPUT
IN= OUT=eth0
SRC=2.2.2.2 DST=1.1.1.1 LEN=152 TOS=0x00 PREC=0x00 TTL=64 ID=45903
PROTO=ESP SPI=0x22222222
以上の結果から、使用の環境においてESPパケットは、
INPUTとOUTPUTチェインに現れるが、FORWARDチェインには現れないことがわかる。
そして次のように考えることができると思った。
外部からのESPパケットは、グローバルアドレスを持つ「eth0」からINPUTチェインを通過して、
IPsec関係のプロセスに到達し処理される。
逆に、内部のIPsec関係のプロセスによって作成されたESPパケットは、
OUTPUTチェインを通過して、グローバルアドレスを持つ「eth0」からネットワーク上に出て行く。
つづいて、ESPカプセルに出入りするICMPパケットの流れを追う。
■IPsecトンネル内を通過するICMPパケットの流れを確認する■
○こちら側(ローカルアドレス 10.2.0.1)で、ログを取る設定を行った。
INPUT OUTPUT FORWARDのチェインでICMPパケットの通過をロギングする。
/sbin/iptables -F
/sbin/iptables -P INPUT ACCEPT
/sbin/iptables -P FORWARD ACCEPT
/sbin/iptables -P OUTPUT ACCEPT
/sbin/iptables -A INPUT -p icmp -j LOG --log-prefix "INPUT"
/sbin/iptables -A OUTPUT -p icmp -j LOG --log-prefix "OUTPUT"
/sbin/iptables -A FORWARD -p icmp -j LOG --log-prefix "FORWARD"
○対向側(ローカルアドレス 10.1.0.1)からこちら側(ローカルアドレス 10.2.0.1)へpingを打ちつづけた。
# ping 10.2.0.1
10.2.0.1から受信: シーケンス番号=0 ttl=63 時間=2.815ミリ秒
10.2.0.1から受信: シーケンス番号=1 ttl=63 時間=1.198ミリ秒
10.2.0.1から受信: シーケンス番号=2 ttl=63 時間=1.374ミリ秒
10.2.0.1から受信: シーケンス番号=3 ttl=63 時間=1.206ミリ秒
10.2.0.1から受信: シーケンス番号=4 ttl=63 時間=1.190ミリ秒
10.2.0.1から受信: シーケンス番号=5 ttl=63 時間=1.326ミリ秒
…
○こちら側(ローカルアドレス 10.2.0.1)において、ログを確認した。
# tail /var/log/messages
Oct 21 04:09:29 localhost kernel:
INPUT
IN=eth0 OUT=
MAC=xx:xx:xx:xx:xx:xx: yy:yy:yy:yy:yy:yy: 08:00
SRC=10.1.0.1 DST=10.2.0.1
LEN=92 TOS=0x00 PREC=0x00 TTL=255 ID=41
PROTO=ICMP TYPE=8 CODE=0 ID=64457 SEQ=90
Oct 21 04:09:29 localhost kernel:
OUTPUT
IN= OUT=eth0
SRC=10.2.0.1 DST=10.1.0.1
LEN=92 TOS=0x00 PREC=0x00 TTL=64 ID=45501
PROTO=ICMP TYPE=0 CODE=0 ID=64457 SEQ=90
Oct 21 04:09:30 localhost kernel:
INPUT
IN=eth0 OUT=
MAC=xx:xx:xx:xx:xx:xx: yy:yy:yy:yy:yy:yy: 08:00
SRC=10.1.0.1 DST=10.2.0.1
LEN=92 TOS=0x00 PREC=0x00 TTL=255 ID=44
PROTO=ICMP TYPE=8 CODE=0 ID=64458 SEQ=91
Oct 21 04:09:30 localhost kernel:
OUTPUT
IN= OUT=eth0
SRC=10.2.0.1 DST=10.1.0.1
LEN=92 TOS=0x00 PREC=0x00 TTL=64 ID=45502
PROTO=ICMP TYPE=0 CODE=0 ID=64458 SEQ=91
トンネルに出入りするicmpパケットは、
使用の環境においてINPUTとOUTPUTチェインに現れるが、
FORWARDチェインには現れないことがわかる。
■以上のことから、次のように考えた■
あくまでも推測であり、自分なりの理解です。
実際の動きとは異なると思われるので、ご注意ください。
以上のテストから次の流れが見える。
外部から来たESPカプセルは、INPUTチェインを通過し、IPsec関係プロセスにより処理され、
プライベートアドレス(10.2.0.1)宛てのICMPリクエストパケット(TYPE=8)がその中から取り出される。
そしてこの取り出されたパケットは、おかしいことに「eth0」からINPUTチェインを通過し、
ICMPリクエストパケットを処理するプロセスに到達する。
これについて、さらに次のように考えた。
IPsec関係プロセスによってESPカプセルから取り出されたこのICMPリクエストパケット(TYPE=8)は、
一切、OUTPUTチェインやFORWARDチェインを通過していない。
にわかに、あたかも「eth0」の外からやってかのように現れ、INPUTチェインを通過し、
ICMPリクエストパケットを処理するプロセスに到達しているように見える。
ここに、NETKEYを用いたIPsecトンネル出入り口の秘密があるようだ。
一方、内部のICMPパケットを処理するプロセスによって作成されたICMPリプライパケット(TYPE=0)は、
プライベートアドレス(10.1.0.1)宛てである。
これはOUTPUTチェインを通過して、「eth0」からネットワーク上に出て行くよう方向づけられている。
routeコマンドでも、対向ネットワーク宛のプライベートパケットは、eth0へのルーティングテーブルを表示していた。(↓)
10.1.0.0 * 255.255.0.0 U 0 0 0 eth0
しかし、eth0へ向かうもののネットワーク上に出ずに、直後にIPsecパケットにカプセル化されていると思われる。
さきほどは、カプセルを解かれたパケットが入力されるときの秘密について考えた。
IPsec関係プロセスによってカプセルを解かれたICMPパケットが、
あたかも「eth0」の外にジャンプしたかのように現れマシンに入力されるのだった。
逆に、カプセル化されるパケットもまた、「eth0」へ行き先が方向づけられた後で、
IPsec関係プロセスに捕捉されカプセル化されるのではないかと思う。
カプセリング処理されて然るべきパケット(OpenSWANの対向ネットワーク設定に拠ると思われる。)については、
「eth0」に出力されると見せかけて実際はネットワーク上へは流れ出ずに、
IPsec関係のプロセスによって途中で捕捉され、カプセル化処理を受けるのだと思う。
ここで生成されたESPパケットが、OUTPUTチェインを経てグローバルアドレス(2.2.2.2)を持つ「eth0」からネットワーク上に出て行くのだと思う。