Weboldal keresés

Telepítse az OpenSSH-t a Windows Server rendszerre


Tegnap megosztottam néhány PowerShell-ötletet az ssh kiszolgáló-összetevő távoli beállításához egy távoli Windows 10 rendszeren. Ez lehetővé teszi, hogy ssh-munkamenetet hozzon létre az asztalon, vagy akár PowerShell-távirányítást is használjon ssh-n keresztül. Ezután meg kell vizsgálnunk, hogy ugyanezt tesszük a Windows Serverek esetében.

Windows Server 2019

Ha Windows Server 2019-et használ, ugyanazt a kódot használhatja, amelyet a Windows 10-nél használtam, legalábbis az én tapasztalataim alapján. A Windows Server 2019 tartalmazza az OpenSSH.Server képességet, amelyet az Add-WindowsCapability segítségével telepíthet. A PowerShell 7 és az sshd telepítéséhez ugyanazt a telepítési szkriptet tudtam használni, amelyet a Windows 10 rendszerben használtam. Az egyetlen változtatást a Write-Progress tevékenységen végeztem.

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

Ellenkező esetben minden ugyanúgy futott, és percek múlva a PowerShell 7 és az ssh távirányítás készen állt a használatra.

Windows Server 2016

A Windows Server 2016 telepítése egy kicsit más. A Microsoft által talált dokumentáció szerint telepítenie kell a GitHub legújabb bitjeit. Ezt megteheti az Invoke-Webrequest segítségével. Bár mielőtt bármit tenne, valószínűleg be kell állítania a hálózati biztonságot.

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

Ha ezt nem teszi meg a Windows Server 2016 rendszeren, hibákat kap a GitHubhoz és a PowerShell-galériához való csatlakozáskor. A zip fájl letöltése után kibonthatja, majd futtathatja a telepítő szkriptet. Itt van a szerverközpontú PowerShell-szkript.

#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."

A szkript Windows 10-es verziójához hasonlóan ezt is az Invoke-Command segítségével távolról történő futtatásra tervezték. És természetesen van egy vezérlőszkriptem.

#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."
}

A szkript támogatja a -Verbose és -WhatIf.

A szkript átmásolja az sshd_config_default fájlt, amelyet az előző bejegyzésből megragadhat. Ha a helyére került, a PowerShell 7 ssh-val való távvezérlése gyerekjáték.

Következő lépések

Ezt a kódot nem éles környezetben kell tesztelnie, és szükség szerint módosítania kell. Bármikor távvezérléssel játszik, fennáll annak a veszélye, hogy sebezhetővé válik. Ennek a folyamatnak az ssh-ről való további ismereteket is magában kell foglalnia. Csak annyit tettem, hogy telepítettem, és képes vagyok együttműködni a PowerShell-lel. Az ssh-hoz még sok más tartozik

Észrevételeket és kérdéseket szívesen fogadunk.

Kapcsolódó cikkek