SSH key auth, but still need password for sudo?

  • SSH with public-private key authentication comes enabled by default with most Linux distributions. This is great because when I create accounts for remote users I don't have to email them sensitive info(passwords).

    However, this process becomes useless when these users need to run sudo -- the server is still asking for their passwords. That means I still need to generate passwords for these users and figure out how to securely get it to them.

    I know about sudoers file and NOPASSWORD parameter. However, I feel uneasy enabling it. I would still want some sort of authentication before users can run sudo commands.

    While doing some research on this topic I found pam_ssh_agent_auth project, which from my understanding enables the same private/public key authentication as used for ssh connections but for sudo command.

    It seems like with this module in place we can have completely passwordless accounts.

    Why is this module or similar process is not part of standard Linux distro configs? Is there some security caveat I'm missing why this is not more widely adopted? Why passworded sudo is considered to be more secure than public/private key sudo?

    Can't they just run `passwd` on their first login to set their password ?

    @AndréDaniel `passwd` requires entering user's "current" password

    There is public/private key alternative to sudo -- it's ssh :) -- see my answer for details.

    Just adding feedback for this solution. It doesn't quite work for permission modifying commands like chmod and chown (there are legitimate workflows and use cases where this is needed), as those implicitly require root privileges - unless you grant r_service sudo rights!! In which case, why go through all that, when you can just enable sudo? Edit: This is reply to Galaxy's answer about not using sudo.

  • I am trying a different approach that doesn't require creating and managing passwords: I set up key-based authentication with the user's public key, disabled password-based authenticon for ssh and set up the user accounts with an empty but expired password (passwd -de). That way users get prompted on their first login and can choose their own passwords.

    I am feeling a bit uneasy about the empty password but as far as I can tell, it's fine as long as password authentication for ssh is disabled and there are no other services running that require authentication (IMAP or something). Any opinions on this?

    That's a creative solution.

    I'd be afraid of the empty password. Couldn't another user on the same machine get into and change the password from su or something similar?

    That's assuming SSH is the only way into the server right? (no local access, Apache/ftpd doesn't authenticate against local accounts, etc.) Also, what happens when someone does `sudo -u `...?

    Also, what happens when someone does `su `...?

    With "sudo -u user_with_empty bash" you get a shell but obviously you'd need root/sudo privileges for that. What happens with "su user_with_empty" is usually defined by PAM. By default su'ing is denied on the distros I know (via /etc/pam.d/su that includes /etc/pam.d/common-auth, see 'nullok_secure')

  • I suggest to avoid even installing sudo on your systems: it's an additional attack vector with usually no justification for having it. I wrote an article on the sudo (mis)usage if you are interested to learn more on the topic: http://dmitry.khlebnikov.net/2015/07/should-we-use-sudo-for-day-to-day.html

    Re: the original question - if you need some privileged command to be executed by non-privileged users you may use the following trick:

    1. generate a passphrase-less SSH key
    2. prepend the public part with the following: from="127.0.0.1",command="your_desired_command_here",no-pty,no-port-forwarding,no-agent-forwarding (you can also restrict the SSH session further, see "man sshd"). Note that the key should be separated from this header by a space character.
    3. install that public key to privileged account's ~/.ssh/authorized_keys
    4. provide the user with the private key (or create a script that simply SSH in over the loopback interface to the privileged account using the private key)

    For example, if the privileged account is r_service (created with useradd -om -u0 -g0 -d /root/service -s /bin/bash r_service) the call to that privileged command from a non-privileged account would be something like:

    $ ssh -i ~/.ssh/privileged_command [email protected]
    

    This way you will grant your users to execute that privileged command without compromising the security model.

    very interesting article

    The article was a good read +1

    Article misses 1) capturing `su` isn't different than capturing user password (just record the whole session); 2) access to a dev server as root isn't usually that useful (the critical data is shared resources); 3) in the dev server instance, I now have your private key without capturing your password you're using `ssh` from the same host to itself

    @JohnMoser, first of all, I think it is a wrong place to discuss the article, but I will briefly address your comment. 1) the article does not promote `su` and actually specifically says that it is no different from any other escalation; 2) and 3) - I think you missed the point. The proposal is to use an ephemeral key that has no value outside the host - even if it is stolen you can't leverage it unless you also has access to the account it was installed on. And if you have such access, then you already possess enough access to execute the call no matter how it was configured.

  • In my opinion, sudo for server admins is a bit overkill. If people log in, and they have root access (through some mechanism), they usually do maintaining tasks, where they will use sudo for >90% of the time. The purpose of sudo is to give accounts that are logged in some separation between untrusted applications and admin-like tasks, and make users aware they are changing the system (and have to watch out). For desktops, both applies. For servers however, most tasks will already require sudo, so both points get weak. sudo has some advantages with its fine-grained control, but to rely on its logging capabilities, you would need to set up remote logging, as otherwise people with root access can falsify past logs.

    Is there some security caveat I'm missing why this is not more widely adopted?

    pam_ssh_agent_auth requires ssh-agent forwarding in order to work over ssh. Then however its a bit pointless to use it, as then every (non-cgrouped) process running under the user's account could use the agent to execute commands as root. This enables every such process to run sudo which is precisely what the NOPASSWORD parameter does.

    My advice would be to have NOPASSWORD and be happy with it. It still gives people the feeling "now I change the system", but it doesn't have annoying passwords.

    If you still wanted to have passwords, you could e-mail them in clear, but require them to be changed the first time they get used. An attacker would need both the email and the user's private key to be successful. If they already have access to the private key, they could do some nasty things to .bashrc and get access the next time the user gets sudo with a password that the attacker doesn't need to know.

    `sudo` for servers is not an overkill when you must restart some service. And I can't hardcode specific command into `sudoers` due to issues beyond the scope of this question. Can you please elaborate on your 2nd paragraph? ssh-agent is running on the client's system, not server, and only when connected.

    From the man page: *the ssh-agent listening to `SSH_AUTH_SOCK` can either be local, or forwarded.* With 'local' the man page means 'running on the server'.

    I fail to see how using pam_ssh_agent_auth improves upon using sudo NOPASSWD either. If you you want to circumvent having to enter the sudo password repeatedly you could just extend the sudo timeout.

  • SSH authentication and security privileges are two different things, hence no point of having it as a default feature. However, it opens one more vector for attack(there is a CVE) and from my point of view makes it easier for users to overuse it, which is bad.

    On the topic of passwords, one way is to send a short-lived password to the user and require him/her to change it after initial login. Or allow them to "register" their account and only work with the hash. There is pros and cons in every approach, but a good place for inspiration is the commercial and free Shell account services.

  • You can create a password for the user, then encrypt the password using the user's ssh public key (which you already have), then send the user the encrypted password. Then, the user can decrypt the encrypted password using their ssh private key.

    See https://superuser.com/questions/576506/how-to-use-ssh-rsa-public-key-to-encrypt-a-text for how to encrypt/decrypt messages using ssh public/private keys.

License under CC-BY-SA with attribution


Content dated before 7/24/2021 11:53 AM