Product SiteDocumentation Site

10.2. 仮想プライベートネットワーク

仮想プライベートネットワーク (略して VPN) は 2 つの異なるローカルネットワークをインターネットに作ったトンネルを経由してつなげる方法です。さらに、トンネルは通常機密を守るために暗号化されます。VPN はリモートマシンを会社のローカルネットワークの中に参加させるために使われます。
この機能を提供するツールにはさまざまなものがあります。OpenVPN は効果的な解決策で、設置と保守が簡単で、SSL/TLS に基づいています。別の可能性は IPsec を使って 2 台のマシン間の IP トラフィックを暗号化することです。さらに、この暗号化は透過的です。つまり、ホスト上で実行されているアプリケーションは VPN の存在を気にする必要がありません。SSH は伝統的な機能に加えて、VPN を提供するために使われる場合もあります。最後に、Microsoft の PPTP プロトコルを使って VPN を作ることも可能です。他にも解決策は存在しますが、本書のテーマを越えています。

10.2.1. OpenVPN

OpenVPN は仮想プライベートネットワーク作成専用ソフトウェアの一種です。OpenVPN をセットアップするには VPN サーバ上とクライアント上に仮想ネットワークインターフェースの作成が必要です。さらに、OpenVPN は tun (IP レベルトンネル) と tap (イーサネットレベルトンネル) インターフェースをサポートします。実際には、VPN クライアントをイーサネットブリッジ経由でサーバのローカルネットワークに参加させる場合を除いて、tun インターフェースが最もよく使われます。
OpenVPN は、SSL/TLS 暗号化と関連する機能 (機密性、認証、整合性、否認防止) を使うために、OpenSSL に依存しています。OpenVPN は共有秘密鍵または公開鍵基盤に基づく X.509 証明書を使うように設定できます。設定は後者を使うことをお勧めします。なぜなら、VPN にアクセスするローミングユーザの数が増えた場合も、大きな自由度があるからです。

10.2.1.1. 公開鍵基盤、easy-rsa

公開鍵暗号では RSA アルゴリズムが広く使われています。公開鍵暗号は秘密鍵と公開鍵からなる「鍵ペア」を使います。2 種類の鍵は互いに密接な関係を持っており、公開鍵で暗号化されたメッセージは秘密鍵を知っている人だけが復号化できるという数学的特徴によって機密性が保証されます。逆に、秘密鍵を使って暗号化されたメッセージは公開鍵を持っている人なら誰でも復号化できます。この特徴を使うことで、メッセージの出自が本物であることを確認することが可能です。なぜなら、秘密鍵を持つものだけがその暗号化メッセージを生成できるからです。デジタルハッシュ関数 (MD5、SHA1、最近の亜種など) を関連させる場合、いかなるメッセージにも適用できる署名メカニズムになります。
しかしながら、鍵ペアを作り、鍵ペアに任意の識別情報を保存し、自由に識別情報を偽ることは誰でも可能です。これに対する 1 つの解決策が X.509 標準によって形式化された認証局 (CA) の概念です。この用語には、ルート証明書として知られる信頼された鍵ペアに保存された識別情報の実体の意味も含まれています。ルート証明書は他の証明書 (鍵ペア) を署名するためにのみ使われ、署名は署名したい鍵ペアに保存される識別情報を確認するために適切な手順を経た後に行われます。こうすることで X.509 を使うアプリケーションは自分に提示された証明書の識別情報を確認し、提示された証明書が信頼されたルート証明書によって署名されたかを判断できます。
OpenVPN はこのルールに従います。なぜなら、パブリック認証局は (高額な) 料金と引き換えに証明書を発行するだけなので、OpenVPN を使えば会社内のプライベート認証局を作成することが可能です。easy-rsa パッケージは X.509 証明書基盤としての機能を果たすツールを提供し、このツールは openssl コマンドを使うスクリプト群として実装されています。
Falcot Corp の管理者は easy-rsa ツールを使い、サーバおよびクライアントに必要な証明書を作ります。easy-rsa ツールを使うことで、すべてのクライアントの設定を同様にすることが可能です。クライアントは Falcot のプライベート認証局から発行された証明書を信頼するようにセットアップしなければいけません。最初に Falcot のプライベート認証局用の証明書を発行します。そして、この目的を達成するために、管理者は認証局に必要なファイルを含むディレクトリを適切な場所にセットアップします。セットアップする場所は、認証局の秘密鍵が盗まれる危険性を和らげるために、ネットワークに接続されていないマシンが好ましいです。
$ make-cadir pki-falcot
$ cd pki-falcot
easy-rsa ツールは必要なパラメータを vars ファイルに保存します。パラメータには特に KEY_ 接頭辞が付けられています。これらの変数は環境変数に組み込まれます。
$ vim vars
$ grep KEY_ vars
export KEY_CONFIG=`$EASY_RSA/whichopensslcnf $EASY_RSA`
export KEY_DIR="$EASY_RSA/keys"
echo NOTE: If you run ./clean-all, I will be doing a rm -rf on $KEY_DIR
export KEY_SIZE=2048
export KEY_EXPIRE=3650
export KEY_COUNTRY="FR"
export KEY_PROVINCE="Loire"
export KEY_CITY="Saint-Étienne"
export KEY_ORG="Falcot Corp"
export KEY_EMAIL="admin@falcot.com"
export KEY_OU="Certificate authority"
export KEY_NAME="Certificate authority for Falcot Corp"
# If you'd like to sign all keys with the same Common Name, uncomment the KEY_CN export below
# export KEY_CN="CommonName"
$ . ./vars
NOTE: If you run ./clean-all, I will be doing a rm -rf on /home/roland/pki-falcot/keys
$ ./clean-all
次に認証局の鍵ペアを作成します (この最中に、鍵ペアの 2 つの部分が keys/ca.crtkeys/ca.key に保存されます)。
$ ./build-ca
Generating a 2048 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) [FR]:
State or Province Name (full name) [Loire]:
Locality Name (eg, city) [Saint-Étienne]:
Organization Name (eg, company) [Falcot Corp]:
Organizational Unit Name (eg, section) [Certificate authority]:
Common Name (eg, your name or your server's hostname) [Falcot Corp CA]:
Name [Certificate authority for Falcot Corp]:
Email Address [admin@falcot.com]:
今や VPN サーバの証明書を作ることが可能です。同様に SSL/TLS 接続のサーバ側には Diffie-Hellman パラメータが必要です。VPN サーバは DNS 名 vpn.falcot.com で識別されます。さらに作成された鍵ファイルの名前に、ここで与えた DNS 名が使われます (keys/vpn.falcot.com.crt は公開鍵証明書、keys/vpn.falcot.com.key は秘密鍵です)。
$ ./build-key-server vpn.falcot.com
Generating a 2048 bit RSA private key
.....................................................................................................................+++
...........+++
writing new private key to 'vpn.falcot.com.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) [FR]:
State or Province Name (full name) [Loire]:
Locality Name (eg, city) [Saint-Étienne]:
Organization Name (eg, company) [Falcot Corp]:
Organizational Unit Name (eg, section) [Certificate authority]:
Common Name (eg, your name or your server's hostname) [vpn.falcot.com]:
Name [Certificate authority for Falcot Corp]:
Email Address [admin@falcot.com]:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Using configuration from /home/roland/pki-falcot/openssl-1.0.0.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName           :PRINTABLE:'FR'
stateOrProvinceName   :PRINTABLE:'Loire'
localityName          :T61STRING:'Saint-\0xFFFFFFC3\0xFFFFFF89tienne'
organizationName      :PRINTABLE:'Falcot Corp'
organizationalUnitName:PRINTABLE:'Certificate authority'
commonName            :PRINTABLE:'vpn.falcot.com'
name                  :PRINTABLE:'Certificate authority for Falcot Corp'
emailAddress          :IA5STRING:'admin@falcot.com'
Certificate is to be certified until Mar  6 14:54:56 2025 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
$ ./build-dh
Generating DH parameters, 2048 bit long safe prime, generator 2
This is going to take a long time
[…]
以下では、VPN クライアント用の証明書を作成します。そして VPN を利用するコンピュータ 1 台ごとおよび人間 1 人ずつに 1 つの証明書が必要です。
$ ./build-key JoeSmith
Generating a 2048 bit RSA private key
................................+++
..............................................+++
writing new private key to 'JoeSmith.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) [FR]:
State or Province Name (full name) [Loire]:
Locality Name (eg, city) [Saint-Étienne]:
Organization Name (eg, company) [Falcot Corp]:
Organizational Unit Name (eg, section) [Certificate authority]:Development unit
Common Name (eg, your name or your server's hostname) [JoeSmith]:Joe Smith
[…]
すべての証明書を作ったら、証明書を適切な場所にコピーする必要があります。すなわち、ルート証明書の公開鍵 (keys/ca.crt) はすべてのマシン (サーバもクライアントも) に /etc/ssl/certs/Falcot_CA.crt という名前で保存されます。サーバの証明書はサーバにだけインストールされます (keys/vpn.falcot.com.crt/etc/ssl/vpn.falcot.com.crt に、keys/vpn.falcot.com.key は管理者だけが読めるようなパーミッション制限を掛けるために /etc/ssl/private/vpn.falcot.com.key に、インストールされます)。同時に、対応する Diffie-Hellman パラメータ (keys/dh2048.pem) は /etc/openvpn/dh2048.pem にインストールされます。クライアント証明書は対応する VPN クライアントに同様の方法でインストールされます。

10.2.1.2. OpenVPN サーバの設定

デフォルトで、OpenVPN 初期化スクリプトは /etc/openvpn/*.conf で定義されたすべての仮想プライベートネットワークを開始します。このため、VPN サーバをセットアップする場合、このディレクトリ内に対応する設定ファイルを配置することになります。設定ファイルの良い足掛かりとして /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz が用意されています。これは比較的標準的なサーバを作るためのものです。もちろん、一部のパラメータを適切に設定しなければいけません。具体的に言えば、cacertkeydh をファイルが設置されている場所に設定する必要があります (それぞれ、/etc/ssl/certs/Falcot_CA.crt/etc/ssl/vpn.falcot.com.crt/etc/ssl/private/vpn.falcot.com.key/etc/openvpn/dh2048.pem に設定します)。server 10.8.0.0 255.255.255.0 ディレクティブは VPN によって使われるサブネットを定義します。そして、サーバにはこの範囲に含まれる最初の IP アドレス (10.8.0.1) が割り当てられ、クライアントには残りの IP アドレスが割り当てられます。
この設定で OpenVPN を開始すると、通常 tun0 という名前の仮想ネットワークインターフェースが作成されます。しかしながら、ファイアウォールは OpenVPN の開始前に実ネットワークインターフェースと同時に設定される場合が多いです。このため、永続的に仮想ネットワークインターフェースを作成すると良いでしょう。OpenVPN は事前に作成された仮想インターフェースを使うように設定することを推奨します。この追加的設定により、インターフェースの名前を選ぶことが可能になります。この目的を達成するには、openvpn --mktun --dev vpn --dev-type tun を使って tun タイプの vpn と名付けられた仮想ネットワークインターフェースを作成します。さらに、このコマンドをファイアウォール設定スクリプトの中で使えば、簡単に設定を統合できます。つまり /etc/network/interfaces ファイルの up 指示文を使います。OpenVPN 設定ファイルをファイアウォール設定に対応させるために、dev vpndev-type tun 指示文を使って、更新します。
これ以上の動作がなければ、VPN クライアントは 10.8.0.1 アドレスの VPN サーバにアクセスできるだけです。クライアントをローカルネットワーク (192.168.0.0/24) へアクセスできる状態にするには、push route 192.168.0.0 255.255.255.0 指示文を OpenVPN 設定に追加します。こうすることで、VPN クライアントは自動的にネットワーク経路を取得し、VPN を経由でローカルネットワークに到達できるようになります。さらに、ローカルネットワークにいるマシンに対して VPN サーバを通じて VPN への経路を知らせる必要もあります (VPN サーバがゲートウェイにインストールされている場合、これは自動的に動きます)。別の方法として、VPN サーバは IP マスカレードを動かすように設定されなければいけません。そうすれば、VPN クライアントからの接続はあたかもクライアントが VPN サーバからアクセスしたかのように見えます (第 10.1 節「ゲートウェイ」を参照してください)。

10.2.1.3. OpenVPN クライアントの設定

OpenVPN クライアントを設定する場合にも、/etc/openvpn/ に設定ファイルを置きます。標準的な設定の良い足掛かりとして /usr/share/doc/openvpn/examples/sample-config-files/client.conf が用意されています。remote vpn.falcot.com 1194 指示文は OpenVPN サーバのアドレスとポート番号を表します。さらに cacertkey も鍵ファイルの場所に合わせて設定が必要です。
起動時に VPN を自動的に開始したくない場合、/etc/default/openvpn ファイルの AUTOSTART 指示文に none を設定してください。VPN 接続の開始と停止は service openvpn@name startservice openvpn@name stop コマンドを使えばいつでも可能です (ここで、接続名 name/etc/openvpn/name.conf で定義したものにマッチします)。
network-manager-openvpn-gnome パッケージには、Network Manager の拡張 (第 8.2.4 節「ローミングユーザ向けの自動ネットワーク設定」参照) が含まれ、これを使うことで OpenVPN 仮想プライベートネットワークを管理することが可能です。誰もがグラフィカルに OpenVPN 接続を設定し、ネットワーク管理アイコンからこれを制御することが可能です。

10.2.2. SSH を使った仮想プライベートネットワーク

SSH を使った仮想プライベートネットワークの作成法には、2 種類の方法があります。歴史的に見て重要な方法が SSH リンクの上で PPP レイヤを確立する方法です。この方法は HOWTO 文書で説明されています。
2 番目の方法はより最近の方法で、OpenSSH 4.3 で導入されました。その結果今や、OpenSSH は SSH 接続のサーバおよびクライアント側に仮想ネットワークインターフェース (tun*) を作り、仮想インターフェースをあたかも物理インターフェースのように設定することが可能です。このトンネルシステムを有効化するにはまず、SSH サーバの設定ファイル (/etc/ssh/sshd_config) の中で PermitTunnel を「yes」に設定しなければいけません。SSH 接続を確立する際には、-w any:any オプションを使って明示的にトンネルの作成を要求しなければいけません (ここで any は必要な tun デバイス番号で置き替えます)。トンネルを作成するには、サーバおよびクライアント側でそのユーザが管理者権限を持っていることが必要です。そうすればネットワークデバイスを作成することが可能です (言い換えれば、接続は root で確立されなければいけません)。
SSH を使って仮想プライベートネットワークを作成する方法は、どちらもかなり直接的なものです。しかしながら、SSH の提供する VPN は最も効率のよい方法ではありません。特に、高レベルのトラフィックをうまく取り扱うことができません。
つまり、TCP/IP スタックが TCP/IP 接続 (SSH) の中にカプセル化される場合、TCP プロトコルは 2 回使われるという点です。1 回は SSH 接続で、もう 1 回がトンネル内です。これは特に、TCP はタイムアウト遅延を変更することでネットワークの状態に接続状態を適合させる機能があることで、問題になります。以下のサイトがこの問題についてより詳しく説明しています。このため、VPN over SSH はパフォーマンスに制約のない単発のトンネルに留めるべきです。

10.2.3. IPsec

IPsec は標準的な IP VPN の中にありますが、さらに詳しく実装を説明します。IPsec エンジンそれ自身は Linux カーネルに統合されています。さらに、要求されるユーザ空間部分、制御と設定ツール、は ipsec-tools パッケージによって提供されます。具体的には、それぞれのホストの /etc/ipsec-tools.conf には、ホストが接続する IPsec トンネル (IPsec 用語で Security Associations) のパラメータが含まれます。さらに /etc/init.d/setkey スクリプトを使うことで、トンネルを開始したり停止することが可能です (それぞれのトンネルは、仮想ネットワークに接続された他のホストと、安全なリンクを確立しています)。このファイルは setkey(8) マニュアルページの提供する文書を使って手作業で作ることも可能です。しかしながら、多数のマシン群にすべてのホスト用のパラメータを明示的に書くことはすぐに難しい作業になります。なぜなら、トンネルの数はすぐに増えるからです。この作業をより簡単にする、たとえば racoonstrongswan などの (IPsec Key Exchange 用の) IKE デーモンがあります。これを使えば、一元管理による作業の簡素化と、鍵を定期的に循環することによる作業の安全化が可能になります。
IPsec は標準規格という地位があるにも関わらず、その設定が複雑なことが原因で、具体的に使われることが少ないです。必要なトンネルが少なくて静的な場合は、OpenVPN に基づく解決策が通常好まれます。

10.2.4. PPTP

PPTP (Point-to-Point Tunneling Protocol) は 2 種類の通信チャンネルを使います。1 つは制御データで、もう 1 つがペイロードデータ用です。後者は GRE プロトコル (Generic Routing Encapsulation) を使います。標準的な PPP リンクはデータ交換チャンネル上に確立されます。

10.2.4.1. クライアントの設定

pptp-linux パッケージには、Linux 用に簡単に設定できる PPTP クライアントが含まれています。以下の説明は公式文書からヒントを得て作ったものです。
Falcot 管理者はいくつかのファイルを作成しました。すなわち /etc/ppp/options.pptp/etc/ppp/peers/falcot/etc/ppp/ip-up.d/falcot/etc/ppp/ip-down.d/falcot を作成しました。

例 10.2 /etc/ppp/options.pptp ファイル

# PPP options used for a PPTP connection
lock
noauth
nobsdcomp
nodeflate

例 10.3 /etc/ppp/peers/falcot ファイル

# vpn.falcot.com is the PPTP server
pty "pptp vpn.falcot.com --nolaunchpppd"
# the connection will identify as the "vpn" user
user vpn
remotename pptp
# encryption is needed
require-mppe-128
file /etc/ppp/options.pptp
ipparam falcot

例 10.4 /etc/ppp/ip-up.d/falcot ファイル

# Create the route to the Falcot network
if [ "$6" = "falcot" ]; then
  # 192.168.0.0/24 is the (remote) Falcot network
  route add -net 192.168.0.0 netmask 255.255.255.0 dev $1
fi

例 10.5 /etc/ppp/ip-down.d/falcot ファイル

# Delete the route to the Falcot network
if [ "$6" = "falcot" ]; then
  # 192.168.0.0/24 is the (remote) Falcot network
  route del -net 192.168.0.0 netmask 255.255.255.0 dev $1
fi

10.2.4.2. サーバの設定

pptpd は Linux 用の PPTP サーバです。主設定ファイルは /etc/pptpd.conf で、いくつかの変更が必要です。すなわち localip (ローカル IP アドレス) と remoteip (リモート IP アドレス) を変更する必要があります。以下の例では、PPTP サーバは常に 192.168.0.199 アドレスを使い、PPTP クライアントは 192.168.0.200 から 192.168.0.250 までの IP アドレスを受け取ります。

例 10.6 /etc/pptpd.conf ファイル

# TAG: speed
#
#       Specifies the speed for the PPP daemon to talk at.
#
speed 115200

# TAG: option
#
#       Specifies the location of the PPP options file.
#       By default PPP looks in '/etc/ppp/options'
#
option /etc/ppp/pptpd-options

# TAG: debug
#
#       Turns on (more) debugging to syslog
#
# debug

# TAG: localip
# TAG: remoteip
#
#       Specifies the local and remote IP address ranges.
#
#       You can specify single IP addresses separated by commas or you can
#       specify ranges, or both. For example:
#
#               192.168.0.234,192.168.0.245-249,192.168.0.254
#
#       IMPORTANT RESTRICTIONS:
#
#       1. No spaces are permitted between commas or within addresses.
#
#       2. If you give more IP addresses than MAX_CONNECTIONS, it will
#          start at the beginning of the list and go until it gets
#          MAX_CONNECTIONS IPs. Others will be ignored.
#
#       3. No shortcuts in ranges! ie. 234-8 does not mean 234 to 238,
#          you must type 234-238 if you mean this.
#
#       4. If you give a single localIP, that's ok - all local IPs will
#          be set to the given one. You MUST still give at least one remote
#          IP for each simultaneous client.
#
#localip 192.168.0.234-238,192.168.0.245
#remoteip 192.168.1.234-238,192.168.1.245
#localip 10.0.1.1
#remoteip 10.0.1.2-100
localip 192.168.0.199
remoteip 192.168.0.200-250
/etc/ppp/pptpd-options を編集して、PPTP サーバの使う PPP 設定を変更します。重要なパラメータはサーバ名 (pptp)、ドメイン名 (falcot.com)、DNS と WINS サーバの IP アドレスです。

例 10.7 /etc/ppp/pptpd-options ファイル

## turn pppd syslog debugging on
#debug

## change 'servername' to whatever you specify as your server name in chap-secrets
name pptp
## change the domainname to your local domain
domain falcot.com

## these are reasonable defaults for WinXXXX clients
## for the security related settings
# The Debian pppd package now supports both MSCHAP and MPPE, so enable them
# here. Please note that the kernel support for MPPE must also be present!
auth
require-chap
require-mschap
require-mschap-v2
require-mppe-128

## Fill in your addresses
ms-dns 192.168.0.1
ms-wins 192.168.0.1

## Fill in your netmask
netmask 255.255.255.0

## some defaults
nodefaultroute
proxyarp
lock
最後に、vpn ユーザ (と対応するパスワード) を /etc/ppp/chap-secrets ファイルに登録します。サーバ名だけは、アスタリスク (*) を使える他のインスタンスと異なり、明示的に指定しなければいけません。さらに、Windows PPTP クライアントはユーザ名ではなく DOMAIN\\USER という形で身元を語ります。このため、以下のファイルに FALCOT\\vpn ユーザが追加されています。ユーザに割り当てる IP アドレスを明記することも可能です。さらに IP アドレスフィールドのアスタリスクは動的にアドレスを割り当てることを意味します。

例 10.8 /etc/ppp/chap-secrets ファイル

# Secrets for authentication using CHAP
# client        server  secret      IP addresses
vpn             pptp    f@Lc3au     *
FALCOT\\vpn     pptp    f@Lc3au     *