RPi-Distro / raspberrypi-sys-mods

A collection of Raspberry Pi-sourced system configuration files and associated scripts
99 stars 36 forks source link

If ssh keys are found in /boot/ssh, add these to authorized_keys & disable default pw #57

Closed berthubert closed 3 years ago

berthubert commented 3 years ago

I like installing Raspberry Pi OS using 'dd'. I then touch /boot/ssh to enable ssh, and then I have to log in using a default password, provision my own SSH public key for access, and disable the default password. This is clunky and error prone.

With this PR, touching /boot/ssh (or /boot/ssh.txt) will still enable SSH access as usual.

However, if you put one or more valid SSH public keys in that file, they will get provisioned to ~pi/.ssh/authorized keys, and the default password will be disabled. This closes a security gap.

I have tested this PR many times on fresh installs, and I have also verified that the old behaviour is unchanged. Some discussion can be found on https://twitter.com/PowerDNS_Bert/status/1426247244412604424

For ease of merging, I have incorporated #55 in this PR, since it is 1) useful and 2) would generate a conflict with this PR. Thanks to @Habbie for this & other great suggestions.

Forceflow commented 3 years ago

This is a good idea. I also image rpi's a lot. This would reduce the time a new system is exposed to the network with default credentials to zero.

MichaIng commented 3 years ago

Great idea. I suggest to not lock the password completely, as this breaks local and serial console logins as well, but instead disable password logins via OpenSSH server option: https://manpages.debian.org/sshd_config#PasswordAuthentication

Also I'm not sure how likely it is that the file syntax is broken due to e.g. things like Windows line endings or so, so probably a more complete validity check makes sense? Not sure which tool to use for that, but likely sshd or gpg or openssl have an ability to verify that key definition/prefix and content are valid and match. If one of the OpenSSH tools can do it, this would be best, to assure that also the algorithm is supported already, e.g. not sure if Ed25519 is supported already on Buster, while PuTTY does.

KizzyCode commented 3 years ago

Also I'm not sure how likely it is that the file syntax is broken due to e.g. things like Windows line endings or so, so probably a more complete validity check makes sense?

AFAIK \r (and newlines in general) are not allowed within a SSH public key line, so it should be safe to simply replace any \r\n – this might result in some empty lines (\r\n\n\n), but those do not cause any problem.

However I'm not sure if it is a good idea to introduce a validity check, because it adds another layer of complexity...

For one thing this makes it harder to debug any problems ("Why is my authorized_keys-file empty?" or "Why is $key missing?"). If SSH does not work correctly I usually look for sshd-related errors, not for deployment-specific logs (how many people would even know where to look for?).

Additionally how would you want to handle any invalid/unsupported keys? The user expects that the pi is locked (= no password based SSH login), so using the password as SSH-fallback-login is not an option because it'd silently introduce a potential security vulnerability.

IMO it's probably the best to leave any invalid/unsupported key to OpenSSH to handle (and ignore/log)...?

MichaIng commented 3 years ago

True, if it is seen as a security feature, rather than a convenience one, then it's better to have a locked system rather than falling back to password authentication 👍.

If SSH does not work correctly I usually look for sshd-related errors

In this case you wouldn't be able to see anything, as long as you do not plug the SD card/USB stick into another Linux system and check the logs offline, and if OpenSSH logs a syntax error in the pubkey file on access attempt to a plain text file.

I'd lock only the SSH server and not the password itself, so that local and serial console login is still possible, in case anything fails. Often Raspberry Pi OS is used as desktop as well, and while it IMO always makes sense to do SSH authentication via key only, one might want to be able to connect a keyboard and screen or a serial cable as well.

KizzyCode commented 3 years ago

True, if it is seen as a security feature, rather than a convenience one, then it's better to have a locked system rather than falling back to password authentication 👍

Yes, and the problem is, from my experience: it will be seen as a security feature, tutorials will say: "So you don't need to change the default password because SSH only accepts the public key"

I'd lock only the SSH server and not the password itself, so that local and serial console login is still possible, in case anything fails.

Yeah, this was misleading on my side – I didn't mean to say anything at all on that point 😅, but: IMO this is a good idea! 👍🏻 If an attacker has physical access to a system like the pi, you've usually lost anyway*; so there is no point in disabling local password-based login – it only makes debugging much harder.

*There are ways to make evil maid attacks harder, but these require a lot of additional effort anyway and are probably out of scope here.

berthubert commented 3 years ago

Also I'm not sure how likely it is that the file syntax is broken due to e.g. things like Windows line endings or so, so probably a more complete validity check makes sense?

I just checked, the Raspberry Pi OS sshd fully ignores Windows line endings in .ssh/authorized_keys This would be a common failure mode otherwise, but we're good here.

berthubert commented 3 years ago

Great idea. I suggest to not lock the password completely, as this breaks local and serial console logins as well, but instead disable password logins via OpenSSH server option: https://manpages.debian.org/sshd_config#PasswordAuthentication

Regarding breaking things - this feature is new. If you want this, you have to explicitly put an SSH public key in a file. If you weren't doing that, this PR won't break anything. I feel pretty strongly that people will assume that this will disable the default 'raspberry' password, and would be surprised if they found out it didn't. Once your system is reached over SSH you can set a non-default password, so you can then still log in over serial etc.

So I would not be in favour of only removing password logins over SSH and then have people discover that when they install (say) an IMAP server that everyone can read your email using the 'raspberry' default password!

MichaIng commented 3 years ago

Finally it is all a question about how it is documented, as intuitively we obviously expect different things. When I see a feature to automatically apply an SSH key for authentication, I would not expect that desktop, console and serial logins are made impossible, unless/until the password it reset manually via SSH, which implies:

So it limits the (initial/intended) use of the feature to pure headless server systems with configured network assured on first boot.

install (say) an IMAP server that everyone can read your email using the 'raspberry' default password!

When one installs an applications which allows remote authentication via UNIX user passwords, then this should be pretty clear in the first place. Not sure which IMAP server does so by default, but I'd always decouple remote service authentication from local UNIX user logins strictly, and expect every installed package to behave so by default (while of course there are often optional UNIX user authentication option available). I personally see securing remote SSH authentication and local user authentication as two different things, so changing or locking UNIX user logins as a separate mandatory step. Also I think the initial pi user password can be changed via rpi-imager, isn't it?

But enough words from me about that: As long as it is documented clear what the feature does and what it does not, it is all fine, and obviously without adding more complexity, we cannot meet everyones personal preference 😄.

kucharskim commented 3 years ago

If disabling password is controversial or without consensus, I personally would split work into two steps. Handling keys as step one, then after consensus implementing if/how password should be disabled or even drop disabling password if it is agreed it should not be implemented. For serial console, I do find password disable not optimal, but it's not a big deal.

XECDesign commented 3 years ago

There is currently no intention to add this feature in this way. Please see https://github.com/RPi-Distro/raspberrypi-sys-mods/pull/40 for discussion and an alternative approach.