UbuntuでOpenVPNサーバーを構築する

2018年6月5日金盾対策Linux, Ubuntu, VPN, OpenVPN, プロキシ, 金盾対策

これまでStrongswanを使用して、IKEv2やIPsecに対応したVPNサーバーを構築してきたのだが、OpenVPNサーバーはどんな感じなんだろうとおもってインストールしてみた。

OpenVPNをパッケージからインストール

これは非常に簡単。aptで一発。

$ sudo apt install openvpn easy-rsa

環境設定ファイルの作成

make-caコマンドを用い、設定ファイルを作成したのち、デフォルトの情報を一部編集する。
これらのファイルは、証明書の作成時に利用されるとのこと。

$ make-cadir ~/ca

作られたcaディレクトリのなかにvarsというファイルがあるので、そちらを開く。
次のように、KEY_COUNTRY等を日本に設定してあげる。 

# These are the default values for fields
# which will be placed in the certificate.
# Don't leave any of these fields blank.
export KEY_COUNTRY="JP"
export KEY_PROVINCE="TYO"
export KEY_CITY="Chiyoda"
export KEY_ORG="MyServer"
export KEY_EMAIL="MailAddr"
export KEY_OU="MyOrganizationalUnit"

その他の設定はとくにいじらず。

これらを環境変数に設定する。

$ source vars
NOTE: If you run ./clean-all, I will be doing a rm -rf on /home/***/ca/keys

ということで、caディレクトリの初期化を行う。

CA証明書と秘密鍵の作成

今回は証明書を用いた認証を行うので、CA証明書とCA秘密鍵の作成を行う。
正直、証明書だの秘密鍵だのは聞きたくもない単語なのだが、my-caを用いれば非常に簡単だ。

先ほどのcaディレクトリで、次のように入力する。

~/ca$ ./build-ca
Generating a 2048 bit RSA private key
....+++
.........................................................................................+++
writing new private key to 'ca.key'
-----
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.
-----
Country Name (2 letter code) [JP]:JP
State or Province Name (full name) [TYO]:TYO
Locality Name (eg, city) [Chiyoda]:Chiyoda
Organization Name (eg, company) [MyServer]:MyServer
Organizational Unit Name (eg, section) [MyOrganizationalUnit]:
Common Name (eg, your name or your server's hostname) [MyServer CA]:
Name [EasyRSA]:
Email Address [****]:

既に先ほど設定しているので、全部EnterでOK。

keysディレクトリに、ca.crt(CA証明書)とca.key(CA秘密鍵)が作成されているのが確認出来る。

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

今度はサーバー証明書。これも簡単で、次で一発OK。

./build-key-server server

keysフォルダには、server.crt(サーバー証明書)とserver.key(サーバー秘密鍵)が作成される。

DHパラメータ生成

DHパラメータとは、TLSを利用する際に必要となるもの。

./build-dh

ちょっと時間がかかるが、まあおいておこう。
keysフォルダには、dh2048.pemが作成される。

TLS認証用秘密鍵の作成

最後に、TLS認証用の秘密鍵を作成する。
これは、openvpnコマンドを使用し、keysフォルダのなかにta.keyとして入れてあげる。

openvpn --genkey --secret keys/ta.key

作成されたファイルのコピー

これで全てのファイルの作成が終了した。これらを全て、/etc/openvpnフォルダに入れてあげる必要がある。これまで作ったファイルは次の通りだ。全てkeysフォルダ配下に含まれている。

ファイル名 内容
ca.crt CA証明書
ca.key CA秘密鍵
server.crt サーバー証明書
server.key サーバー秘密鍵
dh2048.pem DHパラメータ
ta.key TLS認証用秘密鍵

さっさとコピーをしてしまう。

sudo cp ca.crt ca.key server.crt server.key ta.key dh2048.pem /etc/openvpn

クライアント証明書の作成

ここで一度クライアント用の証明書を作成しておく。
これも簡単で、build-keyを用いれば良い。証明書の名前をつけて。

./build-key iphone

keys配下には、「iphone.crt」(クライアント証明書)「iphone.csr」(CA証明書による署名)「iphone.key」(クライアント秘密鍵)が新たに生成される。

OpenVPNサーバーの設定

/etc/openvpnに「server.conf」というファイルを作成する。
以下の形でファイルを作成すれば大丈夫だ。

port   11940 #ポート番号
proto  udp #プロトコル
dev    tun #ルーティング方式を使用

ca          ca.crt #CA証明書の名称
cert        server.crt #サーバー証明書の名称
key         server.key #サーバー秘密鍵の名称
dh          dh2048.pem #DHパラメータの名称

ifconfig-pool-persist ipp.txt #IPアドレスのテーブルファイル

server 10.8.0.0 255.255.255.0 #VPNで使用するプライベートIPとサブネットマスク

push "redirect-gateway def1 bypass-dhcp" #トラフィックの全てをOpenVPN経由とする
push "route 192.168.11.0 255.255.255.0" #外部からLANへのトラフィックをVPNサーバー経由とする 
push "dhcp-option DNS 8.8.8.8" #GoogleDNSを使用
tls-auth ta.key 0                        #TLS認証有効化
cipher AES-256-CBC #認証形式
auth SHA512 #認証形式
comp-lzo #転送データのlzo圧縮有効化
client-to-client #クライアント間の接続を許可
keepalive 10 120 #生存確認を実施

user  nobody
group nogroup #Ubuntuはnobodyではなくnogroup

persist-key #設定の永続化
persist-tun

status      /var/log/openvpn-status.log
log         /var/log/openvpn.log
log-append  /var/log/openvpn.log

verb 3 #ログレベル

OpenVPNを起動する

ここにきて、OpenVPNを起動してみる。

service start openvpn@server

いくつかのサイトではそのまま「service start openvpn」で紹介されていたが、「@server」をつけないとうまく起動しなかった。
その際は、systemctlを用いて「openvpn」をdisabledし、「openvpn@server」をenabledすると良い。

systemctl disable openvpn
systemctl enable oepnvpn@server

IPtablesの設定変更

今回は10.8.0.0/8からのマスカレードと、udp/tcpでのOpenVPNへのアクセスを許可。enp0s31f6は外部へ接続されているポート。

iptables -A INPUT -i enp0s31f6 -m state --state NEW -p udp --dport 11940 -j ACCEPT
iptables -A INPUT -i tun+ -j ACCEPT
iptables -A FORWARD -i tun+ -j ACCEPT
iptables -A FORWARD -i tun+ -o enp0s31f6 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i enp0s31f6 -o tun+ -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
iptables -A OUTPUT -o tun+ -j ACCEPT

iPhoneから接続する

先ほど作成したクライアント証明書たちをひとつにまとめ、設定ファイルを作る。
具体的には、次のような形にする。

client
dev tun
proto udp
remote ホスト名 ポート
remote-cert-tls server
cipher AES-256-CBC #サーバー設定に合わせる
auth SHA512 #サーバー設定に合わせる
comp-lzo  #サーバー設定に合わせる

<ca>
-----BEGIN CERTIFICATE-----

</ca>
<cert>
-----BEGIN CERTIFICATE-----

</cert>
<key>
-----BEGIN PRIVATE KEY-----

</key>
key-direction 1
<tls-auth>
-----BEGIN OpenVPN Static key V1-----

</tls-auth>

これを.ovpnという拡張子で保存した後iPhoneに送信し、「OpenVPN Connect」アプリに入れれば、iPhoneからOpenVPNの利用が可能となる。これをiphone.ovpnという名前で保存する。

openvpn-w562

これをOpenVPN Cpnnectに読み込んであげると、このようにすぐに接続が出来る状態となり、ボタン一発でVPN接続が実現出来る。

肝心の速度は、正直あまり出ない。IKEv2などのほうが早いように感じる。が、中国での使用に関してはあまり規制されることがないらしい。
乞うご期待。