-
Notifications
You must be signed in to change notification settings - Fork 66
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Install and run OpenSSH-win32? #164
Comments
I have been toying with this for a while now, just not sure how big of a customer ask it is, I even have some very slick integrations working (see current state of ssh access on Linux for an idea). You mention a simple process for the installation would be OK, even if it isn't baked into the base image right? We will have to discuss this more before we commit to anything but any more feedback on your use case would be great. |
Please link me?
My own use-case is basically that I want to unify onto ssh. I use packer & ansible to create golden images (Linux/Ubuntu and Windows within GCE, macOS within another provider (choice unfinalised, but looking like macstadium via anka)) that are then used for CI infrastructure. I have a strong requirement that builds be reproducible several years later, for long-term support of games development. Where I work (https://improbable.io) has only a small number of people with Windows infrastructure experience; that's another motivation for wanting to unify onto ssh, it's more widely familiar. We use bazel extensively with various languages including C++, so controlling the build environment is very important to avoid poisoning the remote cache via differing machine setups. The ansible project is working to support a Windows openssh connection plugin (ansible/ansible#25344 -> ansible/ansible#47732). I'm hoping that by adding support (baked or recipe) into a major cloud provider's Windows offering, that work will get wider adoption, quicker. There are a few options for installation described at https://github.com/DarwinJS/ChocoPackages/tree/master/openssh#install-scenario-2-non-chocolatey-using-psh-5-packagemanagement. One that would probably work fine inside
|
See the linux section here: I'm still debating the best way to handle this if we decide to support it. Either a custom package we maintain for the ssh server install or just pulling straight from Microsoft (have you tried following https://docs.microsoft.com/en-us/windows-server/administration/openssh/openssh_install_firstuse?). I'm also not sure how I want to update the agent, the simplest is as you described (that's how we do it on linux, and how I had it working in my POC), but using AuthorizedKeysCommand would be much cleaner and allow us to potentially integrate with oslogin (https://cloud.google.com/compute/docs/oslogin/) |
I haven't tried the first-use setup yet; I only just noticed Server 2019 has an improved experience. Except they seem to have changed the Powershell cmdlets for managing Windows features again. One of our use-cases is to allow people (via their gcloud auth) to remotely connect to instances that match a particular regex in their instance-names. People can remote into canary instances to poke around, but not production instances, basically. cc @shenson for thread. (I'm about to be away for a couple of weeks) |
@adjackura I did a thing. I tell packer to launch the instance with metadata:
This is the Get-GceMetaData -Path instance/attributes/bootstrap-base64 > c:/windows/temp/bootstrap.b64 ; certutil -decode c:/windows/temp/bootstrap.b64 c:/windows/temp/bootstrap.ps1 ; c:/windows/temp/bootstrap.ps1 -username totally-not-telling-you-the-username This is the bootstrap.ps1 that I arrange into param(
[string] $username = "tweeter",
[string] $open_ssh_version = "v7.9.0.0p1-Beta"
)
$ErrorActionPreference = 'Stop'; # stop on all errors
$log_stamp = get-date -format 'yyyyMMdd-HHmmss'
Start-Transcript -Path "$(pwd)/bootstrap.$($log_stamp).log" -IncludeInvocationHeader
# Make the administrator user that we'll be provisioning with during packer run
$Count = Get-Random -min 24 -max 32
$TempPassword = -join ((65..90) + (97..122) + (48..57) | Get-Random -Count $Count | % {[char]$_})
New-LocalUser -Name $username -PasswordNeverExpires -Password ($TempPassword | ConvertTo-SecureString -AsPlainText -Force) | out-null
Add-LocalGroupMember -Group "Administrators" -Member $username | out-null
# Install openssh
# https://github.com/PowerShell/Win32-OpenSSH/wiki/Install-Win32-OpenSSH
$url = "https://github.com/PowerShell/Win32-OpenSSH/releases/download/$($open_ssh_version)/OpenSSH-Win64.zip"
$output = "$($env:TEMP)/OpenSSH-Win64.zip"
# github went TLS 1.2 only from 2018
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12;
(New-Object System.Net.WebClient).DownloadFile($url, $output)
Expand-Archive -Path $output -DestinationPath "$($env:PROGRAMFILES)"
. "$($env:PROGRAMFILES)/OpenSSH-Win64/install-sshd.ps1"
# Set default shell for sshd connections to powershell to avoid legacy cmd nonsense
# https://github.com/PowerShell/Win32-OpenSSH/wiki/DefaultShell
[System.Environment]::SetEnvironmentVariable("PATH", "$($env:PATH);c:\Program Files\OpenSSH-Win64", [System.EnvironmentVariableTarget]::Machine)
New-Item -path "HKLM:\SOFTWARE\OpenSSH" -force
New-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" -Name DefaultShell -Value "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -PropertyType String -Force
New-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" -Name DefaultShellCommandOption -Value "/c" -PropertyType String -Force
# An sshd_config that's basically the stock one but
# * allows public key authentication (which is commented by default)
$sshd_config = "$($env:PROGRAMDATA)/ssh"
New-Item "$($sshd_config)" -Type Directory -Force
$sshd_config_file = "$($sshd_config)/sshd_config"
$sshd_config_base64 = get-gcemetadata -path "instance/attributes/sshd-config-base64"
$sshd_config_text = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($sshd_config_base64))
Set-Content -Path "$($sshd_config_file)" -Value "$($sshd_config_text)"
# Put the public key in the system-wide config location to avoid needing to programmatically create user profile. Sigh.
$public_key_base64 = get-gcemetadata -path "instance/attributes/public-key-base64"
$public_key = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($public_key_base64))
$system_authorized_keys_file = "$($sshd_config)/administrators_authorized_keys"
if (Test-Path "$($system_authorized_keys_file)") {
Remove-Item -Path "$($system_authorized_keys_file)" -force
}
Set-Content -Path "$($system_authorized_keys_file)" -Value "$($public_key)"
# Ensure access control on authorized_keys meets the requirements
# https://stackoverflow.com/questions/16212816/setting-up-openssh-for-windows-using-public-key-authentication
# https://github.com/jen20/packer-aws-windows-ssh/blob/master/files/configure-source-ssh.ps1#L99-L114
$acl = Get-ACL -Path $system_authorized_keys_file
$acl.SetAccessRuleProtection($True, $True)
Set-Acl -Path $system_authorized_keys_file -AclObject $acl
$acl = Get-ACL -Path $system_authorized_keys_file
$ar = New-Object System.Security.AccessControl.FileSystemAccessRule( `
"NT Authority\Authenticated Users", "ReadAndExecute", "Allow")
$acl.RemoveAccessRule($ar)
$ar = New-Object System.Security.AccessControl.FileSystemAccessRule( `
"BUILTIN\Administrators", "FullControl", "Allow")
$acl.RemoveAccessRule($ar)
$ar = New-Object System.Security.AccessControl.FileSystemAccessRule( `
"BUILTIN\Users", "FullControl", "Allow")
$acl.RemoveAccessRule($ar)
Set-Acl -Path $system_authorized_keys_file -AclObject $acl
Restart-Service sshd
Set-Service sshd -StartupType Automatic
# lastly, open up the firewall port
New-NetFirewallRule -Name sshd -DisplayName 'OpenSSH Server (sshd)' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22
Stop-Transcript This is working well so far against Windows 2016 Server desktop edition. Haven't tried it elsewhere so far. I imagine/hope that the only bit necessary to change for Windows 2019 is the 'install openssh' bit. |
Just checking in - this script and setup continue to serve well through Windows versions 2019 and 2022. |
Super excited about this, especially since Winrm is hot garbage. But also fighting weird issues with PSRP ontop of Winrm. since your last comment is ~a year old. Have you toyed with the newer support MS mentioned with SSH? |
To whomever is still ending up here: You can easily install OpenSSH on GCP Windows VMs using Metadata |
I've had positive experience with https://github.com/PowerShell/openssh-portable on Windows Server 2016
ssh-agent
service to hold private keys for user accountsI would love a world where I didn't have to deal with WinRM (can elaborate, but on request - want to keep this concise) and instead could use ssh to communicate to each of my remote fleet.
I was wondering at which point GCE might start to create base images that have it installed and, if not running, at least ready to go via a metadata-script nudge? I appreciate that one could install it via those means too, at the cost of extra time during either baking or boot.
Would you welcome a PR that added it, and if so, would you mind outlining what you might, vs might not, accept?
The text was updated successfully, but these errors were encountered: