ASUSルータとOpenVPNで拠点間VPNを構築

Google Cloudに作成した仮想マシン(VM)とASUSのWi-FiルータをOpenVPNで拠点間VPN(Site-to-Site VPN)を構築しました．拠点間はL3(IPレイヤー)で接続されています．

# バージョン・環境

OpenVPNサーバは，構築済みである前提とします．OpenVPNクライアントであるルータは，購入済みであるとします．

- OpenVPNサーバ
    - Google Compute Engine上の仮想マシン
    - OS: **Ubuntu 18.04**
    - マシンイメージ: **ubuntu-1804-bionic-v20190628**
    - マシンタイプ: **f1-micro**（vCPU x1，メモリ 0.6 GB）
    - OpenVPNバージョン: **v2.4.4**
        - x86_64-pc-linux-gnu
        - OpenSSL 1.1.1
    - OpenVPNポート: **1194/udp**
    - easy-rsaバージョン: v?
- OpenVPNクライアント
    - 型番: **ASUS RT-AX3000**
    - ファームバージョン: **3.0.0.4_386_42095**

# ネットワーク構成

拠点間のネットワークをL3（IPレイヤ）で接続します．

- OpenVPNサーバのグローバルIP: `163.215.100.100`
- 拠点Aネットワーク
    - プライベートネットワーク: `192.168.201.0/24`
    - ゲートウェイ: `192.168.201.1`
- トンネルネットワーク
    - プライベートネットワーク: `192.168.200.0/24`
    - ゲートウェイ: `192.168.200.1`
- 拠点Bネットワーク
    - プライベートネットワーク: `10.138.0.0/20`
    - ゲートウェイ: `10.138.0.1`

![技術系ポンチ絵(4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103672/8734b5f8-007f-e828-dbe9-c74427ef7f36.png)



# 設定ファイル

今回は **/etc/openvpn** の下に **easy-rsa/** を配置しています．

OpenVPNサーバのディレクトリ構成 **/etc/openvpn**

```/etc/openvpn以下のファイル構成
.
├── client
│   └── site-a
├── crl.pem
├── dh.pem
├── easy-rsa
│   ├── build-ca -> /usr/share/easy-rsa/build-ca
│   ├── build-dh -> /usr/share/easy-rsa/build-dh
│   ├── build-inter -> /usr/share/easy-rsa/build-inter
│   ├── build-key -> /usr/share/easy-rsa/build-key
│   ├── build-key-pass -> /usr/share/easy-rsa/build-key-pass
│   ├── build-key-pkcs12 -> /usr/share/easy-rsa/build-key-pkcs12
│   ├── build-key-server -> /usr/share/easy-rsa/build-key-server
│   ├── build-req -> /usr/share/easy-rsa/build-req
│   ├── build-req-pass -> /usr/share/easy-rsa/build-req-pass
│   ├── clean-all -> /usr/share/easy-rsa/clean-all
│   ├── inherit-inter -> /usr/share/easy-rsa/inherit-inter
│   ├── keys
│   │   ├── 01.pem
│   │   ├── 02.pem
│   │   ├── ca.crt
│   │   ├── ca.key
│   │   ├── dh2048.pem
│   │   ├── site-a.crt
│   │   ├── site-a.csr
│   │   ├── site-a.key
│   │   ├── index.txt
│   │   ├── index.txt.attr
│   │   ├── serial
│   │   ├── server.crt
│   │   ├── server.csr
│   │   └── server.key
│   ├── list-crl -> /usr/share/easy-rsa/list-crl
│   ├── openssl-0.9.6.cnf
│   ├── openssl-0.9.8.cnf
│   ├── openssl-1.0.0.cnf
│   ├── pkitool -> /usr/share/easy-rsa/pkitool
│   ├── revoke-full -> /usr/share/easy-rsa/revoke-full
│   ├── revoke-test.pem
│   ├── sign-req -> /usr/share/easy-rsa/sign-req
│   ├── vars
│   └── whichopensslcnf -> /usr/share/easy-rsa/whichopensslcnf
├── ipp.txt
├── server.conf
└── update-resolv-conf

3 directories, 44 files
```

OpenVPNサーバのサーバ向け設定 **server.conf**

```shell:/etc/openvpn/server.conf
# ポート番号
port   1194

# トンネリングに使うプロトコル
proto  udp

# 接続方式(トンネリング)
dev    tun

# 鍵と証明書
ca          easy-rsa/keys/ca.crt
cert        easy-rsa/keys/server.crt
key         easy-rsa/keys/server.key
dh          dh.pem
crl-verify  crl.pem

# クライアントのIP固定ファイル
ifconfig-pool-persist ipp.txt

# トンネリングネットワーク
server 192.168.200.0 255.255.255.0

# ルーティング設定
route 192.168.201.0 255.255.255.0

# クライアントへの設定
push "redirect-gateway def1 bypass-dhcp"
push "route 10.138.0.0 255.255.240.0"
push "dhcp-option DNS 1.1.1.1"

client-config-dir client

keepalive 10 120

# LZO圧縮を有効に
comp-lzo

# OpenVPNの実行ユーザWIP
user  nobody
group nogroup

# 切断後の動作
persist-key
persist-tun

# ログの書き込み先
status      /var/log/openvpn-status.log
log         /var/log/openvpn.log
log-append  /var/log/openvpn.log

# ログレベル
verb 3
```

OpenVPNサーバのクライアント向け設定 **client/site-a**

```:/etc/openvpn/client/site-a
; クライアントのIP固定
ifconfig-push 192.168.200.5 192.168.200.6

; ルーティング設定
iroute 192.168.201.0 255.255.255.0
```

# 手順

以降では，構築済みのOpenVPNサーバへASUSのWi-Fiルータから接続する手順を説明します．

## (1) クライアント用OpenVPN設定ファイル `site-a.ovpn` の作成

OpenVPNクライアント用の設定ファイル **site-a.ovpn** を作成します．設定項目の証明書と鍵は，それぞれ対応する以下のファイルの内容を貼り付けます．

- 認証局証明書
    - 対応するファイル名: **easy-rsa/keys/ca.crt**
    - ファイルの内容が `-----BEGIN CERTIFICATE-----` から始まる．
- クライアント証明書
    - 対応するファイル名: **easy-rsa/keys/site-a.crt**
    - ファイルの内容が `-----BEGIN CERTIFICATE-----` から始まる．
- クライアント秘密鍵
    - 対応するファイル名: **easy-rsa/keys/site-a.key**
    - ファイルの内容が `-----BEGIN RSA PRIVATE KEY-----` から始まる．

```shell:site-a.ovpn
# クライアントモード
client

# 接続方式(トンネリング)
dev tun

# トンネリングに使うプロトコル
proto udp

# OpenVPNサーバのグローバルIPアドレス
remote 163.215.100.100 1194

# 名前解決の再試行
resolv-retry infinite

# ポート番号をバインド無し
nobind

# 切断後の動作
persist-key
persist-tun

# 認証局証明書
<ca>
-----BEGIN CERTIFICATE-----
xxx
-----END CERTIFICATE-----
</ca>

# クライアント証明書
<cert>
-----BEGIN CERTIFICATE-----
xxx
-----END CERTIFICATE-----
</cert>

# クライアント秘密鍵
<key>
-----BEGIN RSA PRIVATE KEY-----
xxx
-----END RSA PRIVATE KEY-----
</key>

# LZO圧縮を有効に
comp-lzo

# ログレベル
verb 3
```

## (2) ASUSルータにOpenVPNクライアントの設定

ASUSルータのWeb管理画面にログインします．メニューから次のボタンを選んでOpenVPNの設定を開きます．

**詳細設定 → VPN → VPNクライアント → プロファイルを追加 → OpenVPN**

(1)で作成した **site-a.ovpn** をアップロードします．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103672/ccd4092d-ce1e-55dc-b918-7d672e1670da.png)

**OK**を選びます．OpenVPNサーバとの接続が確立できると，VPNサーバーリストの**接続状態**にチェックマークが表示されます．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103672/1ecae1e7-50ee-e9d5-7a4b-757e3b1d4119.png)

## (3) 接続のテスト

拠点A, 拠点Bのそれぞれから対向の拠点へpingを送って，返答があるかを確かめます．

```shell:拠点B→拠点A
koyama@openvpn-server:~$ ping 192.168.201.11
PING 192.168.201.11 (192.168.201.11) 56(84) bytes of data.
64 bytes from 192.168.201.11: icmp_seq=1 ttl=63 time=93.9 ms
64 bytes from 192.168.201.11: icmp_seq=2 ttl=63 time=93.8 ms
64 bytes from 192.168.201.11: icmp_seq=3 ttl=63 time=93.8 ms
^C
--- 192.168.201.11 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2002ms
rtt min/avg/max/mdev = 93.836/93.880/93.919/0.355 ms
```

```shell:拠点A→拠点B
admin@RT-AX3000-6338:/tmp/home/root# ping 10.138.0.3
PING 10.138.0.3 (10.138.0.3): 56 data bytes
64 bytes from 10.138.0.3: seq=0 ttl=64 time=93.611 ms
64 bytes from 10.138.0.3: seq=1 ttl=64 time=93.388 ms
64 bytes from 10.138.0.3: seq=2 ttl=64 time=93.604 ms
^C
--- 10.138.0.3 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 93.388/93.534/93.611 ms
```

これで拠点Aと拠点BがSite-to-Site VPNで接続されました．

# 付録

ルーティングテーブルを載せておきます

```shell:拠点B
koyama@openvpn-server:/etc/openvpn$ ip route
default via 10.138.0.1 dev ens4 proto dhcp src 10.138.0.3 metric 100 
10.138.0.1 dev ens4 proto dhcp scope link src 10.138.0.3 metric 100 
192.168.200.0/24 via 192.168.200.2 dev tun0 
192.168.200.2 dev tun0 proto kernel scope link src 192.168.200.1 
192.168.201.0/24 via 192.168.200.2 dev tun0
```

```shell:拠点A
admin@RT-AX3000-6338:/tmp/home/root# ip route
0.0.0.0/1 via 192.168.200.9 dev tun15 
default via 10.203.63.1 dev eth4 
10.138.0.0/24 via 192.168.200.9 dev tun15 
10.192.31.10 via 10.203.63.1 dev eth4  metric 1 
10.203.63.0/24 dev eth4  proto kernel  scope link  src 10.203.63.57 
10.203.63.1 dev eth4  proto kernel  scope link 
163.215.100.100 via 10.203.63.1 dev eth4 
127.0.0.0/8 dev lo  scope link 
128.0.0.0/1 via 192.168.200.9 dev tun15 
192.168.200.1 via 192.168.200.9 dev tun15 
192.168.200.9 dev tun15  proto kernel  scope link  src 192.168.200.10 
192.168.201.0/24 dev br0  proto kernel  scope link  src 192.168.201.1 
192.168.201.0/24 via 192.168.201.1 dev br0  scope link  metric 1
```

`10.203.63.1` が拠点AのWAN側のゲートウェイです．

# 参考URL

- [クラウドサーバと結ぶVPN環境を「OpenVPN」で構築する（前編）：DRBDの仕組みを学ぶ（8）（1/3 ページ） - ＠IT](https://www.atmarkit.co.jp/ait/articles/1603/18/news009.html)
- [OpenVPN - ArchWiki](https://wiki.archlinux.jp/index.php/OpenVPN)
- [OpenVPNで拠点間L2接続 - Qiita](https://qiita.com/ma2shita/items/3ccb5336470676b8558e)
- [図解！UbuntuでOpenVPNを使う：3. 設定 - Qiita](https://qiita.com/MoriKen/items/75587fd862b3ce93e4eb)
- [【用語明解】証明書の申請で登場する各種ファイルの見分け方](https://www.ssl-concier.com/news/topics/164)