OpenVPN
20131231

確認環境
 CentOS6.x
 CentOS5.x
 OpenVPN2.0.9
 OpenVPN2.2.2
 OpenVPN2.3.0
 OpenVPN2.3.2

概要
 1.SSL/TLS-VPNのサーバーを構築する。
 2.IPレベルでの通信が可能なトンネルモードを使用する。
 3.先立ってブリッジモードで実装を行っており、2つ目のVPNを構築する。
 →この場合、「」の設定については飛ばしても構いません。
 4.通信スループット20mbps以上を目指す。
 →暗号化処理の問題で、サーバーのハードウェアスペック(特にCPU)によって大幅に変わってきます。
 →当環境では、地デジ放送のデータ程度(15-18mbps)であればリアルタイムに転送出来る事を確認。
  CPU「A-10 5700(AES-NI未使用)」/メモリ「DDR3-2000-4096MB」/仮想環境OS /

OpenVPNトンネルモードによるメリット
 ルーティングによるアクセス制御の実装が容易
 ブリッジ周りの設定が必要ない為、設定構築が容易
 iphone及びandroidから接続が可能

OpenVPNトンネルモードによるデメリット
 TCP/IP以外のプロトコルを普通には使用出来ない(NetBIOS等)
 ファイアウォール周りでのトラブルが多い。
 →設定しない限りVPNはあくまでも隣接する外部ネットワークとの位置づけで認識される点に注意して下さい。
以下の仕様に基づいて設定をしています。

 VPNサーバ環境(Linux/ネットワークインターフェース/IPアドレス)
  IPアドレス : 192.168.0.3
  サブネットマスク  : 255.255.255.0(/24)
  ネットワークアドレス  : 192.168.0.0
  ブロードキャストアドレス : 192.168.0.255
  tunネットワークインターフェース名 : tun

 VPNサーバ仕様
  サーバーアドレス : ry.tl
  ポート : UDP 1195
  →デフォルトポートはブリッジモードで使用している為変更
  VPNネットワークアドレス : 192.168.111.0/24

 VPNクライアント
  OS : Windows
  ブリッジインターフェース名 : tun
  →「ローカルエリア2」 とかになっているアダプター名

 鍵強度
  RSA鍵 : 4096bit
   →パフォーマンスへの影響は限定的です。
   →各種鍵作成時間の増加。(最初のお星様作成時間の増加が著しい)
   →1時間に1回のSSL/TLSの再ネゴシエーションの時間の増加。
  対称鍵 : AES(256bit)
  →サーバースペックによりますが、パフォーマンスに直結します。
  →可能であれば「AES-NI」を実装すると劇的な向上が見込めます。(対応環境ではないので現在扱っていません。)

 同一システムでOpenVPNによるVPN環境を構築している為、デフォルト設定とは違う点
  server2.config : 「2」の部分
  →コンフィグファイル
  openvpn_tun.log : 「_tun」の部分
  →ログファイル
  ipp2.txt : 「2」の部分
  →配布IPを固定する際の設定ファイル
  ipp_tun.log : 「_tun」の部分
  →ログファイル
  ポート番号については任意
  参考 : 「OpenVPN(ブリッジ)
◆インストール
 [root@Server ~]# yum -y install openvpn
openvpnとlzoがインストールされる。

Centosの場合はFedoraと違い、標準ではyumインストール出来ません。
サードパーティのリポジトリの追加と、標準リポジトリの共存を図る為のプラグインを追加する必要があります。
 RPMforgeリポジトリ(CentOS5.x)
 EPELリポジトリ(CentOS6.x)
 yum-priorities

詳しくはぐーぐる先生にて。
◆CA証明書作成
 [root@Server ~]# cp -pr /usr/share/doc/openvpn-2.0.9/easy-rsa/2.0/ /etc/openvpn/easy-rsa

Centos6.xの場合は以下
 [root@Server ~]# cp -pr /usr/share/openvpn/easy-rsa/2.0/ /etc/openvpn/easy-rsa

 [root@Server ~]# cd /etc/openvpn/easy-rsa/
 [root@Server easy-rsa]# chmod +x *
 [root@Server easy-rsa]# vi vars

以下を設定
 # Increase this to 2048 if you
 # are paranoid. This will slow
 # down TLS negotiation performance
 # as well as the one-time DH parms
 # generation process.
  export KEY_SIZE=4096

 # These are the default values for fields
 # which will be placed in the certificate.
 # Don't leave any of these fields blank.
  export KEY_COUNTRY="JP(国名)"
  export KEY_PROVINCE="OSAKA(都道府県)"
  export KEY_CITY="OSAKA(市町村)"
  export KEY_ORG="ry.tl(サーバーアドレス)"
  export KEY_EMAIL="root@ry.tl(管理人メールアドレス)"

 [root@Server easy-rsa]# source vars
 [root@Server easy-rsa]# ./clean-all  
 [root@Server easy-rsa]# ./build-ca
色々出てくるけどエンター連打

 [root@Server easy-rsa]# cp -pr keys/ca.crt /etc/openvpn/
所定の位置へとコピーします。

◆サーバー証明書作成
 [root@Server easy-rsa]# ./build-key-server server
以下が出てくるまでエンター。

  Sign the certificate? [y/n]:y
  1 out of 1 certificate requests certified, commit? [y/n]y

[root@Server easy-rsa]# cp -pr keys/server.crt keys/server.key /etc/openvpn/
所定の位置へコピーします。

◆DHパラメータ作成
 [root@Server easy-rsa]# ./build-dh
お星様がいっぱい出てくるので終わるのを待つ。

 [root@Server easy-rsa]# cp -pr keys/dh4096.pem /etc/openvpn/
所定の位置へコピーします。

◆共有鍵作成
 [root@Server easy-rsa]# openvpn --genkey --secret keys/ta.key

 [root@Server easy-rsa]# cp -pr keys/ta.key /etc/openvpn/
所定の位置へコピーします。

◆クライアント証明書(「test」アカウント用)
 [root@Server easy-rsa]# ./build-key test
以下が出てくるまでエンター

  Sign the certificate? [y/n]:y
  1 out of 1 certificate requests certified, commit? [y/n]y

〜パス付きを作る場合〜
[root@Server easy-rsa]# ./build-key-pass test
 Enter PEM pass phrase: パスワード
 Verifying - Enter PEM pass phrase:パスワード

◆最後にもろもろをコピー(とりあえず1個ずつ「/root」にでも。)
 [root@Server easy-rsa]# mkdir /root/key

 [root@Server easy-rsa]# cp -pr /etc/openvpn/ca.crt /root/key/
 [root@Server easy-rsa]# cp -pr /etc/openvpn/easy-rsa/keys/test.crt /root/key/
 [root@Server easy-rsa]# cp -pr /etc/openvpn/easy-rsa/keys/test.key /root/key/
 [root@Server easy-rsa]# cp -pr /etc/openvpn/ta.key /root/key/
◆サーバーコンフィグを編集
 [root@Server ~]# vi /etc/openvpn/server2.conf
→サンプルConfigのパス「/usr/share/doc/openvpn-*/sample-config-files/server.conf」

----------------------------------------------------------------------------------------------------
# サーバー用コンフィグ
# Ver 20120202

# 使用するポートの指定(必須)
port 1195

# プロトコルの指定。TCPかUDP(必須)
proto udp

# TUNインターフェース指定(必須)
dev tun

# 認証用鍵ファイルのパス(必須)
ca ca.crt
cert server.crt
key server.key # This file should be kept secret
tls-auth ta.key 0 # This file is secret

# 鍵強度
dh dh4096.pem
cipher AES-256-CBC

# 配布するIPアドレスのテーブル(任意)
# 固定化する際に用いる
ifconfig-pool-persist ipp2.txt

# VPNのネットワークアドレスを指定(必須)
server 192.168.111.0 255.255.255.0

# 以下のローカルネットワークにアクセスする場合、VPNサーバーを経由する。(必須)
push "route 192.168.0.0 255.255.255.0"

# DNSサーバー/WINSサーバーの設定(任意)
#push "dhcp-option DNS 192.168.0.3"
#push "dhcp-option WINS 192.168.0.3"

# クライアント同士の通信を許可(任意)
client-to-client

# キープアライブの設定(推奨)
keepalive 10 120

# LZO(圧縮)の有効化(推奨)
comp-lzo

# ユーザー権限(必須)
user nobody
group nobody

# 読み込み関係(不明)
persist-key
persist-tun

# ログ関係(必須)
status /var/log/openvpn-status_tun.log
log /var/log/openvpn_tun.log
log-append /var/log/openvpn_tun.log

# ログ取得レベル(必須。レベルは任意)
verb 3

# 通信最適化(任意)
link-mtu 1400
mssfix 1300
fragment 1372

# エラーが出る場合の対処(推奨)
replay-window 128
----------------------------------------------------------------------------------------------------

※環境によって変更する事。

◆クライアントに対するIPアドレス配布を固定にする場合(一部のみでも可)
 [root@Server ~]# vi /etc/openvpn/ipp2.txt
test,192.168.111.64
test2,192.168.111.100
◆IPフォワードの設定その1
 [root@Server ~]# echo 1 > /proc/sys/net/ipv4/ip_forward

◆IPフォワードの設定その2
 [root@Server ~]# vi /etc/sysctl.conf
  # Controls IP packet forwarding
  net.ipv4.ip_forward =0

 これを以下に変更する。

  # Controls IP packet forwarding
  net.ipv4.ip_forward =1
◆iptablesの設定を変更
 [root@Server ~]# iptables -A INPUT -s 192.168.111.0/255.255.255.0 -j ACCEPT
VPNのネットワークエリアからの受信を許可する。

 [root@Server ~]# iptables -A FORWARD -s 192.168.111.0/255.255.255.0 -j ACCEPT
VPNのネットワークエリアからの受信を許可する。

 [root@Server ~]# iptables -A INPUT -p udp --dport 1195 -j ACCEPT
VPNに使用するポートへのアクセスを許可する。(ルータでも行う事)

どうしても構築がうまく行かない場合はFW(iptables)で引っかかっている場合が多いので、一度無効化して問題の切り分けしてみて下さい。
◆OpenVPNの起動
 [root@Server ~]# /etc/rc.d/init.d/openvpn start
 openvpn を起動中: [ OK ]

◆自動起動するように設定
 [root@Server ~]# chkconfig openvpn on
◆クライアント作業
先ほど「/root/key」にコピーした鍵一式と「client.ovpn」をC:\Program Files\OpenVPN\config\に保存。
◆クライアント作業(Windows64bitの場合)
先ほど「/root/key」にコピーした鍵一式と「client.ovpn」をC:\Program Files (x86)\OpenVPN\config\に保存。

補足として鍵一式
 ca.crt
 test.crt
 test.key
 ta.key
◆クライアント作業(「client.ovpn」をメモ帳などで開きます。)
# クライアント用コンフィグ
# Ver 20130114

# モード
client

# ネットワーク接続のデバイス名(コントロールパネルなりから確認設定をしてから変更)
dev-node tun

# プロトコル(サーバー側と合わせる。)
proto udp

# サーバーアドレス+ポート番号
remote ry.tl 1195

# 名前解決関係
resolv-retry infinite

# 特定のローカルポートを確保しない。
nobind

# Man-in-the-Middle攻撃対策
ns-cert-type server

# 読み込み関係
persist-key
persist-tun

# キーとかのパス(クライアント毎にファイル名などの変更が必須)
ca ca.crt
cert test.crt
key test.key
tls-auth ta.key 1

# 鍵強度
cipher AES-256-CBC

# LZO(圧縮)の有効化。サーバー側とあわせる必要がある。
comp-lzo

# ログ取得レベル
verb 3

# OpenVPNサーバからパラメータを受け取るための設定らしい。
pull

# OpenVPNサーバからIPアドレスを受け取るための設定らしい。
float

# 通信最適化
link-mtu 1400
mssfix 1300
fragment 1372

# AES-NI対応CPUであれば下記設定を有効にして下さい。
#engine aesni

# エラーが出る場合の対処
replay-window 128
----------------------------------------------------------------------------------------------------

※環境によって変更する事。
◆IPv6機能の停止
 1.コントロールパネル を開く。
 2.ネットワークと共有センター を開く。
 3.アダプターの設定の変更 を開く。
 4.「tun」を右クリックして「プロパティ」を開く。
 5.「インターネット プロトコル バージョン 6(TCP/IPv6)」のチェックを外す。

通信が正常に行えず、エラーが発生する事への対処です。
◆アクセス制御(ルーティング)について
 以上の設定で実装した場合、クライアントがアクセス出来る範囲は以下の通り。
  192.168.111.0/24
 つまりVPNサーバー及びVPNクライアント同士となります。
 但し、クライアント双方にて192.168.111.0のアクセスを許可(FW設定)している必要があります。
 「server2.conf」内の「client-to-client」をコメントアウトする事でクライアント同士の通信を許可しない設定も可能

 サーバー側内部ネットワークと通信を行う場合はルーターでVPNネットワークに対してのルーティングが必要となります。
  192.168.111.0/24(255.255.255.0)への通信を192.168.0.3にルーティング
 Ciscoルーターでの設定例(192.168.0.0のルーター)
  Cisco851#conf t
  Cisco851(config)#ip route 192.168.111.0 255.255.255.0 192.168.0.3
 →この場合クライアントがアクセス出来る範囲は以下の通り
  192.168.0.0/24
  192.168.111.0/24
  但し、アクセス先にて192.168.111.0のアクセスを許可(FW設定)している必要があります。
  また、その他ネットワーク(192.168.10.0/24)等が存在しており、疎通させる場合には同じく双方にてアクセス許可が必要

隣接ネットワークとしてVPNが存在していると考え、アクセス制御を構想するといいかもしれません。
ここでは記述しきれない程の様々な制御方法があります。
◆iphoneでの接続に関して
下記iphone用クライアントをダウンロード
 OpenVPN Connect

iphone.ovpnをメモ帳で開きます。(UTF-8 BOM無)
# iphone用
# 20131231

tls-client
key-direction 1
proto udp
remote ry.tl
port 1195
cipher AES-256-CBC
replay-window 128

<ca>
-----BEGIN CERTIFICATE-----
# ca.crt内の中身貼り付け
-----END CERTIFICATE-----
</ca>
<cert>
-----BEGIN CERTIFICATE-----
# test.crt内の中身貼り付け
-----END CERTIFICATE-----
</cert>
<key>
-----BEGIN CERTIFICATE-----
# test.key内の中身貼り付け
-----END CERTIFICATE-----
</key>
<tls-auth>
-----BEGIN CERTIFICATE-----
# ta.key内の中身貼り付け
-----END CERTIFICATE-----
</tls-auth>

※軽く確認した限りでは、TLS、comp-lzo、及びfragment設定をサーバークライアント共に
無効にしないと接続出来ませんでした。(要検証)
androidはWindowsやLinuxと同様の手順で接続を確認
〜運用後の操作〜
◆追加で使用するクライアント用の認証鍵を作成する場合。
 [root@Server ~]# cd /etc/openvpn/easy-rsa/
 [root@Server easy-rsa]# source vars

 [root@Server easy-rsa]# ./build-key test2
以下が出てくるまでエンター
  Sign the certificate? [y/n]:y
  1 out of 1 certificate requests certified, commit? [y/n]y

〜パス付きを作る場合〜
 [root@Server easy-rsa]# ./build-key-pass test2
  Enter PEM pass phrase: パスワード
  Verifying - Enter PEM pass phrase:パスワード

以上