ubuntuでVPNサーバ構築(OpenVPN)

# 内容
Ubuntu 環境で EasyRSA を用いて OpenVPN サーバを構築する手順をまとめます。  
EasyRSA で独自の認証局(CA)を構築して、サーバ証明書・クライアント証明書を発行するための便利なスクリプトです。
使用するドメインは事前に取得する、もしくはIPアドレスに読み替えてください。

## EasyRSAインストールとPKI初期化
```bash
# sudo apt install easy-rsa

# make-cadir /var/tmp/openvpn

# cd /var/tmp/openvpn

# ls
easyrsa  openssl-easyrsa.cnf  vars  x509-types

# ./easyrsa init-pki

init-pki complete; you may now create a CA or requests.
Your newly created PKI dir is: /var/tmp/openvpn/pki
```

## ルート証明書発行
```bash
# vi vars 
(以下を追記、内容は任意)
set_var EASYRSA_REQ_COUNTRY    "JP"      # 国名
set_var EASYRSA_REQ_PROVINCE   "Tokyo"   # 都道府県
set_var EASYRSA_REQ_CITY       "Shinjuku" # 市区町村
set_var EASYRSA_REQ_ORG        "MyVPN"    # 組織名


# ./easyrsa build-ca nopass
Common Name (eg: your user, host, or server name) [Easy-RSA CA]:MyVPN

CA creation complete and you may now import and sign cert requests.
Your new CA certificate file for publishing is at:
/var/tmp/openvpn/pki/ca.crt

# ls pki/
ca.crt index.txt issued private reqs safessl-easyrsa.cnf
```

## サーバ証明書発行
```bash
# ./easyrsa gen-req server-secret nopass
Using SSL: openssl OpenSSL 3.0.2 15 Mar 2022 (Library: OpenSSL 3.0.2 15 Mar 2022)
.........+...+......+...(省略)+++
-----
Keypair and certificate request completed. Your files are:
req: /var/tmp/openvpn/pki/reqs/server-secret.req
key: /var/tmp/openvpn/pki/private/server-secret.key

# ./easyrsa sign-req server server-secret

Request subject, to be signed as a server certificate for 825 days:

subject=
    commonName                = (ドメイン名)

Certificate created at: /var/tmp/openvpn/pki/issued/server-secret.crt

# ./easyrsa gen-dh
DH parameters of size 2048 created at /var/tmp/openvpn/pki/dh.pem
```

## クライアント証明/秘密鍵
```bash
# ./easyrsa gen-req client-key nopass
.........+...+......+...(省略)+++
-----
Common Name (eg: your user, host, or server name) [client-key]:(ドメイン名)

Keypair and certificate request completed. Your files are:
req: /var/tmp/openvpn/pki/reqs/client-key.req
key: /var/tmp/openvpn/pki/private/client-key.key

# ./easyrsa sign-req client client-key

Request subject, to be signed as a client certificate for 825 days:

subject=
    commonName                = (ドメイン名)
Certificate created at: /var/tmp/openvpn/pki/issued/client-key.crt

```

## 設定ファイル編集
```bash
# ls -l pki/issued/*.crt
-rw------- 1 root root 4500  1月 12 17:02 pki/issued/client-key.crt
-rw------- 1 root root 4651  1月 12 16:54 pki/issued/server-secret.crt

# ls -l pki/private/*.key
-rw------- 1 root root 1704  1月 12 16:50 pki/private/ca.key
-rw------- 1 root root 1700  1月 12 17:00 pki/private/client-key.key
-rw------- 1 root root 1704  1月 12 16:52 pki/private/server-secret.key

# ls -l pki/*.pem
-rw------- 1 root root 424  1月 12 17:48 pki/dh.pem


# cd /etc/openvpn/

# ls
client  server  server.conf  server.conf.org  update-resolv-conf

# mkdir newfiles

# cp -a /var/tmp/openvpn/pki/issued/*.crt ./newfiles/

# cp -a /var/tmp/openvpn/pki/private/server-secret.key ./newfiles/

# cp -a /var/tmp/openvpn/pki/ca.crt ./newfiles/

# cp -a /var/tmp/openvpn/pki/dh.pem newfiles/


# ls newfiles/
ca.crt  client-key.crt  dh.pem  server-secret.crt  server-secret.key


# cat server.conf | grep -vE '^\s*(#|$|;)'
port 1194
proto udp
dev tun
ca /etc/openvpn/newfiles/ca.crt
key /etc/openvpn/newfiles/server-secret.key
cert /etc/openvpn/newfiles/server-secret.crt
dh /etc/openvpn/newfiles/dh.pem
server 10.5.0.0 255.255.255.0
ifconfig-pool-persist /var/log/openvpn/ipp.txt
keepalive 10 120
persist-key
persist-tun
status /var/log/openvpn/openvpn-status.log
verb 3
explicit-exit-notify 1
auth SHA256
topology subnet
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 8.8.8.8"

```

## サービス起動
``` bash
systemctl start openvpn@server
```

## モバイルアプリ用プロファイル作成
モバイル端末にOpenVPNアプリをインストールし、使用するためにはプロファイルが必要です。
プロファイルには設定、証明書、秘密鍵の情報をまとめておく必要があります。
```
client
dev tun
proto udp
remote your-server-ip-or-fqdn 1194
resolv-retry infinite
nobind
persist-key
persist-tun
auth SHA256
verb 3

<ca>
-----BEGIN CERTIFICATE-----
(ここに ca.crt の内容)
-----END CERTIFICATE-----
</ca>

<cert>
-----BEGIN CERTIFICATE-----
(ここに client-key.crt の内容)
-----END CERTIFICATE-----
</cert>

<key>
-----BEGIN PRIVATE KEY-----
(ここに client-key.key の内容)
-----END PRIVATE KEY-----
</key>

```


# 最後に
私はiphoneとAndroid端末でOpenVPNアプリを取得してVPNに接続できるようになりました。