さくらVPSとWireGuardで自宅サーバーにリモートからアクセスする

背景
--------------------
* 自宅に強いマシンを置き、出先でもssh使ってそのマシンで開発をしたい。
* M1 Macbookを使っているが、web系の開発はx86マシンで行いたいシチュエーションがたまにある。
  - 本番環境がx86の方が多いので
* 集合住宅なので固定ipが取れない
* さくらVPSで開発にゴリゴリ使えそうなスペックを選ぶとそれなりに高い
  - CPU8コア、メモリ16GBで13200円/月


概要
--------------------
さくらVPSの一番安いプランを契約しました。
VPSと自宅サーバーの間でVPNを構築し、VPSを起点に自宅サーバーへアクセスしていきます。  
全体の大まか流れとしては

* VPSの基本設定
* WireGuard(VPNソフト)の導入&設定
* VPSから自宅サーバーへのポートフォワーディング設定

となります。



さくらVPS基本設定
--------------------
### 普通に構築
下記の公式の記事を参考に、VPSを構築していきます。  
[ネコでもわかる！さくらのVPS講座 ～第二回「サーバーをさわってみよう！」](https://knowledge.sakura.ad.jp/8218/)
OSをインストールしてサーバーを作るときに、下記のようにオプションを選択します。

* OSインストール形式: 標準OS
* インストールOS: CentOS8 x86\_64
* スタートアップスクリプト利用: 利用しない
* パケットフィルタ設定: 利用しない
* サーバーへのSSHキー登録: 登録する
  - SSHキー: 作業をしている手元のPCのssh公開鍵を入力
  - パスワードを利用したログイン: 無効にする

上記の記事でVPSに一般ユーザーを作成し、パスワード認証でログインしていますが、
ここでは最初からパスワード認証を無効にしていますので、
rootユーザーの`~/.ssh/authorized_keys`をコピーして一般ユーザーも公開鍵で入れるようにします。

```
# cd /home/vpsuser
# mkdir .ssh
# cp ~/.ssh/authorized_keys .ssh/
# chown -R vpsuser:vpsuser .ssh
# chmod 700 .ssh
# chmod 600 .ssh/authorized_keys
```
これで一般ユーザーでssh出来たら成功です。

あとは記事通りrootユーザーでのログインを無効にします。

```
[/etc/ssh/sshd_config]
PermitRootLogin no
```
sshdを再起動します。

```
# systemctl restart sshd.service
```
rootで入れなくなっていたら成功です。


### sshのポートを変更
セキュリティ的に後悔するサーバーのsshポートは変更した方がいいらしいので、22番から2222番に変更します。

```
[/etc/ssh/sshd_config]
Port 2222
```
sshdを再起動します。

```
# systemctl restart sshd.service
```
2222番で入れたら成功です。

### firewalldの設定
サーバーを作成するときに、パケットフィルタをOFFにしていました。
そのままでは全ポートが公開されてしまい、セキュリティ上よろしくないので、
firewalldを設定して必要なポート以外のアクセスを遮断する必要があります。

firewalldについての説明は下記のサイトが詳しいです。  
[ネコでもわかる！さくらのVPS講座 ～第七回「ファイアウォール”firewalld”について理解しよう」](https://knowledge.sakura.ad.jp/10583/)  

この作業はブラウザからアクセスできるさくらVPSのシリアルコンソールから行います(firewalldを起動するとssh接続が弾かれてしまうので)。
firewalldが起動しているか確認します。

```
# firewall-cmd --state
```
起動していなければ起動します。

```
# systemctl start firewalld
```
次に2222番を開きます。

```
# firewall-cmd --add-port=2222/tcp --zone=public --permanent
# firewall-cmd --reload
```
ついでにfirewalldを自動起動するように設定しておきます。

```
# systemctl enable firewalld
```
ここまで完了したら、VPSに2222番でsshしてみて繋がるかどうか確認します。
繋がっていたら成功です。


WireGuard設定
--------------------
下記のサイトを参考にして、WireGuardをVPSと自宅サーバーに導入してVPNを構築します。  
[WireGuardを使って爆速でVPNトンネルを構築する](https://qiita.com/kniwase/items/52d45d618edccbb914ca)  
基本的にはこちらの記事通りにやっていくのですが、VPS側の環境がCentOSですので、幾つかの細かな違いがあります。
まずVPSにWireGuardをインストールするときは下記のようにします。

```
# yum install elrepo-release epel-release
# yum install kmod-wireguard wireguard-tools
```
自宅サーバー(参考記事では「クライアント側」と呼ばれている方ですね)の側はubuntu20.04なので記事通りにインストールできます。

```
sudo apt update
sudo apt install wireguard
```
設定ファイル`/etc/wireguard/wg0.conf`の作り方は記事と全く同じでOKです。


vps側のポート開放はufwではなくfirewalldを使っているので、下記のように設定します。

```
# firewall-cmd --add-port=51820/udp --zone=public --permanent
# firewall-cmd --reload
```

デーモン化の部分はVPS側、自宅サーバー側ともに元記事と同じです。

```
# systemctl start wg-quick@wg0
# systemctl enable wg-quick@wg0
```

疎通確認も(当たり前ですが)同じです

```
ping -c 3 10.0.0.2  # VPSから自宅サーバー
ping -c 3 10.0.0.1  # 自宅サーバーからVPS
```


ポートフォワード設定
--------------------
VPS側で受け付けた通信を自宅サーバーに送る、ポートフォワードの設定をしていきます。
VPS側でrootユーザーになってから、下記の記事に従ってipマスカレードの設定をします。  
[Firewalld : IP マスカレードの設定](https://www.server-world.info/query?os=CentOS_8&p=firewalld&f=2)  
VNP接続である`wg0`をinternalに、普通のネットワーク接続である`System ens3`をexternalにそれぞれゾーンを変更します。

```
# nmcli connection modify wg0 connection.zone internal
# nmcli connection modify "System ens3" connection.zone external
```
上記の設定をするときに、connectionとdeviceの違いに注意してください。
ここで設定するのはdevice名ではなくてconnection名です。device名とconnection名は下記のコマンドで調べられます。

```
# nmcli connection show
NAME         UUID                                  TYPE       DEVICE
System ens3  21d47e65-8523-1a06-af22-6f121086f085  ethernet   ens3
wg0          546b8860-10ab-4c24-8e8c-019365cb2e0e  wireguard  wg0
System ens4  e27f182b-d125-2c43-5a30-43524d0229ac  ethernet   --
System ens5  8126c120-a964-e959-ff98-ac4973344505  ethernet   --
```
最初、何も考えずに`nmcli connection modify "System ens3" connection.zone external`としていたら、
`Error: unknown connection 'ens3'.`というエラーが出てハマりました。下記の記事が参考になりました。  
[nmcliコマンドの隅をつつく](https://qiita.com/kanatatsu64/items/b7b8eca17202386d27e3)

次にipマスカレードの設定を行います。

```
# firewall-cmd --zone=external --add-masquerade --permanent
```

外部から2223番ポートにアクセスがあった場合には`10.0.0.2`(自宅サーバー)の`22`番ポートにフォワーディングするようにした上で、
2223番ポートを開放します。

```
# firewall-cmd --zone=external --add-forward-port=port=2223:proto=tcp:toport=22:toaddr=10.0.0.2 --permanent
# firewall-cmd --add-port=2223/tcp --zone=external --permanent
```

先程設定したsshとWireGuard用のポート開放設定も、`--zone=external`に変えましょう。

```
# firewall-cmd --add-port=2222/tcp --zone=external --permanent
# firewall-cmd --add-port=51820/udp --zone=external --permanent
# firewall-cmd --reload
```

VPSの2223番にsshしたときに、自宅サーバーに繋がれば成功です。

```
ssh username@xxx-xxx-xxxxx.vs.sakura.ne.jp -p 2223
```
うまく繋がらないとき、VPSを再起動してみると繋がることがある?(未確認)

その他の設定
--------------------
他のサービスを自宅サーバーにポートフォワードしたいときも同様にfirewalldの設定をします。
例えばhttpをで自宅サーバーの8000番に通した時は、以下のようにします。

```
# firewall-cmd --zone=external --add-forward-port=port=8000:proto=tcp:toport=8000:toaddr=10.0.0.2 --permanent
# firewall-cmd --add-port=8000/tcp --zone=external --permanent
```