SSHのパスワード認証を止める:Ubuntu 24.04の50-cloud-init.conf
Ubuntu 24.04のVPSで/etc/ssh/sshd_configにPasswordAuthentication noと書いても、/etc/ssh/sshd_config.d/50-cloud-init.confにPasswordAuthentication yesがあれば、パスワードで入れる状態のまま変わらない。sshdは同じ項目で最初に読んだ値を使い、Ubuntuのsshd_configは先頭近くでsshd_config.dのファイルを読み込むためだ。止めるなら、sshd_config.dに00-で始まるファイルを作って書き、sudo sshd -Tで実際の値を見る。
2026年10月23日に、Docker Hubのubuntu:24.04へopenssh-server(1:9.6p1-3ubuntu13.20)とcloud-init(26.1-0ubuntu1~24.04.1)を入れ、ファイルの組み合わせごとにsshdが採る値と、systemctl restart sshの後に実際にパスワード・鍵で入れるかを確かめた。
- 鍵で入れるか確かめる別の端末から鍵でログインできることを先に見る。今のセッションは閉じない
- 00-local.conf に書くsshd_config.d の 50-cloud-init.conf より前に読まれる名前で、PasswordAuthentication no を書く
- sshd -T で値を見る書いた内容でなく、sshdが採った値を確かめてから再起動する
- 別の端末から試すパスワードは Permission denied (publickey). で断られ、鍵では入れることを見る
確かめた環境と方法
- コンテナは
ubuntu:24.04。aptでopenssh-server、cloud-init、sshpass(パスワードでの接続を試すため)を入れた - ファイルの組み合わせの比較は、sshdを
/usr/sbin/sshd -p 2222として直接起動して行った。反映と接続の確認は、別のコンテナでsystemd(255.4-1ubuntu8.18)を動かし、systemctl restart sshで行った - 値の確認は
sshd -T(設定を読み込んで、採った値をすべて表示する)。接続は同じコンテナの中から127.0.0.1へ行った - 実行したスクリプトと出力の全文は公開していない。下の表と本文に、確かめた値と表示をそのまま載せた
VPS事業者のOSイメージで50-cloud-init.confに何が書かれているかは、事業者ごとに確かめていない。下の手順の2つ目で、自分のVPSのファイルを先に見てほしい。
どちらの値が使われるか
OpenSSHのsshd_configのマニュアルは、同じ項目が複数あるときは「the first obtained value will be used」(最初に得た値を使う)と書き、Includeのファイルは辞書順に読むとしている。Ubuntu 24.04の/etc/ssh/sshd_configは、12行目がInclude /etc/ssh/sshd_config.d/*.confで、#PasswordAuthentication yesは66行目にある。つまり66行目を書き換えても、sshd_config.dの値が先に読まれる。
組み合わせを変えてsshd -Tで見たpasswordauthenticationの値は次のとおりだった。
| 設定の置き方 | sshdが採った値 |
|---|---|
何も変えない(sshd_config.dは空) |
yes(既定値) |
50-cloud-init.confにyes |
yes |
50-cloud-init.confにyes、sshd_configの66行目をnoに |
yes(noは使われない) |
50-cloud-init.confにyes、99-local.confにno |
yes(99は50より後に読まれる) |
50-cloud-init.confにyes、00-local.confにno |
no |
sshd_configの66行目は#付きで、既定値はyes。公式のマニュアルでもPasswordAuthenticationの既定はyesになっている。何も書かなければパスワードで入れる。
cloud-initが50-cloud-init.confを書く条件
cloud-init 26.1のソース(cloudinit/config/cc_set_passwords.pyとcloudinit/ssh_util.py)を読むと、次の動きになっていた。
- ユーザーデータの
ssh_pwauthがtrueならyes、falseならnoをPasswordAuthenticationとして書く。指定が無ければ触らない - 書き込み先は、
sshd_configにInclude /etc/ssh/sshd_config.d/*.confの行があれば/etc/ssh/sshd_config.d/50-cloud-init.conf(このファイルが無ければ権限600で新しく作る)。その行が無ければsshd_configそのものを書き換える - この処理(
set_passwordsモジュール)の実行頻度はPER_INSTANCEで、インスタンスごとに1回
PER_INSTANCEなので、普段の再起動のたびに書き直す作りではない。ただし、スナップショットやイメージから別のVPSを作ったとき、cloud-initが新しいインスタンスと判断すればもう一度動く(実際のVPSでは試していない)。OSを入れ直した場合は00-local.confも消えるので、書き直しが要る。50-cloud-init.confを直接noに書き換えるより、自分の設定は00-local.confのような別のファイルに置く方が、cloud-initの書き込みと混ざらない。
締め出されないための準備
パスワード認証を止めた後に鍵で入れなければ、SSHでは入れなくなり、事業者のコンソールから設定を戻すことになる。先に次を確かめる。
| 確かめること | やり方 |
|---|---|
| 鍵でログインできる | 別の端末からssh -i <秘密鍵> <ユーザー>@<VPSのIP>で入る |
authorized_keysの権限 |
chmod 700 ~/.sshとchmod 600 ~/.ssh/authorized_keys |
| SSHを使わずに入る方法 | 事業者の管理画面に、ブラウザから操作するコンソールがあるかを見ておく |
権限は実際に試した。authorized_keysを600にした状態では鍵で入れ、666(誰でも書き込める)に変えると、同じ鍵でPermission denied (publickey)になった。sshdのStrictModes(既定で有効)が、他人が書き換えられるファイルを使わないためだ。鍵の作り方や、誰がどの鍵を持つかの記録は認証情報の台帳にまとめた。
設定の書き方と確かめ方
まず既存のファイルを見る。
ls -l /etc/ssh/sshd_config.d/
sudo cat /etc/ssh/sshd_config.d/*.conf
次に、自分の設定を00-local.confに書く。
sudo tee /etc/ssh/sshd_config.d/00-local.conf <<'EOF'
PasswordAuthentication no
KbdInteractiveAuthentication no
EOF
KbdInteractiveAuthenticationは、パスワードを別の方式で尋ねる認証で、Ubuntu 24.04のsshd_configでは71行目でnoになっていた。ただ、これもsshd_config.dの値が先に読まれるので、同じファイルにnoと書いておく。PAMでワンタイムパスワードなどの二段階認証を使っている場合は、この行をnoにするとその方式でも入れなくなる。使っているかは、先に/etc/pam.d/sshdとAuthenticationMethodsの設定を見る。
書いたら、反映する前に2つのコマンドを打つ。
sudo sshd -t
sudo sshd -T | grep -E '^(passwordauthentication|kbdinteractiveauthentication|permitrootlogin)'
sshd -tは書き間違いを見つける。わざとPasswordAuthentcation no(iが抜けている)と書いたファイルを置くと、Bad configuration option: PasswordAuthentcationと出て終了コード255で止まった。何も表示されなければ問題ない。sshd -Tではpasswordauthentication noと出ることを確かめる。permitrootloginは既定でwithout-passwordと表示された。sshd_configのマニュアルではwithout-passwordはprohibit-passwordの古い別名で、rootはパスワードでは入れない。
値がnoになっていたら、今のSSHのセッションを閉じずに反映する。Ubuntu Serverの公式ドキュメントはsudo systemctl restart ssh.serviceを案内している。
sudo systemctl restart ssh
systemctl is-active ssh
systemdを動かしたコンテナでは、ssh.socketが既定で有効(ssh.serviceは無効)で、最初の接続が来たときにssh.serviceが起動した。00-local.confを書いただけで再起動しないうちは、パスワードで入れたままだった。systemctl restart sshの後はssh.serviceもssh.socketもactiveで、再起動の前からつないでいたセッションは切れずに残った。
反映した後に、別の端末から試す
今のセッションを残したまま、別の端末から2通り試す。1つ目は鍵を使わない指定(PubkeyAuthentication=no)を付ける。付けないと、手元の鍵で入れてしまい、パスワードが止まったかを判断できない。
ssh -o PreferredAuthentications=password -o PubkeyAuthentication=no <ユーザー>@<VPSのIP>
ssh -i <秘密鍵> <ユーザー>@<VPSのIP>
systemdを動かしたコンテナの中から127.0.0.1へこの2つを打つと(別のマシンからの接続は試していない)、00-local.confを置く前は1つ目でもパスワードで入れ、置いてsystemctl restart sshした後は1つ目がPermission denied (publickey).で断られ、2つ目の鍵では入れた。2つ目で入れなかったら、残しておいたセッションで00-local.confを消し、もう一度systemctl restart sshを打つ。検証では、これでパスワードで入れる状態に戻った。
SSHの設定は、外から入れる経路の1つにすぎない。Dockerで公開したポートがファイアウォールの外に出ていないかはUbuntu VPSへDockerを入れる前の確認項目、自動更新でVPSが再起動する条件と時刻はunattended-upgradesの既定値で確かめられる。
参考資料(確認日: 2026年10月23日)
- OpenBSD manual: sshd_config(5)
- Ubuntu Server documentation: OpenSSH server
- cloud-init documentation: Module reference(Set Passwords の ssh_pwauth)
- Ubuntu 24.04のパッケージ openssh-server 1:9.6p1-3ubuntu13.20 の
/etc/ssh/sshd_config、cloud-init 26.1-0ubuntu1~24.04.1 のcloudinit/config/cc_set_passwords.py・cloudinit/ssh_util.py
- 別の端末から鍵でログインできることを確かめ、~/.ssh を700、authorized_keys を600にする
- ls /etc/ssh/sshd_config.d/ で、50-cloud-init.conf などの既存ファイルと中身を見る
- /etc/ssh/sshd_config.d/00-local.conf に PasswordAuthentication no と KbdInteractiveAuthentication no を書く
- sudo sshd -t で書き間違いが無いかを見て、sudo sshd -T で実際の値を確かめる
- 今のセッションを残したまま sudo systemctl restart ssh で反映する
- 別の端末から PubkeyAuthentication=no を付けて接続し、Permission denied (publickey). と出ること、鍵では入れることを確かめる