まだプログラマーですが何か?

プログラマーネタとアスリートネタ中心。たまに作成したウェブサービス関連の話も http://twitter.com/dotnsf

タグ:openvpn

CentOS に OpenVPN のコマンドラインクライアントを導入する手順を紹介します。


OpenVPN そのものは yum で導入可能ですが、前提として EPEL のリポジトリが必要です。未登録の場合はこのコマンドで EPEL リポジトリを作成しておきます:
# rpm -Uvh http://download.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm

そして EPEL リポジトリから OpenVPN を導入します:
# yum install --enablerepo=epel openvpn

これで導入は完了です。/usr/sbin/openvpn コマンドが導入されたはずです:
# which openvpn
/usr/sbin/openvpn

次に接続の設定を行います。.crt ファイルや .ovpn ファイルが存在する場合はそのまま使います。設定ファイルは /etc/openvpn/ フォルダ以下にまとめてコピーしておきます。ない場合は以下のような内容の接続設定ファイルを作成します(以下は一例です。XX.XX.XX.XX 部分に VPN サーバーのアドレスを指定しています。/etc/openvpn/wasaas-uss.ovpn というファイル名で作成しているものとします):
client
dev tun
proto tcp
remote XX.XX.XX.XX 1194
remote-random
resolv-retry infinite
nobind
persist-key
persist-tun
ca wasaas-uss-ca.crt
cert wasaas-uss-client.crt
key wasaas-uss-client.key
ns-cert-type server
verb 3

接続設定ファイルができたら、そのファイルを指定して OpenVPN クライアントを起動します。なお、このコマンドは VPN 接続中はプロンプトが戻ってこないので、メインで利用するのは別のターミナルを開いて行ってください:
# cd /etc/openvpn
# openvpn /etc/openvpn/wasaas-uss.ovpn

しばらく待つと、以下の様なメッセージが表示されて、VPN 接続が完了したことがわかります(プロンプトは戻ってきません):
  :
  :
Wed Jan 20 17:11:30 2016 /sbin/ip route add 169.55.255.64/27 via 10.255.255.1
Wed Jan 20 17:11:30 2016 /sbin/ip route add 169.55.255.160/27 via 10.255.255.1
Wed Jan 20 17:11:30 2016 /sbin/ip route add 169.45.151.32/27 via 10.255.255.1
Wed Jan 20 17:11:30 2016 /sbin/ip route add 169.54.255.192/27 via 10.255.255.1
Wed Jan 20 17:11:30 2016 /sbin/ip route add 169.55.4.160/27 via 10.255.255.1
Wed Jan 20 17:11:30 2016 /sbin/ip route add 169.55.235.0/27 via 10.255.255.1
Wed Jan 20 17:11:30 2016 /sbin/ip route add 169.45.191.0/25 via 10.255.255.1
Wed Jan 20 17:11:30 2016 Initialization Sequence Completed


この状態で ifconfig コマンドを実行すると、VPN 接続で追加された tun0 デバイスが確認できて、IP アドレスも正しく設定されていることが確認できるはずです:
# ifconfig
lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:356 errors:0 dropped:0 overruns:0 frame:0
          TX packets:356 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:228991 (223.6 KiB)  TX bytes:228991 (223.6 KiB)

tun0      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  
          inet addr:10.XX.XX.XX  P-t-P:10.255.255.9  Mask:255.255.255.0
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:100 
          RX bytes:0 (0.0 b)  TX bytes:0 (0.0 b)

wlan0     Link encap:Ethernet  HWaddr CC:E1:D5:3E:37:A2  
          inet addr:192.168.0.114  Bcast:192.168.0.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:627126 errors:0 dropped:0 overruns:0 frame:0
          TX packets:253371 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:272600426 (259.9 MiB)  TX bytes:157587766 (150.2 MiB)

これで VPN 接続ができました。VPN 接続を終了する場合は openvpn コマンドを実行したターミナルで Ctrl+C を実行して、コマンドを終了してください。


自分は自宅に CentOS を中心に構築した簡易ローカルネットワークがあります。自宅には固定の光回線もあるので、ブロードバンドルーターのポートフォワーディング機能を使って自宅内の HTTP サーバーを公開したり、SSH サーバーや DB サーバーににインターネットからログインできるようにしていました。
2015022401



もちろんこれはこれで便利ではあったのですが、自宅内に KVM の仮想サーバーを構築したあたりから少しずつ限界を感じることがでてきました。仮想サーバーができたことで簡単&気楽にマシンを増やして使うことができるようになるのはいいのですが、動的に増やしたマシンに接続するための設定として、2つ以上の異なる HTTP サーバーに 80 番ポートで接続したい、とか、ポートフォワーディングだけでは限界を感じることが多くなってきたのでした。まあ自宅ネットワーク環境もこんな悩みを抱えるレベルになれば立派かな、という感じ:
2015022402




この状況を打破するべく、 自宅ネットワークに VPN(Virtual Private Network) 環境を構築することにしました。結果的にですが、PC と自宅ネットワークとの間の通信をすべて暗号化することにもなるので、セキュリティ的にも向上することになります。この環境をオープンソースの OpenVPN を使ってすべて無料で構築したのですが、その手順をまとめました。


まず目標として、最終的には以下の様なネットワーク構成を作ることにしました:
・自宅ネットワークは 192.168.0.0/24 で、ルータ/DHCP/DNS 含めて今まで使ってきた自宅ネットワーク環境を変えずにそのまま使う。 
・自宅ネットワークのブロードバンドルータは 192.168.0.1、このブロードバンドルータの公開サーバー名は www.myserver.com とする。
・OpenVPN を導入する VPN サーバーは 192.168.0.4(CentOS)
・VPN で接続するクライアントは Windows7 を想定
・VPN で接続するクライアントのネットワークは 10.8.0.0/24(OpenVPN のデフォルト)
・VPN で接続したクライアントから自宅ネットワークへ、自宅ネットワーク内のマシンから VPN で接続したクライアントへの双方向の通信を可能にする
2015022403


上記の最後の文を補足します。この環境ができて VPN 接続ができた後に、VPN のクライアント機(Windows7)からは 192.168.0.XX というそのままのアドレスで自宅ネットワークの各サーバーに接続ができるようになります。加えて自宅ネットワーク内の各サーバー機からも 10.8.0.X というアドレスを指定することで Windows7 機にアクセスできるようになる、この双方向でのアクセスが可能になるような環境とする、ということを目標にします。


では以下にその構築手順を記載します。まず自宅ネットワーク内の1台のマシンに OpenVPN サーバーをインストールします。今回はこのマシンの IP アドレスが 192.168.0.4 で、CentOS が導入されているものと仮定します。また 2015/02/24 時点では OpenVPN の最新バージョンが 2.3.6 だったので、このバージョンをインストールしています。実際にはこちらを参照して、最新バージョンを確認し、最新バージョンのモジュールをダウンロードするようにしてください。

このマシンにログインして root 権限でシェルを開き、以下のコマンドを順次実行します:
# cd /usr/local/src
# yum -y install openssl-devel lzo-devel pam-devel

(最新の OpenVPN をダウンロードしてビルド)
# wget http://swupdate.openvpn.org/community/releases/openvpn-2.3.6.tar.gz # rpmbuild -tb --clean openvpn-2.3.6.tar.gz # yum -y localinstall ~/rpmbuild/RPMS/x86_64/openvpn-2.3.6-1.x86_64.rpm # rm -f ~/rpmbuild/RPMS/x86_64/openvpn-* # rm -f openvpn-2.3.6.tar.gz
(easyrsa をダウンロードしてビルド) # wget https://github.com/OpenVPN/easy-rsa/archive/master.zip # unzip master.zip # cp -r easy-rsa-master/easyrsa3/ /etc/openvpn/ # rm -rf easy-rsa-master/ # rm -f master.zip

これで OpenVPN の導入はできました。次にこの導入モジュールを使って各種鍵・証明書ファイルを作ります:
(初期化)
# cd /etc/openvpn/easyrsa3/
# ./easyrsa init-pki

(CA証明書と秘密鍵作成)
# ./easyrsa build-ca
 (パスフレーズの入力を促されるので2度同じ内容を入力)
 (Common Name(サイト名)を聞かれたらサーバー名(www.myserver.com)を入力)
# cp pki/ca.crt /etc/openvpn/

(サーバー証明書と秘密鍵作成)
# ./easyrsa build-server-full server nopass
 (パスフレーズを聞かれるので、先ほど入力したパスフレーズを入力)
# cp pki/issued/server.crt /etc/openvpn/
# cp pki/private/server.key /etc/openvpn/

(DHパラメータ作成)
# ./easyrsa gen-dh
# cp pki/dh.pem /etc/openvpn/

(ダミーのクライアント証明書作成)
# ./easyrsa build-client-full dmy nopass
 (パスフレーズを聞かれるので、先ほど入力したパスフレーズを入力)

(ダミーのクライアント証明書廃止)
# ./easyrsa revoke dmy
 ("Continue with revocation" と表示されたら yes と入力)
 (パスフレーズを聞かれるので、先ほど入力したパスフレーズを入力)

(証明書廃止リスト作成)
# ./easyrsa gen-crl
 (パスフレーズを聞かれるので、先ほど入力したパスフレーズを入力)
# cp pki/crl.pem /etc/openvpn/
# chmod o+r /etc/openvpn/crl.pem

(TLS認証鍵作成)
# openvpn --genkey --secret /etc/openvpn/ta.key
# cp /usr/share/doc/openvpn-2.3.6/sample/sample-config-files/server.conf /etc/openvpn/

上記で最後にコピーした OpenVPN の設定ファイルを編集します:
# vi /etc/openvpn/server.conf
    :
  (変更が必要な該当箇所のみ記述、ここにある内容以外はそのままで)
    :
dev tun

dh dh.pem

server 10.8.0.0 255.255.255.0

;push "route 192.168.10.0 255.255.255.0"
;push "route 192.168.20.0 255.255.255.0"
push "route 192.168.0.0 255.255.255.0"

tls-auth ta.key 0 # This file is secret

user nobody
group nobody

log-append  /var/log/openvpn.log

# 以下の2行を最終行に追加
management localhost 7505
crl-verify crl.pem

更に easyrsa3 ディレクトリでクライアント証明書および秘密鍵ファイルを生成しておきます。なお、以下の例では client1 という名前のクライアント証明書・秘密鍵ファイルを生成していますが、このクライアント名は一意である必要があります。複数クライアント向けに複数の証明書や秘密鍵ファイルを生成する場合は、既に作成したクライアント名と重ならないように注意してください:
# cd /etc/openvpn/easyrsa3
# ./easyrsa build-client-full client1
 (クライアント用パスフレーズの入力を促されるので2度同じ内容を入力)
 (サーバー用パスフレーズを聞かれるので、作成時に入力したパスフレーズを入力)

起動スクリプトとシャットダウンスクリプトを新規に作成します:
# vi /etc/openvpn/openvpn-startup
#!/bin/bash

/etc/openvpn/openvpn-shutdown
iptables -I OUTPUT -o tun+ -j ACCEPT
iptables -I FORWARD -o tun+ -j ACCEPT

iptables -I INPUT -i tun+ -j ACCEPT

iptables -I FORWARD -i tun+ -d 192.168.1.0/24 -j ACCEPT


# chmod +x /etc/openvpn/openvpn-startup
# vi /etc/openvpn/openvpn-shutdown
#!/bin/bash

delete() {
  rule_number=`iptables -L $target --line-numbers -n -v|grep tun.|awk '{print $1}'|sort -r`
  for num in $rule_number
  do
    iptables -D $target $num
  done
}

target='INPUT'
delete

target='FORWARD'
delete

target='OUTPUT'
delete

# chmod +x /etc/openvpn/openvpn-shutdown

ログローテーションの設定ファイルを新規に作成します:
# vi /etc/logrotate.d/openvpn
/var/log/openvpn.log {
  missingok
  notifempty
  sharedscripts
  postrotate
    systemctl restart openvpn 2>&1 > /dev/null || true
  endscript
}

ここまでの準備ができていれば OpenVPN サーバーを起動し、自動起動設定も行います:
# vi /etc/init.d/openvpn

 (この行のコメントを外す)
  echo 1 > /proc/sys/net/ipv4/ip_forward


# /etc/init.d/openvpn start
# chkconfig openvpn on

次にルータ(この例では 192.168.0.1)上で UDP/1194 へのアクセスを VPN サーバー(この例では 192.168.0.4)にフォワーディングするよう、ポートフォワード(と必要であればファイアウォール)の設定を行います。この具体的な手順はお使いのルータごとに異なるため、ルータの説明書などを参照しておこなってください:
2015022404


更にルータ上のルーティングを変更し、このネットワーク内での 10.8.0.0/24 宛のデータは VPN サーバー(この例では 192.168.0.4)をゲートウェイとするようにルーティングエントリを追加します。これで VPN ネットワークに接続したマシンへネットワーク側から接続することもできるようになります。この具体的な手順もお使いのルータごとに異なるため、ルータの説明書などを参照しておこなってください:
2015022405


これで OpenVPN サーバーおよびルータ型の設定が完了しました。 続けて VPN クライアント(PC側)の設定を行います。

この VPN ネットワークに接続したい PC で OpenVPN のダウンロードページを開き、環境にあった Installer をダウンロード・ダブルクリックして導入します:
2015022406


導入先フォルダの中にクライアント設定ファイルのサンプル(C:\Program Files\OpenVPN\sample-config\client.ovpn)があるので、このファイルを C:\Program Files\OpenVPN\config\client.ovpn としてコピーし、以下の内容に書き換えます(変更箇所のみ記載しています):
remote www.myserver.com 1194 # VPN サーバー名

ca ca.crt # CA証明書のファイル名
cert client1.crt # クライアント証明書のファイル名
key client1.key # クライアント秘密鍵のファイル名

tls-auth ta.key 1 # 行頭にコメントが付いているので外して TLS 認証を有効化

VPN クライアントから VPN サーバーのマシンに SFTP などで接続し、CA 証明書(/etc/openvpn/ca.crt)/クライアント証明書(/etc/openvpn/easyrsa3/pki/issued/client1.crt)/クライアント秘密鍵(/etc/openvpn/easyrsa3/pki/private/client1.key)/TLS認証鍵(/etc/openvpn/ta.key)の各ファイルを転送し、すべて C:\Program Files\OpenVPN\config フォルダ内に保存します。


最後に、この VPN クライアントは Windows7 上では管理者権限で実行する必要があるため、その設定を行います。

スタート → すべてのプログラム → OpenVPN → OpenVPN GUI を右クリックし、「プロパティ」を選択します:
2015022407


"OpenVPN GUI のプロパティ" ダイアログが表示されたら「互換性」タブを選び、「管理者としてこのプログラムを実行する」にチェックを入れます。最後に OK をクリックしてダイアログを閉じます:
2015022408



これで準備はすべて整いました。最後に実際に VPN 接続して動作確認してみます。

VPN クライアントを導入した PC が自宅以外のインターネットに接続している状態で、先ほどの手順で OpenVPN GUI を選択して起動します:


OpenVPN クライアントがタスクバーに格納された状態で起動します。この時点では接続できていないので灰色で表示されているはずです。このアイコンを右クリック → 接続を選択します。
2015022409


OpenVPN のコンソールが表示され、パスワードを聞かれます。ここではクライアントの証明書を作成する時に指定したパスフレーズを入力して OK ボタンをクリックします:
2015022410


正しく接続できるとアイコンが緑色になります。同時に新たに割り当てられた IP アドレス(この例では 10.8.0.6)が吹き出し表示されます:
2015022411


この状態で自宅ネットワーク内のサーバーの IP アドレス(192.168.0.XX)を指定すれば接続できるはずです:
2015022412

逆に自宅ネットワーク内のサーバーから割り当てられた IP アドレスに対しても接続できているはずです:
2015022413


繋がりました! これで外から自宅ネットワークに対してセキュアに、しかもポートフォワードの制約を受けずにアクセスできるようになりました。

VPN 接続を切断するにはタスクバーのアイコンを右クリック→切断 を選択します:
2015022414



今回紹介した方法は Windows クライアントを前提としていましたが、証明書や秘密鍵の作り方を少し変えると iPhone などでも利用できるようになります。 詳しくは以下の参考ページを参照ください:


(参考)
http://centossrv.com/openvpn.shtml


 

このページのトップヘ