Sansan Builders Blog

Sansanのものづくりを支えるメンバーの技術やデザイン、プロダクトマネジメントの情報を発信

【Techの道も一歩から】第31回「クラウド上に自前のVPNを構築し、ラズパイを VPN ルータ化」

f:id:kanjirz50:20190104142720j:plain

こんにちは。DSOC 研究開発部の 高橋寛治です。

リモートワークが盛んである今、 VPN 接続を利用している人が多いのではないでしょうか。 私もそんな一人ですが、そういえば VPN サーバを立てたことがなかったので、挑戦してみました、というのは表向きの理由で、IPv6 による経路の VPN 接続を行いたいということが真の目的です。

自宅回線は IPv4(PPPoE)・IPv6(IPoE) となっており、IPv4 インターネット利用時は PPPoE の輻輳だと考えられますが、混み合う時間帯に RTT(Round Trip Time)*1 が安定しません(速度は普通に100Mbps を超えており十分です)。 諸々の都合により、IPv4 over IPv6 系サービスに変更できないため、IPv6 で接続する VPN サーバをクラウドサービス上に構築することで自前で IPv4 over IPv6 接続を試みます。イメージとしては、こちら で紹介されているものの経路を変えるというものです。

さらに、自宅から常に安定した経路で通信するために、ラズベリーパイを VPN ルータ化します。

結果として、ping を数回試行すると数回に一度跳ねていた RTT が安定するようになりました。

どのクラウドサービス上にサーバーを構築するか

VPN サーバとして利用するため、インスタンス料金や通信料といったランニングコストが安価かつ高品質なネットワークと IPv6 対応しているサービスを選びます。

今回は「さくらVPS」にしました。インターネットは 100Mbps の共有回線であり、グローバルIPアドレスは IPv4・IPv6の両方で付与されます。また、サーバ費用や通信費が月額固定であるため、安心して稼働できます。

RTT はできる限り小さい方がいいため、居住地に最も近い東京リージョンを選びます。

サーバの設定

学生時代によく使っていた CentOS を利用します。バージョンは CentOS 7 を選びました。VPS プランは 1G としました。

まずは、IPv6を有効にします。さくらの公式サイト の通り設定することで有効となります。 さくらVPS では、ウェブコンソール上で IPv4 に対してパケットフィルタリングを行うことができますが、IPv6は未対応です。 firewalld で IPv4 および IPv6 に対してファイアウォールを設定しましょう。

任意の IP アドレスからの SSH プロトコルと VPN 用のポートを開放し、それ以外は閉じます。 SSH の公開鍵認証設定や root ログイン禁止、連続ログイン試行回数など、念のため設定します。

テザリングなどにより別 IP から SSH ログインができないことや、IPv6 アドレスがネットワークインターフェイスに付与されていることを確認したら次へ進みます。

VPNサーバソフトウェアのインストールと設定

VPNサーバソフトウエアのインストール

SoftEther VPN をサーバに導入します。

# ソフトウエアの取得
$ wget https://github.com/SoftEtherVPN/SoftEtherVPN_Stable/releases/download/v4.34-9745-beta/softether-vpnserver-v4.34-9745-beta-2020.04.05-linux-x64-64bit.tar.gz
# 展開
$ tar zxvf softether-vpnserver-v4.34-9745-beta-2020.04.05-linux-x64-64bit.tar.gz
$ cd vpnserver
# ビルド
$ cd make
# 利用許諾などの確認
$ cd ..
# ファイルのコピー
$ sudo cp -r vpnserver /usr/local
$ cd /usr/local/vpnserver
# パーミッションの設定
$ sudo chmod 600 *
$ sudo chmod 700 vpncmd vpnserver

VPNサーバソフトウエアの設定

Windows や Mac から GUI によりリモート経由でサーバソフトウェアの設定を行うことができます。 ここでは、サーバ上でそのまま設定する例を紹介します。

$ cd /usr/local/vpnserver
$ sudo ./vpncmd

vpncmd が起動後にモードを尋ねられます。 VPNサーバの設定を行うため、「1」を入力します。 次に、設定するVPNサーバマシンのIPアドレスを尋ねられるため、「localhost 」を入力します。 Specify Virtual Hub Name は空欄のまま次に進みます。 すると、次のようなプロンプトとなります。

VPN Server>

ここからはコマンドを入力して設定を進めていきます。 コマンドの詳細は公式リファレンスに書いています。

ServerPasswordSet を入力し管理者パスワードを設定します。

BridgeDeviceList ローカルブリッジに利用可能なネットワークアダプタを表示します。 私の環境では eth0 が利用可能でした。

ローカルブリッジ接続を BridgeCreate コマンドで作成します。 ネットワークアダプタには eth0 を指定します。

HubList コマンドで確認できる Virtual Hub Name: DEFAULT を今回は利用します。 次のように、プロンプトの表示が変わります。

VPN Server>Hub DEFAULT
Hub command - Select Virtual Hub to Manage
The Virtual Hub "DEFAULT" has been selected.
The command completed successfully.

VPN Server/DEFAULT>

ユーザの作成(UserCreate)を行い、パスワードを設定(UserPasswordSet ユーザ名)します。

最後に SecureNatEnable コマンドで仮想 NAT を有効にします。

サーバの設定はこれで完了です。

VPNクライアントの設定

設定

SoftEther VPN Client をインストールします。

Windows での設定例です。画像の設定ファイル名が AWS EC2 になっていますが、設定内容は変わりません。

f:id:kanjirz50:20200531185349p:plain
設定例

ホスト名、ポート番号、HUB名、ユーザ名、パスワードを入力します。 使用する仮想LANカードも忘れないように選択します。 その後にOKを押すと設定完了です。

接続確認

接続先マシンが稼働していることを確認し、先ほど設定した VPN クライアントで接続します。 「接続完了」となっていることが確認できたら、IPアドレス確認サイトで確認します。 IPアドレスが変わっており、さくらVPSの IPv4 アドレスになっていれば、VPN経由でインターネットに接続できているということです。

ラズベリーパイを使って VPN ルータを作る

VPN Bridge の導入

ラズベリーパイ4 に SoftEther VPN Bridge を導入し、 VPN ルータを作成します。 ラズベリーパイ4 にした理由は、小さくて省電力であることと、近くで売っていたので、つい GeekSeek*2 で買ってしまったからです。

ルータとするため、LANポートが2つ必要となりますが、ラズベリーパイ4 には 1ポートしか搭載されていません。 そこで、家に転がっている USB-LAN ケーブルを用います。 ASIXのAX88179 系のチップだったため、ドライバ(Linux kernel 5.x/4.x/3.x/2.6.x Driver)をダウンロードします。 ビルドにカーネルヘッダーが必要であるため、 apt install raspberrypi-kernel-headers でインストールしておきます。 make && make install した後に、modprobe usbnetinsmod ax88170_178a.ko として有効にします。

次に、 SoftEther VPN Bridge をインストールします。 公式マニュアルにしたがってインストールした後に、自動起動するよう設定します。 /etc/systemd/system/vpnbridge.service に次の内容のファイルを作成します(/usr/local/vpnbridge/vpnbridge にコピーしたとする)。

[Unit]
Description=SoftEther VPN Bridge
After=network.target

[Service]
Type=forking
User=root
ExecStartPre=/sbin/ip link set dev eth0 promisc on
ExecStart=/usr/local/vpnbridge/vpnbridge start
ExecStop=/usr/local/vpnbridge/vpnbridge stop
Restart=on-abort
WorkingDirectory=/usr/local/vpnbridge

[Install]
WantedBy=multi-user.target

systemctl start vpnbridge && systemctl enable vpnbridge で起動して有効にしておきます。

VPN Bridge の設定

Windows の SoftEther VPN サーバマネージャを利用して、 VPN Bridge の設定を行います。 ブリッジを作成し、VPNサーバへの接続を確立します。 VPN 接続設定は、SoftEther VPN Client と同様の設定を行います。

ローカルブリッジ設定から、追加した USB-LAN ケーブル(今回はeth1)をブリッジするように設定します。 次のように、仮想 HUB が動作中であれば、設定完了です。

f:id:kanjirz50:20200729211714p:plain

これで USB-LAN に接続した端末からインターネットアクセスを行うと、さくらVPS の IPv4 アドレスが表示されます。

気になる安定性

有線 LAN 接続による RTT の比較を Ping test サービス を使って行いました。 上の画像が IPv4(PPPoE 経由)、下の画像は VPN(IPv6 IPoE経由) による平日の21時前の結果です。

f:id:kanjirz50:20200729211744p:plain

f:id:kanjirz50:20200729211756p:plain

グラフによって縦軸が違うためわかりにくいですが、上のグラフはブレが大きいです。左側に数値が書いていますが、 Jitter、max が大きいです。

下のグラフはVPN サーバを経由するため、最小値は 3ms ほど上昇していますが、許容範囲です。 Jitter(RTTの変動) や最大値が小さいことが IPoE 経由の特徴となり、狙っていた安定化を行うことができました。

ちなみに速度ですが、上り下りともに 80 Mbps ほど出ているので十分です。

おまけ:AWS で構築

大まかな手順を次の通りです。

  • IPv6に対応したVPCの作成
  • セキュリティグループの設定
  • EC2インスタンスの起動
  • VPNサーバソフトウェアのインストールと設定
  • VPNクライアントの設定

IPv6に対応したVPCの作成

公式ユーザガイドにしたがって設定します。

IPv6 CIDRブロックで「Amazon が提供した IPv6 CIDR ブロック」を選択することを忘れないようにしておきます。

セキュリティグループの設定

セキュリティグループは必要最低限で作成します。

インバウンドルールには、SSH用のTCPポートと、HTTPS用のTCPポートについて、IPv6の特定ソースに限定したルールを追加します。

EC2インスタンスの起動

t2.micro インスタンスを作成します。ここでは、SSH設定は言及しません。 インターネットと通信するために、パブリックIPv4アドレスを Elastic IP で割り当てます。 公式ユーザガイドにしたがって、作成した EC2 インスタンスに Elastic IP アドレスを割り当てます。

Elastic IP を割り当てるとインスタンスが停止していても費用が発生するため、使わない場合は削除します。

この後は、VPN サーバソフトウェアの設定となりますので、どの環境でも同様です。

サーバ構築は楽しい

やっぱりサーバ構築は純粋に楽しいです。 学生時代にウキウキで研究室のサーバを設定していた頃を思い出しました。 その上、安定した接続が得られて満足です。

執筆者プロフィール

高橋寛治 Sansan株式会社 DSOC (Data Strategy & Operation Center) 研究開発部 研究員

阿南工業高等専門学校卒業後に、長岡技術科学大学に編入学。同大学大学院電気電子情報工学専攻修了。在学中は、自然言語処理の研究に取り組み、解析ツールの開発や機械翻訳に関連する研究を行う。大学院を卒業後、2017年にSansan株式会社に入社。キーワード抽出など自然言語処理を生かした研究開発に取り組む。

▼本連載のほかの記事はこちら

buildersbox.corp-sansan.com

*1:信号を送って返ってくるまでの時間のこと。ping 値と言われることが多いが、ping とはツールのこと。

*2:新しいガジェットやサービスに触れることで、プロダクトに活きてくるものも対象となる技術力向上のための購入支援制度です。詳しくはこちら

© Sansan, Inc.