15
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Windows10同士のSSH接続で公開鍵認証方式を使う

Last updated at Posted at 2020-08-01

あらすじ

RPA用にVirtualBoxでVirtualMachineを作成してWin10をインストールしました。
ゲストのWin10にホストのWin10から公開鍵認証のSSHでアクセスする手順です。

公式

OpenSSH キーの管理

認証関係に詳しい技術者ってやはり少ないのでしょうか?
ドキュメントやスクリプトの更新が停止しています。

※2022/2/022追記 : 2021/10/05に更新してくださったようです。

名前

item name
ホストPC hpc
ホストPCでの利用ユーザー hpcuser
仮想PC vpc
仮想PCでの利用ユーザー rpauser

SSHのサーバーとなるのはゲストで、
SSHのクライアントとなるのはホストです。
ややこしいですね。

sshd:SSHサーバーソフトウェア
ssh:仕組みの名前でもあり、SSHクライアントソフトウェアの名前でもあり、コマンド名でもある
ssh-agent:秘密鍵を振まわすエージェントさん

概略

  1. 仮想PCにsshサーバーをインストール
  2. ホストPCにsshクライアントをインストール
  3. キーペアを好きな場所で作成
  4. 公開鍵を仮想PCに登録
  5. 仮想PCで設定ファイルを変更
  6. ホストPCで秘密鍵をagentに登録
  7. ホストPCから仮想PCへSSH接続を開始

※キーペアの作成時とSSH接続開始時以外は、基本的に管理権限が必要な作業です。

初期設定

まずはWindows Server 2019 および Windows 10 用 OpenSSH のインストールを参考にパスワード認証によるSSHを設定します。

下記のスクリプトは、Windows 10にオンデマンド機能のOpenSSHサーバをインストールする方法などを見ながら手動でおこなうこともできます。

ひとまず管理者権限とpwshのバージョンを確認しておきます

function Test-Admin {
    $wid = [System.Security.Principal.WindowsIdentity]::GetCurrent()
    $prp = New-Object System.Security.Principal.WindowsPrincipal($wid)
    $adm = [System.Security.Principal.WindowsBuiltInRole]::Administrator
    $prp.IsInRole($adm)
}


if ([int]$psversiontable.psversion.major -lt 6) {
    Write-Host "PowerShell version need 6 or later" -BackgroundColor Red -ForegroundColor White
}
else {
    Write-Host "PowerShell version is Fit" -BackgroundColor Green -ForegroundColor White
}


if ((Test-Admin) -eq $false) {
    Write-Host 'You need Administrator privileges to run this.' -BackgroundColor Red -ForegroundColor White

    # Abort the script
    return
}

Microsoftのサーバーから追加機能の一覧を取得

[Object[]]$inputdata=$null
$inputdata=get-WindowsCapability -Online | Where-Object -Property Name -Match "^OpenSSH.*"
[Microsoft.Dism.Commands.BasicCapabilityObject]$server=$null
$server=$inputdata| Where-Object -Property Name -Match ".*Server.*"
[Microsoft.Dism.Commands.BasicCapabilityObject]$client=$null
$client=$inputdata| Where-Object -Property Name -Match ".*Client.*"

インストールされてなければインストールします。
下記はサーバー・クライアントを両方インストールしているので、
片方不要であればコメントアウトします。

if ($server.State -ne 'Installed') {
    # Install the OpenSSH Client

    Add-WindowsCapability -Online -Name $server.Name
}
if ($client.State -ne 'Installed') {
    # Install the OpenSSH Server

    Add-WindowsCapability -Online -Name $client.Name
}

インストール時に作成されたサービスsshdを起動します。

Start-Service sshd
# OPTIONAL but recommended:

Set-Service -Name sshd -StartupType 'Automatic'

インストール時に作成されたファイアウォール例外を有効化します。

# Confirm the Firewall rule is configured. It should be created automatically by setup.

Get-NetFirewallRule -Name *ssh*
# There should be a firewall rule named "OpenSSH-Server-In-TCP", which should be enabled

# There should be a firewall rule named "OpenSSH-Server-In-TCP", which should be enabled

$inputdata=Get-NetFirewallRule |Where-Object -Property name -Match ^sshd$
if($null -eq $inputdata){
    New-NetFirewallRule -Name sshd -DisplayName 'OpenSSH Server (sshd)' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22
}

キーペアの作成

ssh-keygenを実行します。
ただただ、Enterキーを連打していきます。
「ここは簡単ですね。」
そう言いたいところですが、わたしたちのSSH Keysの作り方は間違っているかもしれません。
Enterの連撃は技術検証の時だけに留めたほうが良さそうです。

PS C:\Users\rpauser> ssh-keygen
Generating public/private rpauserkey pair.
Enter file in which to save the key (C:\Users\rpauser/.ssh/id_rsa):
Created directory 'C:\Users\rpauser/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in C:\Users\rpauser/.ssh/id_rsa.
Your public key has been saved in C:\Users\rpauser/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:1Cwo0N/gdgfdsgjgjghfghdfhg/gfdsgsdfgsdg rpauser@vpc
The key's randomart image is:
+---[RSA 2048]----+
|  ..             |
|   ..  . o       |
|    ...oo o      |
|     ...o.       |
|   .   .S.     + |
|  . ..  o .   o.=|
|   o+o .o+.. ..+=|
|  .+.oo+o....o=Eo|
|  . +++   .o++o=*|
+----[SHA256]-----+

念のため、lsでファイルが生成されていることを確認しました。

PS C:\Users\rpauser> cd .ssh
PS C:\Users\rpauser\.ssh> ls
    Directory: C:\Users\rpauser\.ssh
Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a---          2020/07/28    16:13           1679 id_rsa
-a---          2020/07/28    16:13            393 id_rsa.pub

Your identification has been saved in C:\Users\rpauser/.ssh/id_rsa.
Your public key has been saved in C:\Users\rpauser/.ssh/id_rsa.pub.

と言っているので、id_rsaが秘密で、id_rsa.pubが公開ですね

秘密鍵をホストPCに登録する

ssh-agentが何をしてくれるのか肌感覚で理解するには、
ssh-agentを利用して、安全にSSH認証を行うを読むと分かりやすいです。

それではssh-addを使って、ssh-agentに秘密鍵を登録します。
この作業はホストPCで行います。
ssh-agentさんに用は無いので、接続時に毎回秘密鍵のディレクトリを指定します」という場合には、
ホストPCの適当な場所にid_rsaを置いておくだけで大丈夫です。

PS C:\Users\hpcuser\.ssh> ssh-add id_rsa
Error connecting to agent: No such file or directory

「ファイルが無い」っていうので、確認してみます。

PS C:\Users\hpcuser\.ssh> ls
    Directory: C:\Users\hpcuser\.ssh
Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a---          2020/07/28    16:13           1679 id_rsa
-a---          2020/07/28    16:13            393 id_rsa.pub

「秘密鍵があるのに、無いって言ってくる」「なんだ天邪鬼か?」と一瞬考えますが、
よく見ると「エージェントへの接続エラー」って言ってます。

そこで、ssh-agentを確認してみましょう。

PS C:\Users\hpcuser> Get-Service ssh*

Status   Name               DisplayName
------   ----               -----------
Stopped  ssh-agent          OpenSSH Authentication Agent
Running  sshd               OpenSSH SSH Server

止まってますね。
起動しましょう。

PS C:\Users\hpcuser> Start-Service ssh-agent
Start-Service: Service 'OpenSSH Authentication Agent (ssh-agent)' cannot be started due to the following error: Cannot start service 'ssh-agent' on computer '.'.

よくわからないけれど、このディレクトリだと起動できないみたいなこと言ってます。
何でですかね?デフォルトだとStartできないらしいです。

良く分からないけれど、公式ドキュメントを読むと自動起動の設定をするよう促されます。
Setしておけば、Startできるらしいです。デフォルトがDisableなのかもしれませんね。
(インストールし直さないと確認できないので、確認しません。怠慢です。)

次回ホストを再起動したときに自動起動してくれるようにします。

PS C:\Users\hpcuser> Set-Service -name "ssh-agent" -startuptype "automatic"

上手くいけば結果は帰ってきません。

それではssh-agentを起動します。面倒なのでワイルドカードで指定してます。

PS C:\Users\hpcuser> Start-Service ssh*

実行結果は帰ってこないので、別コマンドで確認します。

PS C:\Users\hpcuser> Get-Service ssh*
Status   Name               DisplayName
------   ----               -----------
Running  ssh-agent          OpenSSH Authentication Agent
Running  sshd               OpenSSH SSH Server

無事に起動していることがわかりました。
それではもともとやりたかったssh-addをやりましょう。

PS C:\Users\hpcuser\.ssh> ssh-add .\id_rsa
Identity added: .\id_rsa (.\id_rsa)

OKです。上手く識別情報として追加できたみたいですね。
やはりssh-agentが起動している状態だとaddに成功するみたいです。

公開鍵を仮想PCに登録する

それで、ココから先が難題です。
Windows Server 2019 EC2インスタンスでSSHサーバーを有効にするを参考にして解決した内容です。

この作業は仮想PC内で行います。
公式ドキュメントにもある通り、管理者アカウントは%programdata%\ssh\administrators_authorized_keysに公開鍵を登録する必要があります。

メモ帳で書き換えてもいいですが、スクリプトを使います。

Get-Content C:\id_rsa | Out-File $env:programdata\ssh\administrators_authorized_keys

書き換え完了後に%programdata%\ssh\administrators_authorized_keysのアクセス権設定を書き換える必要があるらしいです。
そのために公式ドキュメントで紹介されているモジュールをインストールすると簡単らしいです。

PS C:\Users\rpauser\.ssh> Install-Module -Force OpenSSHUtils -Scope AllUsers
Install-Package: C:\program files\powershell\7\Modules\PowerShellGet\PSModule.psm1:9709
Line |
9709 |  … talledPackages = PackageManagement\Install-Package @PSBoundParameters
     |                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     | No match was found for the specified search criteria and module name 'OpenSSHUtils'. Try
     | Get-PSRepository to see all available registered module repositories.

ですが、エラーでインストールできません。
なんかダメなようです。ソースに問題ありみたいです。

いろいろ調べるとNuGet Packageファイルを手動ダウンロードして解凍、配置すれば使えるとのこと。
しかし、ナンセンスなのでやりたくありません。

ということで、スクリプトで消せるみたいなのでやってみます。

$administratorsKeyPath = $env:programdata\ssh\administrators_authorized_keys
# ファイルのアクセス制御設定を取得

$acl = Get-Acl $administratorsKeyPath
# アクセス権の継承を解除

$acl.SetAccessRuleProtection($true,$true)
# アクセスルールを除去

$removeRule = $acl.Access | Where-Object { $_.IdentityReference -eq 'NT AUTHORITY\Authenticated Users' }
$acl.RemoveAccessRule($removeRule)

# アクセス権を更新

$acl | Set-Acl -Path $administratorsKeyPath

やっていることは、Authenticated Usersのアクセス権を消すということ

image.png

結果

無事にログインできました。

PS C:\Users\hpcuser> ssh -i "C:\id_rsa" rpauser@vpc

Microsoft Windows [Version 10.0.xxxxx.xxxxx]
(c) 2030 Microsoft Corporation. All rights reserved.

rpauser@vpc C:\Users\rpauser>

まとめ

暗号ややこしい、きらい。
でも安全大事、がんばる。

参考

※2023/07/17追記
sheeplaさんのスクリプトが素晴らしいので、こちらを参考にしてください。
https://gist.github.com/sheepla/77427fdbdd2716c383524d771cbb95c5

15
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?