WSL2を使ってみる
やりたいこと
サーバーを直接扱うでもいいんだけど、WSL2(Linux用WIndowsサブシステム)があったなぁって思い出したので、そろそろWindows内に環境を作ってみようという感じ。
遊ぶための環境って意味合いもあるけど、Docker Desktopを使用するためにセットアップが必要だったっていうのが大きい。
デフォルトのubuntuを使用する前提。
インストール用ドキュメント
代替はマイクロソフトのドキュメントを見れば問題なくセットアップは完了する。
Windows Subsystem for Linux に関するドキュメント | Microsoft Docs
WSLとWSL2の違い
違いとしてはここを見ればいい。
WSL 1 と WSL 2 の比較 | Microsoft Docs
WSLインストール
書いてある通り、コマンド1個でインストールまで完了する。
WSL のインストール | Microsoft Docs
sudo時にパスワード不要設定
とりあえず更新とかいろいろやっていくことになるけど、そのためにsudoが必要になってくるけど、わざわざパスワードを打ち込むのも面倒なので、sudoersの設定をやってあげることにする。
sudo時のパスワード入力を省略する【ubunutu/CentOS】 - F27P
更新
インストール直後だとWIndowsセットアップ直後みたいに、いろいろ更新作業が必要になる状態になっているので、手動で更新してあげる。
Windowsみたいに自動更新はないので、手動で更新するか、自動更新を仕込む必要がある。
とはいえ、メンドクサイノデ手動で十分だと思う。
Ubuntu のアップデート方法 - Qiita
日本語化
セットアップ直後は言語設定がデフォルトなので日本語では表示してくれない。
そのままでもいいけど、せっかくなので設定してみる。
WSL2のUbuntu 20.04を日本語化する - Qiita
ssh接続
Windows Terminalで使うだけならそこまで重要じゃないけど、Visual Studio CodeとかTeratermといったものでの接続を想定すると、ssh接続を行うのがよい。
そのための設定を行う。
といってもこの辺りはよくあるいつもの流れ。
WSL2のUbuntuにSSH(公開鍵/秘密鍵)で接続する - Qiita
WSLでsystemctlを使用する場合
WSLではMS製のinitが動いているらしく、systemctlでサービスの管理が行えない。
このままだとsshdをいちいち起動してあげないと使えないといったこともあるので、そのあたりが面倒であればwsl.confを使ったり、代替のsystemctlを入れる必要がある。
wsl.confを使用する場合
wsl.confで起動時にサービスを自動起動する設定が行える。
ただしこれは今のところWindows11でしか使用できないため、Windows10でこの設定を行うことは出来ない。
WSL での詳細設定の構成 | Microsoft Docs
systemctlでサービスの管理を行うためにはこれが詳しい。
wsl.confで制御出来ないのでwslコマンドのオプションで起動時にサービス開始するようにすることもできるが、それはそれでめんどくさいこともあるので、systemd代替のサービスを使用することで解決できる。
Windows 10 or 11 (WSL2)のUbuntuでsystemctlを利用する方法(systemdをPID1で動作させる方法) | Snow System
wslコマンドオプションで自動起動させる
wslコマンドでディストリビューションを起動させるようにすればサービスの起動も行える。
wsl --help Copyright (c) Microsoft Corporation. All rights reserved. 使用法: wsl.exe [Argument] [Options...] [CommandLine] Linux バイナリを実行するための引数: コマンドラインを指定しない場合、既定のシェルが起動され wsl.exe ます。 --exec、-e <CommandLine> 既定の Linux シェルを使用せずに、指定したコマンドを実行します。 -- 残りのコマンドラインをそのまま渡します。 オプション: --cd <Directory> 指定したディレクトリを現在の作業ディレクトリとして設定します。 ~ が使用されている場合は、Linux ユーザーのホームパスが使用されます。パスが始まる場合 文字が含まれている場合は、Linux の絶対パスと解釈されます。 それ以外の場合、この値は Windows の絶対パスである必要があります。 --分布、-d <Distro> 指定したディストリビューションを実行します。 --ユーザー、-u <UserName> 指定されたユーザーとして実行します。 Windows Subsystem for Linux を管理するための引数: --ヘルプ 使用方法に関する情報を表示します。 --install [Options] 追加の Windows Subsystem for Linux ディストリビューションをインストールします。 有効なディストリビューションの一覧を表示するには、'wsl--list--online' を使用してください。 オプション: --distribution, -d [Argument] 名前を指定して配布をダウンロードしてインストールします。 引数: 有効なディストリビューション名 (大文字と小文字は区別されません)。 例: wsl --install -d Ubuntu wsl --install --distribution Debian --set-default-version <Version> 新しいディストリビューションの既定のインストールバージョンを変更します。 --shutdown 直ちに、すべての実行中の配布および WSL 2 軽快なユーティリティの仮想マシンを終了します。 --status Linux の Windows Subsystem の状態を示します。 --update [Options] オプションが指定されていない場合、WSL 2 カーネルは更新され 、最新バージョンになります。 オプション: --rollback 以前のバージョンの WSL 2 カーネルに戻します。 Windows Subsystem for Linuxのディストリビューションを管理するための引数: --export <Distro> <FileName> ディストリビューションを tar ファイルにエクスポートします。 ファイル名には、標準出力として - を使用できます。 --import <Distro> <InstallLocation> <FileName> [Options] 指定した tar ファイルを新しいディストリビューションとしてインポートします。 ファイル名には標準入力として - を使用できます。 オプション: --version <Version> 新しいディストリビューションに使用するバージョンを指定します。 --list, -l [Options] ディストリビューションの一覧を表示します。 オプション: --all 現在実行中のディストリビューションのみを表示します。 --quiet, -q ディストリビューション名のみを表示します。 --verbose, -v すべてのディストリビューションに関する詳細な情報を表示します。 --online, -o 'wsl --install' を使用してインストールするために使用できるディストリビューションの一覧を表示します。 --set-default, -s <Distro> ディストリビューションを既定として設定します。 --set-version <Distro> <Version> 指定されたディストリビューションのバージョンを変更します。 --terminate, -t <Distro> 指定されたディストリビューションを終了します。 --unregister <Distro> ディストリビューションの登録を解除し、ルートファイルシステムを削除します。
これを利用することになる。
以下はディストリビューション名がUbuntuである場合にsshサービスをディストリビューション起動時に起動させる方法。
wsl -d Ubuntu -- sudo service ssh start
PowerShellでduコマンドっぽいものを作ってみる
やりたいこと
Linux/Unix系でよくあるduコマンドに近いものがWindowsで欲しかった。
クローズ環境で使うので、フリーソフトウェアとかでも気軽に入れられないので、代替として使えそうなものを組んでみる。
たぶん同じようなことをやっている人はいると思う。
duコマンドの出力イメージ
duコマンドは指定されたディレクトリ配下のサイズをはじき出しつつ最後に引数ディレクトリのサイズを出力してくれる。
ということで、イメージとしてはこういうやつを作るっていうことになる。
$ du -h etc 8.0K etc/kernel/postinst.d 12K etc/kernel 4.0K etc/subversion 36K etc/logrotate.d 4.0K etc/smartmontools/smartd_warning.d 24K etc/smartmontools 4.0K etc/security/namespace.d 4.0K etc/security/console.perms.d 8.0K etc/security/limits.d 12K etc/security/console.apps ~~~中略~~~ 52K etc/dconf/db 68K etc/dconf 22M etc
実装のため
PowerShellを使う
PowerShellのスクリプト実行を行う時には実行ポリシーの変更が必要だったりするが、それはめんどくさいので、powershell -command -の仕組みを利用して、直接スクリプトを流し込んで実装するようにした。
これを利用すれば設定変更の必要もなくなるので、ぐっと使いやすくなる気がする。
duコマンドとの違い
duとの違いとして、duは標準出力には引数に渡した対象ディレクトリとサブディレクトリのみ出力される。
今回作るものは対象フォルダと直下のサブフォルダ・ファイルはすべて列挙するようにする。
対象の渡し方
ソースにべた書きとか、引数で対象を渡すというオーソドックスな方法もあったのだが、確認したいフォルダは複数あったのと、対象に変動があった時にわざわざソースを修正することや実行用のbatを編集するのは馬鹿らしいと思ったので、入力用のテキストファイルを用いることとした。
結果の出し方
アウトプットは標準出力に出すだけだと後から(どこがどれだけ増えたとか)比較することもできないので、テキストファイルに吐き出すようにした。
その際にファイル名は日付時刻を使用してなるべくユニークになるようにした。
作ったもの
以下に作ったモノたちのコードを並べる。
これらを使用することで、やりたいことができていることは確認できている。
起動用のbatファイル
PowerShellスクリプトファイルを実行するための起動用batファイル
やることはPowerShellスクリプトファイルの呼び出しだけなので、シンプル。
ファイル名は何でもよい。
@(type dirlist.ps1) | powershell -command -
PowerShellスクリプト
実際に仕事をするPowerShellスクリプトファイル。
ファイル名は何でもよいが、batでは「dirlist.ps1」としているので、デフォルトはこれ。
ファイル名を変える場合はbat内の呼び出しファイル名も変えること。
$ErrorActionPreference = "SilentlyContinue" $RDate = Get-Date -Format "yyyyMMddHHmmss" $File_Name = $RDate + ".txt" $DummyPath ="dummypath/" ### list.txtから対象フォルダと直下のフォルダ・ファイルのサイズを取得してファイル出力 ### 直下のフォルダ・ファイル処理が終わったら指定されたフォルダサイズも出力(ソートのためにダミー文字を付ける) ### 出力ファイルにヘッダー行を出力 [String]::Format("{0}`t{1}", "Path", "Size") | Out-File $File_Name -Encoding default ### list.txtの行数分繰り返す foreach ($list in Get-Content "list.txt" -Encoding Default) { Write-Output $list $j = 0 $k = 0 ### サブフォルダの情報を拾う foreach ($i in (Get-ChildItem "$list" | ForEach-Object {$_.FullName})) { ### パスの最後が\の場合は削除 ### 削除後にソートするためのダミー文字列を文字列最後にセット $ppath = (($i -replace "\\+$", "") -replace "$", "$DummyPath") $k = (Get-ChildItem -LiteralPath "$i" -Recurse -Force | Measure-Object Length -Sum).Sum ### フォルダ・ファイルサイズが0の場合は出力時に文字列変換する if($null -eq $k) { ### フォルダ・ファイルサイズが0の場合 $k = 0 [string]::Format("{0}`t{1:#,#}", $ppath, [string]$k) | Out-File $File_Name -Encoding default -Append } else { ### フォルダサイズが0じゃない場合 [string]::Format("{0}`t{1:#,#}", $ppath, $k) | Out-File $File_Name -Encoding default -Append } ### 編集した出力用パスをクリア $ppath = $null ### 合計値計算 $j = $j + $k } ### パスの最後が\だったら削除 ### 削除後にソート用ダミー文字列を付与 $plist = (($list -replace "\\+$", "") -replace "$", "$DummyPath") ### list.txtに記載されたフォルダ自体の書き出し [string]::Format("{0}`t{1:#,#}", $plist, $j) | Out-File $File_Name -Encoding default -Append } ### CSV読み取り機能を使って編集 ### Path順でソートして出力 $CSVData = Import-Csv -Path $File_Name -Encoding Default -Delimiter "`t" $CSVData | Sort-Object -Property Path -unique | Export-Csv -Path $File_Name -Encoding Default -NoTypeInformation -Delimiter "`t" ### ファイルを読み込んで、ダミー文字列を削除して出力 $OutData = Get-Content -Encoding Default $File_Name | ForEach-Object {$_ -replace "$DummyPath", ""} $OutData | Out-File $File_Name -Encoding default $ErrorActionPreference = "Continue"
使ってみる
テスト用のフォルダ構成
適当な構成としている以下のものでテストを行っている。
マルチバイト文字を含むパス有無とファイルが無いフォルダという環境。
C:. ├─dummy │ test │ └─ダミー ├─1 │ test.txt │ テスト.txt │ ├─2 └─3 test
入力ファイル
ソースを見てもらえればわかる通り、「list.txt」が決め打ちで読み込むファイルとなっている。
そのため、上記のテスト用環境に合わせてこんな感じの入力ファイルを用意した。
C:\tmp\test\dummy C:\tmp\test\ダミー
batファイルを動かして動作を確認
batファイルのコマンドプロンプトウインドウに実行中の入力ファイル行が表示される。
これは大量データの処理時に、どこを実行しているのかがわからなくなったためにあえて出力するようにしているもので、なくてもいい。
出力結果サンプル
出力結果のテキストファイルは起動用のbatとPowershellスクリプトファイルと同じフォルダに「日付時刻.txt」といったファイル名で出力されるので、それを確認する。
今回はこんな感じのものが出来上がっている。
C:\tmp\test\dummyにはファイルが1ファイルしか存在していないので、それのファイルサイズと合計が出力されている。。
C:\tmp\test\ダミーにはサブフォルダが3つあるので、それぞれのファイルサイズと合計が出力されている。
"Path" "Size" "C:\tmp\test\dummy\test" "3,000,000" "C:\tmp\test\dummy" "3,000,000" "C:\tmp\test\ダミー\1" "30,000" "C:\tmp\test\ダミー\2" "0" "C:\tmp\test\ダミー\3" "10,000" "C:\tmp\test\ダミー" "40,000"
この辺もっとやりようがある気がするってところ
PowerShellのデフォルトエンコードがUTF-8かShift_JISかがバージョンによって変わるので、もしかしたらバグる可能性はある。
duの出力順みたいな感じでソートさせているので、ダミー文字列を使った処理をやっているが、ダミー文字が記号だとソート時に最上段に行ってしまうのでアルファベット文字列としている。
エラーは無視しつつ、階層内のすべてのファイルサイズを合計しているので、実値と違いが出ることはあるはず。
リアコンバーターを買った
買ったもの
使っているカメラはPENTAX K-5なので、PENTAXのHD PENTAX-DA AF REAR CONVERTER 1.4X AWを購入。
www.ricoh-imaging.co.jp
これを使えば、焦点距離が1.4倍になるので、ちょっと伸ばしたいときに使えるかなーって思っている。
そろそろK-3 Mk3あたり買いたい気もするけど、K-5で十分というのもあるので、踏ん切りがつかないところ。
そこで現在主力レンズとして使用しているのが、18-135mmのズームレンズということもあって、もうちょっと望遠が欲しい時に使えるかもしれないということで、リアコンバーターを買おうと思ったのが始まり。
ちなみに、18-270mmのレンズも持っているけど、なかなか重いのもあって主力レンズからは外している。
写真比較
適当に同じ位置から同じ被写体を撮ってみたので、比較してみる。
フォトライフの制限で10MB以上のファイルアップロードは出来ないので、ついでにレベル補正してからファイルサイズを縮小しているので、トリミングやごみ処理などはまったくやっていない。
コンバーター無し





とりあえず
普段使う用としては、18-270mmを止めた時と同じで、そのままだと重すぎるというのがあるので、常に使うということはないと思う。
まあいい感じに使っていけたらいいかな。
Let’s Encryptのルート証明書変更対応をやった
やったこと
ログをとるのを忘れてたので何もないけど…。
使用しているサーバOS(CentOS7)のパッケージ更新だけ。
気づいた経緯
IRC ProxyのWebクライアントのためにDDNSに登録してドメインを取得しているのだが、DDNSサービス側から一定期間内にIPアドレス通知がないと連絡があった。
DDNSへのIPアドレス通知については、cronに登録したシェルが一定サイクルで動作し続けているため、まずはDDNS側でのサービス変更を疑った。
もちろんそういうわけはなかったので、サーバに入っていろいろ見てみようとしたところ、開始5分で理由が分かったのが今回のこと。
DDNSへのIPアドレス通知URLのプロトコルとしてhttpsを使用していたのだが、これを手動で動かしてみるとSSLサーバ証明書の問題だということが分かった。
使用しているDDNS自体のSSLサーバ証明書がLet's Encryptであるため、これをどうにかしないとどうにもならないということを把握した。
やったこと
ということで、考えられる手段として、以下のものが考えられた。
この手段の中から、ちゃんと対応することにした。
といっても難しいことは何もなく、パッケージ更新するだけですべて終わった。
ということで更新が何かあるかを確認してみたらいくつかあったので、更新。
yum check-update yum update
おわり。
携帯電話/スマートフォン遍歴
今までの遍歴
C5001T(ネイビー)
https://time-space.kddi.com/ketaizukan/2001/4.html
高校を卒業したぐらいに買ったやつ。
たぶん買ったのはネイビー。
携帯電話は高校を卒業するまでは特に必要性を感じなかったからこの時に新規契約した。
後から知ったけど、東芝端末にあったガチャブルとかいう通知がある場合に折り畳みをちょっとでも開けばバイブレーション機能を動かしてくれるっていうのが地味に便利だった。
ポケットとかバッグからわざわざ出さずとも、ケータイを開けば見ないといけないかどうかがわかったのがよかったよね。
INFOBAR(ICHIMATSU)
https://time-space.kddi.com/ketaizukan/2003/8.html
初めて見たときの衝撃は今でも色あせていないとおもうぐらい強烈だった。
とはいえ、C5001Tを買った後のスパンもあったので、たぶん発売開始から1年ぐらいしてから機種変更したんじゃないかと思う。
ボタンは押しやすいし、バッグの中でも邪魔にならないしってことでかなり使い勝手が良かった。
W31T(ソルティホワイト)
https://time-space.kddi.com/ketaizukan/2005/17.html
IFOBARとは違ってフラットデザインのテンキーだけど、方向キー型セレクターがはっきりとした凹凸だったっていうのと、背面ディスプレイが割と大型だったおかげで使いやすかった。
折りたたんだ状態でも薄型というのと、PCサイトビュアーのおかげでネットサーフィンが捗った。
W52SA(フィールブラック)
https://time-space.kddi.com/ketaizukan/2007/20.html
このころ割とあった画面回転系の端末のひとつ。
ワンセグがついてきたけど使った記憶がないのは、まあそんなもんだよね。
操作系はボタンがフラットなのに押しやすい、セレクター周りもボタン操作含めて目で見ずとも操作できたのでスムーズに使えた。
ただひとつだけ、通常の画面方向で折りたたむと本体の角度設定のおかげで若干開きにくかった。
画面を回転させた状態だとそうでもなかった。
丸みを帯びた形状ではなく、シャープな形状ということで、折りたたみ面に指が入りにくかったことが難点だった。
確かこれを使っているころにはてなハイクがオープンしたんだよね。
T001(スターズブラック)
https://time-space.kddi.com/ketaizukan/2009/25.html
ボタン操作系は問題なし、東芝なのでガチャブル機能もあったってことでストレスなく使えた端末。
有機ELディスプレイだったってのははてなハイクで画像を見る機会が増えたこともあり、使いやすい感覚があった気がする。
フルチェン機能についてはつかわなかった。
INFOBAR A01(KURO)
https://time-space.kddi.com/ketaizukan/2011/18.html
INFOBARのスマートフォン1機種目。
色はICHIMATSUっぽいっていう理由でKUROにしたけど、物理ボタンが3つしかなかったのでNISHIKIGOIでもよかったかなって思った。
片手で無理なく操作できるサイズ感と物理キーによる操作が行えたことで、スマートフォン1台目としてはよかったのかもしれない。
惜しむらくはデザインに振っているおかげで処理レスポンスが悪くなりやすかったというのが、デザインケータイもといデザインスマホですねって思ったけど、これだけを使っているうちは、こんなもんかって思えていたので不自由はなかった。
INFOBAR A02(AOAO)
https://time-space.kddi.com/ketaizukan/2013/13.html
INFOBAR A01にそこまで不自由さは感じていなかったけど、A02の本体在庫がなくなりかけていたので買ったという若干後ろ向きな購入動機。
A01に対して大きくなったのと、iida UIの餅とかゼリーに例えられる独特な操作アニメーションが好感を持てた。
操作感についてはA01よりも格段に使いやすくなっていたので、問題らしい問題はなかった。
個人的に使用した端末では、バッテリーカバーが取り外せた最後の機種だったわけだけど、正直防水性云々よりもバッテリー交換が容易なほうが嬉しかったりする。※いざとなったら逆のことを言いそうではある。
次の機種への機種変更間際にはふいに電源が落ちる等の不具合っぽい現象も起きていた。
INFOBAR A03(NISHIKIGOI)
https://time-space.kddi.com/ketaizukan/2015/12.html
カラーリングに惹かれないというがっかり感があったので、NISHIKIGOIを購入。
物理ボタンは押し感のないタイプだったけど、A01のデザインに近しいことで使っていて楽しめた。
INFOBAR xv(NISHIKIGOI)
https://time-space.kddi.com/ketaizukan/2018/16.html
クラウドファンディングで資金集めしたことでも話題になったガラホ。
(支援したのでコマンド操作で名前出てくる)
だいたいのサイズ感とか初代INFOBARに近くてよかったんだけど、ボタンの押しづらさとかも目立った端末。
なによりブラウザ操作がストレスいっぱいだったのは辛かった。
とはいえ必要十分な「携帯電話」としては、こんなものだよねっていう感じも強かった。
AQUOS sense5G SHG03(ブラック)
https://time-space.kddi.com/ketaizukan/2021/1.html
INFOBAR xvのバッテリーがいきなり落ちるようになってきたので、買い換えた。
5Gになったけど、そこまでの恩恵はまだ感じていない。
基本的にスマホじゃゲームをやらないので、高スペックは求めないけど、動作も機敏でストレスはほぼ感じない。
ただ不思議なことに、たまにバイブレーションが動作しなくなる気がしているが、再起動すれば解決するのでとりあえずはしのいでいる。
certbotコマンドのオプション指定について
cetbot用cron設定見直し
cronの設定値
現在の設定内容は以前も書いたが以下のような感じ。
certbotコマンドが正常終了となったらstone再起動用のbashを起動している。
00 00 01 \* \* sudo /usr/bin/certbot renew && /Local/stone_run.bash 1>/dev/null 2>&1 &
ただし、わざわざ&&でコマンドをつなげることをせずともオプションとかを使用すれば、再起動できるっぽい。
certbotコマンドの再考
usageはこんな感じ。
$ certbot --help renew usage: certbot renew [--cert-name CERTNAME] [options] optional arguments: -h, --help show this help message and exit -c CONFIG_FILE, --config CONFIG_FILE path to config file (default: /etc/letsencrypt/cli.ini and ~/.config/letsencrypt/cli.ini) renew: The 'renew' subcommand will attempt to renew all certificates (or more precisely, certificate lineages) you have previously obtained if they are close to expiry, and print a summary of the results. By default, 'renew' will reuse the options used to create obtain or most recently successfully renew each certificate lineage. You can try it with `--dry-run` first. For more fine-grained control, you can renew individual lineages with the `certonly` subcommand. Hooks are available to run commands before and after renewal; see https://certbot.eff.org/docs/using.html#renewal for more information on these. --cert-name CERTNAME Certificate name to apply. This name is used by Certbot for housekeeping and in file paths; it doesn't affect the content of the certificate itself. To see certificate names, run 'certbot certificates'. When creating a new certificate, specifies the new certificate's name. (default: the first provided domain or the name of an existing certificate on your system for the same domains) --dry-run Perform a test run of the client, obtaining test (invalid) certificates but not saving them to disk. This can currently only be used with the 'certonly' and 'renew' subcommands. Note: Although --dry-run tries to avoid making any persistent changes on a system, it is not completely side-effect free: if used with webserver authenticator plugins like apache and nginx, it makes and then reverts temporary config changes in order to obtain test certificates, and reloads webservers to deploy and then roll back those changes. It also calls --pre-hook and --post-hook commands if they are defined because they may be necessary to accurately simulate renewal. --deploy- hook commands are not called. (default: False) --force-renewal, --renew-by-default If a certificate already exists for the requested domains, renew it now, regardless of whether it is near expiry. (Often --keep-until-expiring is more appropriate). Also implies --expand. (default: False) --allow-subset-of-names When performing domain validation, do not consider it a failure if authorizations can not be obtained for a strict subset of the requested domains. This may be useful for allowing renewals for multiple domains to succeed even if some domains no longer point at this system. This option cannot be used with --csr. (default: False) -q, --quiet Silence all output except errors. Useful for automation via cron. Implies --non-interactive. (default: False) --preferred-chain PREFERRED_CHAIN If the CA offers multiple certificate chains, prefer the chain with an issuer matching this Subject Common Name. If no match, the default offered chain will be used. (default: None) --preferred-challenges PREF_CHALLS A sorted, comma delimited list of the preferred challenge to use during authorization with the most preferred challenge listed first (Eg, "dns" or "http,dns"). Not all plugins support all challenges. See https://certbot.eff.org/docs/using.html#plugins for details. ACME Challenges are versioned, but if you pick "http" rather than "http-01", Certbot will select the latest version automatically. (default: []) --pre-hook PRE_HOOK Command to be run in a shell before obtaining any certificates. Intended primarily for renewal, where it can be used to temporarily shut down a webserver that might conflict with the standalone plugin. This will only be called if a certificate is actually to be obtained/renewed. When renewing several certificates that have identical pre-hooks, only the first will be executed. (default: None) --post-hook POST_HOOK Command to be run in a shell after attempting to obtain/renew certificates. Can be used to deploy renewed certificates, or to restart any servers that were stopped by --pre-hook. This is only run if an attempt was made to obtain/renew a certificate. If multiple renewed certificates have identical post- hooks, only one will be run. (default: None) --deploy-hook DEPLOY_HOOK Command to be run in a shell once for each successfully issued certificate. For this command, the shell variable $RENEWED_LINEAGE will point to the config live subdirectory (for example, "/etc/letsencrypt/live/example.com") containing the new certificates and keys; the shell variable $RENEWED_DOMAINS will contain a space-delimited list of renewed certificate domains (for example, "example.com www.example.com" (default: None) --disable-hook-validation Ordinarily the commands specified for --pre-hook /--post-hook/--deploy-hook will be checked for validity, to see if the programs being run are in the $PATH, so that mistakes can be caught early, even when the hooks aren't being run just yet. The validation is rather simplistic and fails if you use more advanced shell constructs, so you can use this switch to disable it. (default: False) --no-directory-hooks Disable running executables found in Certbot's hook directories during renewal. (default: False) --disable-renew-updates Disable automatic updates to your server configuration that would otherwise be done by the selected installer plugin, and triggered when the user executes "certbot renew", regardless of if the certificate is renewed. This setting does not apply to important TLS configuration updates. (default: False) --no-autorenew Disable auto renewal of certificates. (default: True)
これを見ると、cronなどで自動実行する場合はquietオプションを推奨されている。
また、pre-hook/post-hook/deploy-hookの各オプションでcertbot動作前後や証明書更新が行われた場合のみの処理も行うことが可能っぽい。
このhookオプションは/etc/letsencrypt/renewal-hooks配下にファイルを置くことでも代替できるようなので、用途を考えるとオプションよりもディレクトリにファイルを置いたほうがいいのかもしれない。
新しいcron用コマンド
上記の考察から、quietオプションとpost-hookオプションを使用するとこうなる。
sudo /usr/bin/certbot renew --quiet --post-hook /Local/stone_run.bash
stoneの起動シェルの変更
stone用の起動シェルについてもこのタイミングでいろいろ見直しを行った。
というのも、一度/etc/letsencrypt/renewal-hooks配下にシンボリックリンクを作成する想定で動作を見ていた時に不具合が発生することがわかったためだ。
以下が修正後の起動シェルになる。
例のごとく、シェルと同ディレクトリにあるstone.+confファイルの数だけ処理を繰り返すというところは変わらない。
変わったのはBASE_DIR変数の取得方法で、dirnameに直接$0を渡すのを止め、realpathコマンドをかます形になっている。
これはシンボリックリンクを動作させた場合、$0に設定されるのはシンボリックリンクのパスなので、シェルファイル自体のパスを取得するための変更となっている。
ちなみにreadlinkではなくrealpathとしているのは、この方法ではreadlinkが想定した動作をしてくれなかったためとなる。
readlinkコマンドを使って$(dirname $(readlink -e $0))みたいなことをやってみたところ、どうもうまく動作しなかったので、ワンラインで動作できたrealpathコマンドで代替した感じ。
#!/bin/bash -l #BASE_DIR=`dirname $0` BASE_DIR=`dirname $(realpath $0)` cd ${BASE_DIR} ## Kill if [ `ps -ef | egrep "stone.+conf" | egrep -v "grep|sudo|bash" | wc -l` -ne 0 ]; then for stone_proc in `ps -ef| egrep "stone.+conf" | egrep -v "grep|sudo|bash" | awk '{print $2}'` do sudo kill -9 ${stone_proc} done fi sleep 10 ## Start while true do for target_conf in `ls stone*.conf` do if [ `ps -ef | egrep ${target_conf} | egrep -v "grep|sudo|bash" | wc -l` -eq 0 ]; then nohup sudo /usr/local/bin/stone -C ${BASE_DIR}/${target_conf} 1>/dev/null 2>&1 & fi done if [ `ps -ef | egrep "stone.+conf" | egrep -v "grep|sudo|bash" | wc -l` -eq `ls stone*.conf | wc -l` ]; then break else sleep 10 fi done exit 0
動作検証
検証というほどでもないが、これがうまく動くことを確認するため、quietオプションを外して、dry-runオプションを付けた状態で動かしてみる。
$sudo /usr/bin/certbot renew --dry-run --post-hook /Local/stone_run.bash Saving debug log to /var/log/letsencrypt/letsencrypt.log - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Processing /etc/letsencrypt/renewal/example.com.conf - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Cert not due for renewal, but simulating renewal for dry run Plugins selected: Authenticator standalone, Installer None Starting new HTTPS connection (1): acme-staging-v02.api.letsencrypt.org Simulating renewal of an existing certificate for example.com Performing the following challenges: http-01 challenge for example.com Waiting for verification... Cleaning up challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - new certificate deployed without reload, fullchain is /etc/letsencrypt/live/example.com/fullchain.pem - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Congratulations, all simulated renewals succeeded: /etc/letsencrypt/live/example.com/fullchain.pem (success) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Running post-hook command: /Local/stone_run.bash
予定通りの結果が得られたので、これでいいこととする。