0

I'm managing a several servers which are in Linux. I will have others administrators who will need access to those servers in order to administrate them. So I would like to have a sort of ssh bastion which will transparently connect users to these servers via ssh from their laptop which are in windows. I don’t want to copy the users public keys on my remote servers. I would like to have all the public keys of remote servers in a repository on the ssh bastion. Is this possible?

If yes, what are the configurations do to to have this?

A J
  • 11,367
  • 17
  • 44
  • 59
  • What do you mean by "ssh bastion"? The most secure approach would indeed be to put the users public keys on the server, anything else would be a security nightmare (from a sysadmin POV). – Jan Sep 01 '14 at 09:31
  • Are the user's certificates signed by your own CA? In that case, the servers could validate the certificates, no need to predistribute. You would still have to manage users, though. – noleti Sep 01 '14 at 10:39
  • I mean by "ssh bastion" a sorte of proxy ssh which will be the intermediate between remote servers and hosts who will will to ssh to the remote servers – Diarra Diagne Sep 01 '14 at 11:56

1 Answers1

0

I have an alternative: keep all your clients' SSH keys on one server, and the configure your servers to ask that server for authorized SSH keys. This can be done using the AuthorizedKeysCommand directive in sshd_config.

From the manpage:

 AuthorizedKeysCommand
         Specifies a program to be used to look up the user's public keys.
         The program must be owned by root and not writable by group or
         others.  It will be invoked with a single argument of the
         username being authenticated, and should produce on standard
         output zero or more lines of authorized_keys output (see
         AUTHORIZED_KEYS in sshd(8)).  If a key supplied by
         AuthorizedKeysCommand does not successfully authenticate and
         authorize the user then public key authentication continues using
         the usual AuthorizedKeysFile files.  By default, no
         AuthorizedKeysCommand is run.

 AuthorizedKeysCommandUser
         Specifies the user under whose account the AuthorizedKeysCommand
         is run.  It is recommended to use a dedicated user that has no
         other role on the host than running authorized keys commands.

The command can be simply a script with:

#! /bin/bash
ssh bastion "cat $HOSTNAME/$1/authorized_keys"

Here the server's AuthorizedKeysCommandUser has a key-based (passwordless) login, and simply outputs the authorized_keys file for the hostname/user combination from the keyserver. Another way would be:

#! /bin/bash
wget --post-data="host=$HOSTNAME&user=$1" https://bastion

where the keyserver runs an HTTP server which returns a set of authorized keys based on the hostname and user. A one-file PHP or Python script would be sufficient to process such a form. An advantage would be that using a database server like PostgreSQL or MySQL would be easier. (Of course, you don't need to use the hostname.)

This method is most commonly used with LDAP, I think. There are a couple of scripts for LDAP: http://www.sysadmin.org.au/index.php/2012/12/authorizedkeyscommand/ and http://blather.michaelwlucas.com/archives/1562 that you can look at.


To set this up, in the servers, create a user (call it authkeys) to run the the command (or you can use the nobody user):

adduser --disabled-password --disabled-login --shell /usr/sbin/nologin authkeys

On the intermediate server (call it bastion), a slightly different command: we will set shell to /bin/bash for convenience (but you can limit that):

adduser --disabled-password --disabled-login --shell /bin/bash authkeys

This very unprivileged user will be used for the sole purpose of connecting to the intermediate server and getting the keys. Create a script that this user will run:

sudo tee -a /usr/local/bin/get_keys.sh <<"EOF"
#! /bin/bash
ssh bastion "cat $HOSTNAME/$1/*.pub 2>/dev/null"
EOF
sudo chmod 0755 /usr/local/bin/get_keys.sh

Edit the SSH server configuration /etc/ssh/sshd_config on the servers and add:

AuthorizedKeysCommand /usr/local/bin/get_keys.sh
AuthorizedKeysCommandUser authkeys

And restart the SSH servers:

sudo service ssh restart

Then, for simplicity, generate an SSH key pair and use the same keypair on all servers for authkeys user:

# On one server
ssh-keygen -N '' -f id_rsa

On all the other servers, copy these id_rsa and id_rsa.pub files created by the above command, then add them to the authkeys user's SSH configuration:

cp id_rsa* ~authkeys/.ssh/
sudo chown authkeys:authkeys .ssh -R
sudo chmod 0700 .ssh
chmod 0600 .ssh/*

On the intermediate server, add this key to the authorized_keys list:

cat id_rsa.pub >> ~authkeys/.ssh/authorized_keys

Finally, on the intermediate serves, make a directory structure following the script we used above:

mkdir -p ~authkeys/some_host/some_login

Then add the authorized keys of your administrators to the directory:

echo "some_key" > ~authkeys/some_host/some_login/admin1.pub
echo "some_other_key" > ~authkeys/some_host/some_login/admin2.pub

Chown everything to root (or your user - but anything other than authkeys):

chown root:root ~authkeys/* -R
chmod o=rx ~authkeys/*/* 
chmod o=r ~authkeys/*/*/*.pub -R

Use hostnames or IPs, but remember to change the script to use the appropriate value.

muru
  • 197,895
  • 55
  • 485
  • 740
  • Hi,Thanks for your answer. I think your method is great. So, in my "intermediate" server, I have I lot of users account, and each user has his own key pair. I would be ok to take the first option with the ssh bastion "cat $HOSTNAME/$1/authorized_keys". But whaat are the exact configurations in remote servers side and the intermediate? – Diarra Diagne Sep 01 '14 at 14:37
  • @DiarraDiagne perhaps I should clarify: your users would still be connecting to the servers directly. – muru Sep 01 '14 at 14:38
  • yes that will be the goal – Diarra Diagne Sep 01 '14 at 14:57
  • I would like for example to be connected to a remote server only by typing ssh login@Ip_server – Diarra Diagne Sep 01 '14 at 15:17
  • @DiarraDiagne I have updated the answer with instructions. – muru Sep 01 '14 at 15:41
  • .Thanks a lot for your answers. Let me try it and update you back – Diarra Diagne Sep 02 '14 at 08:42
  • But where do I have to add the following script? on remote servers? on the intermediate? or in both of them sudo tee -a /usr/local/bin/get_keys.sh <<"EOF" #! /bin/bash ssh bastion "cat $HOSTNAME/$1/*.pub 2>/dev/null" EOF sudo chmod 0755 /usr/local/bin/get_keys.sh – Diarra Diagne Sep 02 '14 at 09:27
  • @DiarraDiagne Since that creates the script to be run as the AuthorizedKeysCommand, it should be in the remote servers. – muru Sep 02 '14 at 09:29
  • I tried your suggestions, but finally, It will be the same as putting the public keys of users in different remote servers in order to have direct connection. Ideally, I would like to have all the remote servers public keys in the intermediate server instead of having users public keys on it – Diarra Diagne Sep 02 '14 at 13:29
  • Do you have any idea on it? – Diarra Diagne Sep 03 '14 at 12:44