|||||||||||||||||||||

なんぶ電子

- 更新: 

OpenVPN構築後の第2歩目

OpenVPN

前回OpenVPNのTUN環境を整えました。今回はそこから1歩進めて、サーバーやクライアントが所属しているネットワークのほかの端末とも接続を可能にする方法や、スマホでOpenVPNに接続する方法等を記しておきたいと思います。この時点での設定ファイルは次のようになっていることとします。

サーバー server.conf

dev tun
server 10.8.0.0 255.255.255.0
tls-server
dh dh2048.pem
ca ca.crt
cert server.crt
key server.key
persist-tun
persist-key
keepalive 10 60

クライアント client.conf

client
dev tun
remote xxx.xxx.xxx.xxx
tls-client
ca ca.crt
cert client.crt
key client.key
persist-tun
persist-key

最初に

OpenVPN How Toを参考にネットワーク単位でVPN通信をする設定を進めていきます。

まず通信の確認にはpingコマンドを利用すると思いますが、このコマンドでの通信がファイアウォールで遮断されていると設定に問題なくても通信できないことがあります。サーバーやクライアント、経路中にあるルーターの設定を確認してpingが通るようにしましょう。テスト環境ならファイアウォールをOFFにしておき、通信確認後もとに戻すのもいいと思います。

次にネットワークを公開する側の端末に「IPフォワード」を設定をする必要があります。IPフォワードとはネットワークインターフェース同士の通信を許可する設定です。OpenVPNでは架空のネットワークインターフェースが作られます。これともとよりあるネットワークインターフェースと通信することによりネットワーク公開が実現するのですが、通常このIPフォワードは許可されていません。

筆者のDebian環境ではIPフォワーディングを設定しなくても接続できてしまいましたが、Debianで設定するには/etc/sysctl.confの次のコメントアウトを解除します。

net.ipv4.ip_forward=1

Windowsだとレジストリを修正する必要があるので少し厄介です。誤操作でレジストリを書き換えてしまうと最悪Windowsが起動しなくなることがあります。自己責任でお願いします。方法は@IT:「Windowsのレジストリを設定してIPルーティングを有効にする」に掲載されていました。ありがとうございます。これに従ってHKLM/SYSTEM/CurrentControlSet/Services/Tcpip/Parameters/IPEnableRouterのREG_DWORD値を0から1にします。

筆者のWindows環境ではこの設定をしていないとネットワークへの接続ができませんでした。

サーバー側のネットワークと接続する設定

サーバーやクライアントが所属するネットワークとVPN接続するためにはOpenVPNの設定も必要ですが、それぞれのネットワークのゲートウェイ(ルーター)の設定も必要になります。また、アクセス可能範囲の設定には端末やルーターのファイアウォールを使用します。

ここでは、OpenVPNサーバーのIPアドレスを192.168.10.1/24、クライアントのIPアドレスを192.168.20.1/24、サーバーとクライアント間で使う架空のIPアドレスを10.8.0.0/24とします。

ネットワーク単位で接続をする場合は、サーバーとクライアントで違うネットワークを設定しておく必要があります。また、それらのネットワークは、それぞれがつながっているどのネットワークとも重複してはいけません。たとえばOpenVPNサーバーが所属するネットワークが192.168.10.0/24だった場合には、全体を通してそれ以外に192.168.10.0/24のネットワークがあってはいけません。日本に同じ名前を持つ市が複数存在しないのと同じで、どこにデータを流していいかわからなくなってしまうからです。

まず接続してきたクライアントに通知を出す設定を記述します。192.168.10.0のネットワークはOpenVPNサーバー宛に送信させます。routeコマンドを"(ダブルクォート)で囲ってある点に注意してください。これはサーバー側のconfigに記述します。

push "route 192.168.10.0 255.255.255.0"

この設定はOpenVPNサーバーからクライアント0Sへ伝えられ、最終的にOSのrouteコマンドに置き換えられます。

前回の記事で書いていますが、そのコマンドの実行がクライアントで正常に行われなければ意図した通信ができません。

ただし、必ずしもOpenVPN経由で実行しなければいけないというものではなく、手動で実行することもできます。

次にVPNサーバー側のネットワークからOpenVPNクライアントに向けたデータの経路設定をします。

OpenVPNサーバーが稼働している端末はクライアントへの経路はわかっています。しかし同じネットワークにいるほかの端末はまだそれを知りません。それらの端末すべてに10.8.0.x(xはクライアントに自動で割り当てられる値です)へのデータはOpenVPNサーバーに転送するという設定をすることでも実現可能ですが、ゲートウェイになっているルーターに経路情報を設定するのが一般的です。

各端末はゲートウェイ経由で(正確にはゲートウェイに送信先を教えてもらって)データを転送します。

ゲートウェイ(ルーター)へ経路を設定する方法は製品のメーカーにより様々ですが、そこに「10.8.0.0/24宛のデータはOpenVPNサーバーに転送する」という設定をします。

クライアント側のネットワークと接続する設定

続いてクライアント側のネットワーク192.168.20.0/24を接続します。クライアント側のネットワークは複数存在する可能性があるのでそれに合わせて設定も少し複雑になります。クライアント側のネットワークに関する設定ですがconfigファイルへの記述はすべてサーバー側にします。

まずOpenVPNサーバーが稼働するOSに192.168.20.0/24宛のデータが来た場合にOpenVPNアプリに転送する設定をします。serverのパラメータとして設定したネットワーク以外はこの記述する必要があります。

route 192.168.20.0 255.255.255.0

routeの設定だけだと、OpenVPNアプリは受け取ったデータを複数存在するどのクライアントに送ったらいいかわかりません。今度はそのための設定をします。

この設定はサブファイルを使用するのですが、その前にサブファイルを入れるフォルダを作成します。フォルダの場所をclient-config-dirという項目に記述します。サブファイルは接続するクライアントと同じ名前(証明書内のCommon Name)で作成します。そこにクライアント毎の設定を記述します。

ここで接続してくるクライアント名は「client」とします。

#configファイルでccdというフォルダを指定
client-config-dir ccd

ccd¥client(サブファイル)

#ccdというフォルダ内にclientというファイルを作りそこに記述
iroute 192.168.20.0 255.255.255.0

このirouteの記述で最終的な宛先を決めているのですが、なぜconfigに書かずに個別のファイルを作るかというと、該当のクライアントが接続してくるまでこのルートは存在しない為です。

次に、クライアント側のネットワークのゲートウェイ(ルーター)に「10.8.0.0/24宛のデータはOpenVPNクライアントに転送する」という設定をします。

両側のネットワークを相互接続する

サーバー側のネットワークとクライアント側のネットワークの相互通信を行うなら、configファイルにここまでの両方の設定を記述したうえで、それぞれのゲートウェイ(ルーター)の設定を変更します。

どちらも10.8.0.0/24宛のデータをOpenVPNが稼働している端末へ転送するように設定していたと思いますが、サーバー側は192.168.20.0/24宛、クライアント側は192.168.10.0/24宛のデータを転送するように変更します。10.8.0.0/24の設定は残しておけばサーバーやクライアントを指定して接続する際に使えますが、本来のアドレスである192.168.10.1や192.168.20.1でアクセスできるので必須ではありません。

さらに、OpenVPNクライアント同士を接続したい場合は、configファイルにクライアント同士の接続を許可するclient-to-clientオプションを指定したうえで、クライアントにルート情報通知するpushの記述をします。新たなクライアントのネットワークは192.168.30.0/24としています。

client-to-client
push "route 192.168.20.0 255.255.255.0"
push "route 192.168.30.0
255.255.255.0"

ファイアウォールの設定

OpenVPNサーバーOSやクライアントOS、それぞれの拠点のルーター(ゲートウェイ)にあるファイアウォールのどれにどのような設定をするかは運用方法により分かれると思いますが、ファイアウォールで設定する事は大きく2つに分かれます。ひとつはOpenVPNの通信が遮断されないようにすること。もうひとつはOpenVPN経由で通信可能となる範囲を制限することです。

前者は主にconfigで設定したプロトコルやポート番号がファイアウォールを通過できるようにする設定です。Windowsファイアウォールなら、アプリ単位で通信を許可する方法もあります。

後者は接続元や接続先のIPアドレスを基準に到達の可否を設定します。それぞれが所属する実際のネットワークの他に、OpenVPN用の仮想のIPアドレスも考慮する必要があります。

スマホアプリのインストールと設定方法

スマホにOpenVPNをインストールするにはストア経由で行います。OpenVPNと検索をかけると見つけられると思います。Androidでインストールしてみたところ、OpenVPN-connectに似たアプリになっていました。iPhone用のOpenVPNも存在するようですが、筆者には環境がなく試していません。同じアプリだという前提で話を進めます。

まず、ca証明書、スマホ用証明書、スマホ用秘密鍵、クライアント用の設定をしたconfigファイルを用意します。configファイルののcaやcert、keyの項目はすべて、ファイル名だけの記述にしておくのがおすすめです。

どこでもいいですが、それら4つのファイルをスマホに転送します。この時configファイルの拡張子(最後は).ovpnで終わるようにしてください。

アプリを立ち上げ、「File」タブのメニューからコピーしたconfigファイルを選択します。記述に問題なければ、右上の「ADD」から設定を保存できるようになります。この時チェックボックスにチェックを入れれば、同時に接続も試みます。

スマホ版OpenVPNの使い方

ちなみに執筆時点ではTAP接続は利用できないようでした。

証明書を失効させる(CRL)

もうひとつ管理上忘れてはいけないのは不要になった証明書を失効させることです。

発行した証明書はcaによって管理されます。なのでOpenSSLで証明書を発行したのならOpenSSL、EasyRSAならEasyRSAで失効も処理しないといけません。ちなみにOpenSSLを使って証明書を管理する方法は、別記事でapacheサーバーのクライアント認証のためにCAを作成した際とほぼ同じになりますので参考にしてみてください。

OpenSSLやEasyRSA、vpnuxPKIManager等から出力した失効リスト(ここではcrl.pemとします)をサーバーにコピーし、サーバー側のconfigファイルに次のように記述します。

crl-verify crl.pem

これにより失効リストに掲載された証明書による接続はできなくなります。

最後に

この記事を書いていて接続テストをする中でOpenVPNをIPv6で接続してみたかったのですが、この方法はArchWiki:「OpenVPN」のページに方法がありました。ありがとうございます。IPv6でOpenVPNを接続するには両側で「proto udp6」とするそうです。その上でクライアント側のremoteの項目にはIPv6のアドレスを入れます。IPv6で構築したVPNトンネルにIPv4のデータが通過できるか試してみたかったのですが、できました。他、詳細は先のページを参考にしてください。

またDebian等の環境で「WARNING: file 'server.key' is group or others accessible」というWARNINGがでたら、秘密鍵の権限がセキュリティ上好ましくない状態になっています。keyの所有者はroot、権限は600にすると表示されなくなると思います。

筆者紹介


自分の写真
がーふぁ、とか、ふぃんてっく、とか世の中すっかりハイテクになってしまいました。プログラムのコーディングに触れることもある筆者ですが、自分の作業は硯と筆で文字をかいているみたいな古臭いものだと思っています。 今やこんな風にブログを書くことすらAIにとって代わられそうなほど技術は進んでいます。 生活やビジネスでPCを活用しようとするとき、そんな第一線の技術と比べてしまうとやる気が失せてしまいがちですが、おいしいお惣菜をネットで注文できる時代でも、手作りの味はすたれていません。 提示されたもの(アプリ)に自分を合わせるのでなく、自分の活動にあったアプリを作る。それがPC活用の基本なんじゃなかと思います。 そんな意見に同調していただける方向けにLinuxのDebianOSをはじめとした基本無料のアプリの使い方を紹介できたらなと考えています。

広告