14.9. VPN over IPsec

執筆: Clayton Nik [FAMILY Given].

この章では、FreeBSD ゲートウェイを使って、 インターネットによって分けられた、二つのネットワーク間に VPN を作成します。

14.9.1. IPsec を理解する

執筆: Pandya Hiten M. [FAMILY Given].

この節では、IPsec を設定する過程を通して、 IPsec を使った安全な通信の実現方法について解説します。 IPsec を設定するためには、 カスタムカーネルの構築方法をよく知っている必要があります (8章FreeBSD カーネルのコンフィグレーション をご覧ください)。

IPsec は、インターネットプロトコル (IP) レイヤのトップにあるプロトコルです。 二つもしくはそれ以上のホスト間で安全に通信することを可能にします (そのため、名前に sec が含まれています)。 FreeBSD の IPsec ネットワークスタック は、 IPv4 および IPv6 の両方のプロトコルファミリに対応している KAME 実装をベースとしています。

IPsec は二つのサブプロトコルから構成されます。

  • Encapsulated Security Payload (ESP) は、(Blowfish, 3DES のような) 対称暗号アルゴリズムを使ってデータを暗号化することで、 サードパーティのインタフェースから IP パケットデータを保護します。

  • Authentication Header (AH), は、暗号チェックサムを計算し、IP パケットのヘッドフィールドを安全なハッシュ関数でハッシュ化することで、 IP パケットヘッダをサードパーティのインタフェースやなりすましから守ります。 ハッシュを含む追加のヘッダが追加され、 パケット情報の検証が可能になります。

ESP および AH は、使用する環境に合わせて、 一緒に使うことも別々に使うこともできます。

IPsec は、直接二つのホスト間のトラフィックを暗号化する Transport Mode、もしくは、 2 つの共同するネットワーク間で安全に通信することを可能にするように、 2 つのサブネット間に virtual tunnels を構築する Tunnel Mode のどちらでも用いることができます。 後者はより一般的には、 Virtual Private Network (VPN) として知られています。 FreeBSD での IPsec サブシステムに関するより詳細な情報については、 ipsec(4) マニュアルページを参照してください。

カーネルに IPsec のサポートを追加するには、 カーネルコンフィグレーションファイルに以下のオプションを追加してください。

options   IPSEC        #IP security
device    crypto

IPsec のデバッグサポートが必要であれば、 以下のカーネルオプションを追加してください。

options   IPSEC_DEBUG  #debug for IP security

14.9.2. 問題点

VPN の構成についての標準はありません。 VPN は、数多くの技術と共に実装することが可能です。 その各技術には、それ自身の長所と短所があります。 この章では、シナリオを示し、 そのシナリオに対して、VPN を実装する戦略について説明します。

14.9.3. シナリオ: 家庭と会社の 2 つのネットワークが共にインターネットに接続されています。 この 2 つのネットワークを、VPN によって 1 つのネットワークのように扱えるようにします。

前提は以下の通りです。

  • 少なくとも 2 つのサイトを持っています。

  • どちらのサイトとも内部で IP を使っています。

  • 2 つのサイトは、FreeBSD で運用されているゲートウェイを通して、 インターネットに接続しています。

  • それぞれのネットワークのゲートウェイは、 少なくとも一つのパブリック IP アドレスを持っています。

  • 2 つのネットワークの内部アドレスは、 パブリックでもプライベート IP アドレスでも構いません。 IP アドレスは衝突してはいけません。たとえば、両方のネットワークが 192.168.1.x を使ってはいけません。

14.9.4. FreeBSD 上で IPsec を設定する。

寄稿: Rhodes Tom [FAMILY Given].

最初に Ports Collection から security/ipsec-tools をインストールしてください。 このサードパーティ製ソフトウェア packages は、 設定をサポートする数多くのアプリケーションを提供します。

次に、パケットをトンネリングし、 両方のネットワークが適切に通信するように、 2 つの gif(4) 疑似デバイスを作成します。 root 権限で以下のコマンドを実行してください。 ただし、実行する際には、以下のコマンドの中の internal および external を、 実際の内部および外部のゲートウェイのアドレスに置き換えてください。

# ifconfig gif0 create
# ifconfig gif0 internal1 internal2
# ifconfig gif0 tunnel external1 external2

たとえば、会社の LAN の公開 IP アドレスを 172.16.5.4、 プライベート IP アドレスを 10.246.38.1 とします。また家庭 LAN の公開 IP アドレスを 192.168.1.12、 内部のプライベート IP アドレスを 10.0.0.5 とします。

この説明では分かりにくいので、以下の ifconfig(8) コマンドの出力例をご覧ください。

Gateway 1:
gif0: flags=8051 mtu 1280
tunnel inet 172.16.5.4 --> 192.168.1.12
inet6 fe80::2e0:81ff:fe02:5881%gif0 prefixlen 64 scopeid 0x6
inet 10.246.38.1 --> 10.0.0.5 netmask 0xffffff00

Gateway 2:

gif0: flags=8051 mtu 1280
tunnel inet 192.168.1.12 --> 172.16.5.4
inet 10.0.0.5 --> 10.246.38.1 netmask 0xffffff00
inet6 fe80::250:bfff:fe3a:c1f%gif0 prefixlen 64 scopeid 0x4

設定が完了したら、両方のプライベート IP は、 以下の出力のように ping(8) コマンドで到達できるようになっているはずです。

priv-net# ping 10.0.0.5
PING 10.0.0.5 (10.0.0.5): 56 data bytes
64 bytes from 10.0.0.5: icmp_seq=0 ttl=64 time=42.786 ms
64 bytes from 10.0.0.5: icmp_seq=1 ttl=64 time=19.255 ms
64 bytes from 10.0.0.5: icmp_seq=2 ttl=64 time=20.440 ms
64 bytes from 10.0.0.5: icmp_seq=3 ttl=64 time=21.036 ms
--- 10.0.0.5 ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max/stddev = 19.255/25.879/42.786/9.782 ms

corp-net# ping 10.246.38.1
PING 10.246.38.1 (10.246.38.1): 56 data bytes
64 bytes from 10.246.38.1: icmp_seq=0 ttl=64 time=28.106 ms
64 bytes from 10.246.38.1: icmp_seq=1 ttl=64 time=42.917 ms
64 bytes from 10.246.38.1: icmp_seq=2 ttl=64 time=127.525 ms
64 bytes from 10.246.38.1: icmp_seq=3 ttl=64 time=119.896 ms
64 bytes from 10.246.38.1: icmp_seq=4 ttl=64 time=154.524 ms
--- 10.246.38.1 ping statistics ---
5 packets transmitted, 5 packets received, 0% packet loss
round-trip min/avg/max/stddev = 28.106/94.594/154.524/49.814 ms

予想通り、プライベートアドレスを使って、 両方のネットワークから ICMP パケットを送受信できます。 次に、どちらのネットワークからもメッセージを送信できるように、 パケットのルーティング情報を 両方のゲートウェイに設定する必要があります。 これは以下のコマンドで設定できます。

# corp-net# route add 10.0.0.0 10.0.0.5 255.255.255.0
# corp-net# route add net 10.0.0.0: gateway 10.0.0.5
# priv-net# route add 10.246.38.0 10.246.38.1 255.255.255.0
# priv-net# route add host 10.246.38.0: gateway 10.246.38.1

これで、ネットワーク内のコンピュータは、 ゲートウェイおよびゲートウェイの奥のコンピュータから到達可能となっています。 以下の例で、簡単に確認できます。

corp-net# ping 10.0.0.8
PING 10.0.0.8 (10.0.0.8): 56 data bytes
64 bytes from 10.0.0.8: icmp_seq=0 ttl=63 time=92.391 ms
64 bytes from 10.0.0.8: icmp_seq=1 ttl=63 time=21.870 ms
64 bytes from 10.0.0.8: icmp_seq=2 ttl=63 time=198.022 ms
64 bytes from 10.0.0.8: icmp_seq=3 ttl=63 time=22.241 ms
64 bytes from 10.0.0.8: icmp_seq=4 ttl=63 time=174.705 ms
--- 10.0.0.8 ping statistics ---
5 packets transmitted, 5 packets received, 0% packet loss
round-trip min/avg/max/stddev = 21.870/101.846/198.022/74.001 ms

priv-net# ping 10.246.38.107
PING 10.246.38.1 (10.246.38.107): 56 data bytes
64 bytes from 10.246.38.107: icmp_seq=0 ttl=64 time=53.491 ms
64 bytes from 10.246.38.107: icmp_seq=1 ttl=64 time=23.395 ms
64 bytes from 10.246.38.107: icmp_seq=2 ttl=64 time=23.865 ms
64 bytes from 10.246.38.107: icmp_seq=3 ttl=64 time=21.145 ms
64 bytes from 10.246.38.107: icmp_seq=4 ttl=64 time=36.708 ms
--- 10.246.38.107 ping statistics ---
5 packets transmitted, 5 packets received, 0% packet loss
round-trip min/avg/max/stddev = 21.145/31.721/53.491/12.179 ms

トンネリングの設定は以上のように簡単ですが、 リンクを安全にするには、もう少し掘り下げた設定が必要となります。 以下の設定では、事前共有 (PSK) RSA 鍵を使います。 IP アドレスを除けば、両方の /usr/local/etc/racoon/racoon.conf ファイルは同じで、以下のようになります。

path    pre_shared_key  "/usr/local/etc/racoon/psk.txt"; #location of pre-shared key file
log     debug;	#log verbosity setting: set to 'notify' when testing and debugging is complete

padding	# options are not to be changed
{
        maximum_length  20;
        randomize       off;
        strict_check    off;
        exclusive_tail  off;
}

timer	# timing options. change as needed
{
        counter         5;
        interval        20 sec;
        persend         1;
#       natt_keepalive  15 sec;
        phase1          30 sec;
        phase2          15 sec;
}

listen	# address [port] that racoon will listening on
{
        isakmp          172.16.5.4 [500];
        isakmp_natt     172.16.5.4 [4500];
}

remote  192.168.1.12 [500]
{
        exchange_mode   main,aggressive;
        doi             ipsec_doi;
        situation       identity_only;
        my_identifier   address 172.16.5.4;
        peers_identifier        address 192.168.1.12;
        lifetime        time 8 hour;
        passive         off;
        proposal_check  obey;
#       nat_traversal   off;
        generate_policy off;

                        proposal {
                                encryption_algorithm    blowfish;
                                hash_algorithm          md5;
                                authentication_method   pre_shared_key;
                                lifetime time           30 sec;
                                dh_group                1;
                        }
}

sainfo  (address 10.246.38.0/24 any address 10.0.0.0/24 any)	# address $network/$netmask $type address $network/$netmask $type ( $type being any or esp)
{								# $network must be the two internal networks you are joining.
        pfs_group       1;
        lifetime        time    36000 sec;
        encryption_algorithm    blowfish,3des,des;
        authentication_algorithm        hmac_md5,hmac_sha1;
        compression_algorithm   deflate;
}

上の例で表示されているオプションや、 すべてのオプションについて説明することは、本文書の範囲を超えています。 racoon の設定マニュアルページには、 関連するたくさんの情報が書かれています。

FreeBSD および racoon がホスト間のネットワークトラフィックを暗号化、 復号化できるようにするには、 SPD ポリシの設定が必要です。

このポリシは、 以下のような簡単なシェルスクリプトで設定できます。 以下は会社のゲートウェイの例です。 このファイルをシステムの初期化中に使われるようにするには、 /usr/local/etc/racoon/setkey.conf に保存する必要があります。

flush;
spdflush;
# To the home network
spdadd 10.246.38.0/24 10.0.0.0/24 any -P out ipsec esp/tunnel/172.16.5.4-192.168.1.12/use;
spdadd 10.0.0.0/24 10.246.38.0/24 any -P in ipsec esp/tunnel/192.168.1.12-172.16.5.4/use;

設定ファイルを適切に置くと、以下のコマンドにより、 両方のゲートウェイ上で racoon を起動できます。

# /usr/local/sbin/racoon -F -f /usr/local/etc/racoon/racoon.conf -l /var/log/racoon.log

出力は以下のようになるでしょう。

corp-net# /usr/local/sbin/racoon -F -f /usr/local/etc/racoon/racoon.conf
Foreground mode.
2006-01-30 01:35:47: INFO: begin Identity Protection mode.
2006-01-30 01:35:48: INFO: received Vendor ID: KAME/racoon
2006-01-30 01:35:55: INFO: received Vendor ID: KAME/racoon
n2006-01-30 01:36:04: INFO: ISAKMP-SA established 172.16.5.4[500]-192.168.1.12[500] spi:623b9b3bd2492452:7deab82d54ff704a
2006-01-30 01:36:05: INFO: initiate new phase 2 negotiation: 172.16.5.4[0]192.168.1.12[0]
2006-01-30 01:36:09: INFO: IPsec-SA established: ESP/Tunnel 192.168.1.12[0]->172.16.5.4[0] spi=28496098(0x1b2d0e2)
2006-01-30 01:36:09: INFO: IPsec-SA established: ESP/Tunnel 172.16.5.4[0]->192.168.1.12[0] spi=47784998(0x2d92426)
2006-01-30 01:36:13: INFO: respond new phase 2 negotiation: 172.16.5.4[0]192.168.1.12[0]
2006-01-30 01:36:18: INFO: IPsec-SA established: ESP/Tunnel 192.168.1.12[0]->172.16.5.4[0] spi=124397467(0x76a279b)
2006-01-30 01:36:18: INFO: IPsec-SA established: ESP/Tunnel 172.16.5.4[0]->192.168.1.12[0] spi=175852902(0xa7b4d66)

トンネリングが適切に行われているかどうかを確認するため、 別のコンソール上で tcpdump(1) を使い、 以下のようなコマンドでネットワークの通信を確認してください。 ただし、以下の例の em0 の部分は、 必要に応じて使用しているネットワークインタフェースに置き換えてください。

# tcpdump -i em0 host 172.16.5.4 and dst 192.168.1.12

以下のようなデータがコンソールに表示されます。 もし、表示されない場合は、設定に何か問題があるので、 表示されるデータを使ってデバッグする必要があります。

01:47:32.021683 IP corporatenetwork.com > 192.168.1.12.privatenetwork.com: ESP(spi=0x02acbf9f,seq=0xa)
01:47:33.022442 IP corporatenetwork.com > 192.168.1.12.privatenetwork.com: ESP(spi=0x02acbf9f,seq=0xb)
01:47:34.024218 IP corporatenetwork.com > 192.168.1.12.privatenetwork.com: ESP(spi=0x02acbf9f,seq=0xc)

これで 2 つのネットワークは、 1 つのネットワークのように利用できます。 多くの場合、 両方のネットワークはファイアウォールにより保護されているので、 両方を流れる通信を許可するには、 パケットが両方を行き来できるようにルールを追加する必要があります。 ipfw(8) を使ったファイアウォールの場合は、 ファイアウォールの設定ファイルに、以下の行を追加してください。

ipfw add 00201 allow log esp from any to any
ipfw add 00202 allow log ah from any to any
ipfw add 00203 allow log ipencap from any to any
ipfw add 00204 allow log udp from any 500 to any

注記:

ルール番号は、 現在のホストの設定によっては変更する必要があるでしょう。

pf(4) または ipf(8) を使用しているシステムでは、 以下のルールで上手くいくでしょう。

pass in quick proto esp from any to any
pass in quick proto ah from any to any
pass in quick proto ipencap from any to any
pass in quick proto udp from any port = 500 to any port = 500
pass in quick on gif0 from any to any
pass out quick proto esp from any to any
pass out quick proto ah from any to any
pass out quick proto ipencap from any to any
pass out quick proto udp from any port = 500 to any port = 500
pass out quick on gif0 from any to any

最後に、システムの初期化中に VPN が起動するように、以下の行を /etc/rc.conf に追加してください。

ipsec_enable="YES"
ipsec_program="/usr/local/sbin/setkey"
ipsec_file="/usr/local/etc/racoon/setkey.conf" # allows setting up spd policies on boot
racoon_enable="yes"

本文書、および他の文書は ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/ からダウンロードできます。

FreeBSD に関する質問がある場合には、 ドキュメント を読んだ上で <questions@FreeBSD.org> まで (英語で) 連絡してください。

本文書に関する質問については、 <doc@FreeBSD.org> まで電子メールを (英語で) 送ってください。