VMware ESXi 4.0 / ESXi 4.1: enable SSH login for non-root users (and only them)
Posted by jpluimers on 2010/09/28
VMware ESXi has SSH disabled by default.
In ESX / ESXi 3 and 3.5, it took a while for people to recognize the ‘unsupported’ trick and enable SSH.
In ESXi 4.0, /sbin/services.sh was fixed, so SSH was easier to enable (note: only delete the # in front of the first ssh).
Since ESXi version 4.1, SSH is called “Remote Tech Support (SSH)”, and it very easy to enable from the console.
Thomas Maurer described how easy it is to activate SSH in ESXi 4.1. He provides clear screen shots, whereas the VMware knowledge base article just lists the textual steps.
But contrary to ESX/ESXi 3.5 and lower, and *nix habits, enabling SSH on ESXi 4.x will enable this for the root user.
This has to do with the switch between ESX/ESXi 3.5 and 4.0 from to the dropbear ssh daemon (in the /sbin/dropbearmulti binary).
Dropbear is a very lightweight implementation of the SSH 2 protocol; ideal for ESXi which – as a hypervisor – needs to have a really low footprint.
In addition to the dropbear change, SSH is disabled for non-root users (which has nothing to do with dropbear, see below).
This post is about how to fix not only the SSH (as above) but also how to allow specific users to use SSH.The fact that SSH is disabled for non-root users is very confusing, especially because there is no difference in what you see upon a login through a bad username/password combination, or a user that is not allowed SSH access.
You will see this in under both circumstances:
C:\Users\username>ssh -l username 192.168.71.158 firstname.lastname@example.org's password: Permission denied, please try again.
Fixing SSH access for the user is a two step process.
Both steps involve editing the /etc/passwd file.
So you will need to SSH to your ESXi 4.x box as root user to fix this.
This is what the /etc/passwd file looks like (note I made a copy into /etc/passw.original before doing the edits; always have a backup ):
~ # cat /etc/passwd.original root:x:0:0:Administrator:/:/bin/ash nobody:x:99:99:Nobody:/:/sbin/nologin nfsnobody:x:65534:65534:Anonymous NFS User:/:/sbin/nologin dcui:x:100:100:DCUI User:/:/sbin/nologin daemon:x:2:2:daemon:/:/sbin/nologin vimuser:x:12:20:vimuser:/sbin:/sbin/nologin username:x:501:0:Linux User,,,:/home/username:/sbin/nologin
The first step is to change the default shell for username from /sbin/nologin (ESXi 4.0 has /bin/false) /into /bin/ash (the same shell that user root uses).
Since ESXi is *nix based, but has very few tools installed, you will have to use vi with that, so a list if VI keyboard shortcuts come in handy.
When you have done that, you might think you are ready.
You are not.
This is what you will see:
C:\Users\username>ssh -l username 192.168.71.158 email@example.com's password: You have activated Tech Support Mode. The time and date of this activation have been sent to the system logs. VMware offers supported, powerful system administration tools. Please see www.vmware.com/go/sysadmintools for details. Tech Support Mode may be disabled by an administrative user. Please consult the ESXi Configuration Guide for additional important information. Connection to 192.168.71.158 closed.
In other words: SSH login works, but the connection is immediately closed.
I have seen this behaviour on other *nix machines as well, so I recognized that the login directory for the user was wrong.
Indeed it is: when VMware ESXi 4.x adds a user, it adds the home directory in the /etc/passwd file.
But it does not create that home directory.
There are basically 2 solutions for this:
- create the /home/username directory
- replace the /home/username directory in /etc/passwd with the / root directory
I did the last step, see this diff:
/etc # diff passwd passwd.original --- passwd Wed Aug 4 19:34:14 2010 +++ passwd.original Wed Aug 4 19:27:53 2010 @@ -4,4 +4,4 @@ dcui:x:100:100:DCUI User:/:/sbin/nologin daemon:x:2:2:daemon:/:/sbin/nologin vimuser:x:12:20:vimuser:/sbin:/sbin/nologin -username:x:501:0:Linux User,,,:/:/bin/ash +username:x:501:0:Linux User,,,:/home/username:/sbin/nologin
And now the login works:
C:\Users\username>ssh -l username 192.168.71.158 firstname.lastname@example.org's password: You have activated Tech Support Mode. The time and date of this activation have been sent to the system logs. VMware offers supported, powerful system administration tools. Please see www.vmware.com/go/sysadmintools for details. Tech Support Mode may be disabled by an administrative user. Please consult the ESXi Configuration Guide for additional important information. ~ $ su Password: ~ # pwd /
Now that I you have enabled SSH for a non-root account, you can start disabling it for the root account.
Knowing that the SSH server is in fact dropbear makes that easy: just look up the dropbear man page.
Here you see that adding the -w option to the dropbear commandline will “Disallow root logins”.
The solution is the same for all ESXi 4.x installations:
- login to the console or through SSH
- change this /etc/inetd.conf line by adding -w after the -i
ssh stream tcp nowait root /sbin/dropbearmulti dropbear ++min=0,swap,group=shell -i -K60
ssh stream tcp nowait root /sbin/dropbearmulti dropbear ++min=0,swap,group=shell -i -w -K60
Finally you will need to restart the inetd service by calling services.sh restart
Now that you can only login as non-root using SSH, you still need a means to become root.
Here you can use the su command.
I hope this helps a few people getting this to work sooner than I did.
Daniel Barnes posted the comment below, but since source code font in comments is to be really big, and I did not yet find out how to successfully change the WordPress CSS to alliviate it.
So here is the comment in full:
It is possible to make it permanent. I wrote a script which allows members of a “localadmin” group to remotely login via ssh. Create the group via vSphere and add users to it as desired.
In the “Local Technical Support Mode” shell, execute:
mkdir -p /tmp/oem/etc/vmware/init/init.d vi /tmp/oem/etc/vmware/init/init.d/120.config-inetd
Then enter the code below:
#!/bin/sh # Enable SSH sed '/tcp[^6]/s/^#ssh/ssh/' -i /etc/inetd.conf # Disable root login sed '/ssh/s/-i -K60/-i -w -K60/' -i /etc/inetd.conf # Grant access to localadmin group sed '/localadmin/d;1s/$/\n+:localadmin:ALL/' -i /etc/security/access.conf # Configure shell for localadmin users for u in $(grep ^localadmin /etc/group|cut -d: -f4|sed 's/,/\n/g'|grep -v root); do sed '/^'$u':/s:/sbin/nologin:/bin/ash:' -i /etc/passwd # Create home directories for localadmin users home=$(grep $u /etc/passwd|cut -d: -f6) mkdir -p $home/.ssh chown -R $u:users $home chmod 700 $home/.ssh done # Configure crontab to restore settings CRONTAB=/var/spool/cron/crontabs/root mkdir -p $(dirname $CRONTAB) sed /120.config-inetd/d -i $CRONTAB echo '* * * * * sh /etc/vmware/init/init.d/120.config-inetd' >> $CRONTAB # Remove syslog clutter sed '/120.config-inetd/d' -i /var/log/messages
Do this step if you already have an oem.tgz:
tar xzf /bootbank/oem.tgz -C /tmp/oem
Create a new oem.tgz:
tar czf /bootbank/oem.tgz etc -C /tmp/oem