Amazon EC2とOpenVPNでサーバ-多拠点クライアント間通信をセキュアに行う
はじめに
AWSを使ったシステム構成において、多数の拠点に設置されたクライアントからAWS上のサーバに接続するが、その通信はセキュアに行いたい、という要件が求められる場合があります。
今回はその要件を実現する方法の一つとして、Amazon EC2にOpenVPNサーバを構築し、WindowsクライアントからSSL-VPN接続を行いたいと思います。
サーバ側の設定
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にしています。
OpenVPNを使う場合、サーバ自体がルータのような動きになりますので、システムパラメータを編集しルーティングを有効にします。設定後は再起動しましょう。
$ sudo vi /etc/sysctl.conf net.ipv4.ip_forward = 1
併せて、AWS管理コンソールから、OpenVPNサーバとなっているEC2のSource/Dest CheckをDisabledにします。
では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サーバに向けます。
ふぅ。これでやっと、サーバ側の設定は完了です。
クライアント側の設定
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のインストール
公式サイトからインストーラをダウンロードし、実行します。インストーラが起動するので[次へ]ボタンをクリックします。
[ライセンス契約書]が表示されるので[同意する]ボタンをクリックします。
[インストール先の選択]画面が表示されます。特に変更せず[インストール]ボタンをクリックします。
インストールが完了します。[完了]ボタンをクリックします。
vpnux Clientの設定
Windowsのスタートボタンをクリックすると[vpnux Client]が追加されていますので、クリックして起動します。
[vpnux Client]画面が起動します。[プロファイル]ボタンをクリックします。
[プロファイル]画面が表示されます。[追加]ボタンをクリックします。
[プロファイルの編集]画面が開きますので、以下のような形で設定します。設定後[保存]ボタンをクリックします。
SSL-VPN接続する
[vpnux Client]画面に戻り、[プロファイル]欄に上記で作成したプロファイル名を指定し、[接続]ボタンをクリックします。
正常に接続できたら、以下のように表示されます。
試しにPingを実行してみると、ちゃんとAWS上にあるサーバのプライベートIPアドレスに対して疎通が出来ていることが確認できます!
SSL-VPNを自動接続する
vpnux Clientはコマンドプロンプトからも起動ができます。
これをログインしたタイミングで自動的に実行するようにしておけば、手作業を必要とせずに、システム起動と同時にSSL-VPN接続することが可能です。
さいごに
気軽に、かつ安価で、SSL-VPNによる他拠点クライアントのセキュア接続環境が構築できました。クライアントが増えるたびに秘密鍵と証明書を発行する、という手間はありますが、手順自体は難しいものではありませんし、ファイル自体が漏洩しない限り不正な利用は出来ませんので、安全な通信のためのトレードオフとしては手軽だと思います。