【備忘録】Tinker Board SをSoftEther VPNを入れてVPNサーバーにする

クリーンインストールし直すたびにやり方を忘れるので手順を自分用にメモ。

発売当初はRaspberry Pi 3より高性能で実用的だったTinker Board。後継機も出て久しい2023年にもなるとサーバー用途のSBCとしてはやや見劣りするけど、まだまだ使えると信じる。

TODO 参考文献の整理

# Tinker BoardにOSをインストールする

インストールはWindowsで、最新のOSのzipをダウンロードしてEtcherでmicroSDカードに書き込むだけ。Tinker Board SはeMMC搭載でこちらにもOSをインストール出来るけど、めんどいのでSDカードで。

執筆時点でのTinker Board Sの最新Linux OSは`Tinker Board S Debian 10 V3.0.11`。

https://tinker-board.asus.com/jp/index.html

https://www.balena.io/etcher/

# 初期セットアップ

ディスプレイとキーボードを繋いで直接操作する。

TinkerOSには`ssh`がインストール済みなので最初からSSH接続でもいいはず。ちなみにデフォルトのホスト名は`linaro-alip`（Debian 10の場合。Debian 9は`tinkerboard`）

## 前準備

### アップデートチェック

おまじない

```terminal
$ sudo apt upadate
$ sudo apt upgrade
```

### CLI化

サーバー用途なのでGUI→CLIモードで起動するように変更。

`lightdm`とかGUI関連の不要なパッケージも削除したほうがいいと思うけどとりあえずこれだけ。

```terminal
$ sudo systemctl set-default multi-user.target
```

<!--
### 不要なパッケージ削除（任意）

※ OMVも使いたいので

```
$ sudo apt purge --autoremove gdm3 sddm lxdm xdm lightdm* slim wdm
```
-->

### タイムゾーン設定（任意）

```terminal
$ timedatectl set-timezone Asia/Tokyo
```


## IPアドレスの固定、ブリッジ設定

`/etc/network/interfaces`を編集し、IPアドレスを固定する。

ブリッジを使いたいので先に`bridge-utils`をインストールする。

```terminal
$ sudo apt install bridge-utils
```

`br0`の設定を行い、IPアドレスを固定する。

```terminal
$ sudo vi /etc/network/interfaces
```

```sh
# interfaces(5) file used by ifup(8) and ifdown(8)
# Include files from /etc/network/interfaces.d:
source-directory /etc/network/interfaces.d

#ここから追記
# loopback
auto lo
iface lo inet loopback

# Ethernet port
auto eth0
iface eth0 inet manual

# Bridge interface
auto br0
iface br0 inet static
    address 192.168.10.3   #IPアドレス
    netmask 255.255.255.0  #ネットマスク
    gateway 192.168.10.1   #デフォルトゲートウェイ
    bridge_ports eth0

#その他
allow-hotplug wlan0
iface wlan0 inet manual
wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf
iface default inet dhcp
```

※ IPアドレスは環境によって適時合わせる。

（「その他」はなんで設定したのか忘れた……要らんかも）

再起動してIPアドレスが固定されているか確認

```console
$ sudo reboot
```

```console
$ sudo ifconfig
```

# ポートフォワード（ルーターの設定）

UDPの500, 4500, 1194(OpenVPNを使う場合）を固定したTinker BoardのIPアドレスに対しマッピングし、外部から接続できるようにしておく。

# SoftEther VPN ServerをTinker Boardにインストールする

## ダウンロードからインストールまで

Linux ARM EABI (32bit)のtar.gzをダウンロードする（※Tinker BoardのRockchip RK3288はARMv7-Aの32bit CPU）

アーカイブを展開すると`vpnserver`というディレクトリができるので中に入って`make`する。`vpnserver`ディレクトリごと`/usr/local`に配置してパーミッションを設定する。このとき、所有権を`root`にしてrootで実行するようにしておかないとローカルブリッジ機能が使えないらしい。

SoftEther VPN Serverをアップデートするときも同じ操作で上書きインストールでOK。

![20230111030812.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3093744/4acf3865-9510-bf45-ed1c-8c975b62443b.png)

[公式ドキュメント](https://ja.softether.org/4-docs/1-manual/7/7.3 "7.3 Linux へのインストールと初期設定")通りだけど、一応コマンドだけ。URLは適時変更。

```terminal
$ cd Downloads
$ wget https://github.com/SoftEtherVPN/SoftEtherVPN_Stable/releases/download/v4.41-9782-beta/softether-vpnserver-v4.41-9782-beta-2022.11.17-linux-arm_eabi-32bit.tar.gz
$ tar xzvf softether-vpnserver-v4.41-9782-beta-2022.11.17-linux-arm_eabi-32bit.tar.gz
$ cd vpnserver/
$ make
$ cd ..
$ sudo mv vpnserver /usr/local
$ sudo su -
# chown -R root:root /usr/local/vpnserver/
# cd /usr/local/vpnserver/
# chmod 600 *
# chmod 700 vpncmd
# chmod 700 vpnserver
```

## サービスの登録

起動スクリプトを作成してvpnserverがTinker Board起動時に自動起動するようにする。

起動スクリプト`/etc/init.d/vpnserver`の内容は公式ドキュメントではなく下記のブログからコピってきたほうが良さげ

```console
# vi /etc/init.d/vpnserver
```
<!--
```sh
\#!/bin/sh
### BEGIN INIT INFO
# Provides:                 vpnserver
# Required-Start:           $local_fs $network
# Required-Stop:            $local_fs $network
# Default-Start:            2 3 4 5
# Default-Stop:             0 1 6
# Short-Description:        SoftEther VPN RTM
# Description:              Start vpnserver daemon SoftEther VPN Server
### END INIT INFO

DAEMON=/usr/local/vpnserver/vpnserver
LOCK=/var/lock/vpnserver

# tun/tapモジュールのロード
sudo modprobe tun

. /lib/lsb/init-functions
test -x $DAEMON || exit 0

case "$1" in
start)
sleep 3
log_daemon_msg "Starting SoftEther VPN Server" "vpnserver"
$DAEMON start >/dev/null 2>&1
touch $LOCK
log_end_msg 0
sleep 3

# SoftEther VPNで追加した仮想tapデバイス名を調べる
tap=`/sbin/ifconfig -a| awk '$1 ~ /^tap/ {print $1}'`
/sbin/brctl addif br0 $tap
;;

stop)
log_daemon_msg "Stopping SoftEther VPN Server" "vpnserver"
$DAEMON stop >/dev/null 2>&1
rm $LOCK
log_end_msg 0
sleep 2
;;

restart)
$DAEMON stop
sleep 2

$DAEMON start
sleep 5
# SoftEther VPNで追加した仮想tapデバイス名を調べる
tap=`/sbin/ifconfig -a| awk '$1 ~ /^tap/ {print $1}'`
/sbin/brctl addif br0 $tap
;;

status)
    if [ -e $LOCK ]
    then
        echo "vpnserver is running."
    else
        echo "vpnserver is not running."
    fi
;;
*)

echo "Usage: $0 {start|stop|restart|status}"
exit 1
esac
exit 0
```
-->
https://blog.bnikka.com/raspberrypi/softethervpn.html

※ 公式ドキュメントの起動スクリプトは`chkconfig`を使うことを前提としている。 まずこの部分を`insserv`で設定出来るように[LSB記法](https://wiki.debian.org/LSBInitScripts "LSBInitScripts")にする。ローカルブリッジの利用に必要な処理も記述。SoftEther VPN側で作ったtun/tapモジュールを認識できるようになっているらしい。よく分からん。

スクリプトファイルを作成して権限を設定したら以下の通りに登録する。
rkisp_3A.shがどうとかいくつか警告が出るけどvpnserverには関係ないので無視。


```terminal
# chmod 755 /etc/init.d/vpnserver
# insserv -d vpnserver
```

登録できたことを確認する

```terminal
# systemctl is-enabled vpnserver.service
vpnserver.service is not a native service, redirecting to systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install is-enabled vpnserver
enabled
```

Tinker Boardを再起動してサービスが自動起動することを確認する

```terminal
# sudo reboot
```

```terminal
$ systemctl status vpnserver.service | cat
```

```
● vpnserver.service - LSB: SoftEther VPN RTM
   Loaded: loaded (/etc/init.d/vpnserver; generated)
   Active: active (running) since Mon 2023-01-09 16:49:37 JST; 27s ago
```

Active: active (running)... となるはず。

# SoftEther VPNのインストール（Windows）

VPNサーバーの管理はWindowsやMac OS向けの管理ツールを使ったほうが圧倒的に楽なのでインストールする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3093744/a1e188ec-7ac7-cb8a-e982-83d216120de3.png)

説明省略

# VPNサーバーの設定（管理ツール経由）

説明省略

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3093744/9b922ae1-ef1d-58d1-4d6f-e6877aef2136.png)

## ローカルブリッジの設定

ローカルブリッジが最初からある場合は「ローカルブリッジの削除(D)」で削除する。

「新しい tap デバイスとのブリッジ接続(T)」を選択し、「新しい tap デバイス名(V)」に適当な名前を入力し、「ローカルブリッジを追加(A)」を押下する。

![20230111024816.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3093744/9f3aeb96-182c-31c2-68dc-1060b4f1f83f.png)

![20230111024912.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3093744/0d64530e-94b0-f600-fb28-b37205a31fc7.png)

Tinker Boardを再起動し、`ifconfig`でローカルブリッジ(tap_vlan)が一覧に出てくることを確認する。

```console
$ sudo ifconfig
```

## ユーザーの追加とか

サーバー管理画面にて「仮想HUBの管理(A)」を押下。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3093744/b132fdf9-b3f5-a02f-7c0c-7f7ff2677580.png)

「新規作成」でユーザーを追加する。ユーザーはパスワード認証にする（証明書認証と外部サーバー認証はオープンソース版SoftEther VPNでは使用不可）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3093744/b7b974ea-6a13-4759-017d-18c91a21c25e.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3093744/fcdc2a70-3a0d-7821-1578-1d088158e096.png)

## L2TP/IPsec

L2TP/IPsec接続を使いたい場合、「L2TP サーバー機能を有効にする (L2TP over IPsec)」にチェックする。事前共有鍵に任意の文字列を設定しておく。

Android 12以降はL2TP/IPsecが使えないので、Android 12以降でしか使わないのであればこの設定は不要。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3093744/ae7df03b-0ebc-3eb2-594c-2f13896cb4f1.png)


## OpenVPN設定

Android 12以降で使いたい場合、こちらを使う（2023年1月現在。IKEv2がSoftEther VPNで使えるようになればまた変わってくるかもね）

サーバー管理画面から「OpenVPN / MS-SSTP 設定」ボタンを押下して設定画面を開き「OpenVPN サーバー機能を有効にする」をチェック。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3093744/40d6bfde-3d82-844a-4760-66da80bebf2e.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3093744/1483930b-ecb7-f2bb-6b7c-ba855c8220a5.png)

### OpenVPNクライアント用 設定ファイルの作成

「OpenVPN クライアント用のサンプル設定ファイルを生成(C)」をクリックし、zipファイルを保存する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3093744/254d913f-d3fc-b386-de74-5f88bf6e86a5.png)

zipファイル内にある「～access_l3.ovpn」がOpenVPNの設定ファイルになるので、Androidで使えるようにGoogleドライブなどに保存しておく。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3093744/6c34e7e6-a008-2538-5924-52edab5a1581.png)

### OpenVPNインストール・設定（Android）

Playストアからクライアントアプリをダウンロードしてインストール

https://play.google.com/store/apps/details?id=net.openvpn.openvpn

作成した設定ファイルを読み込ませる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3093744/7cb02a79-11ca-d93c-cc41-512ea1d84650.png)

ユーザー名を入力。Save passwordでパスワードを保存しておくとパスワード入力の手間が省ける。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3093744/39006e60-aa83-560b-e1ba-7f75abd71e56.png)

接続を試みるとクライアント証明書を要求するダイアログが出るが、気にせず「CONTINUE」を押す。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3093744/b74ad504-ec89-87f6-d5dc-5e23f3bbff78.png)


無事接続できたら成功。お疲れ様でした、未来の自分

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3093744/d43ff7d9-16d2-1721-f2b1-4ccae8ad2000.png)


## クライアント証明書を要求される件について

ただのパスワード認証で証明書は不要だが、そんなのお構いなしに接続するたびクライアント証明書を要求してくる。設定ファイルのどこかが間違っているのだろうか。この辺りはおいおい調べていく。

証明書無しのまま「CONTINUE」を押しても普通に接続できるので特に問題はないが、接続時にいちいちメッセージが出てきて鬱陶しい。

仮の対策として、適当にルート証明書を発行して設定ファイルの中に書いておくことで抑制することにした。他に方法があるなら知りたい。

### ルート証明書の発行

管理マネージャのトップ画面から「証明書作成ツール(R)」をクリック。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3093744/3a3d9050-3f01-9f86-a667-d040081e0b77.png)

名前を入力して「OK」で次へ進む。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3093744/5e5d5e07-119c-342e-e603-d7cf3e267387.png)

「X509証明書ファイル(.CER)と秘密鍵ファイル(.KEY)の組み合わせとして保存する(X)」をクリックして「OK」

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3093744/516ec2ec-824d-f6ce-e3c2-752e534f5aa7.png)

.cerファイルと.keyファイルを保存する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3093744/4b4a4464-ec82-c45f-38b9-9d7c53564ce3.png)

先程の「～access_l3.ovpn」ファイルの末尾に記述欄があるので、コメントアウト`;`を削除した上で、.cerファイルの中身と.keyファイルの中身をコピペしてきて.ovpnファイルを保存する。

```
###############################################################################
# Client certificate and key.
# 
# A pair of client certificate and private key is required in case you want to
# use the certificate authentication.
# 
# To enable it, uncomment the lines below.
# Paste your certificate in the <cert> block and the key in the <key> one.

<cert>
-----BEGIN CERTIFICATE-----
（cerファイルの中身）
-----END CERTIFICATE-----
</cert>

<key>
-----BEGIN RSA PRIVATE KEY-----
（keyファイルの中身）
-----END RSA PRIVATE KEY-----
</key>
```

OpenVPNクライアントでプロファイルを設定し直して再接続。


# その他

TODO Tinker BoardのSSHを公開鍵認証するように変更するとかやっておいたほうがいいかもね