VPNサーバの構築(OpenVPN)

2018年12月4日

この記事では、OpenVPNによるVPNサーバの構築方法を紹介します。

外出している際に、自宅内LANで提供しているサービスにアクセスしたくなる時があります。
ですが、セキュリティ上何でもかんでも外部にサービスを公開するわけにもいきません。

そこで、OpenVPNを使って自宅外のネットワークから自宅内LANへVPNを張って、セキュアな暗号化した通信を実現します。
自宅外のネットワークに接続しているクライアント(iPhoneやPC)とVPNサーバ間でVPNを張ると、自宅外にいても自宅内LANに接続しているように、プライベートIPアドレスでアクセス可能となります。

なお、今回はArchLinuxにおけるOpenVPNの設定として、セキュリティ上の理由から認証局(CA)サーバとVPNサーバは分離して構築します。機器としては、以下の通りです。

  • CAサーバ:クライアントとVPNサーバの証明書へ署名を行う認証局
  • VPNサーバ:自宅外のネットワークに接続しているクライアントとVPNを張るサーバ
  • クライアント:自宅外のネットワークに接続しているクライアント端末(iPhoneやPC等)

1.CAサーバの構築

1-1.easy-rsaのインストール

CAサーバにて以下のコマンドでeasy-rsaをインストールします。

$ sudo pacman -S easy-rsa

1-2.CAの構築

CAサーバにて以下のコマンドでPKIを初期化し、CAを構築します。

$ cd /etc/easy-rsa
$ sudo easyrsa init-pki
$ sudo easyrsa build-ca

上記の実行途中で、「Enter New CA Key Passphrase:」と表示されますので、CAのパスフレーズを任意に決めて、入力します。
Common Nameも聞かれますが、デフォルト値のままとします。

2.VPNサーバの構築

2-1.OpenVPNとeasy-rsaのインストール

VPNサーバにて以下のコマンドでOepnVPNとeasy-rsaをインストールします。

$ sudo pacman -S openvpn easy-rsa

2-2.CA公開証明書のコピー

1-2.で作成したCAサーバのCA公開鍵/etc/easy-rsa/pki/ca.crtをVPNサーバの/etc/openvpn/server/配下に保存します。保存時のca.crtのアクセス権はrootとしてください。

2-3.サーバ証明書の作成

VPNサーバにて以下のコマンドでPKIを初期化し、サーバ証明書を作成します。

$ cd /etc/easy-rsa
$ sudo easyrsa init-pki
$ sudo easyrsa gen-req server nopass
$ sudo cp /etc/easy-rsa/pki/private/server.key /etc/openvpn/server/

上記の実行途中にCommon Nameを聞かれますが、デフォルト値のままとします。

上記を実行すると、以下のファイルが作成されます。

  • /etc/easy-rsa/pki/reqs/server.req
  • /etc/easy-rsa/pki/private/server.key

2-4.Diffie-Hellman (DH) パラメータファイルの作成

VPNサーバにて以下のコマンドを実行して、DHパラメータファイルを作成します。

$ sudo openssl dhparam -out /etc/openvpn/server/dh.pem 2048

2-5.Hash-based Message Authentication Code (HMAC) 鍵の作成

VPNサーバにて以下のコマンドを実行して、HMAC鍵を作成します。

$ sudo openvpn --genkey --secret /etc/openvpn/server/ta.key

上記のコマンドで全てのSSL/TLSハンドシェイクパケットにHMAC署名が追加され、適切なHMAC署名が存在しないUDPパケットが拒否されるため、以下の攻撃を防ぎます。

  • ポートスキャン
  • OpenVPN の UDP ポートに対する DOS 攻撃
  • 未権限のマシンからの SSL/TLS ハンドシェイク
  • SSL/TLS 実装のバッファオーバーフロー脆弱性に対する攻撃

3.OpenVPNクライアントファイルの作成

クライアント用のOpenVPNクライアントファイルを作成します。easy-rsaがインストールされていれば作成できますので、今回はVPNサーバ上で作成します。

VPNサーバにて以下のコマンドを実行して、クライアント証明書を作成します。

$ cd /etc/easy-rsa
$ sudo easyrsa gen-req client1 nopass

上記の実行途中にCommon Nameを聞かれますが、デフォルト値のままとします。

上記を実行すると、以下のファイルが作成されます:

  • /etc/easy-rsa/pki/reqs/client1.req
  • /etc/easy-rsa/pki/private/client1.key

4.サーバ/クライアント証明書への署名

サーバー証明書とクライアント証明書に、CAによる署名を加えてVPNサーバとクライアントに送付する必要があります。

4-1.サーバ/クライアント証明書のコピー

VPNサーバ上で作成した以下の証明書要求ファイルをCAサーバの/tmp配下にコピーします。

  • /etc/easy-rsa/pki/reqs/server.req
  • /etc/easy-rsa/pki/reqs/client1.req

4-2.CAサーバでの署名

CAサーバにて以下のコマンドを実行し、証明書要求をインポートして署名します。

$ cd /etc/easy-rsa
$ sudo easyrsa import-req /tmp/server.req server
$ sudo easyrsa import-req /tmp/client1.req client1
$ sudo easyrsa sign-req server server
$ sudo easyrsa sign-req client client1

上記の途中でCAのパスフレーズを聞かれるので、1-2.で設定したパスフレーズを入力します。

上記を実行すると、以下のファイルが作成されます。

  • /etc/easy-rsa/pki/issued/server.crt
  • /etc/easy-rsa/pki/issued/client1.crt

4-3.VPNサーバとクライアントへのCA署名済証明書のコピー

4-2.で作成されたserver.crtをVPNサーバの/etc/openvpn/server/配下へコピーします。

5.OpenVPNの設定

5-1.サンプルファイルのコピー

VPNサーバにて以下のコマンドでOpenVPNのサンプルファイルをコピーします。

$ sudo cp /usr/share/openvpn/examples/server.conf /etc/openvpn/server

5-2.サーバ/クライアント証明書のコピー

5-1.でコピーしたserver.confを以下の通り設定します。

証明書と鍵

以下の通り設定します。

ca ca.crt
cert server.crt
key server.key
dh dh.pem

HMAC鍵

以下の通り設定します。

tls-auth ta.key 0

OpenVPNデーモンの権限

以下の通り設定することで、OpenVPNデーモンをルート権限なしで動作させ、外部からの攻撃に備えます。

user nobody
group nobody

ポート番号とプロトコル

今回はデフォルト値の1194/udpとします。

port 1194
proto udp

サブネット

今回はデフォルト値の10.8.0.0/24とします。

server 10.8.0.0 255.255.255.0

暗号方式

強固な暗号・認証方式、新しいtls暗号だけを使うように設定します。
なお、cipherとauthの値はクライアント側も同様に設定する必要があります。

cipher AES-256-CBC
auth SHA512
tls-version-min 1.2
tls-cipher TLS-DHE-RSA-WITH-AES-256-GCM-SHA384:TLS-DHE-RSA-WITH-AES-128-GCM-SHA256:TLS-DHE-RSA-WITH-AES-256-CBC-SHA:TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA:TLS-DHE-RSA-WITH-AES-128-CBC-SHA:TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA

圧縮

lz4-v2で圧縮します。
OpenVPN2.4より古いクライアントの場合はエラーになるか可能性があるので、その場合は以下をコメントアウトしたままにして、comp-lzoの方を有効にして下さい。

compress lz4-v2
push "compress lz4-v2"

通信経路

VPN接続にクライアントからのすべての通信をVPNサーバ経由で接続するようにします。
また、DNSはここでは、1.1.1.1としていますが、内部DNSサーバがある場合は適宜指定してください。

push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 1.1.1.1"

6.VPNサーバ動作確認

VPNサーバにてrootアカウントで以下のコマンドを実行し、エラーが無いことを確認します。

# cd /etc/openvpn/server
# openvpn /etc/openvpn/server/server.conf

以下のようなエラーが出た場合は、一度VPNサーバを再起動して、再度上記コマンドを実行してください。

Cannot open TUN/TAP dev /dev/net/tun: No such device

7.OpenVPNのサービス化

VPNサーバにて以下のコマンドを実行して、OpenVPNを自動起動するようにします。

sudo systemctl start openvpn-server@server.service
sudo systemctl enable openvpn-server@server.service

8.FWのアクセス許可

VPNサーバ上のiptablesでUDP1194番ポートへアクセスを許可します。

iptablesの具体的な設定方法は、以下の関連記事を参照ください。

関連記事→iptablesの設定

iptables -A INPUT -p udp --dport 1194 -j ACCEPT

また、VPNサーバ上でアクセスを許可したいサービスがあれば、以下のように、10.8.0.0/24からの通信を許可してください。

iptables -A INPUT -p tcp -s 10.8.0.0/24 --dport 22 -j ACCEPT

さら、VPN経由でインターネットや他のサーバにアクセスする場合は、以下のように10.8.0.0/24からの通信を許可します。
ここでは、【インターフェース名】はens192とします。

iptables -t nat -A POSTROUTING -o 【インターフェース名】 -s 10.8.0.0/24 -j MASQUERADE
iptables -I FORWARD -o 【インターフェース名】 -s 10.8.0.0/24 -j ACCEPT

9.クライアントプロファイルの作成

AURにあるovpngenを利用して、OpenVPN ConnectのiOSで使えるファイル形式で、OpenVPN 互換のトンネルプロファイルを作成します。

9-1.ovpngenのインストール

VPNサーバで以下のtrizenコマンドでovpngenをインストールします。

trizenを導入していない場合は、以下を参照して、適宜インストールしてください。
関連記事→trizenのインストール

trizen -S ovpngen

9-2.クライアントプロファイルの作成

ovpngenは5つの以下の引数を指定して、スクリプトを起動します。

  • OpenVPN サーバーのドメイン名 (またはIPアドレス)
  • CA 証明書のフルパス(ca.crt)
  • クライアント証明書のフルパス(client1.crt)
  • クライアント秘密鍵のフルパス(client.key)
  • サーバーTLS共有秘密鍵のフルパス(ta.key)

以下が例になります。以下のコマンドを実行すると、client.ovpnが作成されます。

 ovpngen 【サーバのドメイン名】 /etc/openvpn/server/ca.crt /etc/easy-rsa/pki/signed/client1.crt /etc/easy-rsa/pki/private/client1.key /etc/openvpn/server/ta.key > client.ovpn

9-2.クライアントプロファイルの編集

作成されたclient.ovpnを以下のように編集して、cipherとauthの値をVPNサーバと合わせます。

#cipher AES-256-CBC
cipher AES-256-CBC
#auth SHA512
auth SHA512

10.クライアントからの接続

9.で作成したclient.opvnをクライアント(macやiphone)に適宜コピーの上、VPN接続ソフトにインポートして、VPN接続を行います。

OSソフトウェア
MacOSTunnelblick
iPhoen(ios)OpenVPN Connect

終わりに

OpenVPNによるVPNサーバの構築を紹介しました。
これで、外出している際にも安全に自宅内LANにアクセスすることが可能となりました。外出先からも急ぎ自宅サーバを確認したい時もすぐにアクセスできて一安心です。