Product SiteDocumentation Site

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

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

10.2.1. OpenVPN

OpenVPN は仮想プライベートネットワーク作成専用ソフトウェアの一種です。OpenVPN をセットアップするには VPN サーバ上とクライアント上に仮想ネットワークインターフェイスの作成が必要です; 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 を使えば会社内のプライベート認証局を作成することが可能です。この目的で、OpenVPN には easy-rsa ツールが含まれ、これを使って X.509 証明書基盤の機能が提供されます。easy-rsa ツールは openssl コマンドを使うスクリプト群です; スクリプトは /usr/share/doc/openvpn/examples/easy-rsa/2.0/ 以下に含まれています。
Falcot Corp の管理者は easy-rsa ツールを使い、サーバおよびクライアントに必要な証明書を作ります。easy-rsa ツールを使うことで、全てのクライアントの設定を同じ様にすることが可能です。クライアントは Falcot のプライベート認証局から来た証明書を信頼するようにセットアップしなければいけません。Falcot のプライベート認証局が最初に作成する証明書です; この目的を達成するために、管理者は easy-rsa を含むディレクトリをより適切な場所にコピーします。コピーする場所は、認証局の秘密鍵が盗まれる危険性を和らげるために、ネットワークに繋がれていないマシンが好ましいです。
$ cp -r /usr/share/doc/openvpn/examples/easy-rsa/2.0 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"
$ . ./vars
NOTE: If you run ./clean-all, I will be doing a rm -rf on /home/rhertzog/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) []:
Common Name (eg, your name or your server's hostname) [Falcot Corp CA]:
Name []:
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) []:
Common Name (eg, your name or your server's hostname) [vpn.falcot.com]:
Name []:
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/rhertzog/pki-falcot/openssl.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'
commonName            :PRINTABLE:'vpn.falcot.com'
emailAddress          :IA5STRING:'admin@falcot.com'
Certificate is to be certified until Oct  9 13:57:42 2020 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) []:
Common Name (eg, your name or your server's hostname) [JoeSmith]:Joe Smith
Name []:
Email Address [admin@falcot.com]:joe@falcot.com
[…]
全ての証明書を作ったら、証明書を適切な場所にコピーする必要があります: ルート証明書の公開鍵 (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.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 接続の開始と停止は /etc/init.d/openpvn start name/etc/init.d/openpvn stop name コマンドを使えばいつでも可能です (ここで、接続名 name/etc/openvpn/name.conf で定義したたものにマッチします)。
network-manager-openvpn-gnome パッケージには、Network Manager の拡張 (「ローミングユーザ向けの自動ネットワーク設定」 参照) が含まれ、これを使うことで OpenVPN 仮想プライベートネットワークを管理することが可能です。誰もがグラフィカルに OpenVPN 接続を設定し、ネットワーク管理アイコンからこれを制御することが可能です。

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

SSH を使った仮想プライベートネットワークの作成法には、2 種類の方法があります。歴史上重要な方法が SSH リンクの上で PPP レイヤを確立する方法です。この方法は HOWTO 文書で説明されています:
The second method is more recent, and was introduced with OpenSSH 4.3; it is now possible for OpenSSH to create virtual network interfaces (tun*) on both sides of an SSH connection, and these virtual interfaces can be configured exactly as if they were physical interfaces. The tunneling system must first be enabled by setting PermitTunnel to “yes” in the SSH server configuration file (/etc/ssh/sshd_config). When establishing the SSH connection, the creation of a tunnel must be explicitly requested with the -w any:any option (any can be replaced with the desired tun device number). This requires the user to have administrator privilege on both sides, so as to be able to create the network device (in other words, the connection must be established as 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) マニュアルページの提供する文書を使って手作業で作ることも可能です。しかしながら、多数のマシン群に全てのホスト用のパラメータを明示的に書くことはすぐに難しい作業になります。なぜなら、トンネルの数はすぐに増えるからです。この作業をより簡単にする、例えば racoonstrongswanopenswan 等の (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
The last step involves registering the vpn user (and the associated password) in the /etc/ppp/chap-secrets file. Contrary to other instances where an asterisk (*) would work, the server name must be filled explicitly here. Furthermore, Windows PPTP clients identify themselves under the DOMAIN\\USER form, instead of only providing a user name. This explains why the file also mentions the FALCOT\\vpn user. It is also possible to specify individual IP addresses for users; an asterisk in this field specifies that dynamic addressing should be used.

例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     *