<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Linux on 屑籠というかゴミ箱</title><link>https://blog.teandt.net/tags/linux/</link><description>Recent content in Linux on 屑籠というかゴミ箱</description><generator>Hugo -- gohugo.io</generator><language>ja-jp</language><lastBuildDate>Sun, 27 Sep 2026 22:06:56 +0900</lastBuildDate><atom:link href="https://blog.teandt.net/tags/linux/index.xml" rel="self" type="application/rss+xml"/><item><title>BitwardenSecretsManagerを使ってみる</title><link>https://blog.teandt.net/posts/2026/09/20260927-220656/</link><pubDate>Sun, 27 Sep 2026 22:06:56 +0900</pubDate><guid>https://blog.teandt.net/posts/2026/09/20260927-220656/</guid><description>&lt;img src="https://blog.teandt.net/posts/2026/09/20260927-220656/image01.png" alt="Featured image of post BitwardenSecretsManagerを使ってみる" /&gt;&lt;h2 id="概要"&gt;概要
&lt;/h2&gt;&lt;p&gt;最近APIのシークレットを.envとかに入れるのが嫌なので何かしらマネージャー管理にようと考えて候補を検討して、結局パスワードマネージャー同様にBitwardenにして進めてみた。&lt;br&gt;
比較はInfisical。
管理上の問題とかでBitwardenを選択。&lt;br&gt;
そのままセットアップしていたところマシンアカウントのアクセストークンを環境変数に直接保存する運用が公式運用となっていたので、ちょっと微妙だなとファイル保存して実行時だけ使用する環境で構築した。&lt;br&gt;
可能であれば暗号保存したほうが良いと思うが、結局それも同じ問題を抱えそうなのでいったんこの方式で使ってみる。&lt;/p&gt;
&lt;h2 id="検討した製品サービス"&gt;検討した製品・サービス
&lt;/h2&gt;&lt;h3 id="比較検討"&gt;比較検討
&lt;/h3&gt;&lt;p&gt;シークレットマネージャーはパスワードマネージャー同様にそれなりに普及してきているので候補は色々ある。&lt;br&gt;
BitwardenSecretsManager（以下BitwardenSM）と比較したのはInfisical。&lt;br&gt;
こちらのほうが大分高機能で色々出来る感じなのとOSS版とクラウド版があって、クラウド版はFreeでも個人なら普通に使えるレベルだった。&lt;/p&gt;
&lt;p&gt;調査はChatGPTで調べて公式ドキュメントを参照していった感じ。&lt;br&gt;
ChatGPTまとめで比較としてはこんな感じになった。&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;条件&lt;/th&gt;
 &lt;th&gt;Bitwarden SM Free&lt;/th&gt;
 &lt;th&gt;Infisical Self-host&lt;/th&gt;
 &lt;th&gt;Infisical Cloud Free&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;料金&lt;/td&gt;
 &lt;td&gt;無料&lt;/td&gt;
 &lt;td&gt;OSS部分は無料&lt;/td&gt;
 &lt;td&gt;無料&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Secret数&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;無制限&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;100個超なら問題なし&lt;/td&gt;
 &lt;td&gt;100個超なら問題なし&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Project数&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;3&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;無制限&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;無制限&lt;/strong&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;人間ユーザー&lt;/td&gt;
 &lt;td&gt;最大2&lt;/td&gt;
 &lt;td&gt;Identity枠に含む&lt;/td&gt;
 &lt;td&gt;Identity枠に含む&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Machine Identity&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;3 Machine Accounts&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;Freeでは人間含め計5 Identityが基準&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;人間含め計5 Identity&lt;/strong&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;1人利用時のMachine枠&lt;/td&gt;
 &lt;td&gt;3&lt;/td&gt;
 &lt;td&gt;おおむね4&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;4&lt;/strong&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;複数VMから同一Secret取得&lt;/td&gt;
 &lt;td&gt;○&lt;/td&gt;
 &lt;td&gt;○&lt;/td&gt;
 &lt;td&gt;○&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;2FA&lt;/td&gt;
 &lt;td&gt;○&lt;/td&gt;
 &lt;td&gt;○&lt;/td&gt;
 &lt;td&gt;○&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;FIDO2/WebAuthn 2FA&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;○&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;明示なし&lt;/td&gt;
 &lt;td&gt;明示なし&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;パスキーによるログイン&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;○（Beta）&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;現行Free仕様では確認できず&lt;/td&gt;
 &lt;td&gt;現行Free仕様では確認できず&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Entra ID SSO&lt;/td&gt;
 &lt;td&gt;× Enterpriseのみ&lt;/td&gt;
 &lt;td&gt;Freeでは×&lt;/td&gt;
 &lt;td&gt;× Pro以上&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Audit Log&lt;/td&gt;
 &lt;td&gt;×&lt;/td&gt;
 &lt;td&gt;Freeでは×&lt;/td&gt;
 &lt;td&gt;×&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Secret Versioning&lt;/td&gt;
 &lt;td&gt;Bitwarden方式&lt;/td&gt;
 &lt;td&gt;Freeでは×&lt;/td&gt;
 &lt;td&gt;Freeでは×&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;運用管理&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;不要&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;自分で必要&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;不要&lt;/strong&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;障害・バックアップ責任&lt;/td&gt;
 &lt;td&gt;Bitwarden&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;自分&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;Infisical&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;データを自宅内に限定&lt;/td&gt;
 &lt;td&gt;×&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;◎&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;×&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;当初はセルフホストも考えたけど、結局Cloud版とあまり変わらない制限だったので、Infisicalのセルフホスト版は早めに除外してクラウドのBitwardenSMとInfisical Cloudで比較した。&lt;br&gt;
一番大きな違いとしてBitwardenSMはProject数に制限があること、BitwardenSMはWebログインにパスキーが使えること。&lt;br&gt;
BitwardenSMの&lt;a class="link" href="https://bitwarden.com/help/secrets-manager-plans" target="_blank" rel="noopener"
 &gt;Plans表&lt;/a&gt;にはTwo-step loginのところにそういった記載は無いけれどBitwardenPasswordManager側とWebログインのアカウントが共通なのでパスキーもベータ扱いだけど使える。&lt;/p&gt;
&lt;p&gt;こちらももう少し細かくまとめた。&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;項目&lt;/th&gt;
 &lt;th&gt;Bitwarden Secrets Manager Free&lt;/th&gt;
 &lt;th&gt;Infisical Cloud Free&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;月額&lt;/td&gt;
 &lt;td&gt;$0&lt;/td&gt;
 &lt;td&gt;$0&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;人間ユーザー&lt;/td&gt;
 &lt;td&gt;最大2&lt;/td&gt;
 &lt;td&gt;Machine含め合計5 identities&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Machine用ID&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;3 Machine Accounts&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;5 identitiesの内数&lt;/strong&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;1人利用時のMachine枠&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;3&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;実質4&lt;/strong&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Secret数&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;無制限&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;数による上限は料金表に記載なし&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Project数&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;3&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;無制限&lt;/strong&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Environment&lt;/td&gt;
 &lt;td&gt;独立した同等概念なし&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;3 / Project&lt;/strong&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Secret Folder&lt;/td&gt;
 &lt;td&gt;Project中心&lt;/td&gt;
 &lt;td&gt;○&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Secret Reference&lt;/td&gt;
 &lt;td&gt;基本的なSecret管理&lt;/td&gt;
 &lt;td&gt;○&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Secret Override&lt;/td&gt;
 &lt;td&gt;―&lt;/td&gt;
 &lt;td&gt;○&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;CLI&lt;/td&gt;
 &lt;td&gt;○ &lt;code&gt;bws&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;○&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;API/SDKによる取得&lt;/td&gt;
 &lt;td&gt;○&lt;/td&gt;
 &lt;td&gt;○&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;コンテナへの環境変数注入&lt;/td&gt;
 &lt;td&gt;○&lt;/td&gt;
 &lt;td&gt;○&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Machineごとの権限設定&lt;/td&gt;
 &lt;td&gt;○&lt;/td&gt;
 &lt;td&gt;○&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Secret Sync&lt;/td&gt;
 &lt;td&gt;限定的なIntegrations&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;10 Syncs&lt;/strong&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;2FA&lt;/td&gt;
 &lt;td&gt;○&lt;/td&gt;
 &lt;td&gt;○&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Entra ID SSO&lt;/td&gt;
 &lt;td&gt;×&lt;/td&gt;
 &lt;td&gt;×&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;SAML SSO&lt;/td&gt;
 &lt;td&gt;×（Enterprise）&lt;/td&gt;
 &lt;td&gt;×（Pro）&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;FIDO2/WebAuthn&lt;/td&gt;
 &lt;td&gt;Bitwardenアカウントで○&lt;/td&gt;
 &lt;td&gt;Freeの主要機能として記載なし&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Passkeyログイン&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;○&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;現状は主要Free機能として記載なし&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Audit Log&lt;/td&gt;
 &lt;td&gt;×&lt;/td&gt;
 &lt;td&gt;×&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Secret Versioning&lt;/td&gt;
 &lt;td&gt;専用履歴機能としてFreeにはなし&lt;/td&gt;
 &lt;td&gt;×&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;自動Secret Rotation&lt;/td&gt;
 &lt;td&gt;×&lt;/td&gt;
 &lt;td&gt;×&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Point-in-time Recovery&lt;/td&gt;
 &lt;td&gt;×&lt;/td&gt;
 &lt;td&gt;×&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;IP Allowlist&lt;/td&gt;
 &lt;td&gt;×&lt;/td&gt;
 &lt;td&gt;×&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Freeの主な制約&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;3 Projects / 3 Machines&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;5 identities&lt;/strong&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Project数は自宅の利用ならそんなに必要ないかな？ということで、いったんBitwardenに集約することにした。&lt;br&gt;
駄目なら移行しちゃえばいいし。 AIエージェントが賢くなりすぎて移行がやりやすくなって色々試せるのが最近のいいところ。&lt;/p&gt;
&lt;h3 id="infisicalのossセルフホストとcloudfreeの比較"&gt;InfisicalのOSSセルフホストとCloudFreeの比較
&lt;/h3&gt;&lt;p&gt;OSSセルフホストもMITライセンス部分が一部ということで機能制限されているようなので、これもChatGPTで条件まとめ。&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;機能&lt;/th&gt;
 &lt;th&gt;OSSセルフホスト&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;Web管理画面&lt;/td&gt;
 &lt;td&gt;○&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Secret保存・取得&lt;/td&gt;
 &lt;td&gt;○&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;CLI / API / SDK&lt;/td&gt;
 &lt;td&gt;○&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Machine Identity&lt;/td&gt;
 &lt;td&gt;○&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Universal Auth&lt;/td&gt;
 &lt;td&gt;○&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;複数Project&lt;/td&gt;
 &lt;td&gt;○&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Secret Folder&lt;/td&gt;
 &lt;td&gt;○&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Secret Reference / Import / Override&lt;/td&gt;
 &lt;td&gt;○&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Docker / Kubernetes / Terraform等連携&lt;/td&gt;
 &lt;td&gt;○&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Infisical Agent&lt;/td&gt;
 &lt;td&gt;○&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;2FA&lt;/td&gt;
 &lt;td&gt;○&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;SAML SSO / Entra ID SSO&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;×&lt;/strong&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;OIDC SSO&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;×（ライセンス対象）&lt;/strong&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;LDAP&lt;/td&gt;
 &lt;td&gt;×&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;SCIM&lt;/td&gt;
 &lt;td&gt;×&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;高度なRBAC / Access Control&lt;/td&gt;
 &lt;td&gt;×&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Secret Versioning&lt;/td&gt;
 &lt;td&gt;×&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Point-in-Time Recovery&lt;/td&gt;
 &lt;td&gt;×&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Audit Log&lt;/td&gt;
 &lt;td&gt;×&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Secret Rotation&lt;/td&gt;
 &lt;td&gt;×&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Dynamic Secrets&lt;/td&gt;
 &lt;td&gt;×&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Custom Roles&lt;/td&gt;
 &lt;td&gt;×&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Temporary Access&lt;/td&gt;
 &lt;td&gt;×&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Approval Workflow&lt;/td&gt;
 &lt;td&gt;×&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;External KMS / HSM&lt;/td&gt;
 &lt;td&gt;×&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;SIEMへのAudit Log転送&lt;/td&gt;
 &lt;td&gt;×&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="bitwarden-secrets-managerセットアップ"&gt;Bitwarden Secrets Managerセットアップ
&lt;/h2&gt;&lt;p&gt;公式のスタートアップ説明はこちら&lt;a class="link" href="https://bitwarden.com/help/secrets-manager-quick-start/" title="Secrets Manager Quick Start"
 target="_blank" rel="noopener"
 &gt;Secrets Manager Quick Start&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="bitwarden-secrets-managerの有効化"&gt;Bitwarden Secrets Managerの有効化
&lt;/h3&gt;&lt;p&gt;Bitwarden Password Managerを利用しているなら、Webログイン後画面の左下にSecrets Managerへの切替メニューがあるのでそこを選択して、組織名とPlanを設定して有効化。&lt;br&gt;
有効化するとWebログイン後、Password ManagerとSecrets Managerの切替メニューが左側のサイドメニュー下側に現れるようになるのでそこで、そこで切り替える。&lt;/p&gt;
&lt;p&gt;&lt;img alt="Bitwardenメニュー" class="gallery-image" data-flex-basis="369px" data-flex-grow="154" height="298" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://blog.teandt.net/posts/2026/09/20260927-220656/image01.png" width="459"&gt;&lt;/p&gt;
&lt;h3 id="ユーザーのロール設定"&gt;ユーザーのロール設定
&lt;/h3&gt;&lt;p&gt;Admin Consoleでメンバーを選択し、シークレットマネージャー利用ユーザーのメンバーロールを編集して一番下にある「このユーザーはシークレットマネージャーにアクセスできます」のチェックをONにしておく。&lt;br&gt;
自分の場合は一人で管理者だけなので最初からチェックついていました。&lt;/p&gt;
&lt;h3 id="projectの作成"&gt;Projectの作成
&lt;/h3&gt;&lt;p&gt;最初にProjectを作成する。&lt;br&gt;
FreePlanでは3Projectまでなのでどうしようか迷ったけど&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;applications&lt;/li&gt;
&lt;li&gt;infrastructure&lt;/li&gt;
&lt;li&gt;other
あたりにしておく。&lt;br&gt;
BitwardenSMのFreePlanでは分類がやりにくい問題はあるので、分類するほどシークレットが多い場合はInfisical Cloudのほうが良さそう。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="マシンアカウントの作成"&gt;マシンアカウントの作成
&lt;/h3&gt;&lt;p&gt;シークレットのアクセスを自動化するためにマシンアカウントを作成する。&lt;br&gt;
これも3アカウントに限定されるので、必要があれば機能別に分けるようにするつもりだけどいったんは1アカウントで様子見する。&lt;br&gt;
作成したマシンアカウントに先ほど作成したProjectを割り当て。&lt;br&gt;
とりあえず読み取り専用で登録。&lt;/p&gt;
&lt;h3 id="secrets-manager-clibwsのインストール"&gt;Secrets Manager CLI(bws)のインストール
&lt;/h3&gt;&lt;p&gt;公式のドキュメントはこちら&lt;a class="link" href="https://bitwarden.com/help/secrets-manager-cli/" title="Secrets Manager CLI"
 target="_blank" rel="noopener"
 &gt;Secrets Manager CLI&lt;/a&gt;&lt;br&gt;
テストでインストールしたマシンの条件はこちら&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Distributor ID:	Ubuntu
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Description:	Ubuntu 24.04.5 LTS
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Release:	24.04
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Codename:	noble
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Linuxなので&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo curl https://bws.bitwarden.com/install &lt;span class="p"&gt;|&lt;/span&gt; sh
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;としたら&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;unzip is required to install bws.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;と指摘されたので先に入れておく。正常にインストールしたらバージョン確認&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ bws --version
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;bws 2.1.0
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="アクセス"&gt;アクセス
&lt;/h3&gt;&lt;p&gt;マシンアカウントのアクセストークンを使用してアクセスする。 &lt;br&gt;
マシンアカウントでアクセストークンを作成し、環境変数に設定するのが公式の設定。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nv"&gt;BWS_ACCESS_TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;アクセストークン&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;しかしアクセストークンを環境変数に与えるのはなんか嫌だ。 &lt;br&gt;
ということで、bwsグループを作ってこのグループに参加しているユーザのみトークンファイルを読めるようにしておいて、コマンド実行時にそこから実行時に環境変数に値を入れるようにする。&lt;br&gt;
環境には残さないようにしたラッパー経由でbwsコマンドにアクセスするようにする。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo groupadd --system bws
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo mkdir /etc/bws
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo vi /etc/bws/access-token
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo chown root:bws /etc/bws/access-token
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo chmod &lt;span class="m"&gt;640&lt;/span&gt; /etc/bws/access-token
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo usermod -aG bws &lt;span class="nv"&gt;$USER&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;その後、ラッパー用のスクリプトをユーザーローカルに作成する&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;span class="lnt"&gt;28
&lt;/span&gt;&lt;span class="lnt"&gt;29
&lt;/span&gt;&lt;span class="lnt"&gt;30
&lt;/span&gt;&lt;span class="lnt"&gt;31
&lt;/span&gt;&lt;span class="lnt"&gt;32
&lt;/span&gt;&lt;span class="lnt"&gt;33
&lt;/span&gt;&lt;span class="lnt"&gt;34
&lt;/span&gt;&lt;span class="lnt"&gt;35
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;mkdir -p ~/bin
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cat &amp;gt; ~/bin/bws &lt;span class="s"&gt;&amp;lt;&amp;lt;&amp;#39;EOF&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;#!/usr/bin/env bash
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;set -euo pipefail
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;# 万一呼び出し元でxtraceが有効でも、Secretを出力させない
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;set +x
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;readonly REAL_BWS=&amp;#34;/usr/local/bin/bws&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;readonly TOKEN_FILE=&amp;#34;/etc/bws/access-token&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;if [[ ! -x &amp;#34;$REAL_BWS&amp;#34; ]]; then
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; printf &amp;#39;bws wrapper: executable not found: %s\n&amp;#39; &amp;#34;$REAL_BWS&amp;#34; &amp;gt;&amp;amp;2
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; exit 127
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;fi
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;if [[ ! -r &amp;#34;$TOKEN_FILE&amp;#34; ]]; then
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; printf &amp;#39;bws wrapper: token file is not readable: %s\n&amp;#39; &amp;#34;$TOKEN_FILE&amp;#34; &amp;gt;&amp;amp;2
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; exit 126
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;fi
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;BWS_ACCESS_TOKEN=&amp;#34;$(&amp;lt;&amp;#34;$TOKEN_FILE&amp;#34;)&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;if [[ -z &amp;#34;$BWS_ACCESS_TOKEN&amp;#34; ]]; then
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; printf &amp;#39;bws wrapper: token file is empty: %s\n&amp;#39; &amp;#34;$TOKEN_FILE&amp;#34; &amp;gt;&amp;amp;2
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; exit 1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;fi
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;export BWS_ACCESS_TOKEN
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;exec &amp;#34;$REAL_BWS&amp;#34; &amp;#34;$@&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;EOF&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chmod &lt;span class="m"&gt;700&lt;/span&gt; ~/bin/bws
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;再ログイン後、おそらく自動で優先的なパスとして選択してくれるので以下で確認。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;type&lt;/span&gt; -a bws
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;code&gt;/home/user/bin/bws&lt;/code&gt;が最優先になっていればOK&lt;/p&gt;
&lt;h3 id="docker-compose起動用のスクリプトの作成"&gt;docker-compose起動用のスクリプトの作成
&lt;/h3&gt;&lt;p&gt;当初の目的のメインがdocker composeの.envファイルに秘密情報を書かないようにする、なのでdocker composeで利用できるようにする。&lt;br&gt;
普段行っているように&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker compose up -d
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;とすると、bws runと組み合わせられない。&lt;br&gt;
しかし組み合わせる場合オプションにProjectIDをつけることになるとすると毎回UUIDを引っ張ってくる必要があって面倒くさいので、起動用のスクリプトを作成する。&lt;/p&gt;
&lt;p&gt;以下のような感じで作成した。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#!/usr/bin/env bash
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;set&lt;/span&gt; -euo pipefail
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;readonly&lt;/span&gt; &lt;span class="nv"&gt;PROJECT_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;プロジェクトID&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;exec&lt;/span&gt; bws run --project-id &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$PROJECT_ID&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; -- &lt;span class="s1"&gt;&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; : &amp;#34;${SERVICE_TOKEN:?SERVICE_TOKEN is not set}&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; export TOKEN=&amp;#34;$SERVICE_TOKEN&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; unset SERVICE_TOKEN
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; exec docker compose up -d
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;これを実行できるように権限を与えて&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chmod &lt;span class="m"&gt;755&lt;/span&gt; compose-up
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;./compose-up
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;で実行させるようにした。&lt;br&gt;
終了はこれまで通り&lt;code&gt;docker compose down&lt;/code&gt;。&lt;br&gt;
課題として、compose.yamlで配列として環境変数を渡している場合、終了時に環境変数がないとワーニングが出て嫌なので&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;compose.yamlの環境変数の渡し方はリストにして直接指定する&lt;/li&gt;
&lt;li&gt;BitwardenSMに登録している環境変数名とコンテナに渡す環境変数が違う場合はcompose-upの&lt;code&gt;export&lt;/code&gt;のところで変換してやる
という形で対応した。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="systemd-credsによるaccesstoken暗号化"&gt;systemd-credsによるAccessToken暗号化
&lt;/h3&gt;&lt;p&gt;先程までの方法だと、マシンアカウントのAccessTokenが残るじゃないかと思って色々考えていたけど、systemdと連係をするのであればsystemd-credsが使用できる。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo install -d -m &lt;span class="m"&gt;700&lt;/span&gt; /etc/credstore.encrypted
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemd-ask-password -n &lt;span class="s2"&gt;&amp;#34;BWS Access Token:&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemd-creds encrypt &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --with-key&lt;span class="o"&gt;=&lt;/span&gt;host+tpm2 &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --name&lt;span class="o"&gt;=&lt;/span&gt;bws-access-token &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; - &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; /etc/credstore.encrypted/bws-access-token
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;これを実行するとトークンの入力を聞かれるので入力すると&lt;code&gt;/etc/credstore.encrypted/bws-access-token&lt;/code&gt;に暗号化した状態でトークンを保存してくれる。&lt;br&gt;
そして鍵情報はTPMを利用しているので、Proxmox使っている場合はvTPMを割り当てている必要がある。今回作った。&lt;/p&gt;
&lt;p&gt;確認方法&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemd-creds decrypt /etc/credstore.encrypted/bws-access-token -
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;ただし、こちらはroot権限が必要になるのでユーザ権限で起動するようなroot-less運用している場合は&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;mkdir -p ~/.config/credstore.encrypted
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chmod &lt;span class="m"&gt;700&lt;/span&gt; ~/.config/credstore.encrypted
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemd-ask-password -n &lt;span class="s2"&gt;&amp;#34;BWS Access Token:&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemd-creds encrypt &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --user &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --with-key&lt;span class="o"&gt;=&lt;/span&gt;host+tpm2 &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --name&lt;span class="o"&gt;=&lt;/span&gt;bws-access-token &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; - &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ~/.config/credstore.encrypted/bws-access-token
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;としてCredentialファイルを作成する。&lt;br&gt;
そしてこれを使ってSystemdのUnitファイルを修正して実行したとこ&lt;strong&gt;NG&lt;/strong&gt;。&lt;br&gt;
調べてみたらsystemd 257のバグらしくユーザーサービスとしてLoadCredentialEncryptedとかが使えないようで258で修正予定とのこと。&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;As of systemd 257, the ImportCredential, LoadCredential, LoadCredentialEncrypted, SetCredential and SetCredentialEncrypted settings do not work in user services. This should be fixed by [1] in systemd 258.&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://wiki.tahlwyn.zone/content/archlinux_en_all_maxi_2025-09/Systemd-creds?utm_source=chatgpt.com" title="systemd-creds"
 target="_blank" rel="noopener"
 &gt;引用元&lt;/a&gt;&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;じゃあsystemサービスとしてUnit移行させてそこからユーザーサービスとして起動させるか？と思ったけど、将来Quadletに移行しようとした場合はsystemサービスのUnitからユーザーサービスとして起動できないみたいなので、移行してさらに移行みたいなことをしないといけなさそうなのが面倒。&lt;br&gt;
ということで一旦Podman管理のサービスは後回しにすることに。&lt;/p&gt;</description></item><item><title>immichにEntraIDログインする</title><link>https://blog.teandt.net/posts/2026/09/20260912-220211/</link><pubDate>Sat, 12 Sep 2026 22:02:11 +0900</pubDate><guid>https://blog.teandt.net/posts/2026/09/20260912-220211/</guid><description>&lt;img src="https://blog.teandt.net/posts/2026/09/20260912-220211/image_top.png" alt="Featured image of post immichにEntraIDログインする" /&gt;&lt;h2 id="今回の構成"&gt;今回の構成
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;ImmichはPodmanのコンテナで稼働&lt;/li&gt;
&lt;li&gt;EntraID Freeのテナントを利用&lt;/li&gt;
&lt;li&gt;Immichの名前解決とアクセスにはCloudflare One／WARPが必要&lt;/li&gt;
&lt;li&gt;EntraIDは自分のテナントのユーザーだけが対象&lt;/li&gt;
&lt;li&gt;LAN内の別アドレスではOAuthがうまく動作しないため、パスワードログインも残す&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;普段のアクセス
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;端末 → Cloudflare One／WARP → Immich
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ↕ OIDC
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Microsoft EntraID
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;LAN 内のアクセス
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;端末 →Immichのローカルアドレス → メールアドレス＋パスワード
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Immich の設定画面では「OAuth」と表記されているが、ユーザー認証には OpenID Connect（OIDC）の利用になる。&lt;br&gt;
&lt;a class="link" href="https://docs.immich.app/administration/oauth/" target="_blank" rel="noopener"
 &gt;Immich 公式：OAuth Authentication&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="プライベートなサーバーの認証"&gt;プライベートなサーバーの認証
&lt;/h3&gt;&lt;p&gt;認証後にImmichのリダイレクト URI に戻るのはユーザーのブラウザになる。EntraIDからImmichへの直接の接続は必要ない。&lt;br&gt;
ただ、ブラウザはEntraIDとImmichの両方に、Immich Server はEntraIDの認証エンドポイントにアクセスできる必要がある。&lt;br&gt;
&lt;a class="link" href="https://learn.microsoft.com/en-us/entra/identity-platform/v2-protocols-oidc" target="_blank" rel="noopener"
 &gt;Microsoft 公式：OpenID Connect&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;このため、WARP接続中のブラウザから名前解決できて信頼できる証明書でHTTPS接続できることが前提になる。&lt;/p&gt;
&lt;p&gt;EntraID のリダイレクト URI は localhost などの例外を除きHTTPSが必要になる。&lt;br&gt;
Immich のドキュメントにローカルIPのHTTP例があっても、それをそのままEntraIDに適用できるとは限らないということで.localのようなケースはダメそう。
&lt;a class="link" href="https://learn.microsoft.com/en-us/entra/identity-platform/reply-url" target="_blank" rel="noopener"
 &gt;Microsoft 公式：リダイレクト URI の制約&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="entraid-にimmich用のアプリを登録"&gt;EntraID にImmich用のアプリを登録
&lt;/h2&gt;&lt;p&gt;Microsoft Entra 管理センターで次の順に開く。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;EntraID → アプリの登録 → 新規登録
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;項目&lt;/th&gt;
 &lt;th&gt;設定例&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;名前&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;Immich&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;サポートされているアカウントの種類&lt;/td&gt;
 &lt;td&gt;この組織ディレクトリ内のアカウントのみ（シングルテナント）&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;リダイレクト URI のプラットフォーム&lt;/td&gt;
 &lt;td&gt;Web&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;リダイレクト URI&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;https://immich.example.com/auth/login&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;登録後、概要画面から以下を控える。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;アプリケーション（クライアント）ID&lt;/li&gt;
&lt;li&gt;ディレクトリ（テナント）ID&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="リダイレクト-uri-の追加"&gt;リダイレクト URI の追加
&lt;/h3&gt;&lt;p&gt;アプリの「認証」で、Web のリダイレクト URI に以下を登録する。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;https://immich.example.com/auth/login
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;https://immich.example.com/user-settings
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;https://immich.example.com/api/oauth/mobile-redirect
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;用途は順に&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Web ログイン&lt;/li&gt;
&lt;li&gt;既存アカウントへの OAuth のリンク&lt;/li&gt;
&lt;li&gt;モバイルアプリへの認証結果の受け渡&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;モバイルでは HTTPS の中継先から &lt;code&gt;app.immich:///oauth-callback&lt;/code&gt; に戻す。&lt;br&gt;
&lt;a class="link" href="https://docs.immich.app/administration/oauth/#prerequisites" target="_blank" rel="noopener"
 &gt;Immich 公式：リダイレクト URI&lt;/a&gt;、&lt;a class="link" href="https://docs.immich.app/administration/oauth/#mobile-redirect-uri" target="_blank" rel="noopener"
 &gt;モバイル用リダイレクト&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;ブラウザで実際に開くホスト名と、登録したURIをそろえる。別名でアクセスする場合は、そのURIも登録対象になる。&lt;/p&gt;
&lt;h3 id="クライアントシークレットの作成"&gt;クライアントシークレットの作成
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;アプリの登録
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; →Immich
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; → 証明書とシークレット
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; → クライアント シークレット 
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; → 新しいクライアント シークレット
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;作成後に表示される &lt;strong&gt;「値（Value）」&lt;/strong&gt; をImmichに設定する。「シークレット ID」ではないので注意。&lt;br&gt;
値は作成直後にしか表示されないため、分からなくなった場合は新しいシークレットを作成する。&lt;br&gt;
&lt;a class="link" href="https://learn.microsoft.com/en-us/entra/identity-platform/howto-create-service-principal-portal#option-3-create-a-new-client-secret" target="_blank" rel="noopener"
 &gt;Microsoft 公式：クライアントシークレットの作成&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="利用するユーザーの割り当て"&gt;利用するユーザーの割り当て
&lt;/h2&gt;&lt;p&gt;自分のユーザーだけに利用を限定するため、エンタープライズアプリケーション側で設定する。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;EntraID
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; → エンタープライズ アプリケーション
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; → Immich
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; → プロパティ 
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; → 割り当てが必要ですか？ → はい
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;続いて、「ユーザーとグループ」から利用するユーザーを直接追加する。割り当てを必須にしたアプリには管理者による同意が必要になる。&lt;br&gt;
&lt;a class="link" href="https://learn.microsoft.com/en-us/entra/identity/enterprise-apps/assign-user-or-group-access-portal" target="_blank" rel="noopener"
 &gt;Microsoft 公式：ユーザーとグループの割り当て&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;ただし&lt;strong&gt;Global Administrator は割り当て必須の制限の例外&lt;/strong&gt;であることに注意。&lt;br&gt;
管理者ユーザーでログインできただけでは、未割り当てユーザーの拒否を確認できない。アクセス制限の検証には通常ユーザーを使う必要がある。&lt;br&gt;
&lt;a class="link" href="https://learn.microsoft.com/en-us/entra/identity/enterprise-apps/application-properties" target="_blank" rel="noopener"
 &gt;Microsoft 公式：エンタープライズアプリケーションのプロパティ&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="oauth-profile-does-not-have-an-email-addressメールアドレスがない"&gt;OAuth profile does not have an email address：メールアドレスがない
&lt;/h3&gt;&lt;p&gt;このまま続けていて、エラーが発生したのでメモ。メールアドレスの設定をしておく必要がある。&lt;br&gt;
発生したエラーは以下&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;OAuth profile does not have an email address
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Immichの新規OAuthユーザー登録では、プロファイルの &lt;code&gt;email&lt;/code&gt; が必要になる。&lt;br&gt;
&lt;code&gt;preferred_username&lt;/code&gt; がメールアドレスのような文字列でも、その値で &lt;code&gt;email&lt;/code&gt; を代用する実装にはなっていない。&lt;br&gt;
&lt;a class="link" href="https://github.com/immich-app/immich/blob/main/server/src/services/auth.service.ts" target="_blank" rel="noopener"
 &gt;Immich ソース：認証サービス&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;まずImmichの Scope が &lt;code&gt;openid email profile&lt;/code&gt; になっているか確認する。そのうえで、EntraIDのアプリ登録に &lt;code&gt;email&lt;/code&gt; のオプション要求を追加する。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;アプリの登録
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; →Immich
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; → トークン構成
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; → オプションの要求を追加 
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; → トークンの種類：ID
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; → email を選択 → 追加
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;img alt="emailの要求" class="gallery-image" data-flex-basis="709px" data-flex-grow="295" height="469" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://blog.teandt.net/posts/2026/09/20260912-220211/image01.png" srcset="https://blog.teandt.net/posts/2026/09/20260912-220211/image01_hu_6fb34c40a9158d35.png 800w, https://blog.teandt.net/posts/2026/09/20260912-220211/image01.png 1386w" width="1386"&gt;&lt;/p&gt;
&lt;p&gt;設定方法は &lt;a class="link" href="https://learn.microsoft.com/en-us/entra/identity-platform/optional-claims" target="_blank" rel="noopener"
 &gt;Microsoft 公式：オプション要求の構成&lt;/a&gt; を参照。&lt;/p&gt;
&lt;p&gt;現行の開発ブランチでは、ImmichはIDTokenに &lt;code&gt;email&lt;/code&gt; があればそのclaimsを使い、なければUserInfoを問い合わせる。&lt;br&gt;
どちらからもメールアドレスを取得できないと、新規登録に進めない。&lt;a class="link" href="https://github.com/immich-app/immich/blob/main/server/src/repositories/oauth.repository.ts" target="_blank" rel="noopener"
 &gt;Immich ソース：OAuth リポジトリ&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;ということで、メールアドレスをちゃんと設定しておく必要がある。&lt;br&gt;
EntraIDのユーザ設定でプロパティを見ると、連絡先情報項目に「メールアドレス」があることがわかる。&lt;br&gt;
ここに使いたいメールアドレスを入れておく必要がある。&lt;/p&gt;
&lt;p&gt;&lt;img alt="メールアドレス項目" class="gallery-image" data-flex-basis="124px" data-flex-grow="51" height="436" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://blog.teandt.net/posts/2026/09/20260912-220211/image02.png" width="226"&gt;&lt;/p&gt;
&lt;h2 id="immichの-oauth-を設定する"&gt;Immichの OAuth を設定する
&lt;/h2&gt;&lt;p&gt;Immichの管理画面で&lt;code&gt;Administration → Settings&lt;/code&gt; のOAuth Authenticationで設定。&lt;br&gt;
今回の構成で使う値は以下。&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;項目&lt;/th&gt;
 &lt;th&gt;設定値&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;Enabled&lt;/td&gt;
 &lt;td&gt;ON&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Issuer URL&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;https://login.microsoftonline.com/&amp;lt;TENANT-ID&amp;gt;/v2.0&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Client ID&lt;/td&gt;
 &lt;td&gt;アプリケーション（クライアント）ID&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Client Secret&lt;/td&gt;
 &lt;td&gt;作成したシークレットの「値」&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Scope&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;openid email profile&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;ID Token Signed Response Algorithm&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;RS256&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Userinfo Signed Response Algorithm&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;none&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Storage Label Claim&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;preferred_username&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Button Text&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;Login with EntraID&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Auto Register&lt;/td&gt;
 &lt;td&gt;ON&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Auto Launch&lt;/td&gt;
 &lt;td&gt;OFF&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Mobile Redirect URI Override&lt;/td&gt;
 &lt;td&gt;有効にして下記 URI を指定&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Mobile Redirect URI&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;https://immich.example.com/api/oauth/mobile-redirect&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;設定項目と標準値は &lt;a class="link" href="https://docs.immich.app/administration/oauth/#enable-oauth" target="_blank" rel="noopener"
 &gt;Immich 公式：OAuth の有効化&lt;/a&gt; を参照。画面によって署名アルゴリズムの項目名は異なる。&lt;/p&gt;
&lt;p&gt;Issuer URL の &lt;code&gt;&amp;lt;TENANT-ID&amp;gt;&lt;/code&gt; は実際のテナント ID に置き換える。EntraIDの管理画面を見ればわかるのでそちらを参照。&lt;br&gt;
Discovery 文書の URL は次になる。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;https://login.microsoftonline.com/&amp;lt;TENANT-ID&amp;gt;/v2.0/.well-known/openid-configuration
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;今回はシングルテナントなので、&lt;code&gt;common&lt;/code&gt; や &lt;code&gt;organizations&lt;/code&gt; ではなく、テナント ID を明示する。&lt;a class="link" href="https://learn.microsoft.com/en-us/entra/identity-platform/v2-protocols-oidc#fetch-the-openid-configuration-document" target="_blank" rel="noopener"
 &gt;Microsoft 公式：OIDC の構成文書&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="oauthで登録したユーザーをimmichの管理者にする"&gt;OAuthで登録したユーザーをImmichの管理者にする
&lt;/h2&gt;&lt;p&gt;自動登録されたユーザは管理者になっていないので、管理者として使いたい場合は元の管理者ユーザでログインして管理者権限を付与する必要がある。&lt;br&gt;
管理者でログインして「管理」→「ユーザー」→「対象のユーザー」→「編集」&lt;/p&gt;
&lt;p&gt;&lt;img alt="ユーザ設定" class="gallery-image" data-flex-basis="162px" data-flex-grow="67" height="591" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://blog.teandt.net/posts/2026/09/20260912-220211/image03.png" width="400"&gt;&lt;/p&gt;
&lt;h2 id="oauthで登録したユーザーのパスワードログイン"&gt;OAuthで登録したユーザーのパスワードログイン
&lt;/h2&gt;&lt;p&gt;OAuthで登録したユーザーはパスワードログインが出来ない状態なので、ローカル環境からログインするためにパスワードログインできるように設定する。&lt;br&gt;
元の管理者ユーザーでログインしたうえで「管理」→「ユーザー」→「対象のユーザー」→「パスワードをリセット」を実行すると、パスワードリセットしたうえでランダムパスワードが提示されるのでこれを使ってパスワードの再設定を行う。&lt;/p&gt;
&lt;h2 id="ログイン画面"&gt;ログイン画面
&lt;/h2&gt;&lt;p&gt;ログイン画面にOAuthログイン用の「Login with EntraID」を追加した形になりました。&lt;br&gt;
&lt;img alt="ログイン画面" class="gallery-image" data-flex-basis="216px" data-flex-grow="90" height="936" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://blog.teandt.net/posts/2026/09/20260912-220211/image04.png" srcset="https://blog.teandt.net/posts/2026/09/20260912-220211/image04_hu_687f237cf71de5b2.png 800w, https://blog.teandt.net/posts/2026/09/20260912-220211/image04.png 846w" width="846"&gt;&lt;/p&gt;</description></item><item><title>バックアップツールの見直し（rsnapshotからBackrestへ切替検討）</title><link>https://blog.teandt.net/posts/2026/09/20260912-163845/</link><pubDate>Sat, 12 Sep 2026 16:38:45 +0900</pubDate><guid>https://blog.teandt.net/posts/2026/09/20260912-163845/</guid><description>&lt;img src="https://blog.teandt.net/posts/2026/09/20260912-163845/image01.png" alt="Featured image of post バックアップツールの見直し（rsnapshotからBackrestへ切替検討）" /&gt;&lt;p&gt;これまでLinuxサーバーのバックアップにはrsnapshotを使っていましたが、GUIで設定出来るようにしたいとか外付けHDDを必要なときだけ接続してバックアップ出来るようにしたいとかあって、バックアップツールの見直しを検討。&lt;br&gt;
色々比較したけど扱いやすそうなresticをBackrestで操作するのを基本にしようと環境を構築してみた。&lt;/p&gt;
&lt;h2 id="ツール"&gt;ツール
&lt;/h2&gt;&lt;h3 id="backrest"&gt;Backrest
&lt;/h3&gt;&lt;p&gt;Backrestは、resticをWeb GUIから操作するための管理ツール。&lt;br&gt;
バックアップ処理自体はresticが行ってその管理をBackrestが行う形式。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;バックアップジョブの設定&lt;/li&gt;
&lt;li&gt;スケジュール管理&lt;/li&gt;
&lt;li&gt;保持世代の設定&lt;/li&gt;
&lt;li&gt;prune/checkなどのメンテナンス&lt;/li&gt;
&lt;li&gt;スナップショットの確認&lt;/li&gt;
&lt;li&gt;復元&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;をGUIで行える。&lt;br&gt;
復元も一括操作くらいなら大丈夫そうだけど、個別の世代のファイルを検索かけながら見つけて復元するような使い方は結構難しそうだったので復元が必要な場合はresticを直接CLIで操作してやることで対応する想定。&lt;/p&gt;
&lt;h3 id="restic"&gt;restic
&lt;/h3&gt;&lt;p&gt;機能として以下のようなものがあり、rsnapshotではハードリンクで対応していた世代重複の排除をブロック単位での重複排除で出来るようになっているみたい。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;暗号化&lt;/li&gt;
&lt;li&gt;重複排除&lt;/li&gt;
&lt;li&gt;圧縮&lt;/li&gt;
&lt;li&gt;スナップショット管理&lt;/li&gt;
&lt;li&gt;世代管理&lt;/li&gt;
&lt;li&gt;リポジトリ整合性チェック&lt;/li&gt;
&lt;li&gt;ローカルディスク、SFTP、S3など多様な保存先への対応&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;圧縮に関してはあまり期待していない。というのもバックアップ対象が圧縮済みのものが多いのでおそらくほとんど差がでないはず。&lt;/p&gt;
&lt;p&gt;独自形式で保存されるけど、restic mountコマンドでスナップショットをディレクトリにマウント出来る。
マウントして中身を通常のシェルから操作可能な状態に出来るのでrsnapshotとそんなに変わらない感覚でファイル単位での復元も可能そう。&lt;/p&gt;
&lt;h2 id="インストール"&gt;インストール
&lt;/h2&gt;&lt;h3 id="バックアップ用docker"&gt;バックアップ用Docker
&lt;/h3&gt;&lt;p&gt;今回は以下の方針&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;バックアップ用にBackrestをDocker（Docker compose）で構築運用&lt;/li&gt;
&lt;li&gt;リストアようにホスト側にresticを入れる&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Backrestは&lt;a class="link" href="https://github.com/garethgeorge/backrest" target="_blank" rel="noopener"
 &gt;公式のGitHubページ&lt;/a&gt;を参照して、公式のDocker composeファイルの記載内容を少しだけ修正して実行。&lt;/p&gt;
&lt;p&gt;以下が公式に挙がっているcomposeファイルの内容だけど&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Volumesの特にバックアップ対象と、出力先のマウント設定&lt;/li&gt;
&lt;li&gt;TZ設定&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;あたりだけ修正して実行すれば良い。&lt;br&gt;
バックアップ用としてrootで起動したいのでユーザは指定しない。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-compose.yaml" data-lang="compose.yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;services&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;backrest&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ghcr.io/garethgeorge/backrest:latest&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;container_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;backrest&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;hostname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;backrest&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;./backrest/data:/data&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;./backrest/config:/config&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;./backrest/cache:/cache&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;./backrest/tmp:/tmp&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;./backrest/rclone:/root/.config/rclone&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Mount for rclone config (needed when using rclone remotes)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;/path/to/backup/data:/userdata &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Mount local paths to backup&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;/path/to/local/repos:/repos &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Mount local repos (optional for remote storage)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;BACKREST_DATA=/data&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;BACKREST_CONFIG=/config/config.json&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;XDG_CACHE_HOME=/cache&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;TMPDIR=/tmp&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;TZ=America/Los_Angeles&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;9898:9898&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;restart&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;unless-stopped&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="ホスト用restic"&gt;ホスト用restic
&lt;/h3&gt;&lt;p&gt;ホスト用のresticはUbuntu 24.04LTSなのでaptで入れてもいいんだけど、aptで入れるとかなり古いバージョンになってしまいBackrestのdockerでlatestにするとバージョンがかなり違うため相性問題が出ると嫌なので、最新のバイナリをインストールしておく。&lt;br&gt;
バイナリは&lt;a class="link" href="https://restic.readthedocs.io/en/stable/020_installation.html#official-binaries" target="_blank" rel="noopener"
 &gt;公式&lt;/a&gt;からDLしてインストール。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo install -m &lt;span class="m"&gt;0755&lt;/span&gt; restic /usr/local/bin/restic
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;restic version
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;でインストールしてバージョンが表示されればOK。&lt;/p&gt;
&lt;p&gt;restic mountを使えるようにするにはfuseがインストールされている必要があるということなのでこれはaptで入れておく。&lt;br&gt;
自分の環境では入っていた。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;which fusermount 
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;でなければ&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install fuse3
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;で良いらしい。&lt;/p&gt;
&lt;p&gt;バージョンを上げたい場合は、&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo restic self-update
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;でアップデート出来るらしいので、次回からはバイナリを探しに行く必要は無いみたい。&lt;/p&gt;
&lt;h3 id="設定"&gt;設定
&lt;/h3&gt;&lt;p&gt;docker composeで起動したらブラウザからアクセスすると各種設定を要求されるので適当に入れておく。&lt;/p&gt;
&lt;p&gt;バックアップの設定としては、まずバックアップの保存先の指定として「リポジトリ」を作成する。そしてバックアップ元の指定とかスナップショット件数の設定とかは「プラン」で指定・作成する。試していないけど一つのプランで複数のパスが指定できるので、一つのリポジトリに対して複数のバックアップ元を指定することも出来るはず。&lt;/p&gt;
&lt;p&gt;その他、プランごとに実行タイミングを変えられるので、一つのリポジトリを対象に複数のプランを設定することも可能なはず。現時点では必要なくて試していないけど。&lt;/p&gt;
&lt;h2 id="バックアップデータのマウント"&gt;バックアップデータのマウント
&lt;/h2&gt;&lt;p&gt;バックアップしたデータをシェルからアクセス出来るようにするには&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo restic -r /snapshot_path mount /mnt/restic
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;でマウント出来る。&lt;br&gt;
実行後、リポジトリを作成した際に設定したパスワードを要求されるので入力するとマウントされる。注意点として、実行中しかアクセスできないので別ターミナルを開いてアクセスするとかの工夫は必要。&lt;/p&gt;
&lt;p&gt;Docker Composeファイルを見ればわかるけれど標準だとrootで実行されるため、バックアップデータはrootで保存される。なので、マウントするときにはsudoが必要だし、マウント後にファイルアクセスするにもsudoが必要。&lt;br&gt;
いくつか対策は考えられるけど、rootで管理したほうがいいとは思うので問題がなければこのまま運用してみる予定。&lt;/p&gt;
&lt;h2 id="今後に向けた備考"&gt;今後に向けた備考
&lt;/h2&gt;&lt;p&gt;8TBのHDDが4台？5台？ほど余っているので、定期的に外にバックアップするようにしたい。&lt;/p&gt;
&lt;p&gt;このような環境の場合、間違ってマウントされていない状態でマウントポイントにバックアップしてしまうのを防ぐ必要があるので、Backrestのhook処理に&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;mountpoint -q /mnt/backup-usb &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;exit&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;みたいな感じでマウントの確認チェックを入れておく必要がある。&lt;br&gt;
リポジトリの以下の部分にこの手の設定を入れればいいはず。&lt;/p&gt;
&lt;p&gt;&lt;img alt="Hooks設定項目" class="gallery-image" data-flex-basis="716px" data-flex-grow="298" height="322" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://blog.teandt.net/posts/2026/09/20260912-163845/image02.png" srcset="https://blog.teandt.net/posts/2026/09/20260912-163845/image02_hu_8ce84cc48969b8c5.png 800w, https://blog.teandt.net/posts/2026/09/20260912-163845/image02.png 961w" width="961"&gt;&lt;/p&gt;</description></item><item><title>セルフホストのimmichをCloudflare環境で100MB制限を回避する</title><link>https://blog.teandt.net/posts/2026/09/20260907-191550/</link><pubDate>Mon, 07 Sep 2026 19:15:50 +0900</pubDate><guid>https://blog.teandt.net/posts/2026/09/20260907-191550/</guid><description>&lt;img src="https://blog.teandt.net/posts/2026/09/20260907-191550/image02.png" alt="Featured image of post セルフホストのimmichをCloudflare環境で100MB制限を回避する" /&gt;&lt;h2 id="immich"&gt;immich
&lt;/h2&gt;&lt;p&gt;Google Oneを100GBで契約しているけどAIプランを使うつもりが無いのでストレージ容量を結構気にしないといけない感じになっている。&lt;br&gt;
画像のアップロード場BAN対象になりやすそうなのもあり、セルフホスト出来るGoogleフォト代替の&lt;a class="link" href="https://immich.app/" target="_blank" rel="noopener"
 &gt;immich&lt;/a&gt;を試してみる。&lt;/p&gt;
&lt;h2 id="cloudflareの公開アプリケーションにおける制限について"&gt;Cloudflareの公開アプリケーションにおける制限について
&lt;/h2&gt;&lt;p&gt;Cloudflareではプロキシトラフィック1ペイロードあたりの制限がプランごとに決まっていて、Freeプランでは100MBに制限されている。&lt;a class="link" href="https://developers.cloudflare.com/support/troubleshooting/http-status-codes/4xx-client-error/error-413" target="_blank" rel="noopener"
 &gt;Error 413&lt;/a&gt;&lt;br&gt;
&lt;img alt="Cloudflareの1ペイロード制限" class="gallery-image" data-flex-basis="1284px" data-flex-grow="535" height="225" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://blog.teandt.net/posts/2026/09/20260907-191550/image03.png" srcset="https://blog.teandt.net/posts/2026/09/20260907-191550/image03_hu_45bd489fdd0d3266.png 800w, https://blog.teandt.net/posts/2026/09/20260907-191550/image03.png 1204w" width="1204"&gt;&lt;/p&gt;
&lt;p&gt;画像であれば基本的に問題ないのでimmichで問題になることはあまりないかな？と思っていたけど動画を扱うと一瞬で100MBくらいは飛ぶのでできるだけ回避しておきたい。&lt;/p&gt;
&lt;h2 id="方針"&gt;方針
&lt;/h2&gt;&lt;p&gt;以下のような構成を想定して構築する。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;スマートフォン
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Cloudflare One Client / WARP
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ 認証済み端末
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ▼
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Cloudflare Zero Trust
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ Private hostname route
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ▼
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cloudflared（自宅）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ▼
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Immich
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;192.168.x.x:2283
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Cloudflare Zero TrustのPrivate hostname routeで公開せずにCloudflare Oneの認証を利用してアクセスする方式にする。&lt;br&gt;
ドキュメントを見ると以下の記載があり、1ファイルが大きい場合はPrivate network routeを使用するように記載がある。&lt;a class="link" href="https://developers.cloudflare.com/tunnel/routing" target="_blank" rel="noopener"
 &gt;Routing&lt;/a&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Public hostname routes proxy traffic through Cloudflare. On Free, Pro, and Business plans, the service-specific terms ↗ require you to use a specific paid service to serve video and other large files.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Refer to Delivering videos with Cloudflare for more information. To transfer large files privately, use a private network route instead.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Private networkについてはCloudflare One経由でのアクセスに限定されるけれど、現状CloudflareAccessの認証でOne/WARP利用を条件にしているので、使い勝手としては変わらないはず。&lt;br&gt;
自分以外、もしくは家族とか特定の人以外がアクセスしないような環境であればこの方法で問題ないはず、ということでこの方法で進める。&lt;br&gt;
そしてPrivate Hostname Routeについては先月一般提供始まった機能らしいので、これを使ってみる。&lt;/p&gt;
&lt;h2 id="構成環境"&gt;構成環境
&lt;/h2&gt;&lt;h3 id="概要"&gt;概要
&lt;/h3&gt;&lt;p&gt;環境としてはRHEL10のPodman環境で構築する。&lt;br&gt;
想定している構成は以下のような感じでtunnel用のcloudflaredをDMZ環境にしてリバースプロキシでやり取りする。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Cloudflare
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Immich Tunnel
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ▼
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;┌────────── Immich VM ────────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ Podman network: immich-edge │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ cloudflared ─── Reverse Proxy │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ─────────┼──────── │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ Podman network: immich-app │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ Immich Server │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ PostgreSQL / Valkey │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└─────────────────────────────────────┘
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;最終的にimmichはEntraIDログインを強制するように出来るようなので、そのようにすることでパスワードを個別に管理することもしないことにする。&lt;/p&gt;
&lt;h3 id="使用サービス"&gt;使用サービス
&lt;/h3&gt;&lt;p&gt;以下の構成で検討。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;edge
&lt;ul&gt;
&lt;li&gt;cloudflared&lt;/li&gt;
&lt;li&gt;caddy&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;app
&lt;ul&gt;
&lt;li&gt;immich-server&lt;/li&gt;
&lt;li&gt;postgres&lt;/li&gt;
&lt;li&gt;valkey&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;データ自体はNASのHDDに置くようにして、その他はSSDで管理するように。&lt;br&gt;
NASからVMまではNFSで共有。&lt;/p&gt;
&lt;h2 id="cloudflare-zero-trust設定"&gt;Cloudflare Zero Trust設定
&lt;/h2&gt;&lt;p&gt;いくつかの設定はあるけれど基本的には&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;tunnelの追加&lt;/li&gt;
&lt;li&gt;プライベートホストのルート設定を追加&lt;/li&gt;
&lt;li&gt;Accessのアプリケーション設定の追加&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;といった感じでいく。&lt;br&gt;
後述するけどプライベートホストの名前はTLSで通信するための証明書を確保しようとする場合は保有するドメイン名で適当につける。&lt;/p&gt;
&lt;h2 id="cloudflare-apiの設定"&gt;Cloudflare APIの設定
&lt;/h2&gt;&lt;p&gt;TLS用の証明書確保のためLet&amp;rsquo;s Encriptを使うのだけれど、ローカルのIPアドレスのためDNS-01を使用する。そのために更新用のCloudflareでAPI設定をする必要がある。&lt;/p&gt;
&lt;p&gt;アカウントの管理&lt;br&gt;
→ アカウントAPIトークン&lt;br&gt;
→ トークンを作成&lt;br&gt;
→ 最初から作成&lt;br&gt;
→ 対象を「指定ドメイン」にして対象を指定&lt;br&gt;
→ DNS &amp;amp; Zone&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;DNS：Edit 
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Zone： Read
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;に設定する。&lt;br&gt;
このときのAPIトークンを使用する。&lt;/p&gt;
&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="1683px" data-flex-grow="701" height="151" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://blog.teandt.net/posts/2026/09/20260907-191550/image01.png" srcset="https://blog.teandt.net/posts/2026/09/20260907-191550/image01_hu_7409e0d3412f7d46.png 800w, https://blog.teandt.net/posts/2026/09/20260907-191550/image01.png 1059w" width="1059"&gt;&lt;/p&gt;
&lt;p&gt;必要なトークンは一度しか表示されないので、記録を忘れたら作り直し。&lt;br&gt;
DNS-01の解説はこちらにありました。&lt;a class="link" href="https://qiita.com/n-eguchi/items/0cedd1a47f5621416204" target="_blank" rel="noopener"
 &gt;ホームサーバーの自己署名証明書を Let’s Encrypt の DNS-01 に変更し、自動配布まで行う&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="caddy"&gt;Caddy
&lt;/h2&gt;&lt;h3 id="docker構成"&gt;Docker構成
&lt;/h3&gt;&lt;p&gt;DockerHubにある標準？のCaddyだとCloudflareのDNS-01に対応していない？らしいのでCodexにDocerfile書いてもらった。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;dockerfile&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-dockerfile" data-lang="dockerfile"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;docker.io/library/caddy:2-builder-alpine&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;builder&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;RUN&lt;/span&gt; xcaddy build --with github.com/caddy-dns/cloudflare&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;docker.io/library/caddy:2-alpine&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;COPY&lt;/span&gt; --from&lt;span class="o"&gt;=&lt;/span&gt;builder /usr/bin/caddy /usr/bin/caddy&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;COPY&lt;/span&gt; Caddyfile /etc/caddy/Caddyfile&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="caddyfile"&gt;Caddyfile
&lt;/h3&gt;&lt;p&gt;リバースプロキシとして使用するCaddyがこのあたりの仕組みに対応しているようなので、Caddyfileに書いてしまう。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;caddifile&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-caddyfile" data-lang="caddyfile"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;	&lt;span class="k"&gt;email&lt;/span&gt; &lt;span class="se"&gt;{$ACME_EMAIL}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;	&lt;span class="k"&gt;acme_ca&lt;/span&gt; &lt;span class="s"&gt;https://acme-v02.api.letsencrypt.org/directory&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;	&lt;span class="k"&gt;auto_https&lt;/span&gt; &lt;span class="no"&gt;disable_redirects&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gh"&gt;https://&lt;/span&gt;&lt;span class="se"&gt;{$IMMICH_PRIVATE_HOSTNAME}&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;	&lt;span class="k"&gt;tls&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;		&lt;span class="k"&gt;dns&lt;/span&gt; &lt;span class="s"&gt;cloudflare&lt;/span&gt; &lt;span class="se"&gt;{env.CF_API_TOKEN}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;		&lt;span class="k"&gt;resolvers&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="s"&gt;.1.1.1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;	&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;	&lt;span class="k"&gt;reverse_proxy&lt;/span&gt; &lt;span class="n"&gt;immich-server&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;2283&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;ACME_EMAILやIMMICH_PRIVATE_HOSTNAMEは.envでまとめる感じで。&lt;br&gt;
先ほど設定したトークンはCF_API_TOKENに指定する。&lt;/p&gt;
&lt;h2 id="テスト"&gt;テスト
&lt;/h2&gt;&lt;h3 id="アクセステスト"&gt;アクセステスト
&lt;/h3&gt;&lt;p&gt;Cloudflare OneをONにした状態でアクセス出来るか確認してOKなら、その後Cloudflare OneをOFFにしてアクセスできないことを確認する。&lt;br&gt;
ついでに、ローカルからはTLSなしのhttpでアクセスすることにしたのでそういう環境で。&lt;br&gt;
immichのアプリ設定を見たところ、SSIDでローカル切替が出来るようなのでこれを利用してみたけど他のアプリと同様にVPN設定しているとWifiのSSID検出ができないようでうまくいかない。&lt;br&gt;
Cloudflare OneをOFFにしたら超高速でアップロードできたので、ちゃんとローカルと外部で切替はできている模様。&lt;br&gt;
やっぱりインターネット回線を10Gbpsにしたいな。&lt;br&gt;
10Gbpsでつながればゼロトラストな考えでローカルネットワークの通信も大半を一度インターネット側に渡しても良くなる気がする。&lt;/p&gt;
&lt;h3 id="大容量転送"&gt;大容量転送
&lt;/h3&gt;&lt;p&gt;この状態で起動して初期設定をしたあと、スマホで2分くらいの動画撮影してCloudflare経由で転送して問題ないことを確認する。&lt;br&gt;
300MBちょいのファイルを問題なく転送できたので、想定通りの動作をしている。&lt;/p&gt;</description></item></channel></rss>