UTF-8 Encoding, 2005-07-09 -- 08-05, 趙 亮, 宇都宮大学工学部
公式URI http://freescitech.net/2/ovpn2_howto_ja.html
OpenVPNはフル機能のSSL VPNであり,以下の機能を実装している:業界標準のSSL/TLSプロトコルを利用するOSI第2・第3層のセキュアネットワーク拡張,証明書やスマートカードやユーザ・パスワード等による柔軟なクライアント認証,VPN仮想インタフェースに対しファイアウォールによるユーザ・グループベースのアクセス制御.なお,OpenVPNがWebアプリケーションのプロキシではない.ブラウザを使って設定することはない.
OpenVPN 2.0が以下の点でOpenVPN 1.xの機能を拡張している:スケーラブルなクライアント・サーバモード,複数クライアントが単一TCP/UDPポートを使って同じOpenVPNサーバプロセスに接続できること.
この文章がOpenVPN 2.0クライアント・サーバVPNを構築するための設定方法を段階的に紹介する.内容は以下の通り.
性急な人はすぐサンプル設定ファイルの例へジャンプしたいかもしれないねー
このHOWTOは読者が以下のような基本的なネットワーク概念を知っていると仮定する:IPアドレス,DNS名,ネットマスク,サブネット,IPルーティング,ルータ,ネットワークインタフェース,LAN,ゲートウェイ,ファイアウォール(のルール).
これらの基本概念を理解していないがOpenVPNを使いたい人には,専門家に相談することをお薦めする.多くの文献の著者でもいいし,直接OpenVPNの作者達に連絡をとることも大丈夫(info@openvpn.net).
旧OpenVPN 1.x HOWTOがまだ入手できるようになっている.これはポイントツーポイント接続と静的鍵(事前共用鍵)の設定等,特に関係している.
その他の文書について,文献ページを参照するといい.
このHOWTOはX509 PKI(証明書と秘密鍵を用いる公開鍵基盤)を用いてスケーラブルなクライアント/サーバVPNを構築することを解説する.しかしこれがクライアント一つとサーバ一つのような簡単なVPNには複雑すぎるかもしれない.
そのように素早く最小限な設定でVPNを構築したいなら,静的鍵Mini-HOWTOを参照する.
OpenVPNはここからダウンロードできる.
安全のため,ダウンロードしたらファイルリリースの署名をチェックする.
OpenVPNの実行ファイルをサーバマシンとクライアントマシンにインストールする.この実行ファイルはサーバ機能もクライアント機能も提供する.
お使いのLinuxディストリビューションがRPMパッケージをサポートするなら(SuSE, Fedora, Redhatなど),それを使うのが一番いい.最も簡単な方法は,既存の(対応)バイナリRPMを使うことであるが,自分でビルドすることも可能:
rpmbuild -tb openvpn-[version].tar.gz
.rpmファイルをビルドできたら,いつものように以下のコマンドでインストールする.
rpm -ivh openvpn-[details].rpm
またはアップグレードする.
rpm -Uvh openvpn-[details].rpm
なおバイナリRPMからOpenVPNをインストールするには以下の依存パッケージも必要となる.
また,自分でバイナリRPMパッケージをビルドするための依存パッケージ:
Red Hat Linux 9,あるいはより少い依存関係でRPMパッケージをビルドしたい場合,ファイルopenvpn.specを参照すること.
Debian, Gentoo, またはその他RPMベースではないLinuxディストリビューションを使っているなら,適切な方法,例えばDebianならapt-get,Gentooならemergeを使うとよいであろう.
あるいは一般的な ./configure でLinuxにOpenVPNをインストールすることもできる.そのためには,まず.tar.gzファイルを展開する.
tar xfz openvpn-[version].tar.gz
それからトップディレクトリにcdして以下を入力する.
./configure make make install
Windows版OpenVPNについては,Windows 2000以後が必要であるが,ダウンロードページからインストーラ附きのexeファイルを取ってきて実行するとよい.ただし,OpenVPNのインストールも実行も,管理者権限が必要となる(これはOpenVPNではなくWindowsの制約である).この制約がOpenVPNをサービスとしてバックグラウンドで実行させることにより回避できる.その場合,VPNが成立すると,管理者でないユーザでも利用できるようになる.もっと詳しく読む:OpenVPN + Windowsにおける権限問題について.
OpenVPNをWindows GUIとしてインストールすることができる.Mathias Sundmanのパッケージを利用すると,OpenVPNと一緒にWindows GUIプログラムもインストールされる.
Windowsインストーラを実行したら,OpenVPNが使えるようになる.さらに拡張子.ovpnのファイルに関連を付けられる.OpenVPNを実行するためには:
OpenVPN設定ファイル(.ovpn)を右クリックし,Start OpenVPN on this configuration file("この設定でOpenVPNを起動させる")を選択する.実行中はキーF4で終了する.
コマンドプロンプトから以下のようなコマンドを実行する:
openvpn myconfig.ovpn
コマンドプロンプトで実行中にキーF4でOpenVPNを止めることができる.
サービスとしてOpenVPNを実行させるには,.ovpn設定ファイル(複数可)を\Program Files\OpenVPN\configフォルダにおいておき,OpenVPNサービスを起動させればよい(スタートメニュー -> コントロールパネル -> 管理ツール -> サービス).
Windows版OpenVPN用のGUIもある.
Angelo LaubがOpenVPN GUI for OS Xを開発している.
OpenVPN Client and Mac OS X 10.3も参照する.
ファイルINSTALLに個別のOSに関する注意事項が書かれている.一般に
./configure make make install
という方法を用いるか,自分のOS/ディストリビューション用のOpenVPN portまたはパッケージを探すとよい.
ルーティング vs. イーサネットブリッジの概要については,FAQを,さらに詳しい注と詳細については,OpenVPN Ethernet Bridgingページを参照する.
おおざっぱに言えば,たぶんルーティングは普通の人にとってよい選択であろう.ブリッジに比べてもっと効率よくかつ簡単(OpenVPNの設定そのもの程度)であり,しかもクライアントベースのアクセス制御も,もっと柔軟に行える.
特に以下に挙げるようなブリッジ機能を要求する場合でなければ,ルーティングをお薦めする.
VPNを設定して異なる地点にあるプライベートサブネットをリンクさせることがよくある.
IANA (Internet Assigned Numbers Authority)は,プライベートネットワークのために,以下のような三種類のIPアドレスを予約してある(RFC 1918に成文化されている).
10.0.0.0 | 10.255.255.255 | (10/8 接頭) |
172.16.0.0 | 172.31.255.255 | (172.16/12 接頭) |
192.168.0.0 | 192.168.255.255 | (192.168/16 接頭) |
通常VPNの構成には,上記のネットブロックからアドレスを選ぶべきであるが,IPアドレスまたはサブネットの衝突(=重複あり)を最小限にすることが重要である.避けたい衝突が以下の通りである.
例えば,(VPNの)プライベートLANのサブネットとしてよく使われる192.168.0.0/24を使用するとしよう.あなたが同じサブネットを使っているインターネットカフェのWiFi LANからVPNに接続しようとしている場合,ルーティング衝突が起きる.なぜなら,あなたのマシンが192.168.0.1はローカルのWiFiゲートウェイなのか,VPNのアドレスなのか,知ることができないから.
別例として,192.168.0.0/24を使っている複数のサイトをVPNで繋ごうとする場合も,複雑なNAT変換をやらないと無理であろう.なぜなら,VPNがユニックに識別できないサイト間にパケットをルーティングできないから.
最良の方法は,10.0.0.0/24や192.168.0.0/24をプライベートLANネットワークに採用しないこと.代わりに,WiFiカフェや空港やホテルなど,自分が遠隔から接続する可能性のあるところで使われる心配の少ないアドレスを用いる.よい候補として,範囲の広い10.0.0.0/8ネットブロックにある中間的なもの(例えば10.66.77.0/24)を使うこと.
また,サイトを跨るIP衝突を避けるためには,自分のLANサブネットに対して常にユニックなアドレスを使うこと.
OpenVPN 2.0を構築する最初のステップがPKI(公開鍵基盤)を立てること.PKIは以下の要素を含む.
OpenVPNは証明書に基づいた双方向の検証をサポートする.すなわち,互いに信頼できるようになる前に,クライアントがサーバ証明書を,サーバがクライアントの証明書を検証することである.
サーバもクライアントも,先方を検証する方法は,まずもらった証明書がマスタCAによって署名されものであるか否かを検証する.署名された証明書についてはヘッダをみて,(クライアントやサーバの)名前(CN = Common Name)や種類(type)をチェックする.
このセキュリティモデルは,VPNの観点からみると以下のような特徴を持つ.
この節では,マスタCA証明書/鍵,サーバ証明書/鍵,クライアント三つの証明書/鍵を生成する.
PKIの管理にOpenVPN附属のスクリプトを使うことにする.
Linux, BSD, または他のunix風OSを使っているなら,シェルを開いて,OpenVPNの配付ファイルのeasy-rsaサブディレクトリにcdする.RPMファイルからインストールした場合は,easy-rsaディレクトリが通常以下のところで見つかる:/usr/share/doc/packages/openvpnまたは/usr/share/doc/openvpn-2.0(将来OpenVPNをアップグレードする際に修正したところが上書きされてしまわないように,編集の前にこのディレクトリを別場所,例えば/etc/openvpn,にコピーしておこう.)一方,.tar.gzファイルからインストールした場合は,easy-rsaディレクトリが展開されたソースツリーのトップレベルディレクトリにある.
Windowsを使っているなら,コマンドプロンプトを出して,\Program Files\OpenVPN\easy-rsaにcdする.次のバッチファイルを実行し,設定ファイルをコピーする(既存の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 [me@myhost.mydomain]:
注:以上にある大半のパラメータは,ファイル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]"(サインする? [y/n]) と "1 out of 1 certificate requests certified, commit? [y/n]"(1/1証明書要求を確認したが,よろしい? [y/n]).
クライアントの証明書を生成するのも先と極めて似ている.Linux/BSD/Unix:
./build-key client1 ./build-key client2 ./build-key client3
On Windows:
build-key client1 build-key client2 build-key client3
パスワードでクライアント鍵を保護したいなら,スクリプトbuild-key-passを使うこと.
注意:聞かれたとき,各クライアントに対して適切な名前(Common Name)を使おう,例えば"client1", "client2"と"client3".常にユニークな名前を使うこと.
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 | 鍵署名マシンだけ | ルート(訳注:マスタ)CA鍵 | はい |
dh{n}.pem | サーバだけ | DH (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鍵 | はい |
鍵生成の最後のステップは,必要とするマシンに当該ファイルをコピーすることであるが,秘密ファイルには安全な方法を使うことに気を付けよう.
「ちょっと待って,」,あなたがこういうかもしれない.「既存の安全な方法を使わないでPKIを構築することができないのか.」
答はyesである.上記の例は,簡単のため,同じ場所ですべての秘密鍵を生成していたが,もう少し手間をかけると別の方法でもできる.例えば,サーバ上でクライアントの証明書と鍵を生成する代わりに,クライアントにローカルで専用の秘密鍵を生成してもらい,CSR(証明書署名要求 = Certificate Signing Request)を提出してもらうことができる.逆に鍵署名マシンはCSRを処理し署名された証明書をクライアントへ返せばよい.これなら秘密な.keyファイルが生成したマシンのハードディスクから離れることなくて済むようになる.
はじめはOpenVPNサンプル設定ファイルを使うのがベストであろう.これらのファイルは以下のところにある.
注:サンプル設定ファイルの名前は,Linux, BSDまたは他のunix風OSの場合,server.confとclient.confとなっているが,Windowsの場合はserver.ovpnとclient.ovpnとなっている.
サンプルのサーバ設定ファイルはOpenVPNのサーバ設定にとって理想的な起点である.それにより次のようなVPNが構築される:バーチャルTUNネットワークインタフェース(ルーティングのため)を利用しUDP 1194番ポート(OpenVPNの公式ポート)でクライアントからの接続要求を待つ.さらに接続するクライアントに対しバーチャルなアドレス10.8.0.0/24サブネットを配る.
サンプル設定ファイルを使う前に,まずパラメータca, cert, keyとdhを,先のPKI節で生成したファイルで修正すること.
この時点のサーバ設定ファイルでも使えるが,将来カスタマイズしたくなるかもしれないね:
以下のように同じマシンで複数のOpenVPNインスタンスを異る設定ファイルによって実行させることも可能である.
サンプルのクライアント設定ファイルは(Linux/BSD/Unixではclient.conf,Windowsではclient.ovpn)サンプルのサーバ設定ファイルのデフォールト値に対応している.
最初にOpenVPNサーバがインターネットから接続可能のことを確認する.これは次のことを意味する.
次に,TUN/TAPインタフェースがファイアウォールされないことを確認する.
トラブル究明を簡単にするために,はじめはデーモンやサービスではなく,コマンドラインで(またはWindows上で.ovpnファイルを右クリックし)OpenVPNを起動するのが一番よいであろう.
openvpn [サーバ設定ファイル]
通常のサーバ起動が次のような感じである(環境によって異なる).
Sun Feb 6 20:46:38 2005 OpenVPN 2.0_rc12 i686-suse-linux [SSL] [LZO] [EPOLL] built on Feb 5 2005 Sun 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
サーバ同様,はじめはデーモンやサービスではなく,コマンドラインで(またはWindows上で.ovpnファイルを右クリックし)OpenVPNを起動するのが一番よい.
openvpn [クライアント設定ファイル]
通常のクライアント起動がサーバの場合の出力と似ているが,最後にInitialization Sequence Completedメッセージで終わるはず.
では,クライアントからVPNを使ってpingしてみよう.サーバ側でルーティングを使っている(つまりサーバ設定ファイルにdev tunを用いた)なら,
ping 10.8.0.1
ブリッジを使っている(すなわちサーバ設定ファイルにdev tapを用いた)場合,サーバ側イーサネットサブネットにあるマシン宛にpingしてみよう.
もしpingが成功したらおめでとう! あなたが機能するVPNの構築に成功したのである.
pingが失敗した,またはOpenVPNの初期化が完了できなかった場合,以下のチェックリストに示す症状と解決法をご参照下さい.
エラーメッセージ:TLS Error: TLS key negotiation failed to occur within 60 seconds (check your network connectivity).これはクライアントがサーバへのネットワーク接続に失敗したことを示す.
解決法:以下のことを確認する.
エラーメッセージInitialization Sequence Completed with errors -- これにはWindows上で発生しうる次の原因が考えられる.(a) DHCPクライアントサービスが起動していない,または (b) XP SP2で第三者のパーソナルファイアウォールを使っている.
解決法:DHCPクライアントサービスを起動させる.また,お使いのパーソナルファイアウォールはXP SP2上で正常に動作することを確認する.
Initialization Sequence Completedとなったが,pingテストが失敗する.通常これは,サーバまたはクライアント側のファイアウォールがTUN/TAPインタフェースのVPNトラフィックをブロックしていることを意味する.
解決法:クライアントにおいて(存在しているなら)ファイアウォールのTUN/TAPインタフェースに対するフィルタリングを無効にする.例えばWindows XP SP2では,Windowsセキュリティセンター -> Windowsファイアウォール -> 詳細設定,そしてTAP-Win32アダプタのチェックを外す(注:クライアント側でTUN/TAPアダプタに対するフィルタリングを無効にすることは,セキュリティの観点からみると理由がある.これが,ファイアウォールに対して,認証済みのVPNトラフィックをブロックしないように設定することに過ぎない).また,サーバ側のTUN/TAPインタフェースもフィルタリングされないことを確認する(というものの,TUN/TAPインタフェースに対する適切なファイアウォール設定は,セキュリティ上に便利なこともある.接続ポリシ節を参照).
proto udpを使うと起動時に接続がとまってしまい,サーバのログファイルに次の行が残った.
TLS: Initial packet from x.x.x.x:x, sid=xxxxxxxx xxxxxxxx
ただし,クライアントのログにはそれに対応する行がない.
解決法:これはクライアントからサーバへの片方接続ができることを示している.サーバからクライアントへは,(大体クライアント側の)ファイアウォールによってブロックされている.このファイアウォールは,(a) クライアント側のパーソナルファイアウォール,または (b) クライアント側のNATルータ/ゲートウェイ と考えられる.サーバからクライアントへのUDPパケットを転送するよう,ファイアウォールを修正すること.
トラブル究明についてもっと知りたい場合,FAQの情報を読むとよい.
このことについて標準がない.つまりほとんどのOSがブート時にデーモン/サービスを自動的に起動させる独自の方法を持つ.これに最もよい方法は,LinuxのRPMやWindowsのインストーラのようなパッケージからOpenVPNをインストールすること.
RPMパッケージでOpenVPNをインストールする場合,インストーラがinitscriptを設定する.このinitscriptは,起動すると/etc/openvpnにある.conf設定ファイルを見つけて,ファイル別にOpenVPNデーモン一個を起動させる.
Windowsインストーラはサービスラッパーを設定するが,デフォールトでは無効になっている.有効にするには,コントロールパネル / 管理ツール / サービスの順にたどり,OpenVPNサービスを選択し,右ブタンでプロパーティを選びStartup Typeを自動に設定する.これにより次回ブート時にOpenVPNが自動的に起動される.
起動すると,OpenVPNサービスラッパーがフォルダ\Program Files\OpenVPN\configにある.ovpn設定ファイルを見付け,ファイル別にOpenVPNプロセスを生成する.
OpenVPNは次のようなシグナルを受けつける:
項目writepidでOpenVPNデーモンのPIDをファイルに書き込ませることができ,これによってどのプロセスにシグナルを送ればよいかが分る(initscriptでOpenVPNを起動させているなら,このスクリプトがすでに--writepidをopenvpnのコマンドラインに付加したかもしれない).
OpenVPN GUIページを参照すること.
Windows上では,OpenVPN設定ファイル(.ovpnファイル)を右クリックし,"Start OpenVPN on this config file"を選べばOpenVPNを起動させることができる.
このように起動している場合,以下のようなキーボードコマンドが利用できる.
OpenVPNがWindowsのサービスとして起動している場合,それを制御する方法は以下だけに限る.
ほとんどの設定の変更はサーバの再起動を要求するが,二つだけ特別な項目がある.これらの項目は動的にアップデートできるファイルを指し,サーバの再起動がなくてもすぐ有効になる.
client-config-dir -- この項目は,クライアント設定のディレクトリを指す.OpenVPNサーバは,接続要求が来ると,このディレクトリを調べクライアント別の設定ファイルを探すことになっている(manページを参照).このディレクトリにあるファイルは,サーバ再起動なく,いつでもアップデートできる.なお,変更は新しい接続のみに適用され,既存の接続には適用されない.あるクライアントの設定ファイルを既存接続(または切断されたが,サーバ上のインスタンスがまだタイムアウトになっていない接続)にもすぐ有効にしたい場合,(後述の)管理インタフェースを使ってこのクライアントのインスタンスを殺すとよい.これにより,クライアントが再接続することになり,新しいclient-config-dirのファイルが使用される.
crl-verify -- この項目は,後の証明書廃止の節で述べる廃止証明書リスト(CRL)ファイルを示す.このCRLファイルは随時修正可能でで,変更はすぐ新しい接続またはSSL/TLSチャンネルを再ネゴーシエイトする(デフォールトは一時間に一回)既存接続に適用される.このCRLに追加された証明書を持つ既存接続のクライアントを止めたい場合,後述の管理インタフェースを使用するとよい.
デフォールトの設定はserver.confファイルにある次の一行.
status openvpn-status.log
これにより,現在のクライアント接続情况リストが1分ごとにopenvpn-status.logに書き込まれる.
OpenVPN管理インタフェースは,実行中のOpenVPNプロセスに対してかなりの制御ができる.それを利用するために,直接管理インタフェースのポートにtelnetする方法もあれば,間接にOpenVPN GUIを介して接続する方法もある.
OpenVPNサーバまたはクライアントの管理インタフェースを有効にするには,設定ファイルに次の行を追加するとよい.
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管理インタフェースドキュメントを参照するとよい.
VPNがクライアントとサーバ間一対一の形でうまくいったら,自然にその範囲を拡げ,クライアントがサーバマシンだけでなく,サーバのネットワークにある他のマシンにも接続できるようにしたいかもしれない.
説明のために以下の例を考えよう.サーバ側LANはサブネット10.66.0.0/24,VPNのIPアドレス範囲は10.8.0.0/24であるとしよう(OpenVPNサーバ設定ファイルのserver項目で示される).
まず,接続を許可したいVPNクライアントに10.66.0.0/24サブネットを広告する必要がある.これは簡単で次の項目をサーバ側設定ファイルに追加するだけでよい.
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のメリットの一つとして特に設定が必要ない.
典型的なロードロードウォリアーや遠隔接続の場合は,クライアントが一台のみでVPNに接続する.一方,クライアントマシンがあるLAN(例えばホームオフィス)のゲートウェイとして,LANにある他のマシンもVPN経由で経路を設定できるようにしたいことも考えられる.
これの例で,次のような設定を考えよう.クライアントLANはサブネット192.168.4.0/24を使用しており,VPNクライアントがclient2のCN(名前)の証明書を使う.我々の目的は,クライアントLANのどのマシンでもVPNを介してサーバLANの任意のマシンに通信可能にすること.
設定する前に,いくつか基本要件を確認しておこう.
まず,クライアントマシンにおいて,IPとTUN/TAP転送が有効になっていることを確認しよう.
次に,サーバ側の設定変更について述べる.もしサーバの設定ファイルにクライアント設定ディレクトリを設定していないなら,ここで追加しておく.
client-config-dir ccd
上の設定において,ccdは,OpenVPNサーバデーモンのデフォールト実行ディレクトリに事前に作られたディレクトリ名にすること.通常Linuxでは/etc/openvpn,Windowsでは\Program Files\OpenVPN\configとなる.新クライアントがOpenVPNサーバに接続してきたとき,OpenVPNデーモンはこのディレクトリをチェックし,接続クライアントのCNと一致するファイルを見つけ出そうとする.一致するファイルが見つかったら,このクライアントに適用される追加設定として処理される.
次はccdディレクトリにclient2ファイルを作ること.このファイルには次の行を入れる.
iroute 192.168.4.0 255.255.255.0
これは,サブネット192.168.4.0/24への経路はclient2を経由するとOpenVPNサーバに教えるのである.
次に,以下の一行をメインサーバ設定ファイル(ccd/client2ではない)に追加する.
route 192.168.4.0 255.255.255.0
どうして冗長なrouteとirouteを使うの? こんな質問があるかもしれない.それは,routeはカーネルからOpenVPNサーバへ(TUNインタフェース経由)の経路を制御するのに対し,irouteはOpenVPNサーバから遠隔クライアントへの経路を制御するのであるため. 両方も必要.
次に,client2のサブネット(192.168.4.0/24)とその他のクライアント間の通信を許可するか否かを考えてみよう.許可するなら,以下をサーバ設定ファイルに追加する.
client-to-client push "route 192.168.4.0 255.255.255.0"
これにより,OpenVPNサーバがclient2のサブネットを他の接続しているクライアントに広告するようになる.
最後に,よく忘れがちのことであるが,サーバのLANゲートウェイにおいて,192.168.4.0/24への経路をOpenVPNサーバボックス経由となるように設定しておくこと(OpenVPNサーバボックスがサーバLANのゲートウェイである時には不要).これを忘れた場合に192.168.4.8からサーバLANにある(OpenVPNサーバではない)マシンに対してpingをかけることを考えてみよう.出ていくpingはそのマシンに届くのであろうが,そのマシンがpingに対してどのように応答すればよいか分らないのである.なぜなら,192.168.4.0/24に到達するためのルートが知らないから.おおざっぱに言うと,(VPNサーバがLANのゲートウェイマシンではない場合,)すべてのLANへの経路をVPN経由となるように設定したい場合は,必ず全VPNサブネットへの経路をVPNサーバマシン経由となるように,LANのゲートウェイを設定しておくこと.
同様に,OpenVPNを実行しているクライアントマシンについても,クライアントLANのゲートウェイではない場合,やはりVPN経由で到達できるサブネットへの経路を,OpenVPNクライアントマシン経由となるように設定しなくてはならない.
これにはもっと複雑な設定が必要である(実際にはそれほど難しくないだろうが,詳細を述べるには上記よりもっと難しい).
OpenVPNサーバはDNSやWINSサーバアドレスなどのようなDHCPの設定をクライアントに伝えることができる(いくつかの警告に注意すること).Windowsクライアントは伝えられたDHCPオプションをネイティブに利用できるが,非Windowsクライアントは環境変数リストforeign_option_nを処理するクライアント側upスクリプトを使う必要があるしれない.manページやopenvpn-users メーリングリストアーカイブから非Windowsのforeign_option_nについてのドキュメントとスクリプトサンプルを参照できる.
例えば,接続クライアントに内部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を設定したいとしよう.
そのために我々は次のような基本的な方法を用いる:(a) 利用者をクラス別の専用バーチャルIPアドレス空間に分離させておき,(b) ファイヤウォールを用いてクライアントのバーチャルIPアドレスをキーとして(key off)マシンへの接続を制御する.
この例において,社員不特定多数,システム管理者一人,請負業者二人,がいるとしよう.この場合のIP割り当てとして,社員にはあるIPアドレス空間,システム管理者と請負業者には固定IPアドレス,という方法が考えられる.
注:この例において,OpenVPNサーバ上でソフトウェアベースのファイヤウォールが稼動している,という前提条件がある.ルールを自分で定義できる機能を提供してくれるようなファイヤウォールが必要のため.我々はLinuxのiptablesを例で説明する.
まず,利用者クラス別にバーチャルIPアドレスのマップを作っておこう.
クラス | バーチャルIPの範囲 | 許可されるLAN接続 | CN |
社員 | 10.8.0.0/24 | Samba/メールサーバ 10.66.4.4 | [不特定多数] |
システム管理者 | 10.8.1.0/24 | サブネット 10.66.4.0/24 全体 | sysadmin1 |
請負業者 | 10.8.2.0/24 | 請負業者用サーバ 10.66.4.12 | contractor1, contracter2 |
次はこのマップを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アドレスを定義する.
ifconfig-push 10.8.1.1 10.8.1.2
ifconfig-push 10.8.2.1 10.8.2.2
ifconfig-push 10.8.2.5 10.8.2.6
各ifconfig-pushアドレスのペアは,バーチャルクライアントとサーバのIPアドレスを示し,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 の例を示す.
# Employee rule iptables -A FORWARD -i tun0 -s 10.8.0.0/24 -d 10.66.4.4 -j ACCEPT # Sysadmin rule iptables -A FORWARD -i tun0 -s 10.8.1.0/24 -d 10.66.4.0/24 -j ACCEPT # Contractor rule iptables -A FORWARD -i tun0 -s 10.8.2.0/24 -d 10.66.4.12 -j ACCEPT
OpenVPN 2.0は,サーバが安全にクライアントからユーザ名とパスワードを受け取ってそれに基づいて認証を行なう特徴を持っている.
この認証方法を利用するには,まずクライアントの設定にauth-user-passという項目を追加しておく.これにより,OpenVPNクライアントがユーザからユーザ名/パスワードを聞き,安全なTLSチャンネルを使ってサーバに渡すようになる.
次にサーバが認証プラグインを使うように設定する.プラグインはスクリプトや共用オブジェクトやDLLなどでよい.OpenVPNサーバは,クライアントが接続する度に,このプラグインを呼び出してクライアントからもらったユーザ名/パスワードを渡す.認証プラグインは,OpenVPNサーバがクライアントの接続を許可するかしないかを制御することができる.不許可の場合は失敗(1),許可する場合は成功(0)を返せばよい.
スクリプトプラグインは,サーバ側設定ファイルにauth-user-pass-verify項目を追加することによって利用できる.例:
auth-user-pass-verify auth-pam.pl via-file
により,Perlスクリプトauth-pam.plが接続しているクライアントのユーザ名/パスワードを認証するために用いられる.詳しくはauth-user-pass-verifyについてのmanページを参照すること.
スクリプトauth-pam.plは,OpenVPNソースファイルのsample-scriptsサブディレクトリに入っていて,Linuxサーバ上でPAM認証モジュールを用いてユーザ認証を行う.すなわちシャドウパスワードやRADIUSやLDAP認証が実装されている.ただしauth-pam.plは,主にデモのために作られたものであり,実世界のPAM認証には,下記に述べるopenvpn-auth-pamという共有オブジェクトプラグインを利用する.
共用オブジェクトやDLLプラグインは,通常コンパイル済みのCモジュールであり,OpenVPNサーバが実行時にロードされる.例えばLinux上でRPMベースのOpenVPNパッケージを使っている場合,プラグインopenvpn-auth-pamはすでにビルトされたはず.それを使うには,次をサーバ側設定ファイルに追加するとよい.
plugin /usr/share/openvpn/plugin/lib/openvpn-auth-pam.so login
これにより,OpenVPNサーバがlogin PAM モジュールを用いてクライアントからもらったユーザ名/パスワードを検証するようになる.
実世界製品レベルの利用は,openvpn-auth-pamプラグインをお薦め.スクリプトauth-pam.plよりいくかの長所を持っている:
OpenVPNプラグインを開発するための情報がほしい場合,OpenVPNソースディレクトリのpluginサブディレクトリにあるREADMEファイルを参照すること.
Linux上でプラグインopenvpn-auth-pamをビルトする場合,OpenVPNソースのplugin/auth-pamディレクトリにcdしてmakeを実行するとよい.
デフォールトでは,サーバでauth-user-pass-verifyやユーザ名/パスワードをチェックするpluginを用いていることが二重認証である.つまりクライアント認証のために,証明書とユーザ名/パスワードの両方を確認する必要がある.
セキュリティの観点からお薦めできないが,証明書の確認を無効にしてユーザ名/パスワードだけの確認で認証することもできる.サーバの設定に以下を追加するとよい.
client-cert-not-required
このような設定の場合,常に以下も入れておく.
username-as-common-name
これにより,サーバがユーザ名をクライアントの見出しに用いることになる.これに対し,証明書認証の場合は,クライアントが認証のために提示した証明書のCNが用いられる.
注:client-cert-not-requiredはサーバ証明書の必要性をなくすものではない.従って,client-cert-not-requiredを使っているサーバに接続しようとするクライアントは,設定ファイルからcertとkeyの項目を省略してよいが,サーバの証明書を検証するためにca項目を残しておく必要がある.
OpenVPNクライアントが動作中に,デフォールトではサーバとのやりとりのトラフィックだけがVPNを経由することになる.一般の,例えばWeb閲覧の,トラフィックはVPNではない(直接)経路を使っている.
この方式で望ましくない場合がある.つまりクライアントにおいて,インターネットのWeb閲覧を含むすべてのネットワークトラフィックが,VPN経由となるように設定したい場合である.このようなVPN設定によって,クライアントのパフォーマンスに影響が出るが,同時に公衆インターネットとVPNにつながっているクライアントに対し,より安全なポリシをVPN管理者が設定できるようになる.
サーバの設定ファイルに次の項目を追加する.
push "redirect-gateway def1"
VPNが無線ネットワーク上に設定されていて,かつクライアントもサーバも全員同じ無線サブネットにある場合, フラッグlocalも追加する.
push "redirect-gateway local def1"
オプションredirect-gatewayをクライアントに伝えることにより,クライアントマシン発の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で(サーバ設定のserver項目から分る),ローカルイーサネットインタフェースがeth0と想定している.
redirect-gatewayが用いられた場合,OpenVPNクライアントはDNSの問い合わせをVPN経由とするので,VPNサーバはそれを処理する必要がある.そのために接続しているクライアントにDNSサーバのアドレスを教えてやればよい.VPNの稼動中に通常のDNSサーバ設定の代わりにこのアドレスが用いられる.例えば:
push "dhcp-option DNS 10.8.0.1"
によって,Windowsクライアント(または別途サーバ側スクリプトを持つ非Windowsクライアント)が 10.8.0.1 をDNSサーバと認識するようになる.因に任意のクライアントから交信できるアドレスをDNSサーバアドレスとして用いてよい.
すべてのネットワークトラフィックをVPNにリダイレクトするのは問題がないわけではない.ここでいくつか典型的な分ったこと(訳注:原文gotcha)を示そう.
redirect-gatewayの仕組みについて,詳しくはmanページを参照すること.
動的IPアドレスを持つOpenVPNクライアントは特に設定しなくても簡単にサーバに接続できるが,サーバが動的アドレスである場合はおもしろくなる.OpenVPNは,動的サーバの場合でも問題無いが,もう少し設定が必要になる.
第一ステップは,サーバIPアドレスの変更に"ついていける"ダイナミックDNSアドレスを取得すること.ダイナミックDNSサービスはいくつかある,例えばdyndns.org.
次のステップは,サーバIPアドレスが変わるたびに,ダイナミックDNS名がすぐに更新されるような仕組を設定しておくこと.これにより,クライアントは新IPアドレスでサーバを見つけることができる.そのための基本方法が二つある.
ダイナミックDNSをサポートするNATルータ(例えばLinksys BEFSR41)を用いること.安価で入手しやすいNATルータの大半は,ISPからもらうDHCP情報が変わるたびに,ダイナミックDNS名を更新する機能を持る.この方法が,OpenVPNサーバボックスがファイヤウォールの後ろに(単一NICを持つマシンで)ある場合には理想的である.
ダイナミックDNSクライアント,例えばddclientを使って,サーバIPアドレスが変わったらダイナミックDNSアドレスを更新する.これは,OpenVPNのマシンが複数NICを持つサイトのファイヤウォール/ゲートウェイであるに理想的である.これを実現するには,IPアドレスが変わるたびにDHCPクライアントソフトウェアによって実行されるスクリプトを設定する必要がある.このスクリプトは,(a) ddclientを実行させ新IPアドレスをダイナミックDNSプロバイダに通知するとともに(b) OpenVPNサーバデーモンを再起動させる必要がある.
OpenVPNクライアントは,デフォールトで設定にremoteによって指定されたダイナミックDNS名を用いてサーバIPアドレスの変更に対応できる.通常これが次のようなことになる.(a) OpenVPNクライアントがサーバの旧IPアドレスからkeepaliveメッセージを受信できなくなる.これは再起動を引き起こし,(b) 再起動によってremote項目で指定されたDNS名が再度解決され,それによってクライアントは新IPアドレスを用いてサーバに再接続することができる.
詳しくは,FAQを参照するとよい.
OpenVPNはHTTPプロキシ経由の接続方法をサポートする.そのためのプロキシ認証モードとして以下のようなものがある.
とりわけ,HTTPプロキシはトンネル用プロトコールとしてTCPを要する.そのためにクライアント側にもサーバ側にも次のような設定を追加しておく.
proto tcp
設定ファイルにproto udpが削除されたことも確認しよう.
次に,http-proxy項目をクライアントの設定ファイルに追加する(この項目の詳解についてはmanページを参照すること).
例えば,クライアントLANのHTTPプロキシサーバが192.168.4.1のポート1080をリスニングしているとしよう.クライアントの設定に以下を追加する.
http-proxy 192.168.4.1 1080
HTTPプロキシがBasic認証を要求する場合:
http-proxy 192.168.4.1 1080 stdin basic
また,HTTPプロキシがNTLM認証を要求する場合:
http-proxy 192.168.4.1 1080 stdin ntlm
上にある二つの認証例では,OpenVPNが標準入力からユーザ名/パスワードの入力を提示する.ファイルから読み込ませたい場合,stdinの代わりにファイル名を指定し,ファイルの一行目でユーザ名,二行目でパスワードをおくとよい.
この例は,OpenVPNクライアントがルーティングモードのdev tunトンネルを経由しSamba共有に接続する手順を示す.イーサネットブリッジ(dev tap)を使っているなら従う必要がなかろう.なぜなら,その場合は,OpenVPNクライアントがサーバ側のマシンを見れるから.
説明のため,次のような環境を仮定しよう.
SambaサーバがOpenVPNサーバと異るマシン上にある場合,節「マシンを追加し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サーバと同じマシン上にある場合,smb.confのinterfaces項目を編集し,TUNインタフェースのサブネット10.8.0.0/24をリスニングするようにする.
interfaces = 10.66.0.0/24 10.8.0.0/24
SambaサーバがOpenVPNサーバと同じマシン上にある場合,OpenVPNクライアントからSamba共有に接続するためのフォルダ名:
\\10.8.0.1\\sharename
SambaサーバがOpenVPNサーバと異るマシン上にある場合フォルダ名:
\\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秒間解決しようとする(訳注:デフォールトのタイムアウトは無限大.つまり次のサーバに移らないこと).
サーバリストは,同じマシンに稼動している(異るポートをリスニングしている)複数のOpenVPNサーバデーモンを参照することも可能.例:
remote smp-server1.mydomain 8000 remote smp-server1.mydomain 8001 remote smp-server2.mydomain 8000 remote smp-server2.mydomain 8001
ちなみに複数プロセッサを持つサーバの場合,一台のサーバで複数OpenVPNデーモンを稼動させるのがパフォーマンスから見ると有利である.
さらにOpenVPNは,remote項目で,ドメインのゾーン設定に複数のAレコードを持つDNS名を指定できる.その場合,OpenVPNクライアントが,ドメインを解決する度にAレコードからランダムに一つを選ぶ.
サーバ側での負荷分散/障害迂回に一番簡単な方法は,各サーバにバーチャル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は複数の構造によって高度なセキュリティ層を提供する.
項目tls-authは,すべてのSSL/TSLハンドシェークパケットにHMAC署名を付加することにより整合性を検証する.正しいHMAC署名を持っていないUDPパケットは直ちに破棄される.tls-authによるHMAC署名は,SSL/TLSの提供する範囲を超えてよりよい安全性を提供する.具体的に以下のことに抵抗できる.
なお,tls-authにおいて,標準のRSA証明書/鍵と別の共有秘密鍵を生成する必要がある.
openvpn --genkey --secret ta.key
このコマンドによってOpenVPN静的鍵が生成され,ファイルta.keyに書き込まれる.この鍵は,既存の安全なチャンネルを使ってサーバとクライアントマシンに複製する必要があり,RSA .key と .crt ファイルと同じディレクトリにおくとよかろう.
サーバの設定には以下を追加する.
tls-auth ta.key 0
クライアントの設定には,次を.
tls-auth ta.key 1
OpenVPNはTCPでもUDPでもVPN接続の運びプロトコルとして使えるが,DoS攻撃やポートスキャンに対して,TCPよりUDPのほうが強い.
proto udp
OpenVPNは,初期化が済んだらrootの特権がなくてもよいように非常に念入りに設計されている.この特徴はLinux/BSD/Solarisに使えるはず.攻撃者にとって,root特権のないOpenVPNサーバデーモンはあまりおいしいターゲットにはならないのである.
user nobody group nobody
項目chrootによりOpenVPNデーモンをいわゆるchroot jailに限定させることができる.この場合,デーモンがパラメータで指定された特別なディレクトリ以外に,ホストのファイルシステムにはアクセスできない.例:
chroot jail
によって,OpenVPNデーモンが,初期化時にサブディレクトリjailにcdしこのディレクトリからルートファイルシステムを再構成するようになる.従って,デーモンがjailとそれ以下のサブディレクトリにあるもの以外にファイルをアクセスできないようになる.これはセキュリティの観点からみると重要である.なぜなら,これにより,攻撃者がコード挿入型の突破口(訳注:exploit,システム侵入のための弱点)を利用してサーバに侵入できたとしても,この突破口がサーバのファイルシステムの大部分から切り離されているから.
注意:chrootによって(デーモンだけが見れる)ファイルシステムが再構成されるので,ディレクトリjailにOpenVPNが初期化以後に必要とするファイルを全部おかなければならない.例えば,
RSA鍵のサイズはファイルeasy-rsa/varsにあるKEY_SIZE変数によって変えられるが,すべての鍵を生成する前に設定しておく必要がある.現在のデフォールト値は1024であるが,2048に変えってもVPNトンネルのパフォーマンスに影響しない.ただ,一人のクライアントにつき,一時間一回のSSL/TLS再ネゴシエイションのハンドシェークが少し遅くなる.また,easy-rsa/build-dhを使ってDiffie Hellmanパラメータを生成する過程(一回だけ)がかなり遅くなる.
デフォールトでは,OpenVPNがBlowfish128ビット対称暗号方式を用いる.
OpenVPNは,大きな鍵サイズを持つ暗号化方式を含み,OpenSSLライブラリのサポートする暗号方式が自動的に使える.例えば256ビット版のAES(Advanced Encryption Standard)が,以下をサーバとクライアントの設定ファイルに追加することで使用できる.
cipher AES-256-CBC
セキュリティの利点として,X509 PKIを使用する(OpenVPNがそうしている)ことは,ルートCA鍵(ca.key)をOpenVPNサーバマシンにおく必要がない.高度のセキュリティ環境が要する場合,鍵署名のためのマシンを特別に指定し,物理的によく管理してネットワークから切り離すようにするのがよかろう.必要があればフロッピを使って鍵ファイルを移動させるとよい.この方法により(ネットワークの)攻撃者がルート鍵を盗むことは極めて困難になる.鍵署名用マシンを盗み出そうとする物理的な泥棒には弱いが.
証明書廃止は,以前に署名した証明書を無効にすることで認証に使えなくなることを意味する.
証明書を廃止する典型的な理由として以下のようなものがある.
例として,このHOWTOの鍵生成"の節で生成したclient2の証明書を廃止してみよう.
まず,上の鍵生成"の節でやったように,シェルまたはコマンドプロンプトを出してディレクトリeasy-rsaにcdする.次に,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: /C=KG/ST=NA/O=OpenVPN-TEST/CN=client2/emailAddress=me@myhost.mydomain error 23 at 0 depth lookup:certificate revoked
最終行の"error 23"に注目しよう.これは期待通り.つまり廃止した証明書に対する検証が失敗したのである.
スクリプトrevoke-fullはディレクトリkeysにおいてcrl.pemというCRL(certificate revocation list,証明書廃止リスト)ファイルを生成する.このファイルはOpenVPNサーバがアクセスできるディレクトリに複製する必要がある.それからサーバの設定ファイルにCRL検証を有効にしておく.
crl-verify crl.pem
これにより,接続するクライアントのすべてがこのCRLに対し,証明書検証をパスしなければならない.リストにマッチした場合は接続が破棄される.
オプションcrl-verifyが使われた場合,CRLファイルが新クライアントの接続,または接続しているクライアントのSSL/TLS再ネゴシエーション(デフォールトで一時間一回)するたびに読み込まれる.これは,CRLファイルがOpenVPNデーモンの実行中でも更新できることを意味し,新しいCRLがすぐに新しく接続してくるクライアントに適用されるされる.廃止したい証明書を持つクライアントが接続中にある場合,サーバをシグナル(SIGUSR1またはSIGHUP)で再起動させすべてのクライアントをフラッシュするのもいいし,他のクライアントを騒がさずに管理インタフェースにtelnetして手動で特定なクライアントインスタンスオブジェクトを殺すのもよい.
項目crl-verifyはOpenVPNサーバとクライアントの両方に使えるが,サーバ証明書を廃止した場合以外に,通常CRLファイルをクライアントに配る必要がない.クライアントは他のクライアントの証明書が廃止されたことを知る必要がない.実際,とにかくクライアントが他のクライアントからの直接接続を受け入れるべきではないのである.
CRLファイルは秘密にする必要がない.実際に,OpenVPNデーモンがルート特権を落とした後でも読む必要があるため,"ワールド読める"ように設定すべきである.
項目chrootを使っている場合,CRLファイルのコピーをchrootのディレクトリに置く必要がある.なぜなら,他のファイルと違ってCRLファイルはchrootコールの前ではなく,後に読まれるから.
証明書の廃止となった一般的な理由として,利用者が自分の秘密鍵にパスワードをかけたが,その後それを忘れてしまった場合である.元証明書を廃止しても,利用者元々のCNで新しい証明書/鍵ペアを生成することができる.
認証済みのクライアントがサーバのふりをして別のクライアントに接続するような起こり得る"Man-in-the-Middle"攻撃を防ぐために,クライアント側でサーバの証明書を検証するという強化仕組が必要である.以下,現在それを達成するような方法を四つで勧め度の順に示す.
スクリプトbuild-key-serverを使ってサーバ証明書を生成すること(詳しくはeasy-rsaドキュメント参照).これによってサーバだけの証明書ができる(nsCertType=server).次に以下の一行をクライアントの設定に追加する.
ns-cert-type server
これにより,クライアントが証明書に"nsCertType=server"という指定のないサーバとの接続を行わないようになる.たとえこの証明書はOpenVPNの設定ファイルに指定されたcaファイルによって署名されたものであっても.
クライアント項目tls-remoteを使って,サーバ証明書のCNに基づいて接続を受け入れる/拒否する.
項目tls-verifyによって,サーバ証明書に入っているX509対象の詳細をカスタムテストするようなスクリプトまたはプラグインを使って接続を受け入れる/拒否する.
サーバ証明書とクライアントの証明書は別々のCAで署名する.この場合のca設定は,クライアントの場合はサーバを署名したCAファイルを,サーバの場合はクライアントを署名したCAファイルを,参照する必要がある.
設定ファイル例/server.conf |
################################################# # 複数クライアントを処理するサーバのための # # OpenVPN 2.0設定ファイル例 # # # # これが,多数クライアント対サーバ1つの場合の # # OpenVPNサーバ側設定を示すものである. # # # # OpenVPNさらに一対一の設定もサポートしている # # (詳しくはWebページのExamplesページを参照). # # # # この設定はWindowsにおいてもLinux/BSDシステムに# # おいても問題ないはず.Windowsの場合,パス名を # # クォートしダブルバックスラッシュを用いること.# # 例: # # "C:\\Program Files\\OpenVPN\\config\\foo.key" # # # # コメントは'#'または';'で始まる. # ################################################# # OpenVPNがリスニングするローカルIPアドレス. #(オプション) ;local a.b.c.d # OpenVPNがリスニングするTCP/UDPポート. # 同じマシンで複数OpenVPNインスタンスを動かすには # それぞれ異なるポートを与えること. # さらにファイヤウォールでポートを開ける必要がある. port 1194 # TCPかUDPか? ;proto tcp proto udp # "dev tun" はルーティングIPトンネルを作る. # "dev tap" はイーサネットブリッジを作る. # イーサネットブリッジモードを使いたければ # "dev tap"を使うこと. # VPNの接続ポリシを制御するために,このTUN/TAP # インタフェースに対しファイヤウォールルールを # 設定する必要がある.非Windowsの場合,明示的に # ユニット番号,例えばtun0を指定することが可能. # Windowsの場合は,"dev-node"を使うこと. # 大半のシステムにおいて,TUN/TAPインタフェース # に対し,ファイヤウォールを一部または全部無効に # しないとVPNが正常に動作しなかろう. ;dev tap dev tun # Windowsにおいて,TAP-Win32アダプタが複数ある # 場合,ネットワーク接続パネルから名前を確認し # ここで設定する必要がある.XP SP2以上の場合, # TAPアダプタに対し,Windowsファイヤウォールを # 選択して無効にする必要があるかもしれない. # 非Windowsシステムの場合は通常必要ない. ;dev-node MyTap # SSL/TLSルート証明書(ca), 証明書(cert), # と秘密鍵(key).各クライアントとサーバが, # 専用certとkeyファイルを持つべき.ファイルcaは # クライアントとサーバ間で共用する. # # ディレクトリ"easy-rsa"にRSA証明書と秘密鍵を # 生成するスクリプトを参照する.なお,サーバと # 各クライアント証明書のCNをユニックにすること. # # どんなX509鍵管理システムでも大丈夫.OpenVPNは # PKCS #12 形式の鍵ファイルを利用できる(man # ページの"pkcs12"項目を参照する). ca ca.crt cert server.crt key server.key # このファイルを秘密に保管すること. # Diffie hellman パラメータ. # 次のように生成すること: # openssl dhparam -out dh1024.pem 1024 # 2048ビット鍵を使うなら1024の代わりに2048を用いる. dh dh1024.pem # サーバモードを設定してOpenVPNクライアント用の # サブネットを指定する.サーバは10.8.0.1を使用するが, # 残りはクライアントが使用可能.各クライアントが # 10.8.0.1を用いてサーバに通信できる.イーサネット # ブリッジを使うならコメントアウトすること. # 詳しくはmanページを参照. server 10.8.0.0 255.255.255.0 # クライアントとバーチャルIPアドレスの対応表を # 記録するファイル.OpenVPNはダウンまたは再起動 # したら,再接続のクライアントに対し前に割り当てた # バーチャルIPアドレスを割り当てることができる. ifconfig-pool-persist ipp.txt # イーサネットブリッジのサーバモードを設定する. # 最初にイーサネットNICインタフェースとTAP # インタフェースをブリッジするOSの機能を有効にし, # それからブリッジインタフェースのIP/ネットマスクを # 手動で指定する必要がある.この例では10.8.0.4/ # 255.255.255.0と仮定する.最後にこのサブネットから # 接続クライアント用のIP範囲を設定する(例では, # 10.8.0.50から10.8.0.100まで). # イーサネットブリッジを使わないならコメントアウトの # ままにしておくこと. ;server-bridge 10.8.0.4 255.255.255.0 10.8.0.50 10.8.0.100 # クライアントに経路を伝え,サーバ後ろのプライベート # サブネットに通信できるようにする.注:これらの # プライベートサブネットも,OpenVPNクライアントの # アドレス空間(10.8.0.0/255.255.255.0)までの経路が # OpenVPNサーバ経由であることを知る必要がある. ;push "route 192.168.10.0 255.255.255.0" ;push "route 192.168.20.0 255.255.255.0" # 特定のクライアントに特定のIPアドレスを与えたい, # 接続クライアントの後ろにVPN接続がほしいプライベート # サブネットがあるなどの場合,クライアント別の設定 # ファイルを格納するサブディレクトリ"ccd"を指定する # (詳しくはmanページを参照). # 例:CN "Thelonious" の証明書を持つクライアントが, # 接続マシンの後ろに小さなサブネット,192.168.40.128/ # 255.255.255.248があるとしよう.まず,次のコメントを # 外し, ;client-config-dir ccd ;route 192.168.40.128 255.255.255.248 # それからファイル ccd/Thelonious を作り次行を追加する. # iroute 192.168.40.128 255.255.255.248 # これにより,TheloniousのプライベートサブネットがVPNに # 接続できるようになる.この例は,ブリッジではなく, # ルーティングモードにしか適用できない.それによって, # "dev tun"と"server"を使う必要がある. # 例:Theloniousに固定VPN IPアドレス10.9.0.1を与えたい # としよう.まず,次のコメントを外し, ;client-config-dir ccd ;route 10.9.0.0 255.255.255.252 # それから以下の行をファイルccd/Theloniousに追加する. # ifconfig-push 10.9.0.1 10.9.0.2 # クライアントをグループ別にファイヤウォールの接続 # ポリシを与えたいとしよう.そのための方法が二つある. # (1)OpenVPNデーモンを複数個稼動させ,グループ一つに # 一つ割り当てる.またグループ/デーモン別のTUN/TAP # インタフェースに対し適切にファイヤウォールする. # (2)(上級)異るクライアントの接続に応じて,動的に # ファイヤウォールを修正するスクリプトを書く. # learn-address scriptについて詳しくはmanページ参照. ;learn-address ./script # これが有効になっている場合,すべてのクライアントが # デフォールトゲートウェイをVPN経由とするようになる. # これにより,Web閲覧やDNS解決を含み,IPトラフィックの # すべてがVPN経由となる(そのため,OpenVPNサーバマシンが # TUN/TAPインタフェースに対しインターネット向けのNATを # 行なう必要がある). # 警告:ローカルDHCPサーバパケットもVPNトンネル経由と # なれば,クライアントのネット設定が潰れるかもしれない. # 解決法:クライアントローカルDHCPサーバがデフォールト # ルート0.0.0.0/0.0.0.0ではない特別なルートを通って # 到達できるように設定すること. ;push "redirect-gateway" # いくつかWindows特有のネットワーク設定をクライアントに # 伝えることができる.例えばDNSやWINSサーバのアドレス. # 警告: # http://openvpn.net/faq.html#dhcpcaveats ;push "dhcp-option DNS 10.8.0.1" ;push "dhcp-option WINS 10.8.0.1" # クライアントが互いに"見える"ようにするには,以下の # コメントを外す.デフォールトでは,クライアントが # サーバしか見えない.なお,強制的にクライアントが # サーバしか見えないようにするには,サーバ側TUN/TAP # インタフェースに対し適切なファイヤウォールをかける # 必要がある. ;client-to-client # 複数のクライアントが同時に同じ証明書/鍵ファイル, # またはCNを使って接続するかもしれない場合,この項目の # コメントを外す.これをテストの目的だけにしよう. # 製品での利用は,各クライアントが自分専用の証明書/鍵 # ペアを持つようにすること. # # 使用注意:クライアント別にユニックなCNを持つ証明書/ # 鍵ペアを生成していない場合,次のコメントを外す. ;duplicate-cn # 項目keepaliveは,pingみたいなメッセージをリンク間で # 往来に流すことにより,相手がダウンしているか否かを # チェックする.この例では,10秒間隔に一回ping,そして # 120秒間待っても返信がなければ遠隔ピアがダウンしたと # 判断する. keepalive 10 120 # SSL/TLSの提供するセキュリティよりも安全性を高めるには, # "HMACファイヤウォール"を作って,DoS攻撃やUDPポート # フラッディングに抵抗する. # # 生成方法: # openvpn --genkey --secret ta.key # # サーバと各クライアントはこの鍵のコピーを持つ必要がある. # 二番目のパラメータについて,サーバ側で'0',クライアント # 側で'1'である必要がある. ;tls-auth ta.key 0 # このファイルを秘密にすること. # 暗号方式選択.この選択をクライアントの設定ファイルにも # コピーしなければならない. ;cipher BF-CBC # Blowfish(デフォールト) ;cipher AES-128-CBC # AES ;cipher DES-EDE3-CBC # Triple-DES # VPNリンクに対する圧縮を有効にする.ここで有効に # したら,クライアントのほうも有効にすること. comp-lzo # 許可する同時接続クライアント数の上限. ;max-clients 100 # 初期化したらOpenVPNデーモンの権限を落すのがよいアイディア. # # 非Windowsシステムにおいては,次のコメントを外しておく. user nobody group nobody # オプションpersisi-*によって,再起動時に,権限を落した # ことでアクセスできなくなった資源に対するアクセスを避ける # ことができる. persist-key persist-tun # 現在の接続状況をファイルに出力する.この小ファイルは, # 一分間単位で内容が消されて上書きされる. status openvpn-status.log # デフォールトではログメッセージがsyslog(Windowsの場合, # サービスとして稼動しているなら,ディレクトリ # "\Program Files\OpenVPN\log")に送られる.logまたは # log-appendでこのデフォールトを無効にすることができる. # "log"ではOpenVPN起動時にログファイルの内容が消される. # 一方"log-append"によって内容が追加される.一個だけを # 用いること(同時に使ってはならない). ;log openvpn.log ;log-append openvpn.log # ログファイルの詳細さについて適切なレベルを指定する. # # 0は,致命的なエラー以外になし. # 4は,一般的の用途には妥当である. # 5と6は接続の問題をデバッグするのに役立つ. # 9は非常に詳細である. verb 3 # 連続した重複メッセージを抑制する.この設定例では,同じ # メッセージカテゴリに属する連続のメッセージが,最大でも # 20個だけログに出力される. ;mute 20
設定ファイル例/client.conf |
############################################## # OpenVPN 2.0 クライアント用設定ファイル例 # # これで複数クライアントのサーバに接続できる # # # # この設定が複数のクライアントで共用できるが # # それぞれのクライアントが自分専用のcertと # # keyファイルを持つべき. # # # # Windowsにおいては,ファイルの拡張子が.ovpn # # となるように名前を変えよう. # ############################################## # クライアントであることを指定する.また,後で # サーバ設定ファイルから設定項目を取ってくる. client # ここでサーバと同じ設定を用いること. # 大半のシステムにおいて,TUN/TAPインタフェース # に対し,ファイヤウォールを一部または全部無効に # しないとVPNが正常に動作しなかろう. ;dev tap dev tun # Windowsにおいて,TAP-Win32アダプタが複数ある # 場合,ネットワーク接続パネルから名前を確認し # ここで設定する必要がある.XP SP2以上の場合, # TAPアダプタに対し,Windowsファイヤウォールを # 選択して無効にする必要があるかもしれない. ;dev-node MyTap # 接続するサーバがTCPを使うかUDPを使うか. # サーバと同じように設定すること. ;proto tcp proto udp # サーバのホスト名/IPとポート. # サーバの負荷分散に複数個設定してよい. remote my-server-1 1194 ;remote my-server-2 1194 # 負荷分散のため遠隔ホストリストからランダムに # 選ぶか否かを指定する.指定しない場合は,上で # 示された順に接続を試みる. ;remote-random # OpenVPNサーバホスト名の解決を永久に試みる. # これは,ラップトップのようなインターネットに # 常時接続していないマシンに対して極めて有効. resolv-retry infinite # 大半のクライアントは特定なローカルポート番号を # バインドする必要がない. nobind # 初期化したら権限を落す(非Windowsのみ) user nobody group nobody # 再起動のために状態をいくつか覚えておく. persist-key persist-tun # HTTPプロキシ経由で本当のOpenVPNサーバに # 接続しているなら,プロキシサーバ/IPと # ポートをここにおく.プロキシサーバが # 認証を要求する場合は,manページを参照. ;http-proxy-retry # 接続失敗の場合は再試する ;http-proxy [proxy server] [proxy port #] # ワイヤレスネットワークはよく重複パケットを # たくさん作ってしまう.このフラッグを設定し # 重複パケットに対する警告を止める. ;mute-replay-warnings # SSL/TLSパラメータ. # 詳しくはサーバの設定ファイルを参照. # クライアント別に異る .crt/.key ペアを # 用いることが最善であろう.caファイルは # すべてのクライアント間で共用してもよい. ca ca.crt cert client.crt key client.key # サーバ証明書のnsCertTypeフィールドが"server"に # 設定されているか検証する.これは#mitmで考えた # 起こり得る攻撃に対し,抵抗策として重要である. # # これを利用するには,nsCertTypeフィールドが # "server"となるようにサーバの証明書を生成する # 必要がある.easy-rsaフォルダにあるスクリプト # build-key-serverがこのために使える. ;ns-cert-type server # サーバ側でtls-auth鍵が使われていたら, # クライアントも全員この鍵を持つ必要がある. ;tls-auth ta.key 1 # 暗号方式選択. # サーバがこのオプションを使っていたら, # それをここで指定する必要がある. ;cipher x # VPNリンクに対する圧縮を有効にする. # サーバの設定ファイルに使われていないなら # ここでも有効にしてはならない. comp-lzo # ログファイルの詳細度を指定する. verb 3 # 重複メッセージを抑制する. ;mute 20