RSA key-based PowerShell 7 SSH remoting
Overview
Use PowerShell SSH remoting from Windows 10 to Windows 2012 Server
Why
- Remotely login and administer computers without providing credentials.
- Works with machines that are in a workgroup(Non-AD) as well as on machines that are in different domains.
- Works across various operating systems
- Windows → Mac OS or Linux
- Linux or Mac OS → Windows
- placeholder
Assumptions
PowerShell 7 has been installed on both the client as well as the server and the install path is :
C:\Program Files\PowerShell\7
On Windows 10 - Client
Install OpenSSH
- OpenSSH feature is built into Windows 10
build version
1809 and above .The feature just needs to be enabled. -
To check the Windows 10 build version type
Winver
in PowerShell . -
Open PowerShell as Administrator and type
Get-WindowsCapability -Online | where Name -like 'OpenSSH*'
-
If the
state
of theopenssh.client
isNotPresent
then we need to install it.Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0
In order to SSH from Windows 10 to a remote machine we dont need to enable the OpenSSH.Server role on Windows 10. We just need the client enabled or installed.
Placeholder
Configure the SSH Client
-
Set the service to start Automatically
Set-Service ssh-agent -StartupType Automatic
-
Start the service
Start-Service ssh-agent -PassThru
Placeholder
Generate RSA Key-Pair
-
Change to the the user profile ssh directory
cd $home\.ssh
-
Generate the Public-Private key pair.
ssh-keygen.exe -t rsa
-
You will be prompted to provide a password to secure the private key. Hit enter to continue without providing a password.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
-
sample output
PS C:\Users\kiran\.ssh> ssh-keygen.exe -t rsa Generating public/private rsa key pair. Enter file in which to save the key (C:\Users\kiran/.ssh/id_rsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in C:\Users\kiran/.ssh/id_rsa. Your public key has been saved in C:\Users\kiran/.ssh/id_rsa.pub. The key fingerprint is: SHA256:x5H0LQ29b4favJIxmSKlmYe42JzHJxgEZXaPuX69asQ lab\kiran@KIRAN-Laptop The key's randomart image is: +---[RSA 2048]----+ | .+ . . .. | | .o . = o +. | | . o + o o. | | . o.. .. | | . .SBo o o | | o.*.E.= . +| | + *.+...B ..| | . * +.o +.o | | . +...... | +----[SHA256]-----+ PS C:\Users\kiran\.ssh> dir Directory: C:\Users\kiran\.ssh Mode LastWriteTime Length Name ---- ------------- ------ ---- -a---- 3/18/2020 2:50 PM 1675 id_rsa -a---- 3/18/2020 2:50 PM 410 id_rsa.pub -a---- 3/18/2020 10:58 AM 204 known_hosts
-
You should see the following 2 files in the .ssh directory
- id_rsa ⇒ Private Key
- id_rsa.pub ⇒ Public Key
Placeholder
On Windows 2012 - Server
Install OpenSSH
- Donwload the latest version of OpenSSH from Github
- Extract contents of the latest build to C:\Program Files\OpenSSH (Make sure binary location has the Write permissions to just to SYSTEM, Administrator groups. Authenticated users should and only have Read and Execute.)
-
From an elevated PowerShell Install SSH:
PS C:\Program Files\OpenSSH> .\install-sshd.ps1
-
Open the firewall for sshd.exe to allow inbound SSH connections
New-NetFirewallRule -Name sshd -DisplayName 'SSH Inbound' -Profile @('Domain', 'Private') -Enabled True -Direction Inbound -Action Allow -Protocol TCP ‑LocalPort 22
Placeholder
Configure the SSH server service
-
Set the service to start Automatically
Set-Service sshd -StartupType Automatic
-
Start the service
Start-Service sshd -PassThru
Placeholder
Configure the SSH server Shell
-
The default shell used by SSH is the Windows command shell. We change to PowerShell:
New-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" -Name DefaultShell -Value "C:\Program Files\PowerShell\7\pwsh.exe" -PropertyType String -Force
-
There's a bug in OpenSSH on Windows. It doesn't work with paths with a space. For more information, see this GitHub issue. The workaround is to create a symbolic link that creates a path that OpenSSH can use:
New-Item -ItemType SymbolicLink -Path C:\pwsh -Target 'C:\Program Files\PowerShell\7'
OR
-
You can use the 8.3 short name for any file paths that contain spaces. The 8.3 short name for the
Program Files
folder in Windows is usuallyProgra~1
.We will Use the path below in the sshd_config file.
c:/progra~1/powershell/7/pwsh.exe
Placeholder
Configure the SSH server sshd_config file
-
The SSH keys and configuration file reside in C:\ProgramData\ssh, which is a hidden folder. edit the config file sshd_config file as follows:
# 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 no #MaxAuthTries 6 #MaxSessions 10 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! PasswordAuthentication yes #PermitEmptyPasswords no # GSSAPI options #GSSAPIAuthentication 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 Subsystem powershell c:/progra~1/powershell/7/pwsh.exe -sshs -NoLogo -NoProfile # 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
-
After saving the changes to the sshd_config file, restart the sshd server service:
Restart-Service sshd -PassThru
Placeholder
Public Key configuration
Run this from the windows 10 client
-
Copy the public key from the Windows 10 client to Windows 2012 server:
Make sure that the .ssh directory exists in your server's user home folder.
User can either be a local or a domain account. In my case i am using a domain account
ssh kiran@windows2012Server new-item c:\users\kiran\.ssh -ea 0 -item directory
-
Use scp to copy the public key file generated previously on the window10 client to authorized_keys on your server
scp C:\Users\kiran\.ssh\id_rsa.pub kiran@windows2012Server:C:\Users\kiran\.ssh\authorized_keys
Placeholder
Testing SSH with SSH.exe
Run this from the windows 10 client
-
Test ssh with a domain user named kiran
ssh -v -i C:\Users\kiran\.ssh\id_rsa kiran@windows2012Server
This should get you a powershell 7 console on the remote server named: windows2012Server
You can verify using the "hostname" command.
If this works that means our ssh configuration is a success. we can proceed to the next step.
Placeholder
Testing SSH with PowerShell : Interactive
Run this from the windows 10 client
-
Test powershell ssh-based remoting with a domain user named kiran
Enter-PSSession -HostName windows2012Server -UserName kiran
This should get you a powershell 7 console on the remote server named: windows2012Server
You can verify using the "hostname" command.
Placeholder
Testing with SSH with PowerShell : Non-Interactive
Run this from the windows 10 client
-
Create a ps-session
$session = New-PSSession -HostName windows2012Server -UserName kiran
Username parameter can be omitted if you are remoting from the client that generated the rsa key.
However if you copied the rsa key from one client to another and use it under a different login then username needs to be specified.
-
Test with invoke-command
Invoke-Command -Session $session -ScriptBlock { hostname }
This should return the name of the remote computer : windows2012Server
Placeholder
PowerShell Remoting over SSH does not currently support remote endpoint configuration and JEA (Just Enough Administration)
Top comments (0)