Iruca Log

Iruca Log

東京に住むWeb系エンジニアによる技術&雑記ブログ

SNSでフォローする!

信頼されたSSL証明書を無料で設置してHTTPSを有効化する方法まとめ(AWS EC2)

f:id:iruca21:20170801001215p:plain

目次

はじめに

こんにちは、irucaです。
最近HTTP/2に興味がわいてきて、機能を試してみたいと思いました。
しかしHTTP/2はHTTPSを前提としていて、HTTP(80番ポート)しか開けていない自分のAWSサーバ(EC2)では試すことすらできない!

自己証明書を設置するなら簡単ですが、いちいちブラウザ上で警告が出るのも厄介だし、せっかくなら信頼されるSSL証明書を設置しておきたい。
そんなこんなで調べていると、最近は無料で信頼できるSSL証明書が取得できるらしいではないか。

ということでさっそく試してみました。
自分のサーバでwebサイトを運用している人がサクッとHTTPS対応したければ本記事が参考になります。


下記の手順はAWSのEC2インスタンスを使い、Amazon Linuxで試しています。
CentOS6でも同じ操作になるかと思います。

[root@ip-172-31-25-63 conf.d]# cat /etc/system-release
Amazon Linux AMI release 2017.03

httpd 2.2をアンインストールして httpd 2.4 をインストール

webサーバにはApache HTTPDを使ってみましょう。
標準でインストールされるhttpdはhttpd2.2ですが、これではHTTP/2は動作しないですし、
せっかくなのでhttp2.4をインストールしましょう。

また、HTTPS対応のためにmod_sslを入れておきましょう。httpd v2.2の頃はmod_sslという名前でインストールできますが、
v2.4からは mod24_ssl という名前に変わっているので注意です。

後の作業で、操作中のサーバにhttp/httpsでアクセスできる状態になっている必要があるので、
httpdを起動してブラウザなどからインターネット越しにhttp,httpsでアクセスできることを確認しておきましょう。
まだこの段階ではブラウザから警告が出て、ブラウザに信頼されていない状態になるかと思います。

yum -y remove httpd httpd-tools
yum -y install httpd24 httpd24-tools mod24_ssl

service httpd restart

SSL証明書の作り方

HTTP/2 はHTTPSでアクセスできることが前提となっているので、httpdにSSLの設定をしなければなりません。
ということはSSLでアクセスするための証明書を発行しておく必要があります。

(参考までに) 自己証明書(オレオレ証明書)の作り方

実際にリリースするwebサイトやアプリケーションを作るときは信頼された認証局からSSL証明書を発行してもらう必要がありますが、面倒だという人は自己証明書を利用しましょう。

http://d.hatena.ne.jp/ozuma/20130511/1368284304
こちらのサイトを参考に、以下の3行を実行しましょう。

$ openssl genrsa 2048 > server.key
$ openssl req -new -key server.key > server.csr
$ openssl x509 -days 3650 -req -signkey server.key < server.csr > server.crt

私の環境で実行したときは以下のようになります。

[root@ip-172-31-25-63 conf.d]# openssl genrsa 2048 > server.key
Generating RSA private key, 2048 bit long modulus
...................................................................+++
.......................................................+++
e is 65537 (0x10001)
[root@ip-172-31-25-63 conf.d]# openssl req -new -key server.key > server.csr
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) [XX]:JP
State or Province Name (full name) []:Chiyoda-ku
Locality Name (eg, city) [Default City]:Tokyo
Organization Name (eg, company) [Default Company Ltd]:Iruca Log
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:app.iruca21.com
Email Address []:hhcksport@gmail.com

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
[root@ip-172-31-25-63 conf.d]# openssl x509 -days 3650 -req -signkey server.key < server.csr > server.crt
Signature ok
subject=/C=JP/ST=Chiyoda-ku/L=Tokyo/O=Iruca Log/CN=app.iruca21.com/emailAddress=hhcksport@gmail.com
Getting Private key

信頼できるSSL証明書を使用する場合

こっちが大事な方です!
上のオレオレ証明書の手順はやらなくてよいです。

ブラウザから見たときに警告が出るのを避けるためには、信頼された認証局で発行されたSSL証明書を作成する必要があるのです。
無料でSSL証明書を発行してくれるLet's Encryptというサービスがあることを知ったので、さっそく以下のページを参考に、自分用のSSL証明書を発行してみます。
hyper-text.org



私の場合は app.iruca21.com というドメイン名を持っていて、すでに操作中のサーバの外部IPアドレスにドメイン名を紐づけてあります。
ここではapp.iruca21.com ドメインのSSL証明書を取得してみましょう。



Let's Encryptを使ったSSL証明書の発行

Let's Encryptサービスを使ったSSL証明書の発行には、certbotというエージェントをインストールしておく必要があります。

その過程で、操作中のサーバにHTTPSでサーバにアクセスできる状態にしておく必要があります。
その時点では自己証明書(オレオレ証明書)を設置している状態でかまいません。

下記のコマンドに移る前に、HTTPSのポート(デフォルトで443番)を全IPに対して公開するようにファイアウォールやセキュリティグループを変更して、ブラウザからアクセスしたときに警告は出つつもHTTPSでアクセスできることを確認しておきましょう。
Connection refusedが出たり、Timeoutするようでは下記の手順はうまくいきません。

certbotのインストール

さて、certbotをインストールするにはepelのyum repositoryが必要となるので、
そこから行います。

yum -y install epel-release

vim /etc/yum.repos.d/epel.repo


epel.repoファイル内の[epel] セクションの中で
enabled=0
ではなく
enabled=1
となっており、epelリポジトリが有効化されていることを確認しましょう。

あとはこのページの方法に従ってcertbotをインストールしていきます。
Certbot クライアントのインストール - Let's Encrypt 総合ポータル


と言いたいところですが、私の使っているAmazon Linuxは通常通りの方法ではインストールできずハマるようです。

そこでこちらの方法に従って、pipやpythonのバージョンを上げてvirtualenvを仕込んでから臨んでいきます。
Amazon Linux で certbot(letsencrypt) を使って SSL 証明書を取得する - tkuchikiの日記


mkdir /home/ec2-user/certbot-test
cd /home/ec2-user/certbot-test
pip install --upgrade pip

# EC2でなぜかpipのアップグレード時にパスが外れてしまう問題に対応
vim /root/.bashrc
以下の2行を書き足して終了、PATHを更新するために一度SSHログインしなおしたりしましょう
PATH=$PATH:/usr/local/bin
export PATH

python --version
# Python 2.7系になっていることを確認
pip install virtualenv


wget https://dl.eff.org/certbot-auto
chmod a+x certbot-auto
./certbot-auto --debug


いろいろと対話式のコマンドで聞かれますが、きちんと英文を読みつつ対応を打ち込みましょう。
最終的に以下の出力が得られると成功です。

 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/app.iruca21.com/fullchain.pem. Your cert will
   expire on 2017-10-29. To obtain a new or tweaked version of this
   certificate in the future, simply run certbot-auto again with the
   "certonly" option. To non-interactively renew *all* of your
   certificates, run "certbot-auto renew"

virtualenvコマンドが上手くインストールできていなかったりPATHが通っていなかったり、
https(443番ポート) でインターネット越しにアクセスできなかったりするとエラーが出てうまくいきません。



成功すると、生成したSSL証明書一式をローカルに設置してくれます。

便利だ。





httpdにSSL設定を行う

さて、最後にhttpd用の設定ファイルをちゃんと書き換える必要があります。
certbotは自動的にSSL用のhttpd設定を書いて設置してくれたりしますが、上手く動かないことも多いです。

参考までに私の設定(/etc/httpd/conf.d/ssl.conf)をコピーしておきます。
私の場合は app.iruca21.com というドメイン名についてHTTPSでアクセスできるようにさせたいので下記のようなServerName設定になっています。
certbotがローカルに作成してくれたSSL証明書のファイルパスも自分用に適宜書き換えてください。

Listen 443 https

SSLPassPhraseDialog exec:/usr/libexec/httpd-ssl-pass-dialog
SSLSessionCache         shmcb:/run/httpd/sslcache(512000)
SSLSessionCacheTimeout  300
SSLRandomSeed startup file:/dev/urandom  256
SSLRandomSeed connect builtin
SSLCryptoDevice builtin

<VirtualHost _default_:443>

ServerName app.iruca21.com:443
ErrorLog logs/ssl_error_log
TransferLog logs/ssl_access_log
LogLevel warn
SSLEngine on
SSLProtocol all -SSLv3
SSLProxyProtocol all -SSLv3
SSLHonorCipherOrder on

SSLCertificateFile /etc/letsencrypt/live/app.iruca21.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/app.iruca21.com/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf

<Files ~ "\.(cgi|shtml|phtml|php3?)$">
    SSLOptions +StdEnvVars
</Files>
<Directory "/var/www/cgi-bin">
    SSLOptions +StdEnvVars
</Directory>

BrowserMatch "MSIE [2-5]" \
         nokeepalive ssl-unclean-shutdown \
         downgrade-1.0 force-response-1.0

CustomLog logs/ssl_request_log \
          "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"

</VirtualHost>





試しにアクセスしてみる

さて、最後にhttpdを再起動してアクセスしてみます。

[root@ip-172-31-25-63 conf.d]# httpd -t
Syntax OK
[root@ip-172-31-25-63 conf.d]# service httpd restart
Stopping httpd:                                            [  OK  ]
Starting httpd:                                            [  OK  ]


ブラウザからアクセスしてみる。


f:id:iruca21:20170801000025p:plain


おおー、ちゃんと信頼されとる!!



まとめ

自身のwebサイトに無料で信頼されるSSL証明書を発行・設置する方法をまとめました。
有効期間の短いSSL証明書ですが、certbot-auto renew コマンドで新しくもできるようです。

良い時代になったもんだなあ。