当前位置:网站首页 > 更多 > 玩电脑 > 正文

[玩转系统] 将 OpenSSH 服务器部署到 Windows 10

作者:精品下载站 日期:2024-12-14 08:00:45 浏览:15 分类:玩电脑

将 OpenSSH 服务器部署到 Windows 10


PowerShell 7 提供了许多令人信服的理由来采用它。其中最好的一项是支持 SSH 作为 PowerShell 远程协议。不幸的是,这不是以 Windows 为中心的 IT 专业人员通常会想到的话题。我知道这对我来说绝对是正确的,也是我一直在努力解决的缺陷。从好的方面来说,Windows 10 附带了已安装且可以使用的 OpenSSH 客户端。但是 OpenSSH 服务器呢?在 Windows 平台上,如果要在 PowerShell 中使用 SSH 远程处理,则需要启用并配置此元素。当然,我想使用 PowerShell 远程完成此操作。首先,我想向您展示如何在 Windows 10 上设置 OpenSSH Server 组件。

手动设置

在 Windows 10 中安装 OpenSSH Server 组件的 PowerShell 命令非常简单。首先,我需要能力。我正在以交互方式运行这些命令。

Get-WindowsCapability -online -name openssh.server* | Add-WindowsCapability -online

我使用带有通配符的 Get-WindowsCapability,以防版本号在某个时刻发生变化。我可以看到这有效。

[玩转系统] 将 OpenSSH 服务器部署到 Windows 10

这将设置未运行并配置为手动启动的 sshd 服务。我想将服务配置为启动并自动启动。

Set-Service-Namesshd-StartupTypeAutomatic
Start-Service-Namesshd

我了解到关于 ssh 的一件事,特别是如果您想将它与 PowerShell 远程处理一起使用,那就是验证 ssh 在 PowerShell 之外是否有效。

ssh localhost

系统可能会提示您接受密钥和密码。如果你的设置和我的一样,你最终会看到 CMD 提示符。但也许您在通过 ssh 连接时需要不同的 shell。请注意,我还没有谈论通过 ssh 进行 PowerShell 远程处理。您可以修改计算机上的注册表。

$regPath="HKLM:\SOFTWARE\OpenSSH\"
$regProperty="DefaultShell"
$regValue=(Get-Commandpowershell.exe).source
Set-ItemProperty-Path$regPath-Name$regProperty-Value$regValue

更改应该立即生效,并且不需要重新启动 sshd 服务。使用 ssh 连接到本地主机现在可以提供 Windows PowerShell 会话。组装一个简单的 PowerShell 脚本来交互运行这些命令并不需要太多时间。

远程安装

但我想远程执行此操作。我有一些 Windows 10 虚拟机,我想通过 ssh 连接到它们。我需要使用传统的 PowerShell 远程处理。是的,您可以使用 psexec.exe 等第三方工具或 Desired State Configuration 等工具,但我想坚持使用您可能已经拥有的工具和技能。

当我从事这项工作时,我有一个简单的 PowerShell 脚本,它运行我刚才向您展示的步骤。我认为我需要做的就是使用 Invoke-Command 运行脚本。没有。事实证明,Add-WindowsCapability 命令在远程会话中不起作用。这显然是按需安装功能的一个已知限制。但我不会让这阻止我。我最终的解决方法是创建一个临时计划任务,将 OpenSSH.Server 添加为系统。

$Time=New-ScheduledTaskTrigger-At23:59-Once
$User=New-ScheduledTaskPrincipalSystem
$action=New-ScheduledTaskAction-Execute"PowerShell.exe"-Argument'-noprofile-command"&{Get-WindowsCapability-online-nameopenssh.server*|Add-WindowsCapability-online}"'
$tmpTask=Register-ScheduledTask-taskpath\-TaskName"AddTask"-Trigger$Time-Principal$user-Action$Action
Start-ScheduledTask-TaskNameAddTask

#givethetaskachancetofinish
Start-Sleep-Seconds20

$tmpTask|Unregister-ScheduledTask-confirm:$false

触发时间无关紧要,因为我将手动启动任务,然后将其删除。只要我不在接近午夜的时间运行,就应该没问题。

我还希望我的脚本支持 -WhatIf 并提供详细输出,即使代码是远程运行的。这是我想出的脚本。

#requires-version5.1

<#
ThisisusedtosetupSSHDonaWindows10ClientthroughPowerShellremoting

Sampleusage
VerboseandWhatif
invoke-command-FilePath.\Setup-SSHServer.ps1-ComputerNamewin10-cred$artd-ArgumentList@("Continue",$True)

Verbose
invoke-command-FilePath.\Setup-SSHServer.ps1-ComputerNamewin10-cred$artd-ArgumentList@("Continue")
#>

[cmdletbinding(SupportsShouldProcess)]
param([string]$VerboseOption="SilentlyContinue",[bool]$WhatIfOption=$False)

$VerbosePreference=$VerboseOption
$WhatIfPreference=$WhatIfOption

Write-Verbose"StartingSSHDsetupprocess"
Try{
Write-Verbose"Testingforsshdservice"
$svc=Get-Service-Namesshd-ErrorActionStop
if($svc.status-eq'Running'){
Write-Verbose"sshdserviceappearstobeinstalledandrunning"
}
else{
Write-Warning"sshdservicefoundbutitisn'trunning"
}
#takenofurtheraction
Return"OpenSSHServerinstallationappearstobecomplete."
}
Catch{
Write-Verbose"sshdservicenotfound.Continuingwithinstallation"
}

Write-Verbose"TestingOpenSSH.ServerWindowscapability"
if(-Not$svc){
Try{
$cap=Get-WindowsCapability-NameOpenSSH.Server*-Online-ErrorActionStop
$cap|Out-String|Write-Verbose
}
Catch{
Throw$_
}
}

if($cap.State-eq'NotPresent'-And$cap.name-match"OpenSSH"){
#installcapability
Try{
Write-Verbose"Adding$($cap.name)"
if($pscmdlet.ShouldProcess($cap.Name)){
#installingwithaScheduledtaskasSystemtogetaroundthelimitation
#withAdd-WindowsCapabilityinaPowerShellremotingsession
$Time=New-ScheduledTaskTrigger-At23:59-Once
$User=New-ScheduledTaskPrincipalSystem
$action=New-ScheduledTaskAction-Execute"PowerShell.exe"-Argument'-noprofile-command"&{Get-WindowsCapability-online-nameopenssh.server*|Add-WindowsCapability-online}"'
$tmpTask=Register-ScheduledTask-taskpath\-TaskName"AddTask"-Trigger$Time-Principal$user-Action$Action
Start-ScheduledTask-TaskNameAddTask

#givethetaskachancetofinish
Start-Sleep-Seconds20

$tmpTask|Unregister-ScheduledTask-confirm:$false
}#Whatif
}
Catch{
Throw$_
}
}

Write-Verbose"Setsshdtoautostart"
Try{
if($pscmdlet.ShouldProcess("sshd","Configureservice")){
Set-Service-Namesshd-StartupTypeAutomatic-ErrorActionstop
Write-Verbose"Startthesshdservice"
Start-Service-Namesshd-ErrorActionStop
Get-Servicesshd|Select-Object-Property*|Out-String|Write-Verbose
}
}
Catch{
Write-Warning"Therewasaproblemconfiguringthesshdservice."
}

if(-Not$WhatIfOption){
#onlydisplaythesummaryifnotusing-WhatIf
$msg=@"
SSHsetupcomplete.Edit$ENV:ProgramData\ssh\sshd_configforadditionalconfigurationsoptions
ortoenableremotingunderPowerShell7.

Youwillneedtorestartthesshdserviceforchangestotakeeffect.

"@
Write-Host$msg-ForegroundColorgreen
}

Write-Verbose"EndingSSHDsetupprocess."

该代码与交互式运行的代码有点不同。当您运行 Invoke-Command 并指定文件时,PowerShell 会将文件的内容视为脚本块并在远程运行空间中运行它。这就是为什么这些参数不是典型的函数参数。我将 Verbose 和 WhatIf 首选项从原始命令传递到脚本。

Invoke-Command-FilePath.\Setup-SSHServer.ps1-ComputerNamewin10-cred$artd-ArgumentList@("Continue",$True)

这为我提供了来自远程 Windows 10 计算机的 Verbose 和 Whatif 输出。使用默认值运行脚本效果很好。如果需要,您可以在注册表中添加行来设置默认 shell。但最终我想通过 ssh 配置 PowerShell 远程处理,所以我不需要它们。

PowerShell 7 SSH 远程处理

最后一步是将远程处理配置为使用 ssh,这发生在远程计算机上。您需要编辑 $env:ProgramData\ssh 中的 sshd_config 文件。这是我的副本,已根据必要的 PowerShell 要求进行了编辑。

# This is the sshd server system-wide configuration file.  See
# sshd_config(5) for more information.

# The strategy used for options in the default sshd_config shipped with
# OpenSSH is to specify options with their default value where
# possible, but leave them commented.  Uncommented options override the
# default value.

#Port 22
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::

#HostKey __PROGRAMDATA__/ssh/ssh_host_rsa_key
#HostKey __PROGRAMDATA__/ssh/ssh_host_dsa_key
#HostKey __PROGRAMDATA__/ssh/ssh_host_ecdsa_key
#HostKey __PROGRAMDATA__/ssh/ssh_host_ed25519_key

# Ciphers and keying
#RekeyLimit default none

# Logging
#SyslogFacility AUTH
#LogLevel INFO

# Authentication:

#LoginGraceTime 2m
#PermitRootLogin prohibit-password
#StrictModes yes
#MaxAuthTries 6
#MaxSessions 10

#ENABLED
PubkeyAuthentication yes

# The default is to check both .ssh/authorized_keys and .ssh/authorized_keys2
# but this is overridden so installations will only check .ssh/authorized_keys
AuthorizedKeysFile	.ssh/authorized_keys

#AuthorizedPrincipalsFile none

# For this to work you will also need host keys in %programData%/ssh/ssh_known_hosts
#HostbasedAuthentication no
# Change to yes if you don't trust ~/.ssh/known_hosts for
# HostbasedAuthentication
#IgnoreUserKnownHosts no
# Don't read the user's ~/.rhosts and ~/.shosts files
#IgnoreRhosts yes

# To disable tunneled clear text passwords, change to no here!
# ENABLED: Set this to YES for PowerShell remoting
PasswordAuthentication yes

#PermitEmptyPasswords no

#AllowAgentForwarding yes
#AllowTcpForwarding yes
#GatewayPorts no
#PermitTTY yes
#PrintMotd yes
#PrintLastLog yes
#TCPKeepAlive yes
#UseLogin no
#PermitUserEnvironment no
#ClientAliveInterval 0
#ClientAliveCountMax 3
#UseDNS no
#PidFile /var/run/sshd.pid
#MaxStartups 10:30:100
#PermitTunnel no
#ChrootDirectory none
#VersionAddendum none

# no default banner path
#Banner none

# override default of no subsystems
Subsystem	sftp	sftp-server.exe
#ADDED
Subsystem     powershell c:\progra~1\powershell\pwsh.exe -sshs -NoLogo

# Example of overriding settings on a per-user basis
#Match User anoncvs
#	AllowTcpForwarding no
#	PermitTTY no
#	ForceCommand cvs server

Match Group administrators
       AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys

您可能需要进行其他更改,具体取决于您的组织。假设已安装 OpenSSH.Server 和 PowerShell 7,我可以使用 PowerShell 将此文件复制到远程计算机。

Copy-Item-Path.\sshd_config_default-Destination$env:ProgramData\ssh\sshd_config-ToSession$sess

应重新启动 sshd 服务以使更改生效。

部署

最后一步是将所有这些整合到一个主控制脚本中。我决定添加代码以使用 PSReleaseTools 模块安装 PowerShell 7。

#requires-version5.1

#DeploymentcontrolscripttosetupSSHserveronaremoteWindows10desktop
#ItisassumedPowerShell7is,orwillbe,installed.

[cmdletbinding(SupportsShouldProcess)]
Param(
[Parameter(Position=0,Mandatory)]
[string]$Computername,
[pscredential]$Credential,
[switch]$InstallPowerShell
)

#removeparametersfromPSBoundparameterthatdon'tapplytoNew-PSSession
if($PSBoundParameters.ContainsKey("InstallPowerShell")){
[void]($PSBoundParameters.remove("InstallPowerShell"))
}

if($PSBoundParameters.ContainsKey("WhatIf")){
[void]($PSBoundParameters.remove("WhatIf"))
}

#parametersforWrite-Progress
$prog=@{
Activity="DeploySSHServertoWindows10"
Status=$Computername.toUpper()
CurrentOperation=""
PercentComplete=0
}
#createthePSSession
Try{
Write-Verbose"CreatingaPSSessionto$Computername"
$prog.CurrentOperation="CreatingatemporaryPSSession"
$prog.PercentComplete=10
Write-Progress@prog
$sess=New-PSSession@PSBoundParameters-ErrorActionStop
}
Catch{
Throw$_
}

if($sess){
if($InstallPowerShell){
$prog.currentOperation="InstallingPowerShell7"
$prog.percentComplete=25
Write-Progress@prog
#installPowerShell
if($pscmdlet.ShouldProcess($Computername.toUpper(),"InstallPowerShell7")){

Invoke-Command-ScriptBlock{
[void](Install-PackageProvider-Namenuget-force-forcebootstrap)
Install-ModulePSReleaseTools-Force
Install-PowerShell-EnableRemoting-EnableContextMenu-modeQuiet
}-session$sess
}#whatif
}

#setupSSH
$prog.currentOperation="InstallingOpenSSHServer"
$prog.percentComplete=50
Write-Progress@prog
Invoke-Command-FilePath.\Setup-SSHServer.ps1-Session$sess-ArgumentList@($VerbosePreference,$WhatIfPreference)

#copythesshd_configfile.Thisassumesyou'veinstalledPowerShell7ontheremotecomputer
Write-Verbose"Copyingsshd_configtotarget"
$prog.currentOperation="Copyingdefaultsshd_configtotarget"
$prog.percentcomplete=60
Write-Progress@prog
Copy-Item-Path.\sshd_config_default-Destination$env:ProgramData\ssh\sshd_config-ToSession$sess

#restarttheservice
Write-Verbose"Restartingthesshdserviceonthetarget"
$prog.currentOperation="Restartingthesshservicetarget"
$prog.percentComplete=75
Write-Progress@prog
if($pscmdlet.ShouldProcess("sshd","Restartservice")){
Invoke-Command{Restart-Service-Namesshd}-Session$sess
}

Write-Verbose"RemovingthetemporaryPSSession"
$prog.currentOperation="RemovingtemporaryPSSession"
$prog.percentComplete=90
Write-Progress@prog
$sess|Remove-PSSession

Write-Progress@prog-completed
$msg=@"

SSHServerdeploymentcompletefor$($Computername.toUpper()).

IfPowerShell7isinstalledremotely,youshouldbeabletotest
withanexpressionlike:

Enter-PSSession-hostname$Computername-username<user>-sshtransport

"@

Write-Host$msg-ForegroundColoryellow
}#if$sess

[玩转系统] 将 OpenSSH 服务器部署到 Windows 10

我可能应该在配置 sshd 服务时添加更好的错误处理,但这应该设置所有内容,以便我可以执行以下操作:

[玩转系统] 将 OpenSSH 服务器部署到 Windows 10

下一步

我使用 ssh 和 PowerShell 进行 Windows 之旅的下一部分是配置我的 Windows 服务器。完成后,我可以通过 ssh 使用 PowerShell 远程处理几乎所有内容。明天我会深入探讨这个问题。

您需要 登录账户 后才能发表评论

取消回复欢迎 发表评论:

关灯