エラーの内容
SSH コマンドを実行したとき — リモートサーバーへの接続、Git リポジトリのクローン、またはコードのデプロイ — 次のようなエラーが表示されます:
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: UNPROTECTED PRIVATE KEY FILE! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions for 'id_rsa' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
Load key "/c/Users/YourName/.ssh/id_rsa": bad permissions
Permission denied (publickey).
SSH はキーを読み込みません。接続が切断されます。
OpenSSH は秘密鍵を読み込む前にファイルのパーミッションを確認します。別のアカウントが読み取れる場合、SSH はキーが危険にさらされていると判断し、処理を拒否します。Linux では chmod 600 ~/.ssh/id_rsa の1コマンドで解決できます。Windows は Unix のパーミッションビットではなく NTFS ACL を使用するため、修正方法が異なります。
Windows でこのエラーが発生する理由
秘密鍵を Windows にコピーする際に問題が発生することがほとんどです。ダウンロード、USB ドライブ、または別のマシンから持ってきた場合、ファイルは親フォルダのパーミッションを引き継ぐ傾向があります。つまり、Users グループ、SYSTEM、および Administrators がすべて読み取りアクセス権を持つ可能性があります。OpenSSH はそれを検出し、キーの読み込みを拒否します。
修正方法:PowerShell で icacls を使用する
icacls はこの問題に最適なツールです。PowerShell を開いて(管理者権限は不要)、次を実行します:
# キーが別の場所に保存されている場合はパスを調整してください
$key = "$env:USERPROFILE\.ssh\id_rsa"
# ステップ 1: 継承されたすべてのパーミッションを削除する
icacls $key /inheritance:r
# ステップ 2: 広範なグループのパーミッションを削除する
icacls $key /remove "NT AUTHORITY\SYSTEM"
icacls $key /remove "BUILTIN\Administrators"
icacls $key /remove "BUILTIN\Users"
# ステップ 3: 自分のユーザーにのみ読み取りアクセスを付与する
icacls $key /grant:r "${env:USERNAME}:R"
順番に実行してください。それぞれがパーミッションの層を削除し、最後のコマンドで自分のアクセス権(読み取り専用)を追加します。
ワンライナー版
1行で済ませたい場合は、すべてを連結して実行できます:
icacls "$env:USERPROFILE\.ssh\id_rsa" /inheritance:r /remove "NT AUTHORITY\SYSTEM" /remove "BUILTIN\Administrators" /remove "BUILTIN\Users" /grant:r "${env:USERNAME}:R"
代替修正方法:PowerShell ACL オブジェクトを使用する
icacls はほとんどのケースをカバーします。マシンのセットアップをスクリプト化する場合や、より細かい制御が必要な場合は、.NET の System.Security.AccessControl クラスを直接使用して低レベルで操作できます:
$key = "$env:USERPROFILE\.ssh\id_rsa"
# 現在の ACL を取得する
$acl = Get-Acl $key
# 継承を無効化し、継承されたエントリを削除する
$acl.SetAccessRuleProtection($true, $false)
# 既存のすべてのアクセスルールを削除する
$acl.Access | ForEach-Object { $acl.RemoveAccessRule($_) }
# ルールを追加:現在のユーザーに読み取りアクセスのみを付与する
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule(
$env:USERNAME, "Read", "Allow"
)
$acl.AddAccessRule($rule)
# 更新した ACL をファイルに適用する
Set-Acl -Path $key -AclObject $acl
Write-Host "$key のパーミッションを更新しました"
GUI(エクスプローラー)を使った修正方法
コマンドラインを使いたくない場合は、エクスプローラーでも対応できます:
- エクスプローラーで
id_rsaを右クリック → プロパティ - セキュリティ タブに移動 → 詳細設定 をクリック
- 継承の無効化 をクリック → 継承されたアクセス許可をすべて削除する を選択
- 追加 をクリック → プリンシパルの選択 → Windows ユーザー名を入力 → OK
- 読み取り のみをチェック → OK → 適用
完了後、パーミッション一覧にはあなたのユーザーアカウントのみが表示されるはずです。
修正の確認
SSH をテストする前に、ACL が正しい状態になっているか確認します:
icacls "$env:USERPROFILE\.ssh\id_rsa"
自分のユーザー名のみが表示されていることを確認します:
C:\Users\YourName\.ssh\id_rsa YourName:(R)
Successfully processed 1 files; Failed processing 0 files
次に接続をテストします:
ssh -T git@github.com
またはサーバーに直接接続します:
ssh -i ~/.ssh/id_rsa user@your-server.com
警告ブロックは表示されなくなります。それでも SSH が失敗する場合は、パーミッションではなく認証エラーになります — つまり、キーの読み込みは成功しています。
Git Bash / WSL ユーザー向けの修正方法
WSL または Git Bash 内でキーが WSL ファイルシステムにある場合は、chmod が正常に動作します:
# WSL または Git Bash 内で
chmod 600 ~/.ssh/id_rsa
chmod 700 ~/.ssh
WSL から Windows パスのキー(例:/mnt/c/Users/YourName/.ssh/id_rsa)にアクセスしている場合、chmod は NTFS ACL に影響しません。その場合は PowerShell ウィンドウから icacls を使用してください。
すべての鍵に一括適用する
.ssh フォルダに複数の秘密鍵がありますか?一度にすべて修正できます:
Get-ChildItem "$env:USERPROFILE\.ssh" -File | Where-Object { $_.Name -notmatch '\.pub$|config|known_hosts' } | ForEach-Object {
$path = $_.FullName
icacls $path /inheritance:r /remove "NT AUTHORITY\SYSTEM" /remove "BUILTIN\Administrators" /remove "BUILTIN\Users" /grant:r "${env:USERNAME}:R"
Write-Host "修正済み: $path"
}
ヒント
- キー作成時にパーミッションを設定する。 Windows で
ssh-keygenを実行すると、デフォルトで ACL が正しく設定されます。問題のほとんどはマシン間でキーをコピーする際に発生します。 - キーはユーザープロファイル内に保存する。 共有ディレクトリやシステムディレクトリは広範なパーミッションを引き継ぎ続けます。
C:\Users\YourName\.ssh\に保存することをお勧めします。 - クロスプラットフォームのパーミッション変換。 Windows と Linux を行き来する場合、
chmod 600が ACL でどのように対応するかを理解するには、ToolCraft の Unix パーミッション計算機を使うと視覚的にわかります — ブラウザ上で完全に動作し、データは送信されません。 - 公開鍵に厳格なパーミッションは不要。
id_rsa.pubは読み取り可能な状態のままでも問題ありません。ただし、この機会に.sshディレクトリ全体が自分のアカウントのみの所有であることを確認しておきましょう。

