構成図
PCmは、社外にあるパソコンです。例えば、自宅にある個人用のパソコンや出張先に持ち出した会社のパソコンなどです。利用者はインターネットサービスプロバイダー(以降ISPと略します)と契約しており、モバイルデータ通信カードをパソコンに装備しています。この例では、ISPに接続した結果、グローバルIPアドレス1.0.0.1/32が割り当てられたと仮定します。
この例における事業所は、2.0.0.8/29のグローバルIPアドレスを持っています。また、社内ネットワークには192.168.0.0/24のプライベートIPアドレスが割り当てられています。
Ex.RTは、ISPに接続する為の外部ルーターです。IPSとはアンナンバードで接続しているので、回線側のインターフェース(WAN)にIPアドレスはありません。一方、LAN側のインターフェース(LAN)にはIPアドレスが設定されています。Ex.RTは、2.0.0.8/29のサブネットに設置されているホストにとってのデフォルトゲートウェイです。
In.RTは、外部に公開するネットワーク(2.0.0.8/29)と外部に公開しないネットワーク(192.168.0.0/24)とを接続する内部ルーターです。In.RTは、IPマスカレードの機能を有し、社内ネットワークのパソコンから外部ネットワークにアクセスする際、外部に向かうパケットの発信元IPアドレスとTCP/UDPポートを適切に変換します。In.RTは、192.168.0.0/24のサブネットに設置されているホストにとってのデフォルトゲートウェイです。
VPNは、VPNサーバーです。VPNとIn.RTは一つのホストの上で実行することができるかもしれません。むしろ、その方がグローバルIPアドレスを一つ節約できます。ですが、In.RTがネットワーク専用のボックスでソフトウェアを追加出来ない場合や、単にIn.RTに変更を加えたくないときは、VPNサーバーをIn.RTとは別のホストにインストールしてください。
PCoは、社内ネットワークの中にあるパソコンです。
FTPは、社内でファイルを共有するためのファイルサーバーです。このホストでは、社内ネットワークからのみFTPの利用ができるようにTCP Wrapperが設定されていると仮定します。
OpenVPNでは、接続相手を認証したり暗号鍵を生成したりするときに、静的鍵を用いる方法と電子証明書を用いる方法があります。
静的鍵とはVPNサーバーとVPNクライアントが共通で使用する1つの秘密鍵のことです。具体的にはシステム管理者が事前に文字列を決め、それを書き込んだテキストファイルをサーバーとクライアントに保存します。
静的鍵を用いる場合の長所はVPNを容易に構築できることです。この方法では電子証明書を使いませんので、認証局の設置や運用に掛る手間が省けます。
その反面、拡張性が低いという短所があります。この方法では1台のVPNサーバー(プロセス)に対して1台のVPNクライアントしか接続できません。
もし、VPNクライアントが1台しかなく、とにかくOpenVPNを使ってみたいというのであれば、静的鍵を利用したVPNを構築すると良いでしょう。
とはいえ、この記事では静的鍵を用いた具体的な構築方法については割愛しています。(この記事がお役に立てなくて残念です。)
電子証明書を利用する場合は、基本的に、個々のホストがそれぞれ固有の証明書を保持します。例えば、VPNクライアントが3台あったとすると、VPNサーバーおよび認証局(CA)の証明書を合わせて、合計5つの証明書が必要になります。もし、個々のパソコンにそれぞれ証明書を発行するのは管理が煩わしいというのであれば、複数のVPNクライアントで一つの証明書を共通して利用することもできます。
電子証明書を用いる場合の利点は複数のVPNクライアントを同時にVPNサーバーに接続できることです。
その反面、電子証明書を発行する認証局を必要としますので、設定と運用に少し手間が掛ります。
公に利用できる(パブリック)電子証明書を運用しようとすると、サービスプロバイダー、例えばベリサイン社などのサービスを利用しなければならず費用がかかります。費用は、導入時の初期費用の他にも証明書を更新する際にも発生します。ですが、私的利用に限った(プライベート)電子証明書であれば費用はかかりません。それに、世間で云われているほど難しいものではありません。
社外にあるパソコンをVPNを通じて社内ネットワークに接続するとき、そのパソコンに割り当てるIPアドレスを考えなければなりません。構成図に示したPCmは既にISPからグローバルIPアドレス1.0.0.1/32が割り当てられていますが、実はもう一つ、トンネルの終端のIPアドレスについても検討する必要があります。
VPNは、インターネットの中にあたかも二地点間だけを結ぶ仮想的な専用通信回線を作ります。これをトンネルと呼びます。以下に概念図を示します。
+--------------+ ############## +--------------+ | VPN Client | # Internet # | VPN Server | | | # # | | | tun/tap +---------- ----------+ tun/tap +-------------------- | ===|====================================|=== | | +---------- Tunnel ----------+ +-------------------- | PPP | # # | re0 rl0 | Private Network | | # # | | +--------------+ ############## +--------------+
TUN/TAPはトンネルインターフェースのデバイス名です。
VPNサーバーの社内ネットワーク側のインターフェースrl0のIPアドレスは192.168.0.253/24です。設計者はトンネルインターフェースに割り当てるIPアドレスを社内ネットワークと同じ192.168.0.0/24に含めるか、それとも、10.8.0.0/24など異なるサブネットに含めるかを決めなければなりません。
トンネルインターフェースに割り当てるIPアドレスを社内ネットワークと違うサブネットワークに含める場合、VPNクライアントはVPNサーバー内のルーター機能によって社内ネットワークと接続されます。
+--------------+ ############## +--------------+ | VPN Client | # Internet # | VPN Server | | | # # | | | tun/tap +---------- ----------+ tun +-------------------- | ===|====================================|===+{ROUTER}+ | +---------- (10.8.0.0/24) ----------+ +-------------------- | PPP | # # | re0 rl0 | (192.168.0.0/24) | | # # | | +--------------+ ############## +--------------+
ルーティング接続するときは、TUNデバイスを使用します。
以下にインターフェースの状態とルーティングテーブルがどのように変化するか具体例を示します。
VPNサーバーのインターフェース
先ず、VPNサーバーのインターフェースについて、VPNサーバー(プロセス)を実行する前と実行中の状態を比べます。
[root@localhost ~]# ifconfig |
rl0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500 ether 00:01:80:40:f8:be inet 192.168.0.253 netmask 0xffffff00 broadcast 192.168.0.255 media: Ethernet autoselect (100baseTX <full-duplex>) status: active re0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500 ether 00:0a:79:69:f2:95 inet 2.0.0.12 netmask 0xfffffff8 broadcast 2.0.0.15 media: Ethernet autoselect (100baseTX <full-duplex>) status: active |
[root@localhost ~]# ifconfig |
rl0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500 ether 00:01:80:40:f8:be inet 192.168.0.253 netmask 0xffffff00 broadcast 192.168.0.255 media: Ethernet autoselect (100baseTX <full-duplex>) status: active re0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500 ether 00:0a:79:69:f2:95 inet 2.0.0.12 netmask 0xfffffff8 broadcast 2.0.0.15 media: Ethernet autoselect (100baseTX <full-duplex>) status: active tun0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> metric 0 mtu 1500 inet 10.8.0.1 --> 10.8.0.2 netmask 0xffffffff Opened by PID 1471 |
実行中のVPNサーバーにはインターフェースtun0が生成されています。tunは仮想的なPoint-to-pointネットワークデバイスです。この場合10.8.0.1が自分(VPNサーバー)側のアドレスで、10.8.0.2が相手(VPNクライアント)側のアドレスです。
VPNサーバーのルーティングテーブル
次は、VPNサーバーのルーティングテーブルについて、VPNサーバー(プロセス)を実行する前と実行中の状態を比べます。
[root@localhost ~]# netstat -r |
Routing tables Internet: Destination Gateway Flags Refs Use Netif Expire default 2.0.0.14 UGS 0 0 re0 localhost link#5 UH 0 0 lo0 192.168.0.0 link#1 U 0 29 rl0 192.168.0.253 link#1 UHS 0 0 lo0 2.0.0.8/29 link#2 U 1 10 re0 2.0.0.12 link#2 UHS 0 0 lo0 |
[root@localhost ~]# netstat -r |
Routing tables Internet: Destination Gateway Flags Refs Use Netif Expire default 2.0.0.14 UGS 1 103 re0 10.8.0.0 10.8.0.2 UGS 0 0 tun0 10.8.0.1 link#7 UHS 0 0 lo0 10.8.0.2 link#7 UH 0 0 tun0 localhost link#5 UH 0 0 lo0 192.168.0.0 link#1 U 0 59 rl0 192.168.0.253 link#1 UHS 0 0 lo0 2.0.0.8/29 link#2 U 1 22 re0 2.0.0.12 link#2 UHS 0 0 lo0 |
実行中のVPNサーバーのルーティングテーブルには、1つのネットワークのエントリーと2つのホストのエントリー、合計3つのエントリーがOpenVPNによって追加されています。10.8.0.0はネットワークのエントリーで、そのサブネットに到達するためのネクストホップは10.8.0.2、出力インターフェースはtun0です。
このエントリーは少し混乱するかもしれませんので注意してください。VPNサーバーは自ホスト内に10.8.0.1のインターフェースを持っています。ですから、ネットワーク10.8.0.0には直接つながっていることになるのですが、ネットワーク10.8.0.0宛のパケットをゲートウェイ(相手側のトンネルインターフェース10.8.0.2)に送っています。
VPNクライアントのインターフェース
次は、VPNクライアントのインターフェースの状態について接続前と接続後を比べます。
C:\>ipconfig |
PPP アダプタ isp.domain: 接続固有の DNS サフィックス . . . : 説明. . . . . . . . . . . . . . . : isp.domain 物理アドレス. . . . . . . . . . . : DHCP 有効 . . . . . . . . . . . . : いいえ IPv4 アドレス . . . . . . . . . . : 1.0.0.1(優先) サブネット マスク . . . . . . . . : 255.255.255.255 デフォルト ゲートウェイ . . . . . : 0.0.0.0 NetBIOS over TCP/IP . . . . . . . : 無効 イーサネット アダプタ ローカル エリア接続 2: メディアの状態. . . . . . . . . . : メディアは接続されていません 接続固有の DNS サフィックス . . . : 説明. . . . . . . . . . . . . . . : TAP-Win32 Adapter V9 物理アドレス. . . . . . . . . . . : 00-FF-8A-DF-A7-A6 DHCP 有効 . . . . . . . . . . . . : はい |
C:\>ipconfig |
PPP アダプタ isp.domain: 接続固有の DNS サフィックス . . . : 説明. . . . . . . . . . . . . . . : isp.domain 物理アドレス. . . . . . . . . . . : DHCP 有効 . . . . . . . . . . . . : いいえ IPv4 アドレス . . . . . . . . . . : 1.0.0.1(優先) サブネット マスク . . . . . . . . : 255.255.255.255 デフォルト ゲートウェイ . . . . . : 0.0.0.0 NetBIOS over TCP/IP . . . . . . . : 無効 イーサネット アダプタ ローカル エリア接続 2: 接続固有の DNS サフィックス . . . : 説明. . . . . . . . . . . . . . . : TAP-Win32 Adapter V9 物理アドレス. . . . . . . . . . . : 00-FF-8A-DF-A7-A6 DHCP 有効 . . . . . . . . . . . . : はい IPv4 アドレス . . . . . . . . . . : 10.8.0.6(優先) サブネット マスク . . . . . . . . : 255.255.255.252 リース取得. . . . . . . . . . . . : 2010年6月4日 14:36:47 リースの有効期限. . . . . . . . . : 2011年6月4日 14:36:47 デフォルト ゲートウェイ . . . . . : DHCP サーバー . . . . . . . . . . : 10.8.0.5 NetBIOS over TCP/IP . . . . . . . : 有効 |
VPNサーバーに接続した結果、VPNクライアントのトンネルインターフェースには、IPアドレス10.8.0.6が割り当てられました。
VPNクライアントのルーティングテーブル
最後に、VPNクライアントのルーティングテーブルについて接続前と接続後を比べます。
C:\>netstat -r IPv4 ルート テーブル ======================================== アクティブ ルート: ネットワーク宛先 ネットマスク ゲートウェイ インターフェイス メトリック 0.0.0.0 0.0.0.0 リンク上 1.0.0.1 31 1.0.0.1 255.255.255.255 リンク上 1.0.0.1 286 127.0.0.0 255.0.0.0 リンク上 127.0.0.1 4531 127.0.0.1 255.255.255.255 リンク上 127.0.0.1 4531 127.255.255.255 255.255.255.255 リンク上 127.0.0.1 4531 (省略) ======================================== 固定ルート: なし |
C:\>netstat -r |
IPv4 ルート テーブル ======================================== アクティブ ルート: ネットワーク宛先 ネットマスク ゲートウェイ インターフェイス メトリック 0.0.0.0 0.0.0.0 リンク上 1.0.0.1 31 10.8.0.1 255.255.255.255 10.8.0.5 10.8.0.6 4256 10.8.0.4 255.255.255.252 リンク上 10.8.0.6 4511 10.8.0.6 255.255.255.255 リンク上 10.8.0.6 4511 10.8.0.7 255.255.255.255 リンク上 10.8.0.6 4511 1.0.0.1 255.255.255.255 リンク上 1.0.0.1 286 127.0.0.0 255.0.0.0 リンク上 127.0.0.1 4531 127.0.0.1 255.255.255.255 リンク上 127.0.0.1 4531 127.255.255.255 255.255.255.255 リンク上 127.0.0.1 4531 192.168.0.0 255.255.255.0 10.8.0.5 10.8.0.6 4256 (省略) ======================================== 固定ルート: なし |
OpenVPNのクライアントはVPNサーバーとは違うアドレスを持った仮想的なPoint-to-pointネットワークを作っています。
そのIPネットワークアドレスは10.8.0.4/30、自分(VPNクライアント)側のアドレスは10.8.0.6、相手側(VPNサーバー)側にアドレスは10.8.0.5、10.8.0.7はブロードキャストアドレスです。
注目する点は、192.168.0.0/24のネットワークのエントリーが追加されていることです。このエントリーがあるおかげで、VPNクライアントは社内ネットワーク内の資源にアクセスすることができます。
トンネルのインターフェースに割り当てるIPアドレスを社内ネットワークと同じサブネットワークに含める場合、VPNクライアントはVPNサーバー内のブリッジ機能によって社内ネットワークと接続されます。
+--------------+ ############## +--------------+ | VPN Client | # Internet # | VPN Server | | | # # | | | tun/tap +---------- ----------+ tap +-------------------- | ===|====================================|===+{BRIDGE}+ | +--------- (192.168.0.0/24) ---------+ +-------------------- | PPP | # # | re0 rl0 | (192.168.0.0/24) | | # # | | +--------------+ ############## +--------------+
ブリッジング接続するときは、TAPデバイスを使用します。
このとき、VPNサーバーの社内ネットワーク側のインターフェースrl0にはIPドレスは割り当てられません。ネットワーク管理者は、先ず、VPNサーバー内にブリッジインターフェース、例えばbridge0を作成します。次いでrl0とトンネルインターフェースtap0をブリッジインターフェースにメンバーとして加えます。
一連の流れは次のようになります。
以下にインターフェースの状態とルーティングテーブルがどのように変化するか具体例を示します。
VPNサーバーのインターフェース
先ず、VPNサーバーのインターフェースについて、VPNサーバー(プロセス)を実行する前と実行中の状態を比べます。
[root@localhost ~]# ifconfig |
rl0: flags=8802<BROADCAST,SIMPLEX,MULTICAST> metric 0 mtu 1500 ether 00:01:80:40:f8:be media: Ethernet autoselect status: active re0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500 ether 00:0a:79:69:f2:95 inet 2.0.0.12 netmask 0xfffffff8 broadcast 2.0.0.15 media: Ethernet autoselect (100baseTX <full-duplex>) status: active |
CENTER【図4-12】実行前のVPNサーバーのインターフェース(ブリッジングの場合)
[root@localhost ~]# ifconfig |
rl0: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> metric 0 mtu 1500 ether 00:01:80:40:f8:be media: Ethernet autoselect (100baseTX <full-duplex>) status: active re0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500 ether 00:0a:79:69:f2:95 inet 2.0.0.12 netmask 0xfffffff8 broadcast 2.0.0.15 media: Ethernet autoselect (100baseTX <full-duplex>) status: active bridge0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500 ether 72:4a:14:91:ab:1b inet 192.168.0.253 netmask 0xffffff00 broadcast 192.168.0.255 id 00:00:00:00:00:00 priority 32768 hellotime 2 fwddelay 15 maxage 20 holdcnt 6 proto rstp maxaddr 100 timeout 1200 root id 00:00:00:00:00:00 priority 32768 ifcost 0 port 0 member: rl0 flags=143<LEARNING,DISCOVER,AUTOEDGE,AUTOPTP> ifmaxaddr 0 port 1 priority 128 path cost 55 member: tap0 flags=143<LEARNING,DISCOVER,AUTOEDGE,AUTOPTP> ifmaxaddr 0 port 8 priority 128 path cost 2000000 tap0: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> metric 0 mtu 1500 ether 00:bd:7d:d0:0b:00 Opened by PID 1339 |
実行中のVPNサーバーにはブリッジインターフェースbridge0とトンネルインターフェースtap0が生成されています。bridge0はそのメンバーとしてrl0とtap0を含んでいます。
注目する点は、bridge0にIPアドレスが割り当てられており、rl0にはIPアドレスが割り当てられていないこと。また、rl0にPROMISCフラグがセットされていることです。
VPNサーバーのルーティングテーブル
次は、VPNサーバーのルーティングテーブルについて、VPNサーバー(プロセス)を実行する前と実行中の状態を比べます。
[root@localhost ~]# netstat -r |
Routing tables Internet: Destination Gateway Flags Refs Use Netif Expire default 219.96.231.102 UGS 0 0 re0 localhost link#5 UH 0 0 lo0 2.0.0.8/29 link#2 U 1 6 re0 2.0.0.12 link#2 UHS 0 0 lo0 |
[root@localhost ~]# netstat -r |
Routing tables Internet: Destination Gateway Flags Refs Use Netif Expire default 219.96.231.102 UGS 1 113 re0 localhost link#5 UH 0 0 lo0 192.168.0.0 link#7 U 0 0 bridge 192.168.0.253 link#7 UHS 0 0 lo0 2.0.0.8/29 link#2 U 1 12 re0 2.0.0.12 link#2 UHS 0 0 lo0 |
VPNサーバーを実行すると、bridgeに割り当てたIPホストアドレスとIPネットワークアドレスのエントリーが追加されます。
VPNクライアントのインターフェース
次は、VPNクライアントのインターフェースの状態について接続前と接続後を比べます。
C:\>ipconfig PPP アダプタ isp.domain: 接続固有の DNS サフィックス . . . : 説明. . . . . . . . . . . . . . . : isp.domain 物理アドレス. . . . . . . . . . . : DHCP 有効 . . . . . . . . . . . . : いいえ IPv4 アドレス . . . . . . . . . . : 1.0.0.1(優先) サブネット マスク . . . . . . . . : 255.255.255.255 デフォルト ゲートウェイ . . . . . : 0.0.0.0 NetBIOS over TCP/IP . . . . . . . : 無効 イーサネット アダプタ ローカル エリア接続 2: メディアの状態. . . . . . . . . . : メディアは接続されていません 接続固有の DNS サフィックス . . . : 説明. . . . . . . . . . . . . . . : TAP-Win32 Adapter V9 物理アドレス. . . . . . . . . . . : 00-FF-8A-DF-A7-A6 DHCP 有効 . . . . . . . . . . . . : はい |
C:\>ipconfig PPP アダプタ isp.domain: 接続固有の DNS サフィックス . . . : 説明. . . . . . . . . . . . . . . : isp.domain 物理アドレス. . . . . . . . . . . : DHCP 有効 . . . . . . . . . . . . : いいえ IPv4 アドレス . . . . . . . . . . : 1.0.0.1(優先) サブネット マスク . . . . . . . . : 255.255.255.255 デフォルト ゲートウェイ . . . . . : 0.0.0.0 NetBIOS over TCP/IP . . . . . . . : 無効 イーサネット アダプタ ローカル エリア接続 2: 接続固有の DNS サフィックス . . . : 説明. . . . . . . . . . . . . . . : TAP-Win32 Adapter V9 物理アドレス. . . . . . . . . . . : 00-FF-8A-DF-A7-A6 DHCP 有効 . . . . . . . . . . . . : はい IPv4 アドレス . . . . . . . . . . : 192.168.0.240(優先) サブネット マスク . . . . . . . . : 255.255.255.0 リース取得. . . . . . . . . . . . : 2010年6月4日 16:18:35 リースの有効期限. . . . . . . . . : 2011年6月4日 16:18:35 デフォルト ゲートウェイ . . . . . : NetBIOS over TCP/IP . . . . . . . : 有効 |
VPNサーバーに接続した結果、VPNクライアントのトンネルインターフェースには、192.168.0.240/24が割り当てられました。このIPアドレスのネットワークプレフィックスは、社内ネットワークのそれと同じです。
VPNクライアントのルーティングテーブル
最後に、VPNクライアントのルーティングテーブルについて接続前と接続後を比べます。
C:\>netstat -r IPv4 ルート テーブル ============================================= アクティブ ルート: ネットワーク宛先 ネットマスク ゲートウェイ インターフェイス メトリック 0.0.0.0 0.0.0.0 リンク上 1.0.0.1 31 1.0.0.1 255.255.255.255 リンク上 1.0.0.1 286 127.0.0.0 255.0.0.0 リンク上 127.0.0.1 4531 127.0.0.1 255.255.255.255 リンク上 127.0.0.1 4531 127.255.255.255 255.255.255.255 リンク上 127.0.0.1 4531 (省略) ============================================= 固定ルート: なし |
C:\>netstat -r IPv4 ルート テーブル ================================================== アクティブ ルート: ネットワーク宛先 ネットマスク ゲートウェイ インターフェイス メトリック 0.0.0.0 0.0.0.0 リンク上 1.0.0.1 31 1.0.0.1 255.255.255.255 リンク上 1.0.0.1 286 127.0.0.0 255.0.0.0 リンク上 127.0.0.1 4531 127.0.0.1 255.255.255.255 リンク上 127.0.0.1 4531 127.255.255.255 255.255.255.255 リンク上 127.0.0.1 4531 192.168.0.0 255.255.255.0 リンク上 192.168.0.240 4511 192.168.0.240 255.255.255.255 リンク上 192.168.0.240 4511 192.168.0.255 255.255.255.255 リンク上 192.168.0.240 4511 (省略) ================================================== 固定ルート: なし |
VPNクライアントには192.168.0.240が割り当てられましたので、192.168.0.0/24の社内ネットワークに直接つながっていることを示すエントリーがあります。
VPNサーバーを設置するためには、まず、必要なファイルをホストにコピーするインストール作業を行い、その後どのように動作するかを指示する設定作業を行います。
VPNサーバーにインストールするファイルは2種類あります。一つはソフトウェアのコード群、そしてもう一つは電子証明書等です。
OpenVPNのソフトウェアをインストールすること自体は難しい作業ではありません。
この記事では、FreeBSD 8.0-RELEASEにopenvpn-2.0.6をインストールしています。FreeBSDにopenvpnのパッケージを追加する場合は、次のコマンドを実行します。
[root@localhost ~]# pkg_add -r openvpn |
また、PORTコレクションを使って、make installする方法もあります。この場合はPORTコレクションの情報を更新してからmakeコマンドを実行して下さい。
Linuxにインストールする場合は、dpkgやaptitudeあるいはrpmやyumなど各ディストリビューションに合ったコマンドでインストールしてください。
もちろん、OpenVPNのウェブサイトからソースコードをダウンロードして、コンパイルおよびインストールすることもできます。
認証局(CA)の証明書と秘密鍵
OpenVPNをインストールすると、ディレクトリー/usr/local/share/doc/openvpn/easy-rsa/2.0/に電子証明書を作成するためのスクリプトが展開されます。
OpenVPNのHOWTOには、認証局(Certificate Authority: CA)の証明書と秘密鍵を生成するために、スクリプトbuild-caを実行するように説明されています。
[root@localhost ~]# ./build-ca |
ですが、必ずしもこのスクリプトを使う必要はありません。例えば、IEEE802.1x EAP-TLSによる無線LAN端末の認証を行う為に既に私的な認証局を設置している場合は、その認証局を利用する方が望ましいでしょう。
スクリプトbuild-caは、スクリプトpkitoolを実行します。
[root@localhost ~]# pkitool --interact --initca |
pkitoolは、同じディレクトリの中にあるスクリプトです。pkitoolの中でCAの証明書と秘密鍵を生成する部分は次のとおりです。
$OPENSSL req $BATCH -days $CA_EXPIRE $NODES_REQ -new -x509 -keyout "$CA.key" -out "$CA.crt" -config "$KEY_CONFIG" |
$OPENSSLはスクリプトの中でopensslと定義されています。上のコマンドを書き直すとおおよそ次のようになります。
openssl req -days 3650 -nodes -new -x509 -keyout ca.key -out ca.crt -config openssl.cnf |
なお、OpenSSLのウェブサイトにある"HOWTO certificates <DRAFT!>"を見ると、上のようなコマンドでCAの証明書を作成することを推奨していません。CAの証明書を作成するときは、OpenSSLのパッケージに含まれるスクリプトCA.plなどを使ったほうが良いでしょう。
[root@localhost ~]# ./CA.pl -newca |
このコマンドを実行し質問に答えていけば、2つのファイルが出来上がります。
cacert.pem cakey.pem |
cacert.pemはCAの証明書、cakey.pemはCAの秘密鍵です。
VPNサーバーの証明書と秘密鍵
CAの証明書が出来たら、VPNサーバーの証明書と秘密鍵を作成します。OpenVPNのHOWTOには、VPNサーバーやVPNクライアントの証明書と秘密鍵を生成するために、スクリプトbuild-reqとsign-reqを実行するように説明されています。
[root@localhost ~]# ./build-key-server server |
スクリプトbuild-key-serverはスクリプトpkitoolを実行します。
[root@localhost ~]# pkitool --interact --server |
スクリプトpkitoolの中でサーバーの証明書と秘密鍵を生成する部分は次のとおりです。
[root@localhost ~]# $OPENSSL req $BATCH -days $KEY_EXPIRE $NODES_REQ -new -keyout "$KEY_CN.key" -out "$KEY_CN.csr" $REQ_EXT -config "$KEY_CONFIG" |
[root@localhost ~]# $OPENSSL ca $BATCH -days $KEY_EXPIRE -out "$KEY_CN.crt" -in "$KEY_CN.csr" $CA_EXT -config "$KEY_CONFIG" |
大まかに述べると、"openssl req"コマンドで証明書のリクエストを作成し、"openssl ca"コマンドで認証局の秘密鍵を使ってサインしています。
OpenSSLのパッケージに含まれているCA.plを使用する場合は、次のように実行します。
[root@localhost ~]# ./CA.pl -newreq-nodes |
[root@localhost ~]# ./CA.pl -sign |
直接opensslを実行するなら、次のようにします。
[root@localhost ~]# openssl req -new -nodes -keyout newkey.pem -out newreq.pem -days 3650 -config openssl.cnf |
[root@localhost ~]# openssl ca -policy policy_anything -out newcert.pem -infiles newreq.pem -config openssl.cnf |
このコマンドを実行し質問に答えていけば、次の3つのファイルが出来上がります。
newcert.pem newkey.pem newreq.pem |
このうち、2つのファイルの名前を変更し、1つのファイルを捨てます。
[root@localhost ~]# mv ./newcert.pem ./vpncert.pem |
[root@localhost ~]# mv ./newkey.pem ./vpnkey.pem |
[root@localhost ~]# rm ./newreq.pem |
vpncert.pemはVPNサーバーの証明書、vpnkey.pemはVPNサーバーの秘密鍵です。
./build-key-serverを使うと証明書の有効期間が3650日(約10年)になります。一方、CA.plでは365日になります。CA.plを使うときはスクリプトの中の有効期間の値を変更してください。次の例は一般の証明書の有効期間を1095日(約3年)、認証局の証明書の有効期間を3650日に設定しています。
$DAYS="-days 1095"; # 3 year |
$CADAYS="-days 3650"; # 10 years |
CAとVPNの証明書ができたら、VPNサーバー証明書とVPNサーバー秘密鍵をVPNサーバー(ホスト)の任意のディレクトリに移動し、CA証明書をVPNサーバーにコピーします。ディレクトリはどこでもかまいません。例えば、/etc/openvpn/や/etc/ssl/などです。この記事では定石を避け、あえて/etc/ssl/にコピーします。(OpenVPNのHOWTOでは、ソフトウェアパッケージをインストールしたあと、電子証明書などを作成する前に、ディレクトリ/usr/local/share/doc/openvpn/easy-rsa/を/etc/openvpnなどにコピーすることをすすめています。デフォルトのまま使用し、ディレクトリeasy-rsa/の中に証明書のデータベースを作成すると、パッケージをアップグレードしたときにそれらが破壊されるかもしれないからです。)
ただし、ディレクトリがどこであれ、VPNサーバーの秘密鍵は所有者だけが読みだせるようにアクセス権を変更することを忘れないでください。
それからもう一つ、Diffie Hellman(DH)パラメータを作成して、これもVPNサーバーの任意のディレクトリに格納して下さい。証明書を格納したディレクトリで良いでしょう。
DHパラメータはOpenVPNのパッケージに含まれているスクリプトbuild-dhで作成することができます。
opensslコマンドを使う場合は次のようにします。
openssl dhparam -out dh1024.pem 1024 |
VPNクライアントもVPNサーバーと同じように、ソフトウェアと電子証明書をインストールします。
自宅にあるパソコンや社外に持ち出すパソコンは、多くの場合、マイクロソフト社のWindows OSを搭載していると思います。このような場合は、Mathias Sundmanが開発したOpenVPN GUI for Windowsを使うと操作が簡単です。
インストール用パッケージはOpenVPN GUI for WIndowsのウェブサイトからダウンロードできます。
また、OpenVPN 2.1.1からはWindows用インストーラーの中にOpenVPN GUIが含まれています。
インストールは、ダウンロードした.exeファイルを実行し、画面の指示に従うだけです。途中、TAP-Win32というデバイスをインストールするときに、管理者の許可が求められるかもしれません。
OpenVPNのクライアントに電子証明書をインストールするには、通常、VPNクライアントの証明書と秘密鍵それにCAの証明書をそれぞれ別のファイルとして任意のディレクトリにコピーします。
OpenVPNのHOWTOには、クライアントの証明書と秘密鍵を生成するために、ディレクトリ/usr/local/share/doc/openvpn/easy-rsa/2.0/の中にあるスクリプトbuild-keyまたはbuild-key-passを実行するように説明されています。
[root@localhost ~]# ./build-key client1 |
スクリプトbuild-keyは、スクリプトpkitoolを実行します。
pkitool --interact |
OpenSSLのパッケージに含まれているCA.plを使用する場合は、次のように実行します。
[root@localhost ~]# ./CA.pl -newreq-nodes |
[root@localhost ~]# ./CA.pl -sign |
[root@localhost ~]# mv ./newcert.pem ./pc01cert.pem |
[root@localhost ~]# mv ./newkey.pem ./pc01key.pem |
[root@localhost ~]# rm ./newreq.pem |
pc01cert.pemはVPNクライアントの証明書、pc01key.pemはVPNクライアントの秘密鍵です。
CAの証明書、VPNクライアントの証明書、VPNクライアントの秘密鍵をクライアントのホストに格納するとき、3つのファイルを1つのPKCS#12形式のファイルにまとめて格納することもできます。
[root@localhost ~]# ./CA.pl -newreq-nodes |
[root@localhost ~]# ./CA.pl -sign |
[root@localhost ~]# ./CA.pl -pkcs12 |
[root@localhost ~]# mv ./newcert.pem ./pc01cert.pem |
[root@localhost ~]# mv ./newkey.pem ./pc01key.pem |
[root@localhost ~]# mv ./newcert.p12 ./pc01cert.p12 |
[root@localhost ~]# rm ./newreq.pem |
拡張子.p12を持ったファイルがPKCS#12形式のファイルです。
OpenVPNのパッケージに含まれているスクリプトを使うときは次のようにします。
[root@localhost ~]# ./build-key-pkcs12 client1 |
この結果、次の4つのファイルができます。
client1.csr client1.key client1.crt client1.p12 |
client1.csrはVPNクライアントの証明書要求、client1.keyはVPNクライアントの秘密鍵、client1.crtはVPNクライアントの証明書、そしてclient1.p12がPKCS#12形式のファイルです。
作成した証明書などをOpenVPNのためだけに使うのであれば、3つのファイルをわざわざ1つにまとめる必要はありません。ですが、証明書を他の用途、例えば無線LAN認証などにも利用したいのであれば、PKCS#12形式のファイルを使うことをお勧めします。なぜなら、3つのファイルがばらばらだと、Windows OSで証明書や秘密鍵を管理するユーティリティ、certmgr.mscにインポート出来ないからです。
サーバーでの設定は、OSの設定とOpenVPNの設定の2つに大別できます。OSの設定とは、OSがパケットを転送できるようにルーターまたはブリッジの設定をします。OpenVPNの設定とは、OpenVPNの設定ファイルを編集します。IPルーティングの場合とEthernetブリッジングの場合で編集する項目が異なります。
ルーターサーバーとして設定する場合は、次に示す4つの設定を行います。
具体的にはOSの設定ファイルを編集します。FreeBSDの場合は/etc/rc.confに次のようなもコマンドを記述します。
ifconfig_re0="inet 2.0.0.12 netmask 255.255.255.248" ifconfig_rl0="inet 192.168.0.253 netmask 255.255.255.0" defaultrouter="2.0.0.14" gateway_enable="YES" |
ブリッジサーバーとして設定する場合は、内部側インターフェースにIPアドレスを割り当てません。内部側インターフェースはホストに生成されるブリッジインターフェースにメンバーとして追加します。/etc/rc.confに当該コマンドがあればコメントにしてください。
フォワーディング機能を有効にするコマンドがあれば、それもコメントにします。
ifconfig_re0="inet 2.0.0.12 netmask 255.255.255.248" # ifconfig_rl0="inet 192.168.0.253 netmask 255.255.255.0" defaultrouter="2.0.0.14" # gateway_enable="YES" |
OSの設定ファイルの編集が終わったら、ブリッジを生成してメンバーを追加するためのスクリプトを作ります。ディレクトリ/usr/local/share/doc/openvpn/sample-script/に雛型のbridg-startがありますので、それを適当なディレクトリにコピーします。多くの場合、ディレクトリ/etc/openvpn/、あるいは/usr/local/etc/openvpn/を作成して、その中にコピーします。
FreeBSDの場合は、次のように編集します。
br="bridge0" br_ip="192.168.0.253" br_netmask="255.255.255.0" br_broadcast="192.168.0.255" tap="tap0" eth="rl0" # ifconfig bridge create ifconfig tap create ifconfig $br addm $tap addm $eth up ifconfig $tap up ifconfig $eth up ifconfig $br $br_ip netmask $br_netmask broadcast $br_broadcast |
bridge-startと対をなすもう一つのスクリプトbridge-stopは、VPNサーバー(プロセス)を停止した後、ブリッジインターフェースとトンネルインターフェースを削除します。bridg-stopもディレクトリ/usr/local/share/doc/openvpn/sample-script/にありますので、bridge-startを格納したディレクトリーにコピーして編集します。
FreeBSDの場合は、次のように編集します。
br="bridge0" tap="tap0" # ifconfig $br down ifconfig $tap destroy ifconfig $br destroy |
OpenVPNをブリッジングで実行するときは、まずスクリプトbridge-startを実行し、その後openvpnを実行します。また、openvpnを停止した後は、スクリプトbridge-stopを実行します。
[root@localhost ~]# cd /usr/local/etc/openvpn |
[root@localhost ~]# sh ./bridge-start |
[root@localhost ~]# /usr/local/sbin/openvpn ./openvpn.conf |
[root@localhost ~]# ^C |
[root@localhost ~]# sh ./bridge-stop |
OpenVPNをインストールすると、ディレクトリ/usr/local/share/doc/openvpn/sample-script/にLinux用の起動スクリプトopenvpn.initが格納されます。このスクリプトのインストール方法はスクリプトファイル自信の中に書かれています。
FreeBSDの場合、ディレクトリ/usr/local/etc/rc.dの中に起動スクリプトopenvpnが格納されます。
ブリッジルーターの場合、openvpnが実行される前にスクリプトbridge-startが実行されるように、そしてopenvpnが停止されたあとにスクリプトbridge-stopが実行されるように、起動スクリプトを編集します。FreeBSDの場合、openvpn_precmd()とstop_postcmd()にコマンドを追加します。
openvpn_precmd() { if [ -f /usr/local/etc/openvpn/bridge-start ]; then . /usr/local/etc/openvpn/bridge-start ] (省略) } stop_postcmd() { if [ -f /usr/local/etc/openvpn/bridge-stop ]; then . /usr/local/etc/openvpn/bridge-stop } (省略) } |
FreeBSDの場合、/etc/rc.confにopenvpn_enableの設定を追加すると、ホストが立ち上がる際に起動用スクリプトによって/usr/local/sbin/openvpnが実行されます。このとき合わせてopenvpn_ifも設定して下さい。詳しくはスクリプトファイル自信の中に書かれています。
openvpn_enable="YES" openvpn_if="tap" |
ディレクトリ/usr/local/share/doc/openvpn/sample-config-files/に設定ファイルの雛型server.confがあります。これを適当なディレクトリにコピーします。多くの場合、ディレクトリ/etc/openvpn/、または/usr/local/etc/openvpn/を作成して、その中に設定ファイルをコピーします。起動スクリプトをデフォルトのまま使用するなら、Linuxの場合は/etc/openvpnを、FreeBSDの場合は/usr/local/etc/openvpnを作成するといいでしょう。
server.confをコピーするときファイル名を変えても構いません。例えば、openvpn.confなどです。
[root@localhost ~]# cd /usr/local/share/doc/openvpn/sample-config-files/ |
[root@localhost ~]# cp ./server.conf /usr/local/etc/openvpn/openvpn.conf |
設定ファイルをコピーしたら、編集します。
port(ポート番号)
VPNサーバーのプロセスが接続要求を待ち受けるポート番号です。昔は5000番がデフォルトとして使われていましたが、今は1194がデフォルトです。
port 1194 |
proto(プロトコル)
IPの上位プロトコルを指定します。行の先頭にセミコロン";"を挿入すると、その行はコメント行になります。使用するプロトコルの行を残し、他方の行をコメントにします。
;proto tcp proto udp |
dev(デバイス)
ルーターサーバーの場合は、TUNデバイスを生成するために"dev tun"を指定します。一方、ブリッジサーバーの場合は、TAPデバイスを生成するために"dev tap"を指定します。残った方はコメントにしてください。
;dev tap dev tun |
ブリッジサーバーの場合で、事前にトンネルインターフェースtap0を作成し、Ethernetインターフェースと共にブリッジの設定を済ませているなら、"dev tap0"と記述します。
dev tap0 |
ca, cert, key(電子証明書と秘密鍵)
CAの証明書、VPNサーバーの証明書、それとVPNサーバーの秘密鍵を指定します。3つのファイルがディレクトリー/etc/ssl/の中にあるとすると、次のように記述します。
ca /etc/ssl/cacert.pem cert /etc/ssl/vpncert.pem key /etc/ssl/vpnkey.pem |
PKCS#12形式のファイルを指定する方法は次節の「クライアントの設定」で説明します。言い忘れていましたが、VPNサーバーでもPKCS#12形式のファイルを使うことはできます。
crl-verify(失効リスト)
電子証明書を保存したモバイルパソコンを紛失してしまった場合、そのパソコンを手に入れた人物が無断でVPNサーバーに接続してくるかもしれません。そのような事態を防ぐために、効力を失った証明書がある場合、それらのリスト(crl:失効リスト)をホストに保存して指定します。
crl-verify /etc/ssl/crl.pem |
dh(DHパラメータ)
DHパラメータを指定します。ファイルがディレクトリー/etc/ssl/の中にあるとすると、次のように記述します。
dh /etc/ssl/dh1024.pem |
server(サーバー)
ルーターサーバーの場合、生成するVPNのIPネットワークアドレスを指定する必要があります。そのIPネットワークアドレスはローカル(社内)のIPネットワークアドレスと異っていなければなりません。デフォルトではVPNのIPネットワークアドレスは次のように指定されています。
server 10.8.0.0 255.255.255.0 |
もし、社内ネットワークのIPネットワークアドレスが10.8.0.0/24なら、違うIPネットワークアドレスを指定してください。
server 172.16.0.0 255.255.255.0 |
ブリッジサーバーの場合はこのディレクティブをコメントにします。
;server 10.8.0.0 255.255.255.0 |
server-bridge(ブリッジサーバー) ブリッジサーバーの場合、VPNクライアントに割り当てるIPアドレスの範囲を指定する必要があります。そのIPアドレスのネットワークプレフィックスはローカルネットワークのIPアドレスのネットワークプレフィックスと同じでなければなりません。デフォルトでは次のように指定されています。
server-bridge 10.8.0.4 255.255.255.0 10.8.0.50 10.8.0.100 |
上の設定は、ブリッジサーバーのIPアドレスを10.8.0.4とし、VPNクライアントに割り当てるIPアドレスの範囲を10.8.0.50から10.8.0.100までと指定しています。ローカルネットワークのIPネットワークアドレスが10.8.0.0/24でないなら、適切なアドレスを指定します。構成例の場合では次のようになります。
server-bridge 192.168.0.253 255.255.255.0 192.168.0.240 192.168.0.250 |
このディレクティブはデフォルトではコメントになっています。ルーターサーバーの場合はそのままにしてください。
;server-bridge 10.8.0.4 255.255.255.0 10.8.0.50 10.8.0.100 |
push(経路情報の告知)
ルーターサーバーの場合、VPNクライアントにはローカルネットワークとは異なるIPネットワークアドレスが割り当てられます。VPNクライアントはローカルネットワークへの経路情報を自分のルーティングテーブルに追加する必要があります。そのためにVPNサーバーはローカルネットワークのネットワークアドレスをVPNクライアントに伝えます。
例えば、VPNクライアントにIPネットワークアドレス"192.168.0.0/24"を伝えたいときは、次のように指定します。
push "route 192.168.0.0 255.255.255.0" |
この結果、VPNクライアントのから見て、自ホストのトンネルインターフェースが10.8.0.6、トンネルの相手側終端が10.8.0.5の場合、ネットワーク192.168.0.0/24へはゲートウェイ10.8.0.5を経由して到達出来ることを示すエントリーがVPNクライアントのルーティングテーブルに追加されます。
ブリッジサーバーの場合は基本的には必要ありませんが、社内ネットワークが複数のサブネットを持っているなら、VPNサーバーを設置したサブネット以外のIPネットワークアドレスをpushしてください。
マイクロソフト社のWindows VistaのVPNクライアントで経路情報が追加されないときは、管理者としてプログラム(openvpn)を実行できるように設定して下さい。
nobody(プロセスのUID)
FreeBSDやLinuxなどでopenvpnをデーモンとして実行するとき、権限を低くしてセキュリティを高めます。デフォルトでは次の設定がコメントになっていますので、先頭のセミコロンを外してください。
user nobody group nobody |
log
OpenVPNの動作を記録したいときは、"log"か"log-append"のどちらかをアンコメント(Uncomment)してください。
log openvpn.log ;log-append openvpn.log |
VPNクライアントがモバイルパソコンの場合、インストールが終わったら設定ファイルを編集するだけです。VPNサーバーと違って、パソコンの中にルーターの設定やブリッジの設定をする必要はありません。
OpenVPN GUI for Windowsの場合、設定ファイルの雛型がディレクトリ(フォルダー?)\Program Files\OpenVPN\sample-config\の中に入っています。sample-configの中のclient.ovpnをディレクトリ\Program Files\OpenVPN\config\にコピーします。
client.ovpnをコピーしたら編集します。
dev(デバイス) クライアントのデバイスの設定は、接続するサーバーの設定と同じにします。サーバーの設定が"dev tap0"なら"dev tap"を選択してください。
;dev tap dev tun |
proto(プロトコル)
クライアントのプロトコルの設定は、接続するサーバーの設定と同じにします。
;proto tcp proto udp |
remote(サーバー) 接続するVPNサーバーのグローバルアドレスとTCP/UDPポート番号を指定します。構成例の場合は次のように指定します。
remote 2.0.0.12 1194 |
ca, cert, key(電子証明書と秘密鍵)
CAの証明書、VPNクライアントの証明書、それとVPNクライアントの秘密鍵を指定します。3つのファイルがディレクトリーC:\Cert\の中にあるとすると、次のように記述します。
ca /Cert/cacert.pem cert /Cert/pc01cert.pem key /Cert/pc01key.pem |
PKCS#12形式のファイルを使う場合は、次のように指定します。
pkcs12 /Cert/pc01cert.p12 |
VPNをローカルネットワークにルーティング接続した場合、ローカルネットワーク内部での経路制御に注意して下さい。VPN接続が成功すると、VPNクライアントとVPNサーバーの間でICMP EchoとICMP Echo-Replyが送受信可能になります。ですが、ローカルネットワーク内の他のホストでは通信できな場合があります。
例えば、構成例においてVPNクライアントPCmのトンネルインターフェースのIPアドレスが10.8.0.6/24だと仮定します。このとき、PCmからPCoにICMP Echoを送っても、PCoからPCmにICMP Echo-Replyが返りません。なぜなら、PCoは10.8.0.6宛のICMP Echo-Replyを包んだEthernetフレームをデフォルトゲートウェイであるIn.RT(192.168.0.254)に伝送するからです。
このような事態を避けるため、デフォルトゲートウェイのルーティングテーブルに、ネットワーク10.8.0.0/24へは192.168.0.253を経由して接続できることを示すエントリーを手動で追加してください。
構成例では、FTPは社内ネットワークからのみ利用ができるようにTCP Wrapperが設定されていいると仮定します。そのため、ルーティングの場合はVPNクライアントからFTPサーバーにアクセスできません。このような場合はTCP Wrapperの設定を見直して下さい。