OpenVPNの使用例

例でOpenVPNのできることと使い方を示す.インストールや動作確認についてはほかの文章(リンク)に譲る.なお,特に明示しない限り,以下の操作はシステム管理者の権限(または管理者にお願いすること)が必要である.

例1:外から学内のサーバにアクセスしたい

問題説明:学校(会社や自宅でもいい)のメールサーバ(プロキシサーバやファイルサーバや他のサーバでも構わない)は,内部からはアクセスできるが,セキュリティの理由で外からはアクセスできないようになっている.外からでも内部にいるのと同じようにアクセスしたい.

解決方法:学内にOpenVPNサーバを置くことで外からでも内部の一員として振る舞うことができる.

設定例:Linux+OpenVPNのサーバを構築して静的NATを使うのは一番楽.サーバの(内部LAN側の)IPアドレスが10.128.128.10,ネットマスクが255.255.255.0と仮定する.このサーバに接続するクライアントのすべてが(内部のメールサーバからみたら)このIPアドレスを持つものとなる.

サーバのOpenVPNの設定ファイル openvpn.conf
	port 1194
	proto tcp
	dev tun
	ca /etc/pki/ca.crt
	cert /etc/pki/crt/server.crt
	key /etc/pki/key/server.key
	dh dh1024.pem
	server 192.168.10.0 255.255.255.0
	ifconfig-pool-persist ipp.txt
	push "route 10.128.128.0 255.255.255.0"
	keepalive 10 120
	comp-lzo
	user nobody
	group nobody
	persist-key
	persist-tun
	status openvpn-status.log
	verb 3
	mute 20

ポイントは,内部LAN(10.128.128.0/255.255.255.0)への接続をOpenVPN経由で行うように設定するpushコマンドである.複数を使ってもよい.

クライアントのOpenVPNの設定ファイル openvpn.conf
	client
	port 1194
	proto tcp
	dev tun
	ca /etc/pki/ca.crt
	cert /etc/pki/crt/myname.crt
	key /etc/pki/key/myname.key
	dh dh1024.pem
	remote server_global_hostname_or_ip_address
	keepalive 10 120
	comp-lzo
	persist-key
	persist-tun
	status openvpn-status.log
	verb 3
	mute 20

以上でOpenVPNの準備ができた(確認してください).残っているのはNAT設定.サーバ側でまず/etc/sysctl.confに次の一行(パケット転送)を追加する(再起動したら有効になる).

	net.ipv4.ip_forward = 1

(すぐ有効にするために)次のコマンドを実行する(=の両側にスペースなし).

	# sysctl net.ipv4.ip_forward=1

最後にサーバ側の静的NATを設定する(大文字小文字に注意).

	# iptables -t nat -A POSTROUTING -s 192.168.10.0/24 -d 10.128.128.0/24 -j SNAT --to-source 10.128.128.10

もちろん転送(=FORWARD)を許可しなければならないが,多くのLinuxはデフォールトで許可している模様.詳しくはパケットフィルタリングの資料を参照するといい.

例2:外でいながら学内マシンからのようにインターネットにアクセスしたい

問題説明:学校(会社や自宅でもいい)のIPアドレスからでしかアクセスできないインターネット上にあるWebサイトにアクセスしたい.

解決方法:まず例1のように設定しておき,それからクライアント側のルーティングテーブルを変えるとよい.特定のネットワークアドレスが分かっている場合は,pushコマンドを使うとよいが,分からない場合は,デフォールトゲートウェイを再設定する必要がある.

設定例:デフォールトゲートウェイを再設定する.この作業はクライアント側だけ必要である.まず例1と同じようにOpenVPNで仮想ネットワークを作っておく.次にクライアント側でデフォールトゲートウェイを設定する.

Linuxの場合を示す(他のUNIX系OSは似たような感じでコマンドの使い方が多少異なるかもしれない).以下を/usr/local/sbin/switchとして保存しておく.OpenVPNの起動ができたら,(rootで)switch remoteで学内経由,switch localで普通,切り替えることができる.なお,この例はぼくにとって十分だが,実際の環境に併せて設定してください.

#!/bin/bash

#
# switch script for OpenVPN (2007-05-11)
# 注:DNSサーバも切替えるなら,/etc/の下で二つのresolv.confファイル
# resolv.conf.remote と resolv.conf.local を作って下さい.
#

# remote (Open)VPN server (global IP)
VPN_SERVER="aaa.bbb.ccc.ddd"

# remote gateway
REMOTE_GW="192.168.180.5"

# remote resolv.conf file
REMOTE_RESOLVER="/etc/resolv.conf.remote"

# local gateway server
LOCAL_GW="192.168.0.1"

# local resolv.conf file
LOCAL_RESOLVER="/etc/resolv.conf.local"

if [ $# -ne 1 ]; then
        echo "Usage $0 [remote|local]"
        exit 0
fi

case $1 in
        "remote")
                route add $VPN_SERVER gw $LOCAL_GW
                route del default
                route add default gw $REMOTE_GW
                if [ -f $REMOTE_RESOLVER ]; then
                        rm -f /etc/resolv.conf
                        ln -sf $REMOTE_RESOLVER /etc/resolv.conf
                fi
                route
                echo "Done"
                ;;
        "local")
                route del default
                route add default gw $LOCAL_GW
                if [ -f $LOCAL_RESOLVER ]; then
                        rm -f /etc/resolv.conf
                        ln -sf $LOCAL_RESOLVER /etc/resolv.conf
                fi
                route
                echo "Done"
                ;;
esac
exit 0

ポイントは,デフォールトゲートウェイを変える前に,OpenVPNサーバへのルートを確保しておくこと.そうでなければ,OpenVPNサーバへの通信ができなくなってしまい,結局通信できなくなる.

Windowsクライアントにおいても,基本アイディアは上と同じでコマンドの書き方が違うだけ.さすがにルートって何?routeコマンドの使い方が分からないと仮想ネットワークを立てるべきではない(問題認識ができていない)と思うので,コマンドライン route /? で調べよう.

例3:外でいながら学内マシンからのようにインターネットにアクセスしたい(Windows版)

例2と同じ問題ですが,せっかくだから,Windows版のクライアントの場合も示そう.簡単なため,OpenVPN作動中に切替えなしとしよう.つまり,OpenVPNが起動すると自動的に内部LANの一員となることを考える(やめたい時はOpenVPNを終了させればよい).

まず,クライアントの設定に次の行を追加する.

redirect-gateway def1

以上の行で,OpenVPNが起動すると自動的にデフォールトゲートウェイをVPNサーバに設定してくれるようになる.ただ,普通DNSサーバも変えなければならないので,必要な場合,OpenVPNのインタフェースのプロパティを開いて,DNSサーバの設定を正しいサーバ名に設定しておく必要がある(一回だけ).