Oracle LinuxでOpenVPNサーバを構築する

Always Freeなインスタンスで何ができるかなーと思い
せっかく海外にリージョンを構えてるのでOpenVPNサーバを構築してみた
スプリットトンネリング無効化にひと工夫必要だったので作業メモ

# サーバ情報
* Oracle Linux 8.6
* タイムゾーン:Asia/Tokyo
* ロケール：ja_JP.UTF-8
* SELinux:disabled
* firewalldはポートフォワード設定のため無効化しない

# 参考サイト様
https://qiita.com/yamada-hakase/items/fdf9c276b9cae51b3633

https://www.server-world.info/query?os=CentOS_8&p=openvpn&f=1

https://tecadmin.net/install-openvpn-centos-8/

https://fuketch.wordpress.com/2013/09/10/openvpn%E3%81%AE%E8%A8%AD%E5%AE%9A%EF%BC%88%E3%81%9D%E3%81%AE5%EF%BC%9A%E3%83%88%E3%83%B3%E3%83%8D%E3%83%AB%E3%83%A2%E3%83%BC%E3%83%89%E3%82%AF%E3%83%A9%E3%82%A4%E3%82%A2%E3%83%B3%E3%83%88%E8%A8%AD/

https://note.com/kenkoishinri/n/n9e7453b6d9b0

# サーバ構築

## 構築準備
* EPELリポジトリを有効化
インスタンス作成したてのリポジトリたちではOpenVPNのインストールができないので「ol8_developer_EPEL」リポジトリを有効化する
```
# yum-config-manager --enable ol8_developer_EPEL
```

有効化されたことを確認
```
# yum repolist all | grep -i epel
ol8_developer_EPEL               Oracle Linux 8 EPEL Packages for Develop 有効化
ol8_developer_EPEL_modular       Oracle Linux 8 EPEL Modular Packages for 無効化
```

* 必要パッケージのインストール
openvpnとeasy-rsaをインストールする。
easy-rsaは証明書の作成必要
```
# yum install openvpn easy-rsa
```

## 構築作業(証明書やら鍵やらを作る）
サーバ証明書や認証局を作る。
  ※これから作成する物の説明は[ここ参照](https://nanbu.marune205.net/2021/12/openvpn-tun-1.html?m=1 "ここ")。

* 作業のためにディレクトリ移動
```
# cd /usr/share/easy-rsa/3
```

* pkiの初期化
```
# ./easyrsa init-pki
```

* 認証局作成
パスフレーズは今後証明書を作成するときに使うので控えておく。
```
# ./easyrsa build-ca
~~~色々流れる~~~
Enter New CA Key Passphrase: <任意のパスフレーズ>
Re-Enter New CA Key Passphrase: <任意のパスフレーズ>
~~~色々流れる~~~
Common Name (eg: your user, host, or server name) [Easy-RSA CA]:Server-CA

```

* サーバ証明書作成
<任意の文字列>は、サーバ証明書のファイル名に設定される
```
# ./easyrsa build-server-full <任意の文字列> nopass
~~~色々流れる~~~
Enter pass phrase for /usr/share/easy-rsa/3/pki/private/ca.key:<認証局作成時のパスフレーズ>
```

* クライアント証明書作成
VPNサーバに接続するユーザ分実施する。ファイル名に設定される。
```
# ./easyrsa build-client-full <任意の文字列> nopass
~~~色々流れる~~~
Enter pass phrase for /usr/share/easy-rsa/3/pki/private/ca.key:<認証局作成時のパスフレーズ>
```

* Diffie Hellman ( DH ) パラメーター生成
共通鍵がわからないようにするパラメータファイル。3~5分くらい。
```
# ./easyrsa gen-dh
```

* TLS-Auth鍵作成
セキュリティを高める鍵。
詳しくは[ここ](https://yamatamemo.blogspot.com/2014/04/openvpn-tls-auth.html#:~:text=%E7%B0%A1%E5%8D%98%E3%81%AB%E8%A8%80%E3%81%86%E3%81%A8%E3%80%81%2D%2D,%E3%81%99%E3%81%90%E3%81%AB%E7%A0%B4%E6%A3%84%E3%81%97%E3%81%BE%E3%81%99%E3%80%82 "ここ")か[ここ](https://openvpn.net/community-resources/hardening-openvpn-security/ "ここ")。
```
# openvpn --genkey --secret ./pki/ta.key
```
* /etc/openvpn/server/にコピー
サーバ/クライアント証明書(.crt issuedディレクトリ)
サーバ/クライアント秘密鍵(.key privateディレクトリ)
認証局証明書(ca.crt)
ディフィーヘルマン鍵（dh.pem)
共有秘密（TLS-Auth)鍵(ta.key)
```
# cp -pR /usr/share/easy-rsa/3/pki/{issued,private,ca.crt,dh.pem,ta.key} /etc/openvpn/server/
```

## 構築作業（設定値を変更する）
* IPフォワードの有効化
```
# vim /etc/sysctl.conf
-------
### 下記文字列を追加
net.ipv4.ip_forward = 1
-------

### リロード
# sysctl -p
```

* 設定ファイルをコピー
```
# cp /usr/share/doc/openvpn/sample/sample-config-files/server.conf　 /etc/openvpn/server/
```

* 設定ファイルの修正
```
# vim /etc/openvpn/server/server.conf

### 79行目,80行目 コピーした証明書ファイルパスを指定
ca ca.crt
# cert server.crt
cert /etc/openvpn/server/issued/<任意の文字列>.crt
# key server.key
key /etc/openvpn/server/private/<任意の文字列>.key

### 85行目 ディフィーヘルマン鍵パスを指定
#dh dh2048.pem
dh /etc/openvpn/server/dh.pem

### 101行目 VPN接続時に付与されるネットワークアドレスを指定
#server 10.8.0.0 255.255.255.0
server 192.168.200.0 255.255.255.0

### 141行目 ルーティング先のネットワークを指定（とりあえずサブネットネットワークアドレス）
/// 【追記】255.255.0.0だと正常に動作しない模様
push "route 172.20.1.0 255.255.255.0"
push "route 172.20.2.0 255.255.255.0"

### 192行目 「;」を削除 クライアントの通信を全てOpenVPNサーバ経由化（スプリットトンネル設定）
#;push "redirect-gateway def1 bypass-dhcp"
push "redirect-gateway def1 bypass-dhcp"

### ２００行目 DNSを追加
push "dhcp-option DNS 8.8.8.8"

### 246行目 共通秘密鍵ファイルパスを指定
#tls-auth ta.key 0
tls-auth /etc/openvpn/server/ta.key 0

### 264行目 「;」削除
#;comp-lzo
comp-lzo

### 288行目 ログの場所を変更
#status openvpn-status.log
status /var/log/openvpn-status.log

### 297行目 「;」を削除し、ログの場所を変更
#;log         openvpn.log
#;log-append  openvpn.log
log         /var/log/openvpn.log
log-append  /var/log/openvpn.log
```

* OpenVPNの有効化
```
# systemctl enable --now openvpn-server@server
# systemctl status openvpn-server@server
```

## firewalld設定（ポート解放、マスカレード設定）
* firewalldのポート解放
```
# firewall-cmd --add-port=1194/udp --permanent
# firewall-cmd --reload
```

* firewalldのルーティング設定
```
# firewall-cmd --permanent --add-service=openvpn
# firewall-cmd --permanent --zone=trusted --add-service=openvpn
# firewall-cmd --permanent --zone=trusted --add-interface=tun0
```

* firewalldのマスカレード設定
```
# firewall-cmd --add-masquerade
# firewall-cmd --permanent --add-masquerade 
```

* VPN内のネットワークからきた通信をインターネットへマスカレード設定
```
/// インタフェース情報を取得
# tecadmin=$(ip route get 8.8.8.8 | awk 'NR==1 {print $(NF-2)}')

/// 送信元IPアドレスが192.168.200.0/24ネットワークに属するパケットに対して、外部インターフェースを通じてマスカレード
# firewall-cmd --permanent --direct --passthrough ipv4 -t nat -A POSTROUTING -s 192.168.200.0/24 -o $tecadmin -j MASQUERADE

# firewall-cmd --reload
```

## ひとまず構築完了
お次はクライアント側の設定をしていく。
クライアント設定がうまくいくと、設定したNWアドレスのIPを持って、VPNサーバ経由でインターネットする感じになる
```
utun5: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1500
inet 192.168.200.6 --> 192.168.200.5/30 utun5
```

# クライアント設定
クライアントファイルは２種類ある。
・鍵ファイルを別で管理し、クライアントファイルから参照させる方法
・クライアントファイル内に鍵ファイルを埋め込む方法

## クライアントファイルから参照させる
```
# デフォルトのまま利用
client
# OpenVPN サーバ設定時に指定したプロトコル
;proto tcp
proto udp
# OpenVPN サーバのグローバルIPとポート指定
remote XXX.XXX.XXX.XXX　1194
# 名前解決を試行する
resolv-retry infinite
# 動的にポートをバインドさせる
nobind
# よくわからないけど、デフォルトのまま利用
persist-key
persist-tun

#　認証局証明書
ca /XXX/vpn/ca.crt
# クライアント証明書
cert /XXX/vpn/cert.crt
# クライアント秘密鍵
key /XXX/vpn/key.key
# TLS-Auth キーのパス TLS認証のクライアントとして認識させるために「１」が末尾に
tls-auth /XXX/vpn/ta.key 1
# デフォルト（圧縮に関するらしい）
comp-lzo
# デフォルト（ログに関するらしい）
verb 3
```

## クライアントに埋め込む方法
設定する中で一番ハマったポイントが下記参考サイト様の設定
https://netwiz.jp/iphone-openvpn/

オプションは全部上の記載と同じなので割愛する。
鍵を参照させる部分の代わりに下記を書く。
TLS-Authを埋め込む時だけ注意する。
```
<ca>
-----BEGIN CERTIFICATE-----
XXX
-----END CERTIFICATE-----
</ca>

<cert>
-----BEGIN CERTIFICATE-----
XXX
-----END CERTIFICATE-----
</cert>

<key>
-----BEGIN PRIVATE KEY-----
XXX
-----END PRIVATE KEY-----
</key>

# TLS認証のクライアントとして認識させるため。末尾に「1」が書けないので、代わりに追記
key-direction 1
<tls-auth>
-----BEGIN OpenVPN Static key V1-----
XXX
-----END OpenVPN Static key V1-----
</tls-auth>
```

# やっと接続ができた
個人的にハマったポイントは
・firewalldの設定（マスカレード設定）
・埋め込みクライアントファイル作成のTLS-auth設定

最終的には接続できるようになってよかった。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610268/a84a225e-dabf-bfea-29dd-de566aba3a92.png)