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

[玩转系统] 将 OpenSSH 部署到 Windows Server

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

将 OpenSSH 部署到 Windows Server


昨天我分享了一些在远程 Windows 10 系统上远程设置 ssh 服务器组件的 PowerShell 想法。这将允许您建立到桌面的 ssh 会话,甚至通过 ssh 使用 PowerShell 远程处理。接下来,我们需要考虑对 Windows 服务器执行相同的操作。

Windows 服务器 2019

如果您使用的是 Windows Server 2019,则可以使用我在 Windows 10 中使用的相同代码,至少根据我的经验。 Windows Server 2019 包含 OpenSSH.Server 功能,您可以使用 Add-WindowsCapability 安装该功能。我能够使用与 Windows 10 相同的部署脚本来安装 PowerShell 7 和 sshd。我所做的唯一更改是 Write-Progress 活动。

$prog = @{
    Activity = "Deploy SSH Server to Windows 10/Windows Server 2019"
    Status = $Computername.toUpper()
    CurrentOperation = ""
    PercentComplete = 0
}

除此之外,一切都运行相同,几分钟后 PowerShell 7 和 ssh 远程处理就准备就绪。

[玩转系统] 将 OpenSSH 部署到 Windows Server

Windows 服务器 2016

Windows Server 2016 的安装有点不同。根据我找到的 Microsoft 文档,您需要安装 GitHub 上的最新版本。您可以使用 Invoke-Webrequest 来做到这一点。尽管在执行任何操作之前,您很可能需要配置网络安全。

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

如果您不在 Windows Server 2016 上执行此操作,则尝试连接到 GitHub 和 PowerShell Gallery 时会出现错误。下载 zip 文件后,您可以将其解压,然后运行安装脚本。这是以服务器为中心的 PowerShell 脚本。

#requires -version 5.1

<#
    setup SSHD on Windows Server 2016
    https://github.com/PowerShell/Win32-OpenSSH/wiki/Install-Win32-OpenSSH

    This script is designed to be run remotely using Invoke-Command

    Sample usage:
    Verbose and Whatif
    invoke-command -FilePath .\Setup-SSHServer2.ps1 -ComputerName srv1 -cred $admin -ArgumentList @("Continue",$True)

    Verbose
    invoke-command -FilePath .\Setup-SSHServer2.ps1 -ComputerName srv1 -cred $admin -ArgumentList @("Continue")
#>

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

$VerbosePreference = $VerboseOption
$WhatIfPreference = $WhatIfOption

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$url = 'https://github.com/PowerShell/Win32-OpenSSH/releases/latest/'
$request = [System.Net.WebRequest]::Create($url)
$request.AllowAutoRedirect = $false
$response = $request.GetResponse()
$dl = $([String]$response.GetResponseHeader("Location")).Replace('tag', 'download') + '/OpenSSH-Win64.zip'

$zip = "C:\OpenSSH64.zip"
Write-Verbose "download SSH from $dl to $zip"
if ($pscmdlet.ShouldProcess($dl,"Downloading OpenSSH-Win64 Package")) {
    Try {
        Invoke-WebRequest -Uri $dl -OutFile $zip -DisableKeepAlive -ErrorAction Stop
    }
    Catch {
        Throw $_
    }
    if (Test-Path $zip) {
        Write-Verbose "Extract zip file"
        Expand-Archive $zip -DestinationPath "c:\Program Files" -force
    }
    else {
        Return "zip file failed to download"
    }
}

Write-Verbose "Install SSH"
if ($pscmdlet.ShouldProcess("install-sshd.ps1", "Execute")) {
    Push-Location
    Set-Location -Path 'C:\Program Files\OpenSSH-Win64\'
    . .\install-sshd
    Pop-Location
}

Write-Verbose "Set sshd to auto start"
Try {
    if ($pscmdlet.ShouldProcess("sshd", "Configure service")) {
        Set-Service -Name sshd -StartupType Automatic -ErrorAction stop
        Write-Verbose "Start the sshd service"
        Start-Service -Name sshd -ErrorAction Stop
        Get-Service sshd | Select-Object -Property * | Out-String | Write-Verbose
    }
}
Catch {
    Write-Warning "There was a problem configuring the sshd service."
}

Write-Verbose "Add the firewall rule"
if ($pscmdlet.ShouldProcess("sshd", "Add firewall rule")) {
    Try {
        $rule = New-NetFirewallRule -Name sshd -DisplayName 'OpenSSH Server (sshd)' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22 -ErrorAction Stop
        Write-Verbose ($rule | Out-String)
    }
    Catch {
        Throw $_
    }
}

if (-Not $WhatIfOption) {
    #only display the summary if not using -WhatIf
    $msg = @"

SSH setup complete. Edit $ENV:ProgramData\ssh\sshd_config for additional configurations options
or to enable remoting under PowerShell 7.

You will need to restart the sshd service for changes to take effect.

"@
    Write-Host $msg -ForegroundColor green
}

Write-Verbose "Ending SSHD setup process."

与 Windows 10 版本的脚本一样,该脚本设计为使用 Invoke-Command 远程运行。当然,我有一个控制脚本。

#requires -version 5.1

#Deployment control script to setup SSH server on a remote Windows Server 2016
#It is assumed PowerShell 7 is, or will be, installed.

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

#remove parameters from PSBoundparameter that don't apply to New-PSSession
if ($PSBoundParameters.ContainsKey("InstallPowerShell")) {
    [void]($PSBoundParameters.remove("InstallPowerShell"))
}

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

#parameters for Write-Progress
$prog = @{
    Activity         = "Deploy SSH Server to Windows Server 2016"
    Status           = $Computername.toUpper()
    CurrentOperation = ""
    PercentComplete  = 0
}
#create the PSSession
Try {
    Write-Verbose "Creating a PSSession to $Computername"
    $prog.CurrentOperation = "Creating a temporary PSSession"
    $prog.PercentComplete = 10
    Write-Progress @prog
    $sess = New-PSSession @PSBoundParameters -ErrorAction Stop
}
Catch {
    Throw $_
}

if ($sess) {
    if ($InstallPowerShell) {
        Write-Verbose "Installing PowerShell 7"
        $prog.currentOperation = "Installing PowerShell 7"
        $prog.percentComplete = 25
        Write-Progress @prog
        #install PowerShell
        if ($pscmdlet.ShouldProcess($Computername.toUpper(), "Install PowerShell 7")) {
            Invoke-Command -ScriptBlock {
                #need to set security protocol to Tls12 for Windows Server 2016 otherwise the installs will fail
                Write-Verbose "Setting network security to Tls12"
                [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
                Write-Verbose "Using Security Protocol $([Net.ServicePointManager]::SecurityProtocol)"
                [void](Install-PackageProvider -Name nuget -force -forcebootstrap -minimumversion '2.8.5.201')
                Install-Module PSReleaseTools -Force -Scope AllUsers -Repository PSGallery
                Install-PowerShell -EnableRemoting -EnableContextMenu -Mode Quiet
            } -Session $sess

            #Installing PowerShell may break the session so rebuild it if necessary
            if ($sess.state -eq 'Broken') {
                Write-Verbose "Rebuilding the temporary PSSession"
                $sess = New-PSSession @PSBoundParameters -ErrorAction Stop
            }
        } #whatif
    } #if install PowerShell 7

    #setup SSH
    $prog.currentOperation = "Installing OpenSSH Server"
    $prog.percentComplete = 50
    Write-Progress @prog
    Invoke-Command -FilePath .\Setup-SSHServer2.ps1 -Session $sess -ArgumentList @($VerbosePreference, $WhatIfPreference)

    #copy the sshd_config file. This assumes you've installed PowerShell 7 on the remote computer
    Write-Verbose "Copying sshd_config to target"
    $prog.currentOperation = "Copying default sshd_config to target"
    $prog.percentcomplete = 60
    Write-Progress @prog
    Copy-Item -Path .\sshd_config_default -Destination $env:ProgramData\ssh\sshd_config -ToSession $sess

    #restart the service
    Write-Verbose "Restarting the sshd service on the target"
    $prog.currentOperation = "Restarting the ssh service target"
    $prog.percentComplete = 75
    Write-Progress @prog
    if ($pscmdlet.ShouldProcess("sshd", "Restart service")) {
        Invoke-Command { Restart-Service -Name sshd } -Session $sess
    }

    Write-Verbose "Removing the temporary PSSession"
    $prog.currentOperation = "Removing temporary PSSession"
    $prog.percentComplete = 90
    Write-Progress @prog
    $sess | Remove-PSSession

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

SSH Server deployment complete for $($Computername.toUpper()).

If PowerShell 7 is installed remotely, you should be able to test
with an expression like:

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

"@

    Write-Host $msg -ForegroundColor yellow
} #if $sess
else {
    #this should never get called
    Write-Warning "Failed to create a temporary session to $Computername."
}

该脚本支持 -Verbose 和 -WhatIf。

[玩转系统] 将 OpenSSH 部署到 Windows Server

该脚本将复制 sshd_config_default 文件,您可以从上一篇文章中获取该文件。一旦到位,在 PowerShell 7 中使用 ssh 进行远程处理就变得轻而易举。

[玩转系统] 将 OpenSSH 部署到 Windows Server

下一步

您应该在非生产环境中测试所有这些代码并根据需要进行调整。每当您使用远程处理时,您都面临着让自己变得脆弱的风险。此过程的一部分应该包括了解有关 ssh 的更多信息。我所做的就是安装它并能够使用 PowerShell。 ssh 还有更多功能

欢迎提出意见和问题。

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

取消回复欢迎 发表评论:

关灯