あらすじ
RPA用にVirtualBoxでVirtualMachineを作成してWin10をインストールしました。
ゲストのWin10にホストのWin10から公開鍵認証のSSHでアクセスする手順です。
公式
認証関係に詳しい技術者ってやはり少ないのでしょうか?
ドキュメントやスクリプトの更新が停止しています。
※2022/2/022追記 : 2021/10/05に更新してくださったようです。
名前
item | name |
---|---|
ホストPC | hpc |
ホストPCでの利用ユーザー | hpcuser |
仮想PC | vpc |
仮想PCでの利用ユーザー | rpauser |
SSHのサーバーとなるのはゲストで、
SSHのクライアントとなるのはホストです。
ややこしいですね。
sshd:SSHサーバーソフトウェア
ssh:仕組みの名前でもあり、SSHクライアントソフトウェアの名前でもあり、コマンド名でもある
ssh-agent:秘密鍵を振まわすエージェントさん
概略
- 仮想PCにsshサーバーをインストール
- ホストPCにsshクライアントをインストール
- キーペアを好きな場所で作成
- 公開鍵を仮想PCに登録
- 仮想PCで設定ファイルを変更
- ホストPCで秘密鍵をagentに登録
- ホスト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
のアクセス権を消すということ
結果
無事にログインできました。
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