ただのメモ

開発で得た知識のアウトプット

【Raspberry Pi 】SoftEther VPNとHTTPサーバを同居させて自分自身にアクセスする

 Raspberry Pi(以下ラズパイ)をVPNサーバとして利用しつつ、自身のHTTPサーバにアクセスするための備忘録です。

VPNでローカルのHTTPサーバを見る

 ラズパイ界隈では、しばしばmjpg-streamerと市販のWebカメラを用いた配信環境を構築する記事が書かれます。

github.com

しかし、mjpg-streamerのカメラ画像をそのまま外部に公開すると、第三者にも見られる可能性が非常に高くなり、個人情報的に好ましくありません。

それに対する一つの解決策として、VPNを用いてローカルのサーバにアクセスする方法があります。VPNでは暗号化は勿論のこと、デバイスによっては証明書認証も利用できます。スマホからはL2TP/IPsecが利用できます。つまり、HTTPサーバのBASIC認証などに比べると極めて安全です。

少し話が変わりますが、Webページをネイティブアプリのようなスタイルで閲覧できる、PWAという機能を利用すれば、VPN接続時にだけ利用できる一種のアプリとして提供できます。

f:id:pit-ray:20210413014441g:plain:h500

ちなみに、iPhoneでVPN接続を開始するには、設定 > VPNという2ステップを踏みます。

f:id:pit-ray:20210329082835j:plain

ここでは、ラズパイの構築パターンを書いていきたいと思います。

有線LANと無線LANがあるモデル

 ラズパイ3 B+やラズパイ4などのモデルです。これらのモデルには、無線LANと有線LANが備わっているため、その両方を利用することで簡単にセットアップできます。勿論、tapデバイスやbr0でごにょごにょすることもありません。

SoftEtherのローカルブリッジの注意事項には、次の記載があります。

Linux オペレーティングシステム内部での制限事項により、VPN 側 (仮想 HUB 側) からローカルブリッジしている LAN カードに割り当てられる IP アドレスに対して通信を行うことはできません。この制限は SoftEther VPN が原因ではなく、Linux の内部構造に原因があります。もし VPN 側 (仮想 HUB 側) から Linux でローカルブリッジに使用しているコンピュータ本体と、何らかの通信を行いたい場合 (たとえば VPN Server / VPN Bridge サービスと HTTP サーバーサービスを両方動作させており、VPN 側からもサーバーサービスにアクセスさせたい場合) は、ローカルブリッジ用の LAN カードを用意して接続し、その LAN カードと既存の LAN カードの両方を物理的に同じセグメントに接続してください (この他の場合においても 「3.6 ローカルブリッジ」 で解説したように、ローカルブリッジに使用する LAN カードはそのための単独のものを用意することが推奨されています)。(出典: 3.6 ローカルブリッジ - SoftEther VPN プロジェクト)

この意味は、SoftEtherにブリッジしたLANカードは出口専用になり、入口としては機能しない(自身にアクセスできない)ということです。したがって、ローカルブリッジ用にeth0、自身へのアクセス用にwlan0を利用します(SoftEther VPNの注意書きにあるように、プロミスキャスモードに対応した無線LAN子機か有線LANが必要であるため、必然的にeth0にブリッジします)。wlan0は同セグメントに接続すればいいです。ただ、ローカルブリッジ用のeth0にIPをふってもしょうがないので、eth0へのIPアドレスの割り当ては任意です。理解としては、eth0をVPN接続後の出口のルート、wlan0をローカルでのHTTPサーバとの通信ルートとして利用します(多分これで理解あってると思う)。

ただ、この構成ではラズパイを有線LANに接続しなければならないため、取り回しが良くありません。特に、センサ類とサーバを全て一つのラズパイにまとめたいときには非常に不便です。

どうしてもWi-Fiだけでやりたい

 無線接続でVPNサーバを構築したい場合、中継機を使えば実質的に無線で稼働させられます。つまり、中継機を利用して無線LANから有線LANへ変換します。現在の無線LANを構成している親機のルータとは別の無線ルータの中継機能を利用するか、専用の中継機を用意します。私の場合、BUFFALOのルータが余っていたため、追加費用はかかりませんでした。

親機に中継機を接続するには、次の手順を踏みます。ちなみに親機がNECのAterm BL1000HW、中継機がBUFFALOのWZR-HP-G302Hの場合です。

  1. 中継機として利用したいルータ(以下、中継機)のスイッチをブリッジモードにする。

  2. ルータのIPアドレスを出荷時に戻すために、リセットボタンを長押しし、初期化する。

  3. PCと中継機をLANケーブルで接続する。(この段階では中継機が親機に接続されていないため、無線でアクセスできないから)

  4. エアーステーション設定ツールにより、中継機を検出するか、中継機の裏面に記載されている、ブリッジ時のルータのIPアドレスにブラウザからアクセスする。(このあたりの手順は中継機のメーカや型番によって異なるため、それぞれの公式ページを参照してください)

  5. PCを接続しているのと同じセグメントに中継機のIPアドレスを固定する

  6. 親機と中継機がどちらもBUFFALOであればAOSS、異なるメーカであればWPSで接続する。この方法でうまくいかない場合は、親機のSSIDとパスワードを手動で入力します。BUFFALOの旧型モデルで有れば、エアーステーション間接続の設定から、新型で有れば中継機能の設定から、親機のSSIDをベタ打ちします。モノによっては、SSIDを自動検出できる場合もありますが、私の場合は検出できなかったです。

  7. これで固定したルータのIPアドレスに親機の無線LANからアクセスできるようになりました。今後は中継機の有線LANしか使わないため、好みで中継機のSSID検出をオフにします。

  8. 中継機を再起動します。

BUFFALOの場合には次のページのように型番ごとに設定方法を確認できます。

中継機能の設定方法(WEX-300) | バッファロー

以上により、PCとWi-Fiを切断しても、有線で中継機と接続すればインターネットに繋がるはずです。うまく行かない場合、親機や中継機にpingを送ったり、ipconfigやifconfigを利用してIPアドレスが正しいかどうか確認します。

 このように、無線LANルータの中継機能や専用の中継器を利用することで、無線LANを有線LANに変換し、実質的にWi-FiでVPNサーバを稼働させることができます。中継器によっては2000円クラスでも手に入ったり、お古のルータに中継機能が搭載されている場合もあります。ただ、無線LANの親機によっては専用の中継器でないと接続できないものがあり、予想以上に費用が掛かってしまう可能性があります。その際には、ラズパイを二つ用意し、VPNサーバを有線LANで接続できる位置に置くことも考慮するべきです。

設定方法

SoftEther VPNのサーバをインストールする

証明書認証を利用する場合には、ソースを書き換えてビルドしたりしますが、とりあえず/usr/local/vpnserver/に一式置き、systemdで起動できるようにすればいいです。この点の解説は、他のブログなどを参照ください。

ラズパイの設定をする

/etc/network/interfacesの下部に次のように追加します。

auto lo
iface lo inet loopback

iface eth0 inet manual

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

編集するには、次のようにVimを使うことをお勧めします。

$ sudo apt install vim
$ sudo vim /etc/network/interfaces

合わせて、wpa_supplicant.confにSSIDやら暗号化キーやらを記載します。心配な人は、暗号化キーをハッシュ化しておきましょう。

/etc/dhcpcd.confに次のように追記します。

interface eth0
static ip_address=0.0.0.0

interface wlan0
static ip_address=192.168.0.10/24 # HTTPサーバとVPNサーバ兼用
static routers=192.168.0.1
static domain_name_servers=192.168.0.1

これでラズパイのIPが固定されました。

先ほど説明した通り、ラズパイへのアクセスはWi-Fiを介しますが、デフォルトの省電力機能により不安定になることがあるため、その機能をオフにします。

まず、その機能の状態を確認します。

$ iwconfig
eth0      no wireless extensions.

lo        no wireless extensions.

wlan0     IEEE 802.11  ESSID:"**********"
          Mode:Managed  Frequency:2.412 GHz  Access Point: *************
          Bit Rate=72.2 Mb/s   Tx-Power=31 dBm
          Retry short limit:7   RTS thr:off   Fragment thr:off
          Power Management:on
          Link Quality=45/70  Signal level=-65 dBm
          Rx invalid nwid:0  Rx invalid crypt:0  Rx invalid frag:0
          Tx excessive retries:2  Invalid misc:0   Missed beacon:0

Power Managementがonになっています。次のコマンドでoffになることを確認します。

$ iw dev wlan0 set power_save off

ただ、Power Managementは再起動するとonに戻ってしまうため、起動する毎にこのコマンドが実行されるようにします。起動時にコマンドを実行するには様々な方法がありますが、例としてrc.localを利用します。

$ sudo vim /etc/rc.local

を実行し、次のコマンドを追記します。

# Disable Wi-Fi Power Management
/sbin/iw dev wlan0 set power_save off

これによって、再起動しても省電力機能がoffになります。

SoftEther VPNの設定をする

SoftEther VPNのサーバー管理マネージャでeth0と仮想HUBをローカルブリッジします。

f:id:pit-ray:20210324214022j:plain

親機の設定をする

VPNで接続するデバイスによって次のポートを開放し、wlan0のIPアドレスへフォワーディングします。一般的なルータであれば、親機のIPアドレスをブラウザに打ち込めば設定できるハズです。iptablesなどを利用している場合には、同様に開放します。

接続方法 プロトコル ポート番号
SoftEther VPN Client TCP 5555など(サーバの設定に依存)
iPhoneなどのL2TP/IP接続 UDP 450, 5000

以上で、80ポートで接続すればHTTPサーバに接続され、5555や450, 5000で接続すればVPNサーバによって処理されます。勿論、VPN接続をしている場合でも80ポートでHTTPサーバにアクセスできます。

ここで、VPNサーバのセキュリティを高めるためには、SoftEther Clientによる接続に固有証明書認証を用いたり、L2TP/IP接続のユーザにはアクセスリストで宛先IPアドレスをローカルに限定し、踏み台防止などを行うと良いです。SoftEtherのアクセスリストを利用する場合には、下部に破棄ルールを入れ、上部にローカル許可を入れますが、DHCPを無効化しないためにUDPの67, 68ポートは最優先で許可する必要があります。

今回紹介しなかったものとその指針

有線LANだけ搭載されたラズパイ

 ラズパイ3以前のものは無線LANが無く、物理有線LANのみ搭載されています。この場合、SoftEther VPNの解説記事でよく紹介されているようなtapデバイスとbr0によるブリッジ接続を利用します。

方法1 物理NIC増設する場合(コメントには仮想NICを追加する方法もあり) yunabe.hatenablog.com

方法2 tapデバイスとブリッジを利用する方法 yunabe.hatenablog.com

参考 tapデバイスの理解 blog.treedown.net

今回利用した方法は物理NICを二つ利用する方法であるため、無線LAN子機や有線LANアダプタをドングルしてやれば同様に利用できるはずです。

無線LANだけ搭載されたモデルの場合

ラズパイZeroのWHなどの小型モデルには、有線LANが無く無線LANだけ搭載されています。SoftEther VPNは、公式サイトでも説明がある通り、プロミスキャスモードに対応しているWi-Fiをドングルするか、有線LANアダプタを接続しなければなりません。(残念ながらラズパイのWi-Fiは、プロミスキャスモードに対応していないようです)

自己責任で

 SoftEther VPNは、比較的安全なVPNサーバ/クライアントですが、導入前と導入後では後者のほうが圧倒的にリスクが高くなります。その点注意して自己責任で行ってください。私はネットワークのプロの技術者ではないため、見落としている点がある可能性があります。保身のために言っておきますが、私は一切の責任を負いません