AWSでオートスケーリングなEC2にLetsencrypt(acme.sh)を使ってSSL証明書の自動取得・更新バッチShellを作った件

はい、クリスマスまで今日含めてあと13日ですね！

めでたい！めでたいけど・・・記事のタイトル面白くないね！
もう聞き飽きた！聞き飽きてるよそのネタ！って思われてると思いますが
クリスマスまであとすこしなので

**多めに見て下さい・・・**

## AWSでオートスケーリングなEC2の環境で、今度こそ証明書の自動取得・更新をしたい

一度諦めた人向けに、もうほっとけばやってくれる状態のshellをプレゼント！
クリスマスだしね！

[https://raw.githubusercontent.com/UNICORN-Project/UNICORN/master/supple/lifecycle/Nginx/sslsetting.sh](https://raw.githubusercontent.com/UNICORN-Project/UNICORN/master/supple/lifecycle/Nginx/sslsetting.sh)

**※ 今のところNginx専用**

## やってること(ざっくり)

- サーバにLetEncryt(acme.sh,Python2.7)環境を自動インストールします。
- サーバにGoofys(golang)環境を自動インストールします。
- s3にマウント用のバケットを自動生成します。
- s3を自動マウントします。
- s3の履歴から設定を自動復帰します。
- 証明書の自動取得・更新を行います。
- 指定されたディレクトリに取得・更新した証明書の配置を行います。
 - ※ サーバーのconfigを自動設定したりはしません。
- s3に履歴を自動保存します。
- 証明書の自動取得・更新完了後の結果をチャットワークとSlackに通知します。
- /etc/crontabに自動登録し、毎日更新チェックを行います。

## 使い方

#### [上記URL](https://raw.githubusercontent.com/UNICORN-Project/UNICORN/master/supple/lifecycle/Nginx/sslsetting.sh)からshellをDLし、ファイル内の以下の部分を埋めて下さい。

```
# ------------------------------- 変数定義ココから(適宜変更) ------------------------------- 

# 環境変数
# AWS IAMのS3リードライト権限のあるKEY情報を定義
export AWS_ACCESS_KEY_ID=XXX
export AWS_SECRET_ACCESS_KEY=XXXXXXXXX
export AWS_DEFAULT_REGION=ap-northeast-1

# 変数定義
# Slack設定(webhookurlがある場合のみ処理されます)
webhookurl=''
# サーバー監視通知チャンネル
channelname=projects
# 通知先(@xxx @xxx...形式で指定)
users='@user1 user2 '

# チャットワーク設定(apitokenが在る場合のみ処理されます)
apitoken=''
# サーバー監視通知ルーム
roomid=''
# 通知先([To:1234] [To:1234]...形式で指定)
members='[To:1234] [To:1234]'

# メール設定(メール通知が在る場合は通知先としても使われる)
notifymail=sslnotify@example.com

# プロジェクト名(UNICORN以外の場合は''(空文字)にして下さい)
projectname='Project'
# httpd実行時の権限ユーザー名
httpduser=nginx
# Nginxの設定再読み込みコマンドの定義(最後に自動実行してくれる)
restartcmd="service nginx restart && service php-fpm restart"
# Apacheの場合は↓を使って下さい
#restartcmd="service httpd restart"
# s3をマウントするパス設定(パスは無い自動生成されます)
mountpath=/s3mnt
# TOPドメイン用SSL証明書配置パス(パスは無い自動生成されます・httpdの設定・変更は自動ではしません)
topdomainsslpath=/var/www/.ssl
# Webドメイン用SSL証明書配置パス(パスは無い自動生成されます・httpdの設定・変更は自動ではしません)
webdomainsslpath=/var/www/.ssl
# APIドメイン用SSL証明書配置パス(パスは無い自動生成されます・httpdの設定・変更は自動ではしません)
apidomainsslpath=/var/www/.ssl
# 管理ページドメイン用SSL証明書配置パス(パスは無い自動生成されます・httpdの設定・変更は自動ではしません)
mgrdomainsslpath=/var/www/.ssl
# 静的ファイルドメイン用SSL証明書配置パス(パスは無い自動生成されます・httpdの設定・変更は自動ではしません)
staticdomainsslpath=/var/www/.ssl
# アプリドメイン用SSL証明書配置パス(パスは無い自動生成されます・httpdの設定・変更は自動ではしません)
appdomainsslpath=/var/www/.ssl
topdomaindocumentrootpath=/var/www/release/webdocs
webdomaindocumentrootpath=/var/www/release/webdocs
apidomaindocumentrootpath=/var/www/release/apidocs
mgrdomaindocumentrootpath=/var/www/release/lib/FrameworkManager/template/managedocs
staticdomaindocumentrootpath=/var/www/release/webdocs
appdomaindocumentrootpath=/var/www/release/webdocs
# ログパス
logpath=/var/www/logs
isdev=/var/www/.dev
isProd=/var/www/.production

# 環境によって設定が別れる変数の定義
# 開発環境用
devtopdomain=dev.your.domain
# SSLが不要なドメインの場合は、このようにドメイン設定を空文字にして下さい。documentrootpathは仮想で構わないので設定しておいて下さい
devwebdomain=devweb.your.domain
# SSLが不要なドメインの場合は、このようにドメイン設定を空文字にして下さい。documentrootpathは仮想で構わないので設定しておいて下さい
devapidomain=devapi.your.domain
devmgrdomain=devfwm.your.domain
devstaticdomain=''
devappdomain=''
devbacketname=projectbucketdev
devregion=ap-northeast-1
# リリース環境用
prodtopdomain=your.domain
# SSLが不要なドメインの場合は、このようにドメイン設定を空文字にして下さい。documentrootpathは仮想で構わないので設定しておいて下さい
prodwebdomain=www.your.domain
# SSLが不要なドメインの場合は、このようにドメイン設定を空文字にして下さい。documentrootpathは仮想で構わないので設定しておいて下さい
prodapidomain=api.your.domain
prodmgrdomain=fwm.your.domain
prodstaticdomain=''
prodappdomain=''
prodbacketname=projectbucket
prodregion=ap-northeast-1

# ------------------------------- 変数定義ココまで(適宜変更) ------------------------------- 

```

#### 埋めたらShellを実行。

```
sh sslsetting.sh
```

以上でLetsencryptによる証明書の取得と、以降の自動更新が設定されます。

#### オートスケールで自動更新

EC2のUserDataで、設定済みのshellをDLして実行するようにしておくのが簡単です。
CodeDeploy等を利用している場合は、デプロイ処理の中で設定済みのshellを実行するようにしておけば良いです。

## オマケ - なんでEC2なのにAmazonCertificateManager使わないの？

ACMを使ってELBに証明書を設定する場合、せっかくNginxなのに**HTTP2**が使えないと言うジレンマに陥ったから、ACMをやめてLetsに乗り換えたと言う経緯でした。
なので証明書の自動取得・更新がEC2出来るようになったら
今度はELB-EC2の組み合わせでHTTP2をやってみると良いです！オススメです！

## オマケ2 ELB-EC2(Nginx)でHTTP2を設定する

やり方は結構簡単で

- ELBでProxyProtocolを許可する
 - 参考 → [http://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/classic/enable-proxy-protocol.html](http://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/classic/enable-proxy-protocol.html)
- ELBの設定で443をTCPで転送するように設定を変える
- Nginxの設定で`listen 443`をProxyProtocolで受けるようにする

上記設定はこの辺り([AWSでのHTTP/2 or SPDY運用の課題とPROXY protocol(@dekokun)](http://developer.hatenastaff.com/entry/2016/04/19/140234))の記事が非常に参考になると思いますので参考にして是非HTTP2もトライしてみて下さい(*´v｀)

　

それではノシ

###### Created by [株式会社デジタルクエスト](https://www.digiq.co.jp) 大野 修平 ( [@saimushi](https://twitter.com/saimushi/) )