LinuxでOpenVPNサーバーを構築する方法

LinuxでOpenVPNサーバーを構築する方法

最近では、リモートワークの普及などによって、会社や自宅のネットワークにVPN接続するというケースも増えているように思います。

VPN接続環境を用意する場合、専用のネットワーク機器を用意する方法が一般的ですが、既存のサーバー機器などがあるなら、ソフトウェアでVPN接続環境を構築できる「OpenVPN」はいかがでしょうか。

そこでここでは、OpenVPNの概要とRedhat互換のLinuxにOpenVPNサーバーを構築する方法を紹介します。

Linux上のOpenVPNサーバーへの不正アクセスをfail2banで防ぐ方法
ここでは、OpenVPNサーバー(CentOS 7+OpenVPN)にFail2banをインストールして不正アクセス対策する方法を紹介します。

この記事は、以下の環境での動作結果を基にしており、他のディストリビューションやソフトウェアのバージョンでは、動作結果が異なる場合があることをご了承ください。

ソフトウェアバージョン
CentOS Linux7.9.2009
easy-rsa3.0.8
openvpn2.4.11

OpenVPNとは

LinuxでOpenVPNサーバーを構築する方法

Business VPN | Next-Gen VPN | OpenVPN

OpenVPN.JP

OpenVPNは、OpenVPN Technologies, Inc. を中心に開発されているオープンソースのVPN(Virtual Private Network)ソフトウェアで、無償利用が可能で、LinuxやWindows、MacOSなどで利用可能です。

そのほか、OpenVPNの特長は次のとおりです。

  • 構築が比較的簡単にできる
  • 安定性や安全性に定評がある

想定環境

以降では、下図の構成でLinux(CentOS 7)にOpenVPNサーバーを構築する手順を紹介します。

LinuxでOpenVPNサーバーを構築する方法

Memo

なお、上の構成でOpenVPNサーバーを構築する(tun方式)場合、ローカル環境とリモート環境で同じローカルネットワークアドレス帯を使用していると正常に通信ができなくなるので、異なるネットワークアドレスを使用するよう調整しておく必要があります。

必要なツールをインストールする

まずは、OpenVPNと関連ツールをインストールします。

# yum install epel-release
# yum --enablerepo=epel install openvpn easy-rsa

「easy-rsa」は、認証局(CA)や鍵、証明書の作成に必要なツールです。

easy-rsaを設定する

必要なツールをインストールしたら、easy-rsaを使って、認証局(CA)を作成し、認証局⽤の秘密鍵と証明書を作成します。

認証局を作成する

まず「easyrsa init-pki」コマンドを実行して、認証局を初期化します。

# cd /usr/share/easy-rsa/3.0.8
# ./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.0.8/pki

つぎに「easyrsa build-ca」コマンドを実行して、認証局を作成します。

途中「pass phrase」と「Common Name(認証局の名前)」を設定する箇所があるので、管理しやすいパスフレーズと名前を設定します。

# ./easyrsa build-ca

Using SSL: openssl OpenSSL 1.0.2k-fips  26 Jan 2017

Enter New CA Key Passphrase:
Re-Enter New CA Key Passphrase:
Generating RSA private key, 2048 bit long modulus
........+++
..................+++
e is 65537 (0x10001)
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:
/usr/share/easy-rsa/3.0.8/pki/ca.crt

認証局が作成されると、認証局の秘密鍵と証明書が作成されます。

  • 認証局(CA)の秘密鍵:/usr/share/easy-rsa/3.0.8/pki/private/ca.key
  • 認証局(CA)の証明書:/usr/share/easy-rsa/3.0.8/pki/ca.crt

サーバー証明書を作成する

つぎに「easyrsa build-server-full」コマンドを実行して、OpenVPNサーバの秘密鍵と証明書を作成します。

途中、認証局を設置した際に設定したパスフレーズの⼊⼒が必要となります。

# ./easyrsa build-server-full server nopass

Using SSL: openssl OpenSSL 1.0.2k-fips  26 Jan 2017
Generating a 2048 bit RSA private key
.............................................................................+++
.................................................................................+++
writing new private key to '/usr/share/easy-rsa/3.0.8/pki/easy-rsa-1487.4k2vG0/tmp.M6uVFk'
-----
Using configuration from /usr/share/easy-rsa/3.0.8/pki/easy-rsa-1487.4k2vG0/tmp.z5xKYB
Enter pass phrase for /usr/share/easy-rsa/3.0.8/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 Jan 14 15:01:45 2024 GMT (825 days)

Write out database with 1 new entries
Data Base Updated

コマンドが正常に実行されると、OpenVPNサーバの証明書と秘密鍵が作成されます。

  • OpenVPNサーバの秘密鍵:/usr/share/easy-rsa/3.0.8/pki/private/server.key
  • OpenVPNサーバの証明書:/usr/share/easy-rsa/3.0.8/pki/issued/server.crt

クライアント証明書を作成する

つぎに「easyrsa build-client-full」コマンドを実行して、クライアントの秘密鍵と証明書を作成します。

コマンドの「user1」の部分には、任意のクライアント名を設定し、コマンド実行の途中に、認証局を設置した際に設定したパスフレーズの⼊⼒が必要となります。

また、コマンドに「nopass」を設定すると、OpenVPNサーバに証明書と秘密鍵だけでVPN接続できるようになりますが、セキュリティを強化したい場合は「nopass」を付けずに実行し、秘密鍵にパスワードを設定します。

# ./easyrsa build-client-full user1 nopass

Using SSL: openssl OpenSSL 1.0.2k-fips  26 Jan 2017
Generating a 2048 bit RSA private key
...................................................................................+++
......................................+++
writing new private key to '/usr/share/easy-rsa/3.0.8/pki/easy-rsa-1591.89e4WH/tmp.AbQaHp'
-----
Using configuration from /usr/share/easy-rsa/3.0.8/pki/easy-rsa-1591.89e4WH/tmp.Vs47C5
Enter pass phrase for /usr/share/easy-rsa/3.0.8/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:'user1'
Certificate is to be certified until Jan 14 15:12:10 2024 GMT (825 days)

Write out database with 1 new entries
Data Base Updated

コマンドが正常に実行されると、クライアントの証明書と秘密鍵が作成されます。

  • クライアントの証明書:/usr/share/easy-rsa/3.0.8/pki/issued/user1.crt
  • クライアントの秘密鍵:/usr/share/easy-rsa/3.0.8/pki/private/user1.key

TLS-Auth共有鍵とDHパラメータを作成する

つぎに、以下のコマンドを順に実行して、TLS-Auth⽤共有鍵とDiffie Hellman鍵交換方式で使⽤するDHパラメータを作成します。

# openvpn --genkey --secret ta.key
# ./easyrsa gen-dh

それぞれのファイルは、以下に作成されます。

  • TLS-Auth⽤共有鍵:/usr/share/easy-rsa/3.0.8/ta.key
  • DHパラメータ:/usr/share/easy-rsa/3.0.8/pki/dh.pem

OpenVPNを設定する

つぎに、OpenVPNサーバの設定を行います。

まず、以下のコマンドを順に実行して、easy-rsaの設定で作成したファイルのうち、下記を「/etc/openvpn」ディレクトリにコピーします。

  • ca.crt
  • server.key
  • server.crt
  • dh.pem
  • ta.key
# cd /usr/share/easy-rsa/3.0.8
# cp -p ta.key /etc/openvpn/
# cd pki
# cp -p ca.crt dh.pem private/server.key issued/server.crt /etc/openvpn

つぎに、以下のコマンドを順に実行して、サンプル設定ファイルをベースに設定ファイルを作成します。

# cp -p /usr/share/doc/openvpn-2.4.11/sample/sample-config-files/server.conf /etc/openvpn
# vi /etc/openvpn/server.conf

主だった設定項目は、次のとおりです。

項目名説明
port1194(既定値)使⽤ポート
protoudp(既定値)使⽤プロトコル
devtun(既定値)VPN方式
caca.crt(既定値)認証局証明書
certserver.crt(既定値)OpenVPNサーバ証明書
keyserver.key(既定値)OpenVPNサーバ秘密鍵
dhdh.pemDHパラメータ
server10.8.0.0 255.255.255.0(既定値)サーバ/クライアント割当IP
ifconfig-pool-persist ipp.txt(既定値)クライアントIP情報ファイル
push “route 192.168.200.0 255.255.255.0”ルーティング情報
keepalive10 120(既定値)死活監視設定
tls-authta.key 0(既定値)TLS-auth設定
cipherAES-256-CBC(既定値)暗号化⽅式
compresslz4-v2圧縮設定
push"compress lz4-v2"圧縮設定
max-clients50最⼤接続クライアント数
usernobody実⾏ユーザ
groupnobody実⾏グループ
status/var/log/openvpn-status.logログファイル
log/var/log/openvpn.logログファイル
verb3(既定値)ログレベル
Memo

ログファイルは、デフォルトでOpenVPNサーバーを起動するたびに削除されますが「log」の代わりに「log-append」を設定することで、ログが追記されるようになります。

なお、OpenVPNのログファイルは肥大化しやすいため、定期的に削除したり、ログレベルを調整するなどの工夫が必要になるでしょう。

設定ファイルを作成したら、以下のコマンドを実行してOpenVPNサーバを起動します。

# systemctl start openvpn@server

起動できたら、以下のコマンドを実行してシステム起動時に自動実行されるように設定しておきます。

# systemctl enable openvpn@server

なお、起動や動作に問題がある場合は、ログファイル「/var/log/openvpn.log」に情報が出⼒されていると思いますので、そちらを確認してみてください。

クライアントの接続・切断時に通知するには

OpenVPNでは、クライアントがVPN接続/切断したときにシェルスクリプトなどを実行させることができ、ログへ情報を書き込んだりメール通知させるといったことが可能になります。

VPN接続/切断時にスクリプトを実行させる場合は「server.conf」ファイルに、次の内容を追記します。

# cd /etc/openvpn
# vi server.conf

script-security 2
client-connect /etc/openvpn/connect.sh
client-disconnect /etc/openvpn/disconnect.sh

たとえば、VPN接続/切断時にメール通知させる場合は「connect.sh」と「disconnect.sh」を、以下の内容で作成します。

# vi /etc/openvpn/connect.sh

#!/bin/sh
mail -s "OpenVPN: connect:$common_name $untrusted_ip $ifconfig_pool_remote_ip" root
# vi /etc/openvpn/disconnect.sh

#!/bin/sh
mail -s "OpenVPN: disconnect:$common_name $untrusted_ip $ifconfig_pool_remote_ip" root
# chmod +x connect.sh disconnect.sh

ファイアウォール設定

つぎに、ファイアウォールの設定を行い、外部からの通信を許可します。

以下のコマンドを順に実行して、OpenVPNで使⽤するUDP/1194番ポートの開放し、IPマスカレード有効化します。

# firewall-cmd --permanent --add-port=1194/udp
success
# firewall-cmd --permanent --add-masquerade
success
# firewall-cmd --reload
success

以上でOpenVPNサーバーの設定は完了です。

クラアントからのVPN接続

つぎに、外部のクライアントマシンからVPN接続できるか確認します。

まず、サーバー上で作成した以下のファイルを、クライアントマシンにダウンロードします。

  • 認証局の秘密鍵「ca.crt」
  • クライアンの証明書「user1.crt」
  • クライアントの秘密鍵「user1.key」
  • TLS-Auth⽤共有鍵「ta.key」
  • サンプルプロファイル「/usr/share/doc/openvpn-2.4.11/sample/sample-config-files/client.conf」

あとは、ダウンロードしたサンプルプロファイルを接続環境に合わせて編集し、OpenVPNクライアントソフト「OpenVPN Connect」に設定ファイルをインポートすることで接続できるようになります。

詳しい手順は、以下の記事をご覧ください。

Windows 10からOpenVPNサーバーに接続する方法
ここでは、OpenVPNの公式サイトで提供されている「OpenVPN Connect」を使って、OpenVPNサーバーに接続する方法を紹介します。

あとがき

VPNを使ってリモートワーク環境を構築したいけど、費用はあまりかけられないといったときに「OpenVPN」はベストな選択肢ではないでしょうか。