この記事ではDebian 10上に「OpenVPN」サーバ構築する手順を紹介します。
はじめに
先日、さくらのVPSのサーバを1台新たに契約し、セキュリティ強化のためにOpenVPNサーバを構築しました。その時の手順について紹介したいと思います。
VPNサーバを構築し、このサーバを経由してインターネットへ接続する事により、フリーWi-Fi等のセキュリティ的に不安のあるネットワークからでもセキュアに接続することが出来ます。
この記事では紹介しませんが、他にもVPN経由でのみWordpressの管理画面にログインできるように制御することも可能です。
OpenVPNとは
OpenVPNとは、OpenVPN Technologies, Inc. を中心に開発が行われているオープンソースのVPNソフトウェアです。インターネット上に仮想的なネットワークを構築し、離れた場所にあるホストやネットワーク間の通信を暗号化することによって、セキュアな通信を行うことが出来ます。
WindowsやLinux、MacOSはもちろんのこと、AndroidやiOSでも使用することが出来ます。専用のVPN機器が必要ないため、誰でも比較的簡単にVPNを組むことが可能です。
また、2002年4月にリリースされたバージョン1.1.0以降、重大な脆弱性の指摘を受けたことが無く、セキュリティ的にもかなり安心できるソフトウェアとなっています。
筆者の環境
サーバ | Debian 10 |
クライアント | Ubuntu 18.04 LTS |
VPS上でDebian 10が動作しており、Ubuntu 18.04 LTSのクライアントから接続します。
この記事の目標
サーバとクライアント間のトラフィックは暗号化し、クライアントからインターネットへアクセスする場合は、サーバを経由するように設定していきます。
インターネットアクセス時に暗号化されたネットワークを必ず通るため、暗号化されていないフリーWi-Fiに接続している場合でもセキュリティを確保することが出来るようになります。
また、OpenVPNではいくつかの認証方法を利用出来ますが、スタンダードな「証明書認証」を使用します。CAを時前で設置し、サーバ・クライアントごとに個別の「秘密鍵」、「証明書」を生成して認証を行います。
※ Windowsでのクライアント設定については別記事で紹介したいと思います。
設定
いよいよ設定を行っていきます。設定は以下の順番に行っていきます。
- CAの構築
- サーバ秘密鍵・証明書の生成
- DHパラメータの生成
- TLS認証鍵の生成
- クライアント秘密鍵・証明書の生成
- OpenVPNサーバの設定
- パケット転送の有効化
- IPマスカレードの設定
- OpenVPNクライアントの設定
サーバ
サーバで以下の操作を行います。
パッケージのインストール
必要なパッケージをインストールしていきます。
「easy-rsa」は認証に必要な各種ファイルを生成するために使用します。
「iptables-persistent」はiptablesの設定を恒久化するために使用します。
# apt update
# apt -y install openvpn easy-rsa iptables-persistent
CAの構築
セキュリティ上の理由から、CAとOpenVPNサーバは別々のマシンに分けることが推奨されていますが、今回は同一のマシンで運用を行います。
Easy RSAのディレクトリをコピーし、そこに移動します。
# cp -r /usr/share/easy-rsa /etc/openvpn/
# cd /etc/openvpn/easy-rsa/
証明書や鍵を作成するときのデフォルト値を設定する「vars」をサンプルを元に編集していきます。
# cp vars.example vars
「vars」の91~96行目を自分の環境に合わせて編集します。
set_var EASYRSA_REQ_COUNTRY "JP"
set_var EASYRSA_REQ_PROVINCE "Yamagata"
set_var EASYRSA_REQ_CITY "Sakata"
set_var EASYRSA_REQ_ORG "Flan999's Network"
set_var EASYRSA_REQ_EMAIL "admin@flan999.com"
set_var EASYRSA_REQ_OU "OpenVPN"
初期化を行います。
# ./easyrsa init-pki
Note: using Easy-RSA configuration from: ./vars
init-pki complete; you may now create a CA or requests.
Your newly created PKI dir is: /etc/openvpn/easy-rsa/pki
CAを構築します。途中で「Passphrase」の入力を求められるのでパスフレーズを入力して下さい。「Common Name」はそのままEnterで大丈夫です。
# ./easyrsa build-ca
Note: using Easy-RSA configuration from: ./vars
Using SSL: openssl OpenSSL 1.1.1d 10 Sep 2019
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 /etc/openvpn/easy-rsa/pki/.rnd into RNG
139804265505920:error:2406F079:random number generator:RAND_load_file:Cannot open file:../crypto/rand/randfile.c:98:File
name=/etc/openvpn/easy-rsa/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:
/etc/openvpn/easy-rsa/pki/ca.crt
以下のファイルが生成されるます。
/etc/openvpn/easy-rsa/pki/ca.crt | CAの証明書ファイル |
「/etc/openvpn/」にコピーします。
# cp pki/ca.crt /etc/openvpn/
サーバ秘密鍵・証明書の生成
以下を実行することで、サーバの秘密鍵と証明書ファイルが生成されます。「nopass」オプションにより秘密鍵はパスワード無しで生成されます。途中でパスフレーズを聞かれるので、「CAの構築」で設定したパスフレーズを入力して下さい。
# ./easyrsa build-server-full server nopass
Note: using Easy-RSA configuration from: ./vars
Using SSL: openssl OpenSSL 1.1.1d 10 Sep 2019
Generating a RSA private key
..........................................................+++++
.........................................+++++
writing new private key to '/etc/openvpn/easy-rsa/pki/private/server.key.e1HobpeL4E'
-----
Using configuration from /etc/openvpn/easy-rsa/pki/safessl-easyrsa.cnf
Enter pass phrase for /etc/openvpn/easy-rsa/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 3 11:22:04 2023 GMT (1080 days)
Write out database with 1 new entries
Data Base Updated
以下のファイルが生成されます。
/etc/openvpn/easy-rsa/pki/private/server.key | サーバ秘密鍵 |
/etc/openvpn/easy-rsa/pki/issued/server.crt | サーバ証明書 |
「/etc/openvpn/」にコピーします。
# cp pki/private/server.key /etc/openvpn/
# cp pki/issued/server.crt /etc/openvpn/
DHパラメータの生成
以下を実行してDHパラメータを生成します。生成には若干時間がかかります。
# ./easyrsa gen-dh
Note: using Easy-RSA configuration from: ./vars
Using SSL: openssl OpenSSL 1.1.1d 10 Sep 2019
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 /etc/openvpn/easy-rsa/pki/dh.pem
以下のファイルが生成されます。
/etc/openvpn/easy-rsa/pki/dh.pem | DHパラメータ |
「/etc/openvpn/」にコピーします。
# cp pki/dh.pem /etc/openvpn/
TLS認証鍵の生成
以下を実行してTLS認証鍵を生成します。
# openvpn --genkey --secret ta.key
以下のファイルが生成されます。
/etc/openvpn/easy-rsa/ta.key | TLS認証鍵 |
「/etc/openvpn/」にコピーします。
# cp ta.key /etc/openvpn/
クライアント秘密鍵・証明書の生成
クライアントの秘密鍵・証明書を生成します。途中でパスフレーズを聞かれるので、「CAの構築」で設定したパスフレーズを入力して下さい。
# ./easyrsa build-client-full client01 nopass
Note: using Easy-RSA configuration from: ./vars
Using SSL: openssl OpenSSL 1.1.1d 10 Sep 2019
Generating a RSA private key
............................+++++
........................................................................................................................
..+++++
writing new private key to '/etc/openvpn/easy-rsa/pki/private/client01.key.HGZe9Pboa7'
-----
Using configuration from /etc/openvpn/easy-rsa/pki/safessl-easyrsa.cnf
Enter pass phrase for /etc/openvpn/easy-rsa/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:'client01'
Certificate is to be certified until Apr 3 11:25:54 2023 GMT (1080 days)
Write out database with 1 new entries
Data Base Updated
以下のファイルが生成されます。
/etc/openvpn/easy-rsa/pki/private/client01.key | クライアント秘密鍵 |
/etc/openvpn/easy-rsa/pki/issued/client01.crt | クライアント証明書 |
「/etc/openvpn/client/」にコピーします。
# cp pki/private/client01.key /etc/openvpn/client/
# cp pki/issued/client01.crt /etc/openvpn/client/
OpenVPNサーバの設定
「/etc/openvpn/server.conf」を作成し、以下の内容を記述します。
port 1194
proto udp
dev tun
ca ca.crt
cert server.crt
key server.key
dh dh.pem
server 10.8.0.0 255.255.255.0
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 8.8.8.4"
keepalive 10 120
tls-auth ta.key 0
cipher AES-256-CBC
user nobody
group nogroup
persist-key
persist-tun
status /var/log/openvpn/openvpn-status.log
log /var/log/openvpn/openvpn.log
log-append /var/log/openvpn/openvpn.log
verb 3
explicit-exit-notify 1
設定内容について抜粋すると以下のようになっています。
port 1194 | 1194番ポートを使用 |
proto udp | プロトコルはUDPを使用 |
dev tun | ルーティング方式(tun)で接続 |
server 10.8.0.0 255.255.255.0 | VPNで使用するサブネット:10.8.0.0/24 |
push “redirect-gateway def1 bypass-dhcp” | クライアントの全てのトラフィックはVPNを経由する |
push “dhcp-option DNS 8.8.8.8” | クライアントに通知するDNSサーバ①:8.8.8.8 |
push “dhcp-option DNS 8.8.8.4” | クライアントに通知するDNSサーバ②:8.8.4.4 |
ちなみに、サンプルのコンフィグファイルは「/usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz」にありますので気になる方は参照してみて下さい。
OpenVPNを起動します。
# systemctl start openvpn@server
インターフェイスに「tun0」が追加されます。
# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 9c:a3:ba:06:bc:88 brd ff:ff:ff:ff:ff:ff
inet 153.127.41.234/23 brd 153.127.41.255 scope global ens3
valid_lft forever preferred_lft forever
inet6 fe80::9ea3:baff:fe06:bc88/64 scope link
valid_lft forever preferred_lft forever
3: ens4: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether 9c:a3:ba:08:43:28 brd ff:ff:ff:ff:ff:ff
4: ens5: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether 9c:a3:ba:09:c9:c8 brd ff:ff:ff:ff:ff:ff
6: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 100
link/none
inet 10.8.0.1 peer 10.8.0.2/32 scope global tun0
valid_lft forever preferred_lft forever
inet6 fe80::fa79:45c4:8d8d:88e0/64 scope link stable-privacy
valid_lft forever preferred_lft forever
パケット転送の有効化
VPNクライアントのインターネットへのアクセスはサーバを経由するため、パケット転送を有効化します。「/etc/sysctl.conf」の28行目のコメントを解除します。
net.ipv4.ip_forward=1
設定を反映させます。
# sysctl -p
net.ipv4.ip_forward = 1
IPマスカレードの設定
VPNクライアントのインターネットへのアクセスはサーバを経由しますが、その際にIPマスカレードをする必要があるため、iptablesの設定を行います。インターフェイス「ens3」は各自のサーバのインターネットへ接続しているものに置き換えて下さい。
# iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o ens3 -j MASQUERADE
以下を実行して、再起動後もiptablesの設定が保持されるようにします。
# iptables-save > /etc/iptables/rules.v4
クライアント
クライアントで以下の操作を行います。
パッケージのインストール
必要なパッケージをインストールしていきます。
「traceroute」はVPNサーバを経由してインターネットへ接続していることを確認するためにインストールします。
$ sudo apt update
$ sudo apt -y install openvpn traceroute
必要ファイルをサーバから転送する
サーバ上の以下のファイルをSCPやSFTP等を用いてクライアントへ転送します。
- /etc/openvpn/client/client01.key
- /etc/openvpn/client/client01.crt
- /etc/openvpn/ca.crt
- /etc/openvpn/ta.key
以下はSCPで転送する例です。一時的にサーバ側でrootユーザでのログインを有効化しています。
$ sudo scp root@153.127.41.234:/etc/openvpn/client/client01.key /etc/openvpn
$ sudo scp root@153.127.41.234:/etc/openvpn/client/client01.crt /etc/openvpn
$ sudo scp root@153.127.41.234:/etc/openvpn/ca.crt /etc/openvpn
$ sudo scp root@153.127.41.234:/etc/openvpn/ta.key /etc/openvpn
OpenVPNクライアントの設定
「/etc/openvpn/client.conf」を作成し、以下の内容を記述します。
client
dev tun
proto udp
remote 153.127.41.234 1194
resolv-retry infinite
nobind
user nobody
group nogroup
persist-key
persist-tun
ca ca.crt
cert client01.crt
key client01.key
remote-cert-tls server
tls-auth ta.key 1
cipher AES-256-CBC
verb 3
「remote」のOpenVPNサーバのIPアドレスは適宜書き換えて下さい。
OpenVPNクライアントを起動します。
$ sudo systemctl start openvpn@client
インターフェイスに「tun0」が追加されます。
$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 08:00:27:bb:14:75 brd ff:ff:ff:ff:ff:ff
inet 10.0.2.15/24 brd 10.0.2.255 scope global dynamic eth0
valid_lft 86032sec preferred_lft 86032sec
inet6 fe80::a00:27ff:febb:1475/64 scope link
valid_lft forever preferred_lft forever
3: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 100
link/none
inet 10.8.0.6 peer 10.8.0.5/32 scope global tun0
valid_lft forever preferred_lft forever
inet6 fe80::d9fa:2506:42e7:d0bc/64 scope link stable-privacy
valid_lft forever preferred_lft forever
経路の確認
「traceroute」コマンドでインターネットへの接続がVPNサーバを経由していることを確認します。
試しに「google.co.jp」のサーバまでのルートを調べてみます。
$ traceroute google.co.jp
traceroute to google.co.jp (172.217.26.3), 30 hops max, 60 byte packets
1 10.8.0.1 (10.8.0.1) 33.593 ms 33.315 ms 33.211 ms
2 153.127.40.2 (153.127.40.2) 74.832 ms 74.738 ms 74.638 ms
3 192.168.119.1 (192.168.119.1) 33.733 ms 34.482 ms 34.378 ms
4 iskrt301b-vps-is1a-rt01-2.sakura.ad.jp (103.10.115.117) 32.725 ms 34.008 ms 33.919 ms
5 iskrt1s-rt301b.bb.sakura.ad.jp (103.10.113.125) 33.826 ms 33.755 ms 33.621 ms
6 iskrt4-rt2s.bb.sakura.ad.jp (103.10.113.121) 33.579 ms iskrt3-rt1s.bb.sakura.ad.jp (103.10.113.109) 40.548 ms 40.
536 ms
7 tkert1-iskrt4.bb.sakura.ad.jp (157.17.131.37) 59.362 ms 57.157 ms 57.571 ms
8 as15169.ix.jpix.ad.jp (210.171.224.96) 57.664 ms 57.546 ms 57.550 ms
9 as15169.ix.jpix.ad.jp (210.171.224.96) 57.595 ms 57.677 ms 108.170.242.161 (108.170.242.161) 54.136 ms
10 66.249.95.89 (66.249.95.89) 54.169 ms 66.249.95.155 (66.249.95.155) 54.102 ms 108.170.242.161 (108.170.242.161) 5
5.483 ms
11 66.249.95.89 (66.249.95.89) 55.576 ms 66.249.95.155 (66.249.95.155) 55.569 ms nrt20s02-in-f3.1e100.net (172.217.26
.3) 50.543 ms
1行目を見ると、VPNサーバ(10.8.0.1)を経由していることが分かります。
最後に
OpenVPNサーバの設定は、生成しなければいけないファイルがたくさんあり慣れないと大変だと思います。私もなかなかうまくいかずに苦戦しましたので、そのメモとしてこの記事にまとめてみました。
今回はクライアントがUbuntuの場合で記事を書いてみましたが、別の記事にWindowsクライアントの設定についても紹介したいと思います。
コメント
[…] 前回の記事では、さくらのVPSサーバ上にOpenVPNサーバを構築し、Ubuntu 18.04 LTSのクライアントから接続までを行いました。 […]