There are different schools of thought as to whether you should have SSH enabled on your hosts. VMware recommend it is disabled. With SSH disabled there is no possibility of attack, so that’s the “most secure” option. Of course in the real world there’s a balance between “most secure” and “usability” (e.g. the most secure host is powered off and physically isolated from the network, but you can’t run any workloads ). My preferred route is to have it enabled but locked down.
Note: VMware use the term “ESXi Shell”, most of us would term it “SSH” – the two are used interchangeably in this article although there is a slight difference. You can have the ESXi Shell enabled but SSH disabled – this means you can access the shell via the DCUI. For the sake of this article assume ESXi Shell and SSH are the same.
This is by far the most blogged about topic on SSH with ESXi - I’ll refer you to the documentation rather than repeat!
VMware don’t want you to leave SSH enabled, so by default vSphere will alert you to the fact that it is. If your design decision is to enable SSH but you don’t want the warning, set the advanced setting “SuppressShellWarning” to a value of 1.
To configure via PowerCLI:
Get-VMHost esxi01.definit.local | Get-AdvancedSetting -Name 'UserVars.SuppressShellWarning’ | Set-AdvancedSetting -Value "1" -Confirm:$false
Using the ESXi firewall it’s possible to restrict access to SSH (and other services) based on the IP address of the client. You can enter IP addresses in the following formats: 192.168.0.0/24, 192.168.1.2, 2001::1/64, or fd3e:29a6:0a81:e478::/64. From Manage tab on a host you can open the Security Profile page and edit the firewall. Select the SSH Server rule and modify the allowed connections:
To configure this via PowerCLI you need to use the Get-EsxCli command:
$EsxCli = Get-EsxCli –VMhost esx01.definit.local $EsxCli.network.firewall.ruleset.allowedip.list(“sshServer”) # Returns the current AllowedIPAddresses $EsxCli.network.firewall.ruleset.set($false, $true, "sshServer") # Sets “AllowedAll” to $false, “Enabled” to $true on rule set “sshServer” $EsxCli.network.firewall.ruleset.allowedip.add("192.168.1.20", "sshServer") # Adds “192.168.1.20” to the AllowedIPAddresses ruleset – if you have multiple IPs to add you can repeat this line $EsxCli.network.firewall.refresh() # Reloads the firewall rules
From ESXi 5.1 up there you can configure two timeout settings for the ESXi Shell (SSH). The first “ESXiShellTimeOut” controls the service, and is useful if you enable SSH temporarily, but then forget to disable it (because we’re all busy, right?) The second setting, “ESXiShellInteractiveTimeOut” sets the session timeout for SSH – so if you leave your SSH client logged in and the timeout is set it will end your session and disconnect you. By default, both of these settings have a value of “0” which disables the timeout. The value is in seconds.
To set these by PowerCLI use the Set-AdvancedSetting cmdlet – in the below example I set the ESXiShellInteractiveTimeout to 5 minutes on the host esx01:
Get-VMHost esxi01.definit.local | Get-AdvancedSetting -Name 'UserVars.ESXiShellInteractiveTimeout' | Set-AdvancedSetting -Value "300" -Confirm:$false
It’s possible to use a public/private key pair to authenticate SSH connections to an ESXi host and allow password-less connections. Just because it’s possible, doesn’t mean you should! Bear in mind that if your private key is compromised then an attacker can gain full root access to a host without needing a password.
I used PuTTYGen to generate an SSH-2 RSA public/private key pair without a passphrase and save the public and private keys. I now have two files, id_rsa.pub (the public key) and id_rsa.ppk (the private key). You need to edit the id_rsa.pub file to remove the first two lines, the last line, and remove any line breaks. You also need to insert “ssh-rsa “ at the beginning (credit to Walkernews.net for this)
It’s easier to show you the file goes from this format:
To this:
Alternatively, you could also use the the ssh-keygen command located at /usr/lib/vmware/openssh/bin to generate a key pair. The disadvantage there is that the private key is on the server, so you should be careful there, ensure you remove the private key from that host and store it safely.
I then used WinSCP to copy id_rsa.pub to the /tmp folder on the host, then use PuTTY to SSH to the host and copy the public key to the authorized_keys file using the cat command:
cat /tmp/id_rsa.pub >> /etc/ssh/keys-root/authorized_keys
Note: the /keys-root/ folder could be any other user ID on the host, so if you had a user “sam” then you would use /keys-sam/
If you create the private key with a password, then you will get prompted for the password when you connect. This could be used to create more secure connections to the host (i.e. you need the username, private key and the password to connect rather than just a username and password), but would create quite an administrative burden.
How you configure your hosts for SSH is entirely down to you and your security policy – these are the settings that I use based off of my security policy and accepted risks (I in no way provide guarantee or warrantee for these settings! Do your research – I accept no liability!)
These settings can all be manually set, built into host profiles, or you could use a PowerCLI script to configure them if licensing doesn’t allow.
A slightly more secure configuration would be: