Windows 10 OpenSSH ServerでSSH接続できない(timeout/connection refused)原因と解決策

Windows 10 に OpenSSH Server を入れたのに、別PCやLinuxから SSH 接続すると timeout/connection refused で失敗する——そんなときは「sshd が待ち受けていない」か「ファイアウォール・経路で 22 番(または変更後ポート)が遮断」のどちらかがほとんどです。ここでは最短で原因を切り分け、確実に直す手順を具体例つきでまとめます。

目次

まず理解しておきたい:timeout と connection refused の違い

同じ「SSH できない」でも、エラー文が違うと原因の方向性が変わります。闇雲に設定を触る前に、まずはメッセージの意味を押さえるのが最短ルートです。

症状意味(ざっくり)よくある原因最初に見る場所
connection timed out相手から応答が返ってこない(黙って捨てられている)Windows Defender ファイアウォールで遮断、ルータ/社内NWで遮断、接続先IPの誤り、ポートフォワード未設定ファイアウォール受信ルール、ネットワーク経路、接続先IP
connection refused相手には届いているが「そのポートは受けていない」と拒否されたsshd が未起動、別ポートで待受、ListenAddress が localhost のみ、ポート競合Windows 側の LISTEN 状態(netstat / Get-NetTCPConnection)
鍵交換までは進むが認証で失敗通信自体はできている(待受・FW・経路は基本OK)PIN を入力している、ユーザー制限(AllowUsers/AllowGroups)、PasswordAuthentication 無効、ユーザー名の指定違いOpenSSH のイベントログ、sshd_config、クライアント側 ssh -v

この記事の流れは「Windows 側で待ち受けが成立しているか」→「Windows の受信許可」→「ネットワーク経路」→「認証・設定」の順です。この順番を守るだけで遠回りが激減します。

大前提:OpenSSH Client と OpenSSH Server は別物

Windows 10 では OpenSSH が「クライアント」と「サーバー」に分かれています。Windows → Linux に SSH できるのに、Linux → Windows ができない場合は、クライアントだけ入っていてサーバーが入っていない(または止まっている)ケースが非常に多いです。

インストール状況の確認(PowerShell)

管理者として PowerShell を開き、次で状態を確認します。

Get-WindowsCapability -Online | Where-Object Name -like 'OpenSSH*' | Select-Object Name, State

State が Installed になっていれば導入済みです。サーバー側に必要なのは通常 OpenSSH.Server のほうです。

OpenSSH Server のインストール(未導入の場合)

未インストールなら、次のコマンドで追加できます(Windows のエディションや更新状況により表示名が多少違う場合があります)。

Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0

GUI なら「設定」→「アプリ」→「オプション機能」→「機能の追加」から OpenSSH Server を追加します。

sshd サービスが起動しているか確認する

OpenSSH Server を入れても、サービスが止まっていれば当然つながりません。特に「一度はつながったが、再起動後にダメになった」場合は自動起動が無効になっていることがあります。

サービス状態の確認・起動・自動起動化

Get-Service sshd

# 起動(停止している場合)

Start-Service sshd

# 自動起動にする

Set-Service -Name sshd -StartupType Automatic

ssh-agent は鍵を扱うときに便利ですが、まずは sshd が動くことが最優先です。サービスが起動できない場合は、設定ファイルの書式ミスやホストキー不足が原因のこともあります(ログ確認が有効です)。

Windows が SSH ポートで待ち受けているか(LISTEN の確認)

「接続拒否」「接続はできる気配があるが入れない」などの切り分けで最も重要なのが、Windows 側でポートが LISTEN しているかです。ここが OK なら次はファイアウォールや経路、ここが NG なら sshd/設定/ポートの問題に集中できます。

netstat で確認(定番)

netstat -aon | findstr -i listen | findstr :22

0.0.0.0:22 や [::]:22 が LISTENING なら待受OKです。何も出ない場合は次を疑います。

  • sshd が起動していない(または起動失敗)
  • sshd_config で Port を変更している(例:2222)
  • ListenAddress が 127.0.0.1(localhost)に固定されている
  • 別プロセスが 22 番を使用している(ポート競合)

PowerShell で LISTEN を確認(見やすい)

Get-NetTCPConnection -LocalPort 22 -State Listen | Select-Object LocalAddress, LocalPort, OwningProcess

OwningProcess(PID)が分かったら、どのプロセスが掴んでいるかも確認できます。

tasklist /fi "PID eq 1234"

もし LISTEN が 127.0.0.1:22 だけの場合、外部からは入れません。C:\ProgramData\ssh\sshd_config の ListenAddress が localhost に寄っていないかを確認してください。

接続先 IP を取り違えていないか(意外と多い)

VPN、仮想NIC、Wi-Fi/有線の併用などで Windows の IP が複数あると、接続先を間違えがちです。Windows 側で次を確認し、同一セグメントの正しい IP に向けて接続しているかを見直してください。

ipconfig

「同じ PC のはずなのに ping が通る相手と SSH を試している相手が違う」など、初歩的な勘違いが混ざっていると切り分けが一気に長引きます。

sshd_config の確認ポイント(ポート変更・ユーザー制限・認証)

設定ファイルは通常 C:\ProgramData\ssh\sshd_config にあります(ProgramData は隠しフォルダなのでエクスプローラーで表示設定に注意)。編集後は sshd の再起動が必要です。

# 変更後は反映のため再起動
Restart-Service sshd
項目見るべき理由よくある落とし穴
Port接続先ポートが違うと永遠に接続できないPort を変えたのにファイアウォールが 22 のまま、クライアント側が 22 に接続している
ListenAddress待受アドレスを絞ると外部から入れなくなる127.0.0.1 のみになっている
AllowUsers / AllowGroupsログイン許可対象が絞られていると認証前に拒否される社内手順で追加された設定が残っている
PasswordAuthentication / PubkeyAuthenticationパスワード/鍵のどちらが有効かを決める鍵が未設定なのに PasswordAuthentication を no にしてしまう
LogLevel原因追跡のためログの詳細度を上げられるDEBUG にしても見に行く場所が分からず放置

ポートを変えた場合のクライアント側コマンド

Windows 側で Port 2222 のように変更したら、接続元もポート指定が必要です。

ssh -p 2222 user@<WindowsのIP>

この「サーバーは 2222 で待受、クライアントは 22 に接続」をやってしまうと、症状が環境によって timeout と refused のどちらにも見えて混乱しがちです。まずは サーバーの LISTEN と接続先ポートが一致しているか を確かめてください。

設定を書き換えたら sshd が起動しなくなったとき

設定ファイルの文法ミスがあると sshd が起動できず、結果として LISTEN が消えます。変更後は設定テストをしてから再起動すると安全です(環境によりパスが異なることがあります)。

# 設定ファイルの文法チェック(エラーが出たら内容を見直す)
sshd -t

さらに深掘りしたい場合は、ホストキーが存在するかも確認します。ホストキーが欠けていると起動失敗の原因になります。

# 例:ホストキーの存在確認
dir C:\ProgramData\ssh\ssh_host_*

Windows Defender ファイアウォールの受信許可(プロファイルが最大の落とし穴)

timeout の大半はここです。特に見落としがちなのが「受信ルールはあるのに効かない」パターンで、原因は多くの場合 適用プロファイル(Private/Public/Domain) の不一致です。自宅LANでも Windows 側が Public と判定していれば、Private のみ許可したルールは当たり前にブロックされます。

ネットワークプロファイルの確認

Get-NetConnectionProfile | Select-Object InterfaceAlias, NetworkCategory, IPv4Connectivity, IPv6Connectivity

NetworkCategory が Public になっている場合、LAN 内からのアクセスでも受信ルールが効かないことがあります。意図して Private にしたいなら、管理者 PowerShell で次のように変更します(InterfaceAlias は環境に合わせてください)。

Set-NetConnectionProfile -InterfaceAlias "Ethernet" -NetworkCategory Private

OpenSSH の受信ルールが有効か確認

OpenSSH Server の導入時に「OpenSSH-Server-In-TCP」という受信ルールが作られることがあります。ルールの有無と有効/無効、プロファイルを確認します。

Get-NetFirewallRule -DisplayName "*OpenSSH*" |
  Select-Object DisplayName, Enabled, Direction, Action, Profile

受信ルールを自分で作る(確実)

ルールが無い・壊れている・プロファイルが合わない場合は、作り直すのが早いです。LAN 内だけで使うなら Private のみ、外部公開するなら(推奨はしませんが)必要に応じて Public も含めます。

# 例:TCP 22 を許可(Private のみ)
New-NetFirewallRule -Name "OpenSSH-Server-In-TCP" `
  -DisplayName "OpenSSH Server (sshd)" `
  -Enabled True -Direction Inbound -Protocol TCP -Action Allow `
  -LocalPort 22 -Profile Private

ポートを 2222 に変えたなら -LocalPort 2222 に合わせます。ここがズレていると「ポートを変えたら connection refused / timeout が出る」の定番ループに入ります。

サードパーティ製セキュリティソフトにも注意

Windows Defender のルールが正しくても、別のセキュリティソフトのファイアウォール機能が遮断することがあります。一時的に停止して検証するか、製品側で TCP 22(または変更後ポート)の受信許可を追加してください。

到達性テストで「待受」「ファイアウォール」「経路」を切り分ける

「ping は通るのに SSH は通らない」は珍しくありません。ICMP(ping)と TCP(SSH)は別物で、片方だけ許可/遮断されるのが普通です。迷ったら、次の順でテストすると原因を外しません。

テスト実行場所コマンド例ここで分かること
ローカル疎通Windows 自身Test-NetConnection 127.0.0.1 -Port 22sshd が本当に待ち受けているか(OS内部の問題切り分け)
LAN 内疎通同一 LAN の別端末Test-NetConnection <WindowsのIP> -Port 22Windows の受信ルール/プロファイルで落ちていないか
Linux からの TCP 確認Linux/他OSnc -vz <WindowsのIP> 22TCP レベルで到達しているか(SSH以前の問題を切り分け)
SSH の詳細ログ接続元ssh -vvv user@<WindowsのIP>鍵交換・認証のどこで止まっているか

ポイントは Windows 自身の localhost テスト です。ここで失敗するならネットワーク以前に sshd/設定が原因です。ここで成功して、LAN 内で失敗するならファイアウォールやプロファイルが濃厚です。

ルータ・NAT・社内ネットワークが原因のケース

同じ「外部から接続できない」でも、状況によって対処が変わります。まず「外部」がどこなのかを整理しましょう。

接続元よくある構成追加で必要になりやすい設定代表的な落とし穴
同一 Wi-Fi / 同一 LAN家庭内・小規模オフィス基本は不要(Windows の FW 設定が中心)Windows が Public 扱いでブロック、IP を間違えている
別ネットワーク(テザリング/外出先)インターネット越しルータのポートフォワード、グローバルIP/DNS、必要ならポート変更ポートフォワード無し、二重ルータ、ISP が 22 を遮断
企業ネットワークFW/プロキシ/IDS ありネットワーク管理側の許可が必要ポリシーで遮断(勝手に穴を開けられない)

ポートフォワードと「二重ルータ」

インターネット越しに自宅の Windows 10 に入れない場合は、Windows の設定が正しくても ルータでポートを転送していない と必ず失敗します。さらに、ONU/モデムと自前ルータの二段構成だと「転送設定を片方にしか入れていない」ことで詰まります。構成が複雑なときは、まず LAN 内(同一 Wi-Fi)で接続できる状態を作ってから外部公開へ進むと、原因が混ざりません。

自宅内から「グローバルIP」に接続テストして失敗することがある

ルータによっては、LAN 内から自宅のグローバルIPへ接続する「ヘアピンNAT(NATループバック)」に対応していません。この場合、外出先からは成功するのに、自宅内からのテストだけ失敗します。外部テストはテザリング等の別回線で実施するか、LAN 内はローカルIPで接続してください。

22番が塞がれているときの現実的な回避策

ISP や回線種別によっては 22 番がブロックされることがあります。その場合は 2222 などの高番ポートへ変更し、ルータ側の転送も合わせるのが現実的です。ただし「ポート変更=安全」ではありません。外部公開するなら鍵認証・ユーザー制限・公開範囲の最小化(可能なら VPN)までセットで考えるのが堅実です。

認証で詰まる場合:通信はできているのにログインできない

SSH の接続そのものは成立している(timeout/connection refused ではない)のに、パスワードが通らない・ユーザーが弾かれる場合は、見る場所が変わります。

症状よくある原因対処の方向性
パスワードを求められるが通らないPIN を入力している、パスワードが違う、アカウントがロック/期限切れ正しいパスワードを用意し、イベントログで拒否理由を確認
Permission denied が出るAllowUsers/AllowGroups で拒否、PasswordAuthentication が無効sshd_config を見直し、意図した認証方式に合わせる
鍵を置いたのに鍵認証にならないauthorized_keys の場所違い、ファイル権限(ACL)が緩い鍵の配置と ACL を見直し、ssh -vvv でどの鍵を見ているか確認

Windows Hello の PIN は SSH のパスワードではない

SSH が求めるのは基本的に「Windows アカウントのパスワード」です。普段 PIN でサインインしていると、無意識に PIN を入力してしまい「何度やっても通らない」状態になります。まずは 本来のパスワード を用意してください(Microsoft アカウントやドメイン環境では管理ポリシーに従います)。

ユーザー名の指定ミスを避ける

ローカルアカウント/ドメインアカウントが混在している環境では、ユーザー名の指定で詰まることがあります。まず Windows 側で現在のユーザー名を確認すると確実です。

whoami

ドメイン環境では DOMAIN\username のような形式が出ることがあります。その場合、SSH でも同様の形式で指定すると通ることがあります。ローカルアカウントを明示したい場合は .\username を試すのも定番です。

ログイン許可ユーザーが絞られていないか

sshd_config に AllowUsers / AllowGroups があると、対象外ユーザーは認証前に拒否されます。複数人が触る PC や、以前設定したマシンを流用している場合は特に要注意です。

パスワード認証が無効になっていないか

鍵認証へ移行する際に PasswordAuthentication no にしたまま、クライアント側の鍵配置が終わっていないケースがあります。まずは鍵認証が確実に動くことを確認してからパスワードを無効化するのが安全です。

鍵認証の置き場所と権限(ACL)の基本

Windows の OpenSSH でも、一般的には %USERPROFILE%\.ssh\authorized_keys が鍵の配置先になります。鍵認証が通らないときは「ファイルの場所」と「権限(他ユーザーが読める状態になっていないか)」が論点になりやすいです。まずはイベントログと ssh -vvv で、どの鍵を探しているかを確認してください。

ログを見る:原因が「設定」「権限」「認証」なのか即判定できる

Windows の OpenSSH はイベントログに情報が出ます。接続できない原因が「そもそも sshd が起動していない」のか「ユーザーが拒否されている」のかは、ログを見たほうが早いです。

  • イベント ビューアー → アプリケーションとサービス ログ → OpenSSH → Operational

同時に、接続元では SSH の詳細ログを出すと状況が読みやすくなります。

ssh -vvv user@<WindowsのIP>

「鍵交換までは進む」「ユーザー名は通るがパスワードが違う」「許可されていないユーザー」など、どこで止まっているかが明確になります。

安全に運用するための推奨設定(外部公開するなら必須)

SSH は便利な反面、インターネットに開けると総当たりが飛んできます。家庭内 LAN のみならリスクは下がりますが、それでも最低限の対策はしておくのがおすすめです。

対策目的実務的なポイント
鍵認証を使う総当たり耐性を上げるまず鍵でログインできる状態を作ってからパスワードを無効化
パスワード認証を無効化攻撃面を減らすPasswordAuthentication no は鍵が動いてから
許可ユーザー/グループを絞る不要なアカウントを閉めるAllowUsers / AllowGroups を活用
公開範囲を Private に限定外部からの到達を物理的に減らすファイアウォールの Profile を Private のみにする
VPN 経由で入るSSH を直接公開しない自宅ルータの VPN 機能や WireGuard などを検討

コピペで確認できる:診断用チェックリスト(PowerShell)

最後に、よく使う確認項目をまとめて実行できるコマンド例を載せます。結果を見れば「今どこで詰まっているか」がかなりの精度で分かります(必要に応じて管理者として実行してください)。

# OpenSSH のインストール状況
Get-WindowsCapability -Online |
  Where-Object Name -like 'OpenSSH*' |
  Select-Object Name, State

# sshd の状態
Get-Service sshd | Select-Object Name, Status, StartType

# 22番(または変更後ポート)が LISTEN しているか
Get-NetTCPConnection -State Listen |
  Where-Object LocalPort -in 22,2222 |
  Select-Object LocalAddress, LocalPort, OwningProcess |
  Sort-Object LocalPort

# ネットワークプロファイル(Public/Private)
Get-NetConnectionProfile |
  Select-Object InterfaceAlias, NetworkCategory

# OpenSSH 関連のファイアウォールルール
Get-NetFirewallRule -DisplayName "*OpenSSH*" |
  Select-Object DisplayName, Enabled, Direction, Action, Profile

まとめ:迷わない切り分け順

Windows 10 の OpenSSH で外部から SSH 接続できないときは、次の順に確認すればほぼ詰まりません。

  • OpenSSH Server が入っているか(Client だけになっていないか)
  • sshd が起動しているか、起動失敗していないか
  • ポートが LISTEN しているか(0.0.0.0 / [::] で待受できているか)
  • Windows Defender ファイアウォールの受信許可とプロファイル(Public/Private)
  • 到達性テストで経路/ルータ/ISP を切り分ける
  • 認証で詰まるなら PIN ではなくパスワード、sshd_config とログを確認

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次