Softether VPNのおうちサーバーを建てた話

Dockerはまだ私には早かった。

概要

できたこと

  • リージョンロックの解除
  • 独自ドメインでサーバーにアクセス
  • Let’s Encryptの設定(とMS-SSTPでの接続)
  • ゲスト用HUBの作成と、ローカルへの疎通の遮断
  • その他最適化

できなかったこと

  • SoftetherをDocker+macvlanで動かす
  • CertbotをDocker内で動かす

環境

Dell OptiPlex 7060 Micro
i5 8500T
RAM:8GB

Ubuntu Server 22.4.3

できたこと

使ったバッチファイルとかなんやらはここにまとめてあります。適当にwgetして使ってください。

Softetherをセットアップするやつ(Ubuntu Server 22.04用)
Softetherをセットアップするやつ(Ubuntu Server 22.04用). GitHub Gist: instantly share code, notes, and snippets.

リージョンロックの解除とビルド

ちょくちょく環境をぶっ壊すんでシェルスクリプトにしちゃった

#!/bin/bash

echo "tag:"
read GIT_TAG

sudo apt update && sudo apt upgrade -y
sudo apt install git build-essential libssl-dev libreadline-dev libncurses5-dev zlib1g-dev

wget -nc https://raw.githubusercontent.com/el1n/OpenWRT-package-softether/master/softethervpn/patches/102-regionunlock.patch

if [ ! -d ./SoftEtherVPN_Stable ]; then
git clone -b $GIT_TAG https://github.com/SoftEtherVPN/SoftEtherVPN_Stable.git
else
git -C ./SoftEtherVPN_Stable/ fetch origin master
git -C ./SoftEtherVPN_Stable/ reset --hard tags/$GIT_TAG
fi

cd SoftEtherVPN_Stable
patch -p1 < ../102-regionunlock.patch
./configure
make

sed -i s#/opt/#/usr/local/bin/#g ./systemd/softether-vpnserver.service

sudo systemctl stop softether-vpnserver.service
sudo cp -rfT ./bin/vpnserver/ /usr/local/bin/vpnserver/
sudo cp -rfT ./bin/vpncmd/ /usr/local/bin/vpncmd/
sudo cp -f ./systemd/softether-vpnserver.service /etc/systemd/system/softether-vpnserver.service
sudo systemctl daemon-reload
sudo systemctl enable softether-vpnserver.service
sudo systemctl start softether-vpnserver.service

最初にtagを聞かれますので、ここからbetaなりrtmなりお好きなバージョンを選んでください。

やってることは依存パッケージのインストールと必要なファイルのダウンロード、あとパッチを当ててビルドしてインストールって感じです。
最後にファイルのコピーをわざわざやっているのは、make installするとclientとかもコピーされることとコピー先のディレクトリが気に入らないからです。それに合わせてサービスのファイルも書き換えてます。

DDNSの設定

おうちサーバーなのでDDNSにする必要があります。certbotを使うこともあって今回はCloudflareを使います。
やってることはただddclientセットアップしてるだけです。環境によって変わるので各自ググってください。

一つだけ、Ubuntu 22.04ではddclientをaptからそのまま入れてもCloudflareのDDNS相手に動きます。20.04では動かないという情報も多いので参考までに。

Softetherの組み込みDDNSを使わない理由は、その鯖がSoftetherの鯖ってドメインで分かっちゃうからです。あとLet’s Encrypt通せないのでSSTP使えません。
(今回はAndroidからSSTPするという特殊な条件なので、独自ドメインとLet’s Encryptを使っています。)

Softetherの設定

この時点でポート開けちゃうと外から管理画面に入れちゃうのでまだ閉じといてください。

Windowsのクライアントでサーバー管理ツールを起動、鯖のIPアドレスを指定してパスワードは空欄のまま接続すると管理用パスワードが設定できます。初回のセットアップは適当に済ませてください。

今回は基本的な部分は全部省きます。わからんことはググってください。

ローカルにアクセス禁止

今回は友達にアカウントを1個作る必要があったのでインターネットにのみ接続できる仮想HUBを作ります。事前準備としてすべてのユーザーが所属するグループを作っておいてください。

まずアクセスリストはこんな感じ。必要かわからんものもとりあえず入れてます。

ポイントは破棄のルールの送信元にすべてのユーザーが入っているグループを指定することです。
そうしないとVPN越しに戻ってくるパケットまでロスします。

んで次はグループのセキュリティポリシーですね。
「ARP・DHCP・ICMPv6 以外のブロードキャストを禁止」「IPv6 パケットをすべてフィルタリング」の2つを有効にしてください。IPv6ふさいでおかないとLAN内の端末にアクセスし放題になります。

その他セキュリティとかなんやら

そのほかにも色々やるためにconfigを直接編集しています。
変更箇所は以下の通り

...
	declare DDnsClient
	{
		bool Disabled true # 組み込みDDNSの無効化
	}
...
		bool DisableJsonRpcWebApi true # JSON-RPCの無効化
...
		bool UseWebUI false # Web管理コンソールの無効化

あと今後ルーターに穴開けると管理コンソールに外から入れるようになっちゃうので、LANからのみ管理コンソールに入れるようにします。
以下のファイルをadminip.txtとしてバイナリと同じディレクトリ(先のスクリプトの場合は/usr/local/bin/vpnserver/)に配置します。

127.0.0.0/8
192.168.0.0/16
172.16.0.0/12
10.0.0.0/8

ここまで出来たらポート開放してOKです。
基本的にサーバー管理マネージャーで設定したリスニングポート開ければOKです。うちはUDP高速化を使うためにUDP40000-44999も開けてます。

CertBotの設定

大抵の環境で80番ポートと443番ポートが使えないこと、またWebサーバーの代わりにVPNサーバーが鎮座していることが影響して、Certbotを普通にセットアップすると動きません。

そこでCertbotはDNSレコードで認証するようセットアップしてください。
私の場合はドメインをCloudflareで管理しているので、certbot-dns-cloudflareを使用しました。
この設定方法も環境ごとに変わるので、ググってください。

で、問題がもう一つ。CertbotはSoftetherの証明書の更新に対応していません。
これも自作スクリプトで解決しました。以下のシェルスクリプトを/etc/letsencrypt/renewal-hooks/deploy/に配置してください。

なお当然target_domainは環境に合わせて書き換えてください。あと/password:hogehogeもSoftetherの管理パスワードに書き換えてください。

#!/bin/bash

# /etc/letsencrypt/renewal-hooks/deploy/に配置して"chmod 700"すること。パスワードべた書きなので。

target_domain="domain.example.com"

for domain in $RENEWED_DOMAINS; do
if [ "$domain" = "$target_domain" ]; then
/usr/local/bin/vpncmd/vpncmd localhost:443 /server /password:hogehoge /CMD ServerCertSet /LOADCERT:$RENEWED_LINEAGE/fullchain.pem /LOADKEY:$RENEWED_LINEAGE/privkey.pem
fi
done

ちなみに、/etc/letsencrypt/renewal-hooks/deploy/に置かれたスクリプトは自動renewが成功するたび実行されます。どのドメインのが成功しても実行されるので、ループ使って該当のドメインが更新されたことを確認しないとだめです。まあドメイン1つの環境なら関係ないけど。

以上

これで疎通取れること確認できればOKです。おつかれさまでした。

おまけ: できなかったこと

SoftetherをDocker+macvlanで動かす

これできなかったのほんと悔しい。

どうもプロミスキャストモードでNICが動いていることが重要っぽく、macvlanのコンテナ内からプロミスキャストモードにする方法がわからず断念。
一応仮想NAT機能使えば正常に使えることは確認できたけど、LAN内のコンピュータにアクセスできなかったりして不便なので泣く泣くボツに……

CertbotをDocker内で動かす

これも悔しい。

certbot/dns-cloudflareイメージのドキュメントが見つからず断念…
一発目動いても自動renew動いてないとか発生すると怖いので、あえなくボツ。
詳しい方いたら教えてください。

コメント

タイトルとURLをコピーしました