System Administration & Network Administration
ssh ssh-keys
Updated Sun, 28 Aug 2022 07:48:18 GMT

How to enable ssh for supporters with intelligent key management?


My situation is the following:

  • Am having a lot of customers in a VPN network.
  • Each supporter is having a computer which is also in the VPN.
  • Each supporter should be able to log in into all systems via ssh.
  • If a supporter leaves the company, he should not be able to log into the clients anymore

I thought about the following solutions so far:

  • We could use the same password on all clients - but that's obviously a bad idea.
  • We could store the public key of each supporter on all systems - but that's hard to maintain.
  • We could setup a Proxy server to which a supporter is connecting first and which is then able to log-in to the clients e.g. by a key-pair - but the server might get a lot of traffic then

My question:

Is there a "best practise" or "standard solution" for that case? Maybe a Tool I don't know? I feel like I definitely overlook something.




Solution

Generally you want to be able to make individual people accountable for their actions and to be able to revoke their personal access when their role changes or they leave the company. You don't want to have to do more than revoke their personal credentials.

Thus you want to avoid shared credentials as much as possible.

(Because it is really inconvenient when the default admin password, the one that everybody knows and uses all the time, must be changed because of a leaver. You might overlook one or more systems when resetting that password and more often than not, that default password is never changed at all.)

Thus ideally all systems that need to be managed are configured to use a central identity store (such as for instance LDAP, Active Directory etc.).

In that central identity store each person has a personal account for which they themselves only know the password. For additional rights they get one or more additional group memberships and from those derive group based privileges (sudo and other rights). Thus nobody needs the admin password.

Maybe you want avoid password authentication for ssh logins and want to use ssh public key authentication.

OpenSSH has little know feature called the AuthorizedKeysCommand which allows you to configure your sshd daemon to run a specific help program to retrieve the public keys that you would normally store and deploy in a users /.ssh/authorized_keys file.

That helper program can for example query a database server, a LDAP server or whatever else might be suitable for your purposes.

That avoids the common alternatives of using configuration management tooling to deploy keys to /.ssh/authorized_keys files or to mount network shares with (administrator/user) home directories containing /.ssh/authorized_keys files.

Also revoking access everywhere becomes then as simple as removing the public key from that central server.

See this Q&A for an LDAP example, useful when you also have LDAP already as the central identity store for accounts : SSH key authentication using LDAP


As a slightly simplified derivation you can omit integrating with the central identity store with personal accounts for all people and group based access rights.

This gives you a shared account, where all your support staff can log in with their personal private key, after their public key has been centrally registered and enabled. Remove their public ssh key and their access will be revoked.

  • Create single local account on every server that needs to be managed. For example serverfault-support.

  • Set up a suitable sudo policy for that account with the NOPASSWD option. Maybe something a bit more strict than this though:

    serverfault-support  ALL = NOPASSWD: AL
    
  • Collect the public ssh keys of all your staff in a central location.

  • Generate (whenever staff changes occur) a list of those public_keys in the required authorized keys format.

    ssh-ed25519 AAAAC3NzaB0x***...***== rob.smith@serverfault
    ssh-rsa AAAAB3NzaC1y***...***== rob.jones@serverfault
    

    Refinement: Consider adding additional public key options there as well, for example only allow those keys to be used from the IP-address range used in your VPN, rather than the internet at large.

    from="10.80.0.0/14" ssh-ed25519 AAAAC3NzaB0x***...***== rob.smith@serverfault
    from="10.80.0.0/14" ssh-rsa AAAAB3NzaC1y***...***== rob.jones@serverfault
    
  • Note that public keys are not particularly sensitive data so you publish them some place convenient like for example https://www.example.com/current_authorized_keys

    Refinement: rather than a static list, make that list dynamic with a little DB backend and a management portal. Then you can also limit the output to only show the public keys that for example match: a specific fingerprint and/or a particular remote user or more for improved security and performance. Consider for example attaching an expiry date to the public keys to require your staff to periodically generate a new key-pair for compliance.

  • On every server: set up a Match directive in the /etc/ssh/sshd_config to enable the AuthorizedKeysCommand for the serverfault-support user:

    # /etc/ssh/sshd_config
    # ...
    Match User serverfault-support
          PasswordAuthentication no
          AuthorizedKeysCommand /usr/bin/curl https://www.example.com/current_authorized_keys?user=%u&fingerprint=%f
          AuthorizedKeysCommandUser nobody
          AuthorizedKeysFile /dev/null
    

    The option AuthorizedKeysFile /dev/null prevents users from successfully adding additional keys to the local ~/.ssh/authorized_keys and bypassing the AuthorizedKeysCommand.

  • You'll need to monitor access with the ssh finger print rather than the username that was used to log on

  • When I tested this on a system with SELinux enabled, some policy changes were required.