Skip to main content.
Google custom search

Racoon を使ったリモートユーザーアクセス VPN の構築方法

ソフトウェアリリース

リモートユーザーアクセス VPN

IPsec を使ったユーザーリモートアクセス

VPN ゲートウェイの設定

VPN クライアント


ソフトウェアリリース

カーネル (トップ)

この文書の情報は、以下の NetBSD カーネルを対象としています。

  • 2005 年 5 月以降の NetBSD-current
  • 2005 年 5 月以降の NetBSD-3.0_BETA

ユーザーランド (トップ)

この文書の情報は、以下のユーザーランド (setkey(8), racoon(8), racoonctl(8) および libipsec) を対象としています。

  • 2005 年 5 月以降の NetBSD-current
  • 2005 年 5 月以降の NetBSD-3.0_BETA
  • これより前の NetBSD リリースに、NetBSD の pkgsrc を使って ipsec-tools 0.6.beta2 以上のパッケージを追加したもの


リモートユーザーアクセス VPN

背景となる状況 (トップ)

多くの組織では、リモートアクセスサーバー (Remote Access Server, RAS) を持っており、ユーザーが旧来の公衆電話回線 (Plain Old Telephone System, POTS) とモデム接続を使ってリモートアクセスできるようにしています。

デジタル加入者回線 (Digital Subscriber Line, DSL) やケーブル回線といった 高帯域接続の普及に伴い、POTS を使ったリモートアクセスは時代遅れとなり、 ユーザーは高帯域のリモートアクセスを求めるようになっています。 仮想プライベートネットワーク (Virtual Private Network, VPN) を使うことは、 この問題に対する解決策のひとつです。

VPN アクセス用のユーザー認証としては、いくつかの方法があります。

  • グループパスワード (ユーザー全員が同じパスワードを使う)
  • ログイン名とパスワード
  • x509 証明書

グループパスワードは劣った手法であり、使うべきではありません。 ユーザーを本当に認証しているわけではないからです。 x509 証明書は最高のセキュリティーをもたらしますが、ユーザー証明書の管理が面倒かもしれません。 それでも構わなければ、必要な情報は IPsec FAQ にすべてあります。ログイン名とパスワードは、並のセキュリティーレベルです。 パスワードは推測されたり、別のプロトコルで公開されたり (例: SSL を使わない POP3) するので、安全性は高くはありません。しかし、強いパスワードを使うようにし、 また、傍受されないようなプロトコルの使い方をしていれば、 経済的に安全を実現できます。

この HOW-TO では、リモートユーザー VPN アクセス用に ログイン名とパスワードが使われている状況を対象とします。

セキュリティー上の問題 (トップ)

安全な VPN を確立するために、リモートユーザーは VPN ゲートウェイを認証しなければならず、 また、VPN ゲートウェイはリモートユーザーを認証しなければなりません。 お互いの認証がおこなわれないと、中間者攻撃 (Man in the Middle (MiM) attack) の抜け穴が開き、攻撃者が VPN ゲートウェイになりすまして ユーザーパスワードを収集できてしまいます。

リモートユーザーがログイン名とパスワードで認証すると説明しましたが、 VPN ゲートウェイはどうやって認証するのでしょうか? 事前共有鍵を使う場合、 その鍵を知っている人なら誰でも VPN ゲートウェイになりすますことができますし、 正当なユーザーは事前共有鍵を知っておかねばならなくなります。これは非常に弱いセキュリティーです。 代替策は、VPN ゲートウェイで x509 証明書を使うことです。これはサーバー証明書であり、 ユーザー証明書より管理しやすいものです。ここでは、 VPN ゲートウェイの認証に証明書を使うものとします。

解決策 (トップ)

ここでは、ユーザーの認証にはログイン名とパスワードを使い、 VPN ゲートウェイの認証には証明書を使うことが必要です。これを実現できる手法はあまりありません。 OpenVPN は、これが実現可能な、 Secure Socket Layer (SSL) を使った解決策です。別の解決策として、 IPsec を使う方法もあり、 この HOW-TO ではこちらの方法を取り扱います。


IPsec を使ったユーザーリモートアクセス

IPsec フェーズ 1 認証 (トップ)

IPsec フェーズ 1 は、NetBSD では racoon(8) としても知られる IKE デーモンによって行なわれる、 IPsec 鍵交換 (IPsec Key Exchange, IKE) 操作の一部です。IPsec フェーズ 1 の目的は、 通信相手を認証したうえで、 IPsec フェーズ 2 を安全に行なうためのマスター鍵の設定をすることです。 フェーズ 2 の目的は、IPsec トラフィック交換に使われる鍵を得ることです。 IPsec トラフィック交換がおこなわれている間、フェーズ 2 の鍵は定期的に再生成されます。

IPsec フェーズ 1 は、二つの認証方法を提供します。事前共有鍵と、証明書です。 以下の理由により、IPsec フェーズ 1 はわれわれが求めているものではありません。

  • 事前共有鍵は、ログイン名に縛られません。グループパスワードとした場合だけは管理可能ですが、 それを除けば、事前共有鍵を適切に扱うための管理ツールがありません。
  • IPsec フェーズ 1 認証は、対称的であることが前提です。 つまり、両端ともに事前共有鍵認証を、または両端ともに証明書認証を使う、というものです。 これは、われわれが探しているものではありません。

Xauth (トップ)

Xauth は、フェーズ 1 の後に使われ、ログイン名/パスワード認証を追加する IKE 拡張です。 これは、認証にまつわる問題の半分を解決します。Xauth はフェーズ 1 の直後に使われるので、 フェーズ 1 認証により安全なものとなります。問題の半分は解決しましたが、まだ フェーズ 1 では事前共有鍵か証明書が必要です。事前共有鍵の使用は安全ではありませんし、 証明書を使うことは、ユーザー証明書を使うことを意味します。 ユーザー証明書の使用はわれわれが避けたかったことです。

Hybrid auth (トップ)

Hybrid auth はもうひとつの IKE 拡張で、フェーズ 1 を非対称にするものです。 フェーズ 1 の行なわれている間、VPN ゲートウェイは、リモートユーザーが認証をする必要がなくても、 証明書を使うことができます。フェーズ 1 が行なわれた後の状況は、以下のとおりです。

  • リモートユーザーは、通信相手が VPN ゲートウェイであることがわかっています
  • リモートユーザーと VPN ゲートウェイとの間のやりとりは安全です
  • VPN ゲートウェイは、話している相手が誰かわかっていません

このフェーズ 1 の後、リモートユーザーのセキュリティー認証のために Xauth 交換をすることができます。 その後、フェーズ 2 がおこなわれます。

IPsec + Xauth + Hybrid auth のセキュリティーの度合は、 パスワード認証を使った SSH とだいたい同じぐらいです。

ISAKMP モード設定 (トップ)

以上のとおり、認証の問題は IPsec + Xauth + Hybrid auth を使うことで解決されました。 リモートアクセスをユーザーフレンドリーなものにするために、 リモートユーザーのマシン設定を自動化する必要があります。ISAKMP モード設定は、 VPN ゲートウェイがリモートユーザーのマシンにネットワーク設定 (内部 IP アドレス、 DNS アドレス、ドメイン名など) を提供できるようにする IKE 拡張です。

NAT Traversal (トップ)

リモートユーザーは、IPsec 暗号化ストリームを使った場合には機能しない、 ネットワークアドレス変換器 (Network Address Translator, NAT) の向こうにいるかもしれません。 トラフィックを暗号化する必要があるときは、IPsec は、暗号ペイロード (Encapsulated Security Payload, ESP) というレイヤー 4 のプロトコルを使用します。TCP や UDP とは異なり、ESP はポート番号を持たず、 NAT デバイスが簡単に扱うことはできません。

RFC 3947 および 3948 では、ESP を UDP でカプセル化する方法と、 IPsec ストリームの両端の間にある NAT を管理するための IKE 拡張について解説しています。 このカプセル化の方法と IKE 拡張の組み合わせは、NAT Traversal (NAT-T) として知られています。

NAT-T は、合衆国特許の制約を受けることになるかもしれません

IKE フラグメンテーションおよび ESP フラグメンテーション (トップ)

リモートユーザーが DSL モデムルーター機器を介して接続してくるのは、よくあることでしょう。 これらのデバイスのほとんどは、大きな UDP パケットの扱いに関して、まったく用をなしません。 UDP が DNS リクエストでしか使われないという想定で作られており、それより大きな UDP パケットやフラグメントされた UDP パケットはこぼしてしまいます。 IKE トランザクションや ESP オーバー UDP は大きくなりがちなので、 ブロックされてしまいます。

この問題を処理するため、IKE パケットを小さな断片に分割 IKE 拡張である、 IKE フラグメンテーションを使います。 ESP フラグメンテーションは、大きな ESP オーバー UDP パケットの問題を、 ESP のカプセル化の前に IP フラグメンテーションをすることによって、処理します。 すなわち、ネットワークに frag(IP/UDP/ESP/IP) を送るのではなく IP/UDP/ESP/frag(IP) を送るのです。 このため、IPsec 両端点の間にはさまれたデバイスは、 いかなるフラグメントされたパケットも認識しません。

Dead Peer Detection (トップ)

最後の問題です。リモートユーザーのインターネット接続が不安定で、 あたかも接続が切れたかのようになることがあります。これに対して、 IPsec に内蔵されている仕組みは、しばらく後に IKE phase 2 鍵再生成を強制的に行なうことだけです。 その時に通信相手がオンラインでなかったら、これは失敗し、その結果 VPN トンネルは破棄されます。

この仕組みは、リモートユーザーがオフラインになったことを確認するため頻繁に鍵再生成を強制されるので、 あまり便利ではありません。Dead Peer Detection (DPD) は、リモートの IPsec 端点が生きていることを 定期的に確認するのに使われる IKE 拡張です。 DPD は、リモートホストが数秒間オフラインになったことを確認するのに使うことができます。


VPN ゲートウェイの設定

以下に、IPsec + Xauth + Hybrid auth + ISAKMP モード設定 + NAT-T + DPD + IKE フラグメンテーション + ESP フラグメンテーションを使った VPN ゲートウェイの設定例を示します。

カーネルコンフィギュレーション (トップ)

最初に、少なくとも以下のオプションを含めたカーネルを 構築してインストールする必要があります。

options INET
options GATEWAY
options PFIL_HOOKS
options IPSEC
options IPSEC_ESP
options IPSEC_NAT_T

pseudo-device   ipfilter

パケットフォワーディング (トップ)

以下のコマンドを使って、IPv4 パケットフォワーディングを有効化する必要があります。

# sysctl -w net.inet.ip.forwarding=1

/etc/sysctl.conf に以下の行を追加して、 リブート時に自動的に実行することができます。

net.inet.ip.forwarding=1

証明書の作成 (トップ)

OpenSSL の設定をまだ行なっていない場合は、設定ファイルのサンプルのインストールから始めてください。

# cp /usr/share/examples/openssl/openssl.cnf /etc/openssl/

設定ファイルの用意ができたら、秘密鍵を作り、その鍵を使って証明書署名要求 (Certificate Signing Request, CSR) を作ります。

# cd /etc/openssl
# umask 077
# openssl genrsa > certs/vpngw.key
# umask 022
# openssl req -new -key certs/vpngw.key -out certs/vpngw.csr

この CSR (vpngw.csr) を認証局へ送って、署名をしてもらいます。 これで x509 証明書が交付されます。この証明書を vpngw.crt という名前にすることにします。

自分自身が認証局となりたい場合は、以下の手順で CA 秘密鍵の生成と署名をおこないます。

# cd /etc/openssl
# mkdir -p demoCA/newcerts
# touch demoCA/index.txt
# echo "00" > demoCA/serial
# umask 077
# openssl genrsa > certs/ca.key
# umask 022
# openssl req -days 3650 -x509 -key certs/ca.key -new > certs/ca.crt
# openssl ca -in certs/vpngw.csr -keyfile certs/ca.key -cert certs/ca.crt -out certs/vpngw.crt

秘密鍵が漏れると、 VPN はもう安全ではなくなってしまうので、 秘密鍵は秘密にするようにしてください。CA 証明書 ca.crt をリモートユーザーに渡して、次の手順に進んでください。

racoon(8) の設定 (トップ)

以下に /etc/racoon/racoon.conf ファイルの例を示します。

path certificate "/etc/openssl/certs";

listen {
        adminsock disabled;
}

remote anonymous {
        exchange_mode aggressive;
        certificate_type x509 "vpngw.crt" "vpngw.key";
        my_identifier asn1dn;
        proposal_check claim;
        generate_policy on;		# IPsec ポリシーを自動生成する
	dpd_delay 20;			# 20 秒毎に、 DPD ポーリングする
        nat_traversal force;		# NAT-T を常に使う
        ike_frag on;			# IKE フラグメンテーションを使う
        esp_frag 552;			# ESP フラグメンテーションを使う
        proposal {
                encryption_algorithm aes;
                hash_algorithm sha1;
                authentication_method hybrid_rsa_server;
                dh_group 2;
        }
}
mode_cfg {
        network4 10.99.99.1;		# VPN 用 IPv4 アドレス在庫の先頭のアドレス
        pool_size 253;			# VPN 用 IP アドレス在庫のサイズ: 253 アドレス
        auth_source system;		# /etc/passwd をもとにログインを検証する
        dns4 10.0.12.1;			# IPv4 DNS サーバー
        wins4 10.0.12.1;		# IPv4 WINS サーバー
        banner "/etc/racoon/motd";	# クライアントに対するバナーメッセージ
	pfs_group 2;
}

sainfo anonymous {
	pfs_group 2;
        lifetime time 1 hour;
        encryption_algorithm aes;
        authentication_algorithm hmac_sha1;
        compression_algorithm deflate;
}

mode_cfg セクションで、ISAKMP モード設定を使って VPN ゲートウェイからクライアントへ送られる設定を定義しています。 現在のところ、IPv4 の設定だけに対応しています。 このセクションで、払い出す VPN アドレスの在庫を、先頭のアドレス (network4) と在庫のサイズ (pool_size) により定義しています。auth_source は、ログイン名とパスワードをどうやって検証するかを表します。ここで指定できる値は、 システムユーザーデータベースをもとに検証する system、Pluggable Authentication Module (PAM) システム (/etc/pam.d/racoon が使われます) を使う pam、 RADIUS をもとにログインを検証する radius です。

/etc/racoon/racoon.conf ファイルの準備ができれば、 racoon(8) を実行することができます。

# racoon

ブート時に racoon(8) を起動するためには、 /etc/rc.conf に以下のように書きます。

racoon=YES

さらなるフラグメンテーション問題 (トップ)

この設定例では、ESP フラグメンテーションを使って、送出するパケットが 552 バイトより大きくならないような esp_frag の指定をしています。 552 バイトは非常に小さいですが、これなら最もひどい DSL モデムルーター機器でも使えるはずです。 esp_frag を大きくすれば、性能が向上します。

ESP フラグメンテーションを使えば、どんなサイズの IP パケットでもトンネル経由で交換可能です。 しかし、TCP には特別な場合があり、Path Maximum Transmission Unit (PMTU) 探索にまつわる問題が起きるかもしれません。これに対する解決策は、 最大セグメント長 (Maximum Segment Size, MSS) の調節を使うことです。払い出し用の VPN 内部アドレスの範囲が 10.99.99.0/24 であるとすると、 /etc/ipnat.conf に以下のように書けばよいです。

map ex0 10.99.99.0/24 -> 0/0 mssclamp 512

この設定を有効にするために、以下のようにタイプします。

# ipf -E; ipnat -f /etc/ipnat.conf

起動時にこのコマンドを実行するには、 /etc/rc.conf に以下のように書きます。

ipfilter=YES
ipnat=YES

注意: /etc/ipf.conf ファイルがない場合は、ipfilter=YES とするとシステムが起動しません。 IP フィルタリングが一切必要ない場合は、 空のファイルを作っておけばよいです。

ファイアウォールとの関係 (トップ)

この VPN の手法では、クライアントは VPN ゲートウェイの 500 番ポートと 4500 番ポートへ UDP パケットを送る必要があります。最初のパケットは 500 番ポートで交換され、 それから NAT-T 交渉で 4500 番ポートにトランザクションが移ります。

VPN ゲートウェイの前に立つファイアウォールは、 VPN ゲートウェイ宛の udp/500 と udp/4500 を通すように設定する必要があります。

VPN ゲートウェイと RADIUS (トップ)

RADIUS は、ログインの検証、IP アドレスの割り当てと、 アカウンティングに使うことができます。以下に示すのは、 /etc/racoon/racoon.conf ファイルの mode_cfg セクションで、 RADIUS を使うようにするための例です。

mode_cfg {
	pool_size 253;			# IPv4 アドレス在庫のサイズ
	auth_source radius;		# RADIUS をもとにログインを検証する
	conf_source radius;		# RADIUS で IPv4 アドレスを割り当てる
	accounting radius;		# RADIUS アカウンティング
        dns4 10.0.12.1;			# IPv4 DNS サーバー
        wins4 10.0.12.1;		# IPv4 WINS サーバー
        banner "/etc/racoon/motd";	# クライアントに対するバナーメッセージ
	pfs_group 2;
}

この設定のほか、RADIUS サーバーのアドレスと RADIUS サーバーとの共有鍵を含んだ /etc/radius.conf ファイルを作る必要があります。 このファイルは、共有鍵を安全に保つために、 root の所有としてパーミッションを 0600 にしなければなりません。 以下に例を示します。詳細は radius.conf(5) をご覧ください。

auth radius.example.net MyDirtySecret
acct radius.example.net MyDirtySecret

VPN クライアント

Cisco VPN client (トップ)

前章で説明したような設定をした VPN ゲートウェイは、相互グループ認証 (mutual group authentication; Hybrid authentication と同義) の設定をした Cisco VPN Client と相互運用することができます。 Cisco VPN クライアントが要求するグループおよびグループパスワードを、 racoon(8) は無視しますが、これによってユーザー認証が安全でなくなることはありません。

NAT-T が有効になるよう、クライアントに IPsec オーバー UDP トランスポートの設定をすることを忘れないでください。

クライアントとしての racoon(8) : 設定例 (トップ)

racoon(8) はクライアントとして使うことができます。 CA 証明書を /etc/openssl/certs/ca.crt にインストールし、 /etc/racoon/racoon.conf を以下のように設定する必要があります。

path certificate "/etc/openssl/certs";
path pre_shared_key "/etc/racoon/psk.txt";

listen {
	# racoon と racoonctl との間で使うソケット
        adminsock "/var/racoon/racoon.sock" "root" "operator" 0660;
}

# Here is the address of the VPN gateway
remote 192.0.2.50 {
        exchange_mode aggressive;
        ca_type x509 "ca.crt";
        proposal_check obey;
        mode_cfg on;		# ISAKMP モード設定による設定を受け入れる
	dpd_delay 20;
        nat_traversal force;
        ike_frag on;
        esp_frag 552;
        script "/etc/racoon/phase1-up.sh" phase1_up;
        script "/etc/racoon/phase1-down.sh" phase1_down;
        passive off;
        proposal {
                encryption_algorithm aes;
                hash_algorithm sha1;
                authentication_method hybrid_rsa_client;
                dh_group 2;
       }
}


sainfo anonymous {
        lifetime time 1 hour;
        encryption_algorithm aes;
        authentication_algorithm hmac_sha1;
        compression_algorithm deflate ;
}

二つのスクリプト phase1-up.shphase1-down.sh は、 それぞれ IKE phase 1 の確立時と終了時、つまり VPN 接続時と切断時に呼ばれます。 このスクリプトは IPsec Security Policies (SP), VPN IP アドレス、 ルーティングエントリーの設定と消去を受け持っています。 サンプルスクリプトのままでも必要なことはできるはずですが、 各自の必要に応じてカスタマイズすることもできます。

# cp /usr/share/examples/racoon/roadwarrior/client/*.sh /etc/racoon/

この準備ができれば、 racoon(8) を起動できます。

# racoon

ブート時に racoon(8) を起動するには、/etc/rc.confracoon=YES を書き加えます。

VPN との接続と切断 (トップ)

racoonctl(8) は、VPN への接続や VPN からの切断に使うことができます。 ログイン名を -u オプションで指定します。 パスワードは端末上で入力を促されます。

$ racoonctl vc -u username 192.0.2.50
Password: password
Bound to address 10.99.99.3
==========================================================
                     Flying pigs LTD

 Welcome to our internal network, remote user.
==========================================================
$ racoonctl vd 192.0.2.50
VPN connection terminated

この例では IP アドレスを使っていますが、DNS アドレスを使うこともできます。 注意: 何らかの理由で、ルーティングエントリーかセキュリティーポリシーデータベース (Security Policy Database, SPD) にねじれが起きると、 VPN の切断時に DNS 名前解決ができなくなります。 この場合は、root で以下のコマンドを使って復旧できます。

# setkey -F
# setkey -FP
# route flush
# route add default your_default_gateway

racoon(8) ソケット /var/racoon/racoon.sock への読み書き権限がある人なら、 誰でも VPN の起動や停止をすることができます。 このソケットの所有者とアクセス権限は、/etc/racoon/racoon.conflisten セクションで、adminsock ステートメントを使って設定できます。

Xauth パスワードの保存 (トップ)

Xauth パスワードの入力を省略したい場合、このパスワードを racoon の事前共有鍵 (PSK) ファイルに保持することができます。/etc/racoon/racoon.confremote セクションに、以下の記述を追加します。

xauth_login "username";

そして、 /etc/racoon/psk.txt に、 ログイン名とパスワードを一行で書き足します。

username	password

以上の設定をしておけば、以下のコマンドは、パスワードの入力を求めることなく、 toto ログインを使って VPN 接続を確立します。

$ racoonctl vc 192.0.2.50

Back to  NetBSD ドキュメンテーション: NetBSD IPSec