OpenVPN(ブリッジ)
20120205
確認環境
CentOS6.x
CentOS5.x
Fedora8-10
概要
1.SSL/TLS-VPNのサーバーを構築する。
2.L2レベルでの通信が可能なブリッジモードを使用する。
3.通信スループット20mbps以上を目指す。
→暗号化処理の問題で、サーバーのハードウェアスペック(特にCPU)によって大幅に変わってきます。
→当環境では、地デジのデータ程度であればリアルタイムに転送出来る事を確認。
CPU「C2Q 9550」/メモリ「DDR3-1066-1024MB」/HDD「RealSSD C300」/仮想環境OS
トンネルモード(L3)VPNを構築する場合は「OpenVPN」を参考
OpenVPNブリッジモードによるメリット
ルーティング設定が不要
TCP/IP以外のプロトコルを使用可能
→通常の内部ネットワークと同様に、NetBIOSによるファイル転送やDLNAが使えます。
OpenVPNブリッジモードによるデメリット
アクセス制御の実装が面倒
→基本的には「client-to-client」のコメントアウトをしない限り、VPNサーバ側内部ネットワークに属する
システム全てと通信が可能な為、アクセス制限の方法が限られてしまう。
→内部ネットワーク用NICが増えたと認識する(ようなもの)という点でトンネルモードと大きな違いがあります。
以下の仕様に基づいて設定をしています。
VPNサーバ環境(Linux/ネットワークインターフェース/IPアドレス)
IPアドレス : 192.168.0.3
サブネットマスク : 255.255.255.0(/24)
ネットワークアドレス : 192.168.0.0
ブロードキャストアドレス : 192.168.0.255
物理ネットワークインターフェース名 : eth0
ブリッジ用ネットワークインターフェース名 : br0
TAPインターフェース名 : tap0
VPNサーバ仕様
サーバーアドレス : ry.tl
ポート : UDP 1194
VPNクライアントIPアドレスプール : 192.168.0.64 〜 192.168.0.127
VPNクライアント
OS : Windows
ブリッジインターフェース名 : tap
→「ローカルエリア2」 とかになっているアダプター名
鍵強度
RSA鍵 : 4096bit
→パフォーマンスへの影響は限定的です。
→各種鍵作成時間の増加。(最初のお星様作成時間の増加が著しい)
→1時間に1回のSSL/TLSの再ネゴシエーションの時間の増加。
対称鍵 : AES(256bit)
→サーバースペックによりますが、パフォーマンスに直結します。
→可能であれば「AES-NI」を実装すると劇的な向上が見込めます。(対応環境ではないので現在扱っていません。)
◆インストール
[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
[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/server.conf
----------------------------------------------------------------------------------------------------
# サーバー用コンフィグ
# Ver 20120124
# 使用するポートの指定(必須)
port 1194
# プロトコルの指定。TCPかUDP(必須)
proto udp
# TAPインターフェース指定(必須)
dev tap0
# 認証用鍵ファイルのパス(必須)
ca ca.crt
cert server.crt
key server.key
tls-auth ta.key 0
# 鍵強度
dh dh4096.pem
cipher AES-256-CBC
# 配布するIPアドレスのテーブル(任意)
# 固定化する際に用いる
ifconfig-pool-persist ipp.txt
# VPNサーバーのアドレスと、VPNクライアントのアドレスの幅指定(必須)
server-bridge 192.168.0.3 255.255.255.0 192.168.0.64 192.168.0.127
# 以下のローカルネットワークにアクセスする場合、VPNサーバーを経由する。(推奨)
push "route 192.168.0.0 255.255.255.0"
# DNSサーバー/WINSサーバーの設定(任意)
push "dhcp-option DNS 192.168.0.3"
push "dhcp-option DNS 192.168.0.1"
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.log
log /var/log/openvpn.log
log-append /var/log/openvpn.log
# ログ取得レベル(必須。レベルは任意)
verb 3
# 下記設定については動作の保証は出来ません。
# うまく行けばスループット向上を見込めます。(当環境でNetBIOSを用いたファイル送信で20-25mbps前後)
# ※TAPアダプターが10Mbps接続となっている場合がありますが、実際にはそれ以上の速度で通信も可能です。
# 以下、通信最適化
# MTUを指定(VPN及びL2ヘッダを付与する必要がある為、データサイズを小さくするとオーバーヘッドが減ると予想)
link-mtu 1400
# MSSを指定(上記の通り)
mssfix 1300
# UDPのみ。断片化を防止する為に変更(MTU-28の値を指定)
fragment 1372
# エラーが出る場合の対処
replay-window 128
----------------------------------------------------------------------------------------------------
※環境によって変更する事。
◆クライアントに対するIPアドレス配布を固定にする場合(一部のみでも可)
[root@Server ~]# vi /etc/openvpn/ipp.txt
test,192.168.0.64
test2,192.168.0.120
◆サーバー用ブリッジのインストール
[root@Server ~]# yum -y install bridge-utils
◆サーバー用ブリッジの設定(起動用スクリプトの作成)
[root@Server ~]# vi /etc/openvpn/bridge-start
#!/bin/bash
# 20111219
# ブリッジインターフェース名
br="br0"
# TAPアダプター(インターフェース)名
tap="tap0"
# 物理ネットワークインターフェース名
eth="eth0"
# ひとつ上の物理ネットワークインターフェースのIPアドレス
eth_ip="192.168.0.3"
# サブネットマスク
eth_netmask="255.255.255.0"
# ブロードキャストアドレス
eth_broadcast="192.168.0.255"
# 以降設定不要
for t in $tap; do
openvpn --mktun --dev $t
done
brctl addbr $br
brctl addif $br $eth
for t in $tap; do
brctl addif $br $t
done
for t in $tap; do
ifconfig $t 0.0.0.0 promisc up
done
ifconfig $eth 0.0.0.0 promisc up
ifconfig $br $eth_ip netmask $eth_netmask broadcast $eth_broadcast
※IPアドレス部分を環境に合わせて設定する事。
※書き換える際はインターフェース名に注意
◆サーバー用ブリッジの設定A(停止用のスクリプトの作成)
[root@Server ~]# vi /etc/openvpn/bridge-stop
#!/bin/bash
# 20110129
# ブリッジインターフェース名(ifconfig等で要確認)
br="br0"
# TAPアダプター(インターフェース)名
tap="tap0"
# 以降設定不要
ifconfig $br down
brctl delbr $br
for t in $tap; do
openvpn --rmtun --dev $t
done
※環境に合わせて設定する事。
※書き換える際はインターフェース名に注意
◆ネットワークとOpenVPNの起動と終了の設定
起動順としては「ネットワークの起動→ブリッジ起動→OpenVPNの起動」
終了順としては「OpenVPNの終了→ブリッジ終了→ネットワークの終了」
これらを実装するために設定を行う。
[root@Server ~]# vi /etc/rc.d/init.d/network
----------------------------------------------------------------------------------------------------
びふぉー
touch /var/lock/subsys/network
[ -n "${NETWORKDELAY}" ] && /bin/sleep ${NETWORKDELAY}
;;
stop)
# Don't shut the network down if root is on NFS or a network
# block device.
rootfs=$(awk '{ if ($1 !~ /^[ \t]*#/ && $2 == "/" && $3 != "rootfs") { print $3; }}' /proc/mounts)
rootopts=$(awk '{ if ($1 !~ /^[ \t]*#/ && $2 == "/") { print $4; }}' /etc/mtab)
if [[ "$rootfs" =~ "^nfs" ]] || [[ "$rootopts" =~ "_netdev|_rnetdev" ]] ; then
exit 1
fi
----------------------------------------------------------------------------------------------------
あふたー
touch /var/lock/subsys/network
#ブリッジ有効化
/etc/openvpn/bridge-start
#OpenVPN起動
/etc/rc.d/init.d/openvpn start
[ -n "${NETWORKDELAY}" ] && /bin/sleep ${NETWORKDELAY}
;;
stop)
# Don't shut the network down if root is on NFS or a network
# block device.
#OpenVPN停止
/etc/rc.d/init.d/openvpn stop
#ブリッジ無効化
/etc/openvpn/bridge-stop
rootfs=$(awk '{ if ($1 !~ /^[ \t]*#/ && $2 == "/" && $3 != "rootfs") { print $3; }}' /proc/mounts)
rootopts=$(awk '{ if ($1 !~ /^[ \t]*#/ && $2 == "/") { print $4; }}' /etc/mtab)
if [[ "$rootfs" =~ "^nfs" ]] || [[ "$rootopts" =~ "_netdev|_rnetdev" ]] ; then
exit 1
fi
※システムのアップデートで本ファイルの内容が初期化される場合があります。
その場合の症状としては、起動時に自動でopenvpnが立ち上がらなくなり、
openvpnデーモンを起動しても接続は出来るがホストとの通信が出来ないといった不具合が発生します。
この症状が見られた場合は本ファイルを一度見直して下さい。
◆上記対策の為、一日一回本ファイルの中身を調査するスクリプトを作成(任意)
[root@Server ~]# vi /etc/cron.daily/openvpn_network.sh
#!/bin/sh
export LANG=ja_JP.UTF-8
# Ver 20111214
# ネットワークスクリプトファイル
FILE="/etc/rc.d/init.d/network"
# 検索キーワード
KEY="openvpn"
# メール送信先アドレス。(デフォルトroot宛)
MAILADDRESS="root"
# 以降設定不要
if grep $KEY $FILE > /dev/null 2>&1 ; then
:
else
echo -e "「$FILE」内にて、「$KEY」の文言を確認出来ません。\nOpenVPNの動作に支障が出る可能性がありますので、確認して下さい。\n参考「http://ry.tl/openvpn.html」"| mail -s "ネットワークスクリプト内容の変更を確認" $MAILADDRESS
fi
→cronにて実行され、問題があればメールにて通知されてきます。
◆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 FORWARD -s 192.168.0.0/255.255.255.0 -j ACCEPT
内部アドレスからの通過を許可する。
[root@Server ~]# iptables -A INPUT -p udp --dport 1194 -j ACCEPT
VPNに使用するポートへのアクセスを許可する。(ルータでも行う事)
----------------------------------------------------------------------------------------------------
インターフェース名からIPアドレスを取得して設定している場合は「eth0」から「br0」に変更する必要があります。
→CentOSで自宅サーバー構築様のiptables設定を用いている場合を想定して記します。
赤文字は変更/青文字は追記。試していないので動作の保証は出来ません。
# インタフェース名定義
LAN=br0
# 外部からのUDP1194番ポート(OpenVPN)へのアクセスを日本からのみ許可
# ※OpenVPNサーバーを公開する場合のみ
iptables -A INPUT -p udp --dport 1194 -j ACCEPT_COUNTRY
# 内部からの通過をすべて許可
iptables -A FORWARD -s $LOCALNET -j ACCEPT
どうしても構築がうまく行かない場合はFW(iptables)で引っかかっている場合が多いので、一度無効化して問題の切り分けしてみて下さい。
◆OpenVPNの起動
[root@Server ~]# /etc/rc.d/init.d/network restart
初回は終了する際に、存在しないブリッジインターフェースを終了させようとしてエラーが発生しますが、問題はありません。
以下のようにインターフェースの起動、ブリッジの起動、OpenVPNの起動がされればOK
インターフェース eth0 を終了中: [ OK ]
ループバックインターフェースを終了中 [ OK ]
ループバックインターフェイスを呼び込み中 [ OK ]
インターフェース eth0 を活性化中:
eth0 のIP情報を検出中... 完了。
Wed Jul 22 22:01:24 2009 TUN/TAP device tap0 opened
Wed Jul 22 22:01:24 2009 Persist state set to: ON
openvpn を起動中: [ OK ]
◆クライアント作業
先ほど「/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 20120121
# モード
client
# ネットワーク接続のデバイス名(コントロールパネルなりから確認設定をしてから変更)
dev-node tap
# プロトコル(サーバー側と合わせる。)
proto udp
# サーバーアドレス+ポート番号
remote ry.tl 1194
# 名前解決関係
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
# 下記設定については動作の保証は出来ません。
# うまく行けばスループット向上を見込めます。(当環境でNetBIOSを用いたファイル送信で20-25mbps前後)
# ※TAPアダプターが10Mbps接続となっている場合がありますが、実際にはそれ以上の速度で通信も可能です。
# 以下、通信最適化
# MTUを指定(VPN及びL2ヘッダを付与する必要がある為、データサイズを小さくするとオーバーヘッドが減ると予想)
link-mtu 1400
# MSSを指定(上記の通り)
mssfix 1300
# UDPのみ。断片化を防止する為に変更(MTU-28の値を指定)
fragment 1372
# エラーが出る場合の対処
replay-window 128
----------------------------------------------------------------------------------------------------
※環境によって変更する事。
〜運用後の操作〜
◆追加で使用するクライアント用の認証鍵を作成する場合。
[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:パスワード
最後に
OpenVPNは下記のように「conf」ファイルを複数用意する事によって、同一サーバー上にて複数のVPNサーバーを立てる事が出来ます。
ブリッジモードとトンネルモードの両方を同一サーバー上で構築する事も可能です。
/etc/openvpn/server.conf
/etc/openvpn/server2.conf
使用するポート番号の重複は出来ませんので、注意して下さい。
また、クライアントについても同様の設定で複数サーバーへの接続が可能です。
この場合、トンネル用インターフェースの増設が必須となる点に注意(パッチが用意されています。)
以上