CentOS8でOpenVPN

# はじめに

固定IPを使いたいが、どこかのサービスではなく自分で作成したかったので
VPNサーバを構築しました。VPNといっても以下のプロトコルがありますよね。

IPsec
L2TP
PPTP
SSL-VPN
OpenVPN
Shadowsocks

今回はOpenVPNで作成しました。


# 環境

* conoha VPS
* OpenVPNサーバ：centos 8.3(最小プラン)
* OpenVPNクライアント: macbook(Tunnelblick)

# OpenVPNサーバの構築

認証方式は複数あるのですが証明書方式です。
接続するクライアントごとに証明書を発行してあげます。
※情報が多く構築しやすい。


## 必要なパッケージのインストール

公式サイトを見るとrpmでインストールになっていましたが、普通にdnfでインストール可能だったのでdnfで行います。

~~~shell
dnf -y update
dnf -y install openvpn easy-rsa
~~~

## 証明書の作成

easy-rsaでサーバ証明書やクライアント証明書を作成します。

~~~shell
cd /usr/share/easy-rsa/3/
~~~

認証局を初期化します。

~~~shell
[root@hoge 3]# ./easyrsa init-pki

init-pki complete; you may now create a CA or requests.
Your newly created PKI dir is: /usr/share/easy-rsa/3/pki
~~~

認証局を作成します。

~~~shell
[root@hoge 3]# ./easyrsa build-ca
Using SSL: openssl OpenSSL 1.1.1g FIPS  21 Apr 2020

Enter New CA Key Passphrase:  #任意のパスワード
Re-Enter New CA Key Passphrase: #任意のパスワード
Generating RSA private key, 2048 bit long modulus (2 primes)
............+++++
..........................................+++++
e is 65537 (0x010001)
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Common Name (eg: your user, host, or server name) [Easy-RSA CA]: #何でも良いので指定する。デフォルトのままでもOK

CA creation complete and you may now import and sign cert requests.
Your new CA certificate file for publishing is at:
/usr/share/easy-rsa/3/pki/ca.crt
~~~

DHパラメータを生成します。

~~~shell
[root@hoge 3]# ./easyrsa gen-dh
Using SSL: openssl OpenSSL 1.1.1g FIPS  21 Apr 2020
Generating DH parameters, 2048 bit long safe prime, generator 2
This is going to take a long time
........................................................................................................+....+
DH parameters of size 2048 created at /usr/share/easy-rsa/3/pki/dh.pem
~~~

サーバ秘密鍵の作成から証明書の署名まで

~~~shell
[root@hoge 3]# ./easyrsa build-server-full server nopass
Using SSL: openssl OpenSSL 1.1.1g FIPS  21 Apr 2020
Generating a RSA private key
..................+++++
............................................................................+++++
writing new private key to '/usr/share/easy-rsa/3/pki/easy-rsa-36402.InOa0s/tmp.ILGl7B'
-----
Using configuration from /usr/share/easy-rsa/3/pki/easy-rsa-36402.InOa0s/tmp.omwcm1
Enter pass phrase for /usr/share/easy-rsa/3/pki/private/ca.key: #認証局の作成の時に設定したパスワードを入力
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
commonName            :ASN.1 12:'server'
Certificate is to be certified until Apr  9 05:25:22 2023 GMT (825 days)

Write out database with 1 new entries
Data Base Updated
~~~

クライアント側の秘密鍵の作成から証明書の署名まで
nopassをつけることによってVPN接続時にパスワードを聞かれなくなります。

~~~shell
[root@hoge 3]# ./easyrsa build-client-full client0 nopass
Using SSL: openssl OpenSSL 1.1.1g FIPS  21 Apr 2020
Generating a RSA private key
........+++++
..........+++++
writing new private key to '/usr/share/easy-rsa/3/pki/easy-rsa-36518.woJCtP/tmp.DYeRlx'
-----
Using configuration from /usr/share/easy-rsa/3/pki/easy-rsa-36518.woJCtP/tmp.6ttbFr
Enter pass phrase for /usr/share/easy-rsa/3/pki/private/ca.key: #認証局の作成の時に設定したパスワードを入力
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
commonName            :ASN.1 12:'client0'
Certificate is to be certified until Apr  9 05:25:48 2023 GMT (825 days)

Write out database with 1 new entries
Data Base Updated
~~~

TLS秘密鍵の生成

~~~shell
cd /etc/openvpn/server
openvpn --genkey --secret ta.key
~~~

## サーバ側設定ファイルの作成

OpenVPNの設定ファイルを作成します。

~~~shell
vi /etc/openvpn/server/server.conf
~~~

~~~shell:/etc/openvpn/server/server.conf
port 1194 #Listenするポート
proto udp #udpで上記ポートで受け付ける
dev tun # サーバのLAN側ネットワークとVPNでブリッジする場合はdev tapを使う。 OpenVPNサーバでルーティングする場合はtunにする
ca /usr/share/easy-rsa/3/pki/ca.crt #
cert /usr/share/easy-rsa/3/pki/issued/server.crt #サーバー証明書
key /usr/share/easy-rsa/3/pki/private/server.key #サーバー秘密鍵
dh /usr/share/easy-rsa/3/pki/dh.pem #DH鍵
server 10.8.0.0 255.255.255.0 #クライアントに払い出すアドレス帯。dev tunにつくアドレスでもある。
ifconfig-pool-persist /etc/openvpn/server/ipp.txt
push "redirect-gateway def1 bypass-dhcp bypass-dns" #クライアントの全ての通信をOpenVPN経由にする。後ろのbypassはdhcpとdns通信のみローカルを通す設定。特にDHCPを使ってる環境ではbypass-dhcpが必須。dnsをbypassしない場合はpush "dhcp-option DNS 8.8.8.8"を下に書く
client-to-client #VPNクライアント同士の通信を許可
keepalive 10 120 #クライアントに10秒に１回死活監視パケットを送信。120秒間帰ってこなかったらクライアントがdownしていると見なす
tls-auth /etc/openvpn/server/ta.key 0 #TLS
cipher AES-256-CBC
persist-key
persist-tun
comp-lzo
status openvpn-status.log
verb 3
explicit-exit-notify 1
~~~

## openvpnの起動

@ serverのところは設定ファイル名です。（/etc/openvpn/server/server.conf）

~~~shell
systemctl enable openvpn-server@server.service
systemctl start openvpn-server@server.service
~~~

## firewalldの設定

openvpnを許可する設定を行います。
conohaのVPSはeth0にグローバルIPがついているのでeth0をexternalにします
※zoneをexternalにするとデフォルトでNATしてくれます

~~~shell
nmcli connection modify eth0 connection.zone external
nmcli connection modify tun0 connection.zone trusted

firewall-cmd --zone=external --add-service=openvpn --permanent
firewall-cmd --reload
~~~

~~~shell
[root@hoge ~]# firewall-cmd --list-all --zone=external
external (active)
  target: default
  icmp-block-inversion: no
  interfaces: eth0
  sources:
  services: openvpn ssh
  ports:
  protocols:
  masquerade: yes
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:
~~~

# クライアントの設定（macbook)

## scpで証明書のダウンロード

先ほど作成した証明書をmacbookの任意のディレクトリにダウンロードします。

~~~shell
scp -i ~/.ssh/test.pem root@XXX.XXX.XXX.XXX:/usr/share/easy-rsa/3/pki/ca.crt ./
scp -i ~/.ssh/test.pem root@XXX.XXX.XXX.XXX:/usr/share/easy-rsa/3/pki/issued/client0.crt ./
scp -i ~/.ssh/test.pem root@XXX.XXX.XXX.XXX:/usr/share/easy-rsa/3/pki/private/client0.key ./
scp -i ~/.ssh/test.pem root@XXX.XXX.XXX.XXX:/etc/openvpn/server/ta.key ./
~~~

## クライアント側設定ファイルの作成

Tunnelblickをダウンロードして起動します
https://tunnelblick.net/

設定ファイルをテキストで作成します。

~~~shell:testconfig.ovpn
client
dev tun
proto udp
remote XXX.XXX.XXX.XXX 1194 #接続先とポート
resolv-retry infinite
nobind
persist-key
persist-tun
ca /Users/hoge/workspace/openvpn/ca.crt #scpでダウンロードしたもの
cert /Users/hoge/workspace/openvpn/client0.crt #scpでダウンロードしたもの
key /Users/hoge/workspace/openvpn/client0.key #scpでダウンロードしたもの
tls-auth /Users/hoge/workspace/openvpn/ta.key 1 #scpでダウンロードしたもの
cipher AES-256-CBC
comp-lzo
verb 3
~~~

## 接続出来たことの確認

curlを行い、応答結果がVPNサーバのグローバルIPになっていれば無事つながっています。

~~~shell
% curl ipinfo.io/ip/
XXX.XXX.XXX.XXX
~~~

### 繋がってもブラウズできないサイトがある時

サーバやクライアント側にMTUかMSSの設定を追加してみてください
tunのMTUはデフォルト1500です。

~~~shell
mssfix XXXX
tun-mtu XXXX
~~~