RaspberryPi2のFedora22にOpenVPN構築

コツコツと以前購入してoverclockしたraspberry pi2にOpenVPNを構築していました。
iPhoneでしか動作検証していませんが、iPhoneで繋がるならPCも繋がるでしょう。
Proxyサーバ立てておけばよかったと思った瞬間ですね。

今回は以下のものに導入してみました。
[VPNサーバ]
・Fedora22
・RaspberryPi2

今回は主にVPNサーバー構築(OpenVPN)を参考にしております。fedora22とかcenots7系だとfirewall等細かい部分が違いますが、全体としては同じような手順を踏んでいます。

まえがき

せっかくなので、最初に私が何故vpnを構築しようと考えたかということを記述しておきます。
私なりに調べた結果、そう思っているだけなので間違っているのか正しいのかは定かではありません。

  1. vpnが構築したかった。
  2. 屋内のサーバ複数あるため、いろいろ構築しているとルータのポートフォワードが増えてしまう
  3. 屋内のサーバそれぞれにhttps設定をするのが面倒臭い

1は手段と目的が逆なので置いておきます!

2ですが、屋内にいろいろ立てていくと家にあるルータに設定するポートフォワードの設定が増えていってしまいます。
1箇所開けておくだけなら良いのですが、これが4個、5個と増えていくとそれだけ脆弱になっていくということです。
また穴ごとにセキュリティ対策が必要になり、面倒だったり漏れが出たりしそうで管理しきれない(したくない)と感じました。
そこでvpnを構築してしまえば空いているのでvpnのポートとvpnサーバへのアクセスだけになり、その部分だけセキュアにしておけば基本大丈夫となるわけですね。
という割には、設定が細かく調べきれてないんですけどね。

3についてはssl証明書入れてないので通信がhttpで危ないので、ポートフォワードだとどうなの? ということです。
vpntls通信にしてしまえば、その通信の中でhttpを利用していてもvpn部分で暗号化されているのでhttpsになっているのと同じことになる(はず)。

というわけで、vpn導入に踏み切りました。
本音のところは1が動機の90%なんですけどね!

OpenVPNのインストール

パッケージのインストール

まずOpenVPNのインストールをしていきます。
構築時の2015/11/23時点ではFedora22のdnfでインストールできるopenvpnのバージョンは2.3.8です。

公式サイトからダウンロードできる最新も2.3.8のようでしたので、今回はdnfから導入を行なっていきます。
と言ってはいますが、wgetからインストールしようとしたらビルドで落ちてしまい原因が全く解決できなかったので諦めてdnfにしたというのが本音です。

[root@fedora-pi ~]# dnf install openvpn openssl  

認証局構築ツールのインストール

OpenVPNではeasy-rsa3という認証局構築のパッケージを利用しますので、そちらを導入していきます。

[root@fedora-pi ~]# wget https://github.com/OpenVPN/easy-rsa/archive/master.zip  
[root@fedora-pi ~]# unzip master.zip  
[root@fedora-pi ~]# cp -r easy-rsa-master/easyrsa3/ /etc/openvpn/  
  
# 不要となったファイルを削除  
[root@fedora-pi ~]# rm -rf easy-rsa-master/  
[root@fedora-pi ~]# rm -f master.zip  

認証局作成

まずは導入したeasy-rsa3を初期化します。

[root@fedora-pi ~]# cd /etc/openvpn/easyrsa3/  
[root@fedora-pi easyrsa3]# ./easyrsa init-pki  
  
init-pki complete; you may now create a CA or requests.  
Your newly created PKI dir is: /etc/openvpn/easyrsa3/pki  

出力を見ると分かりますが、認証局によって出力されるファイルを配置するフォルダを作成してくれているようです。
続いて認証局を作成します。
また途中でパスフレーズの入力を求められます。
ここで入力したものは今後何かと入力をすることが出てくるのでちゃんと覚えておきましょう。

[root@fedora-pi easyrsa3]# ./easyrsa build-ca  
Generating a 2048 bit RSA private key  
....+++  
...........................................+++  
writing new private key to '/etc/openvpn/easyrsa3/pki/private/ca.key.8BIwtMglzh'  
Enter PEM pass phrase:  
Verifying - Enter PEM pass phrase:  
-----  
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]:hogehoge  
  
CA creation complete and you may now import and sign cert requests.  
Your new CA certificate file for publishing is at:  
/etc/openvpn/easyrsa3/pki/ca.crt  

途中でCAを入力する箇所がありますが、自分で指定しても良いですし、未入力のままエンターでも良いです。
これでcaファイルが作成されました。

DH鍵の生成

鍵通信を行う際に利用するDH鍵を作成します。
なんでこれを行うのかというのはDH鍵交換に存在する脆弱性「Logjam」、HTTPSなどのプロトコルに影響のページをご確認ください。
これに限らず、仮に通信を傍受されても解読されづらく、もしくは実質解読不可能にするために行なっているということでしょうかね。

# logjam等の脆弱性への防衛手段としてdhパラメータを生成  
[root@fedora-pi easyrsa3]# ./easyrsa gen-dh  
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/easyrsa3/pki/dh.pem  

ちなみにOCしたraspi2で、だいたい45分くらいかかったんじゃないかと思います。
結構時間がかかるものみたいです。

サーバ用秘密鍵と証明書作成

次にサーバ側の秘密鍵と証明書を作成します。
今回はパスフレーズはなしで実行しています。
パスフレーズを設定する場合にはnopassオプションを外せばOKです。

[root@fedora-pi easyrsa3]# ./easyrsa build-server-full server nopass  
Generating a 2048 bit RSA private key  
.................+++  
........................................................................................+++  
writing new private key to '/etc/openvpn/easyrsa3/pki/private/server.key.newe37otTg'  
-----  
Using configuration from /etc/openvpn/easyrsa3/openssl-1.0.cnf  
Enter pass phrase for /etc/openvpn/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:'server'  
Certificate is to be certified until Nov  7 15:50:09 2025 GMT (3650 days)  
  
Write out database with 1 new entries  
Data Base Updated  

証明書廃止リストの作成

証明書の廃止リストを生成するには廃止された証明書が必要なので、リスト作成のために一旦ダミーの証明書を作成してリストの種にしていきます。

まずダミーの証明書を作成します。

[root@fedora-pi easyrsa3]# ./easyrsa build-client-full dummy nopass  
()  

続いて証明書を廃止します。

[root@fedora-pi easyrsa3]# ./easyrsa revoke dummy  
()  

最後に廃止リストを作成します。

[root@fedora-pi easyrsa3]# ./easyrsa gen-crl  
Using configuration from /etc/openvpn/easyrsa3/openssl-1.0.cnf  
Enter pass phrase for /etc/openvpn/easyrsa3/pki/private/ca.key:  
  
An updated CRL has been created.  
CRL file: /etc/openvpn/easyrsa3/pki/crl.pem  
[root@fedora-pi easyrsa3]# chmod o+r /etc/openvpn/easyrsa3/pki/crl.pem  
[root@fedora-pi easyrsa3]# chmod 701 pki  

最後の権限設定を行わないと、open vpnからファイルが見えなくなってしまい接続時にエラーとなるので忘れないよう気をつけて下さい。
別のフォルダに移動させて管理しても良いです。

これで認証局や証明書作成等については一通り準備完了です。

OpenVPNの設定

最初にインストールしたOpenVPNの設定を行っていきます。
ちなみに使うdiffに-uオプションつけるようにしました。こっちの方が変更がわかりやすいので。

# tls認証鍵作成  
[root@fedora-pi ~]# openvpn --genkey --secret /etc/openvpn/ta.key  
[root@fedora-pi ~]# cp /usr/share/doc/openvpn/sample/sample-config-files/server.conf /etc/openvpn/  
[root@fedora-pi ~]# diff -u /usr/share/doc/openvpn/sample/sample-config-files/server.conf /etc/openvpn/server.conf   
--- /usr/share/doc/openvpn/sample/sample-config-files/server.conf   2015-07-17 14:43:32.000000000 +0900  
+++ /etc/openvpn/server.conf    2015-11-23 18:16:18.139362405 +0900  
@@ -75,14 +75,20 @@  
 # Any X509 key management system can be used.  
 # OpenVPN can also use a PKCS #12 formatted key file  
 # (see "pkcs12" directive in man page).  
-ca ca.crt  
-cert server.crt  
-key server.key  # This file should be kept secret  
+;ca ca.crt  
+;cert server.crt  
+;key server.key  # This file should be kept secret  
+  
+ca easyrsa3/pki/ca.crt  
+cert easyrsa3/pki/issued/server.crt  
+key easyrsa3/pki/private/server.key  
   
 # Diffie hellman parameters.  
 # Generate your own with:  
 #   openssl dhparam -out dh2048.pem 2048  
-dh dh2048.pem  
+#dh dh2048.pem  
+;dh dh.pem  
+dh easyrsa3/pki/dh.pem  
   
 # Network topology  
 # Should be subnet (addressing via IP)  
@@ -140,6 +146,7 @@  
 # back to the OpenVPN server.  
 ;push "route 192.168.10.0 255.255.255.0"  
 ;push "route 192.168.20.0 255.255.255.0"  
+push "route 192.168.11.0 255.255.255.0"  
   
 # To assign specific IP addresses to specific  
 # clients or if a connecting client has a private  
@@ -241,7 +248,7 @@  
 # a copy of this key.  
 # The second parameter should be '0'  
 # on the server and '1' on the clients.  
-;tls-auth ta.key 0 # This file is secret  
+tls-auth ta.key 0 # This file is secret  
   
 # Select a cryptographic cipher.  
 # This config item must be copied to  
@@ -264,8 +271,8 @@  
 #  
 # You can uncomment this out on  
 # non-Windows systems.  
-;user nobody  
-;group nobody  
+user nobody  
+group nobody  
   
 # The persist options will try to avoid  
 # accessing certain resources on restart  
@@ -288,6 +295,7 @@  
 # or the other (but not both).  
 ;log         openvpn.log  
 ;log-append  openvpn.log  
+log-append  /var/log/openvpn/openvpn.log  
   
 # Set the appropriate level of log  
 # file verbosity.  
@@ -302,3 +310,6 @@  
 # sequential messages of the same message  
 # category will be output to the log.  
 ;mute 20  
+  
+management localhost 7505  
+crl-verify easyrsa3/pki/crl.pem  

基本的には参考にさせていただいたサイトの通りです。
ファイルの配置場所だけ、ちょっと変えています。

またuser, groupの権限をnobodyに設定しているのはroot権限で動作するのを防ぐためのようです。
万が一の際にroot権限で動作しているとサーバをグチャグチャに攻撃されてしまうので影響範囲を可能な限り少なくするのが大切ということですね。

またmanagementの設定をするとt、telnet localhost 7505などで現在接続中のクライアントを切断したりの管理機能が使えるみたいです。

ログ設定

ログフォルダの指定などをしたので、フォルダを作成します。

[root@fedora-pi ~]# mkdir /var/log/openvpn  
[root@fedora-pi ~]# vi /etc/logrotate.d/openvpn  
[root@fedora-pi ~]# cat /etc/logrotate.d/openvpn   
/var/log/openvpn/openvpn.log {  
    missingok  
    notifempty  
    sharedscripts  
    postrotate  
        systemctl restart openvpn 2>&1 > /dev/null || true  
    endscript  
}  

ついでにlogrotateも設定します。
そのうちlogrotateも全体的にしっかりと設定して、バックアップとったりしておきたいですね。

firewalld設定

この設定ですが、正直ちゃんと理解していません。
後々もう少し範囲を絞った適切な設定をしていきたいと思います。

[root@fedora-pi ~]# firewall-cmd --add-service=openvpn --permanent  
[root@fedora-pi ~]# firewall-cmd --permanent --direct --passthrough ipv4 -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE  
[root@fedora-pi ~]# firewall-cmd --zone=trusted --add-interface=tun0  
[root@fedora-pi ~]# echo 1 > /proc/sys/net/ipv4/ip_forward  
[root@fedora-pi ~]# echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf  
  
# 私個人的な設定。homeネットワーク以外からssh等を排除  
[root@fedora-pi ~]# firewall-cmd --add-source=10.8.0.0/24 --zone=home --permanent  
success  
[root@fedora-pi ~]# firewall-cmd --add-source=192.168.11.0/24 --zone=home --permanent  
success  
[root@fedora-pi ~]# firewall-cmd --remove-service=ssh --zone=public --permanent  
success  
[root@fedora-pi ~]# firewall-cmd --reload  
success  

firewall-cmd --zone=trusted --add-interface=tun0」の設定あたりから、よくわからないからフルオープンという匂いがしています。
一応この設定で、vpn接続後に家にある他のサーバ上にあるredmine等に接続できています。

OpenVPNの起動

何気に私はここでつまづきました。

[root@fedora-pi src]# ln -s /lib/systemd/system/openvpn\@.service /etc/systemd/system/multi-user.target.wants/openvpn\@server.service  
[root@fedora-pi src]# systemctl -f enable openvpn@server.service  
Removed symlink /etc/systemd/system/multi-user.target.wants/openvpn@server.service.  
Created symlink from /etc/systemd/system/multi-user.target.wants/openvpn@server.service to /usr/lib/systemd/system/openvpn@.service.  
[root@fedora-pi src]# systemctl start openvpn@server.service  

というのもサービスの名前に@が入っているなんて今まで経験したことがなかったので、コンパイルミスで残ってる途中生成ファイルか何かだと思い込んでいたのです。
普通にそのまま名前だったみたいです。

以上で、openvpnのインストール設定は完了です。
次はクライアント証明書を作成して接続です。

クライアント設定

open vpnサーバに接続するためにクライアントの設定を行います。

iPhoneの設定

まだPCは試してないので、今回はiPhoneから接続してみます。
もし家のwifiに繋いでいる方は、一旦wifiではなくキャリアの回線に戻してくださいね。

クライアント証明書作成(サーバ側)

まずは証明書を作成します。これはサーバで実行します。

[root@fedora-pi easyrsa3]# ./easyrsa build-client-full iphone nopass  
Generating a 2048 bit RSA private key  
...........................................................................................................+++  
.......+++  
writing new private key to '/etc/openvpn/easyrsa3/pki/private/iphone.key.wQQzrNJXXe'  
-----  
Using configuration from /etc/openvpn/easyrsa3/openssl-1.0.cnf  
Enter pass phrase for /etc/openvpn/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:'iphone'  
Certificate is to be certified until Nov 19 15:38:32 2025 GMT (3650 days)  
  
Write out database with 1 new entries  
Data Base Updated  

iPhoneOpenVPNアプリはパスフレーズに対応していないようなので、nopassで作成します。

client用設定ファイル作成

続いてiPhonevpnクライアント用の設定ファイルを作成します。

[root@fedora-pi ~]# cp /usr/share/doc/openvpn/sample/sample-config-files/client.conf /etc/openvpn/client.conf  
[root@fedora-pi ~]# vi /etc/openvpn/client.conf  
[root@fedora-pi ~]# mv /etc/openvpn/client.conf /etc/openvpn/iphone_client.conf  
[root@fedora-pi ~]# diff -u /usr/share/doc/openvpn/sample/sample-config-files/client.conf /etc/openvpn/iphone_client.conf  
--- /usr/share/doc/openvpn/sample/sample-config-files/client.conf   2015-07-17 14:43:32.000000000 +0900  
+++ /etc/openvpn/iphone_client.conf 2015-11-23 01:51:49.059753830 +0900  
@@ -39,8 +39,9 @@  
 # The hostname/IP and port of the server.  
 # You can have multiple remote entries  
 # to load balance between the servers.  
-remote my-server-1 1194  
+;remote my-server-1 1194  
 ;remote my-server-2 1194  
+remote hogehoge.ddns 1194  
   
 # Choose a random host from the remote  
 # list for load-balancing.  Otherwise  
@@ -85,9 +86,9 @@  
 # a separate .crt/.key file pair  
 # for each client.  A single ca  
 # file can be used for all clients.  
-ca ca.crt  
-cert client.crt  
-key client.key  
+;ca ca.crt  
+;cert client.crt  
+;key client.key  
   
 # Verify server certificate by checking that the  
 # certicate has the correct key usage set.  
@@ -105,7 +106,8 @@  
   
 # If a tls-auth key is used on the server  
 # then every client must also have the key.  
-;tls-auth ta.key 1  
+;tls-auth [inline] 1  
+key-direction 1  
   
 # Select a cryptographic cipher.  
 # If the cipher option is used on the server  
@@ -122,3 +124,101 @@  
   
 # Silence repeating messages  
 ;mute 20  
+  
+  
+<ca>  
+-----BEGIN CERTIFICATE-----  
()  
+-----END CERTIFICATE-----  
+</ca>  
+<cert>  
+-----BEGIN CERTIFICATE-----  
()  
+-----END CERTIFICATE-----  
+</cert>  
+<key>  
+-----BEGIN PRIVATE KEY-----  
()  
+-----END PRIVATE KEY-----  
+</key>  
+<tls-auth>  
+-----BEGIN OpenVPN Static key V1-----  
()  
+-----END OpenVPN Static key V1-----  
+</tls-auth>  

remoteには接続しに行くopen vpnサーバを指定します。
私の場合は、dnsddnsを利用しているのと家にルータがあるのでそこからポートフォワードの設定をしています。
特に問題なく通信は通っているので、家にネット環境に合わせた指定をしてもらえればだいたい動くと思います。

また証明書などのファイルはファイルそのものを指定して記述することもできるのですが、今回は設定ファイルに直接記述してみました。
ちょっと前までは tls-auth [inline] 1 の部分のように[inline]という指定が必要だったりしたみたいなのですが、現在はタグがあれば良いみたいです。
key-direction設定がないとtls-authが有効にならないようなので、忘れないようにしましょう。

私の場合にはファイルの中身はそれぞれ以下から取っています。
ca: /etc/openvpn/easyrsa3/pki/ca.crt
cert: ls /etc/openvpn/easyrsa3/pki/issued/iphone.crt
key: ls /etc/openvpn/easyrsa3/pki/private/iphone.key
tls-auth: /etc/openvpn/ta.key

あとは作成したファイルを自分のPCにダウンロードして、iTunesからiPhoneに転送してください。
そのときファイルの拡張子をovpnにするのを忘れないように。
細かい手順はiPhoneやiPad (iOS) でOpenVPNを使ってみよう!を参考にしていただいた方がわかりやすいかと思います。

以上でopen vpnの設定は完了です。

あとがき

今回はopen vpnの導入ということでコマンドを打ち込むぶんにはそんな大した量ではないのですが、そもそもvpnってなんだとか、通信が安全なのかとか調べてたら時間がかかりました。

もしうまく繋がらないということがあればtcpdumpなどを利用して通信がそもそも届いているか等調べてみましょう。

[root@fedora-pi ~]# dnf install tcpdump  
[root@fedora-pi ~]# tcpdump -i eth0 -n port 1194  

tcpdumpは何かと便利なので、まだあまり使ったことがない方はぜひ使ってみてください。

また今後はvpnに接続があったときにメールで通知したりしたいなぁと思っています。
できるのかなぁ?