14.9. VPN over IPsec

執筆: Clayton Nik [FAMILY Given].

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

14.9.1. IPsec を理解する

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

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

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

注記:

FreeBSD 5.X では hardware accelerated IPsec スタックが追加されました。 これは、Fast IPsec として知られているもので、 OpenBSD から移植されました。 IPsec のパフォーマンスを最適化するために、(利用できる場合には) crypto(4) サブシステムを経由して、 暗号ハードウェアを使用します。 このサブシステムは新しいので、まだ IPsec の KAME 版で利用可能な機能のすべてに対応しているわけではありません。 しかしながら、hardware-accelerated IPsec を有効にするためには、 カーネルコンフィグレーションファイルに以下のカーネルオプションを追加する必要があります。

options	  FAST_IPSEC  # new IPsec (cannot define w/ IPSEC)
        

現在の時点では、Fast IPsec サブシステムを IPsec の KAME 実装のかわりに使うことはできません。 より多くの情報については、fast_ipsec(4) を参照してください。

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
options   IPSEC_ESP    #IP security (crypto; define w/ IPSEC)
      

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

options   IPSEC_DEBUG  #debug for IP security
      

14.9.2. 問題点

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

14.9.3. シナリオ #1: インターネットに接続している 2 つのネットワークが 1 つのネットワークとして振る舞う

これは、私が最初に VPN を調べ始める原因となったシナリオです。 前提は以下の通りです。

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

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

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

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

  • 2 つのネットワークの内部アドレスは、 パブリックでもプライベート IP アドレスでも構いません。 必要であれば、ゲートウェイコンピュータで NAT を走らせることもできます。

  • 2 つのネットワークの内部 IP アドレスは、 衝突してはいけません。 VPN 技術と NAT を用いることで、理論的には、 そのようなことは可能と考えますが、 その設定は悪夢でしょう。

2 つのネットワークに接続を試みた際に、 両方のネットワークで同じ範囲の内部 IP アドレスが使われていることに気づいたら (たとえば、両方で 192.168.1.x を使用している場合)、 どちらかの番号を振りなおす必要があります。

VPN の文書では、同じ ASCII アートを使うことがルールになっているので、 この文書でも例外ではなく同様にアスキーアートを用います。

ネットワークのトポロジは以下のようになります。

Network #1            [ Internal Hosts ]    Private Net, 192.168.1.2-254
                      [   Win9x/NT/2K  ]
                      [      UNIX      ]
                               |
                               |
                        .---[fxp1]---.      Private IP, 192.168.1.1
                        |   FreeBSD  |
                        `---[fxp0]---'      Public IP, A.B.C.D
                               |
                               |
                      -=-=- Internet -=-=-
                               |
                               |
                        .---[fxp0]---.      Public IP, W.X.Y.Z
                        |   FreeBSD  |
                        `---[fxp1]---'      Private IP, 192.168.2.1
                               |
                               |
Network #2            [ Internal Hosts ]
                      [   Win9x/NT/2K  ]    Private Net, 192.168.2.2-254
                      [      UNIX      ]
      

ふたつのパブリック IP アドレスに注目してください。 この文書では、これらの IP アドレスを参照する際には、 これらの文字を用います。 この文書の中で、これらの文字を見たら、 あなた自身のパブリック IP アドレスに置き換えてください。 内部では、2 つのゲートウェイコンピュータは、両方とも .1 IP アドレスを持っています。そして、2 つのネットワークは、 異なるプライベート IP アドレスを使っています (それぞれ 192.168.1.x および 192.168.2.x)。 プライベートネットワークにあるすべてのコンピュータは、 デフォルトゲートウェイとして、 .1 コンピュータを使うように設定されています。

意図していることは、ネットワークの観点から、 各ネットワークは他のネットワークにあるコンピュータを、 (時折パケットをドロップするようなややゆっくりなルータではありますが) 同じルータに直接接続しているようにすることです。

これは、たとえば、192.168.1.20 というコンピュータは、 以下を実行できるということです。

ping 192.168.2.34

透過的にこれは動くはずです。 Windows® コンピュータは、他のネットワークのコンピュータを、 ローカルネットワークのコンピュータを見るのとまったく同じように、 見ることができ、共有ファイルを見たりできます。

すべてのことが安全に行われなければなりません。 これは、2 つのネットワークの通信が暗号化されていなければならないことを意味しています。

これらの 2 つのネットワーク間に VPN を構築するには複数のプロセスが必要となります。 各ステージは以下のようになります。

  1. 2 つのネットワーク間にインターネットを経由して、 virtual ネットワークのリンクを作成します。 それが適切に動いていることを ping(8) のようなツールを使って、試験を行います。

  2. 2 つのネットワーク間で、 必要に応じて透過的に暗号化、 復号化を保証するようにセキュリティポリシを適用します。 tcpdump(1) のようなツールを使って、 通信が暗号化されていることを確認します。

  3. FreeBSD ゲートウェイにて、Windows® のコンピュータが VPN を通して他のコンピュータを見ることができるように追加のソフトウェアを設定します。

14.9.3.1. ステップ 1: virtual ネットワークリンクの作成

ネットワーク #1 のゲートウェイコンピュータにログインしているとします。 このコンピュータのパブリック IP アドレスは A.B.C.D、 プライベート IP アドレスは 192.168.1.1 です。 W.X.Y.Z の IP アドレスのコンピュータのプライベートアドレスに対し ping 192.168.2.1 を実行したとします。 このコマンドが成功するには何が必要でしょうか?

  1. ゲートウェイコンピュータは、どのように 192.168.2.1 に達するかを知っていなければなりません。 言い換えると、 192.168.2.1 への経路を知っている必要があります。

  2. 192.168.x のような範囲のプライベート IP アドレスは広いインターネットでは、 使われることは想定されていません。 そのかわり、 192.168.2.1 に送信した各パケットは、他のパケットに包れている必要があります。 このパケットは A.B.C.D から、 W.X.Y.Z へと送られる必要があります。 このプロセスは、 カプセル化 と呼ばれます。

  3. このパケットが W.X.Y.Z に届くと、 非カプセル化 され、 192.168.2.1 に送信されます。

これは、2 つのネットワーク間で、 tunnel が必要ということを示しています。二つの トンネルマウス は、 IP アドレス A.B.C.DW.X.Y.Z です。 そして、トンネルは、これをパススルーすることを許容するプライベート IP アドレスのアドレスが指定されている必要があります。 トンネルは、パブリックインターネットを経由して、 プライベート IP アドレスで送信する時に使われます。

このトンネルは、一般的なインタフェースもしくは、FreeBSD では gif デバイスで作成されます。 想像通り、各ゲートウェイホストの gif インタフェースは、4 つの IP アドレスで設定されなくてはなりません。 2 つはパブリック IP アドレスで、 2 つはプライベートの IP アドレスです。

両方の FreeBSD カーネルで gif デバイスのサポートを組み入れてコンパイルする必要があります。 以下の行を加えることで設定できます。

pseudo-device gif

両方のコンピュータのカーネルコンフィグレーションファイルに上記の行を加え、 コンパイル、インストールし、通常通り再起動してください。

トンネルの設定は 2 つのプロセスで行います。 最初は、gifconfig(8) を使って、 外部 (パブリック) IP アドレスを設定するします。 その後、プライベート IP アドレスを ifconfig(8) を使って設定します。

ネットワーク #1 にあるゲートウェイコンピュータで以下の 2 つのコマンドを実行してトンネルを作成します。

gifconfig gif0 A.B.C.D W.X.Y.Z
ifconfig gif0 inet 192.168.1.1 192.168.2.1 netmask 0xffffffff
      

もう片方のゲートウェイコンピュータで、 IP アドレスの順を逆にして同じコマンドを実行します。

gifconfig gif0 W.X.Y.Z A.B.C.D
ifconfig gif0 inet 192.168.2.1 192.168.1.1 netmask 0xffffffff
      

以下を実行して、設定を確認をしてください。

gifconfig gif0

たとえば、ネットワーク #1 のゲートウェイにおいては、 以下のように確認できます。

# gifconfig gif0
gif0: flags=8011<UP,POINTTOPOINT,MULTICAST> mtu 1280
inet 192.168.1.1 --> 192.168.2.1 netmask 0xffffffff
physical address inet A.B.C.D --> W.X.Y.Z
      

出力からわかるように、 物理アドレス A.B.C.DW.X.Y.Z の間にトンネルが作成され、 192.168.1.1192.168.2.1 の間の通信がトンネルで許可されています。

両方のコンピュータのルーティングテーブルにエントリが追加されました。 netstat -rn で確認できます。 ネットワーク #1 のゲートウェイホストでの出力は以下のようになります。

# netstat -rn
Routing tables
 
Internet:
Destination      Gateway       Flags    Refs    Use    Netif  Expire
...
192.168.2.1      192.168.1.1   UH        0        0    gif0
...
      

Flags の値が示すように、 これはホストのルートで、 各ゲートウェイは他のゲートウェイとどのように通信すれば良いかを知っていますが、 他の関連するネットワークへの通信を知らないことを意味しています。 この問題は、すぐに解決されます。

両方のコンピュータでファイアウォールを設定していることがあります。 VPN トラフィックのためには、ファイアウォールを迂回する必要があります。 両方のネットワーク間のすべてのトラフィックを許可するか、VPN の末端をお互い保護するようなファイアウォールのルールを追加したいと思うでしょう。

すべての VPN を経由するトラフィックを許容するようなファイアウォールを設定すると、 テストを大きく簡略化できます。 後でいつでも、セキュリティを強化できます。 もし、ゲートウェイコンピュータで ipfw(8) を用いているのであれば、 以下のようなコマンドで、 他のファイアウォールのルールに影響することなく、 VPN の末端の間のトラフィックを許可します。

ipfw add 1 allow ip from any to any via gif0

両方のゲートウェイコンピュータでこのコマンドを実行する必要があります。

各ゲートウェイコンピュータで他のゲートウェイコンピュータに対して、 ping を実行することができれば十分です。 192.168.1.1 において、以下を実行が可能で

ping 192.168.2.1

そして、レスポンスを受け取れる必要があります。 同じことを他のゲートウェイコンピュータで実行できる必要があります。

しかしながら、各ネットワークの内部のコンピュータにアクセスはまだできません。 これは、 ゲートウェイコンピュータがお互いにアクセスする方法を知っているが、 各ゲートウェイの奥にあるネットワークにアクセスする方法を知らないという、 ルーティングに起因しています。

この問題を解決するには、 静的ルートを各ゲートウェイコンピュータに追加する必要があります。 このために最初のゲートウェイで行うコマンドは以下のようになります。

route add 192.168.2.0 192.168.2.1 netmask 0xffffff00
      

このコマンドの意味は、ネットワーク 192.168.2.0 のホストにアクセスするには、パケットを 192.168.2.1 のホストに送る ことを意味しています。 もう片方のゲートウェイでは、同様のコマンドを実行する必要があります。 その場合には、かわりに、 192.168.1.x アドレスを使う必要があります。

これで、片方のネットワーク上のホストからの IP トラフィックは、 もう片方のネットワーク上のホストに届くようになります。

2 つのネットワーク間の virtual および network について構築できたので、 VPN について、2/3 が構築されました。残りは private です。 ping(8) および tcpdump(1) を使って試験できます。 ゲートウェイホストにログインして以下を実行してください。

tcpdump dst host 192.168.2.1

同じホストの他のログインセッションで、 以下を実行してください。

ping 192.168.2.1

以下のような出力が表示されます。

16:10:24.018080 192.168.1.1 > 192.168.2.1: icmp: echo request
16:10:24.018109 192.168.1.1 > 192.168.2.1: icmp: echo reply
16:10:25.018814 192.168.1.1 > 192.168.2.1: icmp: echo request
16:10:25.018847 192.168.1.1 > 192.168.2.1: icmp: echo reply
16:10:26.028896 192.168.1.1 > 192.168.2.1: icmp: echo request
16:10:26.029112 192.168.1.1 > 192.168.2.1: icmp: echo reply
      

この出力からわかるように、ICMP メッセージが戻り、 復号化されます。 tcpdump(1)-s パラメータを用いると、 パケットから多くのデータを捕え、 より多くの情報を得ることができます。

明らかにこれは、受け入れられるものではありません。 次の節では、2 つのネットワーク間のリンクについて、 すべての通信が自動的に暗号化されるように安全にする方法について説明します。

まとめ
  • 両方のカーネルを pseudo-device gif で構築します。

  • ゲートウェイホスト #1 の /etc/rc.conf を編集して、以下の行を (必要に応じて IP アドレスを変更して) 追加します。

    gifconfig_gif0="A.B.C.D W.X.Y.Z"
    ifconfig_gif0="inet 192.168.1.1 192.168.2.1 netmask 0xffffffff"
    static_routes="vpn"
    route_vpn="192.168.2.0 192.168.2.1 netmask 0xffffff00"
              
  • 両方のホストのファイアウォールスクリプト (/etc/rc.firewall など) を編集して以下を追加します。

    ipfw add 1 allow ip from any to any via gif0
  • 同様の変更を、ゲートウェイホスト #2 の /etc/rc.conf においても行います。 ここで、IP アドレスの順番は逆にします。

14.9.3.2. ステップ 2: リンクを安全にする。

リンクを安全にするために、IPsec を用います。 IPsec は、2 つのホストが暗号鍵に合意し、 その鍵を 2 つのホストの間でデータを暗号化するのに用いるメカニズムを提供します。

ここでは、設定を行う上で考慮すべき領域が 2 つあります。

  1. 2 つのホストで、 用いる暗号メカニズムに合意するメカニズムが必要です。 2 つのホストが一度このメカニズムに合意したら、 これらの間で セキュリティアソシエーション が確立されたことになります。

  2. どのトラフィックを暗号化するかを特定するメカニズムが必要となります。 外向きのトラフィックのすべてを暗号化する必要はないのは明らかです。 -- VPN に関係するトラフィックのみを暗号化することが望まれます。 どのトラフィックを暗号すべきかを決めるために導入されるルールを セキュリティポリシ と呼びます。

セキュリティアソシエーションおよびセキュリティポリシの両方は、 カーネルにより管理されています。そして、ユーザランドプログラムにより、 変更することができます。 しかしながら、これを行う前に、カーネルを IPsec および Encapsulated Security Payload (ESP) プロトコルに対応するように、 設定する必要があります。 これは、カーネルを以下のように設定することで可能です。

options IPSEC
options IPSEC_ESP
       

そして再構築し、再インストールを行って、再起動してください。 これは両方のゲートウェイホストのカーネルで行う必要があります。

セキュリティアソシエーションの設定に関していうと、 2 つの選択肢があります。 1 つ目は、2 つのホスト間の設定を手動で設定する方法で、 暗号アルゴリズム、暗号鍵などを選択する必要があります。 もう 1 つは、これらをあなたに代わり行う Internet Key Exchange protocol (IKE) を実装しているデーモンを用いることです。

後者が推奨されます。とにかく、設定がより簡単です。

setkey(8) を用い得ることでセキュリティポリシを設定したり、 表示できます。 route(8) がカーネルルーティングテーブルに関しているのと同様に、 setkey は、カーネルセキュリティポリシテーブルに関連しています。 setkey は、 現在のセキュリティアソシエーションも表示でき、 類推をさらに進めると、その点において、 netstat -r と同種です。

FreeBSD でセキュリティアソシエーションを管理するデーモンは数多くあります。 この文書では、その中の一つの racoon の使い方について説明します。 racoom は、FreeBSD Ports Collection の security カテゴリにあります。 通常の方法でインストールができます。

racoon は、両方のゲートウェイホストで実行される必要があります。 それぞれのホストで、もう一つの VPN の端の IP アドレスおよび (あなたが選択したもので、両方のゲートウェイで同じ必要のある) 秘密鍵で設定する必要があります。

2 つのデーモンは、互いにコンタクトし、 (設定した秘密鍵を用いて) だれが相手であるかを確認します。 デーモンはその後、新しい秘密鍵を生成し、 VPN 上のトラフィックの暗号化のために用います。 攻撃者がこれらの鍵の (理論的には、不可能ですが) 1 つをクラックしても、それ以上できないように、 この秘密鍵を定期的に変更します。 -- 彼らがカギをクラックしたときには、 2 つのデーモンは他の鍵を選択していることでしょう。

racoon's の設定は、 ${PREFIX}/etc/racoon で行われます。 ここには、設定ファイルが置かれていますが、 それほど多く変更する必要はありません。 おそらくあなたが変更すべき racoon の設定の他の部分は、 pre-shared key です。

デフォルトの racoon の設定では、これは、 ${PREFIX}/etc/racoon/psk.txt ファイルにあると仮定されています。 pre-shared key は、VPN リンクを経由するトラフィックの暗号化には、 用いられません。 鍵管理デーモンがお互いを信頼するためのトークンです。

psk.txt は、 あなたが取り扱う各リモートのサイトに関連する行を含んでいます。 この例では、どこに 2 つのサイトがあるのか、 各 psk.txt ファイルは、一行を含んでいます (なぜならば、各 VPN の端は、他の端のみを取り扱うため)。

ゲートウェイホストの #1 では、 この行は以下のようなものです。

W.X.Y.Z            secret

これは、リモート端の 公開 IP アドレス、空白、 安全を提供するためのテキスト文字です。 明らかに、secret をあなたの鍵に使うべきではありません。 パスワードに対する通常の規則に従ってください。

ゲートウェイホスト #2 では、この行は以下のようになります。

A.B.C.D            secret

これは、リモート端の公開 IP アドレスと先ほどと同じ秘密鍵です。 racoon を実行する前に psk.txt のモードは、 0600 (i.e., root のみが read/write できます) としてください。

両方のホストゲートウェイコンピュータで racoon を走らせる必要があります。IKE トラフィックを許可するファイアウォールルールを追加する必要があります。 IKE トラフィックは、UDP 上で ISAKMP (Internet Security Association Key Management Protocol) port に対して実行されるものです。 このルールはファイアウォールルールセットの極めて最初に記述する必要があります。

ipfw add 1 allow udp from A.B.C.D to W.X.Y.Z isakmp
ipfw add 1 allow udp from W.X.Y.Z to A.B.C.D isakmp
      

一度 racoon を走らせたら、 片方のゲートウェイホストから、他のホストへ ping を実行できます。 接続は、まだ暗号化されていませんが、racoon はその後 2 つのホスト間のセキュリティアソシエーションを設定します。 これは時間を要し、 ping コマンドが反応する前に少し時間の遅れとして認識できるでしょう。

一度セキュリティアソシエーションが確立されたら、 setkey(8) を使って確認できます。 どちらかのホストで以下のように実行して、 セキュリティアソシエーション情報を確認してください。

setkey -D

以上で問題の半分が終わりました。 もう半分は、セキュリティポリシの設定です。

適切なセキュリティポリシを作成するには、 これまでにどのように設定されているかを確認することが必要となります。 この議論は、両方のリンクの端で行われます。

送信された各 IP パケットには、ヘッダがあり、 パケットに関するデータを持っています。 ヘッダにはソースおよびデスティネーションの両方の IP アドレスが含まれています。 我々はすでに知っているように、公開インターネット上では、 192.168.x.y といった範囲のプライベート IP アドレスは使われません。 そのかわり、最初に他のパケット内にカプセル化されます。 このパケットは、プライベートアドレスのかわりに、 公開ソースおよびデスティネーションの IP アドレスを持っています。

そのため、外向きのパケットは以下のように始まります。

  .----------------------.
  | Src: 192.168.1.1     |
  | Dst: 192.168.2.1     |
  | <other header info>  |
  +----------------------+
  | <packet data>        |
  `----------------------'

その後、他のパケットの中に以下のようにカプセル化されます。

  .--------------------------.
  | Src: A.B.C.D             |
  | Dst: W.X.Y.Z             |
  | <other header info>      |
  +--------------------------+
  | .----------------------. |
  | | Src: 192.168.1.1     | |
  | | Dst: 192.168.2.1     | |
  | | <other header info>  | |
  | +----------------------+ |
  | | <packet data>        | |
  | `----------------------' |
  `--------------------------'

このカプセル化は gif デバイスにより行われます。確認できるように、 パケットは外側に本来の IP アドレスを持っており、 オリジナルパケットは、 インターネットに外向きに送られるパケットの中にデータとしてラップされています。

明らかに、VPN 間のすべてのトラフィックが暗号化されることが必要となります。 言葉にすると以下のようになります。

もしパケットが A.B.C.D から、 W.X.Y.Z へと送られるとすると、 必要なセキュリティアソシエーションを使って暗号化されます。

もしパケットが、 W.X.Y.Z から届き、 A.B.C.D へと送られる場合には、 必要なセキュリティアソシエーションを用いて復号化されます。

これは正解に近いのですが、極めて正しいというわけではありません。 もしこれを行ったとすると、 W.X.Y.Z へのトラフィック、または、ここからのトラフィックのすべてが、 VPN ではないトラックまで暗号化されてしまいます。 これはあなたが行いたいこととはまったく違います。 適切なポリシは以下のようなものになります。

A.B.C.D からパケットが出たとして、 そのパケットが他のパケットをカプセル化し、 W.X.Y.Z へと送られるとすると、 セキュリティアソシエーションを用いて暗号化します。

もし、パケットが、W.X.Y.Z から届き、 そのパケットが他のパケットをカプセル化し、A.B.C.D へと送られる場合には、 必要なセキュリティアソシエーションを使って復号化されます。

微妙な変更ですが、必要な変更です。

セキュリティポリシは、同じく setkey(8) を用いることで設定します。 setkey(8) は、ポリシを定義する設定言語の機能を持ちます。 stdin を使って設定の指示を行うか、設定の指示を含むファイル名を -f に指定して使用します。

W.X.Y.Z 向けへのすべてのトラフィックを暗号化するには、 ゲートウェイホスト #1 (パブリック IP アドレス A.B.C.D) の設定は以下のようにしてください。

spdadd A.B.C.D/32 W.X.Y.Z/32 ipencap -P out ipsec esp/tunnel/A.B.C.D-W.X.Y.Z/require;
       

これらのコマンドをファイル (たとえば /etc/ipsec.conf) に追加し、 以下を実行してください。

# setkey -f /etc/ipsec.conf

spdadd は、setkey(8) に対し、 安全なポリシのデータベースにルールを追加することを伝えます。 この行の残りでは、どのパケットがこのポリシに一致するかを特定します。 A.B.C.D/32 および W.X.Y.Z/32 は、 このポリシを適応したいネットワークを特定するための IP アドレスとネットマスクです。 このケースでは、これらの 2 つのホスト間の通信に適応したいという例です。 ipencap は、カーネルに対して、このポリシは、 他のパケットをカプセル化しているパケットのみに適応することを伝えます。 -P out は、このポリシを外向きのパケットに適応し、 ipsec により、 パケットが安全であることを伝えます。

2 行目は、パケットをどのように暗号化するかを指定します。 esp は使用するプロトコルで、 tunnel は、IPsec パケットにおいてさらにカプセル化されることを指定します。 A.B.C.D および W.X.Y.Z は、 使用するセキュリティアソシエーションを選択するのに用います。 最後の require は、このルールにマッチした場合に、 パケットを暗号化することを指定します。

このルールは、外向きのパケットのみにマッチします。 同様のルールが内向きのパケットに対して必要です。

spdadd W.X.Y.Z/32 A.B.C.D/32 ipencap -P in ipsec esp/tunnel/W.X.Y.Z-A.B.C.D/require;

このケースでは、out のかわりに in、そして IP アドレスを逆にすることが必要です。

(IP アドレス W.X.Y.Z の) 他のゲートウェイホストにも同じルールが必要です。

spdadd W.X.Y.Z/32 A.B.C.D/32 ipencap -P out ipsec esp/tunnel/W.X.Y.Z-A.B.C.D/require;
       spdadd A.B.C.D/32 W.X.Y.Z/32 ipencap -P in ipsec esp/tunnel/A.B.C.D-W.X.Y.Z/require;

最後に、ファイアウォールに ESP および IPENCAP パケットが行き来することを許可するルールを追加する必要があります。 これらのルールは、 それぞれのホストに追加する必要があります。

ipfw add 1 allow esp from A.B.C.D to W.X.Y.Z
ipfw add 1 allow esp from W.X.Y.Z to A.B.C.D
ipfw add 1 allow ipencap from A.B.C.D to W.X.Y.Z
ipfw add 1 allow ipencap from W.X.Y.Z to A.B.C.D
       

ルールは対称なので、 それぞれのゲートウェイホストに同じルールを利用できます。

外向きのパケットは、以下のようになります。

  .------------------------------.  --------------------------.
  | Src: A.B.C.D                 |                            |
  | Dst: W.X.Y.Z                 |                            |
  | <other header info>          |                            |  Encrypted
  +------------------------------+                            |  packet.
  | .--------------------------. |  -------------.            |  contents
  | | Src: A.B.C.D             | |               |            |  are
  | | Dst: W.X.Y.Z             | |               |            |  completely
  | | <other header info>      | |               |            |- secure
  | +--------------------------+ |               |  Encap'd   |  from third
  | | .----------------------. | |  -.           |  packet    |  party
  | | | Src: 192.168.1.1     | | |   |  Original |- with real |  snooping
  | | | Dst: 192.168.2.1     | | |   |  packet,  |  IP addr   |
  | | | <other header info>  | | |   |- private  |            |
  | | +----------------------+ | |   |  IP addr  |            |
  | | | <packet data>        | | |   |           |            |
  | | `----------------------' | |  -'           |            |
  | `--------------------------' |  -------------'            |
  `------------------------------'  --------------------------'
       

VPN の端から受け取った場合には、 (racoon によりネゴシエートされたセキュリティアソシエーションを用いて) 最初に復号化を行います。 その後、gif インタフェースに入ります。 このインタフェースは、内部のネットワークを回ることのできる最も内側のパケットになるまで、セカンドレイヤのラップをはがします。

先ほどと同じく ping(8) 試験でセキュリティを確認できます。 最初に、A.B.C.D ゲートウェイコンピュータにログインして、 以下を実行してください。

tcpdump dst host 192.168.2.1

同じホストの別のログインセッションで以下を実行してください。

ping 192.168.2.1

今回は、以下のような出力が表示されます。

XXX tcpdump output

tcpdump(1) は、ESP パケットを表示します。 -s オプションを使って実行すると、 暗号化のため、見ても理解できないものが表示されるでしょう。

おめでとうございます。 これで 2 つのリモートサイト間の VPN を設定できました。

まとめ
  • 以下のオプションでカーネルを再構築します。

    options IPSEC
    options IPSEC_ESP
              
  • security/racoon をインストールします。 両方のゲートウェイホストにおいて、 ${PREFIX}/etc/racoon/psk.txt を変更して、 リモートホストの IP アドレスのエントリおよびお互いが知っている秘密鍵を追加してください。 このファイルのモードは 0600 に設定してください。

  • 各ホストにおいて以下の行を /etc/rc.conf に追加してください。

    ipsec_enable="YES"
    ipsec_file="/etc/ipsec.conf"
              
  • 各ホストにおいて /etc/ipsec.conf を作成し、必要となる spdadd 行を追加してください。 ゲートウェイホスト #1 では以下のようになります。

    spdadd A.B.C.D/32 W.X.Y.Z/32 ipencap -P out ipsec
      esp/tunnel/A.B.C.D-W.X.Y.Z/require;
    spdadd W.X.Y.Z/32 A.B.C.D/32 ipencap -P in ipsec
      esp/tunnel/W.X.Y.Z-A.B.C.D/require;
    

    ゲートウェイホスト 2 では以下のようになります。

    spdadd W.X.Y.Z/32 A.B.C.D/32 ipencap -P out ipsec
      esp/tunnel/W.X.Y.Z-A.B.C.D/require;
    spdadd A.B.C.D/32 W.X.Y.Z/32 ipencap -P in ipsec
      esp/tunnel/A.B.C.D-W.X.Y.Z/require;
    
  • 両方のホストにおいて IKE, ESP, および IPENCAP トラフィックが許可されるようにファイアウォールのルールを追加してください。

    ipfw add 1 allow udp from A.B.C.D to W.X.Y.Z isakmp
    ipfw add 1 allow udp from W.X.Y.Z to A.B.C.D isakmp
    ipfw add 1 allow esp from A.B.C.D to W.X.Y.Z
    ipfw add 1 allow esp from W.X.Y.Z to A.B.C.D
    ipfw add 1 allow ipencap from A.B.C.D to W.X.Y.Z
    ipfw add 1 allow ipencap from W.X.Y.Z to A.B.C.D
              

直前の 2 つのステップは、VPN を実行できれば十分です。 各ネットワークのコンピュータは、IP アドレスを使って他のネットワークのコンピュータを参照できますし、 すべてのリンクを横切るトラフィックは自動的にそして安全に暗号化されます。

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

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

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