Ubuntu Weekly Recipe

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

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

今回はUbuntuの具体的な利用方法として,VPS,LXC,OpenVPNなどを利用して,Android端末からローカルにあるUbuntuマシンのコンテンツをインターネット越しに閲覧する方法を紹介します。

まずは目的を決める

写真や動画のマルチメディアコンテンツの保存について頭を悩ませている人は多いでしょう。デジタルカメラやスマートフォンといった簡単に撮影できる機材が手元にあるおかげで,写真や動画が際限なく増えていくために整理が大変ですし,単体のファイルサイズも大きいのでクラウドストレージはすぐにあふれてしまいます。自分で撮影したデータは世界に1つだけなので,おいそれとは捨てられません。

家にあるマシンに保存する場合,今度は閲覧が問題になってきます。できれば家の外からでも閲覧したい,そうすると家のマシンを常時起動しながらサーバーをインターネットに公開する必要がある,など考えるべきことが増えてきます。

そこで今回はご家庭にあるメディアライブラリーを,インターネット越しにAndroidを使って閲覧することを目的に,その手段を考えてみようと思います注1)⁠

注1)
と,最初に目的を立ててからその手段を模索するように書いていますが,ぜんぶ嘘(後付け)です。いつものように,手段(VPSとLXCを使って何かしたいというところ)から目的を考えました。

VPSを経由する

ご家庭のメディアライブラリーをインターネットに公開する一番シンプルな方法は,ライブラリーをサーバーとして直接インターネットに繋ぐ方法です。

この場合,次のような点を考慮する必要があります。

  • 外部からアクセスできるようにルーターを適切に設定する
  • サーバーのIPアドレスを,クライアントが知る術を用意する
  • DLNAなどルーター越しには使えないサービスについては代替手段を用意する

この中で一番やっかいなのはルーターの設定でしょう。ルーターごとに手順が異なるうえに,プロバイダーの契約内容によっては,できることが限定されるケースもよくあります。

VPSを1台用意し,インターネット側のアクセスを待ち受けるのは,すべてVPS上に存在するサービスになるよう心がければ,ルーターの設定はほぼ変更しなくてすみます。

2番目のIPアドレスについては,VPSなら最初からグローバルな固定IPアドレスが割り振られているので,対応不要になるでしょう。ちなみに3番目については,VPSにするだけでは状況は変わりません。

VPSを使う場合,毎月1,000円前後の料金がかかってしまうというデメリットは存在します。しかしご家庭で常時PCを起動する時の電気代に比べるとそこまで高い料金ではありません注2)⁠さらに最近のVPSなら100Gバイト程度のディスク領域もついてくるので,自前でサービスをインターネットに公開することを考えているのであれば,クラウドサービスの有料枠を購入するよりはお手軽でしょう注3)⁠

よって今回はクライアントがインターネットから接続するサーバーは一度VPSを経由するような設定を紹介します。ご家庭内のサービスを外向けに公開する場合は,適宜VPSの部分をご家庭のサーバーに読み替えて設定してください。

注2)
ただし,Celeron J1900搭載の省エネPCだと,高負荷時に20W前後,アイドル時に数Wぐらいとのことですので,これくらいのクラスやARMサーバーになってくると電気代だけ見るとVPSの方が割高になります。
注3)
ここでは電気代しか見ていませんが,ハードウェアの購入費や維持費,障害時の対応コストなども考慮に入れるとVPSはかなりお得です。

接続方式としてOpenVPNを使う

家庭内LANで公開されているホームサーバーをVPS経由でインターネットからアクセスする方法はいくつか存在します。たとえばVPSにプロキシーを設定する方法や,VPNやSSHを使ってトンネルを作成する方法,などです。

今回はその中でもOpenVPNを利用します。OpenVPNはさまざまなプラットフォームに対応した,仮想プライベートネットワークを構築するソフトウェアです。特定のプロトコルのみをトンネルしたいとは限らないこと,Android側の設定ができるだけ簡単にしたいこと,パッケージマネージャーからすぐにインストールできることなどがOpenVPNを使用するおもな理由です。

VPS上にOpenVPNサーバーを構築し,ホームサーバーやAndroid端末をOpenVPNクライアントとして設定します。OpenVPNサーバーはアクセスしてきたOpenVPNクライアント同士をLAN内で接続したように見せ,さらにOpenVPNを経由するパケットはOpenSSLを使って暗号化されます。

今回はルーティングモード(tunデバイスを使う接続方法)のみを紹介します。メディアサーバーとしてDLNAを使う場合は,ブリッジモード(tapデバイスを使う接続方法)の方が望ましいのですが,Android側でブリッジモードを使うためにはrootを取る必要があるため除外しました。DLNAを使いたいのであれば,L2TP/IPsecを使えるソフトウェア,たとえばSoftEther VPNを使うと良いでしょう。

メディアリポジトリとしてWebDAVを使う

メディアサーバーといえば前節でも述べたとおりまずDLNAが思いつきます。DLNAは配信機器を検知するためにSSDPのブロードキャストパケットを送信するのですが,ルーティングモードのOpenVPNはこのパケットを配送してくれませんので,そのままではDLNAサーバーを利用できません。

今回はよりお手軽に,WebDAVでメディアリポジトリを公開して,AndroidのESファイルエクスプローラーでアクセスする形を採用します。WebDAVはWebサーバー上でリソースの移動やコピー,属性管理を行えるようにした,HTTPの拡張です。オンラインストレージサーバーとして人気のownCloudも,WebDAVのインターフェースとして実装されています。よって今回の手順はそのままownCloudにも適用できるはずです。ちなみにWebDAVサーバーとして,今回はnginxを使用します。

ちなみに,WebDAVはLAN内部でファイルを公開するサーバーとして使っているだけなので,SambaやNFS,SFTPなどに置き換えることも可能です。Android側のアプリに合わせて,使いやすいものを使うと良いでしょう。

LXCを使う

ここまでで紹介したソフトウェアはすべてLXCのコンテナ上にインストールすることにします。VPS上に直接OpenVPNをインストールしてももちろん良いのですが,コンテナ上にインストールしておけば,OpenVPNを使わなくなったら,コンテナごと止めてしまえるというメリットがあります注4)⁠

合わせてUbuntuでLXCを使う場合における,ネットワークやデバイス,AppArmorの設定についてもこのRecipeで確認していきましょう。

注4)
特権コンテナーを使用するので,セキュリティ面のメリットはあまりありません。

サーバー側の設定

最初にVPS側の設定を行います。VPSにはあらかじめUbuntu 14.04 LTSがインストールされているものとします。12.04でもそれほど変わるわけではありませんが,LXCの機能を考えるとカーネルはHWEカーネルにしてより新しくしておいたほうが良いでしょう。もし12.04でLXCをインストールしたい場合はリポジトリのそれではなく,1.0.xが提供されているUbuntu LXCチームのPPAを使用してください。

(Ubuntu 12.04 LTSのみ実行する)
$ sudo apt-get install python-software-properties
$ sudo add-apt-repository ppa:ubuntu-lxc/stable
$ sudo apt-get install linux-hwe-generic

LXCのインストール

VPS上に用意したUbuntuにLXCをインストールします。

$ sudo apt update
$ sudo apt install lxc

UbuntuのLXCのコンテナ(ゲスト)はdnsmasqによって,10.0.3.2から10.0.3.254までのIPv4アドレスが動的に割り当てられます。そのままですと,NATの設定を行うときに不便なので,アドレスレンジのうち前半をDHCPで使用しつつ,後半は固定IPアドレスとして利用できるようにしておきます。

$ sudo sed -i 's/LXC_DHCP_RANGE="10.0.3.2,10.0.3.254"/LXC_DHCP_RANGE="10.0.3.2,10.0.3.127"/' /etc/default/lxc-net
$ sudo sed -i 's/LXC_DHCP_MAX="253"/LXC_DHCP_MAX="126"/' /etc/default/lxc-net
$ sudo stop lxc
$ sudo start lxc

OpenVPN用のコンテナの作成

OpenVPN用のコンテナ(コンテナ名:openvpn)を作成します。

$ sudo lxc-create -t ubuntu-cloud -n openvpn -- --auth-key=/home/`id -un`/.ssh/authorized_keys

ubuntu-cloudは,クラウドインスタンス上で動作することを想定したイメージファイルです。ubuntuテンプレートがdebootstrapコマンドを使って一からルートファイルシステムを作るのに対して,ubuntu-cloudテンプレートはサーバーから既存のイメージをダウンロードして設定します。今回はubuntu-cloudテンプレートを使っていますが,ubuntuテンプレートでも後述のネットワーク設定方法以外は同じです。

「--auth-keys」オプションは,コンテナの初期ユーザー(ユーザー名:ubuntu,パスワード:ubuntu)の.ssh/authorized_keysに書き込む公開鍵情報を指定します。公開鍵や既存のauthorized_keysを指定可能です。ubuntu-cloudテンプレートのクラウドイメージはAmazon EC2の鍵情報やcloud-initで指定された鍵が最初から登録されることを前提に,sshd_configのPasswordAuthenticationをnoに設定しているためです。起動後にsshログインできるように,使用する鍵情報をこのオプションで渡しています注5)⁠ubuntuテンプレートを使う場合は必要ありません。

各テンプレート固有のオプションはテンプレートに「--help」オプションを渡すことで確認できます。さらにubuntu-cloudテンプレートについては,hook側にもいくつかオプションがあるので,後者のコマンドのように参照すると良いでしょう。Amazon EC2のように,Cloud Init用のデータを渡すことも可能です。

$ lxc-create -t ubuntu-cloud --help
$ /usr/share/lxc/hooks/ubuntu-cloud-prep --help

次に,openvpnコンテナのIPv4アドレスを固定化します。ここでは,⁠10.0.3.200」を割り当てることにします。ファイルパス名に出てくる「openvpn」はコンテナ名です。名前の異なるコンテナを作成した場合は,適宜読み替えてください。

$ sudo editor /var/lib/lxc/openvpn/config
「# Network configuration」付近に次の2つのオプションを追加します。
    lxc.network.ipv4 = 10.0.3.200/24
    lxc.network.ipv4.gateway = 10.0.3.1

ubuntuテンプレートの場合
$ sudo editor /var/lib/lxc/openvpn/rootfs/etc/network/interfaces

ubuntu-cloudテンプレートの場合
$ sudo editor /var/lib/lxc/openvpn/rootfs/etc/network/interfaces.d/eth0.cfg

eth0をdhcpからmanualに変更し,DNS設定を追加します
    auto eth0
    iface eth0 inet manual
        dns-nameservers 10.0.3.1

interfacesファイルは,ubuntuテンプレートとubuntu-cloudテンプレートでファイル名が異なるので注意してください。内容はどちらも同じです。

openvpnコンテナを起動し,sshでアクセスします。ユーザー名,パスワード共に「ubuntu」です。

$ sudo lxc-start -n openvpn -d
$ sudo lxc-info -n openvpn
Name:           openvpn
State:          RUNNING
PID:            1817
IP:             10.0.3.200
CPU use:        74.27 seconds
BlkIO use:      329.48 MiB
Memory use:     206.20 MiB
KMem use:       0 bytes
Link:           vethLUALUW
 TX bytes:      61.14 MiB
 RX bytes:      61.61 MiB
 Total bytes:   122.75 MiB

$ ssh ubuntu@10.0.3.200

うまく動作するようなら,openvpnコンテナが自動起動するように設定しておきましょう。

$ sudo editor /var/lib/lxc/openvpn/config

以下の行を追加する
    # enable autostart
    lxc.start.auto = 1

$ sudo lxc-ls --fancy openvpn
NAME     STATE    IPV4        IPV6  AUTOSTART
---------------------------------------------
openvpn  RUNNING  10.0.3.200  -     YES

以降,openvpnコンテナ上での作業は,プロンプトを「openvpn$」と表示します。

注5)
もちろん,シリアルコンソールを使用したり,ホスト上でゲストのルートファイルシステムをあとから直接編集するのであれば,最初にこのオプションを指定する必要はありません。

著者プロフィール

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

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

コメント

コメントの記入