softetherのちょっとしたセキュリティ向上設定

# はじめに

[Softether VPN](https://ja.softether.org/)は手軽でL2VPNを構築できるオープンソースのソフトウェアである。
手軽とは言え、デフォルトのままではセキュリティレベルが低いままになっている箇所が存在するので、気づいたところをつぶしていこうと思う。

Softether VPNの特徴は、なんといっても、OS上に仮想のNICやHUBを構築し、リモート接続、端末間、他拠点間のVPNを簡単に構築できる点にある。対応OSは、windowsやmac、linux、solarisと多岐にわたるが、管理するにはmacやWindowsのアプリが必要となる。

# 動作環境
- utuntu 18.04.2 (64bit)
- Softether VPN Server 4.29 Build 9680

# Softetherの基本的な考え方

Softetherは用途に応じて、Softether VPN Server、Softether VPN Client、Softether VPN Bridgeの3種類のコンポーネントがある。それ以外には、VPN Server を管理するためのサーバ管理マネージャなどがある。

VPN Serverは、Softetherを利用する上で必ずインストールが必要になるもので、最低一つの仮想HUBを作成する。仮想HUBは複数自由に作成できる。仮想HUB毎に、VPN ClientやVPN Bridgeの接続ユーザの認証情報を個別に管理するのが特徴。

VPN Client は主に端末向けのコンポーネントで、遠隔から仮想HUBに接続するためのツールとなる。

VPN Bridge は、主にローカルネットワークに接続されたルーティング機能を持つ所謂支店のサーバ向けで、仮想HUBにカスケード接続が可能なコンポーネントとなる。

私は、自宅と実家のそれぞれに設置したlinuxサーバにVPN Server をインストールして、仮想HUB同士をカスケード接続して利用しているので、ここからは VPN Serverに特化した話になる。

では、さっそく見直しポイントを見てみよう。

# リスナーポートの限定

サーバ管理マネージャを立ち上げると「リスナーの管理」の項目が目に付く。
ここは、サーバ管理マネージャがVPN Serverに接続するポート番号、および、仮想HUBのカスケード接続に使わるポート番号となるようだ。

![fig1.png](https://qiita-image-store.s3.amazonaws.com/0/287776/d2c6a58d-5a5a-25dd-f6bb-f36f4dab0015.png)

初期状態では、443 992 1194 5555の4つのポートが登録されているが、疎通に問題がなければ 5555 などの well-known port以外のポートを一つ選択したほうがよいと思う。（好きなポート番号に変えるほうがもっと安全）

# サーバ管理マネージャの接続端末の限定

初期状態では、VPN Server はサーバ管理マネージャのすべての接続を受け付ける設定となる。

これは、意識しないでいると、VPN Server のカスケード接続を受け付けるために、ブロードバンドルータにポートフォワードの設定を入れたはいいが、実はインターネットからサーバ管理マネージャへの接続がそのまま許可されていた・・・なんてことになってしまう。（本当に接続できるのか検証したわけではないが・・）

他拠点となる実家は、当然動的IPアドレス割り当てなので、ブロードバンドルータにFWとしてルールを登録するわけにもいかない。さてどうしようか。

当然、管理者パスワードでの認証は必要になるわけだが、昨今、パスワード認証をインターネット上に公開するのは、安心して夜も眠れない。

ということで、どうせ自宅のLANからしかサーバ管理マネージャは起動しないわけなので、接続元IPアドレスの制限をかける。

[Softether VPN Server マニュアル](https://ja.softether.org/4-docs/1-manual/3/3.3)の「3.3.18 IP アドレスによるリモート管理接続元の制限」に記載があるとおり、`vpnserver` ディレクトリ(`vpnserver`の実行ファイルがあるディレクトリ)に接続元IPアドレスもしくはネットワークを記載した、`adminip.txt` を設置する。設置するとすぐに有効になる。

```text:vpnserver/adminip.txt
127.0.0.0/8
192.168.0.0/16
172.16.0.0/12
10.0.0.0/8
```
 
# 仮想HUBのカスケード接続の暗号化アルゴリズムの変更

カスケード接続される側(サーバ側)のサーバ管理マネージャ画面で「暗号化と通信関係の設定」を開き、
「使用する暗号化アルゴリズム」のフォームで暗号化アルゴリズムを変更して強度を高める。
ここでは、「AES256-SHA256」を選択した。

![fig2.png](https://qiita-image-store.s3.amazonaws.com/0/287776/22fb361f-749b-7f9b-858a-0ff6ffa3ed9a.png)

# ユーザ認証で署名済み証明書認証を有効にする

ユーザ認証ではいくつかの認証方式を選択できるが、「署名済み証明書認証」を選択すると、以下のメッセージが表示され、とても悲しくなる。

![fig3.png](https://qiita-image-store.s3.amazonaws.com/0/287776/bf419db9-d87b-4501-ccac-16aa53c495f3.png)

しかしSoftether自体が無料だから仕方がないとあきらめようかとしたところ、VPN Serverのパッチを当てて再ビルドで有効にすることができるとの情報があったので、さっそくトライしてみる。(VPN Client/VPN Bridge側の再ビルドは不要である。)

下の記事によると、どうやら利権がらみで、機能が無効化されているようだ。特定の国向けに機能が無効化されているようなので、もしかすると、VPN Server が起動している環境変数`LANG=C`とかすることにより機能が有効になるかもしれないが、ここは再ビルドする。（自己責任で）

[SoftEther のリージョンロックを外して RADIUS や証明書認証を有効にする](https://blog.cles.jp/item/9524)
[固有証明書認証について - SoftEther VPN User Forum](https://www.vpnusers.com/viewtopic.php?t=4223)

## softether の再ビルド

[Softether ソースコード](https://ja.softether.org/5-download/src)

> (余談)
> 上記URLに記載されているが、2019/01/21よりSoftetherのライセンス形態がGPLv2からApache License 2.0に変更になったそうだ。
> 機能制限にどのような影響を及ぼすかわからないが、softetherとしては益々の発展が望めるのではないかと期待する。

すでにインストールしてあるRTM版softetherの同バージョンのソースコード(Source Code)を取得する。
[Git Hub (SoftEtherVPN_Stable)](https://github.com/SoftEtherVPN/SoftEtherVPN_Stable/releases)

```terminal:ビルドに必要なパッケージのインストール
$ sudo apt install build-essential
$ sudo apt install libreadline-dev libssl-dev libncurses-dev libz-dev
```

```terminal:softetherの再ビルド
$ wget https://github.com/SoftEtherVPN/SoftEtherVPN_Stable/archive/v4.29-9680-rtm.tar.gz
$ tar zxvf v4.29-9680-rtm.tar.gz
$ cd SoftEtherVPN_Stable-4.29-9680-rtm
```

ここで制限解除の修正をする。

```diff:diff&nbsp;-up&nbsp;src/Cedar/Server.c.orig&nbsp;src/Cedar/Server.c
--- src/Cedar/Server.c.orig     2019-02-28 20:13:45.000000000 +0900
+++ src/Cedar/Server.c  2019-03-24 05:44:02.344012456 +0900
@@ -10854,7 +10854,7 @@ bool SiIsEnterpriseFunctionsRestrictedOn

        if (StrCmpi(region, "JP") == 0 || StrCmpi(region, "CN") == 0)
        {
-               ret = true;
+//             ret = true;
        }

        return ret;
```

ビルドする。

```
$ ./configure
$ make
```

ここで、置き換えに必要なファイルが出来上がったので、置き換え前にvpnserverのバックアップをしておく。
(vpnserverのサービスとして登録、インストール先は `/usr/local/vpnserver` としている。)

```terminal:softetherのバックアップ
$ sudo su -
# systemctl stop vpnserver
# cd /usr/local
# cp -rp vpnserver vpnserver.bak
```

以下、置き換え方法は2種類ある。

1. 実行バイナリを置き換える方法。(簡単)
1. 共有ライブラリを置き換え再リンクして置き換える方法。(手間がかかる)

### 方法1 実行バイナリを置き換える方法(簡単)

実行バイナリと`hamcore.se2`をコピーするだけである。
間違えて、RTM版vpnserverを`make`すると、実行バイナリが上書きされてしまうので注意が必要である。
(方法2を実践すれば問題ない)

```terminal:実行ファイルの置き換え
$ sudo su -
# cd (vpnserverをビルドした場所)/SoftEtherVPN_Stable-4.29-9680-rtm
# cp -rp bin/vpnserver/vpnserver /usr/local/vpnserver/
# cp -rp bin/vpncmd/vpncmd /usr/local/vpnserver/
# cp -rp bin/vpncmd/hamcore.se2 /usr/local/vpnserver/
# systemctl start vpnserver
```

### 方法2 共有ライブラリを置き換え再リンクして置き換える方法(手間がかかる)

**2019/03/24内容修正しました**

RTM版vpnserverは、別パッケージの利用ライブラリを付属して配布しており、ライセンスの都合上、ユーザでの明示的なリンク(ビルド)をさせている(詳しくは`lib/License.txt`に記載がある)。調べてみると、この利用ライブラリは、とても古く、精神衛生上気持ちいいものではない。

色々検討した結果、RTM版vpnserverと同等な形式で、かつ、バイナリをスマートに差し替えるには、Makefileの修正が一番早かったため、それを実践する。

RTM版vpnserverのMakefileを修正する。

```diff:diff&nbsp;-up&nbsp;Makefile.orig&nbsp;Makefile
--- Makefile.orig       2019-03-24 04:21:24.946774797 +0900
+++ Makefile    2019-03-24 19:01:07.428996308 +0900
@@ -14,7 +14,7 @@ else
        NO_PIE_OPTION=
 endif

-OPTIONS=$(NO_PIE_OPTION) -O2 -fsigned-char -pthread -m64 -lm -ldl -lrt -lpthread -L./ lib/libssl.a lib/libcrypto.a lib/libiconv.a lib/libcharset.a lib/libedit.a lib/libncurses.a lib/libz.a lib/libintelaes.a
+OPTIONS=$(NO_PIE_OPTION) -O2 -fsigned-char -pthread -m64 -lm -ldl -lrt -lpthread -lssl -lcrypto -lreadline -lncurses -lz

 default:
        @./.install.sh
@@ -25,14 +25,6 @@ default:

 i_read_and_agree_the_license_agreement:
        @echo "Preparing SoftEther VPN Server..."
-       -ranlib lib/libcharset.a
-       -ranlib lib/libcrypto.a
-       -ranlib lib/libedit.a
-       -ranlib lib/libiconv.a
-       -ranlib lib/libintelaes.a
-       -ranlib lib/libncurses.a
-       -ranlib lib/libssl.a
-       -ranlib lib/libz.a
        -ranlib code/vpnserver.a
        $(CC) code/vpnserver.a $(OPTIONS) -o vpnserver
        -ranlib code/vpncmd.a
```

修正したRTM版vpnserverを再ビルドする。

```terminal:ライブラリの置き換え
$ sudo su -
# cd (vpnserverをビルドした場所)/SoftEtherVPN_Stable-4.29-9680-rtm/
# cp -rp tmp/as/vpnserver.a /usr/local/vpnserver/code
# cp -rp tmp/as/vpncmd.a /usr/local/vpnserver/code
# cp -rp bin/vpncmd/hamcore.se2 /usr/local/vpnserver/
# cd /usr/local/vpnserver/
# make
# systemctl start vpnserver
```

## 署名済み証明書認証のユーザを作成する

機能制限を解除できたので、署名済み証明書認証のユーザを作成してみる。
仮想HUBの管理からユーザの管理を開き、新規作成する。
![fig4.png](https://qiita-image-store.s3.amazonaws.com/0/287776/bf28003d-3c44-092f-1c85-418d0e5ea732.png)
![fig5.png](https://qiita-image-store.s3.amazonaws.com/0/287776/ff7e40a2-fc40-8ddb-4e9e-c64067db82b9.png)
![fig6.png](https://qiita-image-store.s3.amazonaws.com/0/287776/6783fd46-5120-9832-4cb7-abf89880d67b.png)
![fig7.png](https://qiita-image-store.s3.amazonaws.com/0/287776/a9e54936-d098-05b9-d560-aba74f42b8cc.png)

これで、無事に署名済み証明書認証のユーザが作成できた。

すでにパスワード認証を行っているユーザがいるならば、すべて署名済み証明書認証に切り替えることにより、リスクが軽減できるはずである。

証明書の発行自体は、softetherの証明書発行ツールから行うことができる。証明書の各種設定方法は、他の方の記事に譲ることとする。

証明書によるクライアント認証は、とても煩雑ではあるが、パスワード認証よりは安心感があるのは間違いがない。