VPSのSSHでパスワードを止める|sshd_configの効く値を確かめる
Linux のVPSを借りた直後は、root ユーザーにパスワードでSSHログインできる状態になっていることがあります。XServer VPSのマニュアルでも、申し込み時にSSH Keyを設定しなかった場合は、root とパスワードでログインする手順が案内されています。インターネットに公開されたサーバーでは、パスワードを狙った総当たりのログインを受けやすいため、鍵でのログインに切り替え、パスワードでのログインを止めるのが基本の対策です。ただし、設定ファイルに「no」と書いたのに効いていない、という落とし穴があります。この記事では、OpenSSHのマニュアルの決まりを整理し、実際に効く値を求めるPythonで確かめます。
(確認:OpenBSD manual pages「sshd_config(5)」「sshd(8)」、XServer VPS マニュアル「SSH Key」(パスワード認証の無効化の手順を含む)「SSH接続方法」「コンソール接続」。確認日:2026年10月30日(「コンソール接続」は11月2日)。筆者はXServer VPSで設定を変えて確かめてはいません。Linuxの配布版によって、既定値や設定ファイルの構成が違う場合があります)
XServer VPSのマニュアルに書かれていること
- SSHの認証には「パスワード認証」と「鍵認証」がある。鍵認証は、第三者による不正なSSH接続を防ぎ、セキュリティを上げる方法
- 申し込み時・OSの再インストール時に「SSH Key」を設定できる(この時に登録する鍵は root ユーザー用)。使っているサーバーにも、あとから鍵を設定して、ログインを鍵認証だけに制限できる
- SSH Keyを設定していない場合の接続は、ユーザー名 root と、サーバー作成時に設定した root パスワードを使う
- SSHで接続する前に、パケットフィルターをONにして、SSHのフィルタールールを追加する
- 秘密鍵をなくすと、そのサーバーにログインできなくなる
OpenSSHのマニュアル(sshd_config)の決まり
| 項目 | 意味 | 既定値 |
|---|---|---|
| PasswordAuthentication | パスワード認証を許すか | yes |
| KbdInteractiveAuthentication | キーボード対話認証を許すか | yes |
| PubkeyAuthentication | 公開鍵認証を許すか | yes |
| PermitRootLogin | root のログインを許すか(yes/prohibit-password/forced-commands-only/no)。prohibit-password は root のパスワード認証とキーボード対話認証を止める | prohibit-password |
そして重要なのが、「同じ項目は、特に断りがない限り、最初に得た値が使われる」という決まりです。Include は書かれた位置で別のファイルを読み込むため、ファイルの先頭に Include があり、そこで読むファイルに「PasswordAuthentication yes」があると、本体の後ろに「no」と書いても効きません。設定ファイルから求めた値は、sshd -T(設定を確かめて、実際に効く設定を表示する)で確かめられます。ただし、これは「ファイルを読んだ結果」で、動いている sshd に効くのは、sshd を再起動した後です。
XServer VPSのマニュアルの「SSH Keyを設定していない場合は root とパスワードで接続」という案内から、作成直後のサーバーでは、root のパスワードでのログインが許されていると考えられます(上の表の既定値の prohibit-password とは違う設定になっているという、筆者の推定)。
コード:設定ファイルから効く値を求める
sshd_config と、Include で読むファイルの中身から、4つの項目の値を「最初に得た値」の決まりで求めます。Match ブロックとワイルドカードの Include は扱わない簡略版です。
# sshd_config(と Include で読み込むファイル)から、ログインに関わる4項目の「実際に効く値」を求める(読み取りのみ)
# OpenSSH の sshd_config(5):同じ項目は、特に断りがない限り「最初に得た値」が使われる。Include は書かれた位置で読み込まれる
# 既定値(同マニュアル):PasswordAuthentication yes/PermitRootLogin prohibit-password/PubkeyAuthentication yes/KbdInteractiveAuthentication yes
# 簡略化:Match ブロックとワイルドカードの Include は扱わない(Include はファイル名を1つずつ渡す前提)。本番では sshd -T で確かめる
import re
DEFAULT = {'passwordauthentication': 'yes', 'permitrootlogin': 'prohibit-password',
'pubkeyauthentication': 'yes', 'kbdinteractiveauthentication': 'yes'}
SAFE = {'passwordauthentication': {'no'}, 'permitrootlogin': {'no', 'prohibit-password'},
'pubkeyauthentication': {'yes'}, 'kbdinteractiveauthentication': {'no'}}
def effective(files, main):
# files: {ファイル名: 内容}。main から読み始め、Include を書かれた位置で展開する
got = {}
def read(name):
for line in files[name].splitlines():
line = line.split('#', 1)[0].strip()
if not line:
continue
parts = re.split(r'[\s=]+', line, maxsplit=1) # 空白・タブ・= のどれで区切ってもよい
key, val = parts[0].lower(), (parts[1].strip() if len(parts) > 1 else '')
if key == 'include':
for inc in val.split():
if inc in files:
read(inc)
elif key in DEFAULT and key not in got:
got[key] = (val.lower(), name) # 最初に得た値だけを残す
read(main)
return {k: got.get(k, (DEFAULT[k], '既定値')) for k in DEFAULT}
def report(title, files, main='sshd_config'):
print(f'■ {title}')
for k, (v, src) in effective(files, main).items():
print(f' {k:<30}{v:<20}{"OK" if v in SAFE[k] else "要確認":<6}({src})')
print()
report('例1:何も書き換えていない(すべて既定値)', {'sshd_config': '#PasswordAuthentication yes\n#PermitRootLogin prohibit-password\n'})
report('例2:本体の末尾で鍵だけにした', {'sshd_config': 'PasswordAuthentication no\nKbdInteractiveAuthentication no\nPermitRootLogin prohibit-password\n'})
report('例3:先頭の Include で読む別ファイルが yes を書いている', {
'sshd_config': 'Include sshd_config.d/50-cloud-init.conf\nPasswordAuthentication no\nKbdInteractiveAuthentication no\n',
'sshd_config.d/50-cloud-init.conf': 'PasswordAuthentication yes\n'})
計算の結果(Python 3)
■ 例1:何も書き換えていない(すべて既定値)
passwordauthentication yes 要確認 (既定値)
permitrootlogin prohibit-password OK (既定値)
pubkeyauthentication yes OK (既定値)
kbdinteractiveauthentication yes 要確認 (既定値)
■ 例2:本体の末尾で鍵だけにした
passwordauthentication no OK (sshd_config)
permitrootlogin prohibit-password OK (sshd_config)
pubkeyauthentication yes OK (既定値)
kbdinteractiveauthentication no OK (sshd_config)
■ 例3:先頭の Include で読む別ファイルが yes を書いている
passwordauthentication yes 要確認 (sshd_config.d/50-cloud-init.conf)
permitrootlogin prohibit-password OK (既定値)
pubkeyauthentication yes OK (既定値)
kbdinteractiveauthentication no OK (sshd_config)
- 例1:何も書いていなければ既定値で、パスワード認証とキーボード対話認証は「yes」のまま
- 例2:本体に「no」と書けば、パスワードでのログインは止まる
- 例3:先頭の Include で読む別ファイルに「yes」があると、本体に「no」と書いても「yes」が効く。このファイル名(50-cloud-init.conf)は例で、どのファイルがあるかは、サーバーで
ls /etc/ssh/sshd_config.d/などで確かめる
切り替える順番(筆者の考え)
- 鍵でログインできることを先に確かめる:鍵の作り方はVPSにSSH鍵でログインする準備にあります
- 入れなくなった時の道を先に確かめる:XServer VPSには、VPSパネルからの「コンソール接続」(VNCコンソール・シリアルコンソール)があり、SSHで入れない時も操作できる(マニュアル)。鍵をなくした時に備えて、秘密鍵のバックアップを安全な場所に取っておく
- 設定ファイルを書き換える:マニュアルの手順では
/etc/ssh/sshd_configを開き、PasswordAuthentication noとPermitRootLogin prohibit-passwordにする。sshd -Tで kbdinteractiveauthentication が yes と出る場合は、KbdInteractiveAuthentication noも加える(上のコードの例2) sshd -tで書き間違いを確かめ、sshd -Tでファイルから求めた値を見る:先頭の Include で読むファイルに yes が残っていないかも、ここで分かる- 今の接続は切らずに、sshd を再起動する:マニュアルでは、AlmaLinux・Rocky Linux・CentOS などは
systemctl restart sshd、Ubuntu などそれ以外はsystemctl restart ssh。再起動しないと、書き換えた設定は効かない - 別の窓で、効いたことを確かめる:新しい接続で、鍵で入れること、パスワードでは入れないこと(例:
ssh -o PubkeyAuthentication=no root@サーバーのIPが断られる)を確かめてから、元の接続を閉じる - パケットフィルターでSSHを開ける範囲を絞る:送信元のIPアドレスを指定できる(XServer VPSのマニュアル)。自宅のIPが変わる場合の考え方はVPSのRDPを固定IPだけに許可する方法にあります
この記事で確かめていないこと
- XServer VPSの各OSのイメージで、作成直後の sshd_config と Include のファイルの実際の中身
- Linuxの配布版ごとの既定値の違い(このマニュアルは OpenBSD のもの)
- Match ブロックを使った、ユーザーごとの設定の扱い
まとめ
- XServer VPSは、SSH Keyを設定しないと root とパスワードでログインする。鍵認証に切り替え、パスワードでのログインを止めるのが基本
- sshd_config は「最初に得た値」が効く。先頭の Include で読むファイルに yes があると、本体の no は効かない。
sshd -Tでファイルから求めた値を確かめる - 書き換えたら sshd を再起動し、別の窓で「鍵で入れる・パスワードでは断られる」を確かめる。コンソール接続と秘密鍵のバックアップを先に用意しておく
本記事はOpenSSHの公式マニュアルとXServer VPSのマニュアルにもとづく整理です。設定を変える前に、使っているOSの案内も確認してください。XServer VPSの使い道と料金はXServer VPS(Linux)の使い道と料金にまとめています。


