【2024年08月版】AWS EC2 AmazonLinux で WireGuard による VPN 環境構築

# はじめに
AWS上でAmazonLinux2を利用してWireGuardによるVPN環境を構築します。

:::note info
2023年02月版から2024年08月版に更新しました。
kernel 4.14 の Amazon Linux2 だと、追加の手順が必要でした。
:::

- サーバはAmazonLinux2
- クライアントはMac/Windows/iOS/Android等WireGuardのクライアントソフトがある環境
- クライアントがWireGuardのVPNを経由してVPC内の別のインスタンス（AmazonLinux2）へ接続できる

```terminal
# uname -a
Linux #####.ap-northeast-1.compute.internal 5.10.157-139.675.amzn2.x86_64 #1 SMP Thu Dec 8 01:29:11 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
# cat /etc/os-release 
NAME="Amazon Linux"
VERSION="2"
ID="amzn"
ID_LIKE="centos rhel fedora"
VERSION_ID="2"
PRETTY_NAME="Amazon Linux 2"
ANSI_COLOR="0;33"
CPE_NAME="cpe:2.3:o:amazon:amazon_linux:2"
HOME_URL="https://amazonlinux.com/"
```

# インスタンスの起動
AWS上で利用するサーバのインスタンスを起動します。起動後、PingやSSH等で双方向に接続できることを確認しておきます。

- VPNサーバとなるインスタンスの起動  
  AmazonLinux2を選択します。SecurityGroupでICMPv4とSSH、WireGuardの接続で利用するUDPのPortを開けておきます。このインスタンスはEIPかPublicIPをもたせて外からSSH接続できるようにします。

- VPC内部のアクセス先となるインスタンスの起動(LinuxでもWindowsでもなんでも)
  VPNサーバとなるインスタンスと同一サブネットに配置します。このインスタンスはEIPもPublicIPも持ちません。SecurityGroupでICMPv4とその他必要なプロトコルとポートを通しておきます。PingやSSHなどで、VPNサーバとなるインスタンスからアクセスできることを確認しておきます。

# WireGuardのインストール（サーバ側）

以下のコマンドを実行します。

```shell-session
$ sudo yum update
$ sudo amazon-linux-extras install epel
$ sudo yum update
$ sudo yum install wireguard-tools
```

# WireGuardの設定（サーバ側）
[Wireguard Config Generator](https://www.wireguardconfig.com/)で作成します。

- Random Seed: デフォルトのままで設定
- Listen Port: VPNサーバのSecurityGroupで開けたUDPのポート番号を設定
- Number of Clients: 最初は1とかで設定
- CIDR: 某サービスのように100.0.0.0/24のVPN内で利用するCIDRを設定(例：100.0.0.0/24)
- Client Allowed IPs: VPC内で利用するサブネットを設定(例：10.10.0.0/24)
- Endpoint: VPNサーバのEIP(PublicIP)とポートを設定
- DNS: デフォルトのままで設定
- Post-Up rule: デフォルトのままで設定
- Post-Down rule: デフォルトのままで設定
- Use Pre-Shared Keys(Enhanced Security): チェックを付ける

出力された設定をVPNサーバに書き込みます。キーはマスクしています。
クライアントの設定は、後で利用します。

```shell-session
$ sudo vim /etc/wireguard/wg0.conf
```

```text:/etc/wireguard/wg0.conf
[Interface]
Address = 100.0.0.1/24
ListenPort = 11112
PrivateKey = ********************
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

[Peer]
PublicKey = ********************
PresharedKey = ********************
AllowedIPs = 10.10.0.2/32
```

VPNからVPCへアクセスできるように設定します。
以下のコマンドを実行します。

```shell-session
$ sudo vim /etc/sysctl.conf
```

```text:/etc/sysctl.conf
net.ipv4.ip_forward=1
```

```shell-session
$ sudo sysctl -p
```

サービスを起動、再起動しても自動起動するように設定します。
以下のコマンドを実行します。

```shell-session
$ sudo systemctl enable --now wg-quick@wg0
```

起動しているか確認します。

```shell-session
$ sudo systemctl status wg-quick@wg0
```

ここで、"RTNETLINK answers: Operation not supported"等のエラーが出る場合は、一旦再起動します。

```shell-session
$ sudo reboot
```

:::note warn
Amazon Linux 2　の kernel 4.14系だと、以下のエラーとなることがある。

- `RTNETLINK answers: Operation not supported`
- `Unable to access interface: Protocol not supported`

その場合は、以下の追加の手順場必要
:::

```terminal
$ sudo curl -Lo /etc/yum.repos.d/wireguard.repo   https://copr.fedorainfracloud.org/coprs/jdoss/wireguard/repo/epel-7/jdoss-wireguard-epel-7.repo
$ sudo yum clean all
$ sudo yum install -y wireguard-dkms
```

# WireGuardのインストール（クライアント側）
[WireGuard](https://www.wireguard.com/)から環境にあわせたクランアントをダウンロードしインストールします。
クライアントもAmazonLinuxで構築する場合は、同手順でWireGuardをインストールします。

# WireGuardの設定（クライアント側）
インストールしたWireGuardのクライアントアプリを起動して、
上記の[Wireguard Config Generator](https://www.wireguardconfig.com/)で作成したクライアントの設定をファイルまたは、コピー＆ペーストで読み込んで設定します。
AmazonLinuxの場合は、[Wireguard Config Generator](https://www.wireguardconfig.com/)で作成したクライアントの設定内容をサーバと同一ファイル(/etc/wireguard/wg0.conf)に書き込みます。
PersistentKeepalive = 10 を追加で設定することで、一度接続すると接続が継続されます。記述がなければ一定時間通信がないと切断されます　＝　サーバ側からの通信では復帰せず、再度クライアント側から通信が発生するまで切断されたままになります。

# 接続確認
設定したWireGuardのクライアントを接続します。
その後、Pingや確認に利用する接続が、WireGuardのVPNサーバ、および、VPC内部のアクセス先に到達できることを確認します。
到達できない場合、WireGuardのサーバの設定、クライアントの設定、SecurityGroup、sysctl.confにip_forward=1で設定されているかどうかなど、クライアントから近い順に確認してみてください。

# 特記： ufw 併用について
WireGuardでip forwardingするLinuxで、ufwを利用する場合、`/etc/default/ufw`ファイルの`DEFAULT_FORWARD_POLICY` を `ACCEPT` に変更しないと、ブロックされてしまうので注意。
WireGuard仕様時で`net/ipv4/ip_forward=1`を利用している場合でPing(ICMP)は通るのにTCP/UDPはつながらないというときは、ufwの設定が、`DEFAULT_FORWARD_POLICY=“ACCEPT"`になっているか確認したほうがいい。

# おわりに
かんたんでしたね。