きなこのブログ

技術系の覚書など。

マンションLANでSoftEther VPN on Raspberry pi 3

いわゆるマンションLANというのか、ホテルのようにLANポートが壁に出ていて挿したらインターネットに出られるけどローカルIPしかもらえない、という環境でVPNする方法です。

前回の記事の続きです。

目標:グローバルIPなしでVPN接続して、自分自身と家LANにアクセスしたい

いくらルータがRTX830であってもグローバルIPが無ければVPNセッションは張れません。そこで、自宅LAN内にVPNサーバを立て、いわゆる「NAT越え」を実現する方法を考えます。

VPN Azureを使う

Raspberry piの活用もしたかったので、今回はSoftEther VPN serverを使用することにしました。SoftEtherは元々L2TPなどに対応していないネットワークでもHTTPSプロトコルで通信することでVPNセッションを確立するそうです。つまり自宅のルータがVPNパススルーに対応していない安いやつでも大丈夫です。さらにVPN Azureという機能でサーバリレーらしきやり方を用いることで、グローバルIPのない拠点に対してもVPN接続が出来るようにしてくれます。

ネットワーク構成を考える

結論から言うと、NIC1枚構成は諦めました。かなりハマったのですが、tap作ったりbr作ったりL3SW作ってサブネット分けたり仮想HUB増やしてカスケードとか色々やりましたけどうまく行きませんでした。

幸いにしてRaspberry pi 3にはNICが有線と無線の2枚搭載されています。ここではeth0をVPN用、wlan0をLAN内接用として使用する構成にします。

概要図(手書き)

f:id:kinakomochi-tank:20180524070602p:plain

Raspberry piVPN ClientがVPN Azureで待ち合わせて家LANに一緒に帰るイメージでしょうか。TeamViewerと似てますね。VPN ClientはRaspberry piを含む家LANのすべての端末にアクセスできます。

VPN Azureの代わりにVPSを自分で立ててサーバリレーする方法もあるみたいです。ちょっと興味はあったものの、国内サービスだと月額1000円くらいはするようだし、外国の激安VPSだとサービス継続性の不安やセキュリティ問題をクリアする自信がなかったので、無料(!)のVPN Azureで頑張ってみることにしました。

構築手順を考える

この記事で扱う構成を簡単にまとめると以下のようになります。

この構成では、既存の環境にラズパイとラズパイ上の設定を足すだけです。難しい起動スクリプトもありません。それではやっていきましょう。

SoftEther VPN serverの設定

SoftEther VPN serverをインストール

公式サイトのとおりです。

  1. SoftEtherのサイトからVPN Serverパッケージをダウンロードします。ここではLinux -> ARM EABI (32bit)のもの。

  2. teratermRaspberry piSSHログインします。

  3. ダウンロードしたファイルをteratermドラッグ&ドロップするとあら不思議。/home/pi(例)と入力してSCPをクリックするとファイルがラズパイにコピーされます。そう、これがSCP…!

  4. ここからはCUI

   # パッケージを解凍
   tar xf softether-vpnserver-v4.27-9664-beta-2018.04.20-linux-arm_eabi-32bit.tar.gz
   # vpnserverというフォルダができるのでmakeコマンドを実行
   cd vpnserver
   sudo make
   # フォルダごと実行フォルダへ移動
   cd ..
   sudo mv vpnserver /usr/local
   cd /usr/local/vpnserver/
   # 実行権限を付与
   sudo chmod 600 *
   sudo chmod 700 vpncmd
   sudo chmod 700 vpnserver

5.インストールできたか確認してみる

   sudo /usr/local/vpnserver/vpncmd
   1. VPN Server または VPN Bridge の管理
   #あとは空白のままEnterEnter
   check
   この動作環境チェックツールを実行したシステムがテストに合格した場合は、SoftEther VPN ソフトウェアが動作する可能性が高いです。チェックにはしばらく時間がかかる場合があります。そのままお待ちください...
   
   'カーネル系' のチェック中...
                 [合格] ○
   'メモリ操作系' のチェック中...
                 [合格] ○
   'ANSI / Unicode 文字列処理系' のチェック中...
                 [合格] ○
   'ファイルシステム' のチェック中...
                 [合格] ○
   'スレッド処理システム' のチェック中...
                 [合格] ○
   'ネットワークシステム' のチェック中...
                 [合格] ○
   
   すべてのチェックに合格しました。このシステム上で SoftEther VPN Server / Bridge  が正しく動作する可能性が高いと思われます。
   
   コマンドは正常に終了しました。

6.全部○になったらとりあえずOKです。exitで抜けます。

init.d vs systemd

よその記事を見ていて、init.dで起動スクリプトを書く記事と、それをさらにsystemdで登録などしている記事があって混乱したのでちょっと調べてみました。

  • デーモン…要するに(Windowsで言うところの)サービス。

  • init…デーモンを起動するためのもの。よりカーネルに近いところにいる。

  • init.d…initの一種であるsysvinitで使われる起動スクリプトが置かれるディレクト/etc/init.dのこと。

  • systemd…sysvinitの進化系。

  • sysvinit…Debianの説明によると、

    jessie 以降のデフォルトは、Linux では systemd になります。これは円滑な移行を促すとともに、systemd への切り替え後に 万が一システムが起動しなくなった場合に備えてフォールバック用の SysV init バイナリを提供します。

    ということなので、systemdで動くならわざわざsysvinitを使わなくていいということですね。

とりあえず今Stretchを触っている限りではsystemdだけで困っていません。

起動ファイルを作ってスタートアップに登録する

参考サイト:SoftEther VPN Serverをsystemd対応にする - Qiita

サービスのファイルを作る

sudo touch /etc/systemd/system/vpnserver.service

vpnserver.serviceの中身を書く

[Unit]
Description=SoftEther VPN Server
After=network.target network-online.target

[Service]
User=root
ExecStart=/usr/local/vpnserver/vpnserver start
ExecStop=/usr/local/vpnserver/vpnserver stop
Type=forking
RestartSec=3s
WorkingDirectory=/usr/local/vpnserver/
ExecStartPre=/sbin/ip link set dev eth0 promisc on

[Install]
WantedBy=multi-user.target

デーモンをリロードして作ったvpnserverを立ち上げてみる

$ sudo systemctl daemon-reload
$ sudo systemctl start vpnserver

自動起動に登録してちゃんと上がってくるか確認

$ sudo systemctl enable vpnserver.service
$ sudo reboot
$ systemctl status vpnserver.service
● vpnserver.service - SoftEther VPN Server
   Loaded: loaded (/etc/systemd/system/vpnserver.service; enabled; vendor preset
   Active: active (running) since Tue 2018-04-24 21:56:41 JST; 45s ago

Active: active (running)になっていればいい。やったぜ。

SoftEther VPN 管理マネージャの設定

  1. VPN serverと同じところから「SoftEther VPN Server Manager for Windows」をダウンロードして、作業用PC(Windows)に管理マネージャをインストールします。
  2. 新しい接続設定を作成して、ホスト名をwlan0に固定したIPアドレスにします。(eth0はこのあとアクセスできなくなるので)ポート番号は443のままで
  3. 接続設定の作成画面では管理パスワードを入力しないでOK
  4. できた接続先に接続すると管理画面が開きます

まずはこの時点で対象機器=Raspberry piにアクセスできています。このあと仮想HUBの設定を間違えたりネットワーク設定をトチったりするとブロードキャストストームが発生することもあるので、駄目になったら接続設定を削除してやり直しましょう。

  1. 仮想HUBを作成 名前と管理用パスワードは適当に
  2. 仮想HUBの管理ー>ユーザの管理で適当にユーザを作る
  3. パスワード認証にしてパスワードを設定 これがVPNアクセスアカウントになる
  4. ローカルブリッジ設定で作った仮想HUBとeth0をブリッジ
  5. VPN Azure設定から適当なホスト名を作成

もしもの時のCUIから操作

sudo /usr/local/vpnserver/vpncmd
1
Enter
Enter
help

ネットワーク設定

interfacesの設定

/etc/network/interfacesは特に触るところはありません。

# Please note that this file is written to be used with dhcpcd
# For static IP, consult /etc/dhcpcd.conf and 'man dhcpcd.conf'

# Include files from /etc/network/interfaces.d:
source-directory /etc/network/interfaces.d

auto lo
iface lo inet loopback

iface eth0 inet manual

allow-hotlplug wlan0
iface wlan0 inet manual
wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf

ネットワークに接続される時に実質auto eth0allow-hotplug eth0の違いは無さそうに見えるのですが、SoftEtherのセットアップで色々やっている時にauto eth0すると上手く立ち上がりませんでした。違いがよく分かりませんが、上記は成功例として記載しておきます。(参考:/etc/network/interfaces" の基本的なシンタックス - Debian公式ドキュメント)

dhcpcd.confの設定

/etc/dhcpcd.confeth0を0.0.0.0にします。理屈はよく分かっていませんが、こうすることでeth0はIPが”無い”ものとみなされるようです。L2で接続されているということなのかな??

interface eth0
static ip_address=0.0.0.0

interface wlan0
static ip_address=192.168.0.116/24
static routers=192.168.0.1
static domain_name_servers=192.168.0.1

実はこの0.0.0.0を使う設定に気づいたのがかなり最後の方だったので、これを使えばNIC1枚構成でも上手く行っていたのかもしれません。(根気が尽きたので未検証。。。)

wpa_supplicant.confの設定

wpa_supplicant.confもとくにいじりません。

ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
country=JP

# ここから追記
network={
    ssid="SSID" #ダブルクォーテーションが必要
    scan_ssid=1 #SSIDがステルスなら1にする
    psk=暗号化されたパスフレーズ #暗号化しないと動かない(気がする)
    key_mgmt=WPA-PSK #なくてもいいかも
}

ネットワーク>vpnserverの順に起動する必要があるので、sudo rebootして完了です。デーモンとインタフェースが立ち上がっているか確認しておきましょう。

SotfEther VPN Clientをインストール

ここではWindows版を使います。SoftEther VPN ClientはPCに仮想ネットワークインタフェースを一個増やします。そいつが仮想HUBとカスケード接続されてあたかもClient PCが家LANに参加しているように振る舞います。当然ながら、物理インタフェースがインターネットに接続している必要があります。

  1. 外出先のPCでVPN Clientをインストールしましょう。
  2. 新しいVPN接続を作成します。
  3. 接続先VPNサーバを自分のvpnazureホスト名にして
  4. 仮想HUBに設定したユーザ名とパスワードを入れて
  5. ポートは443、992、1194、5555のどれでもいい
  6. 接続できると家のルータからDHCPアドレスがもらえます。

接続確認

  • とりあえずwlan0のアドレスにpingしてみる
  • 手っ取り早くターミナルログイン
  • その他WebサービスなりSMBなりお好きに

DHCPがもらえない時は仮想HUBの設定を確認してください。SecureNATが有効になっているとこの構成ではだめです。

ラズパイ以外には接続できるけどラズパイ自身に接続できない時はブリッジかwlanの設定が間違ってます。eth0は0.0.0.0にすること、tapやbrctlは使わないことです。

あとバカバカしいんですがdhcpcdでrouterのアドレスを打ち間違えてて仮想HUBまで繋がらないというのもありました。この時はRaspberryPiのターミナルからVPN Azureのホスト名にpingできないのでインターネットに出れてないとわかりました。

セットアップするより記事にするほうが大変ですね…はてなMarkdown難しい。とりあえず、次引っ越す時はパブリックIPがもらえる所にしたいと思います。