OpenVPN による VPN 環境の構築

2011/01/31
★★★★

VPN を使うと、外出先から、スモールオフィス内のネットワークや自宅のネットワークに、インターネット経由で、接続することが可能となる。

RAS (Remote Access Server) の電話回線が、インターネットに代わったものと考えればいいだろう。
( ただ、電話回線という閉鎖的なインフラが、オープンなインターネットというインフラに置き換わったときのセキュリティに対する意識はしっかりもっておくべき。)

スモールオフィス内のネットワークや自宅の PC にあるファイルを参照したい場合に役立つ。

SkyDrive 等のオンラインストレージを使うのも良いが、オンラインストレージに、ファイルをアップロードすることを忘れてしまったり、インターフェースが Web であることが多く、PC 上のファイルとの同期をとることが手間であったりする。

オフィスによっては、オフィスのネットワーク経由でないとメールサーバーにアクセスできないという事もある。

また、プロバイダによっては、プロバイダが提供するネットワーク経由でないと、メールサーバーにアクセスできないという仕様もある。

VPN は、これらを克服する重要なインフラだ。

そこで、今回は、OpenVPN を使って VPN 環境を構築する方法を紹介する。 

構成する環境は以下の通り。
OpenVPN Target Topology

上図の仮想のネットワーク (VPN) が、今回の対象範囲となる。

また、以降の手順は、以下の条件を前提とする。

  • VPN サーバー: CentOS 5.5 x64
  • ノート PC: Windows 7 x64

OpenVPN のインストール

バイナリー (rpm) のインストールでは、以下のパッケージが必要となる。

  • openssl
  • lzo
  • pam

ソースコードをコンパイルするには、以下のパッケージが必要となる。

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

今回は、どちらでもなく、yum で OpenVPN をインストールする。リポジトリは、RPMforge を使う。

RPMforge をリポジトリを追加していない場合は、以下の記事の手順により、RPMforge リポジトリを追加する。

RPMforge をリポジトリを有効にする。

"/etc/yum.repos.d/rpmforge.repo" の [rpmforge] -> [enable] を "1" に設定する。

OpenVPN をインストールする。

[root@centkun ~]# yum install -y openvpn
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * addons: ftp.jaist.ac.jp
 * base: ftp.jaist.ac.jp
 * extras: ftp.jaist.ac.jp
 * rpmforge: fr2.rpmfind.net
 * updates: ftp.jaist.ac.jp
Setting up Install Process
Resolving Dependencies
--> Running transaction check
---> Package openvpn.x86_64 0:2.1.4-1.el5.rf set to be updated
--> Processing Dependency: lzo for package: openvpn
--> Processing Dependency: liblzo2.so.2()(64bit) for package: openvpn
--> Running transaction check
---> Package lzo.x86_64 0:2.04-1.el5.rf set to be updated
--> Finished

Dependency Resolution Dependencies Resolved
==========================================================================================
 Package Arch Version Repository Size ==========================================================================================
Installing:
 openvpn x86_64 2.1.4-1.el5.rf rpmforge 442 k
Installing for dependencies:
 lzo x86_64 2.04-1.el5.rf rpmforge 139 k

Transaction Summary ==========================================================================================
Install 2 Package(s)
Upgrade 0 Package(s)

Total download size: 581 k
Downloading Packages:
(1/2): lzo-2.04-1.el5.rf.x86_64.rpm | 139 kB 00:01
(2/2): openvpn-2.1.4-1.el5.rf.x86_64.rpm | 442 kB 00:01
------------------------------------------------------------------------------------------
Total 156 kB/s | 581 kB 00:03
Running rpm_check_debug
Running Transaction Test
Finished Transaction Test Transaction Test Succeeded
Running Transaction
 Installing : lzo 1/2
 Installing : openvpn 2/2

Installed:
 openvpn.x86_64 0:2.1.4-1.el5.rf

Dependency Installed:
 lzo.x86_64 0:2.04-1.el5.rf

Complete!

以降の手順では、RPMforge リポジトリは、利用しないので、RPMforge リポジトリを無効にしておく。

"/etc/yum.repos.d/rpmforge.repo" の [rpmforge] -> [enable] を "0" に設定する。

openssl もインストールされるはずだが、もし、インストールされていなければインストールする。

[root@centkun ~]# yum install -y openssl
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * addons: ftp.jaist.ac.jp
 * base: ftp.jaist.ac.jp
 * extras: ftp.jaist.ac.jp
 * updates: ftp.jaist.ac.jp
Setting up Install Process Resolving Dependencies
--> Running transaction check
---> Package openssl.i686 0:0.9.8e-12.el5_5.7 set to be updated
---> Package openssl.x86_64 0:0.9.8e-12.el5_5.7 set to be updated
--> Finished Dependency Resolution

Dependencies Resolved

==========================================================================================
Package Arch Version Repository Size
==========================================================================================
Updating:
 openssl i686 0.9.8e-12.el5_5.7 updates 1.4 M
 openssl x86_64 0.9.8e-12.el5_5.7 updates 1.4 M

Transaction Summary
==========================================================================================
Install 0 Package(s)
Upgrade 2 Package(s)

Total download size: 2.9 M
Downloading Packages:
(1/2): openssl-0.9.8e-12.el5_5.7.i686.rpm | 1.4 MB 00:00
(2/2): openssl-0.9.8e-12.el5_5.7.x86_64.rpm | 1.4 MB 00:00
------------------------------------------------------------------------------------------
Total 3.3 MB/s | 2.9 MB 00:00
Running rpm_check_debug
Running Transaction Test
Finished Transaction Test
Transaction Test Succeeded
Running Transaction
 Updating : openssl 1/4
 Updating : openssl 2/4
 Cleanup : openssl 3/4
 Cleanup : openssl 4/4

Updated: openssl.i686 0:0.9.8e-12.el5_5.7
 openssl.x86_64 0:0.9.8e-12.el5_5.7

Complete!

routed VPN と bridged VPN

OpenVPN では、routed VPN と bridged VPN の二つの構成がサポートされている。

bridged VPN を使うケースとしては、以下の場合がある。

  • VPN 上で、IPX のような IP ではないプロトコルを使用したい場合
  • VPN を通して、ブロードキャストを用いたアプリケーションを使用する場合
  • VPN を通して、SMB, WINS を使わない Windows ファイル共有をしたい場合
    (*) 現在の一般的な Windows のファイル共有ではない過去の Netbios のファイル共有。

これらのケースは、殆ど適用されることはないため、routed VPN で構成する。

独自の認証局の構築、ルート証明書と秘密キーの生成

OpenVPN Generate certificate and key

OpenVPN にバンドルされているスクリプトファイルを使用して、独自認証局のルート証明書と秘密キーを生成する。

スクリプトファイルを /etc/openvpn にコピーし、実行権限を付与する。

[root@centkun ~]# cp -r /usr/share/doc/openvpn-2.1.4/easy-rsa/2.0/ /etc/openvpn/easy-rsa
[root@centkun ~]# chmod +x /etc/openvpn/easy-rsa/*

スクリプトで、PKI (認証基盤) を初期化する。

[root@centkun ~]# cd /etc/openvpn/easy-rsa/
[root@centkun easy-rsa]# . ./vars
NOTE: If you run ./clean-all, I will be doing a rm -rf on /etc/openvpn/easy-rsa/keys
[root@centkun easy-rsa]# ./clean-all

独自認証局 (CA) の証明書と秘密キーを生成する

[root@centkun 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) [US]:JP
State or Province Name (full name) [CA]:Kanagawa
Locality Name (eg, city) [SanFrancisco]:Fujisawa
Organization Name (eg, company) [Fort-Funston]:MASUDAQ.COM
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) [Fort-Funston CA]:MASUDAQ.COM CA
Name []:
Email Address [me@myhost.mydomain]:ca@masudaq.com

サーバー用の証明書と秘密キーの発行

OpenVPN サーバーの証明書と秘密キーを生成する。

[root@centkun easy-rsa]# ./build-key-server server
Generating a 1024 bit RSA private key
................................................++++++
...............................................................++++++
writing new private key to 'server.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) [US]:JP
State or Province Name (full name) [CA]:Kanagawa
Locality Name (eg, city) [SanFrancisco]:Fujisawa
Organization Name (eg, company) [Fort-Funston]:MASUDAQ.COM
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) [server]:
Name []:
Email Address [me@myhost.mydomain]:ca@masudaq.com 

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Using configuration from /etc/openvpn/easy-rsa/openssl.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName :PRINTABLE:'JP'
stateOrProvinceName :PRINTABLE:'Kanagawa'
localityName :PRINTABLE:'Fujisawa'
organizationName :PRINTABLE:'MASUDAQ.COM'
commonName :PRINTABLE:'server'
emailAddress :IA5STRING:'ca@masudaq.com'
Certificate is to be certified until Jan 27 11:59:41 2021 GMT (3650 days)
Sign the certificate? [y/n]:y


1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated 

クライアント用の証明書と秘密キーの発行

OpenVPN クライアントの証明書と秘密キーを生成する。

VPN 接続させたいクライアントの台数分以下の手順を行う。

今回は、"client001" というコンピュータ名の証明書と秘密キーを発行する。

[root@centkun easy-rsa]# ./build-key client001
Generating a 1024 bit RSA private key
..............++++++
.........................++++++
writing new private key to 'client001.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) [US]:JP
State or Province Name (full name) [CA]:Kanagawa
Locality Name (eg, city) [SanFrancisco]:Fujisawa
Organization Name (eg, company) [Fort-Funston]:MASUDAQ.COM
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) [client001]:
Name []:
Email Address [me@myhost.mydomain]:client001@masudaq.com

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Using configuration from /etc/openvpn/easy-rsa/openssl.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName :PRINTABLE:'JP'
stateOrProvinceName :PRINTABLE:'Kanagawa'
localityName :PRINTABLE:'Fujisawa'
organizationName :PRINTABLE:'MASUDAQ.COM'
commonName :PRINTABLE:'client001'
emailAddress :IA5STRING:'client001@masudaq.com'
Certificate is to be certified until Jan 27 12:07:34 2021 GMT (3650 days)
Sign the certificate? [y/n]:y

1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated

Common Name は、必ず一意にしなかればいけないことに気を付ける。つまり、"client001" という名前で複数の証明書と秘密キーを生成しない。

パスワードで保護された秘密キーを生成したい場合は、"build-key" の代わりに、"build-key-pass" スクリプトを実行する。

DH (Diffie Hellman) パラメーターの生成

[root@centkun easy-rsa]# ./build-dh
Generating DH parameters, 1024 bit long safe prime, generator 2
This is going to take a long time
.....................................+......................+....................................
...................+...............................................................................
...........................+......................................................+..............
.......+...........................................................................................
........++*++*++*

keys ディレクトリに OpenVPN のセットアップに必要なファイルが生成されていることを確認する。

[root@centkun easy-rsa]# ls keys -lls keys -l
-rw-r--r-- 1 root 1298 1月 31 10:57 ca.crt
-rw------- 1 root 887 1月 31 10:57 ca.key
-rw-r--r-- 1 root 3876 1月 31 11:03 client001.crt
-rw------- 1 root 887 1月 31 11:03 client001.key
-rw-r--r-- 1 root 245 1月 31 11:14 dh1024.pem
-rw-r--r-- 1 root 3978 1月 31 10:57 server.crt
-rw------- 1 root 887 1月 31 10:57 server.key

*.crt が証明書。*.key が秘密キー。ca 用、server 用、client001 用の証明書と秘密キー、 DH パラメータファイル dh1024.pem が生成されていることを確認する。
*.key は、所有者 root に対してのみ rw 権限が付与されている。*.key は、大切に保管すること。

OpenVPN の構成

CA とサーバーの証明書と秘密キー、DH パラメーターを /etc/openvpn にコピーする。
(ca.key は、利用しないが、easy-rsa にあると誤って初期化してしまう懸念から、コピー対象としている。)

[root@centkun ~]# cp /etc/openvpn/easy-rsa/keys/ca.* /etc/openvpn/
[root@centkun ~]# cp /etc/openvpn/easy-rsa/keys/server.* /etc/openvpn/
[root@centkun ~]# cp /etc/openvpn/easy-rsa/keys/dh1024.pem /etc/openvpn/

サンプルファイル server.conf を /etc/openvpn にコピーする。

[root@centkun ~]# cp /usr/share/doc/openvpn-2.1.4/sample-config-files/server.conf /etc/openvpn/

構成ファイルをカスタマイズする。
server.confg ファイルの "#" 以降は、もちろん、コメントだが、";" もコメントであることに注意。

[root@centkun ~]# vi /etc/openvpn/server.conf

# ポート 1194 でリッスンする
port 1194

# UDP を使う # UDP を使う
proto udp

#デフォルト
dev tun

# CA の証明書とサーバー証明書、秘密キーのパスの定義
ca /etc/openvpn/ca.crt
cert /etc/openvpn/server.crt
key /etc/openvpn/server.key

# DH パラメーターファイルのパスの定義
dh /etc/openvpn/dh1024.pem

# 仮想ネットワーク (VPN) のネットワークアドレスの定義
server 10.8.0.0 255.255.255.0

# ローカルエリアネットワークのネットワークアドレスの定義
push "route 192.168.11.0 255.255.255.0"

# OpenVPN 実行ユーザーの権限を限定する
user nobody
group nobody

# ログファイルのパスの定義
log-append /var/log/openvpn.log

サーバーのネットワーク構成

インターフェース間 (物理 NIC と OpenVPN 仮想 NIC) のパケット転送を有効にする。

[root@centkun ~]# echo 1 > /proc/sys/net/ipv4/ip_forward

この設定は、OS 再起動時に初期化されてしまうため、当記事で動作確認がとれたならば、以下の手順で、パケット転送を有効にする。

[root@centkun ~]# vi /etc/sysctl.conf
# Kernel sysctl configuration file for Red Hat Linux
#
# For binary values, 0 is disabled, 1 is enabled. See sysctl(8) and
# sysctl.conf(5) for more details.

# Controls IP packet forwarding
#net.ipv4.ip_forward = 0 この値を以下のように "1" にする。
net.ipv4.ip_forward = 1

# Controls source route verification
net.ipv4.conf.default.rp_filter = 1

# Do not accept source routing
net.ipv4.conf.default.accept_source_route = 0
.......

:wq

次に、OpenVPN サーバーのファイアウォールで、プロトコル UDP、ポート 1194 の着信を許可するよう設定する。

この時、以下の記事を参考にして、[その他のポート] に "1194:udp" もしくは、"openvpn:1194" と設定する。

CentOS ポート開放 ファイアウォールの設定

system-config-securitylevel-tui - openvpn

ルーターの構成

ルーター (WAN 側) の 1194 ポートの着信を OpenVPN サーバーの 1194 ポートに転送するよう構成する。
ルーターのメーカーによって、NAT、アドレス変換、ポートフォワード等と呼称は異なる。

ルーター (LAN 側) に、以下の静的ルートを追加する。VPN サーバー:192.168.11.11 が仮想ネットワークのルーター (ゲートウェイ) となる。

ネットワークアドレス サブネットマスク ゲートウェイ
10.8.0.0 255.255.255.0 192.168.11.11

これにより、プライベートネットワークのノードからの、10.8.0.0/24 宛ての着信は、192.168.11.11 を経由するようになる。

OpenVPN クライアントのインストール

今回は、VPN クライアントとして、Windows 7 を利用する。

Windows 7 上で、[OpenVPN] -> [Community Project] -> [Download] から、Windows Installer の [openvpn-2.1.4-install.exe] をダウンロードする。

openvpn-2.1.4-install.exe を実行し、インストーラーの指示通りにウイザードを進める。この時、インストールオプションは、デフォルトのままでよい。 

インストール中に以下のウインドウが表示される。[インストール] を選択する。
OpenVPN for Windows Install - TAP Adapter

OpenVPN クライアントの証明書、秘密キー、ルート証明書の配布

CA サーバー (OpenVPN) で生成した、client001.ctr、client001.key と、ルート証明書 ca.ctr をクライアント (Windows 7) 上にコピーする。
(*) 秘密キーのコピーは、必ずセキュアな方法を使うこと。
(*) client001.key は、root に対してのみ読み取りのアクセス権が与えられていることに注意する。

[スタート] -> [すべてのプログラム] -> [OpenVPN] -> [Shortcuts] -> [OpenVPN configuration file directory] を選択し、設定ファイル用のフォルダを開き、client001.ctr、client001.key ファイルをコピーする。

この時、WinSCP で 直接、[OpenVPN configuration file directory] で開いたフォルダへコピーする場合、同フォルダへのアクセスには、管理者権限が必要となるため、WinSCP を [管理者として実行] で起動するか、一時的にアクセス権のある別のフォルダにファイルをコピーしてから、 Windows 上で、[OpenVPN configuration file directory] フォルダにコピーする。

[スタート] -> [すべてのプログラム] -> [OpenVPN] -> [Shortcuts] -> [OpenVPN Sample Configuration Files] を選択し、"client.ovpn" を [OpenVPN configuration file directory] で開いたフォルダへコピーする。

OpenVPN クライアントの構成

[スタート] -> [すべてのプログラム] -> [OpenVPN] -> [Shortcuts] -> [OpenVPN Sample Configuration Files] フォルダ内の "client.ovpn"を [OpenVPN configuration file directory] にコピーする。

[メモ帳] などのテキストエディタでコピーした "client.ovpn" ファイルを開く。[メモ帳] を使う場合は、以下の方法で、メモ帳を起動し、[ファイル] メニューから、"client.ovpn" を開く。

また、サンプルの "client.ovpn" ファイルは、改行コードが CR LF ではないためメモ帳では編集することが難しい。その場合は、以下からファイルをダウンロードして利用するとよい。

"client.ovpn" ファイルを編集する。

# 接続先 VPN サーバーのホスト名とポートを定義する
remote vpnsrv.masudaq.com 1194

# ルート証明書のパスを定義する (相対パスで良いのでファイル名のみ)
ca ca.crt

# クライアント証明書、秘密キーのパス定義する (相対パスで良いのでファイル名のみ)
cert client001.crt
key client001.key

#cf. http://openvpn.net/howto.html#mitm
ns-cert-type server

"client.ovpn" ファイルの変更を保存する。

VPN の動作確認

OpenVPN サーバーを起動する。

[root@centkun ~]# /etc/rc.d/init.d/openvpn start

OpenVPN クライアントを起動する。

[スタート] -> [すべてのプログラム] -> [OpenVPN] -> [OpenVPN GUI] を右クリックし、[管理者として実行...] を選択する。

タスクバーに OpenVPN GUI のアイコンが表示される。

アイコンをダブルクリック、もしくは、アイコンを右クリック [Connect] でサーバーへ接続する。

接続中は、黄色いアイコンだが、接続が確立すると緑色のアイコンになり、アサインされた IP が表示される。

管理者権限 VPN クライアントを起動することが手間であれば、[OpenVPN GUI] のショートカットを右クリックし、[プロパティ] -> [互換性] タブ -> [特権レベル] -> [管理者としてこのプログラムを実行する] にチェックを入れ、[OK] で設定を適用する。もちろんセキュリティレベルは落ちるので、当設定は、自己責任でお願いしたい。

VPN サーバー、クライアント間の疎通確認

VPN クライアントでコマンドプロンプトを起動し、VPN クライアントから、VPN サーバーへの疎通確認を行う。

まずは、VPN 側のインターフェースへの疎通確認。

C:\Users\seven> ping 10.8.0.1

10.8.0.1 に ping を送信しています 32 バイトのデータ:
10.8.0.1 からの応答: バイト数 =32 時間 =4ms TTL=64
10.8.0.1 からの応答: バイト数 =32 時間 =4ms TTL=64
10.8.0.1 からの応答: バイト数 =32 時間 =4ms TTL=64
10.8.0.1 からの応答: バイト数 =32 時間 =4ms TTL=64

10.8.0.1 の ping 統計:
 パケット数: 送信 = 4、受信 = 4、損失 = 0 (0% の損失)、
 最小 = 4ms、最大 = 4ms、平均 = 4ms

次に、ローカルネットワーク側のインターフェースへの疎通確認。

C:\Users\seven>ping 192.168.11.11

192.168.11.11 に ping を送信しています 32 バイトのデータ:
192.168.11.11 からの応答: バイト数 =32 時間 =4ms TTL=64
192.168.11.11 からの応答: バイト数 =32 時間 =4ms TTL=64
192.168.11.11 からの応答: バイト数 =32 時間 =73ms TTL=64
192.168.11.11 からの応答: バイト数 =32 時間 =4ms TTL=64

192.168.11.11 の ping 統計:
 パケット数: 送信 = 4、受信 = 4、損失 = 0 (0% の損失)、
ラウンド トリップの概算時間 (ミリ秒):
 最小 = 4ms、最大 = 73ms、平均 = 21ms

最後に、VPN サーバーがルーターとして機能しているかを確認する。

プライベートネットワーク上のファイルサーバー: 192.168.1.7 へ ICMP を送る。

C:\Users\seven>ping 192.168.1.7

192.168.1.7 に ping を送信しています 32 バイトのデータ:
192.168.1.7 からの応答: バイト数 =32 時間 =4ms TTL=128
192.168.1.7 からの応答: バイト数 =32 時間 =4ms TTL=128
192.168.1.7 からの応答: バイト数 =32 時間 =7ms TTL=128
192.168.1.7 からの応答: バイト数 =32 時間 =6ms TTL=128

192.168.1.7 の ping 統計:
 パケット数: 送信 = 4、受信 = 4、損失 = 0 (0% の損失)、
ラウンド トリップの概算時間 (ミリ秒):
 最小 = 4ms、最大 = 7ms、平均 = 5ms

ローカルエリアネットワークへのアクセス

VPN クライアントから、プライベートネットワークへの疎通確認がとれた。

最後に、プライベートネットワーク上のファイルサーバーの Windows 共有ファイルを参照する。

VPN サーバーのファイアウォールのポートを開放する。

CentOS ポート開放 ファイアウォールの設定 を参照し、Samba (SMB: Windows ファイル共有) のポートを開放する。
system-config-securitylevel-tui - openvpn

VPN クライアントから、プライベートネットワーク上のファイルサーバー: 192.168.1.7 へ UNC 形式 "\\192.168.1.7" で、アクセスし、共有しているファイルが参照できることを確認する。

同様に、プライベートネットワーク上の Web サーバーにアクセスしたいのであれば、[WWW (HTTP)]、[Secure WWW (HTTPS)] を選択、ポートを開放する。

補足として、OpenVPN のポート番号を変更しない限りは、ファイやウォールの設定は、セキュリティレベル: 有効、SELinux: Enforcing で動作する。
system-config-securitylevel-tui - openvpn

長い旅だったが、やってみる価値はあるはずだ。

以下は、参考にしたサイト。

HOWTO Installing OpenVPN

以上

コメント (0)

コメントの投稿