Ubuntu Weekly Recipe

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

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

OpenVPNとeasy-rsaのインストールとサーバー証明書の作成

次にOpenVPNと,PKI(公開鍵基盤)の構築に便利なeasy-rsaパッケージをopenvpnコンテナにインストールします。

openvpn$ sudo apt update
openvpn$ sudo apt install openvpn easy-rsa

ルーティングモードのOpenVPNはtunデバイスを使用しますので。デバイスノードを作成しておきます。

openvpn$ sudo mkdir /dev/net
openvpn$ sudo mknod /dev/net/tun c 10 200
openvpn$ sudo chmod 0666 /dev/net/tun

コンテナ上でデバイスノードを作成した場合,そのデバイスを使用できるようにcgroupに設定する必要があります。tunデバイス(メジャー番号10,マイナー番号200)であれば,以下のような設定を記述します。

lxc.cgroup.devices.allow = c 10:200 rwm

ただしubuntu,ubuntu-cloudテンプレートの場合,最初から/usr/share/lxc/config/ubuntu.common.confに上記が記述されているため,改めて設定する必要はありません。

次にUbuntuのドキュメントを参考に認証局の鍵と証明書を作成します。

openvpn$ sudo mkdir /etc/openvpn/easy-rsa/
openvpn$ sudo cp -r /usr/share/easy-rsa/* /etc/openvpn/easy-rsa/
openvpn$ sudo editor /etc/openvpn/easy-rsa/vars
以下の値を適宜書き換え,KEY_ALTNAMESを追加する
    export KEY_COUNTRY="US"
    export KEY_PROVINCE="CA"
    export KEY_CITY="SanFrancisco"
    export KEY_ORG="Fort-Funston"
    export KEY_EMAIL="me@myhost.mydomain"
    export KEY_OU="MyOrganizationalUnit"

    export KEY_NAME="EasyRSA"
    export KEY_CN="CommonName"
    export KEY_ALTNAMES="EasyRSA"
openvpn$ sudo -s
openvpn# cd /etc/openvpn/easy-rsa/
openvpn# source vars
openvpn# ./clean-all
openvpn# ./build-ca
    すべてEnterを入力
openvpn# exit

varsの設定は,OpenVPN用のプライベートな認証局であることを念頭に置いて設定してください。これにより/etc/openvpn/easy-rsa/keys以下に,認証局の鍵(ca.key)や証明書(ca.crt)などが作成されます。

さらにOpenVPNサーバー用の証明書を作成し,先ほどの認証局の鍵で署名を行います。

openvpn$ sudo -s
openvpn# cd /etc/openvpn/easy-rsa/
openvpn# source vars
openvpn# ./build-key-server サーバー名
    基本的にEnterを押し,最後2つの署名を行うかどうかの確認でyと入力
openvpn# ./build-dh
openvpn# cp keys/サーバー名.crt keys/サーバー名.key keys/ca.crt keys/dh2048.pem /etc/openvpn/
openvpn# exit

最後から2つ目のコマンドで,作成した認証局の証明書とサーバー用の証明書と公開鍵をOpenVPNから見える場所にコピーしています。/etc/openvpn/easy-rsa/ディレクトリは,今後クライアント証明書の作成でも使用するのでそのままにしておいてください。

OpenVPNサーバーの設定

パッケージにある設定ファイルの雛形を元に,OpenVPNサーバーの設定を行います。

openvpn$ sudo cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz /etc/openvpn/
openvpn$ sudo gzip -d /etc/openvpn/server.conf.gz
openvpn$ sudo editor /etc/openvpn/server.conf
    ca ca.crt
    cert サーバー名.crt
    key サーバー名.key
    dh dh2048.pem
    client-to-client

client-to-clientオプションは,OpenVPNクライアント間通信を行うためのオプションです。先頭にある「;」を削除して,このオプションを有効にしてください。

最後に,OpenVPNサーバーを起動します。

openvpn$ sudo service openvpn start
openvpn$ ip addr show dev 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.1 peer 10.8.0.2/32 scope global tun0
       valid_lft forever preferred_lft forever

OpenVPNでは,10.8.0.0/24をアドレスVPN内のアドレスとして割り当てます。

正しく起動できているかどうかは,/var/log/syslogのログで確認できます。

Jun 13 23:30:25 openvpn ovpn-server[615]: Initialization Sequence Completed

ホスト側の設定

OpenVPNサーバーは,初期設定ではUDPの1194ポートで,クライアントからの接続を待ち受けます。よってLXCのコンテナでOpenVPNサーバーを動かすためには,ホストの1194/UDPに届いたパケットをopenvpnコンテナに転送する必要があります。

具体的にはホスト上で以下のルールをiptablesに追加します。

$ sudo iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
$ sudo iptables -t nat -A PREROUTING -p udp --dport 1194 -j DNAT --to 10.0.3.200:1194

このルールをホスト起動時に適用するようにしても良いのですが,せっかくなのでopenvpnコンテナが起動したときのみ,このルールを適用するように設定してみましょう。LXCの設定ファイルには,コンテナのネットワークの作成と設定が済んだ後にホスト側で実行するスクリプトを指定できます。

まず次のような設定ファイルを,⁠/var/lib/lxc/openvpn/iptables.sh」という名前でホスト上に作成しましょう。openvpnはコンテナ名で,10.0.3.200はopenvpnコンテナのIPv4アドレスです注6)⁠

#!/bin/sh

# for OpenVPN
case $3 in
up)
    iptables -w -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
    iptables -w -t nat -A PREROUTING -p udp --dport 1194 -j DNAT --to 10.0.3.200:1194
    ;;
down)
    iptables -w -t nat -D POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
    iptables -w -t nat -D PREROUTING -p udp --dport 1194 -j DNAT --to 10.0.3.200:1194
    ;;
esac

POSTROUTING向けのルールは,コンテナ内部のOpenVPNサーバーが外部のOpenVPNクライアントと通信するために必要です。PREROUTINGは,OpenVPNサーバーがクライアントからのアクセスを待ち受けるために必要です。

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

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

これでopenvpnコンテナ起動時にルールが追加され,コンテナ終了時にルールが削除されます。試しに再起動してみましょう。

$ sudo lxc-stop -n openvpn
$ sudo lxc-start -n openvpn
$ sudo iptables -t nat -L
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination
DNAT       udp  --  anywhere             anywhere             udp dpt:openvpn to:10.0.3.200:1194

Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination
MASQUERADE  all  --  10.0.3.0/24         !10.0.3.0/24
MASQUERADE  all  --  10.8.0.0/24          anywhere

ここまででOpenVPNサーバーの設定は完了です。

注6)
ポート番号(1194)やネットワークインターフェース名(eth0)⁠プロトコル名(udp)は各自の設定に合わせて変更してください。

著者プロフィール

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

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