OpenVPN-2.0.5 ルーティングモード/共通鍵を使う [FC4]

[サーバの実験室 Redhat/Fedora]

作成 : 2006/02/05

"サーバの実験室"の検索


OpenVPN 共通鍵を使う

証明書を使うなら、OpenVPN-2.0.5 証明書を使うを参照。

共通鍵を使ってVPN接続してみる。 Fedora Coreでの実験したときの記録だが、Windowsでもほとんど同じやり方。 環境は下図のような感じ。 接続を開始するほうがクライアントで、待っているほうがサーバ。

               +---+ +---+ +---+
               |PC1| |PC2| |PC3|
               +-+-+ +-+-+ +-+-+
                 |     |     |
192.168.0.0/24 --+-+---+-----+--
                   |
+----------------+ |          +---+            +----------------+
| OpenVPN Server +-+----------+ R +------------+ OpenVPN Client |
+----------------+            +---+            +----------------+
 eth0(192.168.0.1)                             eth0(192.168.1.1)

論理的には下図のような構成かな。

+---+ +---+ +---+
|PC1| |PC2| |PC3|
+-+-+ +-+-+ +-+-+
  |     |     |
--+-+---+-----+-- 192.168.0.0/24
    |
    |   +------------------------------+              +------------------------------+
    |   +------+                +------+              +------+                +------+
    +---+ eth0 +----------------+ tun0 +--------------+ tun0 +----------------+ eth0 +
        +------+ OpenVPN Server +------+              +------+ OpenVPN Client +------+
        +------------------------------+              +------------------------------+
        192.168.0.1           172.16.0.1              172.16.0.2           192.168.1.1

Fedora Coreへのインストール

OpenVPN-2.0.5 インストールを参照。 サーバになるPCとクライアントになるPCの両方にインストールしておく。

共通鍵を作成(サーバ側で実行)

次のコマンドを実行する。

# openvpn --genkey --secret /etc/openvpn/static.key
Windowsでは、
> openvpn --genkey --secret "C:\Program Files\OpenVPN\config\static.key"
のようにする

/etc/openvpnディレクトリに、共通鍵ファイルstatic.keyが作成される。 ファイルの中身は下のような感じ。

#
# 2048 bit OpenVPN static key
#
-----BEGIN OpenVPN Static key V1-----
4361a4ed1737c1f26c801c82e7d17302
6c64fab35c83f28d1e87818ebd3308ed
143235b881cf32011d28dee1116b0fa5
d320e64deed1b8e324635a5dbdc04bcc
b13854e146e15e46c312b1fefe8bc601
2fc7b110b2be71afe12bb03e63313007
43570b6d4152507fc61c0d760306af74
6e4ec4b31fe6af1224c1211f0db711d1
1067d562b7c14ace1555d2531bacb30e
05205860177d2af42123ef6c5b67ddf2
71cb34b770bc6ece18cd1ef7133f3741
28051667746151b7f4d40c8fba8bb12c
41cf0240b4785b456718fc61c1f3c70e
65c2135dfe87e22dc1f3f58e30f4167a
55be7ab0d167cd53ff3fb0fe6c5d8ef4
4116f23f62f8ddaa301c8e1b7e06b3d2
-----END OpenVPN Static key V1-----

共通鍵ファイルstatic.keyは、関係ないユーザからアクセスされないようにしておくこと。 rootだけ読み書き可能とか。

# chown root:root static.key
# chmod 600 static.key
Windowsでは....

共通鍵をコピー(クライアント側で実行)

クライアントでは共通鍵を作らない。 サーバで作成した共通鍵ファイルstatic.keyをもらってきて、/etc/openvpnディレクトリにコピーする。 関係ないユーザからアクセスされないよう、rootだけ読み書き可能とかにしておくこと。

# cp static.key /etc/openvpn
Windowsでは、C:\Program Files\OpenVPN\configフォルダにコピーしておく

# chown root:root /etc/openvpn/static.key
# chmod 600 /etc/openvpn/static.key

サーバ側の設定ファイル(サーバ側で実行)

/etc/openvpnディレクトリに、拡張子confの適当な名前のファイルを作る (Windowsでは、C:\Program Files\OpenVPN\configフォルダに、拡張子ovpnの適当な名前のファイルを作る)。 仮に、static.confとしておく。 これにサーバの設定を書く。

# /etc/openvpn/static.conf
# サーバの設定

# tunデバイスを使って、レイヤ3のVPN接続をする
dev tun

# プロトコルにはTCPを使う
# UDPを使うときは、proto udpとする
proto tcp-server

# 1194番ポート(デフォルト)で待つ
# root権限で動作させない場合、特権ポートは使えない(WindowsではOK)
port 1194

# 自分側の仮想インタフェースに172.16.0.1を割り当てる
# 相手側の仮想インタフェースは172.16.0.2
ifconfig 172.16.0.1 172.16.0.2

# 共通鍵を指定する
# Windowsでは、secret "C:\\Program Files\\OpenVPN\\config\\static.key"のように指定する(\でエスケープすること)
secret "/etc/openvpn/static.key"

# どのユーザの権限でOpenVPNを動作させるか指定する
# パッケージインストール時、openvpnユーザも作成されている
# Windowsでは無効
user openvpn

# どのグループの権限でOpenVPNを動作させるか指定する
# パッケージインストール時、openvpnグループも作成されている
# Windowsでは無効
group openvpn

# このオプションを指定すると、起動時(のroot権限で動作しているとき)にしかtunデバイスをオープンしない
persist-tun

# このオプションを指定すると、起動時(のroot権限で動作しているとき)にしか鍵ファイルを読み込まない
persist-key

# /etc/openvpnディレクトリにchrootする
chroot "/etc/openvpn"

OpenVPNサーバは、クライアントが切断するとき、SIGUSR1を受信して再起動する。 このとき、tunデバイスを一度クローズして再オープンするのだが、tunデバイス/dev/net/tunはrootユーザとrootグループしかアクセスできない。 このため、userオプションでroot以外のユーザを指定すると、Permission Deniedでサーバのプロセスは終了してしまう。 persist-tunオプションを指定すると、プロセス起動時にroot権限で動作しているときしかtunデバイスにアクセスしないため、これを回避できる。

同じような理由で、portオプションで特権ポートを指定した場合、最初のクライアントからは正常に接続できるが、クライアントが切断したとたんサーバは異常終了するという現象が起きる。 (openvpnユーザでは特権ポートを開けないため)。 こちらは回避手段がないので、どうしても特権ポートで受けたい場合はポートフォワーディングするしかない。

クライアント側の設定ファイル(クライアント側で実行)

/etc/openvpnディレクトリに、拡張子confの適当な名前のファイルを作る (Windowsでは、C:\Program Files\OpenVPN\configフォルダに、拡張子ovpnの適当な名前のファイルを作る)。 仮に、static.confとしておく。 これにクライアントの設定を書く。

# /etc/openvpn/static.conf
# クライアントの設定

# tunデバイスを使って、レイヤ3のVPN接続をする
dev tun

# プロトコルにはTCPを使う
# UDPを使うときは、proto udpとする
proto tcp-client

# サーバの1194番ポート(デフォルト)を使って接続する
port 1194

# サーバのIPアドレス
remote 192.168.0.1

# 自分側の仮想インタフェースに172.16.0.2を割り当てる
# 相手側の仮想インタフェースは172.16.0.1
ifconfig 172.16.0.2 172.16.0.1

# 共通鍵を指定する
# Windowsでは、secret "C:\\Program Files\\OpenVPN\\config\\static.key"のように指定する(\でエスケープすること)
secret "/etc/openvpn/static.key"

# /etc/openvpnディレクトリにchrootする
chroot "/etc/openvpn"

# WEBプロキシ経由で接続する
# プロキシ経由の場合はTCPプロトコルを使うこと
# http-proxy proxy.example.com 8000

# サーバ背後のLANへのルーティング
route 192.168.0.0 255.255.255.0 172.16.0.1
# サーバへのルーティング
# VPN接続をするためのパケットがVPNトンネルを通るようなルーティングの指定をしてはいけない
route 192.168.0.1 255.255.255.255 X.X.X.X

# デフォルトルートをVPNにするには、redirect-gatewayを使う
# redirect-gateway def1

クライアント側では、persist-tunオプションやpersist-keyオプションはいらないと思う。

OpenVPNを起動(サーバ側で実行)

OpenVPNを起動する

# openvpn --config /etc/openvpn/static.conf
Windowsでは、xxxx.ovpnファイルを右クリックして"Start OpenVPN on this config file"をクリックする。

Sun Feb  5 18:34:49 2006 OpenVPN 2.0.5 i386-redhat-linux-gnu [SSL] [LZO] [EPOLL] built on Jan  5 2006
Sun Feb  5 18:34:49 2006 Static Encrypt: Cipher 'BF-CBC' initialized with 128 bit key
Sun Feb  5 18:34:49 2006 Static Encrypt: Using 160 bit message hash 'SHA1' for HMAC authentication
Sun Feb  5 18:34:49 2006 Static Decrypt: Cipher 'BF-CBC' initialized with 128 bit key
Sun Feb  5 18:34:49 2006 Static Decrypt: Using 160 bit message hash 'SHA1' for HMAC authentication
Sun Feb  5 18:34:49 2006 TUN/TAP device tun0 opened
Sun Feb  5 18:34:49 2006 /sbin/ip link set dev tun0 up mtu 1500
Sun Feb  5 18:34:49 2006 /sbin/ip addr add dev tun0 local 172.16.0.1 peer 172.16.0.2
Sun Feb  5 18:34:49 2006 Data Channel MTU parms [ L:1546 D:1450 EF:46 EB:4 ET:0 EL:0 ]
Sun Feb  5 18:34:49 2006 Local Options hash (VER=V4): '836050b1'
Sun Feb  5 18:34:49 2006 Expected Remote Options hash (VER=V4): '7c6d049b'
Sun Feb  5 18:34:49 2006 chroot to '/etc/openvpn' and cd to '/' succeeded
Sun Feb  5 18:34:49 2006 GID set to openvpn
Sun Feb  5 18:34:49 2006 UID set to openvpn
Sun Feb  5 18:34:49 2006 Listening for incoming TCP connection on [undef]:1194
クライアントが接続してくるまで待つ
Sun Feb  5 18:36:53 2006 TCP connection established with 192.168.1.1:2865
Sun Feb  5 18:36:53 2006 TCPv4_SERVER link local (bound): [undef]:1194
Sun Feb  5 18:36:53 2006 TCPv4_SERVER link remote: 192.168.1.1:2865
Sun Feb  5 18:37:03 2006 Peer Connection Initiated with 192.168.1.1:2865
Sun Feb  5 18:37:03 2006 Initialization Sequence Completed
クライアントとの接続確立
クライアントが切断
Sun Feb  5 18:39:53 2006 Connection reset, restarting [-1]
Sun Feb  5 18:39:53 2006 TCP/UDP: Closing socket
Sun Feb  5 18:39:53 2006 SIGUSR1[soft,connection-reset] received, process restarting
Sun Feb  5 18:39:53 2006 Restart pause, 1 second(s)
Sun Feb  5 18:39:54 2006 Re-using pre-shared static key
Sun Feb  5 18:39:54 2006 Preserving previous TUN/TAP instance: tun0
Sun Feb  5 18:39:54 2006 Data Channel MTU parms [ L:1546 D:1450 EF:46 EB:4 ET:0 EL:0 ]
Sun Feb  5 18:39:54 2006 Local Options hash (VER=V4): '836050b1'
Sun Feb  5 18:39:54 2006 Expected Remote Options hash (VER=V4): '7c6d049b'
Sun Feb  5 18:39:54 2006 Listening for incoming TCP connection on [undef]:1194
クライアントが接続してくるまで待つ

終了するときは、Ctrl+C (Windowsの場合は、F4キーで終了)。

VPN接続が確立しているにもかかわらず、サーバまたはサーバ背後のLANへ接続できない場合は、iptablesのINPUTチェインとFORWARDチェインを確認してみる。 あと、/etc/sysctl.confファイルのnet.ipv4.ip_forwardが"1"になっていることを確認する。

OpenVPNを起動(クライアント側で実行)

OpenVPNを起動する

# openvpn --config /etc/openvpn/static.conf
Windowsでは、xxxx.ovpnファイルを右クリックして"Start OpenVPN on this config file"をクリックする。

Sun Feb  5 18:43:36 2006 OpenVPN 2.0.5 i386-redhat-linux-gnu [SSL] [LZO] [EPOLL] built on Jan  5 2006
Sun Feb  5 18:43:36 2006 WARNING: you are using user/group/chroot without persist-key/persist-tun -- this may cause restarts to fail
Sun Feb  5 18:43:36 2006 TUN/TAP device tun0 opened
Sun Feb  5 18:43:36 2006 /sbin/ip link set dev tun0 up mtu 1500
Sun Feb  5 18:43:36 2006 /sbin/ip addr add dev tun0 local 172.16.0.2 peer 172.16.0.1
Sun Feb  5 18:43:36 2006 chroot to '/etc/openvpn' and cd to '/' succeeded
Sun Feb  5 18:43:36 2006 Attempting to establish TCP connection with 192.168.0.1:1194
Sun Feb  5 18:43:36 2006 TCP connection established with 192.168.0.1:1194
Sun Feb  5 18:43:36 2006 TCPv4_CLIENT link local: [undef]
Sun Feb  5 18:43:36 2006 TCPv4_CLIENT link remote: 192.168.0.1:1194
Sun Feb  5 18:43:46 2006 Peer Connection Initiated with 192.168.0.1:1194
Sun Feb  5 18:43:46 2006 Initialization Sequence Completed
サーバとの接続確立
サーバから切断
Sun Feb  5 18:44:37 2006 event_wait : Interrupted system call (code=4)
Sun Feb  5 18:44:37 2006 SIGINT[hard,] received, process exiting

終了するときは、Ctrl+C (Windowsの場合は、F4キーで終了)。

サーバ起動時にOpenVPNも起動(サーバ・クライアントとも)

chkconfigを使って、サーバ起動時に開始するサービスとして登録する。

# chkconfig openvpn on

サーバ起動時に/etc/init.d/openvpnスクリプトが実行される。 このスクリプトは、/etc/openvpnディレクトリにあるxxxx.confファイルを*すべて*読み込む。 ログは、/var/log/messagesを見ること。

Windowsの場合は、"OpenVPN Service"サービスの"スタートアップの種類"を"自動"に設定する。 C:\Program Files\OpenVPN\configフォルダにあるxxxx.ovpnファイルを*すべて*読み込む。 ログは、C:\Program Files\OpenVPN\log\xxxx.logを見ること。

特権ポートで待つように見せかけるための設定(サーバ側)

サーバ側の設定ファイルで書いたように、OpenVPNは特権ポートを使うことができない。 しかし、イントラネットから外部へのアクセスが80番ポート宛や443番ポート宛だけに制限されていることがある。 この場合、iptablesなどでポートフォワーディングしなければならない。

# /etc/sysconfig/iptablesに追加

*nat
:PREROUTING ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A PREROUTING -i eth0 -p tcp -d 192.168.0.1 --dport 443 -j DNAT --to-destination 192.168.0.1:1194

[サーバの実験室 Redhat/Fedora]