2022年08月14日

【スマートホーム】SSL証明書更新処理の自動サイクル

こんにちは。

先日似たような記事を書きました。そちらはSSL証明書更新処理結果のメール通知についてです。
今回は更新処理のサイクルについて書きます。



■Let's Encryptクライアント「Lego」の罠

SSL証明書はLet's Encryptの無料のものを利用しています。
Let's Encrypt公式のクライアントもあるのですがどうも評判がよろしくないようで、安定してると評価の高いLegoを利用しています。

Let's Encryptの証明書は90日で期限切れとなることは前回記事にも書きました。
じゃあ毎日更新しとけば安心じゃんと考えがちになってしまいますが、あまりに頻繁にリクエストすると認証局からブロックされてしまうそうです。
認証局として負荷を抑えるという目的でしょうかね。Legoもそうした方針を尊重しているようで、デフォルトでは有効期限が残り30日にならないと認証局に更新リクエストを送信しない仕様となっているようです。

実はこれに素直に従うとけっこうややこしいことになります。
月ごとに日数が異なったり2月は短かったり閏年があったり・・・ということをしっかり考慮して更新処理をスケジュールしておかないと、更新可能な30日間を取りこぼして期限切れになる可能性があります(後述)。



■定期実行のスケジュールにはcrontabを使う

crontabは指定した「月日時分秒」のパターンで同じ処理を繰り返し実行するようスケジュールできます。
SSL証明書の定期更新というタスクにはまさにうってつけで、ネット上の多くの例でも取り上げられています。
しかし「月日時分秒」でしか指定できないという点がネックとなり、更新可能30日間をすっぽりとスキップしてしまう危険も含んでいます。
例:毎月01日に更新処理をスケジュール
・01月31日が有効期限=更新可能な30日間は01月02日から開始
・01月01日に実行→更新可能期間前なので更新スキップ
・02月01日に実行→有効期限切れ

◇月2回実行
毎月2回実行していれば更新可能な30日間を取りこぼすことは無いでしょう。
しかし実際に更新できるまで少なくとも60日間あるのに2週間足らずのインターバルで無駄撃ちを重ねるのもカッコ悪いなあと思ったり。
更新処理は大した負荷ではないので気にすることはないんでしょうけど、こういうとこ気にしちゃう性格なんとかしたい。

◇その他の方法@
crontabでも工夫すれば「月日時分秒」ではなく「30日ごと」等で更新処理を動かすことも可能だそうです。
crontabのスケジュール自体は「毎日1回」としておき「当日が基準日からの経過日数30日ごとにあたる」場合にのみ更新処理を実行するという条件付けをする方法です。
しかし月2回実行以上に無駄撃ちしまくりですし、crontabの書き方もトリッキーになります。
パッと見て何やってるのか理解しにくいのが難点です。

◇その他の方法A
crontab以外にもタスクをスケジュールできるコマンドがあります。atコマンドです。
しかしatコマンドは「POSIX準拠」なる仕様だそうで、bashを標準シェルとしている多くのLinuxディストリビューションでは扱いにくいとのこと。
Raspberry Pi OSも例に漏れず、atコマンドからbashで書いたスクリプトを実行できない可能性が高いです。
そもそもRaspberry Pi OSにはatコマンドが含まれておらずインストールする必要があります。
また、atコマンド→shを呼び出し→bashを呼び出しという手間が発生し、やはり後々のメンテナンスが面倒なことになりそうです。



■Legoの理解不足だった

先程「デフォルトでは有効期限が残り30日にならないと認証局に更新リクエストを送信しない仕様」と書きました。
そうです、あくまでデフォルトではそういう仕様だというだけでオプションで変更することが出来ます。
勉強不足でこの点を見落としていました。むしろ30日制限は認証局側の制約だと勝手に誤解していました。

「--days xx」とオプション指定すれば残りxx日であれば更新を認証局にリクエストします。
なので、crontabで2ヶ月毎の01日にスケジュールして更新処理で--days 90とオプション指定しておけば、約60日ごとに証明書が更新されるサイクルが組めます。

crontab:隔月01日の03時15分に更新処理を実行する例
15 3 1 */2 * /etc/renew_ssl.sh

/etc/renew_ssl.sh:有効期限の残日数に関わらず強制的に証明書更新する例
いろいろ準備
lego xxxxxxxxx renew --days 90
いろいろ後処理


■まとめ

Legoの利用例はネット上にたくさん情報があるのですが「更新は月1回やっとけばいいっしょ」という論調が多い気がします。
しかしそこに上述のような罠が潜んでいる点まで言及している情報はありませんでした。
まあ私が読み取れていなかっただけって話しですけど・・・。
「30日制限は認証局側の制約」ってどこで誤解したんだろ・・・(´・ω・`)







.
posted by Huwy at 08:12 | Comment(0) | TrackBack(0) | スマートホーム | このブログの読者になる | 更新情報をチェックする

2022年07月28日

【スマートホーム】SSL証明書更新処理結果をNode-REDでメール送信

こんにちは。

先日、Raspberry Pi 4Bで稼働中のNode-REDを外部公開しました。
外部公開と言っても私自身が外部からアクセスしたいだけなんですが、お勉強がてらリバースプロキシサーバを立てたりファイアウォールを設定したり・・・さらに無駄にもSSL証明書まで適用してみたりしました。

そんなSSL証明書は無料のLet's Encryptを利用しており、90日で有効期限が切れるため定期的に更新する必要があります。
更新処理はシェルスクリプトで自動化し定期実行しているのですが、もし失敗している場合にそれに気付かないままだと有効期限切れとなってしまいます。
そこで成功/失敗に関わらず処理結果をメールで自分に送ることを検討してみました。


■上手くいかん

さっそくLinux端末からメール送信するためのプログラムをインストールしてみたのですがどうにも上手くいきません。
先人のお知恵を拝借しながらsSMTP, Exim4を試してみたのですが、両方ともダメでした。

□sSMTP
謎のエラーが発生してメール送信に失敗します。
これは多くの方も上げられている問題で、設定ファイルにAuthLogin="YES"を追記すれば行ける!などの情報も試してみたのですが上手くいきませんでした。

□Exim4
こちらはSMTPサーバに拒否られます。何故なのかはさっぱり分かりません。
ネットにはGmailを利用した例が多く挙げられていましたが、諸々の事情で私はAOLメールを使う前提としました。
ファイアウォールのポート許可など万障お繰り合わせしたはずなんですが、GmailとAOLの差分を上手く設定に反映できていないっぽい?
どこをどうしていいのやら・・・。


■上手くいっている例がある

今回の「シェルスクリプトからメール送信」とは別件で実はメール送信出来ている例があります。
Node-REDのemailノードです。
Node-REDで操作している家電の稼働状況をAOLメールで送信していて、問題なく使えています。
じゃあSSL証明書更新の結果もNode-REDに送信させてしまえ!と思い立ちました。


■すげえ簡単じゃん

更新処理の標準出力/標準エラーはキャッシュファイルに出力するようスクリプトを組んでいます。
このキャッシュファイルをNode-REDで読み取ってそのままメール本文として送信してしまえばいいわけです。
そんなNode-REDフローを新規作成しHTTPでリクエストを受け付けるようにしました。
(シェルスクリプトからNode-REDフローを呼び出すもっとクレバーな方法があるのかもしれませんが)

シェルスクリプトには自ホストのNode-RED実行ポートに向けてHTTPリクエストを投げる一文を追加。
上述のキャッシュファイルのフルパスをパラメータとして渡すようにしました。以下のようなイメージ。
さて結果は・・・無事に成功!これでわざわざログファイルを見にいかなくても成否をプッシュで検出できます。
うーん、Node-REDのemailノードに出来てsSMTPやExim4では出来なかった理由はなんなんでしょう。
結果オーライなら深掘りしないという私の軽薄なポリシーに則り、sSMTPやExim4のことは忘れることにします。


■余談
シェルスクリプトの定期実行はcrontabで行っていますが、crontabにはスケジュールしたジョブの成否をメール送信する機能があるそうですね。
しかしRaspberry Pi OSに組み込まれたcrontabにはその機能が除外されいるようです。メール送信に関する設定項目がありません。
(crontabのコメントにはなんかゴニョゴニョ書いてあるんだけどな・・・)
そもそもメール送信コマンドも組み込まれていないようで、mailutilsをインストールする必要がありました。






.

posted by Huwy at 23:23 | Comment(0) | TrackBack(0) | スマートホーム | このブログの読者になる | 更新情報をチェックする

2022年05月19日

【スマートホーム】3年越しの夢

こんにちは。

以前の記事にも書きましたが、我が家で契約しているプロバイダは自宅サーバの設置を認めていませんでした。
当時サポートに問い合わせて言質も得ていました。

しかしこの度、制限付きながら晴れて設置OKという運びになりました。
プロバイダの説明ではなんでもコロナ禍でリモートワークが増えてどーのこーの・・・。
いまさらコロナを理由に解禁するのも解せませんが、そもそもそれと自宅サーバがどういう関係があるのいまいち分かりません。
でもまあ結果オーライ。
これによってスマートホーム構築でやりたくても出来なかったことが一気に進むことになりました。

スマートホーム構築を始めたのが約3年前、ようやく夢が叶います。ドリカム。


■Beebotte

BeebotteというMQTTブローカについて何回か記事にしてきました。
我が家のスマートホームの要であるNode-REDに外部からリクエストするための超苦肉の策として使っていました。
私にとってかなり重要な位置付けのサービスなのに、そこそこ不安定で出来れば使うのやめたかったんですよね。

今にして思えば、公開できないゆえに外部から何も受け付けられないはずのNode-REDが、ことMQTTだけは受信できていた理屈を理解できていません。
HTTPリクエストとレスポンスのように、最初に接続を確立した時点のルートを保持し続けてたんでしょうかね?
ネット上の情報を丸々パクって構築していたので理解が及んでいませんでした。

Beeboteは、例えばSesameスマートロックの解錠/施錠イベントをNode-REDに到達させ最終的には照明などの家電操作までを自動化するフローの、迂回路として使っていました。
IFTTTのSesameトリガ(解錠) → WebhookでBeebotteにPublish依頼 → Node-REDのMQTTノードで受信
その他にもさまざまなイベントをNode-REDに到達させるためにBeebotteに頼りっぱなしだったわけです。
サーバ公開が可能となったことで、Node-REDが外部から直接リクエストを受け付けらるようになります。
上記の例で言えば、SesameAPIがIFTTTもBeebotteも経由することなくNode-REDのエンドポイントに直接リクエストできます。
もうBeebotte要らない!


■IFTTT

既に上記にも書きましたが、Sesameのイベントを拾う手段はIFTTTしかありませんでした。
これもNode-REDが直接拾えるようになったので、わざわざ経由させる必要がなくなります。
もうIFTTTも要らない!
(うそ、IFTTTはいろいろ便利なのでこれからも使います。Proプランも契約してるしね)


Smart Home 20220507_抜粋.png




■それでも道は険し

こうして外部サービスの依存度が下がってハッピーなのですが、その代わり今度はセキュリティがばがばのNode-REDを保護してやらなくてはいけません。
ぶっちゃけセキュリティ設定についてはまだお勉強中で、がばがばのまま外部公開されてる極めてリスキーな状態。
まあ悪意ある第三者がNode-REDに侵入できたところで、私が家電操作に少し手間取るだけですけど。


■まとめと共有

今回の作業をNotionにまとめて近日公開予定です。
プロバイダや利用サービスの限られたかなりニッチの狭い内容になりますが、ビンゴで当てはまる方の参考になれば幸いです。

2022/05/20追記:
書きました。






.


posted by Huwy at 01:50 | Comment(0) | TrackBack(0) | スマートホーム | このブログの読者になる | 更新情報をチェックする

2022年05月08日

【スマートホーム】我が家の現在の構成

こんにちは。

我が家のスマートホームの整理をしていた(Notionで!)過程で構成図を作ってみました。
我が家でしか通用しないごちゃごちゃ構成だし、個々の細かい説明も省いてるから何のこっちゃ分からんと思いますが、せっかく作ったので見てってー。

Smart-Home-20220507.png






.
posted by Huwy at 11:47 | Comment(0) | TrackBack(0) | スマートホーム | このブログの読者になる | 更新情報をチェックする

2021年08月08日

【スマートホーム】え?Beebotte終わり?

こんにちは。

我が家のスマートホームの構成要素の1つとして「マンションのエントランスドアを鍵を使わずに解錠する」というフローがあります。
このフローは次のような仕組みにしていました。
  1. スマホからMQTTブローカBeebotteにWebhook送信
  2. BeebotteからサブスクライバであるRespberryPiにメッセージ送信
  3. RaspberryPiのNode-REDでメッセージを受信しBluetooth経由でSwitchbotを操作
  4. Switchbotで室内インターホンのエントランスドア解錠ボタンを押下
このフローがひと月前ほどから不安定になり、エントランスで立ち往生することが頻発していました。
数回チャレンジすれば正常動作するので、私は上記3のBluetooth送信が不安定なのかなと思っていました。
ちなみにこの場合、普通に物理鍵を使って解錠してたので実害がありません。
こういう事態に備えて常に物理鍵を持ち歩くという全然スマートじゃないホームだったというわけです。

今日(2021/08/08)になって完全に動作しなくなってしまい、上記3を疑っている私はNode-REDのデバッグを実施。
その結果、Node-REDのBeebotteノードが受信待ちのままスタックしてしまっていることが分かりました。

MQTTでは実際のメッセージ送信前にブローカとサブスクライバの間で事前通信が行われます。
一応Beebotteノードが反応するので、この事前通信は問題ないようです。
おかしいなと思いBeebotteの公式サイトに何かしらの情報が無いかと確認してみました。

SS-2021-08-08 162956.jpg

・・・サーバ死んでるやんけ!
「GOTO HOMEPAGE」とかボタンが表示されていますが、これがそのホームページです。
え〜〜〜〜〜障害?メンテナンス?それともサービス終了?
ネット検索してみましたが何の情報も得られません。
いずれの原因にせよ何の事前通告も無いとなると突然の障害ということでしょうか?
ひと月前からの不安定さを放置し続けたとなれば、サービスを放棄したのでしょうか?
比較的最近書いた記事が現実となってしまい、サーバ設置を許可しないプロバイダに改めて舌打ちしてしまいましたよ。

さてこうなってしまった以上、対策を考えねばなりません。
別のMQTTブローカサービスを検討するのが現実的でしょう。
はあ、めんど。

追記:
本記事を投稿した2時間40分後の2021/08/08 20:00現在、復旧したようです。
サブスクライバとの疎通も確認出来ましたし、公式サイトも従来どおりアクセスできます。
ただし障害やメンテについての報告はどこにもありませんでした。
本件でいろいろネット検索している中で公式Twitterアカウントも確認しましたが、2019年以降ツイートしていないようです。
もうあまりやる気がないのかな・・・
もしものために引き続き他のMQTTブローカを検討しておこうと思います。






.
posted by Huwy at 17:40 | Comment(0) | スマートホーム | このブログの読者になる | 更新情報をチェックする