Ubuntu 14.04 で OpenVPN
はじめに
この記事は、OpenVPNを使用して外部から内部ネットワークにアクセスする仕組みを構築する手順をメモしています。いろいろ他のサイトを参考にしています。
Business VPN | Next-Gen VPN | OpenVPN
ところで
公式サイトに行くと VPN Solution という項目があって、ここから OpenVPN Access Serverという管理ツールをダウンロードできるのですが、GUIが使えたりしていろいろ便利そうではあるのですが、有料製品のようです。今回は、あくまで無料でVPNサーバーを構築する予定ですので、こちらではなく。必要なドキュメント等は、Communityのほうにあります。
前提となる環境
今回、サーバーには、Ubuntu 14.04 LTS Server を使用しています。これは、すでにインストールされ、内部ネットワーク環境に置かれているものとします。 内部環境のネットワークアドレスは 192,168.1.0/24 とし、ゲートウェイは 192.168.1.1、VPNサーバーのアドレスは 192.168.1.10 としています。 外部のクライアントPCから、内部のAPサーバーに アドレス 192.168.1.20 でアクセスできるところまでが目標です。
iPhoneからも接続することを考えていますので、接続方式は ブリッジ ではなく NAT で、仮想ネットワークドライバは TAP ではなく TUN を使用します。
作業前に
以下の作業のほとんどは、root権限で行う必要があります。Ubuntuの場合、普段は sudo で実行しますが、面倒なのであらかじめ root 権限を取得して作業しました。
$ sudo -i
OpenVPN を Ubuntu にインストールする
まずは、レポジトリの情報を最新にアップデートします。
# apt-get update
そして、パッケージをインストールします。 *1
# apt-get install openvpn easy-rsa libssl-dev openssl
サーバー証明書を発行する
サーバー用に、公開鍵(.crt)、秘密鍵(.key)、証明書署名要求(.csr)、DHパラメータ(.pem)を作成します。
証明書作成用のディレクトリを作成
証明書発行用のディレクトリが必要になります。Ubuntuには専用のコマンド make-cadir が用意されているようなのでこれを使います。場所は、通常 /etc/openvpn の下に、easy-rsa ディレクトリを作成するようです。作成後、そのディレクトリに移動します。
# make-cadir /etc/openvpn/easy-rsa # cd /etc/openvpn/easy-rsa
/etc/openvpn │ └─ east-rsa ←
Ubuntu Manpage: make-cadir - create certificates dir
証明書作成用の環境変数を設定する
移動先の easy-rsa ディレクトリに、vars というファイルがあります。このファイルの中に、必要な情報を入力していきます。
# vi ./vars
export KEY_COUNTRY="JP" # 国 export KEY_PROVINCE="Tokyo" # 都道府県 export KEY_CITY="Shinjuku" # 市区町村 export KEY_ORG="My Company Co.Ltd." # 組織 export KEY_EMAIL="admin@my-company.com" # メールアドレス export KEY_OU="Sales" # 組織単位
変更した varsファイルを読み込みます。
# . ./vars
サーバー証明書を作成する
以下のコマンド(実行可能ファイル)を順に実行してください。
# ./clean-all
# ./build-dh
# ./pkitool --initca
# ./pkitool --server server
# cd ./keys # openvpn --genkey --secret
以上の作業で、keysディレクトリに以下の鍵ファイルが作成されていると思います。
/etc/openvpn │ └─ east-rsa │ └─ keys ca.crt ← ca.key ← server.crt ← server.csr ← server.key ← dh2048.pem ← ta.key ←
これらのファイルを /etc/openvpn ディレクトリの下へコピーします。
# cp ca.crt server.crt server.keydh1024.pem ta.key /etc/openvpn
/etc/openvpn │ ca.crt ← │ server.crt ← │ server.key ← │ dh2048.pem ← │ ta.key ← │ └─ east-rsa │ └─ keys ca.crt ca.key server.crt server.csr server.key dh2048.pem ta.key
OpenVPNを設定する
設定ファイルの作成
OpenVPNの設定を環境に合わせて変更していきます。設定ファイルは、まだ作成されていません。/usr/share/doc/openvpn にサンプル設定ファイルがありますので、以下のコマンドを実行してこれを server.conf として /etc/openvpn にコピーします。
# gunzip -c /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz > /etc/openvpn/server.conf
/etc/openvpn │ ca.crt │ server.crt │ server.key │ dh2048.pem │ ta.key │ server.conf ← │ └─ east-rsa │ └─ keys
この server.conf が設定ファイルになりますので、これを編集します。
# vi /etc/openvpn/server.conf
VPN通信の設定(規定値のまま)
ポート番号とプロトコルを指定します。必要がなければ、規定値のままで構いません。クライアント側のルーターで既定のポート番号が制限されている場合などに、tcp/443を使用することなどが可能とのことです。
port 1194
;proto tcp proto udp
接続用の仮想ネットワークデバイスを指定します。今回の例では、iPhoneからの接続を考慮して TUN を選択しています。規定で TUN となっているので、変更は必要ありません。
;dev tap dev tun
VPN通信に使用するネットワークアドレスを指定します。クライアント・サーバー間はこのアドレスで通信が行われ、サーバーで内部ネットワークアドレスに変換されます。今回の場合、規定値をそのまま使用しています。後の手順で、内部ネットワーク側のルーター設定でこのアドレスを指定する必要があります。
server 10.8.0.0 255.255.255.0
証明書の指定(規定値のまま)
- で作成した証明書を指定します。今回の場合、とくに変更は必要ありません。
ca ca.crt cert server.crt key server.key
DHパラメータの指定
- で作成した dh2048.pem を指定します。今回の場合、以下のように変更する必要があります*2
;dh dh1024.pem dh dh2048.pem
アクセス先となる内部ネットワークの設定
外部からアクセスしたいネットワークのアドレスを入力します。push "route ..." の箇所を変更してください。今回の例 192.168.1.0/24 の場合は、以下のように指定します。
push "route 192.168.1.0 255.255.255.0"
次に、push "redirect-gateway ..."の箇所のコメントアウトを外して有効化します。これを有効にすることで、WebブラウジングやDNS参照など、VPN ClientのすべてのトラフィックをVPNサーバー経由にするそうです。
push "redirect-gateway def1 bypass-dhcp"
そして、DNSの設定を変更します。push "dhcp-option DNS..."の箇所を変更します。今回の例では、DNSサーバーとして192.168.1.1を指定します。
push "dhcp-option DNS 192.168.1.1"
TLSの設定
ファイルの末尾に以下の情報を追加します。
mode server tls-server
TLS暗号化を有効化します。
tls-auth ta.key 0
通信暗号化の設定
サーバー・クライアント間で用いる暗号化の方式を指定します。ここで指定した方式を、クライアント側からも指定する必要があります。ここが、サーバーとクライアントで異なっていると、クライアントからの接続時にエラーとなります。
cipher AES-256-CBC
サービス実行ユーザーの変更
規定では、OpenVPN は root ユーザーとして動作するため、これを nobody:nogroup に変更し、セキュリティを高めておきます。
user nobody group nogroup
その他のオプション
クライアント間通信の有効化
client-to-client
複数台のクライアントで、同じ証明書を使い回す(非推奨)。
;duplicate-cn
VPN通信の圧縮。今回、これを有効にするとiPhoneからの接続がうまくいかなかったため、コメントアウトしました。
;comp-lzo
設定の反映
server.conf を保存したら、openvpnサービスを再起動します。
# service openvpn restart
参考サイト
- How To Set Up an OpenVPN Server on Ubuntu 14.04 | DigitalOcean
- http://blog.chibatching.com/blog/2014/09/08/construct-openvpn-server-in-ubuntu/
- Ubuntu Server 14.04をVPNサーバーにしてみた。 - Qiita
内部ネットワークの他のサーバーにアクセスするための設定をする
以上の設定のみで手順を進めると、クライアント側からOpenVPNサーバー自体(図の192.168.1.10あるいは10.8.0.1)にはアクセス可能となりますが、内部ネットワークの他のサーバー等(イントラネット上の業務アプリケーションや共有フォルダなど)にアクセスしようとしても、パケットが届かないためエラーとなってしまいます。そこで、OpenVPNサーバー上で、クライアントから 10.8.0.0/24 経由で来たパケットを 192.168.1.0/24 に転送する必要があります。
フォワーディングの有効化
まず、IPフォワーディングを有効にします。カーネルパラメータを変更しますので、sysctl.conf を開きます。
# vi /etc/sysctl.conf
そして、以下の行のコメントアウトを解除して保存します。
net.ipv4.ip_forward = 1
設定を即座に反映するために、以下のコマンドを実行します。
# sysctl -p
ルーティング設定の追加
そして、フォワーディングの設定をします。他のサイトでは ufw を使用した例が多く示されていますが、ここでは iptables を利用しています。なお、iptablesは、すべてACCEPTとなっており、とくにフィルタリング等は行われていない(ファイアウォール等は別途設けられている)ケースを想定しています。
まず、iptables の設定を永続化するためのツールを導入します。
# apt-get install iptables-persistent
次に、iptables に以下の設定を追加します。ifconfig コマンドで、物理ネットワークデバイスのデバイス名を確認しておいてください。
# ifconfig eth0 Link encap:Ethernet HWaddr 00:0B:CD:1C:18:5A inet addr:192.168.1.10 Bcast:192.168.1.255 Mask:255.255.255.0 ... lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 ... tun0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 inet addr:10.8.0.1 P-t-P:10.8.0.2 Mask:255.255.255.255 ...
そのうえで、以下のコマンドを入力してください。今回は、仮想ネットワークデバイスが tun0(10.8.0.0/24)、物理ネットワークデバイス eth0(192.168.1.0/24)であるとします。
# iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
設定を保存します。
# service iptables-persistent save
参考サイト
- VPNを構築しよう・その6・ルーティングモードでのOpenVPNサーバセットアップ:ぴろにっき:SSブログ
- http://web.mit.edu/rhel-doc/4/RH-DOCS/rhel-sg-ja-4/s1-firewall-ipt-fwd.html
- http://iwashi.co/2015/01/16/ubuntu-iptables-persistent/
ルーターを設定する
OpenVPNサーバー上での設定は以上ですが、内部ネットワークのゲートウェイとなっているルーター機器で、いくつか設定を行います。
ポート開放を許可する
外部から udp/1194へのアクセスを許可します。ルーターのフィルタリングなどを使用します。
NTT OG410Xiの例
規定で、何もフィルタリングされていない場合は空欄。
外部からの udp/1194 宛てのパケットを VPNサーバーに送る
次に、外部のVPNクライアントからのアクセスを、VPNサーバーを経由するように設定します。ルーターの静的IPマスカレードを使用します。
NTT OG410Xiの例
内部からの 10.8.0.0/24 宛てのパケットを VPNサーバーに送る
そして、内部から、10.8.0.0/24 に宛てたパケットがすべて VPNサーバーを経由するように設定します。ルーターのルーティングなどを使用します。
NTT OG410Xiの例
参考サイト
クライアント証明書の作成
以上で、サーバー用の設定は完了です。あとは、外部から接続するクライアント端末ごとに、証明書を発行します。この証明書を用いて、各クライアントが内部ネットワークにアクセスします。ここでは、仮にアクセス先の グローバルIPアドレスが 123.456.78.9 であるとしています。
(ログアウトしていれば再度OpenVPNサーバーにログインし、)2. で作成した /etc/openvpn/easy-rsa ディレクトリに移動します。
# cd /etc/openvpn/easy-rsa
/etc/openvpn │ └─ east-rsa ←
作成済みの環境変数を読み込みます。
# . ./vars
作成したいクライアントの識別名を任意に命名します。ここでは、 client1 とします。以下のコマンドを実行してください。
# ./pkitool client1
もし、パスワードを設定したい場合には、--passオプションを使用します。証明書作成中にパスワードを聞かれますので、入力してください(確認を含めて2回)。ただし、4文字以上でないと怒られます。
# ./pkitool --pass client1
これで、keysディレクトリの中に、クライアント用の証明書が作成されているはずです。
/etc/openvpn │ └─ east-rsa │ └─ keys ca.crt ca.key server.crt server.csr server.key dh2048.pem ta.key client1.crt ← client1.csr ← client1.key ←
作成されたファイルのうち、client1.crt、client1.key、ca.crt、ta.key を何らかの手段でクライアント端末に送ります。セキュリティに配慮して、できるだけ安全な方法で受け渡しをしてください。
/etc/openvpn │ └─ east-rsa │ └─ keys ca.crt ← ca.key server.crt server.csr server.key dh2048.pem ta.key ← client1.crt ← client1.csr client1.key ←
VPNクライアントの設定(Windows)
アプリケーションの入手
プラスシステムズ株式会社の提供するサイトから、vpnux Clientをダウンロードし、手順に従ってインストールします。*3こちらのソフトウェアの使用が、公式サイトでも推奨されているようです。
設定
インストールが完了したら、vpnux Client を起動し、メニューの [プロファイル] → [追加]
で設定画面を開きます。
上図のように設定をしたら、[保存]
します。作成したプロファイルが、一覧画面に表示されたら完了です。
接続
起動時の画面から、作成済みのプロファイルを選択し、[接続]
をクリックするだけです。非常に簡単です。
VPNクライアントの設定(iPhone)
ovpnファイルの作成
新規に、テキストファイルを作成します。拡張子は .ovpnとしてください。ファイル名は仮に client1.ovpnとします。ファイルの内容は、以下のようなものになります。remoteの値には、接続先のグローバルIPアドレス、もしくはホスト名を入力します。 cipherの値を、2. で server.conf に指定した値と揃えることに注意してください。
tls-client key-direction 1 remote 123.456.78.9 cipher AES-256-CBC port 1194 proto udp <ca> ----- ca.crt の BEGIN CERTIFICATE ~ END CERTIFICATE までをペースト ----- </ca> <cert> ----- client1.crt の BEGIN CERTIFICATE ~ END CERTIFICATE までをペースト ----- </cert> <key> ----- client1.key の BEGIN ENCRYPTED PRIVATE KEY ~ END ENCRYPTED PRIVATE KEY までをペースト ----- </key> <tls-auth> ----- ta.key の BEGIN OpenVPN Static key V1 ~ END OpenVPN Static key V1 までをペースト ----- </tls-auth>
上記のようなファイルを作成したら、<ca>
、<cert>
、<key>
、<tls-auth>
各タグの中に該当する証明書(上記コメントのとおり)の鍵文字列を張り付けて保存します。
アプリの入手
iPhoneから App Store にアクセスし、OpenVPN Connect という無料アプリをダウンロードします。
設定のインポート
このアプリに、iTunes等の手段で、上記で作成した client1.ovpnを渡します。セキュアかどうか微妙なところですが、iPhoneのメールクライアントやファイラー等から .ovpnファイルを OpenVPN Connectで開くこともできます。
アプリでファイルを開くと、以下のような画面が表示されますので、+ボタンをタップします。これで、設定が完了します。
接続の開始
VPN接続を開始するには、下記の場所をタップしてください。
ステータスが Connected に変われば、接続完了です。
設定に問題がなければ、Safari等のブラウザやSMBに対応したファイラー等で、内部ネットワーク環境にアクセスできるはずです。下のアプリで、内部ネットワーク上の共有フォルダにアクセスることができました。
参考サイト
- http://www.marbacka.net/misc/arkiv/openvpn_iphone.html
- How To Set Up an OpenVPN Server on Ubuntu 14.04 | DigitalOcean
トラブルシューティング
もし、ステータスが接続済になっているにも関わらず、内部ネットワークにアクセスできない場合は、server.conf もしくは クライアントソフトウェア(あるいは client1.ovpn)の設定が間違っているか、ルーティングが正しく行われていないことが考えられます。
クライアント側の接続ログは、以下の場所から確認できますので、参考にしてください。
OpenVPN Connectの場合
サーバー側のログは、server.conf で何も設定を変更していなければ、システムログを確認します。
# view /var/log/syslog
以下に、私の引っかかったポイントをいくつか挙げておきます。
OpenVPNサーバーで、正しくIPフォワーディングの設定が出来ているか。とくに、sysctl.conf を変更し、反映したか。
- VPNサーバー自体(192.168.1.10)にはアクセスできるが、他のサーバー(192.168.1.20)にはアクセスできない状態の場合、これが該当する可能性が高いです。
クライアントとサーバーで、暗号化方式を揃えたか。
- サーバーで cipher を AES-256-CBC としたなら、クライアント側でも同じにする必要があります。
内部ネットワークからのレスポンスが正しく OpenVPNサーバーに戻ってくるか
- ルーター 192.168.1.1 で、10.8.0.0/24 宛てのパケットを正しくルーティングする必要があります。