Ubuntu Weekly Recipe

第329回 VPSとLXCとOpenVPNで仮想プライベートネットワークを構築する

この記事を読むのに必要な時間:およそ 12 分

クライアント側の設定

次にOpenVPNクライアントの設定を行います。クライアントごとに以下の3つの作業が必要です。

  • そのクライアント用のクライアント証明書と鍵を作成する(OpenVPNサーバー上で行う)
  • クライアント証明書と鍵,認証局の証明書を安全な方法でクライアントに移動する
  • クライアントの設定を行う

クライアント証明書の作成

今回の設定では,OpenVPNサーバーに接続するために,認証局の証明書で署名されたクライアント証明書が必要になります。そこで最初に,OpenVPNサーバー(つまりはVPS上のopenvpnコンテナの中)でクライアント証明書を作成しましょう。

openvpn$ sudo -s
openvpn# cd /etc/openvpn/easy-rsa/
openvpn# source vars
openvpn# ./build-key クライアント名
    基本的にEnterを押し,最後二つの署名を行うかどうかの確認でyと入力
openvpn# tar zcvf クライアント名.tgz keys/クライアント名.crt keys/クライアント名.key keys/ca.crt
openvpn# rm keys/クライアント名.*
openvpn# exit

必要なのは証明書(クライアント名.crt)⁠(クライアント名.key)⁠認証局の証明書(ca.crt)です。これを固めて安全な方法でクライアントへと移動します。移動したら作成したクライアント証明書と鍵は削除しておきましょう。

この作業はクライアントの数だけ行います。以降はすべてclient.tgzという名前で作ったことを前提に説明しますが,ファイルの内容はクライアントごとに異なっていることに注意してください。

LXCクライアントの設定

まずはLXCでクライアントコンテナを作成し,そこから接続する方法を試してみましょう。⁠LXCのインストール」「OpenVPN用のコンテナの作成」と同様にLXCをインストールして,コンテナを作成してください。ここでは作成したコンテナ名を「openvpn-client」とします。IPアドレスの固定化は実施してもしなくてもかまいません。

次にこのコンテナ上にOpenVPNをインストールし,tunデバイスを作成します。

openvpn-client$ sudo apt update
openvpn-client$ sudo apt install openvpn
openvpn-client$ sudo mkdir /dev/net
openvpn-client$ sudo mknod /dev/net/tun c 10 200
openvpn-client$ sudo chmod 0666 /dev/net/tun

事前に作成しておいたクライアント用の証明書類(client.tgz)をコンテナ内部に移動し,設定ディレクトリに展開します。

openvpn-client$ sudo tar xvf client.tgz -C /etc/openvpn/

クライアント用の設定ファイルを雛形から作成します。

openvpn-client$ sudo cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf /etc/openvpn/
openvpn-client$ sudo editor /etc/openvpn/client.conf
    remote myvps.example.com 1194
    ca keys/ca.crt
    cert keys/client.crt
    key keys/client.key

remoteには,OpenVPNサーバーのアドレスを指定してください。ca,cert,keyには先ほど展開した証明書類のファイルパスを指定します。

さらにiptablesの設定もしておきましょう。クライアント側は待ち受けはないので,サーバーとクライアントの間のパケットを疎通する設定だけで問題ありません。OpenVPNサーバーの時と同様に次のような設定ファイルを,⁠/var/lib/lxc/openvpn-client/iptables.sh」という名前でホスト上に作成します。

#!/bin/sh

# for OpenVPN
case $3 in
up)
    iptables -w -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
    ;;
down)
    iptables -w -t nat -D POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
    ;;
esac

さらにスクリプトに実行権限を追加し,コンテナ起動時に呼び出せるように設定を追加します。

$ sudo chmod a+x /var/lib/lxc/openvpn-client/iptables.sh
$ sudo editor /var/lib/lxc/openvpn-client/config
以下の2行を追加する
    lxc.network.script.up = /var/lib/lxc/openvpn-client/iptables.sh
    lxc.network.script.down = /var/lib/lxc/openvpn-client/iptables.sh

最後にOpenVPNサービスを立ち上げましょう。

openvpn-client$ sudo service openvpn start

次のようにtun0に10.8.0.0/24のどれかのアドレスが割り当てられていれば接続完了です。OpenVPNサーバーにpingを飛ばして疎通するかどうかも確認しておきましょう。

openvpn-client$ ip addr show tun0
2: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 100
    link/none
    inet 10.8.0.10 peer 10.8.0.9/32 scope global tun0
       valid_lft forever preferred_lft forever
openvpn-client$ ping 10.8.0.1
PING 10.8.0.1 (10.8.0.1) 56(84) bytes of data.
64 bytes from 10.8.0.1: icmp_seq=1 ttl=64 time=107 ms
64 bytes from 10.8.0.1: icmp_seq=2 ttl=64 time=100 ms
...

もしアドレスが割り当てられない,pingが通らない,といったトラブルに遭遇した場合,まずはOpenVPNサーバー上の/var/log/syslogを確認してください。サーバー側にクライアントから接続されていれば,次のようなログが残っているはずです。

ovpn-server[615]: AA.BB.CC.DD:23730 TLS: Initial packet from [AF_INET]AA.BB.CC.DD:23730, sid=1d1cec97 357177c6
(中略)
ovpn-server[615]: client5/AA.BB.CC.DD:23730 SENT CONTROL [client5]: 'PUSH_REPLY,route 10.8.0.0 255.255.255.0,topology net30,ping 10,ping-restart 120,ifconfig 10.8.0.18 10.8.0.17' (status=1)

もしこの間にエラーが表示されているようなら,そのエラーに対応しましょう。そもそも「Initial packet」が表示されない場合はOpenVPNサーバーが起動していないか,途中でパケットがフィルタリングされている,クライアントが全然異なるサーバーにアクセスしようとしているなどが考えられます。iptablesやサーバー,クライアントの設定ファイルを再度確認してください。

とくに今回はホストからLXCゲストへとNATでつなげているので,設定を間違うと途中でパケットがドロップされます。ホスト上で「sudo tcpdump -i eth0 port 1194」などとして,少なくともホスト上まではパケットが届いているかどうかや,ゲスト上にはどうかということも確認すると良いでしょう。

デスクトップクライアントの設定

デスクトップ版のUbuntuに最初からインストールされているネットワーク管理ツールであるNetworkManagerには,OpenVPNに接続するためのプラグインが存在します。これを使うと,デスクトップから直接OpenVPNサーバーへ接続できます。

最初にデスクトップ上にOpenVPNプラグインをインストールし,NetworkManagerを再起動してください。

$ sudo apt install network-manager-openvpn
$ sudo restart network-manager

画面右上のネットワークインジケーターの「VPN接続>VPNを設定>追加ボタン>OpenVPN>作成ボタン」と順番に選択すると,次のようなダイアログが表示されるはずです。

図1 ⁠接続名」はインジケーターで表示する名前として使われる

図1 「接続名」はインジケーターで表示する名前として使われる

GatewayにはOpenVPNサーバーのアドレス,User Certificateにはクライアント証明書類から展開したクライアント証明書(crtファイル)⁠CA Certificateには同じく展開した認証局の証明書(caファイル)⁠Private Keyにはクライアントの鍵(keyファイル)をそれぞれ指定します。

さらに「Advanced」ボタンで表示される画面から「Use LZO data compression」にチェックを入れておいてください。

次にIPv4設定タブに移動し,⁠方式」「自動(VPN)アドレス専用」に変更します。そして「ルート」ボタンから「そのネットワーク上のリソースのためにのみこの接続を使用」にチェックを入れます。これによりVPNのサブネットへの接続のみVPNが使われるようになります。クライアントから外向けのアクセスをすべてVPN経由にしたい場合はここの設定は変更しないでください。

最後に「保存」ボタンを押してダイアログを閉じたら設定完了です。

OpenVPNサーバーへの接続は,ネットワークインジケーターのVPN接続から,VPN接続名を選択します。接続に成功すれば,ネットワークインジケーターのアイコンの右下に鍵マークが追加されます。

図2 接続に成功すれば,通知が表示され,アイコンに鍵マークが追加される

図2 接続に成功すれば,通知が表示され,アイコンに鍵マークが追加される

Androidクライアントの設定

Androidには公式のOpenVPNクライアントであるOpenVPN Connectと非公式のクライアントであるOpenVPN for Androidの2種類のクライアントが存在します。基本はLXCの時と同様に,client.confと証明書類を用意してAndroidに安全な方法で移動するだけです。client.confはclient.ovpnという名前に変更しておきましょう。

client.ovpnは,UbuntuのOpenVPNパッケージにある雛形を元に設定すれば問題ありません。設定ファイルと証明書類をopenvpnというフォルダーを作成してそこにすべて保存し,クライアントから設定ファイルを読み込めば,接続できるはずです。

図3 非公式ながらOpenVPN for Androidの方が自由度は高

図3 非公式ながらOpenVPN for Androidの方が自由度は高

接続に成功したらIPv4アドレスが割り当てられています。前述のデスクトップやLXCクライアントも動作済みであれば,OpenVPNサーバーとクライアント間だけでなく,クライアント同士でもpingが疎通することを確認しておきましょう。

著者プロフィール

柴田充也(しばたみつや)

Ubuntu Japanese Team Member。数年前にLaunchpad上でStellariumの翻訳をしたことがきっかけで,Ubuntuの翻訳にも関わるようになりました。