OpenVPNでクラウドサーバと自宅のLinuxサーバ(?)の間をVPNでとりあえず接続してみた。

By | 2018年5月18日 , Last update: 2022年4月12日

はじめに

自宅でLinuxサーバ(?)として使用していた小型PC(AOpen MP67-D、以下単に「小型PC」と書きます。)をIntel NUC(NUC7i5BNH、以下単に「NUC」と書きます↓)

と交換するべく、仕事や買い物の合間を縫ってデータ等の移行作業が大好評進行中(2018年5月現在)です。

そこで、データ移行のついでにクラウドサーバと自宅のNUCの間のVPNをOpenVPNを使って接続することとしました。

この記事ではOpenVPNの設定やインストールの方法について書いていきます。

スポンサーリンク

クラウドサーバ側でのOpenVPNのインストール

OpenVPNは以下のコマンドをroot権限で実行するとインストールできます。

# dnf install openvpn

 

easy-rsa-3.0.5のダウンロード

GitHubからeasy-rsa-3.0.5のパッケージをZIPファイルとしてダウンロードします。ZIPファイルをダウンロードしたら、それをクラウドサーバ上の適当なディレクトリの下に展開します。すると、easy-rsa-3.0.5という名前のディレクトリが作られて、その下に以下のファイルやディレクトリが展開されます。

[panda@pandanote.info easy-rsa-3.0.5]$ ls -l
合計 24
-rw-rw-r–. 1 panda panda 1305 2月 27 00:29 COPYING.md
-rw-rw-r–. 1 panda panda 3231 2月 27 00:29 ChangeLog
-rw-rw-r–. 1 panda panda 160 2月 27 00:29 KNOWN_ISSUES
drwxrwxr-x. 2 panda panda 43 2月 27 00:29 Licensing
-rw-rw-r–. 1 panda panda 1970 2月 27 00:29 README.md
-rw-rw-r–. 1 panda panda 3335 2月 27 00:29 README.quickstart.md
drwxrwxr-x. 2 panda panda 46 2月 27 00:29 build
drwxrwxr-x. 3 panda panda 35 2月 27 00:29 distro
drwxrwxr-x. 2 panda panda 143 2月 27 00:29 doc
drwxrwxr-x. 3 panda panda 86 2月 27 00:29 easyrsa3
-rw-rw-r–. 1 panda panda 95 2月 27 00:29 op_test.sh
drwxrwxr-x. 2 panda panda 23 2月 27 00:29 release-keys

 

認証局、証明書及び秘密鍵並びにその他もろもろの作成

以下の作業では認証局を作成後、証明書等を前項のリストのうちのeasyrsa3ディレクトリの下で作成していきます。

認証局の初期化

以下のコマンドを実行し、認証局を初期化します。

[panda@pandanote.info easyrsa3]$ ./easyrsa init-pki
init-pki complete; you may now create a CA or requests.
Your newly created PKI dir is: /home/panda/openvpn/easy-rsa-3.0.5/easyrsa3/pki

 
このコマンドを実行すると、easyrsaと同じディレクトリにpkiディレクトリが作成されます。

[panda@pandanote.info easyrsa3]$ ls -l
合計 60
-rwxr-xr-x. 1 panda panda 37427 2月 27 00:29 easyrsa
-rw-rw-r–. 1 panda panda 4560 2月 27 00:29 openssl-easyrsa.cnf
drwx——. 4 panda panda 33 5月 16 22:44 pki
-rw-rw-r–. 1 panda panda 8459 2月 27 00:29 vars.example
drwxrwxr-x. 2 panda panda 78 2月 27 00:29 x509-types

 

認証局の作成


スポンサーリンク

以下のコマンドを実行し、認証局を作成します。Common Nameはデフォルト値としました。

[panda@pandanote.info easyrsa3]$ ./easyrsa build-ca
Enter New CA Key Passphrase: [パスフレーズ]
Re-Enter New CA Key Passphrase: [パスフレーズ]
Generating RSA private key, 2048 bit long modulus
……+++
……………………………………………………………………………………………….+++
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]:
CA creation complete and you may now import and sign cert requests.
Your new CA certificate file for publishing is at:
/home/panda/openvpn/easy-rsa-3.0.5/easyrsa3/pki/ca.crt

 

証明書失効リスト(CRL)の作成

以下のコマンドを実行し、証明書失効リスト(CRL)を作成します。

[panda@pandanote.info easyrsa3]$ ./easyrsa gen-crl
Using configuration from ./openssl-easyrsa.cnf
Enter pass phrase for /home/panda/openvpn/easy-rsa-3.0.5/easyrsa3/pki/private/ca.key:
 
An updated CRL has been created.
CRL file: /home/panda/openvpn/easy-rsa-3.0.5/easyrsa3/pki/crl.pem

 
なお、/var/log/openvpn.logに

VERIFY ERROR: depth=0, error=CRL has expired: CN=client

 
というような感じのログ(CRLの有効期限が切れたことを知らせるエラー)が表示された場合も、上記のコマンドを実行し、生成されたcrl.pemを/etc/openvpn/serverの下にコピーすると良いようです。

DHパラメータの生成

以下のコマンドを実行し、DH(Diffie-Hellman)パラメータを生成します。パラメータの生成には時間がかかりますので、ひたすら待ちます。

[panda@pandanote.info easyrsa3]$ ./easyrsa gen-dh
(中略)
DH parameters of size 2048 created at /home/panda/openvpn/easy-rsa-3.0.5/easyrsa3/pki/dh.pem

 

サーバ用秘密鍵及び証明書の作成


スポンサーリンク

以下のコマンドを実行し、サーバ用秘密鍵及び証明書を作成します。第2引数にはファイル名を指定します。また、接続開始時のパスフレーズを不要としたい場合には”nopass”を引数として追加します。

[panda@pandanote.info easyrsa3]$ ./easyrsa build-server-full pandanote.info nopass         Generating a 2048 bit RSA private key
..............+++
................................+++
writing new private key to '/home/panda/openvpn/easy-rsa-3.0.5/easyrsa3/pki/private/pandanote.info.key.qqs3TxRYZA'
-----
Using configuration from ./openssl-easyrsa.cnf
Enter pass phrase for /home/panda/openvpn/easy-rsa-3.0.5/easyrsa3/pki/private/ca.key:
Can't open /home/panda/openvpn/easy-rsa-3.0.5/easyrsa3/pki/index.txt.attr for reading, No such file or directory
140257658697472:error:02001002:system library:fopen:No such file or directory:crypto/bio/bss_file.c:74:fopen('/home/panda/openvpn/easy-rsa-3.0.5/easyrsa3/pki/index.txt.attr','r')
140257658697472:error:2006D080:BIO routines:BIO_new_file:no such file:crypto/bio/bss_file.c:81:
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
commonName            :ASN.1 12:'pandanote.info'
Certificate is to be certified until May 13 14:00:07 2028 GMT (3650 days)
 
Write out database with 1 new entries
Data Base Updated

クライアント用秘密鍵及び証明書の作成

以下のコマンドを実行し、クライアント用秘密鍵及び証明書を作成します。第2引数にはクライアント名を指定します。

クライアント名はちょっと手を抜いています。(´・ω・`)

また、接続開始時のパスフレーズを不要としたい場合には”nopass”を第3引数として追加します。

[panda@pandanote.info easyrsa3]$ ./easyrsa build-client-full client nopass
Generating a 2048 bit RSA private key
…………………………………………………..+++
…………………..+++
writing new private key to ‘/home/panda/openvpn/easy-rsa-3.0.5/easyrsa3/pki/private/client.key.5hnIpxYUJs’
—–
Using configuration from ./openssl-easyrsa.cnf
Enter pass phrase for /home/panda/openvpn/easy-rsa-3.0.5/easyrsa3/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:’client’
Certificate is to be certified until May 15 11:02:46 2028 GMT (3650 days)
 
Write out database with 1 new entries
Data Base Updated

 
上記のコマンドを実行すると、以下のファイルが作成されます。<第2引数で指定した文字列>を変更した場合にはクライアント用の設定ファイルの変更が必要です。

  • 秘密鍵(pki/privateの下に作成されます。): <第2引数で指定した文字列>.key
  • 証明書(pki/issuedの下に作成されます。): <第2引数で指定した文字列>.crt

OpenVPNサーバとしてのセットアップ

認証局、証明書及び秘密鍵並びにその他もろもろが作成できたら、クラウドサーバをOpenVPNにサーバとしてセットアップします。

サービス名の選択


スポンサーリンク

クラウドサーバがOpenVPNサーバになりますので、そのための設定を行います。なお、Fedora 26 ServerではOpenVPNに対応したサービス名が以下の3個あります。

  1. openvpn-client
  2. openvpn-server
  3. openvpn

/lib/systemdの下に上記のサービス名にそれぞれ対応する起動及び終了用のスクリプトがありますので、それらのファイルの内容を確認しておきます。その上でどのサービスを使用するかを決めます。クラウドサーバ側ではopenvpn-serverをサービスとして使用することとしました。

TLS認証鍵の作成

以下のコマンドを実行し、TLS認証鍵を作成します。作成したTLS認証鍵は /etc/openvpn/serverディレクトリの下に直接置いてしまいます。

[root@pandanote.info easyrsa3]# openvpn –genkey –secret /etc/openvpn/server/ta.key

 

設定用のファイルのコピー

root権限で以下のコマンドを実行し、「認証局、証明書及び秘密鍵並びにその他もろもろの作成」の項で作成したファイルを起動及び終了用のスクリプトで指定されているディレクトリの下にコピーします。SELinuxを”enforcing”に設定している場合にはchconコマンドも実行します。

[root@pandanote.info easyrsa3]# cp pki/ca.crt /etc/openvpn/server/
[root@pandanote.info easyrsa3]# cp pki/issued/pandanote.info.crt /etc/openvpn/server/
[root@pandanote.info easyrsa3]# cp pki/private/pandanote.info.key /etc/openvpn/server/
[root@pandanote.info easyrsa3]# cp pki/crl.pem /etc/openvpn/server/
[root@pandanote.info easyrsa3]# cp pki/dh.pem /etc/openvpn/server/
[root@pandanote.info easyrsa3]# chcon -t openvpn_etc_t /etc/openvpn/server/*

 

server.confの設定

スポンサーリンク

/usr/share/doc/openvpn/sample/sample-config-filesの下に設定ファイルのサンプル(server.conf)がありますので、これを/etc/openvpn/serverの下にコピーしてから、以下のように修正または追加します(コメント行が多いので、修正した部分と追加した部分のみを示します)。なお、ファイルパスは絶対パスまたは作業ディレクトリからの相対パスを指定します。また、ユーザID及びグループ名はnobodyではなく、openvpnを指定しています(こうしないと、client-config-dirの下のファイルが読めませんでした)。

cert pandanote.info.crt
key pandanote.info.key
dh dh.pem
server 192.168.0.0 255.255.255.0
push “route 192.168.0.0 255.255.255.0”
# comp-lzo
user openvpn
group openvpn
log-append /var/log/openvpn.log
# 以下の2行を追加します。
management localhost 7505 # OpenVPNの管理インターフェース
crl-verify crl.pem

 
[2022/04/12 補足] VORACLE攻撃を防ぐため、comp-lzoの設定は削除(上記の設定例ではコメントアウト)しました(VORACLE攻撃の詳細については[2]参照)。

SELinuxの設定の変更

OpenVPNの管理インタフェースを追加しているので、以下のコマンドを実行し、追加の際に指定したポート番号をOpenVPNが(SELinuxが有効になっている場合でも)管理インタフェースとして使用できるようにします。

# semanage port -a -t openvpn_port_t -p udp 7505

 

firewallの設定の変更

OpenVPNサーバはデフォルトの設定ではUDPの1194番ポートを使用しますので、OpenVPNサーバの起動の前にroot権限で以下のコマンドを実行し、使用可能な状態にしておきます。

# firewall-cmd --zone=<zone name> --add-service=openvpn
# firewall-cmd --zone=<zone name> --add-service=openvpn --permanent

 

ルータの設定

ルータの設定でUDPの1194番ポートを通過させるように設定します。具体的な設定の方法についてはルータごとに異なりますので、本記事では省略します。

OpenVPNサーバの起動

root権限で以下のコマンドを実行し、NUCのブート時にOpenVPNが自動的に起動するように設定しておきます。なお、第2引数のアットマークの後ろの文字列は、作業用ディレクトリ(/etc/openvpn/server)の下に置いた設定ファイルのファイル名のうち拡張子を除いたものを指定します。

[root@pandanote.info server]# systemctl enable openvpn-server@server
Created symlink /etc/systemd/system/multi-user.target.wants/openvpn-server@server.service → /usr/lib/systemd/system/openvpn-server@.service.

 
次にroot権限で以下のコマンドを実行し、OpenVPNを起動します。

[root@pandanote.info server]# systemctl start openvpn-server@server

 
この時点ではまだクライアントの設定を行っていませんが、以下のコマンドを実行し、tunインターフェースが存在することを確認します。

[root@pandanote.info server]# ip addr show
(中略)
13: tun0: mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 100
link/none
inet 192.168.0.1 peer 192.168.0.2/32 scope global tun0
valid_lft forever preferred_lft forever
inet6 fe80::6e8d:a678:2e39:f51e/64 scope link flags 800
valid_lft forever preferred_lft forever

 
まだ接続ができていませんが、tunインターフェースが追加されているようです。

これで、OpenVPNクライアントからの接続を受け付けるための準備が整いました。

OpenVPNクライアント側でのOpenVPNのインストール

OpenVPNサーバの設定が完了したら、OpenVPNクライアント側になるNUC側のインストール及び設定を行います。
OpenVPNは以下のコマンドをroot権限で実行するとインストールできます。

# dnf install openvpn

 

クライアント証明書及び秘密鍵並びにその他もろもろの設定

サービス名の選択

NUCがOpenVPNクライアントになりますので、そのための設定を行います。なお、Fedora 27 ServerではOpenVPNに対応したサービス名が以下の2個あります。

  1. openvpn-client
  2. openvpn-server

サーバ側と同様に/lib/systemdの下に上記のサービス名にそれぞれ対応する起動及び終了用のスクリプトがありますので、それらのファイルの内容を確認しておきます。その上でどのサービスを使用するかを決めます。NUC側ではopenvpn-clientをサービスとして使用することとしました。

サーバからのファイルのコピー

サーバから以下のファイルをNUCの/etc/openvpn/clientにコピーします。

  1. easy-rsaで作成したCAの証明書(ca.crt)、クライアントの証明書(client.crt)及び秘密鍵(client.key)
  2. /etc/openvpn/serverに作成したTLS認証鍵(ta.key)

 

client.confの設定

/usr/share/doc/openvpn/sample/sample-config-filesの下に設定ファイルのサンプル(client.conf)がありますので、これを/etc/openvpn/clientの下にコピーしてから、以下のように修正または追加します(コメント行が多いので、修正した部分と追加した部分のみを示します)。なお、ファイルパスは絶対パスまたは作業ディレクトリからの相対パスを指定します。

remote <サーバのIPv4アドレス> 1194
user nobody
group nobody
# comp-lzo

 
[2022/04/12 補足] VORACLE攻撃を防ぐため、comp-lzoの設定は削除(上記の設定例ではコメントアウト)しました(VORACLE攻撃の詳細については[2]参照)。

また、クライアントの証明書のファイル名がclient.crtでない場合、または秘密鍵のファイル名がclient.keyでない場合には上記の設定に加えて以下の設定が必要です。

cert <クライアントの証明書のファイル名>
key <クライアントの秘密鍵のファイル名>

 

SELinux用のコンテキストの変更

SELinuxを有効(enforcing)に設定している場合には以下のコマンドを実行し、設定ファイルなどののコンテキストを変更しておきます。

[root@pandanote.info client]# chcon -t openvpn_etc_t /etc/openvpn/client/*

 

OpenVPNの起動

root権限で以下のコマンドを実行し、NUCのブート時にOpenVPNが自動的に起動するように設定しておきます。なお、第2引数のアットマークの後ろの文字列は、作業用ディレクトリ(/etc/openvpn/client)の下に置いた設定ファイルのファイル名のうち拡張子を除いたものを指定します。

[root@pandanote.info client]# systemctl enable openvpn-client@client
Created symlink /etc/systemd/system/multi-user.target.wants/openvpn-client@client.service → /usr/lib/systemd/system/openvpn-client@.service.

 
次にroot権限で以下のコマンドを実行し、OpenVPNを起動します。

[root@pandanote.info client]# systemctl start openvpn-client@client

 
最後に以下のコマンドを実行し、クライアント側でもインターフェースが作成されていることと、pingが通ることを確認します。

[root@nuc client]# ip addr show
(中略)
5: tun0: mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 100
link/none
inet 192.168.0.6 peer 192.168.0.5/32 scope global tun0
valid_lft forever preferred_lft forever
inet6 fe80::8a49:3a36:dba:20a7/64 scope link stable-privacy
valid_lft forever preferred_lft forever
[root@nuc client]# ping 192.168.0.1
PING 192.168.0.1 (192.168.0.1) 56(84) bytes of data.
64 bytes from 192.168.0.1: icmp_seq=1 ttl=64 time=13.7 ms
64 bytes from 192.168.0.1: icmp_seq=2 ttl=64 time=13.7 ms
64 bytes from 192.168.0.1: icmp_seq=3 ttl=64 time=13.6 ms
^C
— 192.168.0.1 ping statistics —
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 13.616/13.720/13.794/0.155 ms

 
これで、ひとまず設定は完了です。

お疲れさまでした!!

まとめ

NUCへの移行の前まではPPTPを使ってVPNを構成してクラウドサーバと自宅のLinuxサーバ(?)の間を接続していましたが、移行作業を行っていた時点(2018年5月時点)ではPPTPを使い続けるのはあまりお勧めされなくなってきていましたので、OpenVPNへの移行もついでにすませてしまうこととした次第です。

セキュリティ関連のソフトウェアは設定項目が大量にあるものが多いですが、OpenVPNはそれに通信の確認作業もあるので、正直きついですね…

何とかしてください… (´・ω・`)

実は疎通確認の作業でかなりハマったので、次の記事でそれについて書きます。

この記事は以上です。

References / 参考文献