SoftEther + Raspberry Pi + VPS でどこでも自宅に L2 接続

# はじめに

出先から自宅内のファイルサーバ等にアクセスしたいことがある。そこで [SoftEther VPN](https://ja.softether.org/) を使って、宿泊先ホテル等のインターネット回線から自宅のネットワークに VPN で L2 接続できる装置を作ってみる。

![raspberrypi.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104866/bf12dcc5-6dc4-1c98-95ea-87537f33b5af.jpeg)

この装置の片方の NIC をインターネットにつなぐと、もう片方の NIC から自宅の LAN が L2 で取り出せるようにする。

# 構成図

![network.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104866/5548d461-c524-7b9f-3bcb-a1da853dc2b6.png)

# SoftEther VPN とは

> SoftEther VPN はオープンソースの、無償で、複数プラットフォームおよび複数 VPN プロトコル対応の VPN ソフトウェアであり、Apache License 2.0 で提供され、筑波大学における研究プロジェクトとして運営されています。

([SoftEther VPN プロジェクト](https://ja.softether.org/) から引用)

# 用意するもの

- Raspberry Pi 3 Model B+
- USB - 有線 LAN アダプタ (今回は Buffalo の LUA4-U3-AGT を使用)
- グローバル IP アドレスが割り当てられる VPS
- EtherIP か L2TPv3 が喋れる L3 スイッチ (今回は NEC の IX2105 を使用)

# 構築手順

## 各種パラメータ

以降の手順で使用する各種パラメータは下記のとおり。環境に応じて適宜読み替えて実施すること。

|パラメータ名|値|
|---|---|
|VPN Server のホスト名|vpn.example.com|
|VPN Server のポート番号|443|
|VPN Server の仮想 HUB 名|VPN1|
|VPN Client の仮想 NIC 名|tun1|
|IPsec 事前共有鍵|vpn|
|ISAKMP Phase1 ID|IX|

※ 実際には事前共有鍵や Phase1 ID はもっと複雑な文字列にした方が良い。

## SoftEther VPN Server の構築

Ubuntu 18.04.2 LTS を入れた VPS 上に、自宅〜出先間の仮想的なハブとなる SoftEther VPN Server を構築する。

まず必要なパッケージをインストールする。

```
$ sudo apt update
$ sudo apt install -y gcc make libssl-dev libreadline-dev libncurses5-dev bridge-utils
```

[SoftEther ダウンロードページ](https://ja.softether.org/5-download)から Server のソースコードをダウンロードしてきて make する。その際、ライセンスに同意するか聞かれるので、同意する場合は「1」を3回入力する。

```
$ mkdir -p src
$ cd src
$ curl -O https://github.com/SoftEtherVPN/SoftEtherVPN_Stable/releases/download/v4.30-9696-beta/softether-vpnserver-v4.30-9696-beta-2019.07.08-linux-x64-64bit.tar.gz
$ tar xvzf softether-vpnserver-*-linux-x64-64bit.tar.gz
$ cd vpnserver
$ make
```

ビルドしたファイル群を `/usr/local` ディレクトリにコピーする。

```
$ cd ..
$ sudo cp -pr vpnserver /usr/local/
```

systemd の設定ファイルを作成する。

```/etc/systemd/system/vpnserver.service
[Unit]
Description=Softether VPN Server Service
After=network.target

[Service]
Type=forking
User=root
ExecStart=/usr/local/vpnserver/vpnserver start
ExecStop=/usr/local/vpnserver/vpnserver stop
Restart=always

[Install]
WantedBy=multi-user.target
```

vpnserver を起動する。

```
$ sudo systemctl daemon-reload
$ sudo systemctl start vpnserver
```

OS が再起動したときに、vpnserver が自動起動するようにしておく。

```
$ sudo systemctl enable vpnserver
```

これで SoftEther VPN Server が使えるようになる。

## SoftEther VPN Server の設定

管理用の端末から、SoftEther VPN Server の設定をする。

[SoftEther ダウンロードページ](https://ja.softether.org/5-download)から管理ツールをダウンロードしてくる。今回は Mac を使うので「Manager for Mac OS X」を使用する。

<img width="481" alt="manager01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104866/18ff4ca8-ba49-e74c-85e1-2f5d24ff94ee.png">

初回接続すると、セットアップウィザードが表示される。設定方法は下記のとおり。

- [VPN サーバー管理マネージャ](https://ja.softether.org/4-docs/1-manual/2._SoftEther_VPN_%E5%85%A8%E8%88%AC%E3%83%9E%E3%83%8B%E3%83%A5%E3%82%A2%E3%83%AB/2.4_VPN_%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E7%AE%A1%E7%90%86%E3%83%9E%E3%83%8D%E3%83%BC%E3%82%B8%E3%83%A3)

セットアップが済んだら、以下の設定を済ませる。

- 仮想ハブの設定
- 仮想ハブにユーザの設定
- L2TP の設定

なお特定の接続元 IP アドレスからしか管理マネージャで接続できないようにするには、VPN Server に設定ファイル `/usr/local/vpnserver/adminip.txt` を作成して、接続を許可する IP アドレスを記載する。

```/usr/local/vpnserver/adminip.txt
172.16.0.20
203.0.113.1
```

## 自宅の IX2105 から SoftEther VPN Server に接続

次に自宅のスイッチ NEC IX2105 から、VPS 上の SoftEther VPN Server に「EtherIP」(Ethernet over IP) というプロトコルで接続する。基本的に下記のページに書かれている手順のとおり。

- [NEC ルータ等からの EtherIP を用いた VPN 接続方法](https://ja.softether.org/4-docs/2-howto/Other_VPN_Appliance_Setup_Guide/7)
- [Ethernet over IP 機能に関する FAQ](https://jpn.nec.com/univerge/ix/faq/etherip.html)

主要な設定抜粋。

```
ip access-list any-permit permit ip src any dest any
!
ike proposal vpn1ikeprop encryption aes hash sha group 1024-bit lifetime 3600
!
ike policy vpn1ikepolicy peer-fqdn-ipv4 vpn.example.com key vpn mode aggressive vpn1ikeprop
ike local-id vpn1ikepolicy keyid IX
!
ipsec autokey-proposal vpn1secprop esp-aes esp-sha lifetime time 3600
!
ipsec autokey-map vpn1secpolicy any-permit peer-fqdn-ipv4 vpn.example.com vpn1secprop
!
interface Tunnel1.0
  tunnel mode ether-ip ipsec
  no ip address
  ipsec policy tunnel vpn1secpolicy out
  bridge-group 1
  no shutdown
```

## Raspberry Pi から SoftEther VPN Server に接続

Raspberry Pi から VPN Server に SoftEther プロトコルで接続するために、SoftEther VPN Client をインストールする。

まず有線 LAN アダプタを Raspberry Pi に接続する。うまくいけば eth1 として認識する。Raspberry Pi にもともとある NIC は、DHCP で IP アドレスが降ってきてインターネットに出られるブロードバンドルータ等に接続する。

必要なパッケージをインストールする。

```
$ sudo apt update
$ sudo apt install -y gcc make libssl-dev bridge-utils
```

仮想ブリッジ br1 を作成し、eth1 を接続する。

```/etc/network/interfaces.d/br1
auto br1
iface br1 inet manual
    bridge_ports eth1
    bridge_maxwait 10
```

内側用 NIC とブリッジでは DHCP クライアント機能を無効にする。

```
$ echo "denyinterfaces eth1 br1 vpn_tun1" | sudo tee -a /etc/dhcpcd.conf
```

一旦再起動する。

```
$ sudo reboot
```

仮想ブリッジの接続状況は下記のコマンドで確認できる。

```
$ brctl show
```

[SoftEther ダウンロードページ](https://ja.softether.org/5-download)から Client のソースコードをダウンロードしてきて make する。Server と同様に、ライセンスに同意するか聞かれるので、同意する場合は「1」を3回入力する。

```
$ mkdir -p src
$ cd src
$ curl -O https://github.com/SoftEtherVPN/SoftEtherVPN_Stable/releases/download/v4.30-9696-beta/softether-vpnclient-v4.30-9696-beta-2019.07.08-linux-arm_eabi-32bit.tar.gz
$ tar xvzf softether-vpnclient-*-linux-arm_eabi-32bit.tar.gz
$ cd vpnclient
$ make
```

ビルドしたファイル群を `/usr/local` ディレクトリにコピーする。

```
$ cd ..
$ sudo cp -pr vpnclient /usr/local/
```

仮想 NIC を作成する。

```
$ sudo /usr/local/vpnclient/vpncmd /client localhost /cmd \
    NicCreate tun1
$ sudo /usr/local/vpnclient/vpncmd /client localhost /cmd \
    NicEnable tun1
```

接続情報を設定する。
※ サーバ名やユーザ名、パスワード等は適宜読み替えること

```
$ sudo /usr/local/vpnclient/vpncmd /client localhost /cmd \
    AccountCreate VPN1 \
    /SERVER:vpn.example.com:443 \
    /HUB:HUB1 \
    /USERNAME:user1 \
    /NICNAME:tun1
$ sudo /usr/local/vpnclient/vpncmd /client localhost /cmd \
    AccountPasswordSet VPN1 \
    /PASSWORD:hogehoge \
    /TYPE:standard
```

systemd の設定ファイルを作成する。

```/etc/systemd/system/vpnclient.service
[Unit]
Description=Softether VPN Client Service
After=network.target

[Service]
Type=forking
User=root
ExecStart=/usr/local/vpnclient/vpnclient start
ExecStop=/usr/local/vpnclient/vpnclient stop
Restart=on-abort
WorkingDirectory=/usr/local/vpnclient
ExecStartPost=/bin/bash -c "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/vpnclient && sleep 1 && vpncmd /client localhost /cmd AccountConnect VPN1 && brctl addif br1 vpn_tun1"

[Install]
WantedBy=multi-user.target
```

※ `ExecStartPost` の部分は改善の余地があると思う。

vpnclient を起動する。

```
$ sudo systemctl daemon-reload
$ sudo systemctl start vpnclient
```

OS が再起動したときに、vpnserver が自動起動するようにしておく。

```
$ sudo systemctl enable vpnclient
```

VPN の接続状況は下記のコマンドで確認できる。

```
$ sudo /usr/local/vpnclient/vpncmd /client localhost /cmd \
    AccountStatusGet VPN1
```

# 完成

Raspberry Pi に挿した有線 LAN アダプタに適当な機器を接続すると、SoftEther VPN Server を介して、IX2105 側の LAN に L2 でつながる。