EC2にHTTPSでアクセスするための設定をご紹介します.
また, ドメイン名をすでに持っているという前提で話を進めます.
自分のサーバーのappache環境を載せておきます.
$ httpd -v Server version: Apache/2.2.34 (Unix)
安全な通信とは
HTTPSとHTTPの違いは, 通信の安全性が保証されているかにあります.
HTTP通信では, AさんがBさんへ送信した通信内容が, 第三者Cさんに盗聴, 改ざんされるおそれがあります.
一方でHTTPS通信では, 通信内容が暗号化されているため, HTTPと比較すると安全に通信を行うことができます.
しかし, 通信内容が暗号化されているだけでは十分に安全とは言えません.
Aさんがデータを送信している相手がBさんであれば安全ですが, 送信先が実はBさんではなく第三者Cさんであった場合, Aさんは気づかずに重要なデータを外部に送信してしまっていることになります.
そこで, 送信先Bさんは”SSL証明書”なるものによって, “Aさんがデータを送信しようとしている送信先は間違いなくBさんである”ということを証明する必要があります.
(SSL証明書のより詳しい仕組みはこちらにまとめられていますので, ぜひご参照ください.)
以下では, サーバー (上例でのBさん) が安全にHTTPS通信を受け付けるための手順を紹介します.
port 443の開放
最初に443番ポート (HTTPSのポート) が開いているか確認しましょう.
$ nmap -sT [サーバーのipアドレス or ドメイン名] Starting Nmap 6.40 ( http://nmap.org ) at 2019-02-13 06:42 UTC Nmap scan report for [サーバーのドメイン名] ([サーバーのipアドレス]) Host is up (0.00044s latency). rDNS record for [サーバーのipアドレス]: ec2-xxxxxxxxxxxxx.ap-northeast-1.compute.amazonaws.com Not shown: 998 filtered ports PORT STATE SERVICE 80/tcp open http 443/tcp closed https
一番最後の行に注目すると “443/tcp closed https” とありますが, この状態ではhttpsは開いてません.
そこで, iptablesというファイアウォールを管理するためのツールを利用しましょう.
このツールでは, 特定のポートへの通信を許可し, それ以外のポートへの通信をファイアウォールで弾く事ができます.
不必要なポートを開いていると攻撃の対象になってしまうため, 必要なポートのみを開放しましょう.
また, 似たようなパケットフィルタリングツールにfirewalldというものが存在しますが, iptablesとの共存はできないのでどちらか一方を使いましょう (どっちでもいいですが今回はiptablesでいきます).
以下のコマンドを実行しましょう.
$ iptables -A INPUT -p tcp -m tcp --dport 443 -j ACCEPT $ service iptables save $ service iptables restart
1行目で443番ポートの開放, 2行目で設定の変更を保存, 3行目でiptablesを再起動しています.
もう一度ポートの確認をして, 443番ポートが開いていれば成功です.
$ nmap -sT [サーバーのipアドレス or ドメイン名] Starting Nmap 6.40 ( http://nmap.org ) at 2019-02-13 06:42 UTC Nmap scan report for [サーバーのドメイン名] ([サーバーのipアドレス]) Host is up (0.00044s latency). rDNS record for [サーバーのipアドレス]: ec2-xxxxxxxxxxxxx.ap-northeast-1.compute.amazonaws.com Not shown: 998 filtered ports PORT STATE SERVICE 80/tcp open http 443/tcp open https
SSL証明書の取得
次に, 冒頭で紹介したSSL証明書を取得します.
SSL証明書は認証局 (CA) によってサーバーに発行され, “あるユーザーがアクセスしようとしているドメインは, 間違いなく本物のサーバーのドメインである”ということを証明してくれます.
SSL証明書を取得するには証明書署名要求 (CSR) をCAへ送信する必要があるのですが, 一般にこの作業には費用がかかります.
しかし, Let’s EncryptというCAは無料でSSL証明書を発行してくれるので, そちらを利用します.
次のようなコマンドを実行しましょう.
$ sudo curl https://dl.eff.org/certbot-auto -o /usr/bin/certbot-auto $ chmod 700 /usr/bin/certbot-auto $ sudo certbot-auto certonly --webroot -w /var/www/html -d [サーバーのドメイン名] --email [自分のメールアドレス] (略) IMPORTANT NOTES: Congratulations! Your Certificate and chain have been saved at: /etc/letsencrypt/live/[ドメイン名]/fullchain.pem Your key file has been saved at: /etc/letsencrypt/live/[ドメイン名]/privkey.pem (略)
1行目でcert-botという専用のツールをインストールします.
3行目でサーバーのドメイン名に対してSSL証明書を発行するための手続きを行います.
Congratulations! と出力されれば成功です.
ここで, 生成されたファイルの簡単な説明をします.
自分の環境では, /etc/letsencrypt/live/[ドメイン名]/というディレクトリに生成されました.
cert.pem
SSL証明書chain.pem
中間証明書fullchain.pem
サーバ証明書と中間証明書が結合されたファイルprivkey.pem
秘密鍵 (鬼大事です, 他人の手に渡らないように気をつけてください)
ちなみに, /etc/letsencrypt/csr/にCAへ署名を要求するためのCSRが生成されますが, SSL証明書がすでに発行された場合, こちらはもう不要です.
また, 次のコマンドで証明書の詳細を確認できます.
$ openssl s_client -connect [サーバーのドメイン名]:443 -showcerts
mod_sslのインストール
ApacheでSSL通信を行うためのモジュールにmod_sslというものが存在します.
まずはこれをインストールしましょう.
$ sudo yum -y install mod_ssl
/etc/httpd/conf.d/ssl.confが設定ファイルとして生成されます. 取得したSSL証明書のパスを書き込みましょう.
# Server Certificate: # Point SSLCertificateFile at a PEM encoded certificate. If # the certificate is encrypted, then you will be prompted for a # pass phrase. Note that a kill -HUP will prompt again. A new # certificate can be generated using the genkey(1) command. #SSLCertificateFile /etc/pki/tls/certs/localhost.crt // コメントアウト SSLCertificateFile [SSL証明書 (cert.pem) のパス] // 追加 # Server Private Key: # If the key is not combined with the certificate, use this # directive to point at the key file. Keep in mind that if # you've both a RSA and a DSA private key you can configure # both in parallel (to also allow the use of DSA ciphers, etc.) #SSLCertificateKeyFile /etc/letsencrypt/csr/0001_csr-certbot.pem // コメントアウト SSLCertificateKeyFile [秘密鍵 (privkey.pem) のパス] // 追加 # Server Certificate Chain: # Point SSLCertificateChainFile at a file containing the # concatenation of PEM encoded CA certificates which form the # certificate chain for the server certificate. Alternatively # the referenced file can be the same as SSLCertificateFile # when the CA certificates are directly appended to the server # certificate for convinience. #SSLCertificateChainFile /etc/pki/tls/certs/server-chain.crt // コメントアウト SSLCertificateChainFile [中間証明書 (chain.pem) のパス] // 追加
設定は以上で終了です.
Apacheを再起動しましょう.
$ service httpd restart
最後に, https://[サーバーのドメイン名]へアクセスできるか確認してみましょう.
Chrome右上の「︙→ その他のツール→ デベロッパーツール→ Security」をクリックすると, 証明書が正しく反映できているか確認ができます。