長らく買ったまま放置してたDash Buttonを何かに使おうと思って、ボタンをぽちったらSSL証明書(LetsencryptのDV証明書)の更新を行うようにしてみました

環境

実際のところ、ただ更新するだけならBitbucketとDroneを経由する必要はありませんが、もともと手動でタグ付けを行っていた環境があったのと、いつ更新したかをgitのログで管理出来る仕組みをそのままにしたかったので、このようにしました

Dash Buttonのハック

ハックというほどの事でもないですが、WiFi設定とMacアドレスが確認出来る所までやります

ウチの環境はMACアクセス制限をかけてたので、上記の記事を参考に、Fingアプリを使いました

Raspberry PI: anyenvを入れてpyenv環境をつくる

pyenv経由でやったほうが後々何かと役に立つので、anyenvでpyenvを入れます

※anyenvのインストール手順はリンク先の通りなのでここでは割愛します

1
2
3
4
5
6
7
8
9
// pyenvを入れる
$ anyenv install pyenv
$ exec $SHELL -l

// virtualenvも使えるようにする
$ git clone https://github.com/yyuu/pyenv-virtualenv ~/.anyenv/envs/pyenv/plugins/pyenv-virtualenv

// Pythonを入れる
$ pyenv install 3.6.2

Raspberry PI: virtualenvで環境を用意する

1
2
3
// パスなどは任意
$ cd /path/to/project
$ pyenv virtualenv 3.6.2 dash-button

Raspberry PI: pipでライブラリをインストール

こちらのライブラリを使わせてもらいます

1
$ pip install amazon-dash

単純なechoのみのymlを作成し、動作を確認します

1
2
3
4
5
6
7
8
9
$ vim amazon-dash.yml

settings:
delay: 10
devices:
xx:xx:xx:xx:xx:xx: ← Dash ButtonのMACアドレス
name: Nescafe
user: pi
cmd: echo "hoge"
1
2
3
4
// 権限はrootにする必要がある
$ sudo chown root:root amazon-dash.yml
$ sudo amazon-dash run
hoge ← Dash Buttonを押してhogeが出たらOK

Bitbucket: SSL更新のためのリポジトリを作る

(※設定ファイルをリポジトリ管理しない場合は飛ばして下さい)

letsencryptとHSTSでDockerコンテナ内にある自サイトをSSL化してみた時のメモの手順にあるように、設定ファイルはiniにしてあるので、このiniファイルのバージョン管理と同時に、このリポジトリにタグが切られたらWebサーバ側のSSL更新フラグを立てるようにします

Drone: 作ったリポジトリのpipelineを設定

(※設定ファイルをリポジトリ管理しない場合は、.drone.ymlの「script」の内容を、amazon-dash.ymlで実行して先に進んで下さい)

Drone自体の構築は、JenkinsからDroneに乗り換えてみた話などを参考にしてください

Droneの「Settings」にアクセスし、「Repository Hooks」の「tag」のみにチェックが入っているのを確認して保存

.drone.ymlは以下のように作成します

1
2
3
4
5
6
7
8
9
10
11
12
13
pipeline:

ssl-update:
host: "[certbot-autoを実行するホスト]"
username: "drone"
port: 22
image: appleboy/drone-ssh
secrets: [ ssh_key ]
script:
- "echo '1' > /var/tmp/cert-update"
- "chmod 666 /var/tmp/cert-update"
when:
event: tag

やっている事は単純で、certbot-autoを実行するホスト側の/var/tmp/cert-updateファイルに、「1」というフラグを立てに行っているだけです。
なので、Dashボタンが押されたら即、/var/tmp/cert-updateを更新しに行くように作成しても同じですので、
リポジトリ管理しない方はDash Button側のymlでそのように作成します

certbot: 証明書の更新

先ほど立てたフラグを検知してcertbot-autoを実行するスクリプトをcronで回します

1
2
$ crontab -l
0 18 * * * script -a /path/to/log/ssl-`date +\%Y\%m\%d`.log -c /path/to/cron.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ cat cron.sh

#!/bin/bash
STATUS=`cat /var/tmp/ssl-update`

if [[ "1" == ${STATUS} ]]; then
echo "0" > /var/tmp/ssl-update

echo "+++ Try ssh Web1 /etc/letsencrypt/ini/web1.ini Run the certbot."
ssh web1 /usr/local/bin/certbot-auto certonly --config /etc/letsencrypt/ini/web1.ini --non-interactive --agree-tos --expand
echo "+++ Try ssh Web2 /etc/letsencrypt/ini/web2.ini Run the certbot."
ssh web2 /usr/local/bin/certbot-auto certonly --config /etc/letsencrypt/ini/web2.ini --non-interactive --agree-tos --expand
echo "+++ Try ssh Web3 /etc/letsencrypt/ini/web3.ini Run the certbot."
ssh web3 /usr/local/bin/certbot-auto certonly --config /etc/letsencrypt/ini/web3.ini --non-interactive --agree-tos --expand

else
echo "/var/tmp/ssl-update is '0'. Skip for ssl-update."
fi