Linux - TECH PLAY - TECH PLAY

TECH PLAY

Linux

イベント

マガジン

技術ブログ

こんにちは、OSSよろず相談室のSKです。 OSS に関するお問い合わせが日々寄せられる中で、今回は Linux における pam_faillock によるアカウント一時ロック に関連して寄せられたお問い合わせをご紹介します。 以下のような問い合わせがありました。 Red Hat Server 環境にて、一時的にログインができなくなる事象が発生しました。 一般ユーザがリモートからログインしたところ、認証エラーとなりログインできませんでした。 管理者(root)ユーザに切り替えて passwd -S コマンドで確認したところ PS (パスワード設定済み・有効)と表示されており、アカウントロック( LK )にはなっていません。 また、特に解除操作を行わなくても一定時間経過すると正常にログインできるようになります。何が原因なのでしょうか? passwd -S コマンドは /etc/shadow ファイルを参照しますが、 pam_faillock による一時ロック情報は /etc/shadow ではなく専用のディレクトリ( /var/run/faillock/ )で管理されているため、 passwd -S では確認できません。 今回は、このやり取りに関連して、「 pam_faillock とは何か」「 passwd -S で確認できない理由」「 faillock コマンドでの確認方法」「Linux(Red Hat系)での動作検証手順」について解説します。 pam_faillock とは? pam_faillock は、Linuxの認証システム(PAM)で提供されているセキュリティモジュールです。 短時間に指定された回数以上の認証失敗(パスワード間違いなど)が発生した際に、ブルートフォース攻撃(総当たり攻撃)などの不正アクセスを防ぐ目的で、該当アカウントを一時的に自動ロックします。 なぜ passwd -S で確認できないのか? passwd -S コマンドは /etc/shadow ファイルを参照 してアカウントのステータス( PS : パスワード有効、 LK : ロック等)を判定します。 passwd -S コマンド出力例 testuser PS 2026-09-01 0 99999 7 -1 (Password set, SHA512 crypt.) 一方、 pam_faillock による一時ロック情報は /etc/shadow を書き換えるのではなく、専用のディレクトリ(デフォルト: /var/run/faillock/ )に失敗履歴として記録・管理 されます。 そのため、 /etc/shadow 上は正常( PS )に見えても、 pam_faillock の失敗カウンタが上限に達していることで認証が拒否される現象が発生します。 システムログと設定パラメータ システムログ(/var/log/secure)の出力例 pam_faillock により一時ロックが発生すると、 /var/log/secure に以下のようなログが出力されます。 Sep 01 13:32:06 server sshd:pam_unix(sshd:auth): authentication failure; ... user=<対象ユーザ名> Sep 01 13:32:40 server sshd:pam_unix(sshd:auth): authentication failure; ... user=<対象ユーザ名> Sep 01 13:36:01 server sshd:pam_unix(sshd:auth): authentication failure; ... user=<対象ユーザ名> Sep 01 13:36:01 server sshd:pam_faillock(sshd:auth): Consecutive login failures for user <対象ユーザ名> account temporarily locked 設定パラメータ例(/etc/security/faillock.conf) /etc/security/faillock.conf の代表的な設定項目は以下の通りです。 deny = 3 fail_interval = 900 unlock_time = 1800 deny = 3 : 3回連続で認証失敗するとロックされます。 fail_interval = 900 : 15分間(900秒)の中で発生した失敗回数をカウントします。 unlock_time = 1800 : ロック発生後、30分間(1800秒)経過すると自動的にロックが解除されます。 注意点 パスワード変更では解除されない :ロック中にパスワード変更を行っても pam_faillock のロック状態は解除されません( passwd と pam_faillock の管理領域が独立しているため)。 失敗試行の繰り返しによる延長 :ロック中にログイン試行を繰り返すと新たな失敗履歴が追加され、ロック期間( unlock_time )がさらに延長されることがあります。 faillock コマンドによるロック状態の確認方法 pam_faillock による認証失敗履歴およびロック状態を確認するには、 faillock コマンド を使用します。 faillock --user <対象ユーザ名> 実行結果の例: When Type Source Valid 2026-09-01 15:25:51 TTY pts/1 V 2026-09-01 15:25:59 TTY pts/1 V 2026-09-01 15:26:06 TTY pts/1 V Valid 列に V が表示されている試行が有効な失敗記録としてカウントされており、これが指定回数( deny の値)に達するとロック状態となります。 Linux での動作検証手順 実際に Linux(今回は Red Hat Enterprise Linux 8)環境で pam_faillock の動作を確認する手順例です。 1. テスト用ユーザの作成 # useradd testuser # passwd testuser 2. SSSDの最小構成設定と起動 # cat << 'EOF' > /etc/sssd/sssd.conf [sssd] config_file_version = 2 services = nss, pam domains = files [domain/files] id_provider = files EOF # chown root:root /etc/sssd/sssd.conf # chmod 600 /etc/sssd/sssd.conf # systemctl enable --now sssd 3. authselect による faillock の有効化 # authselect enable-feature with-faillock # authselect apply-changes # authselect current 4. faillock.conf の設定 # cp -p /etc/security/faillock.conf /etc/security/faillock.conf.org # cat << 'EOF' >> /etc/security/faillock.conf deny = 3 fail_interval = 900 unlock_time = 60 EOF 5. 意図的な認証失敗とロック確認 一般ユーザへ切り替えた上で、わざとパスワードを間違えてログインを試みます。 # su - testuser # パスワードを3回以上間違える その後、root ユーザで失敗履歴を確認します。 # faillock --user testuser まとめ Linux で「パスワード設定は正常( PS )なのにログインできない」場合は、 pam_faillock による一時ロック を疑い、 /var/log/secure や faillock --user <ユーザ名> コマンドで状態を確認することが有効です。 ご覧いただきありがとうございました! 参考ドキュメント  pam_faillock(8) — Linux manual page   https://man7.org/linux/man-pages/man8/pam_faillock.8.html  faillock(8) — Linux manual page   https://man7.org/linux/man-pages/man8/faillock.8.html ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post OSSサポートの現場から!一時的なアカウントロックの原因とは first appeared on SIOS Tech Lab .
Hyper-VのDefault Switchに接続されたLinux仮想マシンのIPアドレスが再起動のたびに変わる問題を回避し、「mshome.net」を利用して固定のホスト名でSSH接続する方法とその注意点について解説します。
許可がどこで決まっているか、実はちゃんと確かめたことがなかったんですよね。auto mode で回してはいるものの、何がどう自動で通っていて、何が誰の判断を経ているのか、腰を据えて追いかけたことは一度も無くて。 僕の場合は「 CLAUDE.md に書いてあるから塞げている」と思ってたんですよね。壊されたくない場所があったので CLAUDE.md に「これはやるな」って書いておいて、それで防御になっていると。 入口は2つあると思ってます。8月14日の既定化で、設定した覚えがないのに auto mode になっていた人もいれば、僕みたいに CLAUDE.md で塞いだつもりでいた人もいると思います。でも聞きたいことは同じで、auto mode って実際どう動いているのか、追加のルールはどこに書けば効くのか。この2つに絞って書いていきます。 auto mode って実際どんなフローで動いてんの? 8月14日から auto になったのは Pro・Max・Team プランの対話セッションだけです。経緯は 公式ブログ に譲りますね。バージョンにも条件があって、macOS・Linux・WSL は v2.1.228 以降、Windows ネイティブは v2.1.233 以降が対象です。それより前のバージョンでは、既定はいまも Manual のままです。Enterprise プランと Claude Console の API キー、それにヘッドレスの claude -p は、既定が auto になりません。auto mode 自体が使えないわけじゃないので、自分で切り替えれば動きます。 判定は3つの分かれ道になっていて、上から順番に見ていって、最初に当てはまったところで決着します。つまり後ろの分かれ道が見るのは、それより手前で決まらなかったものだけなんですよね。ここには例外がいくつかあるんですが、この記事に効いてくるのは1つだけなので、3つを並べたあとで書きますね。 permissions 。allow / ask / deny を自分で settings.json に書いたルールです。ここに一致したら、allow ならそのまま実行、ask なら確認が出て、deny なら拒否になります。そこで終わりで、classifier は呼ばれません。 自動承認 。読み取りと、 Write や Edit みたいな編集ツールによる working directory 内の編集です。 permissions で決まらなかったものは、ここで誰にも確認されずに通ります。逆に言うと、Bash コマンドはここには入りません。中で何をするかに関係なく、classifier に回ります。 classifier 。それ以外の全部を、この別のモデルが判断します。結果は実行か拒否かの二択で、拒否されても自分には聞かれません。Claude が理由を受け取って別の手を試すだけです。 気づいてほしいのは、この3つがどれも「Claude Code が何を通すか」の話だということです。 CLAUDE.md や Skills は、ここに入っていないんですよね。 permissions は Claude Code が叩けるコマンドの選定、classifier は自然言語で足す判断ルール、 CLAUDE.md や Skills は何を生成させるか。前の2つは実行のときに通すかどうかを決めるもので、見られる順番が違うだけです。この順番で監査が行われて、問題なければ自動で実行されるって感じです。 CLAUDE.md や Skills はその手前、何をやろうとするかを決める側にいます。 3つ目の「それ以外の全部」は、思ったより広いです。中身に関係なく Bash コマンドは全部ここですし、MCP ツールや、working directory の外への編集も入ります。 しかも、classifier に回る量は増える方向なんですよね。Claude Code 自体が Bash を優先して使うようになっていて、ファイルを読むのも cat 、直すのも sed で済ませたりします(v2.1.221 から。changelog には載っていません。詳しくは 同僚が追いかけた記事 )。 Read や Edit なら自動承認で終わる話が、Bash に化けたぶんだけ classifier に回ります。 ただ、protected paths( .git や .claude 、 .devcontainer など)への書き込みは、この流れから外れます。working directory の中にあっても自動承認されませんし、 permissions の allow に一致していても素通りしません。どちらの場合も classifier に回されます。設定の書き込みに対して割込みが入るのは安心感がありますね。 ここで効いてくるのが2つ目の自動承認です。 Write や Edit みたいな編集ツール経由の編集は、classifier に届く前にここで決着します。 実際、壊されたくないファイルを classifier 側の設定( autoMode の soft_deny 。危ないと思うものを自然言語で書いておく欄です)に書いておいて、そこを自分で書き換えにいったことがあります。手元の 2.1.233 で試したときは、同じパスに対して Bash 経由( cp や git checkout -- 、 cat > 、 truncate )は拒否されたのに、 Write ツールと Edit ツールは素通りしてました。2セッション・4ファイルで一致したので、たまたまではなさそうです。ただしこれは soft_deny に書き足したうえでの観測なので、素の設定だとまた違う結果になるはずです。そこは前提として持っておいてください。 追加のルールを効かせたいとき、どこに書けばいいの? auto mode に何か足したい、という発想自体はまちがってないです。ただ、まず手が伸びるのは CLAUDE.md だと思うんですよね。さっき、 CLAUDE.md はこの流れの外だと言いました。なぜ外なのか。 理由は、読まれていないからじゃないんです。 公式ドキュメント にも “The classifier sees user messages, tool calls other than read-only lookups such as file reads and searches, and your CLAUDE.md content” とはっきり書いてあって、classifier はちゃんと CLAUDE.md の中身を読んでます。読まれてはいるんです。ただ、 別のページ にはこう書いてあります。”Permission rules are enforced by Claude Code, not by the model. Instructions in your prompt or CLAUDE.md shape what Claude tries to do, but they don’t change what Claude Code allows.” つまり CLAUDE.md は Claude に「こう振る舞ってほしい」という方向性を渡す場所であって、実際に止める・止めないを決めるのは Claude Code 側の permission rules のほうです。読まれてはいるけど、止める力は持っていない。だから流れの外なんです。 じゃあ、その permission rules はどこに書くのか。ここで大事なのが、 止めたいものによって書く場所が違う ということです。編集を止めたいなら permissions 、classifier の判断に効かせたいなら autoMode 。整理すると、こうなります。 どこで決まるか 何が対象か 追加ルールを書ける場所 permissions 自分で書いた allow / ask / deny に一致するもの .claude/settings.json (project)や ~/.claude/settings.json (user) 自動承認 permissions で決まらなかった、読み取りと編集ツールによる working directory 内の編集(Bash コマンドは入らない) 書ける場所が無い classifier それ以外ぜんぶ autoMode (個人は ~/.claude/settings.json のみ。managed settings では組織が配布できる) 判定の外 classifier は読むけど、それ自体は判定しない CLAUDE.md や Skills(生成の方向性を渡す場所) 書く場所が違うといっても、ファイルが分かれるわけじゃないです。個人の設定なら、どちらも ~/.claude/settings.json の中にこう並びます。 { "permissions": { "deny": [] }, "autoMode": { "soft_deny": [] } } 上の permissions が編集を止める側、下の autoMode が classifier に効かせる側。中身はこのあと、節ごとに埋めていきます。 それと、この2つは択一じゃないです。 同じものを本当に守りたいなら、両方に書くことになります。 permissions が本命で、 autoMode は保険。なぜ保険まで要るのかは、次の節で実際に測った結果と一緒に書きますね。 ※ protected paths への書き込みは例外で、working directory の中にあっても自動承認されず、 permissions の allow に一致していても素通りしません。どちらも classifier に回されます。protected paths は公式に列挙されていて、ディレクトリなら .git や .claude 、 .vscode 、 .devcontainer など、ファイルなら .gitconfig やシェルの設定ファイル、 .npmrc 、 .pre-commit-config.yaml 、 .mcp.json などが入ります。ここで注意したいのは、 .env や SSH の鍵はこの一覧に入っていないことです。名前からして守られていそうですが、protected paths ではないので、機密を守りたいならそこは自分で permissions に Read(パス) の deny を書く必要があります。 Read の deny は Edit・Write も一緒に塞いでくれます。 自動承認される前に止めたいとき 自動で編集されるのを止めたいなら、書き先は permissions です。working directory の中の編集はそのまま自動承認されますし、 autoMode が効くのは classifier に回ってきたものだけなので、自動承認で決着した編集には届かないからです。 書くなら permissions の Edit(パス) の deny や ask です。 permissions は自動承認より先に見られるので、working directory かどうかに関係なく、まずここでせき止められます。 たとえば .env を触らせたくないなら、こう書きます。 { "permissions": { "deny": [ "Read(./.env)" ] } } Edit じゃなくて Read で書いているのは、 Read の deny が Edit・Write も一緒に塞いでくれるからです。そこに新しくファイルを作るのも塞がれます。読み出しも書き換えも、まとめてここで止まります。 ただし、この deny で止まるのは編集ツール経由の編集だけです。 Bash 経由の編集は classifier に回ります。しかも、Claude Code 自体が Bash を優先して使うようになっていて(さっき出した v2.1.221 の話です)、ファイルの書き換えも sed -i や cat > で済ませることが増えています。 permissions に Bash(...) の deny を書く手もあるんですが、コマンドの形は無数にあるので、パスを守る用途だと取りこぼします。 さっき「両方に書くことになる」と言ったのは、これが理由です。 permissions は classifier が呼ばれる前に止まるので、こちらが本命。そこをすり抜ける Bash 経由を classifier で受け止めるのが autoMode で、こっちが保険です。実測がそのまま根拠になっていて、 soft_deny に書いたパスで Bash 経由は拒否されたのに、 Write ・ Edit は素通りしました。片方だけでは穴が開く、ということです。 classifier の判断を変えたいとき 一方で、classifier の判断そのものに手を入れたいとき、「うちではこれも危ないから、いったん止めてほしい」というルールを足したいときは、 autoMode の soft_deny に書きます。効くのは classifier に回ってくるものなので、working directory の外だけじゃなくて、中にあるパスでも Bash 経由の操作なら対象になります。個人が書ける場所という意味では、これは user setting、つまり ~/.claude/settings.json だけです。project の .claude/settings.json にも settings.local.json にも書けません(ここは後でまとめて触れます)。組織が配布する managed settings には autoMode を書けて、そちらは読まれますが、それは配る側の話なので今回は自分の環境で完結する範囲にとどめます。 置き場所としては、 autoMode の下に allow や hard_deny と並んで soft_deny という配列があります。さっきの .env を Bash 経由でも守るなら、こう書きます。 { "autoMode": { "soft_deny": [ "$defaults", "機密ファイル [named+specifics — must name: 対象のパスと操作]: .env とその複製を Bash 経由で読む・書き換える・消す" ] } } ちなみに .env は、公式が auto mode の「既定で許可されるもの」に名指しで挙げてます。「 .env を読んで、対応する API に認証情報を送る」が、そのまま許可の一覧に載ってるんですよね。名前からして守られていそうなのに、既定では通る側です。守りたいなら自分で書くしかない、というのはそういう意味です。 1つ目の $defaults は忘れないでください。ここを削って自分のラベルだけにすると、Claude Code が最初から持っている既定の防御を丸ごと置き換えてしまいます。 soft_deny なら force push や curl | bash 、本番へのデプロイ、auto mode の迂回まで、まとめて消えます。実害があるところなので、コピペするときは気をつけてほしいです。 中身が気になるなら claude auto-mode defaults で全部出ますし、 --label を付ければ1つずつ読めます。 claude auto-mode defaults --label 'Git Destructive' [named+specifics — must name: 何を名指しさせるか] というラベルは、会話の中でパスと操作を名指しすれば解除できる、というバーの高さを表しています。 soft_deny の「soft」はここのことです。さっき保険と書いたのはこの意味で、 permissions の deny と違って、こちらは名指しされれば開きます。 効いてない設定が3つある ここまでで置き場所は分かったんですが、実は 書けたのに効いていない 、という形の事故が3か所あります。 3つに共通しているのは、書けてしまうことです。設定としては受け付けられるので、書いた本人は効いているつもりでいる。だから気づけないんですよね。 ひとつ断っておくと、一次ソースを確認したのは 2.1.245、実測は 2.1.233 のときのものです。3つとも公式に書かれている挙動なんですけど、公式の挙動も版で動きます。 ひとつ目。 autoMode を project の .claude/settings.json や settings.local.json に書いても読まれません。理由も公式に書いてあって、この2つはリポジトリの中にあるので、チェックインされた設定やビルドの一手が自分で allow を注入できてしまうからです。個人が書ける場所は user setting、つまり ~/.claude/settings.json だけです(どこが読まれるかは 公式ドキュメント にスコープの一覧があります)。 ふたつ目。 permissions で編集を止めたいときは Edit(パス) で書きます。 Write(パス) も設定としては受け付けられるんですけど、実際の判定では参照されません。さっきの Configure permissions に、ファイルの permission で見られるのは Edit(パス) と Read(パス) だけだと書いてあります。3つのうちこれだけは起動時に警告が出るので、見ていれば気づけます。 みっつ目。auto mode に入っているあいだは、広い allow が落ちます。公式に挙がっているのは5つで、 Bash(*) や PowerShell(*) みたいな丸ごとの許可、 Bash(python*) みたいなワイルドカードのインタプリタ、パッケージマネージャの run 、 Agent の allow、 Monitor の allow です。一覧は公式ドキュメントの「 How the classifier evaluates actions 」にあります。 Bash(npm test) みたいな狭い指定は残ります。 なお、その狭い指定まで含めて全部 classifier に回したいなら、 autoMode の classifyAllShell を true にする手もあります。判定を1回ぶん待つことになるので、速さと引き換えですね。 落ちるといっても消えるわけじゃなくて、manual に戻せばまた効きます。なお Monitor がこの一覧に入ったのは v2.1.236 からで、それより前は auto mode でも効き続けていました。 自分の環境がどうなっているかは claude auto-mode config で確かめられます(やり方は次の節で書きます)。 書いたとおりに、毎回そのとおり効くの? ここまでの内容を自分の運用に落とすと、 ~/.claude/settings.json はホストと bind で共有していて、複数の開発環境をまたいでも同じ判定基準を持たせてます。リビルドしても消えないので、環境ごとに書き直す手間がありません。何を共有して何を分けるかの設計は 別記事 に整理してあります。 揺れたときの条件 環境をまたいでは効くとして、時間をまたいでも同じように効くのか。ここは留保が要ります。前日に同じルールが止めた削除が、翌日の新しいセッションでは通ってしまったことがあって。設定も対象のディレクトリも同じで、解除条件を満たしたわけでもありません。しかも揺れは片方向だけじゃなくて、同じ日に逆向きも起きていて、削除は通ったのに復元しようとした4つの経路が全部拒否されたこともあります。効くか効かないかが両方向に振れて読めない、というのが正確なところです。どちらの観測もまだ1件ずつなので、そこは留保として置いておきます。 原因はまだ特定できていません。公式ドキュメントには、classifier が出した deny は対話 CLI だとそのターンのあいだだけ持続する、という記述があります。ただこれは判定がどこまで有効かという話です。日をまたいで揺れた理由を説明するものではないので、原因の説明とは切り離して、別立ての事実として置いておきます。 別の環境で似た揺れを観測している人 もいるようです。 落ち方を混ぜると読めなくなる ここで揺れ方を混ぜないように整理しておきます。 「判定の揺れ」: いま話したのは、判定は返ってきたけど結果が日をまたいで変わった、という揺れです。 「問い合わせの失敗」: これとは別に、classifier への問い合わせそのものが失敗して cannot determine the safety が返ってくることがあります。 公式ドキュメント にも “usually transient” と書いていて、確認を挟む側に倒れる分には安心していい動きです。 「回数で止まる」: classifier が3回続けてブロックするか、セッション通算で20回に達すると、auto mode がいったん止まって確認が戻ってきます。出てきた確認を承認すればまた auto に戻りますし、途中で1つでも通れば連続のカウントはリセットされます。閾値は変えられません。さっき「classifier に拒否されても自分には聞かれない」と書きましたが、確認が戻ってくるのはここです。 「auto mode の停止」: もう一つ、auto mode がそもそも動かなくなることもあります。こちらは 公式ドキュメント が “not a transient outage” と書いているとおり一時的ではなくて、自分もセッションを再起動して直らず manual に戻したことがあります。 問い合わせの失敗が安心できるからといって、判定の揺れまで安心していいわけではありません。判定の揺れでは classifier がちゃんと判定を返しているので、問い合わせの失敗とは別の場所で起きています。逆に言うと、通ってしまう側に振れるのは判定の揺れだけです。残りの3つは、確認が戻ってくるか、そもそも止まるかで、安全側に倒れます。 で、どうしているか こういう判定の揺れに対して、自分がやっているのは原因を追いかけるのをやめることです。追っても割に合わないので。 かといって、揺れた当のものを permissions に移したわけでもないんですよね。submodule の削除は、いまも autoMode の soft_deny に置いたままです。 rm を permissions で塞ぎにいくと、Claude Code が元から持っている安全装置と役割がかぶるので、そこは重ねずに任せているという判断です。 じゃあ何をしているかというと、どれを classifier に預けているかを自覚しておく、くらいのことです。確実に止めたいものは、揺れの話とは関係なく最初から permissions に置いてあります。機密ファイルの読み出しは Read(パス) の deny、複数セッションで事故りやすい git add -A は Bash(...) の deny。ここは classifier の判断を待たずに手前で決着するので、そもそも揺れません。逆に classifier に預けたものは、揺れることを承知で預けている。どこに書くかの使い分けって、結局そこの線引きなんだと思います。 スマホから渡して回すときの運用は 別記事 に書いていて、そこでは「何を触らせるかは分かったうえで渡す」という前提を先に置いています。 で、自分のは今どうなってる? CLAUDE.md に書いておけば止まっていると思ってた僕みたいな人は、一度 claude auto-mode config で自分の autoMode の中身を確認しておくといいと思います。project の .claude/settings.json や settings.local.json に書いた autoMode が読まれているかどうかも、ここに出るかどうかで分かります。 ひとつだけ注意点があって、出力をそのまま grep に掛けるのはやめたほうがいいです。途中の説明文にたまたま引っかかって、変な断定をしたことがあるので。まず、パースが通ることを確かめてから中身を見てください。 claude auto-mode config | python3 -c "import json, sys; json.load(sys.stdin)" これでエラーが出なければ、 allow や soft_deny の中身を安心して読みにいけます。 ここまで書いておいてなんですが、この記事の内容も、測った版から動いている可能性があります。実際 Monitor の件がそうでした。だから最後に置くのは答えじゃなくて、自分の手元を確かめる方法のほうかなと思ってます。 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post Claude Code の auto mode はどう動く?追加ルールを書く場所を整理してみた first appeared on SIOS Tech Lab .

動画

書籍