前回のブログ記事で、Windows環境でOpenSSHサーバーを有効化する手順を公開しました。
初期設定では、接続先に存在するローカルユーザーすべてでログインできる状態です。
SSH接続を許可するユーザーアカウントの制御、パスワード認証を禁止し鍵認証する方法について記載します。
SSH接続を許可するユーザーアカウントの制御
設定ファイルの変更
OpenSSHサーバの設定ファイルに設定値を追加することで実現します。
設定ファイルの規定値は、C:\ProgramData\ssh\sshd_config になります。
メモ帳で設定ファイルの編集を行います。
PowerShellプロンプトを管理者権限で開き、以下コマンドを実行します。
notepad C:\ProgramData\ssh\sshd_config
設定項目は4つあり、DenyUsers、AllowUsers、DenyGroups、AllowGroupsの順番で評価されます。
ローカルアカウントのssh_userは拒否し、ssh_connectを許可する場合は以下のように書きます。
DenyUsers ssh_user
AllowUsers ssh_connect
ただ、ssh_connectのローカルアカウントのみ許可する場合、AllowUsers設定のみでも大丈夫です。
AllowUsers設定に存在しないローカルアカウントは拒否されます。
設定ファイルを上書き保存し、サービスを再起動することで反映できます。
Restart-Service sshd
ssh_connectのローカルアカウントはパスワード認証が通りますが、ssh_userのローカルアカウントはパスワード認証が失敗するように動作が変わります。
ログ確認
アクセス拒否の履歴確認は、イベントビューアの「アプリケーションとサービスログ」-「OpenSSH」-「Operational」から確認できます。
以下のようなログが出力されます。
sshd: User ssh_user from 127.0.0.1 not allowed because not listed in AllowUsers
パスワード認証を禁止し鍵認証する方法
前提条件
今回は同一機器内でクライアントとサーバーが分かれるため、アカウントで区別させています。
クライアントがymiyakuboアカウント、サーバー側がssh_connectアカウントです。
どちらの機能の話か括弧で表現をします。
鍵の作成(クライアント作業)
SSHクライアント側で秘密鍵と公開鍵を作成します。
以下コマンドを実行し鍵を作成します。
ssh-keygen -t ed25519
鍵の保存場所は初期値で問題がないため、Enterキーを押します。
パスフレーズは任意の値を入力してください。(未入力は推奨されません)
ユーザープロファイル(例ではC:\Users\ymiyakubo)の「.ssh」フォルダー配下に秘密鍵(id_ed25519)と公開鍵(id_ed25519.pub)が作成されます。
鍵の登録(クライアント⇒サーバー作業)
クライアント側で作成した公開鍵をサーバー側の接続先アカウントに保存します。
今回は、同一サーバー内なので以下のようにしています。
type c:\Users\ymiyakubo\.ssh\id_ed25519.pub >> C:\Users\ssh_connect\.ssh\authorized_keys
sshdサーバーの設定ファイルの初期値は、「StrictModes yes」となっています。
初期値で作業を進めた場合、鍵認証が失敗します。authorized_keysファイルにadministartorsなどのアクセス権があるためです。
サーバー側のauthorized_keysファイルのアクセス権は、ローカルアカウントとシステムのみがフルコントロールの状態にする必要があります。
以下のように設定をしてください。(ローカルアカウントがssh_connectの場合)
icacls.exe "C:\Users\ssh_connect\.ssh\authorized_keys" /inheritance:r /grant "ssh_connect:F" /grant "SYSTEM:F"
なお、厳密なアクセス権の確認をさせたくない場合は、sshサーバー側の設定ファイルで「StrictModes no」の設定を入れることで解決します。
設定ファイルの変更(サーバー作業)
メモ帳で設定ファイルの編集を行います。
PowerShellプロンプトを管理者権限で開き、以下コマンドを実行します。
notepad C:\ProgramData\ssh\sshd_config
以下の設定をします。
PasswordAuthentication no
PubkeyAuthentication yes
PasswordAuthentication no によりパスワード認証を無効化します。
PubkeyAuthentication yes により鍵認証を有効化します。
厳密なアクセス確認が不要な場合は以下設定も追加してください。
StrictModes no
別の設定方法として、使用できる認証方法の選択をすることもできます。
公開鍵のみの場合は以下のようにします。
AuthenticationMethods publickey
ここで設定できる値は、publickeyとpasswordのみです。(併用可)
設定ファイルを上書き保存し、サービスを再起動することで反映できます。
Restart-Service sshd
接続確認(クライアント作業)
以下コマンドで接続確認してください。
ssh ssh_connect@127.0.0.1
秘密鍵のパスワードを設定した場合、認証成功後にアクセスができます。
成功すると以下のような画面に遷移します。
補足:ssh-agentを利用するパターン(クライアント作業)
ssh-agentを使用したssh接続をする方法を紹介します。秘密鍵をエージェントに登録しておき認証をする方法です。
PowerShellプロンプトを管理者権限で開き、ssh-agentを起動させます。
以下コマンドでサービスの起動状態を確認してください。
Get-Service ssh-agent
StatusがStoppedの場合は停止状態のため起動する必要があります。ただし、スタートタイプがDisabledの場合、エラーになるため以下で確認します。
(Get-Service ssh-agent).StartType
出力結果がDisabledの場合は、ManualかAutomaticに変更します。Manualの場合は以下のコマンドです。
Set-Service ssh-agent -StartupType Manual
次に以下コマンドでサービスの起動とステータス確認をします。
Start-Service ssh-agent; Get-Service ssh-agent
起動後はStatusがRunningに変わります。
以下コマンドで秘密鍵を登録します。
ssh-add C:\Users\ymiyakubo\.ssh\id_ed25519
設定したパスフレーズを入力し認証が通れば、Identity addedの出力がされます。
登録した鍵は、ssh-add -l コマンドで確認できます。鍵が登録された状態で以下コマンドを入力すると、パスフレーズを入力することなく接続ができるようになります。
ssh ssh_connect@127.0.0.1
鍵情報を削除したい場合は、ssh-add -d コマンドを実行してください。
トラブルシュート対応
設定ファイルが修復不能な状態になった
既定の設定ファイル(C:\ProgramData\ssh\sshd_config)を削除し、sshdのサービスを再起動することで再作成されます。
再作成された設定ファイルを編集してください。
ssh-agentが起動できない
サービス起動時に以下エラーが発生する場合、スタートアップの種類が無効(Disabled)になっています。
Start-Service : 次のエラーのため、サービス 'OpenSSH Authentication Agent (ssh-agent)' を開始できません: コンピューター '.' でサービス 'ssh-agent' を開始でき
ません。
発生場所 行:1 文字:1
+ Start-Service ssh-agent
+ ~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OpenError: (System.ServiceProcess.ServiceController:ServiceController) [Start-Service], ServiceCommandException
+ FullyQualifiedErrorId : CouldNotStartService,Microsoft.PowerShell.Commands.StartServiceCommand
以下コマンドでスタートアップの種類を手動(Manual)か自動(Automatic)に変更します。
Manualの場合は以下になります。
Set-Service ssh-agent -StartupType Manual
秘密鍵と公開鍵のペアが正しいのにSSH接続できない
sshdサーバーの設定ファイルの初期値は、「StrictModes yes」となっています。「StrictModes no」に変更し、sshdサービスを再起動後、接続できるか確認してください。
もし、接続出来た場合はauthorized_keysファイルのアクセス権問題です。以下のどちらかを検討してください。
- 「StrictModes no」設定のまま運用する
- サーバー側のauthorized_keysファイルのアクセス権を修正する
おわりに
WindowsでのSSHサーバーの構築で躓く人が多いので記事にしました。
ログを見ても解決策が分からないパターンがあるかと思います。
例えば、鍵認証で失敗している理由についてです。ssh接続時のエラーでは、Permission denied (publickey).などの表示のみです。
この内容だけでは、サーバー側のauthorized_keysファイルのアクセス権に問題があると気づけないでしょう。
知見がある人ならsshdの設定ファイルにあるStrictModes関連だとピンと来ますが…
SSHサーバーに限らず、エラー内容で判断がつかない場合は、設定値で該当しそうな項目がないか探すのが良いと個人的には思っています。