概要
Raspi5で作業中にssh接続できなくなるという問題に直面したため、それを解決しました。それの備忘録です。
状況
-
Raspi5でROSをDockerで動かしており、CPU負荷の重い自律走行を実行すると、ssh接続が切断される。(Connection reset)
-
切断されたときのコメントは
client_loop: send disconnect: Connection reset
-
ssh -T "echo OK" のような 非対話コマンドは通る。
-
sshd ログでは「session open」まで進んでから クライアントが切断。
-
Raspiを再起動すれば大抵直るが、いちいち再起動するのはメンドクサイ。
原因
pam_systemd.so が D-Bus 経由で systemd-logind にセッション登録を行う際、高負荷下で応答が返らずハング。
→ PAM がブロックされ、sshd セッションが閉じられる。
→ Windows クライアント側で Connection reset。
ChatGPTが言う技術的背景(個人的にはD-Busが詰まるんだなっていうことしかわからん)
pam_systemd.so はログイン時に systemd-logind へ「新しいセッションを作成して」とD-Bus 通信 (/run/systemd/private) を行う。この通信は同期(ブロッキング)で、logind が応答しないと sshd が止まる。CPU高負荷やメモリ不足時、D-Busキュー詰まり・logindデッドロックが発生。
結果的に認証は通るが、PAMが応答を返せずSSHがタイムアウト。
解決策
/etc/pam.d/sshd 内の次の行をコメントアウト:
session optional pam_systemd.so
session optional pam_motd.so
もしくは、コマンドラインから
sudo sed -i -E 's/^(\s*session\s+optional\s+pam_systemd\.so.*)$/# \1/' /etc/pam.d/sshd
sudo sed -i -E 's/^(\s*session\s+optional\s+pam_motd\.so.*)$/# \1/' /etc/pam.d/sshd
そして、sshdを再起動する。
sudo systemctl reload ssh
要するに...
pam_systemd.so は「systemdへ“いま誰がログインしているか”を登録するだけのモジュール」であり、その通信が高負荷時に詰まると SSH全体が人質になる。
コメントアウトは「systemdへの報告を止めて、SSHを生かす」安全な対処となる。
補足(将来の自分へ)
もしくは、/dev/pts/ptmx の権限が 000 になっており、PTYが作れない状態になっているかもしれないので、それも確認するように。
- 一時修正
sudo mount -t devpts -o remount,mode=620,gid=5,ptmxmode=0666 devpts /dev/pts
- 恒久的な修正
devpts /dev/pts devpts defaults,gid=5,mode=620,ptmxmode=0666 0 0
感想
ChatGPT全面協力の元解決したが、正直ChatGPTさんは同じことを繰り返し支持してきたり、取り返しのつかないコマンドを打たせたりしてくるので、気を付けないといけない。
やはり、強力なツールを持っていても使用者がそれに見合った技術を持っていなければ、問題解決をスピーディに行うことは難しい。今回は運よく解決したが、パラメータ調整などの実機を伴う指令や最新packageの参照、複雑な要件の環境構築などはうまくいかないことが多いので、もっと問題の核心を自分で発見できるようにならなければ。