ブリッジモードとルーティングモード
OpenVPN は「ブリッジモード」と「ルーティングモード」の 2種類がある。
今回はこのうち「ブリッジモード」を使用して、OpenVPN サーバー側にあるネットワーク上の PC 全てにアクセスできるような環境を構築してみた。
SoftEther ユーザー向け:ブリッジモードについて
SoftEther ユーザー向け限定の話になるが、OpenVPN でブリッジモードを構築する際は、SoftEther のような仮想 NIC でローカルのブリッジに接続する必要はない。
これは、OpenVPN をブリッジモードで動作させた場合は、ブリッジも自分自身をブリッジに接続するためである。
カーネルコンフィギュレーション
TAP デバイスとブリッジデバイスを使用するため、カーネルの再構築もしくはカーネルモジュールのインストールが必要となる。

FreeBSD 4.x 以前の FreeBSD
カーネルコンフィギュレーションファイルに
options   BRIDGE
device   tap
を記述して再構築し、再起動を行う。
それ以降の FreeBSD
試しに kldload してみる。
# kldload if_tap
# kldload bridge
モジュールがロードできたら
# sysctl net.link.ether.bridge
# sysctl net.link.tap
で各ツリーが見えるかを確認する。
もし "sysctl: unknown oid 'ツリー名'" とエラーになったらロード出来ていないことになる。

kldload 出来たら起動時に自動的にロードするよう設定する
# vi /boot/loader.conf
if_tap_load="YES"
bridge_load="YES"
インストール
ソースを取得して展開
http://openvpn.net/ からソースをダウンロードして展開。
Windows 用は Version 2.1 系から OpenVPN コントロール用 GUI が同梱された。
ビルド
いつも通りのビルド方法で。
% ./configure --disable-lzo
% make
# make install
ディレクトリの変更
OpenVPN を実行するディレクトリを変更する。
# mkdir -p /usr/local/openvpn/sbin
# mkdir -p /usr/local/openvpn/etc
# mkdir -p /usr/local/openvpn/keys
# chmod 700 /usr/local/openvpn/keys
# mv /usr/local/sbin/openvpn /usr/local/openvpn/sbin
証明書/鍵の作成と各マシンへの配付
ブリッジで複数クライアントの接続を行う場合は証明書/鍵が必要となるので、これらを自力で作成する。
作成用スクリプトは OpenVPN のソースディレクトリ配下 (easy-rsa ディレクトリ) にあらかじめ用意されているのでこれを使用する。

スクリプトの修正
vars スクリプト内の変数及びちょっとした修正を行う。
easy-rsa スクリプト群はどうも vars スクリプトの環境変数を上手く引き継げないようなので、これも合わせて修正。

まずは /(OpenVPN ソースディレクトリ)/easy-rsa/ に移動しておく。
# These are the default values for fields
# which will be placed in the certificate.
# Don't leave any of these fields blank.
export KEY_COUNTRY=***
export KEY_PROVINCE=***
export KEY_CITY=***
export KEY_ORG=***
export KEY_EMAIL=***

$1 ←これを追加
最後の方にある KEY_* はデフォルトでも良いし自分で好きな値に書き換えても良い。
最終行の $1 は、vars スクリプトで環境変数が設定された後にスクリプトを呼び出すための処置。
ルート CA 認証局の開設
まずは証明書に署名を行うためのルート CA 認証局を開設する。
一度きりの実行でよい。
# ./vars "./clean-all"
# ./vars "./build-ca"
"Organizational Unit Name" は空のまま。
"Common Name" はなんでも良いが、今回は "OpenVPN-CA" という文字列を使用した。
サーバー証明書/鍵の作成
サーバーで使用する証明書と鍵を作成する。
一度きりの実行でよい。
# ./vars "./build-key-server server"
"Organizational Unit Name" は空のまま。
"Common Name" は "server" とした。
"A challenge password" は空のまま。
"An optional company name" は空のまま。
"Sign the certificate?" (サインしても良いか?) には "y"。
"1 out of 1 certificate requests certified, commit?" (1/1証明書要求を確認したが良いか?) には "y"。
DH (Diffie-Hellman) パラメータファイルの作成
サーバーで使用する "DH パラメータ" ファイルを作成する。
一度きりの実行でよい。
# ./vars "./build-dh"
マシンパワーに左右されるほどの時間がかかるのでのんびりお待ち下さい。
といっても PentiumIII 800MHz で数分だが。
クライアント証明書/鍵の作成
クライアントで使用する証明書と鍵を作成する。
クライアント単位で個別の証明書が必要なので、クライアントが増えたらこの操作を行うこと。
# ./vars "./build-key client1"
"Organizational Unit Name" は空のまま。
"Common Name" は "client1" とした。名前は何でもよいので証明書ファイル名の名前を指定するとよい。
"A challenge password" は空のまま。
"An optional company name" は空のまま。
"Sign the certificate?" (サインしても良いか?) には "y"。
"1 out of 1 certificate requests certified, commit?" (1/1証明書要求を確認したが良いか?) には "y"。
各マシンへの配付
証明書/鍵が出来たら、ファイルをそれぞれのマシンへ配付する。

OpenVPN クライアントへ配付
OpenVPN インストールディレクトリ配下にある config ディレクトリに置くと良い。
  • クライアント証明書 (client*.crt)
  • クライアント鍵 (client*.key)
  • ルート CA 証明書 (ca.crt)
client*.crt と crient*.key は、1台につき 1ペアで配付すること。
例えば OpenVPN クライアントが 3台あるならば、OpenVPN クライアント 1台目には client1.*、同 2台目には client2.* というふうに配付する。
OpenVPN サーバーへ保存
今回は始めに作成した /usr/local/openvpn/keys/ ディレクトリに置く。
  • サーバー証明書 (server.crt)
  • サーバー鍵 (server.key)
  • ルート CA 証明書 (ca.crt)
  • DH パラメータ (dh*.pem)
余ったファイルは削除せずに保存しておくこと。
設定ファイルの準備
設定ファイルはサーバー用とクライアント用を用意する。


サーバー用は OpenVPN サーバーの /usr/local/openvpn/etc/ にコピーする。
クライアント用は OpenVPN インストールディレクトリ配下の config にコピーする。
ブリッジ生成スクリプトの作成
Bridge Up 用と Bridge Down 用スクリプトの 2種類を作成する。


ファイルは /usr/local/openvpn/sbin/ に置く。

tap デバイスに IP アドレスを割り当てる必要はなさそうなので、ブリッジ設定のみを行うようにしている。
起動スクリプトの作成
スタートアップ用スクリプトを作成する。


これを /usr/local/etc/rc.d/ に置く。
OpenVPN サーバーの起動とクライアントからの接続
まずは手動で起動してみる。
# /usr/local/openvpn/sbin/ --config /usr/local/openvpn/etc/bridge.conf
デーモンで起動せずフロントエンドで起動するので、エラーを吐いていないかを確認。
エラーを吐いているなら適時修正する。
エラーを吐いていないならば、(別の端末から接続して) ifconfig で tap デバイスが UP しているか、及びブリッジの状態を確認する。
IP アドレスが割り当てられる必要はない。
# ifconfig -a
tap0: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1310
         ether 00:bd:bd:ef:01:00
         Opened by PID ****
※一部省略
# sysctl -a net.link.ether.bridge_cfg
net.link.ether.bridge_cfg: fxp0 tap0
# sysctl -a net.link.ether.bridge
net.link.ether.bridge: 1
確認が出来たら CTRL+C で強制終了し、tap デバイスが DOWN しているか、及びブリッジの状態を確認する。
# ifconfig -a
tap0: flags=8802<BROADCAST,SIMPLEX,MULTICAST> mtu 1310
         ether 00:bd:bd:ef:01:00
※一部省略
# sysctl -a net.link.ether.bridge_cfg
net.link.ether.bridge_cfg:
# sysctl -a net.link.ether.bridge
net.link.ether.bridge: 0
正常に起動できたことが確認できたら起動スクリプトで起動させる。

OpenVPN サーバーが起動したら今度は OpenVPN クライアントのテストを行う。
今回は Windows 用クライアントで説明をする。
タスクトレイに入っているアイコンを右クリック→ "Connect"、もしくはアイコンのダブルクリックで接続を行う。
接続が完了したら "client is now connected." と出るが、これが出ても安心は出来ず、DHCP から IP アドレスが配付されていない可能性もあるので確認を行うこと。
C:\>ipconfig
Ethernet adapter OVPN:

        Connection-specific DNS Suffix  . : ***********
        Description . . . . . . . . . . . : TAP-Win32 Adapter V8
        Physical Address. . . . . . . . . : 00-FF-6A-21-C7-50
        Dhcp Enabled. . . . . . . . . . . : No
        IP Address. . . . . . . . . . . . : 192.168.1.101
        Subnet Mask . . . . . . . . . . . : 255.255.255.0
        Default Gateway . . . . . . . . . :
        DNS Servers . . . . . . . . . . . : 192.168.1.10
        Primary WINS Server . . . . . . . : 192.168.1.10
今回は特定のネットワーク (192.168.1.0/24) のみ OpenVPN を通るという設定を行ったので、デフォルトゲートウェイは設定していない。
# redirect-gateway def1 を設定するとデフォルトゲートウェイ欄が埋まる。
また、(OpenVPN クライアントを異ネットワークのルーターとして使う実験を行っているため、) OVPN (OpenVPN のインターフェイス名) のネットワーク設定は手動で IP アドレス割り当てなどを行っており、OpenVPN DHCP を含む DHCP からの IP アドレス配付は使用しなかった。
この状態で OpenVPN クライアントと OpenVPN サーバー両方からお互いのネットワーク上に居る PC に対して ping を打ってみる。
ping が届かない場合は、ルーティングのチェック (通るべき所を通らなかったり、通るべきではないところを通ったりしていないか) と、OpenVPN NIC と tap デバイスに IP アドレスが割り当てられているかを確認する。

あとは NET VIEW コマンドで相手の PC 群が見えるかどうか、共有ディレクトリにアクセスできるかなどを確認して完了となる。
もしデフォルトで OpenVPN 経由の通信を行いたいのであれば、クライアント側で redirect-gateway def1 を設定するか、もしくはサーバー側で push "redirect-gateway def1" を設定すればよい。
OpenVPN for PocketPC 利用時の注意
Windows Vista 利用時の注意
Windows Vista で 2.0系の OpenVPN を使用すると以下のようなエラーとなる。
ROUTE: route addition failed using CreateIpForwardEntry: パラメータが正しくありません。 [status=87 if_index=3]
これは、Windows Vista では CreateIpForwardEntry の仕様変更により OpenVPN が出力する route コマンドの構文を処理できないのが原因。
解決方法としては、2.1系を使うと良い。
# OpenVPN GUI も備えている。
OpenVPN for Windows 利用時の注意
redirect-gateway def1 で接続している際、nslookup の DNS が OpenVPN ではなくローカルで指定された DNS を見に行くようになっているが、これは Windows の nslookup の仕様で、nslookup はバインドされているインターフェイスの順序で一番上にあるインターフェイスの DNS 設定を参照するという仕様のため。
解決方法は
http://support.microsoft.com/kb/311218
を参照のこと。
おまけ
OpenVPN クライアントで "Routing and Remote Access" サービスを起動し、OpenVPN クライアントが属するネットワークの PC で OpenVPN クライアントをゲートウェイに設定すると、OpenVPN クライアントではない PC からも OpenVPN サーバー側の PC などにアクセスできる。
戻り側のルーティングも必要なので、OpenVPN サーバー側のアクセス対象 PC でもルーティングを切っておかなければならないことに注意。