lavabit / robox

The tools needed to robotically create/configure/provision a large number of operating systems, for a variety of hypervisors, using packer.
620 stars 139 forks source link

Random root password and SSH login enabled in the final image. Can this be avoided? #226

Closed dragetd closed 2 years ago

dragetd commented 2 years ago

Multiple VMs enable PermitRootLogin. For example Debian:

https://github.com/lavabit/robox/blob/01b7ccfcb38c4b353a842d7c412d090734d4e2e6/http/generic.debian11.vagrant.cfg#L63

and the root user also has a password set. The way it is done via sed causes it to be replaced inside the comment-section of SSHD. With this replacement, it almost look like a backdoor. The option ends up embedded between comments which is easy to over-read.

…
# Set this to 'yes' to enable PAM authentication, account processing,
# and session processing. If this is enabled, PAM authentication will
# be allowed through the ChallengeResponseAuthentication and
# PasswordAuthentication.  Depending on your PAM configuration,
# PAM authentication via ChallengeResponseAuthentication may bypass
PermitRootLogin yes
# If you just want the PAM account and session checks to run without
# PAM authentication, then enable this but set PasswordAuthentication
# and ChallengeResponseAuthentication to 'no'.
UsePAM yes
…

Is this intended? And why?

timschumi commented 2 years ago

This PermitRootLogin was part of a comment, so it is likely not the one that should have been edited (the sed command basically just says "Edit every line that contains PermitRootLogin to say PermitRootLogin yes):

# Set this to 'yes' to enable PAM authentication, account processing,
# and session processing. If this is enabled, PAM authentication will
# be allowed through the KbdInteractiveAuthentication and
# PasswordAuthentication.  Depending on your PAM configuration,
# PAM authentication via KbdInteractiveAuthentication may bypass
# the setting of "PermitRootLogin without-password".
# If you just want the PAM account and session checks to run without
# PAM authentication, then enable this but set PasswordAuthentication
# and KbdInteractiveAuthentication to 'no'.

There should be another PermitRootLogin statement further up that is much more obvious and not buried between comments.

One could edit the sed command to ignore comments, but I'm not if it would work (as the PermitRootLogin that is meant to be edited is commented by default as well) and if it's really worth the effort.

That said, maybe we could also evaluate whether logging in as root over ssh is required post-installation at all.

ladar commented 2 years ago

There should be another PermitRootLogin statement further up that is much more obvious and not buried between comments. One could edit the sed command to ignore comments, but I'm not if it would work (as the PermitRootLogin that is meant to be edited is commented by default as well) and if it's really worth the effort.

The root account is used to build and configure the box image. But if you look at the common/scripts/lockout.sh script, you'll see every box config randomizes the root password at the end of the build process. So this isn't a backdoor, because nobody can login as root ... until the root password has been meanually set to a known value. It would be nice if the README.md included a section on how to use the box images, which talked topics like this. Including locking down the root/vagrant user accounts, adding fail2ban, etc. But we don't current have anybody volunteering to help with documentation.

The above said, in my perfect world the Robox build process wouldn't blindly run a find/replace on the sshd_config file. Instead we'd surgically add a file to /etc/ssh/sshd_config.d/ or some other appropriate directory, and then add the necessary include directive to the /etc/ssh/sshd_config file. If we switched to this approach, then the directive could be removed by the cleanup.sh or lockout.sh scripts. Unfortunatelly I don't have enough time to make this kind of change and test it. Perhaps @dragetd ... would you like to take on this task, and submit a pull request along these lines?

That said, maybe we could also evaluate whether logging in as root over ssh is required post-installation at all.

As I mentioned above, post box build, it shouldn't be required, let alone possible, unless someone logs in as vagrant first, and then either sets the root password, or adds an authorized_key file.

What is personally more worrisome than the root login scenario, is the base box convention which stipulates the vagrant user password should also be set to vagrant. If someone were to unknowingly expose SSH to the Internet, this simple user/password combo could in fact be used to breach a box.

I've wanted to write a script for some time that would close this loophole, but it would take quite a bit of work. My thought was to add a script which would run during the first vagrant login. If the first login is over SSH, and uses the insecure key/pair, and that insecure key subsequently gets replaced, then this script could close the loophole by randomizing the vagrant user password and/or disabling SSH password authentication. Alternatively, if the first login occurred via the console, or via SSH using a password, then a warning message could be shown, and the well known and insecure Vagrant key pair could be removed from the authorized_keys file.

But getting such a script right is tricky, and it's likely that no matter how thorough such a script is, there will be edge cases it doesn't handle properly. That is in addition to the complexity of writing a script that can handle the variety of distros, and distro variations we now support.

Along these lines I've also been meaning open an issue in the Vagrant repo, so we can get a discussion started on contemporary expectationsare for a Vagrant box. What are the minimum, and what are the ideal acceptance criteria are for a base box image?

We could also open issue to discuss whether Vagrant itself shouldn't be randomizing the vagrant account password when it replaces the insecure key. Or as an alternative, should there be a Vagrantfile directive which instructs controls whether the account password is randomized. Something along the lines of the existing config.ssh.insert_key directive. If something like this existed, it could added to the Vagrantfile that gets embedded with the base box.

dragetd commented 2 years ago

Some thoughts:

But I would have to take a closer look on how things are setup. As far as I understood: Vagrant expects the base-images to have a 'vagrant' user (without a password) that comes with an insecure ssh keypair. https://www.vagrantup.com/docs/boxes/base#vagrant-user

This user should have sudo permissions. As soon as vagrant starts a box, it auto-replaces the insecure keypair with a freshly generated new keypair which will be part of the .vagrant settings directory where the vagrant box was initialized. No password ever needed.

I do not have that much experience building images, so maybe I got something completely wrong. But I thought it ought to be enough to use a seed config or such that creates a default user called 'vagrant' where a known, insecure vagrant SSH-key is deployed and no password is set (or removed, if it had to be set as part of the installation).

It would not only be a matter of documentation, but I would rather not touch the sshd config at all (at least in an image called 'generic'. Sadly I do not think I will find time for taking a shot at this soon. :S

ladar commented 2 years ago

@dragetd I used to use a more specific regex, which I think might have been ^#PermitRootLogin but it kept breaking. When I add a new distro, or variant, I often copy the existing config. And the more specific regex would break, because the sshd_config would start using # PermitRootLogin, or ##PermitRootLogin, or ## PermitRootLogin or the commented would get removed, and it'd become PermitRootLogin no.

So eventually I just started using a the current regex, which doesn't care. But like you point out, it matches the string inside the boilerplate comment that a lot (but not all) distros include with the sshd_config. It's a minor cosmetic issue, so I never really worried about it.

As for what you described regarding the password, it doesn't take all scenarios into account. The password has to be set to something known, so that if the SSH setup fails, which happens frequently. Some providers have this issue more often then others. But, if it does fail the box can still be accessed via the console (at a minimum), and the issue fixed.

There are also boxes which don't use the insecure key method, but instead specify a username and password in the Vagrantfile, I don't really know why. It could just be legacy logic leftover over from before the key method became standard, and SSH access using a password isn't needed anymore. But it's also possible that someone uses the Robox images as a base, and repackages it for a specific purpose, and then relies on username/password login method. I don't really know, so I'm going off the base box standard I found long ago. And I'm not aware of any official updates to it.

I found the attached tidbit from the Pro Vagrant book I had. I think there was more in the Vagrant Up and Running that Mitchell Hashimoto wrote, but I can't find my copy at the moment.

Screenshot from 2021-12-18 19-57-07