できない.dev

SSH で ~/.ssh/config に書いた設定が反映されない

ssh_config は各項目について最初に見つかった値を採用する。
汎用の Host * を先頭に置くと、後ろに書いた個別ホストの設定は勝てない。
並び順と Host パターンの一致を確認し、ssh -G で実効値を見る。

公開: 更新:

実行例あり(2026-09-12 に実環境で検証)

要約

~/.ssh/config の設定が効かない原因で最も多いのは、書く順番である。
ssh_config は各設定項目について「最初に指定された値を使う」と定められている。
後から書いた値で上書きされるわけではない。

Host *
  User ubuntu
 
Host myserver
  HostName 203.0.113.10
  User deploy      # ← 先に Host * の User が確定しているので採用されない

この設定で ssh myserver すると、接続先は正しいのにユーザーは ubuntu のままになる。
汎用ブロックを先頭に置いた時点で、後続の個別指定は勝てない。

実行例

Host * を先頭に置いた状態で ssh -G myserver の実効値を見ると、HostName は個別ブロックの 203.0.113.10 が採用されているのに User だけ ubuntu のままになる。
個別ブロックを先に、Host * を末尾へ並べ替えると User は deploy に変わり、末尾の Host * に書いた ServerAliveInterval も併せて効いている。

$ cat /root/.ssh/config
Host *
  User ubuntu
 
Host myserver
  HostName 203.0.113.10
  User deploy
$ ssh -G myserver | grep -E "^(hostname|user) "
Pseudo-terminal will not be allocated because stdin is not a terminal.
user ubuntu
hostname 203.0.113.10
$ cat /root/.ssh/config
Host myserver
  HostName 203.0.113.10
  User deploy
 
Host *
  ServerAliveInterval 60
$ ssh -G myserver | grep -E "^(hostname|user|serveraliveinterval) "
Pseudo-terminal will not be allocated because stdin is not a terminal.
user deploy
hostname 203.0.113.10
serveraliveinterval 60

— 2026-09-12 時点の出力

検証環境

検証日
実行環境
alpine:3Alpine Linux v3.24

この記事の「実行例」は、上記の環境で実際にコマンドを実行して得られた出力をそのまま掲載しています。 再現手順はリポジトリの検証スクリプトとして管理し、定期的に再実行して出力を更新しています。

よくある原因

  1. Host * が先頭にある: ssh_config(5)(新しいタブで開く) のとおり「特記が無い限り、各設定項目は最初に指定された値が使われる」。
    汎用ブロックは最後に置くのが原則である。
  2. Host パターンが一致していない: Host myserver と書いて ssh myserver.example.com で接続すると一致しない。
    パターンはコマンドラインに与えた文字列に対して照合される。
  3. ssh-agent の鍵が先に出る: agent に複数の鍵が登録されていると、IdentityFile で指定した鍵より先にそちらが提示され、サーバー側で試行回数超過になることがある。
  4. config の権限が緩い: 他ユーザーから書き込める設定ファイルは読み込まれない。

解決策

1. 個別を先、汎用を後に置く

Host myserver
  HostName 203.0.113.10
  User deploy
  IdentityFile ~/.ssh/id_ed25519_deploy
  IdentitiesOnly yes
 
Host *
  ServerAliveInterval 60

この順序なら User は deploy に確定し、ServerAliveInterval は全ホスト共通の既定として効く。

2. 実効値を確認する

ssh -G myserver

ssh -G は接続せずに、そのホストへ適用される設定を解決して出力する。user deploy や identityfile の行を見れば、意図した値が採用されているかが一目で分かる。
想定と違えば、その項目を先に決めているブロックが上にある。

3. 鍵を固定する

IdentitiesOnly yes

IdentitiesOnly は「設定または既定のファイルで指定した鍵だけを使う」ことを ssh に指示する。
agent がより多くの鍵を提示していても無視されるため、鍵が多い環境で「別の鍵で認証されてしまう」問題が止まる。

4. 権限と読み込み順を見る

chmod 600 ~/.ssh/config
ssh -v myserver 2>&1 | grep -i 'reading configuration'

どの設定ファイルの何行目が適用されたかが出る。/etc/ssh/ssh_config 側で先に決まっている項目があれば、ユーザー設定では変えられないことも確認できる。

この記事は役立ちましたか?