VPNサーバーを完全無料で作る（Oracle Cloud編）

# はじめに

リモートで仕事する人が増えたと思いますが、VPN がないと何かと不便です。
Oracle Cloud で無料で構築できるのでメモを残しておきます。
VPN には WireGuard を使用します。とっても簡単。

### 今回使う環境

| 項目| 内容 |
|---|---|
| 契約 | [Oracle Cloud Always Free](https://www.oracle.com/jp/cloud/) （ずっと無料） |
| インスタンス | VM.Standard.E2.1.Micro / OCPU 1 / RAM 1GB |
| OS | [Oracle Linux 8](https://www.oracle.com/jp/linux/) （RHEL互換） |
| ミドルウェア | [WireGuard](https://www.wireguard.com/) （Linux，Windows，Mac OSX，iOS，Android 対応） |

CentOS 8 のサポート期間短縮に伴い、Oracle Linux 8 を使って建ててみます。

追記 2024-11-28
Oracle Linux 9, Rocky Linux 9, Alma Linux 9 でも同様の手順で構築可能です。

# サーバーとクライアントの関係
![wg1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21236/c3318c6a-26ec-91e2-e8d7-c8fe7446578d.png)

WireGuad では、それぞれの秘密鍵を生成し、それぞれの設定ファイルにはお互いの公開鍵を書いていきます。

######サーバー側の設定ファイル
* サーバーの秘密鍵
* クライアントの公開鍵（クライアントの秘密鍵から生成したもの）

######クライアント側の設定ファイル
* クライアントの秘密鍵
* サーバーの公開鍵（サーバーの秘密鍵から生成したもの）


### クライアントが複数の場合

クライアントが複数になる場合は、サーバー側の設定ファイルにクライアントの公開鍵をひたすら追加していきます。


![wg2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21236/d206833b-162a-6976-2eef-afeaa2b888ed.png)

# サーバー

## 導入

利用できる EPEL リポジトリを確認する

```console:ssh
[root@vm opc]# dnf repolist all | grep -i epel
ol8_developer_EPEL    Oracle Linux 8 EPEL Packages for Development (x86 disabled
```

EPEL を有効化してアップデートをかける（注意：ol8_developer_EPEL は Oracle Linux 8 専用です）

```console:ssh
[root@vm opc]# dnf config-manager --enable ol8_developer_EPEL
[root@vm opc]# dnf update
...（省略）...
Complete!
```

WireGuard をインストールする

```console:ssh
[root@vm opc]# dnf install wireguard-tools
```



## サーバー側の設定

### 設定ファイル


サーバー側のプライベートキー（秘密鍵）を生成する

```console:ssh
[root@vm opc]# wg genkey | tee /etc/wireguard/server.key
OJHeFvySvtcqllcIz+LgaZ+58JflkdPpWd3BmNyq1WM=
```

サーバー側のパブリックキー（公開鍵）を生成する

```console:ssh
[root@vm opc]# cat /etc/wireguard/server.key | wg pubkey | tee /etc/wireguard/server.pub
tKkp9E2sa8W0aX2I21bWaqG6lXJY+o6iftwWpLijoUc=
```

インターフェースを確認する

```console:ssh
[root@vm opc]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9000 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 02:00:17:00:19:db brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.5/24 brd 10.0.0.255 scope global dynamic ens3
       valid_lft 84446sec preferred_lft 84446sec
    inet6 fe80::17ff:fe00:19db/64 scope link 
       valid_lft forever preferred_lft forever
```

### Firewall の設定を確認する

```console:ssh
[root@vm opc]# firewall-cmd --get-active-zone
public
  interfaces: ens3
```

### WireGuard の設定ファイルを作る

```console:ssh
vi /etc/wireguard/wg0.conf
```



```console:/etc/wireguard/wg0.conf
[Interface]
PrivateKey = OJHeFvySvtcqllcIz+LgaZ+58JflkdPpWd3BmNyq1WM=
Address = 10.10.10.1/24
ListenPort = 51820
MTU = 1380

PostUp = firewall-cmd --zone=public --add-masquerade; firewall-cmd --direct --add-rule ipv4 filter FORWARD 0 -i wg0 -o ens3 -j ACCEPT; firewall-cmd --direct --add-rule ipv4 nat POSTROUTING 0 -o ens3 -j MASQUERADE; firewall-cmd --add-port=51820/udp
PostDown = firewall-cmd --zone=public --remove-masquerade; firewall-cmd --direct --remove-rule ipv4 filter FORWARD 0 -i wg0 -o ens3 -j ACCEPT; firewall-cmd --direct --remove-rule ipv4 nat POSTROUTING 0 -o ens3 -j MASQUERADE; firewall-cmd --remove-port=51820/udp

[Peer]
PublicKey = 9wVHswghFDUnBm+erw8HZFBC3PvLuacdZLKlasaORg4=
AllowedIPs = 10.10.10.2/32
```

| [Interface] | 自身の設定（ここではサーバー） |
|---|---|
| PrivateKey | サーバーの秘密鍵 |
| Address | VPN インターフェースの IP アドレス（ローカル IP アドレス） |
| ListenPort | ポート番号 |
| MTU | パケットのサイズ（応答が無くなる場合は設定する） |
| PostUp | WG 起動時に実行するコマンド（Firewall に穴を開ける、など） |
| PostDown | WG 起動時に実行するコマンド（Firewall の穴をふさぐ、など） | 


| [Peer] | 相手の設定（ここではクライアント） |
|---|---|
| PublicKey | クライアントの公開鍵 |
| AllowedIPs | VPN を経由させる対象 IP アドレスの範囲（CIDR）<br/>基本的にはクライアントに割り当てるIPアドレスで良い |


複数のクライアントを定義するには [Peer] をセクションを増やしていけばいいです。

## 起動

```console:ssh
[root@vm opc]# systemctl enable --now wg-quick@wg0
Created symlink /etc/systemd/system/multi-user.target.wants/wg-quick@wg0.service → /usr/lib/systemd/system/wg-quick@.service.
```

穴が開いている確認します。

```console:ssh
[root@vm opc]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9000 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 02:00:17:00:19:db brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.5/24 brd 10.0.0.255 scope global dynamic ens3
       valid_lft 83602sec preferred_lft 83602sec
    inet6 fe80::17ff:fe00:19db/64 scope link 
       valid_lft forever preferred_lft forever
3: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 8920 qdisc noqueue state UNKNOWN group default qlen 1000
    link/none 
    inet 10.10.10.1/32 scope global wg0
       valid_lft forever preferred_lft forever
```

## インフラ側の準備

仮想ファイアウォールにも、51820番ポートで UDP 通信を許可するよう設定します。
※ 環境によって操作手順が異なります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21236/5095b5bf-85c0-5a5e-b3ce-38ca525687ca.png)

Oracle Cloud の場合はセキュリティーリストのイングレスルールに追加します。

# クライアント

## 導入

Linuxであればサーバー側導入と同じ手順。
Windows，Android，OS X，iOSであれば公式および各ストアからダウンロードしてください。

## 設定ファイル

```
[Interface]
PrivateKey = ECR41Y/9tslY6TjTj33kzHWcTUsFj8DSaXN2jHp580A=
Address = 10.10.10.2/32
MTU = 1380
DNS = 8.8.8.8, 8.8.4.4

[Peer]
PublicKey = tKkp9E2sa8W0aX2I21bWaqG6lXJY+o6iftwWpLijoUc=
AllowedIPs = 10.10.10.1/24
Endpoint = <VpnServerIpAddress>:51820
PersistentKeepalive = 25
```

| [Interface] | 自身の設定（ここではクライアント） |
|---|---|
| PrivateKey | クライアントの秘密鍵 |
| Address | VPN インターフェースの IP アドレス（ローカル IP アドレス） |
| MTU | パケットのサイズ（応答が無くなる場合は設定する） |
| DNS | DNS サーバーを指定（必要に応じて） |


| [Peer] | 相手の設定（ここではサーバー） |
|---|---|
| PublicKey | サーバーの公開鍵 |
| Endpoint | エンドポイント（サーバーのグローバル IP アドレスまたはFQDNと、ポート番号）
| AllowedIPs | VPN を経由させる対象 IP アドレスの範囲（CIDR）<br/>0.0.0.0/0 ですべての宛先が経由する，内部だけであれば 10.10.10.1/24 でよい |
| PersistentKeepalive | KeepAlive 送信間隔（秒）<br/>勝手に切れてしまう場合は設定・調整すると良い |

おわり。

# 更新履歴
2021-01-09 初稿
2021-01-12 秘密鍵の図を追加
2021-05-13 yum コマンドから dnf コマンドへ修正
2021-12-07 クライアントの設定、仮想ファイアウォールの設定、その他追加
2021-12-13 MTU を追記
2024-11-28 Enterprise Linux 9 でも構築可能なことを確認