DefGuard / defguard

Zero-Trust access management with true WireGuard® 2FA/MFA
https://defguard.net
Other
1.62k stars 54 forks source link

SSH Client MFA #422

Open teon opened 1 year ago

teon commented 1 year ago

Would be great to enable SSH login MFA the flow would be:

  1. User authenticates using SSH keys from defguard (using defguard client ssh-auth command.
  2. That command detects if the user has MFA enabled - if so - requires the user to open a URL (print the URL on the terminal) and do MFA auth and after successful MFA - just then logs in the user
asteven commented 8 months ago

The problem with the approach you outlined above is that the user experience sucks. While working with ssh, you typically run a myriad of ssh/scp commands throughout the day, having to do some MFA dance for each and every connection is not usable. SSH master connection helps, but this may be limited by ssh server config (e.g. MaxSessions and friends). There are also many tools/scripts that wrap ssh in some way so you can not control how the ssh executable (or lib) is used.

An alternative is to implement a SSH certificate authority.

Then after a clients logs in to defguard, with MFA and all, defguard creates a ssh certificate for the clients ssh pub-key and writes it to disk and/or adds it to the clients ssh-agent. Optionally add some principals to the certificate and/or configure some of the ssh cert config settings (see man ssh-keygen).

The admin can then configure his ssh servers with TrustedUserCAKeys and optionally AuthorizedPrincipalsFile.

We've used a similar approach to implement RBAC for ssh connections.

For added security, add a configurable TTL to the certificate and ideally run the connections through a small custom ssh proxy which reaps connections after the TTL has expired. This enforces the client to redo the login/mfa dance to get a new certificate. ssh unfortunately does not offer a concept of connection TTL.

We have a full implementation of the above in python and have been using it for years internally. I found your project, defguard, while looking for a similar user experience for Wireguard.

I unfortunately do not speak any rust (yet ;). But if you're interested in the idea I can share notes, concepts and python code to get you started.

teon commented 8 months ago

@asteven i was also thinking about this - and my idea was not to even build own CA solution, but provide integration with StepCA (https://smallstep.com/docs/step-ca/) as it's open source.

Other approach is to also provide session tokens by Defguard - but that would require implementation of PAM modules (and not a ,client') - the upside is that we could incorporate rules for MFA to SSH (and session length when tokens are issued)...

asteven commented 8 months ago

I think creating your own ssh CA takes less time and code then to integrate with StepCA and to document how admins now have to setup and operate 2 services.

You can create a basic ssh CA POC in a 30 line shell script. The harder part is coming up with a data model for storing the metadata figuring out the UX and (G)UI. But as you already have a db, it's probably just another table.

Hooking into PAM is doable. But my experience has not been the best. e.g. we tested OPAs pam module We also use pam plugins from slurm and a few custom ones. PAM config is pretty distro specific and error prone.

From our experience a solution based on a ssh ca is much simpler and just works. A server can be configured by dropping a config file which uses TrustedUserCAKeys with AuthorizedPrincipalsCommand or AuthorizedPrincipalsFile in /etc/ssh/sshd_config.d/.

Our current solution works for linux, mac and windows clients without any changes. The only thing we are lacking is a nice GUI for non-technical users. That's why I've been looking towards DefGuard ;-) That and the fact that I'd like to add wireguard to the mix.