14

Users logged in on my Linux server should be able to ssh to a specific remote machine with a default account. The authentication on the remote machine uses public key, so on the server the corresponding private key is available.

I don't want the server users to actually be able to read the private key. Basically, the fact that they have access to the server allows them the ssh right, and removing them from the server should also disallow connection to the remote machine.

How can I allow users to open an ssh connection without giving them read access to the private key?

My thoughts so far: obviously the ssh executable must be able to read the private key, so it must run under another user on the server which has those right. Once the ssh connection is established, I can then "forward" it to the user so that he can enter commands and interact with the remote machine.

  • Is this a good approach?
  • How should I implement the forward?
  • How can the user initiate the connection (that is, the execution of the ssh by the user which has read rights on the key)?
  • Is there a security loophole? - if the users can execute an ssh as another user, can they then do everything that other user could (including, reading the private key)?
  • It seems to be a duplicate of stackoverflow.com/questions/9286622/protecting-ssh-keys – wenzul Oct 23 '14 at 10:05
  • 1
    Configure the remote server to accept connections with that key only from the IP of your server ? That way even if they steal the key they can't do anything. – user186340 Oct 23 '14 at 16:10
  • @AndréDaniel well perhaps they could log into another, completely unrelated computer which is also configured to accept passwordless logins from the server. That's the only reason I can think of to have a setup like this; if it's not that, I'm rather curious as to what it is. (Not that it matters, really.) – David Z Oct 23 '14 at 23:44
  • @DavidZ I don't really understand... the key shouldn't be trusted anywhere but on the target server assuming the IP matches the one of the first server (to where the users connect to). – user186340 Oct 23 '14 at 23:45
  • 2
    If you need to lock it down in this way, I assume you've taken measures to disallow users from adding new public keys to the ~/.ssh/authorized_keys file? – mpontillo Oct 24 '14 at 0:52
31

That is one of the reasons sudo exists. Simply allow your users to run 1 single command with only the pre-authorized command-line options and most obvious circumventions are solved. e.g.

#/etc/sudoers
%users ALL = (some_uid) NOPASSWD: /usr/bin/ssh -i /home/some_uid/.ssh/remote-host.key username@remotehost

sets up sudo so all members of the group users can run the ssh command as user some_uid without entering their own password (or that of the some_uid account) when they run:

sudo -u some_uid /usr/bin/ssh -i /home/some_uid/.ssh/remote-host.key username@remotehost

Remove the NOPASSWD: option to force that users enter their own passwords before logging in to the remote-host.
Possibly set up an alias or wrapper script as a convenience for your users because sudo is quite picky about using the correct arguments.

| improve this answer | |
  • Works like a charm. This should also be the recommended answer for the duplicate mentioned by wenzul. – Philipp Oct 23 '14 at 11:12
10

This seems like a good use case for host-based authentication. This is a method of authentication where SSH does not use an individual user's key on the local machine (in this case, your server) to authenticate; instead, it uses the host's private key, the one stored in /etc/ssh/ and which is only readable by root.

To set this up, you'll need to create a file named .shosts on the remote machine, in the home directory of the user you want people to log in as (not in ~/.ssh). The file should have the contents

server-hostname +

where server-hostname is the name of your server, and + is a literal plus sign that serves as a wildcard meaning "any user".

You'll also need to ensure that the remote machine can verify the server's host key, which means the server's host key needs to be listed in either /etc/ssh/ssh_known_hosts or ~/.ssh/known_hosts on the remote machine. If this is not already the case, you can set it up by logging into the remote machine and running

ssh-keyscan server-hostname >> /etc/ssh/ssh_known/hosts

Once you've set up these steps, you can delete the private key on the server entirely, if you don't need it for anything else. (And if you do, you can always set it to be only readable by root or something.)

You can also easily do things like allowing or denying certain users access to the remote machine. See the man pages of ssh and hosts.equiv for details.

One problem with this setup is that users who log into the remote machine can modify .shosts. There's nothing they can do that would allow them to log in to the remote machine as a different user, but they could cut off their own or others' access to the remote machine. If this is a concern, you might be able to make .shosts only writable by root or something - I'm not sure if this works, but you could try it and see. (Other methods like the one with sudo are susceptible to the same risk, since a user could always delete ~/.ssh/authorized_keys.)

| improve this answer | |
  • +1; I think this option provides good flexibility, in case the user needs to use SSH features other than the terminal, such as port forwarding, secure copy, etc. Even an alternate SSH client should work. The sudo option could be better for a locked-down environment, though... – mpontillo Oct 24 '14 at 0:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.