Open curbengh opened 3 years ago
As far as I can tell your problem is caused by this line in sshd.nix. Specifically it disables unixAuth if password authentication is disabled. You can override it with:
security.pam.services.sshd.unixAuth = lib.mkForce true;
(You'll need to add lib
to { config, pkgs, ... }:
at the beginning of your configuration.nix if it's not in there yet)
With that I get password authentication + TOTP. I'm not sure why it's still asking me for a password, it seems to be doing pubkey + password + TOTP, but this is also the first time I've used google-authenticator with PAM.
I'm not sure why it's still asking me for a password
My guess is unixAuth = password prompt. Enabling googleAuthenticator also enables unixAuth (pam.nix).
A workaround can be,
- unixAuth = cfg.passwordAuthentication;
+ unixAuth = cfg.passwordAuthentication || config.security.pam.services.sshd.googleAuthenticator.enable;
This may cause confusion because user expects no password prompt when ssh's passwordAuthentication is disabled, but password prompt is still there due to PAM/unixAuth.
We can clarify by adding a note to security.pam.services.
This also affects other pam services like duoSecurity
and gnupg
.
Another approach is to separate those pam services from unixAuth.
Looks like the dependency cannot be removed.
I replicated the ssh config on Ubuntu Server 20.04.2
# /etc/ssh/sshd_config
PasswordAuthentication no
Match user curben
AuthenticationMethods publickey,keyboard-interactive
It resulted in similar behavior; it prompts for publickey + password + OTP. So, I think this behavior is expected.
I still feel googleAuthenticator should take precedence over ssh's passwordAuthentication.
security.pam.services = {
sshd.googleAuthenticator.enable = true;
};
services.openssh = {
passwordAuthentication = false;
}
I think ideally we'd have an option in the openssh module to enable the google authenticator, which could then set the rest correctly. But I'm not too involved with nixpkgs, so I'm not sure if that's something that'd be wanted in general.
I marked this as stale due to inactivity. → More info
This issue has been mentioned on NixOS Discourse. There might be relevant details there:
https://discourse.nixos.org/t/setting-up-google-authenticator-for-ssh/36931/3
This is still a valid issue. If you want to enable Google Authenticator without passwords (i.e. ssh key + 2FA) it seems that you have to format the whole config file as text. For example this seems to mostly work:
security.pam.services = {
sshd.text = ''
account required pam_unix.so # unix (order 10900)
auth required ${pkgs.google-authenticator}/lib/security/pam_google_authenticator.so nullok no_increment_hotp # google_authenticator (order 12500)
auth sufficient pam_permit.so
session required pam_env.so conffile=/etc/pam/environment readenv=0 # env (order 10100)
session required pam_unix.so # unix (order 10200)
session required pam_loginuid.so # loginuid (order 10300)
session optional ${pkgs.systemd}/lib/security/pam_systemd.so # systemd (order 12000)
'';
};
You also need some settings on the OpenSSH module:
services.openssh = {
settings = {
PasswordAuthentication = false;
KbdInteractiveAuthentication = true;
AuthenticationMethods = "publickey,keyboard-interactive";
PermitRootLogin = "yes"; # disable "prohibit-password", which breaks PAM
};
};
@pdg137 This works for me as well in my config, thanks !
For the other people that comes across this thread, this is what I believe this does:
# Check for the client's public key
account required pam_unix.so # unix (order 10900)
# Actually check for the 2FA code.
# "nullok": accept session if .google_authenticator doesn't exist
# "no_increment_hotp": make sure the counter isn't incremented for failed attempts.
auth required ${pkgs.google-authenticator}/lib/security/pam_google_authenticator.so nullok no_increment_hotp # google_authenticator (order 12500)
# If .google_authenticator isn't present, you can still let them through
auth sufficient pam_permit.so
# Load the environment variables for the new ssh session
session required pam_env.so conffile=/etc/pam/environment readenv=0 # env (order 10100)
# Logs when a user logins or leave the system.
session required pam_unix.so # unix (order 10200)
# Record user's login uid to the process attribute
session required pam_loginuid.so # loginuid (order 10300)
# Register user sessions in the systemd login manager
session optional ${pkgs.systemd}/lib/security/pam_systemd.so # systemd (order 12000)
Let me know if I got anything wrong.
@curbengh is this still an issue ?
I think ideally we'd have an option in the openssh module to enable the google authenticator, which could then set the rest correctly. But I'm not too involved with nixpkgs, so I'm not sure if that's something that'd be wanted in general.
We can open another issue for that but I think this one is solved.
Describe the bug Enabling Google Authenticator TOTP via pam services for sshd has no effect.
Possibly related: https://github.com/NixOS/nixpkgs/issues/18503
To Reproduce
Setup googleAuthenticator token
Expected behavior
/etc/pam.d/sshd
should havepam_google_authenticator.so
.Metadata