ubuntu 20.04 LTS serverにOpenVPNをインストール

ubuntu 20.04 LTS server にopenvpnをインストールした時の覚書です。

## openvpnのインストール
~~~
$ sudo apt install openvpn easy-rsa
~~~
でopenvpnとeasy-rsaをインストール。
## 認証キーの作成と準備
~~~shell:
$ make-cadir ~/ca
$ cd ~/ca
$ ./easyrsa init-pki
$ ./easyrsa build-ca

Note: using Easy-RSA configuration from: ./vars

Using SSL: openssl OpenSSL 1.1.1f  31 Mar 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)
Can''t load /home/nakane/ca/pki/.rnd into RNG
140149241394496:error:2406F079:random number generator:RAND_load_file:Cannot open file:../crypto/rand/randfile.c:98:Filename=/home/nakane/ca/pki/.rnd
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]:(ユーザーとかホストとかサーバ名とか)

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

$ ./easyrsa gen-dh
$ ./easyrsa build-server-full server nopass
$ cd pki
$ sudo cp ca.crt private/ca.key issued/server.crt private/server.key  /etc/openvpn
$ sudo openvpn --genkey --secret /etc/openvpn/ta.key
~~~
## OpenVPNサーバの設定

設定ファイル準備

~~~
$ gunzip -c /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz > ~/server.conf
$ sudo cp ~/server.conf /etc/openvpn/server.conf
~~~

設定ファイル編集

`$ sudo vi /etc/openvpn/server.conf`

で設定ファイルを開きます。

~~~
port 1194
proto udp
dev tun
ca ca.crt
cert server.crt
key server.key  # This file should be kept secret
dh none
auth SHA256
server 10.8.0.0 255.255.255.0
ifconfig-pool-persist /var/log/openvpn/ipp.txt
push "route 172.16.0.0 255.255.255.0"
push "dhcp-option DNS XX.XX.XX.XX"
push "dhcp-option DNS XX.XX.XX.XX"
push "redirect-gateway eth0"
keepalive 10 120
tls-auth ta.key 0 # This file is secret
cipher AES-256-GCM
user nobody
group nogroup
persist-key
persist-tun
status /var/log/openvpn/openvpn-status.log
log    /var/log/openvpn/openvpn.log
explicit-exit-notify 1
verb 3
~~~
自分が設定したのは以上です。
ローカルアドレスとイーサアダプタは自分の環境に置き換えてください。
`server`行はVPNに割り当てるアドレス空間設定。
`push "route hoge hoge"`は自アドレス空間で完結しないパケットをルーティングする設定。
`push "redirect-gateway eth0"`は全ての通信をVPN経由させる設定です。
他の項目の内容はサンプルファイルのコメント参照。

設定が終わったら
`$ sudo service openvpn start`
でopenvpnサーバを起動します。

`$ service openvpn status`
でサービスの状態を確認します。

~~~
● openvpn.service - OpenVPN service
     Loaded: loaded (/lib/systemd/system/openvpn.service; enabled; vendor prese>
     Active: inactive (dead) since Sat 2021-02-06 14:53:52 JST; 3h 52min ago
   Main PID: 24925 (code=exited, status=0/SUCCESS)

Feb 06 14:51:41 shimarin systemd[1]: Starting OpenVPN service...
Feb 06 14:51:41 shimarin systemd[1]: Finished OpenVPN service.~~~
~~~
動いてない…。
色々調べたら
`$ sudo service openvpn@server start`
でないと動かないことがあるらしい。
`$ service openvpn@server status`
でサービスの状態を確認。

~~~
● openvpn@server.service - OpenVPN connection to server
     Loaded: loaded (/lib/systemd/system/openvpn@.service; enabled-runtime; ven>
     Active: active (running) since Sat 2021-02-06 18:15:45 JST; 29min ago
       Docs: man:openvpn(8)
             https://community.openvpn.net/openvpn/wiki/Openvpn24ManPage
             https://community.openvpn.net/openvpn/wiki/HOWTO
   Main PID: 46107 (openvpn)
     Status: "Initialization Sequence Completed"
      Tasks: 1 (limit: 9301)
     Memory: 1.8M
     CGroup: /system.slice/system-openvpn.slice/openvpn@server.service
             mq46107 /usr/sbin/openvpn --daemon ovpn-server --status /run/openv>

Feb 06 18:15:45 server systemd[1]: Starting OpenVPN connection to server...
Feb 06 18:15:45 server systemd[1]: Started OpenVPN connection to server.
~~~
こんどは動きました、何が原因かはちょっと分かりませんが動いたのでヨシ。

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

サーバの準備はできたのでクライアント用の接続設定をします。

### 認証キー準備
~~~
$ cd ~/ca
$ ./easyrsa build-client-full user nopass
$ sudo cp pki/issued/user.crt pki/private/user.key /etc/openvpn
~~~

これでopenvpnサーバにクライアント用の認証ファイルが用意出来ました。

### クライアント設定ファイル作成準備

ホームに`ovpn_head`として以下のようなファイルを準備

~~~
client
dev tun
proto udp
remote server.FQDN 1194
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
key-direction 1
cipher AES-256-GCM
auth SHA256
verb 3
user nobody
group nogroup
~~~

次はこんな感じのスクリプトを作り、`chmod 755`しておきます。

~~~shell:mkovpn.sh
#!/bin/bash
ca_path=/home/user/ca/pki
key_path=/home/user/ca/pki/private
crt_path=/home/user/ca/pki/issued
if [ $# -ne 2 ]; then
       echo "mkovpn.sh HEADER CLIENT" 1>&2
       exit 1
fi
header=$1
target=$2
cat $header
echo '<ca>'
grep -A 30 'BEGIN CERTIFICATE' "$ca_path/ca.crt"
echo '</ca>'
echo '<key>'
cat "$key_path/$target.key"
echo '</key>'
echo '<cert>'
grep -A 30 'BEGIN CERTIFICATE' "$crt_path/$target.crt"
echo '</cert>'
~~~

一つ目の引数は準備したヘッダファイル名、二つ目の引数はユーザ名です。

`$ ./mkovpn.sh ovpn_head user > user.ovpn`

と実行して`user.ovpn`というファイルを作ります。
これをクライアントで設定すればVPN接続可能になります。

## ポートフォワード設定

`$ sudo vi /etc/sysctl.conf`
で

~~~
#net.ipv4.ip_forward=1
↓
net.ipv4.ip_forward=1
~~~
のようにコメントを外して再起動すればポートフォワードが有効になります。
~~再起動しないで反映するには普通にsudoしてもだめだったので~~
コメントでご指摘いただきました。
`$ sudo sysctl -p`
でちゃんと反映されますね、ありがとうございます。

~~~
$ sudo sysctl -a | grep ip_forward
net.ipv4.ip_forward = 1
~~~

でちゃんと設定されていることを確認。

この設定を忘れるとvpnに繋がるけどその先に繋がらない、となります、念のため。