Amazon EC2とOpenVPNでサーバ-多拠点クライアント間通信をセキュアに行う

はじめに

AWSを使ったシステム構成において、多数の拠点に設置されたクライアントからAWS上のサーバに接続するが、その通信はセキュアに行いたい、という要件が求められる場合があります。

今回はその要件を実現する方法の一つとして、Amazon EC2にOpenVPNサーバを構築し、WindowsクライアントからSSL-VPN接続を行いたいと思います。

AWS_Design_OpenVPN_-_Cacoo

サーバ側の設定

EC2インスタンスの起動

EC2インスタンスを起動します。今回はAmazon Linux(amzn-ami-hvm-2014.09.2.x86_64-ebs (ami-18869819))を使いました。またElasticIPを付与しておきます。

OpenVPNのインストール

OpenVPNはyumで一発インストールできます。

$ sudo yum install -y openvpn

easy-rsaのインストール

OpenVPNには4つの認証方式があるのですが、今回は多拠点から接続されることから、証明書方式を使いますので、easy-rsaを使って認証局を構築します。

easy-rsaはコンパイル済みのバイナリとして提供されていますので、ダウンロードして展開します。

$ wget https://github.com/OpenVPN/easy-rsa/releases/download/v3.0.0-rc2/EasyRSA-3.0.0-rc2.tgz
$ tar -xvzf EasyRSA-3.0.0-rc2.tgz
$ sudo mv EasyRSA-3.0.0-rc2 /usr/local/EasyRSA
$ cd /usr/local/EasyRSA/
$ ls
COPYING    KNOWN_ISSUES  README.quickstart.md  easyrsa          vars.example
ChangeLog  Licensing     doc                   openssl-1.0.cnf  x509-types

認証局の設定

init-pkiで、認証局の初期化を行います。

$ ./easyrsa init-pki

init-pki complete; you may now create a CA or requests.
Your newly created PKI dir is: /usr/local/EasyRSA/pki

ここで生成されたpkiディレクトリに、認証局が生成されるデータが全て保存されます。

次にbuild-caで、認証局を作成します。Common Nameは適当につけます。今回はデフォルトのままとしました。

$ ./easyrsa build-ca
Generating a 2048 bit RSA private key
.....................................+++
.......+++
writing new private key to '/usr/local/EasyRSA/pki/private/ca.key'
Enter PEM pass phrase:<CA証明書のパスフレーズ>
Verifying - Enter PEM pass phrase:<CA証明書のパスフレーズ>
-----
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/local/EasyRSA/pki/ca.crt

CA証明書(/usr/local/EasyRSA/pki/ca.crt)が作成されます。

最後にgen-dhでDHパラメータを生成します。

$  ./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 /usr/local/EasyRSA/pki/dh.pem

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

build-server-fullで、サーバ用の秘密鍵と証明書の作成、署名を行います。また今回はパスフレーズ不要な形で作成しますのでnopassオプションを追加しています。

$ ./easyrsa build-server-full server nopass
Generating a 2048 bit RSA private key
.......................................+++
...........................................+++
writing new private key to '/usr/local/EasyRSA/pki/private/server.key'
-----
Using configuration from /usr/local/EasyRSA/openssl-1.0.cnf
Enter pass phrase for /usr/local/EasyRSA/pki/private/ca.key:<CA証明書のパスフレーズ>
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 Mar  8 07:43:25 2025 GMT (3650 days)

Write out database with 1 new entries
Data Base Updated

これでサーバ用の秘密鍵(/usr/local/EasyRSA/pki/private/server.key)と証明書(/usr/local/EasyRSA/pki/issued/server.crt)が作成されます。

クライアント用の秘密鍵と証明書の作成

build-client-fullで、クライアント用の秘密鍵と証明書の作成、署名を行います。また今回はパスフレーズ不要な形で作成しますのでnopassオプションを追加しています。クライアントの名前をclient1としており、拠点が増えるたびに別の名前で秘密鍵と証明書を作成します。

$  ./easyrsa build-client-full client1 nopass
Generating a 2048 bit RSA private key
.....................................................................+++
.........+++
writing new private key to '/usr/local/EasyRSA/pki/private/client1.key'
-----
Using configuration from /usr/local/EasyRSA/openssl-1.0.cnf
Enter pass phrase for /usr/local/EasyRSA/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:'client1'
Certificate is to be certified until Mar  8 07:31:37 2025 GMT (3650 days)

Write out database with 1 new entries
Data Base Updated

これでクライアント用の秘密鍵(/usr/local/EasyRSA/pki/private/client1.key)と証明書(/usr/local/EasyRSA/pki/issued/client1.crt)が作成されます。

OpenVPNサーバの設定

まず、作成したCA証明書、サーバ用証明書、サーバ用秘密鍵、DHパラメータを、/etc/openvpn下にコピーします。

$ sudo cp pki/ca.crt /etc/openvpn/
$ sudo cp pki/issued/server.crt /etc/openvpn/
$ sudo cp pki/private/server.key /etc/openvpn/
$ sudo cp pki/dh.pem /etc/openvpn/dh2048.pem

サーバの設定ファイルの雛形をコピーします。

$ sudo cp /usr/share/doc/openvpn-2.3.6/sample/sample-config-files/server.conf /etc/openvpn/server.conf

サーバの設定ファイルを修正します。有効行は以下の通り。「push "route"」行のみ、環境(AWS側のIPサブネット)に応じて編集します。

$ sudo vi /etc/openvpn/server.conf
port 1194
proto udp
dev tun
ca ca.crt
cert server.crt
key server.key
dh dh2048.pem
server 10.8.0.0 255.255.255.0
ifconfig-pool-persist ipp.txt
push "route 172.31.0.0 255.255.0.0"
keepalive 10 120
comp-lzo
user nobody
group nobody
persist-key
persist-tun
status openvpn-status.log
log-append  openvpn.log
verb 3

システムの設定

OpenVPNサーバに、セキュリティグループで1194/UDP通信を許可します。また今回はPingで疎通確認もしたいので、合わせてICMPもPermitにしています。

EC2_Management_Console 2

OpenVPNを使う場合、サーバ自体がルータのような動きになりますので、システムパラメータを編集しルーティングを有効にします。設定後は再起動しましょう。

$ sudo vi /etc/sysctl.conf
net.ipv4.ip_forward = 1

併せて、AWS管理コンソールから、OpenVPNサーバとなっているEC2のSource/Dest CheckをDisabledにします。

EC2_Management_Console

ではOpenVPNを起動します。

$ sudo service openvpn start
Starting openvpn:                                          [  OK  ]

$ sudo chkconfig openvpn on
$ sudo chkconfig openvpn --list
openvpn        	0:off	1:off	2:on	3:on	4:on	5:on	6:off

VPCの設定

今回の環境では、各拠点のクライアントからEC2への通信はOpenVPN経由で行われますが、その戻りの通信(EC2から各拠点のクライアントへの通信)もOpenVPN経由で行われなくてはいけません。そのためルーティングテーブルを修正し、各拠点ネットワークに対するゲートウェイをOpenVPNサーバに向けます。

VPC_Management_Console

ふぅ。これでやっと、サーバ側の設定は完了です。

クライアント側の設定

Windows用のOpenVPNクライアントは複数ありますが、今回はvpnux Clientを使います。

必要なファイルの転送

OpenVPNサーバ上で作成した以下のファイルを、SCPなどを使い、Windowsクライアント側に転送しておきます。

  • /usr/local/EasyRSA/pki/ca.crt
  • /usr/local/EasyRSA/pki/private/client1.key
  • /usr/local/EasyRSA/pki/issued/client1.crt

vpnux Clientのインストール

公式サイトからインストーラをダウンロードし、実行します。インストーラが起動するので[次へ]ボタンをクリックします。

Windows_7_x64

[ライセンス契約書]が表示されるので[同意する]ボタンをクリックします。

Windows_7_x64 2

[インストール先の選択]画面が表示されます。特に変更せず[インストール]ボタンをクリックします。

Windows_7_x64 3

インストールが完了します。[完了]ボタンをクリックします。

Windows_7_x64 5

vpnux Clientの設定

Windowsのスタートボタンをクリックすると[vpnux Client]が追加されていますので、クリックして起動します。

Windows_7_x64_と_vpnux_Client_-_OpenVPN_client_for_Windows

[vpnux Client]画面が起動します。[プロファイル]ボタンをクリックします。

Windows_7_x64 6

[プロファイル]画面が表示されます。[追加]ボタンをクリックします。

Windows_7_x64 7

[プロファイルの編集]画面が開きますので、以下のような形で設定します。設定後[保存]ボタンをクリックします。

Windows_7_x64 11

SSL-VPN接続する

[vpnux Client]画面に戻り、[プロファイル]欄に上記で作成したプロファイル名を指定し、[接続]ボタンをクリックします。

Windows_7_x64 12

正常に接続できたら、以下のように表示されます。

Windows_7_x64 13

試しにPingを実行してみると、ちゃんとAWS上にあるサーバのプライベートIPアドレスに対して疎通が出来ていることが確認できます!

Windows_7_x64 9

SSL-VPNを自動接続する

 vpnux Clientはコマンドプロンプトからも起動ができます。

Windows_7_x64 8

これをログインしたタイミングで自動的に実行するようにしておけば、手作業を必要とせずに、システム起動と同時にSSL-VPN接続することが可能です。

さいごに

気軽に、かつ安価で、SSL-VPNによる他拠点クライアントのセキュア接続環境が構築できました。クライアントが増えるたびに秘密鍵と証明書を発行する、という手間はありますが、手順自体は難しいものではありませんし、ファイル自体が漏洩しない限り不正な利用は出来ませんので、安全な通信のためのトレードオフとしては手軽だと思います。