Pocket

このページはOpenVPN公式サイトのコンテンツ(“Howto”)の翻訳ですが、完全な翻訳であることを保証するものではありません。正確な情報については公式サイトの情報も併せてご確認ください。

目次

OpenVPNの紹介(イントロダクション)

OpenVPNは業界標準であるSSL/TLSプロトコルを利用した、高機能のSSL VPNです。証明書やスマートカード、ID/パスワードを使った柔軟なクライアント認証が可能であり、 VPNの仮想インターフェイスに対してファイアーウォールを設定することによってユーザーやグループ単位でのアクセス制御もできます。 OpenVPNはWebアプリケーションプロキシではありませんので、Webブラウザを使って操作するものではありません。

このドキュメントでは、OpenVPN 2.0のクライアント/サーバーの設定方法をステップバイステップで解説します。

設定ファイルのサンプルを参照したい場合はこちらからどうぞ。

想定されている読者

このドキュメントは、ネットワークに関する基礎知識、たとえばIPアドレス、DNS、ネットマスク、サブネット、IPルーティング、ルータ、ネットワークインターフェイス、LAN、ゲートウェイ、ファイアーウォールなどについての基本的な知識を持っている方を対象にしています。

OpenVPN 1.xのドキュメント

旧バージョンであるOpenVPN 1.0のドキュメントも「OpenVPN 1.x HOWTO」から参照できます。Point-to-Pointでの接続や静的鍵での設定などについて有用な情報が含まれていますので、必要に応じて参照してください。

他の資料

他にもたくさんの資料があります。こちらをご覧ください。

クイックスタート

ここからは、X509 PKI(証明書と秘密鍵を使った公開鍵認証)を使ってVPNクライアント/サーバーを構成する方法を説明します。
「設定は最小限にしてとにかくVPNをすぐ使いたい!」という場合は、静的鍵での設定が簡単です。静的鍵 Mini-HOWTOを参照してください。

静的鍵を利用する場合の利点

  • セットアップが簡単
  • X509 PKIの保守が不要

静的鍵を利用する場合の欠点

  • 拡張性が低い - 1台のクライアントと1台のサーバーの組み合わせのみ
  • PFS(Perfect Forward Secrecy)の欠如 — 鍵が漏洩した場合、以前のセッションについてもデータが明らかになってしまう
  • VPNのペアごとに秘密鍵をプレーンテキストファイルとして保持しなければならない
  • 秘密鍵を交換するのに、安全な方法(フロッピーディスクなどの物理媒体、暗号化されたネットワーク経由など)を使わなければならない

インストール

まずはOpenVPNをダウンロードします。 正しくダウンロードできたかどうかを確認するため、ダウンロードしたファイルの署名を確認しておくとさらに安全です。

OpenVPNの実行ファイルはサーバーとクライアントの両方にインストールする必要がありますが、サーバーとクライアントに同じ実行ファイルをインストールします。

Linuxの場合(RPMパッケージを使うとき)

RPMパッケージをサポートしたLinuxディストリビューション(SuSE、Fedora、Redhatなど)を使うときには、RPMを使ってインストールするのが最も簡単です。

お使いのディストリビューションに対応したバイナリRPMファイルを入手してインストールするという方法が一般的ですが、次のように自分でRPMファイルをビルドすることもできます。

rpmbuild -tb openvpn-[version].tar.gz

RPMファイルを入手/ビルドできれば、通常のRPMファイルの場合と同じ方法でインストールできます。

rpm -ivh openvpn-[details].rpm

インストール済みのOpenVPNをアップグレードする場合は次のようにします。

rpm -Uvh openvpn-[details].rpm

OpenVPNのバイナリRPMパッケージをインストールする場合、次の依存関係があります。

  • openssl
  • lzo
  • pam

また、自分でRPMパッケージをビルドする場合にはさらに次の依存関係があります。

  • openssl-devel
  • lzo-devel
  • pam-devel

Red Hat Linux 9でのRPMビルドや、依存関係の制御などに関してはopenvpn.specファイルを参照してください。

Linuxの場合(RPMを使わないとき)

DebianやGentooなど、RPMベースではないLinuxディストリビューションの場合は、そのディストリビューションで利用できるパッケージングシステム(apt-getやemergeなど)を使ってインストールすることができます。

また、./configureコマンドを使ってインストールすることもできます。
最初に.tar.gzファイルを展開します。

tar xfz openvpn-[version].tar.gz

展開したディレクトリに移動してmakeします。

./configure
make
make install

Windowsの場合

ダウンロードページにある自己解凍exeファイルを実行してインストールします。

OpenVPNはWindows 2000以降でのみ動作することと、OpenVPNをインストール/実行するには管理者権限が必要(Windowsの制約のため)であることに注意してください。 インストール後であれば、サービスとして動作することにより管理者権限のないユーザーでもOpenVPNを利用することができます。 詳細については「More discussion on OpenVPN + Windows privilege issues」を参照してください。

Windows用のOpenVPN GUIのインストール時にOpenVPNをインストールすることもできます。Mathias Sundmanのインストールパッケージを使うと、GUIツールとOpenVPN本体を同時にインストールできます。

OpenVPNをWindowsインストーラでインストールすると、.ovpnファイルがOpenVPNに関連付けられます。

インストールが完了した後、OpenVPNを次のいずれかの方法で実行します。

  • OpenVPN設定ファイル(.ovpn)で右クリックして、コンテキストメニューで「Start OpenVPN on this configuration file(この設定ファイルでOpenVPNを開始する)」を選択する。OpenVPNを終了するにはF4キーを押します。
  • コマンドプロンプトからOpenVPNのコマンドを実行する。実行後、OpenVPNを終了するにはF4キーを押します。
openvpn myconfig.ovpn
  • OpenVPNをサービスとして実行する。設定ファイルを \Program Files\OpenVPN\configに配置してOpenVPNサービスを起動します。

Windows用にはGUIもあり、GUIから起動することもできます。

Windowsへのインストールについては、こちらにある情報も参照してください。

Mac OS Xの場合

Angelo LaubとDirk TheisenがOpenVPN GUI for OS Xを公開しています。

OpenVPN Client and Mac OS X 10.3も参照してください。

その他のOS

特定のOS向けの注記がINSTALLに記載されていますので参照してください。通常は下記の方法でインストールできます。

./configure
make
make install

「ルーティング」と「ブリッジ」のどちらを使うか?

「ルーティング」と「ブリッジ」の違いについてはFAQで、ブリッジの詳細はこちらのページでさらに詳しく説明されていますので、参照してください。

一般的には「ルーティング」が適している場合が多く、設定も容易です。 また、クライアントごとのアクセス制御もこちらのほうが高機能です。

しかし「ブリッジ」でないと利用できない機能もあります。下記のような機能が必要な場合は「ブリッジ」を使用する必要があります。

  • 非IPプロトコル(IPXなど)をVPN上で使用する必要がある場合
  • ブロードキャストパケットをVPN上で使用する必要がある場合(ネットワークゲームなど)
  • SambaやWINSを使用せずに、VPN経由でWindowsファイル共有のブラウズをしたい場合

サブネットの設定

VPNを設定する場合、通常は異なるロケーションにあるサブネットを相互にリンクさせます。

Internet Assigned Numbers Authority (IANA) は、RFC1918において下記のIPアドレスブロックをプライベートネットワーク用アドレスとして定義しています。

10.0.0.010.255.255.255(10/8 prefix)
172.16.0.0172.31.255.255(172.16/12 prefix)
192.168.0.0192.168.255.255(192.168/16 prefix)

VPN設定でもこれらのプライベートIPアドレスブロック内のアドレスを使用しますが、IPアドレスやサブネットが重複しないよう注意する必要があります。たとえば次のような状況は避けなければなりません。

  • 同一VPN内の他の拠点にあるネットワークと同じサブネットになってしまう
  • リモートアクセスを使用する場合で、アクセス元のサブネットがVPNのサブネットと重複してしまう

たとえば、よく使用されるプライベートLANのサブネットとして192.168.0.0/24があります。 外部のインターネットカフェからVPNにアクセスしようとしたとき、そのインターネットカフェのLANがこの同じサブネットを使うよう設定されているとすると、ルーティングの衝突が発生します。192.168.0.1というゲートウェイのアドレスが、そのインターネットカフェのLAN内のアドレスなのか、VPN上のアドレスなのかが判断できないためです。

もうひとつの例を考えてみます。複数の拠点間をVPNで接続しようとしますが、それぞれの拠点のLANでサブネットとして192.168.0.0/24を使用していたとします。 この場合も問題が発生します。各拠点で異なるサブネットを使用しないと、どのサイトにパケットを送ればいいかが判断できないためです。

この問題を避けるための最善の解決策は10.0.0.0/24や192.168.0.0/24をプライベートLANのネットワークアドレスとして使用しないことです。VPNのアクセス元(インターネットカフェや空港、ホテルなども含む)で使用されている可能性の低いサブネットを選択します。たとえば、10.0.0.0/8アドレスブロックの途中のアドレス(10.66.77.0/24 など)を抜き出して使えば、アドレスが重なりにくくなるかもしれません。

認証局(CA)の設置とOpenVPN用証明書と鍵の生成

概要

OpenVPN 2.0の設定の第一段階は、PKI(公開鍵基盤)の構築です。PKIには以下のものが含まれます。

  • サーバーとクライアントそれぞれに個別に必要な証明書(公開鍵とも言われます)と秘密鍵
  • サーバーやクライアントで使用される証明書に署名するために必要な認証局(CA)の証明書と鍵

OpenVPNは双方向の認証をサポートしています。したがって、信頼された接続を確立するためにはクライアントはサーバーの証明書を認証し、サーバーはクライアントの証明書を認証する必要があります。

この認証では、まずマスター認証機関(CA)によって署名されているかを確認し、その後証明書のヘッダ情報(共通名や認証タイプなど)をチェックします。

VPNの観点からすると、このセキュリティモデルにはさまざまな利点があります。

  • サーバーは自分自身の証明書と鍵を持っていればよい。サーバーは接続してくる可能性のあるすべてのクライアントの証明書を持っている必要がありません。
  • サーバーはマスター認証機関(CA)が署名した証明書だけを受け入れる。
  • 秘密鍵に問題があり廃止したくなった場合には、証明書をCRL(Certificate Revocation List)に加えればよい。CRLを使えば、PKI全体を再構築しなくても特定の証明書を拒否できます。
  • サーバーは証明書内に埋め込まれた特定のフィールド(共通名など)に基づいて、クライアントごとのアクセス権限を強制できる。

マスター認証機関(CA)の証明書と鍵の生成

このセクションでは、まずマスター認証機関の証明書と鍵を生成した後、サーバーの証明書と鍵を生成し、続けて3台のクライアントそれぞれの証明書と鍵を生成する方法を説明します。

LinuxやBSD、UnixベースのOSを使用している場合には、シェルを開き、OpenVPNが配置されているディレクトリのeasy-rsaサブディレクトリに入ります。 RPMファイルからインストールした場合は、このディレクトリは通常/usr/share/doc/packages/openvpnか/usr/share/doc/openvpn-2.0にあります。

[注] RPMファイルからインストールした場合、設定ファイルを編集する前に、設定ファイルを/etc/openvpnなどのディレクトリにコピーしておくと安全です。こうしておけば、今後OpenVPNをアップグレードしたときにも設定ファイルが上書きされることを防ぐことができます。

.tar.gzファイルからインストールした場合は、easy-rsaサブディレクトリはソースツリーを展開したトップディレクトリの下にあります。

Windowsを使用している場合には、コマンドプロンプトを開き、\Program Files\OpenVPN\easy-rsaディレクトリに入ります。 次のバッチファイルを実行して設定ファイルをコピーします(このコマンドを実行すると、vars.batとopenssl.cnfが上書きされます)。

init-config

varsファイル(Windowsの場合はvars.batファイル)で記述されているKEY_COUNTRY、KEY_PROVINCE、KEY_CITY、KEY_ORG、KEY_EMAILの各パラメータを設定します。 これらのパラメータはブランクにしないようにしてください。

続いて、PKIを初期化します。Linux/BSD/Unixの場合は次のようにします。

. ./vars
./clean-all
./build-ca

Windowsの場合は次のようにします。

vars
clean-all
build-ca

最後にbuild-caコマンドを実行すると、opensslコマンドが呼び出されて認証機関(CA)の証明書と鍵が生成されます。

ai:easy-rsa # ./build-ca
Generating a 1024 bit RSA private key
............++++++
...........++++++
writing new private key to 'ca.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [KG]:
State or Province Name (full name) [NA]:
Locality Name (eg, city) [BISHKEK]:
Organization Name (eg, company) [OpenVPN-TEST]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:OpenVPN-CA
Email Address [[email protected]]:

[email protected][email protected]varsまたはvars.batファイルで設定した値が使用されます。

Common Name(共通名)だけはデフォルト値が設定されないため、ここで必ず入力しなければなりません。上記の例では「OpenVPN-CA」としています。

サーバー用の証明書と鍵の生成

次に、サーバー用の証明書と秘密鍵を生成します。Linux/BSD/Unixの場合は次のようにします。

./build-key-server server

Windowsの場合は次のようにします。

build-key-server server

ここでもほとんどのパラメータはデフォルトのままで問題ないはずですが、Common Nameは設定する必要があります。ここでは「server」と設定します。

また、「Sign the certificate?(証明書に署名しますか?) [y/n]」と「1 out of 1 certificate requests certified, commit?(1つの証明書要求がありますが、コミットしますか?) [y/n]」という2つの質問が出ますが、両方にYesと答えてください。

3台のクライアント用の証明書と鍵の生成

基本的にサーバーの手順と同様の方法です。Linux/BSD/Unixの場合は次のようにします。

./build-key client1
./build-key client2
./build-key client3

Windowsの場合は次のようにします。

build-key client1
build-key client2
build-key client3

クライアントの鍵をパスワードで保護したい場合には、代わりにbuild-key-passコマンドを使用してください。

各クライアントには固有のCommon Nameを設定する必要があります。これは他のクライアント用証明書で使用した共通名と重複することはできません。 このサンプルでは「client1」「client2」「client3」という共通名を使用します。

Diffie Hellmanパラメータの生成

OpenVPNサーバーでDiffie Hellmanパラメータを生成します。Linux/BSD/Unixの場合は次のようにします。

./build-dh

Windowsの場合は次のようにします。

build-dh

コマンドを実行すると次のように表示されます。

ai:easy-rsa # ./build-dh
>Generating DH parameters, 1024 bit long safe prime, generator 2
This is going to take a long time
.................+...........................................
...................+.............+.................+.........
......................................

鍵ファイル

新しく作成された証明書と鍵はkeysサブディレクトリにあります。 今までの手順に従うと、以下のようなファイルがあるはずです。

ファイル名適用場所目的秘密かどうか
ca.crtサーバー + すべてのクライアントルートCAの証明書いいえ
ca.key署名するPCのみルートCAの鍵はい
dh{n}.pemサーバーのみDiffie Hellmanパラメータいいえ
server.crtサーバーのみサーバーの証明書いいえ
server.keyサーバーのみサーバーの鍵はい
client1.crtクライアント1のみクライアント1の証明書いいえ
client1.keyクライアント1のみクライアント1の鍵はい
client2.crtクライアント2のみクライアント2の証明書いいえ
client2.keyクライアント2のみクライアント2の鍵はい
client3.crtクライアント3のみクライアント3の証明書いいえ
client3.keyクライアント3のみクライアント3の鍵はい

鍵を生成したら、それぞれのPCに必要なファイルをコピーします。これらのファイルは重要なファイルですので、ファイルを各PCにコピーする際には安全な方法でファイルをやり取りするように注意してください。

サーバー用/クライアント用の設定ファイルの作成

サンプル設定ファイル

設定ファイルを作成するには、サンプル設定ファイルをベースに利用するのが便利です。サンプル設定ファイルは下記の場所にあります。

  • OpenVPNのソースファイル内にあるsample-config-filesディレクトリ
  • RPMパッケージからインストールした場合は、/usr/share/doc/packages/openvpnディレクトリか/usr/share/doc/openvpn-2.0ディレクトリ内にあるsample-config-filesディレクトリ
  • Windows版の場合は[スタート]-[すべてのプログラム]-[OpenVPN]-[OpenVPN Sample Configuration Files]

Linux、BSDなどのUnix系のOSでは、サンプル設定ファイルはserver.confclient.confというファイル名になっています。Windows版ではserver.ovpnclient.ovpnというファイル名になっています。

サーバー設定ファイルの編集

サンプルのサーバー設定ファイルをベースにして、サーバー設定ファイルの編集を行います。この設定では、仮想TUNネットワークインターフェイスをルーティングとして作成し、 UDPポート 1194(OpenVPNの標準ポート番号)でクライアントからの接続を受け付け、VPNクライアントには10.8.0.0/24サブネットのアドレスを配布します。

サンプルの設定ファイルを使用する前には、cacertkey、およびdhの各パラメータをPKIのセクションで作成した実際のファイルの場所に設定してください。

これだけの設定でサーバー設定ファイルを使うこともできますが、通常はさらに以下のような設定を行います。

  • Ethernetブリッジを使用する場合は、serverdev tunの代わりにserver-bridgedev tapを使用する必要があります。
  • OpenVPNサーバーでUDPポートではなくTCPポートで接続を受け付ける場合には、proto udpではなくproto tcpと設定します(UDPとTCPの両方のポートで受け付ける場合には、 2つの別個のOpenVPNインスタンスを実行する必要があります)。
  • 10.8.0.0/24以外の仮想IPアドレスを使用する場合には、serverディレクティブを変更する必要があります。その場合、仮想IPアドレス範囲としてネットワーク上で使用されていないプライベートアドレスブロックを使うようにしてください。
  • VPN上でクライアント同士が接続できるようにするには、client-to-clientのコメントを外します。デフォルトでは各クライアントはサーバーに対してのみ接続できます。
  • Linux、BSD、その他のUnix系OSを使用している場合は、user nobodygroup nobodyのコメントを外すことによってセキュリティを向上させることもできます。

1台のPC上で複数のOpenVPNインスタンスを実行する場合は、それぞれのインスタンスで個別の設定ファイルを使用します。このためには下記のような設定が必要になります。

  • 各インスタンスごとに別個のportを設定する必要があります(UDPとTCPは別々のポート空間を使用するため、1つのデーモンでUDP 1194を、別のデーモンでTCP 1194を利用することができます)。
  • Windowsを使用している場合は、各OpenVPN設定ごとに別個のTAP-Win32アダプタが必要です。アダプタは[スタート]-[すべてのプログラム]-[OpenVPN]-[Add a new TAP-Win32 virtual ethernet adapter]から追加できます。
  • 複数のOpenVPNインスタンスを実行する場合には、それぞれのインスタンスでファイルの出力時に同じファイルを上書きしてしまうことがないように注意してください。loglog-appendstatusifconfig-pool-persistなどの設定が関係します。

クライアント設定ファイルの編集

クライアント用のサンプル設定ファイル(Linux/BSD/Unixではclient.conf、Windowsではclient.ovpn)は、サーバー用のサンプル設定ファイルでの設定に対応するようになっています。

  • サーバー用設定ファイルと同様、cacertkey、およびdhの各パラメータをPKIのセクションで作成した実際のファイルの場所に設定してください。各クライアントは個別のcert/keyペアを使用する必要があります。サーバーとクライアントの両方に必要なファイルはcaファイルのみです。
  • 次にremoteディレクティブにOpenVPNサーバーのホスト名かアドレスとポート番号を設定します。
  • 最後に、クライアント用設定ファイルの設定とサーバー用設定ファイルの設定の整合がきちんと取れているかを確認します。特に確認すべきなのはdev(tunかtap)、proto(udpかtcp)が揃っているかですが、もし使用されるのであればcomp-lzofragmentもサーバーとクライアントの両方で設定が行われているかを確認してください。

VPNの起動と接続テスト

サーバーの起動

まず、OpenVPNサーバーがインターネットからアクセスできるようになっていることを確認します。ファイアーウォールの設定も確認し、OpenVPNのポート(設定したポート)にアクセスできるように設定されているかをチェックしてください。

次に、TUN/TAPインターフェイスに対するファイアーウォールの保護を解除します。

トラブルシューティングを容易にするために、OpenVPNをデーモンやサービスとしてではなく、まずはコマンドラインから(Windowsの場合は.ovpnファイルを右クリックして)実行します。

openvpn [サーバー設定ファイル]

通常、サーバーは起動時に次のようなメッセージを表示します。

Sun Feb  6 20:46:38 2005 OpenVPN 2.0_rc12 i686-suse-linux [SSL] [LZO] [EPOLL] built on Feb  5 2005Sun Feb  6 20:46:38 2005 Diffie-Hellman initialized with 1024 bit key
Sun Feb  6 20:46:38 2005 TLS-Auth MTU parms [ L:1542 D:138 EF:38 EB:0 ET:0 EL:0 ]
Sun Feb  6 20:46:38 2005 TUN/TAP device tun1 opened
Sun Feb  6 20:46:38 2005 /sbin/ifconfig tun1 10.8.0.1 pointopoint 10.8.0.2 mtu 1500
Sun Feb  6 20:46:38 2005 /sbin/route add -net 10.8.0.0 netmask 255.255.255.0 gw 10.8.0.2
Sun Feb  6 20:46:38 2005 Data Channel MTU parms [ L:1542 D:1450 EF:42 EB:23 ET:0 EL:0 AF:3/1 ]
Sun Feb  6 20:46:38 2005 UDPv4 link local (bound): [undef]:1194
Sun Feb  6 20:46:38 2005 UDPv4 link remote: [undef]
Sun Feb  6 20:46:38 2005 MULTI: multi_init called, r=256 v=256
Sun Feb  6 20:46:38 2005 IFCONFIG POOL: base=10.8.0.4 size=62
Sun Feb  6 20:46:38 2005 IFCONFIG POOL LIST
Sun Feb  6 20:46:38 2005 Initialization Sequence Completed

クライアントの起動

サーバーと同様、OpenVPNをデーモンやサービスとしてではなく、まずはコマンドラインから(Windowsの場合は.ovpnファイルを右クリックして)実行します。

openvpn [クライアント設定ファイル]

Windows版では通常、前述のサーバーの起動時の出力と似たようなメッセージが表示されます。メッセージの末尾はInitialization Sequence Completedとなります。

では、クライアントからVPN経由でPINGを実行してみましょう。ルーティングを使用している場合(サーバー設定ファイルでdev tunを使用している場合)は次のようにします。

ping 10.8.0.1

ブリッジモードを使用している場合(サーバー設定ファイルでdev tapを使用している場合)は、サーバーのサブネット上にあるIPアドレスに対してPINGを実行します。

PINGが成功すれば、VPNでの接続は成功です。

トラブルシューティング

PINGが失敗した場合、またOpenVPNクライアントが接続を開始できない場合には、以下の点を確認してください。

TLS Error: TLS key negotiation failed to occur within 60 seconds (check your network connectivity)と表示される。このエラーはクライアントがサーバーへのネットワーク接続が確立できないときに発生します。

解決策: 以下の点をご確認ください。

  • クライアント設定ファイルでOpenVPNサーバーの正しいホスト名、IPアドレスとポート名を設定していることを確認する。
  • OpenVPNサーバーがNICを1つだけ搭載していて保護されたLAN上にある場合、ゲートウェイやファイアーウォールの設定でアクセスできなくなっていないことを確認する。
Initialization Sequence Completed with errorsと表示される。このメッセージはWindows版で (1)DHCPクライアントサービスが実行されていないとき、(2) XP SP2上でサードパーティのパーソナルファイアーウォールを使用しているとき、に発生する可能性があります。

解決策: DHCPが利用できるようになっていること、またパーソナルファイアーウォールがXP SP2上で正しく動作するものであることを確認する。

Initialization Sequence Completedメッセージは表示されるものの、PINGが成功しない。これはTUN/TAPインターフェイス上のVPNネットワークトラフィックがファイアーウォールによってフィルタされているときによく起きる問題です。

解決策: クライアントのTUN/TAPインターフェイスでファイアーウォールを無効にする。Windows XP SP2の場合、[Windowsセキュリティセンター]-[Windowsファイアーウォール]-[詳細]でTAP-Win32アダプタのファイアーウォールを解除する。また、サーバー側のTUN/TAPインターフェイスでもトラフィックがフィルタされていないことを確認する(サーバー側でのファイアーウォールの利用については、「クライアント特有のルールとアクセスポリシーの設定」も参照してください)。

proto udp設定を使用しているが、接続開始時に接続が止まってしまい、サーバーに下記のようなログが残される。
TLS: Initial packet from x.x.x.x:x, sid=xxxxxxxx xxxxxxxx

クライアント側にログが残されていない。

解決策: 接続がクライアントからサーバーへの一方のみしか確立できないため、サーバーからクライアントへのデータが(おそらくはクライアント側で)ブロックされている。(1)クライアント上でパーソナルファイアーウォールが動作しているか、(2)クライアント用のNATルータゲートウェイが動作している可能性がある。サーバーからクライアントへのUDPパケットが許可されるようファイアーウォールの設定を変更する。

トラブルシューティングに関するさらに多くの情報がFAQにありますので、参照してください。

システムのスタートアップでOpenVPNが自動起動するように設定する

ブート時にデーモンやサービスを自動起動する方法はOSによって異なります。

WindowsインストーラやRPMのようなパッケージからインストールすると、標準で自動起動の設定が行われます。

Linux

LinuxでRPMパッケージからOpenVPNをインストールした場合、インストーラによってinitscriptがセットアップされます。実行すると/etc/openvpnディレクトリ内にある.confファイルが検索され、見つかった設定ファイルごとに別個のOpenVPNデーモンが起動します。

Windows

Windowsインストーラを使ってインストールするときにサービスラッパーも同時にセットアップされますが、デフォルトではOFFになっています。サービスを有効化するには、[コントロールパネル]にある[管理ツール]から[サービス]を開き、OpenVPNサービスを選択して右クリックして[プロパティ]を選択します。[スタートアップの種類]を「自動」に設定すると、サービスは次回の再起動時から自動起動します。

サービスが起動されると、OpenVPNサービスラッパーが\Program Files\OpenVPN\configフォルダにある.ovpn設定ファイルを検索し、見つかった設定ファイルごとに別個のOpenVPNプロセスが起動します。

実行中のOpenVPNプロセスの制御

Linux/BSD/Unixで動作している場合

OpenVPNは下記のシグナルを受け付けます。

  • SIGUSR1 — root権限なしで再起動する条件付き再起動
  • SIGHUP — 強制再起動
  • SIGUSR2 — ログファイルかsyslogへの接続状況の出力
  • SIGTERM, SIGINT — 終了

writepidディレクティブを使用するとOpenVPNデーモンが使用するPIDをファイルに書き出すことができるため、シグナルを送るプロセスを判別できます(initscriptでOpenVPNを起動した場合は、コマンドラインに–writepidディレクティブを付加して起動します)。

WindowsでGUIから動作している場合

OpenVPN GUIを参照してください。

Windowsでコマンドプロンプトウィンドウから動作している場合

Windowsでは、OpenVPN設定ファイル(.ovpnファイル)で右クリックして[Start OpenVPN on this config file]を選択することによって起動できます。

この方法で起動すると、以下のキーボードコマンドが使用可能になります。

  • F1 — 条件付き再起動(TAPアダプタをクローズ/再オープンしない)
  • F2 — 接続状況の表示
  • F3 — 強制再起動
  • F4 — 終了

Windowsサービスとして動作している場合

OpenVPNをWindowsのサービスとして起動した場合には、以下の方法でのみ制御できます。

  • サービスコントロールマネージャ([コントロールパネル]-[管理ツール]-[サービス])で開始/停止する
  • 後述の管理インターフェイスを使用する

サーバー起動中の設定変更

ほとんどの設定変更については、変更後にサーバーの再起動が必要です。ただし、2つのディレクティブによって参照されているファイルだけは例外で、それらのファイルは書き換えられた後すぐに反映され、設定の反映のためにサーバープロセスを再起動する必要がありません。

client-config-dir — このディレクティブはクライアント設定ディレクトリを設定するものです。これはクライアントごとの設定ファイルを格納するディレクトリであり、サーバーへの接続のたびにスキャンされます(詳細についてはman pageを参照してください。)。このディレクトリ内のファイルは変更がすぐに反映され、サーバーの再起動は必要ありません。ただし、この設定の変更が適用されるのは設定変更後に接続してくる新しい接続に対してのみで、既存の接続には適用されないことに注意してください。既存の接続(または、切断したもののまだタイムアウトしていない接続)にも新しい設定を適用したい場合は、後述する管理インターフェイスを使用してその接続のインスタンスをKillしてください。これによって再接続が行われ、新しいclient-config-dirファイルが適用されることになります。

crl-verify — このディレクティブは「証明書の失効」で後述する証明書失効リスト(CRL:Certificate Revocation List)を指定するためのものです。ここで指定されたCRLファイルを書き換えた場合は、その後接続してくる新しい接続や、既存の接続のSSL/TLSチャンネルの再ネゴシエーション(デフォルトでは1時間おき)の際にすぐに適用されます。CRLに追加した証明書を使っているクライアントからの接続をすぐに切断したい場合には、後述する管理インターフェイスを使用してください。

ステータスファイル

デフォルトのserver.confでは次のように設定されています。

status openvpn-status.log

このファイルには、現在接続しているクライアント接続のリストが1分ごとに書き出されます。

管理インターフェイスの使用

OpenVPN管理インターフェイスを使うと、実行中のOpenVPNプロセスを制御できます。この管理インターフェイスは管理用のポートにTELNETで接続することによって直接使用することもできますし、この機能を利用するGUIを使って間接的に使用することもできます。

この管理インターフェイスを有効にするには、サーバーかクライアントの設定ファイルで次のように設定します。

management localhost 7505

この設定では、OpenVPNの管理インターフェイスはTCPポート 7505で接続を受け付けます(もちろん他の空いているポートを設定することもできます)。

この設定を行ってOpenVPNが実行されている状態であれば、この管理インターフェイスにTELNETクライアントを使って接続することができます。

ai:~ # telnet localhost 7505
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
>INFO:OpenVPN Management Interface Version 1 -- type 'help' for more info
help
Management Interface for OpenVPN 2.0_rc14 i686-suse-linux [SSL] [LZO] [EPOLL] built on Feb 15 2005
Commands:
echo [on|off] [N|all]  : Like log, but only show messages in echo buffer.
exit|quit              : Close management session.
help                   : Print this message.
hold [on|off|release]  : Set/show hold flag to on/off state, or
release current hold and start tunnel.
kill cn                : Kill the client instance(s) having common name cn.
kill IP:port           : Kill the client instance connecting from IP:port.
log [on|off] [N|all]   : Turn on/off realtime log display
                         + show last N lines or 'all' for entire history.
mute [n]               : Set log mute level to n, or show level if n is absent.
net                    : (Windows only) Show network info and routing table.
password type p        : Enter password p for a queried OpenVPN password.
signal s               : Send signal s to daemon,
                         s = SIGHUP|SIGTERM|SIGUSR1|SIGUSR2.
state [on|off] [N|all] : Like log, but show state history.
status [n]             : Show current daemon status info using format #n.
test n                 : Produce n lines of output for testing/debugging.
username type u        : Enter username u for a queried OpenVPN username.
verb [n]               : Set log verbosity level to n, or show if n is absent.
version                : Show current version number.
END
exit
Connection closed by foreign host.
ai:~ #

詳細についてはOpenVPN Management Interface Documentationを参照してください。

クライアント側、またはサーバー側サブネットへのクライアントPCの追加によるVPNの拡張

ルーティングVPN(dev tun)でサーバー側に複数PCを接続する

クライアントとサーバー間でVPNが動作するようになると、クライアントを追加し、サーバーだけではなくサーバーネットワーク上にある複数のPCにアクセスできるようにVPNを拡張したいと思うことでしょう。

この例では、サーバー側LANはサブネットとして10.66.0.0/24を使用しており、OpenVPNのサーバー設定ファイルのserverディレクティブの設定ではVPN IPアドレス範囲として10.8.0.0/24を使用しているものとします。

まず、VPNクライアントに対して、10.66.0.0/24のサブネットにVPN経由でアクセスさせるようにする必要があります。これは、サーバーの設定ファイル内のディレクティブを下記のように設定することによって簡単にできます。

push "route 10.66.0.0 255.255.255.0"

次に、サーバー側LANのゲートウェイにおいて、VPNクライアントサブネット(10.8.0.0/24)からOpenVPNサーバーへルーティングされるように設定する必要があります(これはOpenVPNサーバーとLANゲートウェイが別の場合にのみ必要な設定です)。

また、OpenVPNサーバーでIPフォワードTUN/TAPフォワードが有効になっていることを確認してください。

ブリッジVPN(dev tap)でサーバー側に複数PCを接続する

ブリッジの場合は、追加の設定を行う必要はありません。これはブリッジを利用しているメリットの1つです。

ルーティングVPN(dev tun)でクライアント側に複数PCを接続する

典型的なリモートアクセスの場合、クライアントPCは1台のPCとしてVPNに接続します。しかし、クライアントPCをローカルLAN(ホームオフィスなど)のゲートウェイとして利用し、そのクライアントLAN上にある各PCをVPNに接続したい場合があります。

今回の例ではクライアントLANは192.168.4.0/24サブネットを使用しており、このVPNクライアントは共通名としてclient2を設定した証明書を使うものとします。目標は、クライアントLAN上のすべてのマシンがVPN経由でサーバーLAN上の任意のPCにアクセスできるようにすることです。

セットアップの前に必要なことがいくつかあります。

  • クライアントLAN(今回の例では192.168.4.0/24)と同じサブネットがVPN上で使用されていないことを確認してください。VPNに接続するそれぞれのサブネットは固有である必要があります。
  • このクライアントの証明書では必ずユニークな共通名(今回の例ではclient2)を設定してください。サーバー設定ファイルでduplicate-cnフラグを使用することはできません。

まず、このクライアントPCでIPフォワードTUN/TAPフォワードを有効にしてください。

次に、サーバー側の設定を変更します。サーバー設定ファイルでクライアント設定ディレクトリへの参照が行われていない場合は、次の行を追加してください。

client-config-dir ccd

このディレクティブで設定されているccdは、OpenVPNサーバーデーモンが起動する際に事前に作成されるディレクトリの名前です。通常、Linuxの場合は/etc/openvpn、Windowsの場合は\Program Files\OpenVPN\configが使用されます。新しいクライアントがOpenVPNサーバーに接続してくると、デーモンがこのディレクトリをチェックし、接続してきたクライアントと一致する共通名が設定された設定ファイルがないかどうかを確認します。ファイルが見つかった場合には、この設定が読み込まれ、追加の設定ディレクティブが適用されます。

次に、ccdディレクトリにclient2というファイルを作成します。このファイルには次の1行を含めます。

iroute 192.168.4.0 255.255.255.0

この設定は、OpenVPNサーバーに対し、192.168.4.0/24サブネットへの通信をclient2にルートさせるためのものです。

続いて、メインのサーバー設定ファイル(ccd/client2ファイルではありません)に下記の1行を加えます。

route 192.168.4.0 255.255.255.0

routeirouteの両方の設定を行うのは冗長に感じるかもしれません。 routeはカーネルからOpenVPNサーバー(TUNインターフェイス経由)でのルート設定に使用される設定で、irouteはOpenVPNサーバーからリモートクライアントでのルート設定に使用されます。そのため、この2つはどちらも必要なものです。

client2のサブネット(192.168.4.0/24)とOpenVPNサーバーの他のクライアントとの間でのネットワークトラフィックを許可したい場合には、サーバー設定ファイルに下記の設定を加えます。

client-to-client
push "route 192.168.4.0 255.255.255.0"

この設定により、OpenVPNサーバーはクライアント2のサブネットを他のクライアントに通知することになります。

最後に(よく忘れる点ですが)、サーバーのLANゲートウェイにおいて、192.168.4.0/24への通信をOpenVPNサーバーにルーティングする設定を追加します(OpenVPN本体がサーバーLANのゲートウェイも兼ねている場合はこのステップは不要です)。もしこの設定を行わずに、 192.168.4.8からサーバーLAN上のPC(OpenVPNサーバー以外)にPINGを飛ばしたらどうなるでしょうか? PINGはその対象PCには届きますが、192.168.4.0/24へのルートが設定されていないため、リプライを返すためのルートがわからないことになります。

同様に、OpenVPNが稼動しているクライアントマシンがクライアントLANのゲートウェイでない場合、クライアントLANのゲートウェイにおいて、OpenVPNクライアントマシンにVPNで接続できるようにすべてのサブネットへのルートが設定されている必要があります。

ブリッジVPN(dev tap)でクライアント側に複数PCを接続する

こちらは少し複雑です(実際にはそれほど難しくありませんが)。下記のような手順が必要です。

  • クライアント上のTAPインターフェイスと、LANに接続したNICをブリッジします。
  • クライアント上のTAPインターフェイスのIPアドレスとネットマスクは手動で設定します。
  • クライアント側LAN内のPCのIPアドレスとネットマスクは、ブリッジされたサブネットの範囲内にある必要があります。ここで説明されているように、DHCPサーバーを使用する方法もあります。

クライアントに対するDHCPオプションの設定

OpenVPNサーバーはクライアントに対し、DNSやWINSサーバーのアドレスなどのDHCPオプションをプッシュすることができます(詳細についてはFAQを参照してください)。 WindowsクライアントはプッシュされたDHCPオプションをOSレベルで受け入れますが、Windows以外のクライアントの場合は、 foreign_option_n環境変数リストをパースするupスクリプトを使用する必要があります。詳細やスクリプトのサンプルはman pageopenvpn-users mailing list archiveを参照してください。

たとえば、接続してくるクライアントに対して内部DNSサーバーを10.66.0.4と10.66.0.5、WINSサーバーを10.66.0.8として設定したい場合には、OpenVPNサーバー設定で次のように設定します。

push "dhcp-option DNS 10.66.0.4"
push "dhcp-option DNS 10.66.0.5"
push "dhcp-option WINS 10.66.0.8"

Windowsでこの動作を確認するには、OpenVPNサーバーに接続している状態でコマンドプロンプトから下記のコマンドを実行します。

ipconfig /all

TAP-Win32アダプタの欄に、サーバーからプッシュされたDHCPオプションが表示されているはずです。

クライアント特有のルールとアクセスポリシーの設定

企業で使用するVPNをセットアップするとして、以下の3つのグループごとにアクセスポリシーを設定する場合を想定します。

  • システム管理者 — ネットワーク上のすべてのPCへのアクセスが可能
  • 正社員 — Samba/メールサーバーにのみアクセスが可能
  • 契約社員 — 特別なサーバーにのみアクセスが可能

基本的なアプローチとしては (a) 各グループごとに仮想IPアドレスを分離し、(b) クライアントの仮想IPアドレスを利用してアクセスを制御するファイアーウォールを設定する、ということになります。

今回の例では、正社員の人数は可変であるものの、システム管理者は1名のみ、契約社員は2名のみ、という構成を想定してみましょう。また、IPアドレスの割り当て方針としては、正社員に対してはIPアドレス範囲からアドレスを割り当て、システム管理者と契約社員には固定IPアドレスを割り当てるものとします。

前提条件として、アクセス制御を可能にするため、OpenVPNサーバー上でソフトウェアファイアーウォールが動作している必要があります。今回は一例としてLinuxのiptableでの例を説明しましょう。

まず、グループごとの仮想IPアドレスのマッピングを決めます。

グループ仮想IPアドレス範囲アクセス可能な範囲共通名
正社員10.8.0.0/2410.66.4.4のsamba/メールサーバー[いろいろ]
システム
管理者
10.8.1.0/2410.66.4.0/24サブネット全体sysadmin1
契約社員10.8.2.0/2410.66.4.12の契約社員用サーバーcontractor1,
contractor2

次に、このマッピングをOpenVPNサーバー設定に書き換えます。その際、前述の手順に従い、すべてのクライアントが利用可能な10.66.4.0/24サブネットが構成してあることを確認してください(10.66.4.0/24サブネットにアクセスできるようにルーティングの設定を行った後、上記のポリシーに従ってアクセス制御を行うようファイアウォールを設定します)。

まず、ファイアーウォールルールでインターフェイスを識別できるようにするために、tunインターフェイスのユニット番号を決めます。

dev tun0

サーバー構成ファイルで、正社員用IPアドレス範囲を定義します。

server 10.8.0.0 255.255.255.0

システム管理者用および契約社員用のIPアドレス範囲に対するルーティングを追加します。

route 10.8.1.0 255.255.255.0
route 10.8.2.0 255.255.255.0

システム管理者と契約社員には固定IPアドレスを割り振る必要があるため、クライアント設定ファイルディレクトリを使用します。

client-config-dir ccd

これで、ccdサブディレクトリに正社員以外のVPNクライアント用に固定IPアドレスを設定するための設定ファイルを格納することになります。

ccd/sysadmin1

ifconfig-push 10.8.1.1 10.8.1.2

ccd/contractor1

ifconfig-push 10.8.2.1 10.8.2.2

ccd/contractor2

ifconfig-push 10.8.2.5 10.8.2.6

ifconfig-pushで設定されている2つのアドレスは、仮想的なクライアントとサーバーのエンドポイントを示しています。WindowsクライアントおよびTAP-Win32ドライバとの互換性のため、これらのアドレスは連続する/30サブネットから選択する必要があります。具体的には、ここで指定するIPアドレスの最後のオクテットの組み合わせは、下記のセットのいずれかでなければなりません。

[  1,  2] [  5,  6] [  9, 10] [ 13, 14] [ 17, 18]
[ 21, 22] [ 25, 26] [ 29, 30] [ 33, 34] [ 37, 38]
[ 41, 42] [ 45, 46] [ 49, 50] [ 53, 54] [ 57, 58]
[ 61, 62] [ 65, 66] [ 69, 70] [ 73, 74] [ 77, 78]
[ 81, 82] [ 85, 86] [ 89, 90] [ 93, 94] [ 97, 98]
[101,102] [105,106] [109,110] [113,114] [117,118]
[121,122] [125,126] [129,130] [133,134] [137,138]
[141,142] [145,146] [149,150] [153,154] [157,158]
[161,162] [165,166] [169,170] [173,174] [177,178]
[181,182] [185,186] [189,190] [193,194] [197,198]
[201,202] [205,206] [209,210] [213,214] [217,218]
[221,222] [225,226] [229,230] [233,234] [237,238]
[241,242] [245,246] [249,250] [253,254]

これでOpenVPNの構成は完了です。あとはアクセスポリシーに基づいてファイアーウォールルールを設定します。一例としてLinuxのiptablesの場合は、次のように設定します。

# 正社員用ルール
iptables -A FORWARD -i tun0 -s 10.8.0.0/24 -d 10.66.4.4 -j ACCEPT
# システム管理者用ルール
iptables -A FORWARD -i tun0 -s 10.8.1.0/24 -d 10.66.4.0/24 -j ACCEPT
# 契約社員用ルール
iptables -A FORWARD -i tun0 -s 10.8.2.0/24 -d 10.66.4.12 -j ACCEPT

別の認証方法の使用

OpenVPN 2.0には、接続しているクライアントからOpenVPNサーバーがユーザー名やパスワードを安全に取得し、これらの情報をクライアントを認証するための基盤として利用するための機能が備わっています。

この認証方式を利用するには、クライアント設定ファイルにauth-user-passディレクティブを追加します。この設定を追加するとOpenVPNクライアントはユーザーにユーザー名とパスワードを問い合わせ、それらの情報をセキュアなTLSチャンネルを経由してサーバーに渡します。

次に、スクリプトや共有オブジェクト、DLLなどの認証プラグインを使用するようにサーバーを設定します。OpenVPNサーバーはVPNクライアントが接続しようとしてくるたびにプラグインを呼び出し、クライアントで入力されたユーザー名とパスワードをプラグインに渡します。認証プラグインは、 OpenVPNサーバーへの接続を許可するかどうかを戻り値(1:接続拒否、0:接続許可)によって制御します。

スクリプトプラグインの使用

スクリプトプラグインを使用するには、サーバー設定ファイルにauth-user-pass-verifyディレクティブを追加します。次のように設定します。

auth-user-pass-verify auth-pam.pl via-file

この設定では、接続してきたクライアントのユーザー名とパスワードをauth-pam.plスクリプトで認証することになります。auth-user-pass-verifyディレクティブの詳細についてはman pageを参照してください。

auth-pam.plはOpenVPNのソースファイル一式の中にあるsample-scriptsディレクトリに含まれています。このスクリプトではPAM認証モジュール(シャドウパスワード、RADIUS、LDAPによる認証が実装されています)を使用してLinuxサーバー上のユーザーを認証します。auth-pam.plは主にデモンストレーション用に作成されています。PAM認証を実際に使用したい場合には、次に説明するopenvpn-auth-pam共有オブジェクトプラグインを使用してください。

共有オブジェクトまたはDLLプラグインの使用

共有オブジェクトやDLLのプラグインはCモジュールとしてコンパイルされ、OpenVPNサーバーの起動時に読み込まれます。RPMベースのLinux用のOpenVPNパッケージを使用している場合には、openvpn-auth-pamプラグインがビルドされています。このプラグインを使用するには、サーバー設定ファイルに下記の記述を追加します。

plugin /usr/share/openvpn/plugin/lib/openvpn-auth-pam.so login

この設定により、OpenVPNサーバーはクライアントで入力されたユーザー名とパスワードをlogin PAMモジュールを使って検証します。

PAM認証を実際に使用する場合には、openvpn-auth-pamプラグインを使用するほうが望ましいと言えます。このプラグインはauth-pam.plに比べていくつかの利点があります。

  • 共有オブジェクトであるopenvpn-auth-pamプラグインは分割された権限実行モデルを利用しており、より安全です。これにより、user nobodygroup nobodychrootといったディレクティブを使ってOpenVPNサーバーを実行する際の権限を制限しつつ、rootしか読み込めないシャドウパスワードファイルを使っての認証が実現できます。
  • ユーザー名やパスワードをファイルや環境変数ではなく、仮想メモリ経由でプラグインに渡すことができます。これはサーバー上のセキュリティを向上させます。
  • Cでコンパイルされたプラグインはスクリプトより早く動作します。

OpenVPNで使用できるプラグインを開発する方法については、OpenVPNのソース内にあるpluginディレクトリのREADMEファイルを参照してください。

Linux上でopenvpn-auth-pamプラグインをビルドするには、OpenVPNのソース内にあるplugin/auth-pamディレクトリに入り、makeを実行します。

デフォルトでは、auth-user-pass-verify、またはユーザー名とパスワードによる認証を行うプラグインを使用すると、二重の認証が行われることになります。したがって、クライアントが認証をパスするには、クライアント証明書による認証と、ユーザー名とパスワードによる認証の両方が必要です。

セキュリティ上はお勧めできませんが、クライアント証明書による認証を行わないようにし、ユーザー名とパスワードによってのみ認証を行うように設定することもできます。その場合にはサーバー設定で下記の記述を追加します。

client-cert-not-required

この設定を行う場合には下記の設定も行います。

username-as-common-name

これにより、サーバーはユーザー名をインデックス用に使用します。クライアント証明書での認証の場合は共通名が使用されます。

[注] client-cert-not-requiredはサーバー証明書を不要にするものではありません。client-cert-not-requiredを使用したサーバーに接続するクライアントはクライアント設定ファイルからcert とkeyディレクティブを削除できますが、caディレクティブは削除できません。これはクライアントがサーバー証明書を検証する際に必要だからです。

クライアント側でスマートカードを利用した2ファクタ認証を行うためのOpenVPNの設定方法

2ファクタ認証(dual-factor authentication)について

2ファクタ認証とは、「持っている物」と「知っていること」という2つの要素を組み合わせた認証方式のことです。

「持っている物」としてよく使用されるのは複製不可能なデバイス、たとえば秘密鍵を格納した暗号化トークンです。このような暗号化トークンでは、秘密鍵はデバイスの中で生成され、外に出ることはありません。暗号化トークンを所有しているユーザーがリモートネットワーク上にある保護されたサービスにアクセスしようとしたとき、そのユーザーが物理的に認証済みトークンを持っていれば認証プロセスは高い信頼性でユーザーを証明することができます。

「知っていること」としてよく使用されるのが暗号化デバイスのパスワードです。正しいパスワードが入力されなければ、秘密鍵にアクセスできません。暗号化デバイスの別の機能として、何度も間違ったパスワードが入力されたときに秘密鍵を使用できなくする、ということがあります。この機能により、もしユーザーがデバイスを紛失したとしても、他の人がそのデバイスを使用できなくすることができます。

暗号化デバイスは一般的にスマートカードやトークンと呼ばれ、PKI(公開鍵基盤)と組み合わせて使用されます。VPNサーバーはX.509証明書をチェックし、ユーザーが正しい秘密鍵を持っているかどうか検証することができます。デバイスの複製が不可能であり、さらに正しいパスワードも必要とすることで、サーバーはユーザー認証を高度なレベルで実現できることになります。

2ファクタ認証はパスワードベースの認証よりはるかに強力です。仮に最悪のケースを想定したとしても、暗号化トークンが使用できるのは一度に一人だけです。パスワードは他のユーザーによって推測されたり暴露されたりすることがあり得るため、パスワードのみの認証方式では、最悪の場合、非常に多くの人々が不正なアクセスを行う可能性があります。

秘密鍵をファイルとして保管する場合、通常、この鍵はパスワードによって暗号化されます。しかし、この方法の問題は、クライアント上でスパイウェアなどを利用したり、パスワードのアタックをかけることにより、暗号化された鍵が復号化されてしまう可能性があることです。暗号化デバイスを使用するときとは異なり、復号化に何回も失敗したときに鍵を自動的に消去する機能もありません。

PKCS#11とは?

この標準は、暗号化情報を保持したり暗号化機能を実行したりするデバイスのAPI(Cryptoki)を定義しています。Cryptokiは「cryptographic token interface」を短縮したもので、crypto-keyと発音しますが、シンプルなオブジェクトベースのアプローチに従い、特定の技術やデバイスに依存せず、リソースを共有化(複数のアプリケーションが複数のデバイスにアクセス可能)するという目標のもと、暗号化トークンのようなデバイスにアプリケーションがアクセスするための共通の論理ビューを提供します。

出典: RSA Security Inc. http://www.rsasecurity.com/rsalabs/pkcs/pkcs-11 (訳注:リンク切れ)

要約すると、PKCS#11はアプリケーションがスマートカードや他の暗号化トークンにアクセスするために使用される標準仕様です。デバイス開発元の多くはPKCS#11プロバイダインターフェイスを実装したライブラリを提供しており、このライブラリを使用してアプリケーションはデバイスにアクセスすることができます。PKCS#11はクロスプラットフォームであり、特定のベンダーに依存していません。

PKCS#11プロバイダライブラリを見つける

最初にしなければならないことは、デバイスドライバと共にインストールされているはずのプロバイダライブラリを探し出すことです。各ベンダーはそれぞれ独自のライブラリを提供しています。たとえば、OpenSC PKCS#11プロバイダであれば、Unixでは/usr/lib/pkcs11/opensc-pkcs11.so、Windowsではopensc- pkcs11.dllです。

暗号化トークンの設定方法

以下の登録手順に従ってください。

  • PKCS#11トークンを初期化する。
  • PKCS#11トークン上でRSA鍵ペアを生成する。
  • 生成された鍵ペアに基づいて証明書要求を作成する。証明書要求の作成にはOpenSCとOpenSSLを使用できます。
  • 証明書要求を認証機関に送り、作成された証明書を受け取る。
  • 証明書をトークンに読み込む。この際、証明書のIDやラベル属性は秘密鍵のIDやラベル属性とマッチする必要がある。

これらの設定が終わったトークンは、同じIDとラベル属性を持った秘密鍵と証明書を格納しているトークンとなります。

簡単な登録用ユーティリティとしてOpenVPN 2.1シリーズの一部であるEasy-RSA 2.0が用意されています。READMEファイルに書かれている手順に従い、その後pkitoolを使って登録してください。

トークンの初期化は以下のコマンドで行います。

$ ./pkitool --pkcs11-slots /usr/lib/pkcs11/<provider>
$ ./pkitool --pkcs11-init /usr/lib/pkcs11/<provider> <slot> <label>

証明書の登録は以下のコマンドで行います。

$ ./pkitool --pkcs11 /usr/lib/pkcs11/<provider> <slot> <label> client1

暗号化トークンを使用するようにOpenVPNを設定するには

PKCS#11の機能を使用するには、OpenVPN 2.1以降のバージョンである必要があります。最新のβ版をhttp://openvpn.net/download.htmlから入手できます。

正しいスロットを識別する

各PKCS#11プロバイダは複数のデバイスをサポートしており、スロットごとに1つのデバイスがあります。スロットの一覧を表示するには下記のコマンドを実行します。

$ openvpn --show-pkcs11-slots /usr/lib/pkcs11/<provider>
 Provider Information:
        cryptokiVersion: 2.11
        manufacturerID: ...
        flags: 0
The following slots are available for use with this provider.
Each slot shown below may be used as a parameter to a
--pkcs11-slot-type and --pkcs11-slot options.

Slots: (id - name)
0 - My reader 00 00
1 - My reader 01 00

このコマンドの出力から、特定のスロットを指定することができます。たとえば、pkcs11-slot-type idpkcs11-slot 1オプションや、2番目のスロットを選択するためにpkcs11-slot-type namepkcs-slot “My reader 01 00”のように使用します。また、トークン名でスロットを選択することもできます。たとえば、Token1があるスロットを指定するにはpkcs11-slot-type labelとpkcs11-slot “Token1”オプションを使用します。

正しいオブジェクトを識別する

各PKCS#11トークンには複数のオブジェクトが含まれています。各オブジェクトにはidlabelという特殊な2つの属性があります。トークンに何が含まれているのかを確認するには、次のコマンドを実行します。

$ openvpn --show-pkcs11-objects /usr/lib/pkcs11/<provider> <slot-id>
 PIN:
 Token Information:
         label:          Token1
         manufacturerID: ...
         model:          ...
         serialNumber:   0104524263233729
         flags:          0000040d
You can access this token using
pkcs11-slot-type "label" --pkcs11-slot "Token1" options.

The following objects are available for use with this token.
Each object shown below may be used as a parameter to
--pkcs11-id-type and --pkcs11-id options.

Object
Label: AUTH000-20050705B436961C5E5F6D2B
Id:
41 54 5f 4b 45 59 45 58 43 48 41 4e 47 45 1b ed
81 a2 96 62 24 c4 a8 0a f1 42 48 10 e6 5d 00
Type: Certificate
subject: /CN=User1
serialNumber: 2A5F4854000000000032
notBefore: 050705164745Z
Object
Label: AUTH000-20050705B436961C5E5F6D2B
Id:
41 54 5f 4b 45 59 45 58 43 48 41 4e 47 45 1b ed
81 a2 96 62 24 c4 a8 0a f1 42 48 10 e6 5d 00
Type: Private Key
Sign: TRUE
Sign Recover: TRUE

このオブジェクトへの参照は次のようになります。

  • Label(推奨):
    pkcs11-id-type label
    pkcs11-id "AUTH000-20050705B436961C5E5F6D2B"
  • Id:
    pkcs11-id-type id
    pkcs11-id "41 54 5f 4b 45 59 45 58 43 48 41 4e 47 45 1b ed
     81 a2 96 62 24 c4 a8 0a f1 42 48 10 e6 5d 00"
  • X.509証明書のSubject:
    pkcs11-id-type subject
    pkcs11-id "/CN=User1"

OpenVPNをPKCS#11と組み合わせて使用する

  • PKCS#11を使用するための典型的なOpenVPNオプション
    pkcs11-providers /usr/lib/pkcs11/<provider>
    pkcs11-slot-type label
    pkcs11-slot "Token1"
    pkcs11-id-type label
    pkcs11-id "AUTH000-20050705B436961C5E5F6D2B"

    この設定では、”Token1″が入っているスロットを選択し、ラベル”AUTH000-20050705B436961C5E5F6D2B”に基づいた証明書と秘密鍵を選択します。

  • PKCS#11を使用するための拡張されたOpenVPNオプション
    pkcs11-providers /usr/lib/pkcs11/provider1.so /usr/lib/pkcs11/provider2.so
    pkcs11-slot-type label
    pkcs11-slot "Token1"
    pkcs11-id-type label
    pkcs11-id "AUTH000-20050705B436961C5E5F6D2B"
    pkcs11-pin-cache 300
    daemon
    auth-retry nointeract
    management-hold
    management 127.0.0.1 8888
    management-query-passwords

    この設定ではOpenVPNに2つのプロバイダを読み込み、”Token1″が入っているスロットを検索し、ラベル”AUTH000-20050705B436961C5E5F6D2B”に基づいた証明書と秘密鍵を選択して、パスワードを問い合わせるために管理インターフェイスを使用します。トークンにアクセスできなかったときには、デーモンは保留状態に戻ります。トークンはパスワードを再問い合わせしてから300 秒間使用されます。

PKCS#11実装に関する考慮事項

多くのPKCS#11プロバイダはスレッドを使用していますが、LinuxThreads(setuid、chroot)の実装上の問題を避けるため、PKCS#11を使用する予定であればglibcを有効にしたNative POSIX Thread Library (NPTL)にアップグレードすることをお勧めします。

OpenSC PKCS#11プロバイダ

OpenSC PKCS#11プロバイダはUnixであれば/usr/lib/pkcs11/opensc-pkcs11.so、Windowsであればopensc-pkcs11.dllです。

OpenSC PKCS#11プロバイダは秘密鍵の属性を正しくレポートしないという問題があります。この問題を避けるにはpkcs11-sign-mode signオプションを指定してください。

PKCS#11と Microsoft Cryptographic API(CryptoAPI)の違い

PKCS#11はフリーで、ベンダーに依存せず、クロスプラットフォームな標準です。CryptoAPIはマイクロソフト特定のAPIです。多くのスマートカードベンダーは両方のインターフェイスをサポートしています。Windows環境ではユーザーはどちらのインターフェイスを使用するか選択しなければなりません。

MS CryptoAPI(cryptoapicertオプション)を使用したOpenVPNの現在の実装は、サービスとして実行させなければ問題なく動作します。管理された環境下でサービスとしてOpenVPNを実行させたい場合は、下記のような理由により多くのスマートカードが正しく動作しない可能性があります。

  • 大半のスマートカードプロバイダは証明書をローカルPC上にロードしません。そのため、この実装はユーザーの証明書にアクセスできません。
  • OpenVPNをエンドユーザーに対話させずにサービスとして動作させた場合、サービスはユーザーに対してスマートカードのパスワードを問い合わせることができません。そのため、スマートカードのパスワード検証プロセスに失敗します。

PKCS#11インターフェイスを使用すると、PKCS#11はMicrosoftストアにアクセスする必要がなく、エンドユーザーに問い合わせを行う必要もないので、任意の実装においてOpenVPNをスマートカードと組み合わせて使用できます。

クライアントのすべてのトラフィック(Webトラフィックを含む)をVPN経由にルーティングする

概要

OpenVPNが有効になっているとき、デフォルトではOpenVPNサーバーのネットワークとのやり取りのみVPN上での通信が行われます。通常のWebブラウジングなどは直接接続され、VPNを経由することはありません。

特定のケースにおいては、Webブラウジングなどを含むすべての通信をVPN経由で行いたいということがあります。この設定はクライアント上のパフォーマンスの低下は避けられませんが、VPN管理者にとってはクライアントが通常のインターネットとVPNに同時に接続する場合でもセキュリティポリシーの適用が行いやすくなります。

設定

サーバー設定ファイルに下記の設定を追加します。

push "redirect-gateway def1"

VPNが無線LANに接続されており、すべてのOpenVPNクライアントとOpenVPNサーバーも同じ無線LANのサブネット上にある場合は、localフラグを追加します。

push "redirect-gateway local def1"

redirect-gatewayをクライアントにプッシュすると、クライアントPCからのすべてのIPネットワークトラフィックがOpenVPNサーバーを経由するようになります。これにより、サーバーではトラフィックをどのように扱うか、たとえばインターネットにNATで接続させたり、サーバーのネットワーク上にあるHTTPプロキシに渡したりするなどの設定を行う必要があります。

Linuxの場合は、次のようなコマンドでVPNクライアントのトラフィックをインターネットにNATで接続させることができます。

iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE

このコマンド例では、VPNサブネットが10.8.0.0/24(OpenVPNサーバー設定のserverディレクティブによる)で、ローカルEthernetインターフェイスがeth0であることを想定しています。

redirect-gatewayディレクティブを使用すると、OpenVPNクライアントはDNS問い合わせもVPN経由で行うようになるため、VPNサーバーがDNS問い合わせも処理できるようにする必要があります。これは、VPNが接続しているときに使用できるDNSサーバーのアドレス情報をクライアントにプッシュすることによって行えます。

push "dhcp-option DNS 10.8.0.1"

これにより、Windowsクライアントの場合はDNSサーバーとして10.8.0.1を使用するようになります(Windows以外のクライアントの場合はサーバー側のスクリプトが必要です)。DNSサーバーのアドレスにはクライアントから接続できるアドレスを使用してください。

注意事項

すべてのネットワークトラフィックをVPN経由にすることは、問題になることもあり得ます。以下のような点に注意する必要があります。

  • インターネットに接続しているOpenVPNクライアントPCはたいてい、DHCPサーバーと定期的に通信を行ってIPアドレスのリースを更新します。しかし、redirect-gatewayオプションはクライアントがローカルDHCPサーバーに接続できないようにしてしまう(DHCPメッセージがVPN上を通ってしまうため)ので、IPアドレスのリースを失うことになります。
  • WindowsクライアントにDNSアドレスをプッシュするときに問題が発生する可能性があります。
  • クライアントでのWebブラウジングは相当遅くなります。

redirect-gatewayディレクティブの仕組みについては、こちらを参照してください。

動的IPアドレスでのOpenVPNサーバーの運用

OpenVPNクライアントは動的IPアドレスでも特別な設定なしでサーバーに接続できます。また、サーバー自身が動的アドレスであっても問題ありません。 OpenVPNはいくつかの追加設定を行えば、動的IPアドレスでのサーバーでも問題なく動作します。

まず最初に必要なステップは、サーバーのIPアドレスが変わるたびにIPアドレスを更新できる、ダイナミックDNSのアドレスを取得することです。 dyndns.orgなど、いくつかのダイナミックDNSサービスが提供されています。

次に、サーバーのIPアドレスが変わるたびにDNSを更新するようセットアップすることです。これによって、クライアントはサーバーのIPアドレスが変わっても接続先を特定できます。これには2つの方法があります。

クライアント設定ファイルでremoteディレクティブを使ってダイナミックDNS名を設定すると、デフォルトでOpenVPNクライアントはサーバーのIPアドレスの変更を検知します。この動作の流れとしては (a) OpenVPNクライアントが古いIPアドレスからのキープアライブメッセージの受信に失敗して再起動が行われ、(b) 再起動時にremoteディレクティブで指定されたアドレスが再度解決され、新しいIPアドレスに接続できるようになります。

動的IPアドレスについてはFAQも参照してください。

HTTPプロキシ経由でのOpenVPNサーバーへの接続

OpenVPNはHTTPプロキシ経由での接続をサポートしており、次の認証モードが使用可能です。

  • プロキシ認証なし
  • 基本プロキシ認証
  • NTLMプロキシ認証

HTTPプロキシを利用するには、トンネルキャリアプロトコルとしてTCPを使用していなければなりません。サーバーとクライアントの設定ファイルで次のように記述されている必要があります。

proto tcp

proto udpの記述は削除してください。
次に、クライアント設定ファイルにhttp-proxyディレクティブを追加します(このディレクティブに関する詳細はman pageを参照してください)。
たとえば、クライアントLAN上にHTTPプロキシサーバーが存在しており、そのプロキシのアドレスが192.168.4.1で、ポート1080でリッスンしているとします。このプロキシを利用するには、クライアント設定で下記の記述を追加します。

http-proxy 192.168.4.1 1080

HTTPプロキシで基本認証が必要な場合は次のようにします。

http-proxy 192.168.4.1 1080 stdin basic

HTTPプロキシでNTLM認証が必要な場合は次のようにします。

http-proxy 192.168.4.1 1080 stdin ntlm

この2つの認証方法の例では、OpenVPNはユーザー名とパスワードを標準入力から読み込みます。もしファイルから読み込ませたい場合にはstdinをファイル名に置き換え、そのファイルの1行目にユーザー名を、2行目にパスワードを記述してください。

OpenVPN経由でSamba共有に接続する

このサンプルでは、ルーティングでのdev tunトンネルを経由してOpenVPNクライアントがSamba共有に接続する方法を説明します。ブリッジを使用している場合(dev tap)はOpenVPNクライアントがサーバー側ネットワークにあるPCを参照できるため、下記の手順は必要ありません。
今回の例では、以下のような状況を想定します。

  • サーバー側LANはサブネット10.66.0.0/24を使用します。
  • VPNのIPアドレス範囲は10.8.0.0/24を使用します(OpenVPNサーバー設定ファイルのserverディレクティブで設定します)。
  • SambaサーバーのIPアドレスは10.66.0.4を使用します。
  • Sambaサーバーは既にローカルLANからアクセスできるよう設定されています。

SambaとOpenVPNサーバーが別のPCで動作している場合は、「クライアント側、またはサーバー側サブネットへのクライアントPCの追加によるVPNの拡張」で説明された手順を確認してください。

次に、Samba設定ファイル(smb.conf)を編集します。hosts allowディレクティブにおいて、10.8.0.0/24サブネットから接続してくるOpenVPNクライアントが接続できるよう許可してください。次のように設定します。

hosts allow = 10.66.0.0/24 10.8.0.0/24 127.0.0.1

SambaとOpenVPNサーバーが同一PC上で動作している場合は、smb.confファイルのinterfacesディレクティブを編集し、10.8.0.0/24のサブネットのTUNインターフェイスもリッスンするようにします。

interfaces  = 10.66.0.0/24 10.8.0.0/24

SambaとOpenVPNサーバーが同一PC上で動作している場合は、OpenVPNクライアントからSamba共有にフォルダ名を使って接続します。

\\10.8.0.1\\sharename

SambaとOpenVPNサーバーが別々のPCで動作している場合は、次のように接続します。

\\10.66.0.4\sharename

たとえば、コマンドプロンプトで次のように入力します。

net use z: \\10.66.0.4\sharename /USER:myusername

ロードバランス/フェールオーバー構成

クライアント

OpenVPNクライアントは複数のサーバーを参照するように設定することができます。これにより、ロードバランシングやフェールオーバーが実現できます。

remote server1.mydomain
remote server2.mydomain
remote server3.mydomain

このように設定すると、OpenVPNはServer1、Server2、Server3の順番に接続しようとしますが、既存の接続が切断された場合、OpenVPNクライアントは直前まで接続していたサーバーに再接続しようとします。接続できなかった場合、リストの次のサーバーに接続しようとします。また、リスト上にあるサーバーに対してランダムに接続するよう設定することもできます。これによって結果的に各サーバーの負荷が分散しやすくなります。

remote-random

さらに、OpenVPNクライアントがDNS参照に失敗したときに次のサーバーに接続させるようにするには、以下のようにします。

resolv-retry 60

この「60」という値は、リストの次のサーバーに移る前にOpenVPNクライアントがremoteで定義されている各サーバーのDNS参照を60秒間試行するよう設定するものです。
このサーバーリストは、1台のサーバー上で稼動している複数のOpenVPNサーバーデーモンを参照するように設定することもできます。これらのデーモンはそれぞれ別個のポートを使用しています。

remote smp-server1.mydomain 8000
remote smp-server1.mydomain 8001
remote smp-server2.mydomain 8000
remote smp-server2.mydomain 8001

サーバーがマルチプロセッサのPCを使用している場合、複数のOpenVPNデーモンを実行する際のパフォーマンスの向上が期待できます。
また、OpenVPNはremoteディレクティブにおいて、複数のAレコードが設定されたDNS名を参照するように設定することもできます。この場合、OpenVPNクライアントはDNS参照時に”A”レコードのいずれか1つをランダムに選択して接続することになります。

サーバー

ロードバランシング/フェールオーバーを実現する最も簡単な方法は、クラスタ内の各サーバーで同一の設定ファイル(仮想IPアドレス範囲だけはそれぞれ別個に設定します)を使用することです。

server1

server 10.8.0.0 255.255.255.0

server2

server 10.8.1.0 255.255.255.0

server3

server 10.8.2.0 255.255.255.0

OpenVPNのセキュリティを強化する

ネットワークセキュリティの鉄則の1つは、「ひとつのセキュリティコンポーネントに決して大きな信頼を置かない」ということです。1つに大きく依存してしまうと、セキュリティに壊滅的な損害を与える可能性があるためです。OpenVPNではこのような問題に対応するため、セキュリティレイヤーを追加するためのいくつかの方法を提供しています。

tls-auth

tls-authディレクティブを指定すると、整合性の検証を行うためのすべてのSSL/TLSハンドシェイクパケットにHMAC署名が追加されます。正しいHMAC署名を有していないUDPパケットは、その後の処理は行われずに破棄されます。 tls-auth HMAC署名はSSL/TLSによって提供されるセキュリティに加えてさらに高度なセキュリティを提供し、次のような攻撃や問題に対処できます。

  • OpenVPN UDPポートに対するDoSアタックなどの攻撃
  • リッスン中のサーバーのUTPポートを特定するためのポートスキャン
  • SSL/TLS実装上のバッファオーバーフローの脆弱性
  • 認証されていないマシンからのSSL/TLSハンドシェイクの開始(いずれにしても最終的には認証に失敗することになりますが、tls-authを使えばさらに前のポイントで切り捨てることができます)

tls-authを使用する場合は、標準のRSA証明書と鍵に加えて、共有静的鍵を生成しておく必要があります。

openvpn --genkey --secret ta.key

このコマンドを実行するとOpenVPNの静的鍵が生成され、ファイルta.keyに書き込まれます。この鍵ファイルをサーバーとすべてのクライアントにコピーしておく必要があります(安全な方法でコピーするように注意してください)。このファイルはRSAの.key.crtファイルのあるディレクトリに入れておきます。
サーバー設定ファイルに以下の行を追加します。

tls-auth ta.key 0

クライアント設定ファイルに以下の行を追加します。

tls-auth ta.key 1

proto udp

OpenVPNでは、VPNキャリアプロトコルとしてTCPかUDPのいずれかのプロトコルを使用することができますが、UDPプロトコルのほうがDoSアタックやポートスキャニングに対して強力です。

proto udp

非特権モード(Linuxのみ)

Linux上では、OpenVPNを非特権モード内で動作させることができます。設定はやや複雑になりますが、最良のセキュリティが提供されます。

この構成で動作させるには、設定スクリプトで –enable-iproute2 を指定し、OpenVPNでiprouteインターフェイスを使用するように設定する必要があります。また、システム上でsudoパッケージが利用可能になっている必要もあります。

この構成では、Linuxの機能を使用してtunデバイスのパーミッションを変更し、非特権ユーザーがアクセスできるようにします。また、インターフェイス設定とルーティングテーブルを変更するため、sudoを使ってiprouteを実行します。

以下のように設定します。

  • 以下のスクリプトを/usr/local/sbin/unpriv-ipとして保存します。
    #!/bin/sh
    sudo /sbin/ip $*
  • visudoを使用して、ユーザー’user1’が/sbin/ipを実行できるように以下の行を追記します。
    user1 ALL=(ALL)  NOPASSWD: /sbin/ip

    以下のコマンドでユーザーのグループに割り当てることも可能です。

    %users ALL=(ALL)  NOPASSWD: /sbin/ip
  • OpenVPNの設定ファイルに以下の記述を追記します。
    dev tunX/tapX
    iproute /usr/local/sbin/unpriv-ip

    Xに適切な値を設定し、tunかtapのいずれかを指定してください。

  • インターフェイスを追加し、指定したユーザー/グループが管理できるようにするため、以下のコマンドでtunX(Xに適切な値を設定してください)インターフェイスを作成します。
    openvpn --mktun --dev tunX --type tun --user user1 --group users
  • OpenVPNを非特権ユーザーのコンテキストで実行します。

/usr/local/sbin/unpriv-ipスクリプトのパラメータ設定により、さらにセキュリティを高めることができます。

user/group (Windows以外の場合)

OpenVPNはインストール後、ルート権限をドロップさせてもきちんと動作するように設計されており、Linux/BSD/Solarisではこの機能を利用することをお勧めします。OpenVPNサーバーデーモンをルート権限なしで動作させると、外部からの攻撃に対して強化されます。

user nobody
group nobody

chroot (Windows以外の場合)

chrootディレクティブを使用すると、OpenVPNデーモンをchroot jailにロックさせることができます。これにより、OpenVPNデーモンはパラメータで指定された特定のディレクトリ以外のディレクトリにアクセスできなくなります。たとえば、次のように設定したとします。

chroot jail

この設定により、OpenVPNデーモンは初期化時にjailディレクトリに移動し、このディレクトリをルートディレクトリとして扱います。これにより、OpenVPNデーモンはjailディレクトリとそのサブディレクトリ以外のファイルにアクセスできなくなります。これにより、たとえ攻撃を受けたとしてもサーバーのファイルシステムを保護することができます。

[注] chrootを利用する場合には、OpenVPNが初期化後に使用するすべてのファイルをjailディレクトリに配置しておく必要があります。たとえば、下記のようなファイルです。
crl-verifyファイル
client-config-dirディレクトリ

RSA鍵のサイズを大きくする

RSA鍵サイズはeasy-rsa/varsファイルのKEY_SIZE変数で制御されており、すべての鍵を生成する前に設定しておく必要があります。デフォルトでは1024に設定されていますが、この値は2048まで増加させることができます。値を大きくしてもVPNトンネルのパフォーマンスそのものに悪影響はありませんが、各クライアントが1時間おきに実行するSSL/TLSの再ネゴシエーションにかかる時間が若干増えます。また、初期設定時に一度だけ行うeasy-rsa/build-dhスクリプトを使ったDiffie Hellmanパラメータの生成に時間がかかるようになります。

対称鍵を大きくする

デフォルトではOpenVPNは128ビットの鍵を使用したBlowfishを使用します。
OpenVPNはOpenSSLライブラリがサポートする任意の暗号化方式を自動的にサポートしており、鍵サイズを大きくすることも可能です。たとえば、256ビットのAES (Advanced Encryption Standard) を使用するには、サーバーとクライアントの設定ファイルで下記の記述を追加します。

cipher AES-256-CBC

ルート鍵(ca.key)をネットワークから切り離されたPC上に確保する

X509 PKI を使用するメリットの1つは、ルートCA鍵(ca.key)をOpenVPNサーバー上に置いておく必要がないことです。高いセキュリティが必要な環境では、鍵の署名のための専用PCを用意しておき、そのPCを物理的に安全な場所に設置し、ネットワークから切り離しておきます。鍵ファイルの移動にはフロッピーディスクなどが使用できるでしょう。これにより攻撃者がルート鍵を盗むことは(物理的にそのPCにアクセスできなければ)非常に困難になります。

証明書の失効

証明書の失効」とは、以前署名した証明書を無効にし、認証できなくすることです。

下記のような場合に、証明書を失効させることがあります。

  • 証明書に関連付けられた秘密鍵が漏洩されたか、盗まれた場合
  • 暗号化された秘密鍵のパスワードをユーザーが忘れてしまった場合
  • VPNユーザーのアクセスを終了させたい場合

この例では、このHOWTOの中で生成したclient2証明書を失効させます。
シェルかコマンドプロンプトを開き、キーの生成時に使用したeasy-rsaディレクトリに入ります。その後、Linux/BSD/Unixの場合は次のようにします。

. ./vars
./revoke-full client2

Windowsの場合は次のようにします。

vars
revoke-full client2

すると、次のようなメッセージが表示されます。

Using configuration from /root/openvpn/20/openvpn/tmp/easy-rsa/openssl.cnf
DEBUG[load_index]: unique_subject = "yes"
Revoking Certificate 04.
Data Base Updated
Using configuration from /root/openvpn/20/openvpn/tmp/easy-rsa/openssl.cnf
DEBUG[load_index]: unique_subject = "yes"
client2.crt: [email protected]main
error 23 at 0 depth lookup:certificate revoked

最後の”error 23″が気になるかもしれませんが、このメッセージは問題ありません。これは、失効させた証明書の検証に失敗したということを示しているからです。
revoke-fullスクリプトはkeysサブディレクトリ内にcrl.pemというCRL(証明書失効リスト)ファイルを生成します。このファイルをOpenVPNサーバーがアクセスできる場所にコピーし、サーバー設定ファイルで下記の記述を加えることによりCRLによる検証を有効化します。

crl-verify crl.pem

これにより、すべての接続クライアントはCRLによって検証され、CRLにマッチした接続はドロップされることになります。

CRLに関する注意事項

  • OpenVPNでcrl-verifyオプションを使用すると、新規クライアントの接続時、また既存のSSL/TLS接続の再ネゴシエーション時(デフォルトでは1時間おき)にCRLファイルを再度読み込みます。このため、OpenVPNサーバーデーモンの実行中であってもCRLファイルの書き換えが可能で、書き換えた結果は新しいクライアントの接続から即時に反映されます。失効させた証明書が既に接続済みのクライアントのものの場合は、サーバーにシグナル(SIGUSR1かSIGHUP)を送って再起動させる(すべてのクライアント接続が切断されます)か、管理インターフェイスを使ってTELNETで接続し、失効したクライアントのインスタンスを切断します。
  • crl-verifyディレクティブはサーバーとクライアントのどちらででも使用できますが、通常の場合、サーバー証明書が失効されたのではない限りCRLファイルをクライアントに配布する必要はありません。
  • CRLファイルは秘密にはなりません。OpenVPNデーモンがルート権限をドロップされても読み取ることができるようにしておく必要があります。
  • chrootディレクティブを使用している場合は、CRLファイルをchrootディレクトリにコピーしておいてください。OpenVPNが読み込む他のファイルとは異なり、CRLファイルはchroot呼び出しが実行された後に読み込まれます。
  • 証明書を失効させる理由の1つが、ユーザーが秘密鍵のパスワードを忘れてしまった場合です。元の証明書を失効させると、元の証明書と同じ共通名で新しい証明書と鍵のペアを生成することができます。

クライアントが接続先のサーバー証明書を検証しない場合に発生する可能性のある「Man-in-the-Middle」攻撃について

認証済みのクライアントがサーバーを偽装して他のクライアントに接続しようとする「Man-in-the-Middle」攻撃の可能性を回避するために、各クライアントにサーバー証明書を強制的に検証させることができます。これを実現するには下記の5つの方法があります(優先順)。

  • [OpenVPN 2.1以降] 特定の鍵用途(Key usage)および拡張鍵用途(Extended key usage)を指定してサーバー証明書を生成します。RFC3280では、TLS接続において下記の属性が提供されるべきとしています。
    モード鍵用途(Key usage)拡張鍵用途(Extended key usage)
    クライアントdigitalSignatureTLS Web Client Authentication
    keyAgreement
    digitalSignature, keyAgreement
    サーバーdigitalSignature, keyEnciphermentTLS Web Server Authentication
    digitalSignature, keyAgreement

    サーバー証明書はbuild-key-serverスクリプトを使って生成できます(詳細についてはeasy-rsaを参照してください)。このスクリプトを使用して証明書を作成すると、適切な属性がセットされたサーバー専用証明書として作成されます。クライアントの設定ファイルに下記の設定を加えます。

    remote-cert-tls server
  • [OpenVPN 2.0以前] build-key-serverスクリプトを使ってサーバー証明書を生成します(詳細についてはeasy-rsaを参照してください)。このスクリプトを使用して証明書を作成すると、nsCertType=serverとして設定されたサーバー専用証明書として作成されます。クライアントの設定ファイルに下記の設定を加えます。
    ns-cert-type server

    これにより、OpenVPN設定ファイルで設定されたcaファイルで署名されていたとしても、nsCertType=serverとして生成されていない証明書を持つサーバーへの接続が拒否されます。

  • クライアントでtls-remoteディレクティブを使用することにより、サーバー証明書の共通名に基づいてサーバー接続を許可/拒否を制御できます。
  • tls-verifyスクリプトかプラグインを使用して、サーバー証明書に埋め込まれたX509サブジェクトを独自の方法で検査した結果によって、サーバー接続を許可/拒否を制御できます。
  • サーバー証明書とクライアント証明書を別々のCAを使って署名します。クライアント設定のcaディレクティブにはサーバー証明書を署名したCAファイル、サーバー設定のcaディレクティブにはクライアント証明書を署名したCAファイルを設定します。

サンプル設定ファイル

sample-config-files/server.conf

#################################################
# Sample OpenVPN 2.0 config file for            #
# multi-client server.                          #
#                                               #
# This file is for the server side              #
# of a many-clients <-> one-server              #
# OpenVPN configuration.                        #
#                                               #
# OpenVPN also supports                         #
# single-machine <-> single-machine             #
# configurations (See the Examples page         #
# on the web site for more info).               #
#                                               #
# This config should work on Windows            #
# or Linux/BSD systems.  Remember on            #
# Windows to quote pathnames and use            #
# double backslashes, e.g.:                     #
# "C:\\Program Files\\OpenVPN\\config\\foo.key" #
#                                               #
# Comments are preceded with '#' or ';'         #
#################################################
# Which local IP address should OpenVPN
# listen on? (optional)
;local a.b.c.d

# Which TCP/UDP port should OpenVPN listen on?
# If you want to run multiple OpenVPN instances
# on the same machine, use a different port
# number for each one. You will need to
# open up this port on your firewall.
port 1194

# TCP or UDP server?
;proto tcp
proto udp

# "dev tun" will create a routed IP tunnel,
# "dev tap" will create an ethernet tunnel.
# Use "dev tap0" if you are ethernet bridging
# and have precreated a tap0 virtual interface
# and bridged it with your ethernet interface.
# If you want to control access policies
# over the VPN, you must create firewall
# rules for the the TUN/TAP interface.
# On non-Windows systems, you can give
# an explicit unit number, such as tun0.
# On Windows, use "dev-node" for this.
# On most systems, the VPN will not function
# unless you partially or fully disable
# the firewall for the TUN/TAP interface.
;dev tap
dev tun

# Windows needs the TAP-Win32 adapter name
# from the Network Connections panel if you
# have more than one. On XP SP2 or higher,
# you may need to selectively disable the
# Windows firewall for the TAP adapter.
# Non-Windows systems usually don't need this.
;dev-node MyTap

# SSL/TLS root certificate (ca), certificate
# (cert), and private key (key). Each client
# and the server must have their own cert and
# key file. The server and all clients will
# use the same ca file.
#
# See the "easy-rsa" directory for a series
# of scripts for generating RSA certificates
# and private keys. Remember to use
# a unique Common Name for the server
# and each of the client certificates.
#
# Any X509 key management system can be used.
# OpenVPN can also use a PKCS #12 formatted key file
# (see "pkcs12" directive in man page).
ca ca.crt
cert server.crt
key server.key # This file should be kept secret

# Diffie hellman parameters.
# Generate your own with:
# openssl dhparam -out dh1024.pem 1024
# Substitute 2048 for 1024 if you are using
# 2048 bit keys.
dh dh1024.pem

# Configure server mode and supply a VPN subnet
# for OpenVPN to draw client addresses from.
# The server will take 10.8.0.1 for itself,
# the rest will be made available to clients.
# Each client will be able to reach the server
# on 10.8.0.1. Comment this line out if you are
# ethernet bridging. See the man page for more info.
server 10.8.0.0 255.255.255.0

# Maintain a record of client <-> virtual IP address
# associations in this file. If OpenVPN goes down or
# is restarted, reconnecting clients can be assigned
# the same virtual IP address from the pool that was
# previously assigned.
ifconfig-pool-persist ipp.txt

# Configure server mode for ethernet bridging.
# You must first use your OS's bridging capability
# to bridge the TAP interface with the ethernet
# NIC interface. Then you must manually set the
# IP/netmask on the bridge interface, here we
# assume 10.8.0.4/255.255.255.0. Finally we
# must set aside an IP range in this subnet
# (start=10.8.0.50 end=10.8.0.100) to allocate
# to connecting clients. Leave this line commented
# out unless you are ethernet bridging.
;server-bridge 10.8.0.4 255.255.255.0 10.8.0.50 10.8.0.100

# Push routes to the client to allow it
# to reach other private subnets behind
# the server. Remember that these
# private subnets will also need
# to know to route the OpenVPN client
# address pool (10.8.0.0/255.255.255.0)
# back to the OpenVPN server.
;push "route 192.168.10.0 255.255.255.0"
;push "route 192.168.20.0 255.255.255.0"

# To assign specific IP addresses to specific
# clients or if a connecting client has a private
# subnet behind it that should also have VPN access,
# use the subdirectory "ccd" for client-specific
# configuration files (see man page for more info).

# EXAMPLE: Suppose the client
# having the certificate common name "Thelonious"
# also has a small subnet behind his connecting
# machine, such as 192.168.40.128/255.255.255.248.
# First, uncomment out these lines:
;client-config-dir ccd
;route 192.168.40.128 255.255.255.248
# Then create a file ccd/Thelonious with this line:
# iroute 192.168.40.128 255.255.255.248
# This will allow Thelonious' private subnet to
# access the VPN. This example will only work
# if you are routing, not bridging, i.e. you are
# using "dev tun" and "server" directives.

# EXAMPLE: Suppose you want to give
# Thelonious a fixed VPN IP address of 10.9.0.1.
# First uncomment out these lines:
;client-config-dir ccd
;route 10.9.0.0 255.255.255.252
# Then add this line to ccd/Thelonious:
# ifconfig-push 10.9.0.1 10.9.0.2

# Suppose that you want to enable different
# firewall access policies for different groups
# of clients. There are two methods:
# (1) Run multiple OpenVPN daemons, one for each
# group, and firewall the TUN/TAP interface
# for each group/daemon appropriately.
# (2) (Advanced) Create a script to dynamically
# modify the firewall in response to access
# from different clients. See man
# page for more info on learn-address script.
;learn-address ./script

# If enabled, this directive will configure
# all clients to redirect their default
# network gateway through the VPN, causing
# all IP traffic such as web browsing and
# and DNS lookups to go through the VPN
# (The OpenVPN server machine may need to NAT
# the TUN/TAP interface to the internet in
# order for this to work properly).
# CAVEAT: May break client's network config if
# client's local DHCP server packets get routed
# through the tunnel. Solution: make sure
# client's local DHCP server is reachable via
# a more specific route than the default route
# of 0.0.0.0/0.0.0.0.
;push "redirect-gateway"

# Certain Windows-specific network settings
# can be pushed to clients, such as DNS
# or WINS server addresses. CAVEAT:
# <a href="http://openvpn.net/faq.html#dhcpcaveats"
# mce_href="http://openvpn.net/faq.html#dhcpcaveats">http://openvpn.net/faq.html#dhcpcaveats</a>

;push "dhcp-option DNS 10.8.0.1"
;push "dhcp-option WINS 10.8.0.1"

# Uncomment this directive to allow different
# clients to be able to "see" each other.
# By default, clients will only see the server.
# To force clients to only see the server, you
# will also need to appropriately firewall the
# server's TUN/TAP interface.
;client-to-client

# Uncomment this directive if multiple clients
# might connect with the same certificate/key
# files or common names. This is recommended
# only for testing purposes. For production use,
# each client should have its own certificate/key
# pair.
#
# IF YOU HAVE NOT GENERATED INDIVIDUAL
# CERTIFICATE/KEY PAIRS FOR EACH CLIENT,
# EACH HAVING ITS OWN UNIQUE "COMMON NAME",
# UNCOMMENT THIS LINE OUT.
;duplicate-cn

# The keepalive directive causes ping-like
# messages to be sent back and forth over
# the link so that each side knows when
# the other side has gone down.
# Ping every 10 seconds, assume that remote
# peer is down if no ping received during
# a 120 second time period.
keepalive 10 120

# For extra security beyond that provided
# by SSL/TLS, create an "HMAC firewall"
# to help block DoS attacks and UDP port flooding.
#
# Generate with:
# openvpn --genkey --secret ta.key
#
# The server and each client must have
# a copy of this key.
# The second parameter should be '0'
# on the server and '1' on the clients.
;tls-auth ta.key 0 # This file is secret

# Select a cryptographic cipher.
# This config item must be copied to
# the client config file as well.
;cipher BF-CBC # Blowfish (default)
;cipher AES-128-CBC # AES
;cipher DES-EDE3-CBC # Triple-DES

# Enable compression on the VPN link.
# If you enable it here, you must also
# enable it in the client config file.
comp-lzo

# The maximum number of concurrently connected
# clients we want to allow.
;max-clients 100

# It's a good idea to reduce the OpenVPN
# daemon's privileges after initialization.
#
# You can uncomment this out on
# non-Windows systems.
;user nobody
;group nobody

# The persist options will try to avoid
# accessing certain resources on restart
# that may no longer be accessible because
# of the privilege downgrade.
persist-key
persist-tun

# Output a short status file showing
# current connections, truncated
# and rewritten every minute.
status openvpn-status.log

# By default, log messages will go to the syslog (or
# on Windows, if running as a service, they will go to
# the "\Program Files\OpenVPN\log" directory).
# Use log or log-append to override this default.
# "log" will truncate the log file on OpenVPN startup,
# while "log-append" will append to it. Use one
# or the other (but not both).
;log openvpn.log
;log-append openvpn.log

# Set the appropriate level of log
# file verbosity.
#
# 0 is silent, except for fatal errors
# 4 is reasonable for general usage
# 5 and 6 can help to debug connection problems
# 9 is extremely verbose
verb 3

# Silence repeating messages. At most 20
# sequential messages of the same message
# category will be output to the log.
;mute 20

sample-config-files/client.conf

##############################################
# Sample client-side OpenVPN 2.0 config file #
# for connecting to multi-client server.     #
#                                            #
# This configuration can be used by multiple #
# clients, however each client should have   #
# its own cert and key files.                #
#                                            #
# On Windows, you might want to rename this  #
# file so it has a .ovpn extension           #
##############################################
# Specify that we are a client and that we
# will be pulling certain config file directives
# from the server.
client

# Use the same setting as you are using on
# the server.
# On most systems, the VPN will not function
# unless you partially or fully disable
# the firewall for the TUN/TAP interface.
;dev tap
dev tun

# Windows needs the TAP-Win32 adapter name
# from the Network Connections panel
# if you have more than one. On XP SP2,
# you may need to disable the firewall
# for the TAP adapter.
;dev-node MyTap

# Are we connecting to a TCP or
# UDP server? Use the same setting as
# on the server.
;proto tcp
proto udp

# The hostname/IP and port of the server.
# You can have multiple remote entries
# to load balance between the servers.
remote my-server-1 1194
;remote my-server-2 1194

# Choose a random host from the remote
# list for load-balancing. Otherwise
# try hosts in the order specified.
;remote-random

# Keep trying indefinitely to resolve the
# host name of the OpenVPN server. Very useful
# on machines which are not permanently connected
# to the internet such as laptops.
resolv-retry infinite

# Most clients don't need to bind to
# a specific local port number.
nobind

# Downgrade privileges after initialization (non-Windows only)
;user nobody
;group nobody

# Try to preserve some state across restarts.
persist-key
persist-tun

# If you are connecting through an
# HTTP proxy to reach the actual OpenVPN
# server, put the proxy server/IP and
# port number here. See the man page
# if your proxy server requires
# authentication.
;http-proxy-retry # retry on connection failures
;http-proxy [proxy server] [proxy port #]

# Wireless networks often produce a lot
# of duplicate packets. Set this flag
# to silence duplicate packet warnings.
;mute-replay-warnings

# SSL/TLS parms.
# See the server config file for more
# description. It's best to use
# a separate .crt/.key file pair
# for each client. A single ca
# file can be used for all clients.
ca ca.crt
cert client.crt
key client.key

# Verify server certificate by checking
# that the certicate has the nsCertType
# field set to "server". This is an
# important precaution to protect against
# a potential attack discussed here:
# http://openvpn.net/howto.html#mitm
#
# To use this feature, you will need to generate
# your server certificates with the nsCertType
# field set to "server". The build-key-server
# script in the easy-rsa folder will do this.
;ns-cert-type server

# If a tls-auth key is used on the server
# then every client must also have the key.
;tls-auth ta.key 1

# Select a cryptographic cipher.
# If the cipher option is used on the server
# then you must also specify it here.
;cipher x

# Enable compression on the VPN link.
# Don't enable this unless it is also
# enabled in the server config file.
comp-lzo

# Set log file verbosity.
verb 3

# Silence repeating messages
;mute 20