Ssh Config Key File
I hope this post will help you through the agony of configuring private key authentication in ssh for Windows so you can experience the ecstasy of actually using it with PowerShell for PowerShell 7 ssh-based remoting.
It’s been over five years since the PowerShell team announced that ssh was coming to Windows. That’s plenty of time to have exhaustively documented the steps to make it work well with public key authentication. But as my hours of agony configuring ssh on Windows Server prove, that hasn’t happened. As of this writing, there is an open pull request to improve the doc. But the pull request largely revises the existing documentation. That doc set is so badly organized and written, I’m not convinced the updates will make much difference in the topic I cover here. That topic is setting up file permissions for using Windows ssh with public key authentication.
- By default ssh looks for the key called idrsa.pub, we have to tell ssh to look for a different public key file depending on the service. This is where the config file comes handy.
- You must start ssh-agent (if it is not running already) before using ssh-add as follows: eval `ssh-agent -s` # start the agent ssh-add idrsa2 # Where idrsa2 is your new private key file. Note that the eval command starts the agent on Git Bash on Windows. Other environments may use a.
- Ssh-keygen -t rsa -b 2048 This will generate the SSH key. Press Enter at the following prompt to save the key in the default location (under your user directory as a folder named.ssh). You will then be prompted to enter a secure passphrase, but you can leave that blank.
Windows ssh works fine out-of-the-box with password authentication. However, it’s another story with public key authentication. (Available authentication methods are configured in sshd_config
.) For maximum security, enable public key authentication and disable password authentication. One should never have ssh password authentication enabled for Azure and/or AWS VMs. Never. Another security suggestion: move the sshd listener to a non-standard TCP port (not TCP 22). In fact, I’ve never worked in a client that does use password authentication for ssh access. And with PowerShell 7 ssh remoting, password authentication would mean constant calls to Get-Credential
. With public key authentication, ssh-agent
can be used to make credentials available to New-PsSession
and Enter-PsSession
.
Most Linux infrastructure architects are familiar with the access controls required for common ssh configuration files including ~/.ssh/config
, ~/.ssh/authorized_keys
and whatever private key is specified via either ssh-agent
or via the -i
identity parameter on the ssh command. These files must be owned by the user and must not allow group or world write access and, preferably, no group or world access at all. In Linux, this is accomplished with a simple chmod 600 [filename]
.
Enter the SSH config file: # contents of $HOME/.ssh/config Host dev HostName dev.example.com Port 22000 User fooey This means that I can simply $ ssh dev, and the options will be read from the configuration file.
Not so in Windows. Windows Server uses a flexible but complicated ACL security scheme — which is integrated with Active Directory users and groups — to control access to files. Failure to have the correct ACLs for one of the ssh configuration files produces a range of errors raging from obvious to the impenetrable.
For example, in this first screenshot in which I am attempting to ssh to localhost using a public key, the error is explicit. The public key’s ACLs are too broad.
But when the user’s $HOME.sshauthorized_keys
file — which contains the public key to be be matched to the incoming private key — is incorrectly ACLed, the ssh event log entry shows a maddeningly unhelpful response, as seen in this screenshot.
Before we discuss the proper ACLs for these files, let me suggest another tip that might make your life easier: avoid using %programdata%/ssh/administrators_authorized_keys
. This configuration setting in sshd_config
is supposed to allow centralization of public keys for domain users in the AD administrator groups. I spent hours and hours working on this without any success. I simply commented this out in sshd_config
and set up an administrator account as any end user account is set up: with the public keys in $HOME/.ssh
. This is a good idea but a terrible implementation and so, IMHO, it’s not worth the effort.
So, what are the proper ACL’s for user configuration files? The settings are both simple and undocumented. ACLs for ssh files must:
- Be owned by the user which will attempt to authenticate via ssh
- Have no inherited permissions
- Give full control to these three identities and no others: SYSTEM, Administrators and, of course, the user.
Here’s a screenshot showing the correct ACL settings for a user’s authorized_keys
file. Note that inheritance is disabled.
And here’s a screenshot showing the correct ACL settings for a private key used by ssh-agent
and/or an ssh -i [filename]
command.
There may be other combinations that work — but I couldn’t find any in my extensive testing on Windows Server 2019. In my testing, the results were binary. With these settings, connections work every time. Changing any of the settings, for example, adding the system administrator identity to a user’s authorized_keys
file instantly created the hard-to-debug error you see above.
Administratively, managing these required ACLs on a per-user basis is somewhat clumsy. To scale this, you would need to automate applying these settings. That shouldn’t be too hard. You could have a model file, use Get-Acl
to create the required input object for Set-Acl
and modify the file as required via PowerShell script. But once you know the required settings (hello, doc writers?), it’s no worse than it is in Linux.
Finally, here’s a bonus tip: remove all Write-Host
statements from the destination user’s $Profile
which you will PowerShell remote into. See this GitHub issue for more.
I hope you find this information helpful. Please feel free to leave a comment below with your tips for configuring ssh on Windows.
If you are even a tad bit familiar with SSH, you know that you can use it to connect to remote Linux systems.
Using SSH to connect to remote system is simple. All you need to do is to use a command like this:
This connects to the default SSH port 22. You may specify the port as well if you want.
Ssh Config Set Key File
Now this is all plain and simple if you just have one server. Even if you don’t remember the server’s IP address, you can perform a reverse search to the history using the famous terminal keyboard shortcut Ctrl+R and find the SSH command you used in the past.
But things get complicated when you have several servers to manage. I have around ten servers that I connect to from time to time. Some are production servers and some are test servers.
Now keeping a track of these servers is not easy. Even if I can find the SSH commands from the history, it is difficult to guess which IP belongs to which server.
Of course, I can open my dashboards on Linode, UpCloud, DigitalOcean and Google Cloud to get the IP or keep a list on my local system.
A better and easier way is to use SSH config file.
Using SSH config file for easily connecting to remote servers
The SSH config file allows you to create different profiles for different host configurations. There is no limit to such profiles and you may add as many as possible.
So, if you connect to multiple remote systems via SSH, creating SSH profiles will be a good move to save your time.
Let me show you how to use it.
Step 1: Create the SSH config file
When you install SSH, you’ll have a ~/.ssh directory created automatically. This direct contains your public key, private key a known_hosts file. Your config is also stored here.
At least on Ubuntu, the SSH config file is not created by default. You can easily create this file using the touch command like this:
Step 2: Add an SSH profile in the config file
Now that you have the SSH config file, you can edit it using Vim or Nano. Let me show you an example of the syntax which you should follow.
Ssh Configuration File
Let’s say you connect to a server with IP 275.128.172.46. Your username is Alice and the server is used for hosting your website. To harden SSH security, you use port 1500 instead of the default SSH port 22.
You can add all this information in the following manner in your ~/.ssh/config file:
Just save the information in the file. No need to restart any service.
Now, instead of writing a long command like this:
You can just use this command (tab completion works as well):
Ssh Config File Example
When you run the above command, ssh looks for a Host named website in the ~/.ssh/config. If it finds a host with that name, it gets all the information related and used it for making an SSH connection.
You might wonder about a few things, so I’ll mention it here:
- There is no space or tab indention restriction while entering the host information. Space or tab indention are used for making the config file easily understandable.
- The Hostname can be the IP address of the server or a hostname that can be resolved on your network.
- All the parameters like hostname, user and port are optional. However, I personally advise keeping at least hostname because that’s what you need (and you forget) most of the time.
- If your SSH config file is wrongly configured, it will result in an error when you try to use it for SSH connection.
- You cannot save passwords in SSH config. I advise adding your public SSH key to the server for easy access.
Step 3: Adding multiple profiles in SSH config file
The previous step gave you an idea about how to add an SSH profile. Let’s take it to the next step by adding multiple profiles in it.
Here’s what the SSH config file looks like now:
This time, I have added four different SSH profiles in it.
Did you notice the Host * entry at the end of the file? You can use this entry to for adding a parameter common to all profiles if that parameter hasn’t been mentioned for the profile explicitly. Sims mods 3 for mac.
So if I try to use the main-server SSH profile, it will automatically take root user.
How To Open .key File
ssh main-server = ssh root@275.128.172.49
Order of the SSH configuration
The ssh configuration follows the following order:
- command-line options
- user’s configuration file (~/.ssh/config)
- system-wide configuration file (/etc/ssh/ssh_config)
This means that the priority is given to the command you enter and then it looks into ~/.ssh/config and then in /etc/ssh/ssh_config.
So, if you want to override a profile, you can do that using the -o option of the ssh command.
For example, if I use this command:
It will take user bob instead of the user alice as defined in the ~/.ssh/config (in the previous step).
There’s a lot more to SSH config
To be honest, there is so much more to SSH config file that cannot be covered in a single article. You can use name/IP matching, subnets and what not.
The scope of this article was to introduce you to SSH config and help you create SSH profiles for easily connecting to various remote Linux systems.
You can always refer to the man page of ssh_config to know more about the parameters you can use while creating your SSH config file.
I hope this SSH tip was helpful to you. If you already use SSH config file and have a some nifty tip with you, do share it with the rest of us in the comment section.
Become a Member for FREE
Join the conversation.