自宅(大阪の方)のインターネット環境をSoftbank Airに変えた。
ところが、Softbank Airの機器(Airターミナル)はポート開放ができないので、自宅のVPNサーバー(SoftEther VPN Server)に外から接続できなくなってしまった。
どうしたもんか、と色々調べていたら、似たような境遇の方がいて(Softbank Air導入期。VPSでVPNを使って自宅LANへアクセスしてみた。 | しま★りん.blog @ayurina)、この記事が大変参考になったので、同じような構成を組んでみることにした。
具体的には
- VPSを借りて、そこにSoftEther VPN Serverを立てる。
- 自宅サーバーにはSoftEther VPN Bridgeを入れて、VPS上のSoftEther VPN Serverにカスケード接続する。
外部からVPN接続する時は、VPS上のVPN Serverに対して接続しに行く。ここを経由することによって、外部からも自宅LANに入れるようになる。
構成を図に示すと、下のようになる。赤い太い線がVPNトンネル、緑の細い線がL2の論理接続を示す。
Fig.1 VPNネットワーク構成 |
- おうちサーバー上の仮想HUB"BRIDGE"とVPS上の仮想HUB"DEFAULT"の間は、SoftEther VPNによりL2のトンネルが形成される。
- おうちサーバー(及び自宅内の他のデバイス。図では省略)は、仮想HUB"BRIDGE"経由でVPS上の仮想HUB"DEFAULT"とL2接続する。
- VPSのOSは、TAPインターフェイス"tap_vpn"を介して仮想HUB"DEFAULT"とL2接続する(Linuxの場合、物理NIC"eth0"は仮想HUBと接続できない。SoftEther VPNマニュアル 3.6.9 tap デバイスの使用参照)。
- 外部から接続する場合は、そのデバイスのVPNクライアント機能(Windowsの場合はMS-SSTP、iOSやAndroidの場合はL2TP over IPsec)で仮想HUB"DEFAULT"との間にトンネルを作って通信を行う。
なお、VPSにはDigitalOceanを使うことにした。
DigitalOceanとは
DigitalOceanは、1ヶ月$5から借りられる激安VPS。サインアップしてクレジットカードを登録し、"Create Droplet"をクリックしてOSのディストリビューションとサイズ、データセンターを選ぶだけで、あっという間に仮想サーバーが手に入る(ちなみに、DigitalOceanでは仮想サーバーのことを"Droplet"と呼ぶ)。
Fig.2 DigitalOceanにてVPSを作成 |
また、SSH接続するために公開鍵の登録を行う必要がある。この辺りの手順は、本稿のメインテーマではないので、詳細は割愛する。
VPSにSoftEther VPN Serverを導入する
公式サイトからLinux 64bit用のインストーラをダウンロードして、makeする。基本的にはマニュアル通り。なお、2016年2月14日現在の最新バージョンは4.19。
$ wget http://jp.softether-download.com/files/softether/v4.19-9599-beta-2015.10.19-tree/Linux/SoftEther_VPN_Server/64bit_-_Intel_x64_or_AMD64/softether-vpnserver-v4.19-9599-beta-2015.10.19-linux-x64-64bit.tar.gz --2016-02-xx hh:mi:ss-- http://jp.softether-download.com/files/softether/v4.19-9599-beta-2015.10.19-tree/Linux/SoftEther_VPN_Server/64bit_-_Intel_x64_or_AMD64/softether-vpnserver-v4.19-9599-beta-2015.10.19-linux-x64-64bit.tar.gz Resolving jp.softether-download.com (jp.softether-download.com)... 130.158.75.49 Connecting to jp.softether-download.com (jp.softether-download.com)|130.158.75.49|:80... connected. HTTP request sent, awaiting response... 200 OK Length: 6277746 (6.0M) [application/x-gzip] Saving to: ?softether-vpnserver-v4.19-9599-beta-2015.10.19-linux-x64-64bit.tar.gz? 100%[======================================>] 6,277,746 4.67MB/s in 1.3s 2016-02-14 12:53:00 (4.67 MB/s) - ?softether-vpnserver-v4.19-9599-beta-2015.10.19-linux-x64-64bit.tar.gz? saved [6277746/6277746] $ tar xvzf ./softether-vpnserver-v4.19-9599-beta-2015.10.19-linux-x64-64bit.tar.gz vpnserver/ vpnserver/Makefile (snip) vpnserver/hamcore.se2 $ cd vpnserver $ make -------------------------------------------------------------------- SoftEther VPN Server (Ver 4.19, Build 9599, Intel x64 / AMD64) for Linux Install Utility Copyright (c) SoftEther Project at University of Tsukuba, Japan. All Rights Reserved. -------------------------------------------------------------------- Do you want to read the License Agreement for this software ? 1. Yes 2. No Please choose one of above number:以後、画面の指示に従ってmakeを進める。
makeが終わったら、vpnserverディレクトリを/usr/localに移動し、root以外触れないようパーミッションを変更。
ここからは、rootで作業する。
(Syntax Highlighterの都合上、プロンプトは#ではなく$です。悪しからず)
$ cd .. $ mv vpnserver /usr/local $ cd /usr/local/vpnserver $ chmod 600 * $ chmod 700 vpncmd $ chmod 700 vpnserverここまでで配置は完了。
次に、vpnserverをサービス化するが、公式マニュアルにはchkconfigを使う方法しか書いてない。せっかくCentOS7なので、systemdを使うようにする。
Systemd用SoftEther設定ファイル - blog.204504byse.infoを参考にさせていただいた。
[Unit] Description=SoftEther VPN Server After=network.target [Service] Type=forking ExecStart=/usr/local/vpnserver/vpnserver start ExecStop=/usr/local/vpnserver/vpnserver stop [Install] WantedBy=multi-user.targetサービスを起動し、自動起動の設定を行う。
$ systemctl start vpnserver $ systemctl enable vpnserverこれで無事サーバーが立ち上がった。
VPN Serverの設定
"SoftEther VPN Server Manager for Windows"のインストーラをダウンロードし、おうちサーバーにインストールする(以後"SoftEther VPN サーバー管理マネージャ"と呼ぶ)。インストールが完了したら、SoftEther VPN サーバー管理マネージャを起動し、VPS上のVPN Serverに接続する。
初回接続時にはパスワードの設定を求められるので、設定する。
メイン画面はこんな感じ。
Fig.3 SoftEther VPN サーバー管理マネージャのメイン画面 |
まず"仮想 HUB の管理"をクリックして仮想HUB管理画面に移動する。
"ユーザーの管理"にて「外部から接続するユーザー」と「VPN Brigdeが使うユーザー」の2つを作る。
Fig.4 ユーザーを2つ追加 |
"仮想 NAT および仮想 DHCP サーバー機能" にて、SecureNAT 機能を有効にする。これでSecureNAT 仮想ホストが起動する。
"SecureNAT の設定"にて、SecureNAT 仮想ホストのIPアドレスを設定。
仮想DHCPサーバー機能を有効化し、配布IPアドレス帯とサブネットマスクを設定する。
Fig.5 DHCPサーバーとして動作させるための設定 |
ここでやることは、"L2TP サーバー機能を有効にする (L2TP over IPsec)"にチェックを入れて、"IPsec 共通設定"に好きな事前共有鍵(PSK)を設定するだけ。
次に、WindowsのVPNクライアント用に"OpenVPN / MS-SSTP 設定"を行う。
ここでやることはもっと簡単で、"MS-SSTP VPN サーバー機能を有効にする"にチェックを入れるだけ。
次に、MS-SSTP用のサーバー証明書を作る。
"暗号化と通信関係の設定"に移動し、"サーバー証明書"の"新規作成"をクリックし、画面の指示に従う。
サーバー証明書が出来上がったら、"エクスポート"をクリックして、"X509 証明書ファイル(.CER)と秘密鍵ファイル(.KEY)の組み合わせとして保存する"を選び、CERファイルを保存する。
このCERファイルは、別途、Windowsクライアントの証明書ストア(信頼されたルート証明機関)にインポートしておく。
また、外部からDNS名で接続できるようにダイナミックDNS機能を使う必要があるが、これはデフォルトで有効になっている(ありがたい!)ので、特にいじる必要はない。メイン画面下部に表示されている"現在の DDNS ホスト名"をメモっておけばOK。ちなみに、先ほど作成したサーバー証明書のCNは、このDDNSホスト名になっている。
最後に、VPSのOSが仮想HUBと通信をするためのTAPインターフェイスを作る(これをやらないと、おうちサーバーからも外部からVPN接続したデバイスからも、VPSサーバーと通信することができない)。
"ローカルブリッジ設定"で、仮想 HUB"DEFAULT"を選び、"新しい tap デバイスとのブリッジ接続"を選択。新しい tap デバイス名を "vpn" として"ローカルブリッジを追加"をクリック。
Fig.6 tapデバイスの作成 |
…これだけでよい、はずなのだけど、私の環境では、VPSのOSを再起動した後、うまくtap_vpnにIPアドレスが設定されない現象に出くわした。
(どうも、vpnserverが起動してtapデバイスを作りに行く前に、Network ManagerがtapデバイスにIPアドレスを割り当てようとして空振りしているっぽい?
systemd用のファイルに"After=network.target"って書いてるのにな?
この辺り、ちゃんと原因切り分けできてません)
仕方がないので、とりあえずの回避策として、vpnserverの起動スクリプトを用意することにした。
スクリプトでやっていることは、『vpnserverのプロセスを立ち上げた後、tapデバイスが作られるのを待ってから、tapデバイスにIPアドレスを割り当てる』というもの。
作成したスクリプトは以下の通り。/opt の下に vpnserver.sh という名前で保存し、chmod +Rで実行権限を付けておく。
※昔ながらのrcスクリプト風の書き方になっていてダサい(お作法に沿っていない)気がするので、後日見直したい。
#!/bin/sh # description: SoftEther VPN Server DAEMON=/usr/local/vpnserver/vpnserver LOCK=/var/lock/subsys/vpnserver test -x $DAEMON || exit 0 case "$1" in start) $DAEMON start touch $LOCK i=0 while [ $i -lt 10 ]; do sleep 1 if [ `nmcli c show | grep tap_vpn | wc -l` -gt 0 ]; then /usr/bin/nmcli connection modify tap_vpn ipv4.method manual ipv4.addresses 192.168.1.252/24 ipv4.gateway 192.168.1.1 /usr/bin/nmcli connection down tap_vpn /usr/bin/nmcli connection up tap_vpn logger /opt/vpnserver.sh:tap_vpn ip address set successful break fi i=$((i+1)) done ;; stop) $DAEMON stop rm $LOCK ;; restart) $DAEMON stop sleep 3 $DAEMON start i=0 while [ $i -lt 10 ]; do sleep 1 if [ `nmcli c show | grep tap_vpn | wc -l` -gt 0 ]; then /usr/bin/nmcli connection modify tap_vpn ipv4.method manual ipv4.addresses 192.168.1.252/24 ipv4.gateway 192.168.1.1 /usr/bin/nmcli connection down tap_vpn /usr/bin/nmcli connection up tap_vpn logger /opt/vpnserver.sh:tap_vpn ip address set successful break fi i=$((i+1)) done ;; *) echo "Usage: $0 {start|stop|restart}" exit 1 esac exit 0systemd用ファイルを以下のように書き換える。
[Unit] Description=SoftEther VPN Server After=network.target [Service] Type=forking ExecStart=/opt/vpnserver.sh start ExecStop=/opt/vpnserver.sh stop ExecReload=/opt/vpnserver.sh restart [Install] WantedBy=multi-user.target今のところ、これでうまく動いている。
おうちサーバーにSoftEther VPN Bridgeを導入し、設定する
公式サイトからWindows用のインストーラをダウンロードして、Bridgeをインストールする。インストールが終わったら設定を行う。
おうちサーバー上でSoftEther VPN サーバー管理マネージャを起動し、localhost に接続する。
メイン画面を見ると分かるが、インストール時点で自動的に"BRIDGE"という固定名称の仮想HUBが作成されている(VPN Bridgeは、この1つの仮想HUBしか持つことができない)。
まず、"ローカルブリッジ設定"で仮想HUB"BRIDGE"と物理NICとのひも付けを行う。
Fig.7 ブリッジの作成 |
Fig.8 カスケード接続で自宅のブリッジとVPSの仮想HUBを接続する |
後は、クライアントデバイス(PCやタブレット等)にVPN接続設定を行うだけ。そっちは本稿の主旨ではないので省略。
2016.02.18 自分用追記
サービス起動順を制御しないと、Apacheがtap_vpnのIPアドレス 192.168.1.252 のバインドに失敗して起動がコケるので、httpd.serviceをvpnserverより後に起動する必要がある。3行目の"After"を修正。$ cp /usr/lib/systemd/system/httpd.service /etc/systemd/system/ $ vi /etc/systemd/system/httpd.service
[Unit] Description=The Apache HTTP Server After=network.target remote-fs.target nss-lookup.target vpnserver.service [Service] Type=notify EnvironmentFile=/etc/sysconfig/httpd ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND ExecReload=/usr/sbin/httpd $OPTIONS -k graceful ExecStop=/bin/kill -WINCH ${MAINPID} # We want systemd to give httpd some time to finish gracefully, but still want # it to kill httpd after TimeoutStopSec if something went wrong during the # graceful stop. Normally, Systemd sends SIGTERM signal right after the # ExecStop, which would kill httpd. We are sending useless SIGCONT here to give # httpd time to finish. KillSignal=SIGCONT PrivateTmp=true [Install] WantedBy=multi-user.target
0 コメント:
コメントを投稿