I'm sketching on a way to harden and automate server login using ssh-keygen with certificates where certificates, valid for e.g. 1 week, are generated on a trusted server and can be used to both create the server-user and logging in. The scheme could easily be extended to support different roles, such as deployment, backup, sudo, etc.
My question is: would you say that proposed method below is secure and reliable?
In short, the steps would be:
- User logs in to web-page
- User provides SSH public key
- Server generate two certificates, one for root to create the user and the other for logging in
- User downloads the generated certificates to home-folder on client machine
- First time accessing the server, the user would use the user-creation-certificate. Upon connection (as root), the server will create the user and then log out.
- In normal usage, the login-certificate will be used. This certificate will need refresh once a week.
- If a user suspects certificate loss, then the user himself or an admin can update the key revocation list from the issuing server
The most significant steps involved would be:
- Create a user-signing key stored on a secure server. The Server could be protected by oauth2_proxy for authentication and letsencrypt for SSL. By using oauth2_proxy, the user identity becomes known and authenticated. Authorization could be by group-memberships checked by oauth2_proxy.
- All servers be provisioned to accept users by signature of the key from step 1. (Set TrustedUserCAKeys in /etc/ssh/sshd_config) Password based login can be removed, and the key revocation list should be continuously synchronized.
- When a user requests a create-user certificate, the user will provide his public key, and the server will create the certificate and provide to user. The identity is saved to provide key-revocation capabilities if needed.
ssh-keygen -s ca-private-keyfile -I 'create user username valid NN' -V +30d -n root -O clear -O force-command='useradd username' user-provided-public-key
- When a user requests a login certificate, the user will provide his public key, and the server will create the certificate and provide to user. (Again, saving identity for possible key-revocation)
ssh-keygen -s ca-private-keyfile -I 'user@org valid nn' -V +7d -n username user-provided-public-key
- It would be possible and recommended to add a two-factor verification step to at least the signature generation steps.
- The user should, for convenience, have two SSH key pairs to let ssh distinguish between the desired certificates.
- It would be easy to issue more types of access by changing the force-command, like getting sudo access: -n root -O force-command 'adduser username sudo' with the added benefit of users getting to choose when to invoke their rights and on what hosts.
- To provide more granular access, certificates can be issued with limits to host-names, or different signing key-paris can be installed on different classes of hosts.
- To provide some protection against an attacker reading the files on the issuing server (e.g. getting access to backup), the SSH key-pair could be encrypted on the server. The users who need to issue certificates would have to know the pass phrase and provide it on each signature request.
I have found a similar setup where colleagues sign each others signature requests: https://github.com/cloudtools/ssh-cert-authority but I would prefer a setup like the above.