google / google-authenticator-libpam

Apache License 2.0
1.8k stars 286 forks source link

Unable to login to Server. Verification code is never valid. #56

Closed eusonlito closed 7 years ago

eusonlito commented 7 years ago

I have disabled time-based tokens to avoid token timeout problems. I never could to login into server using Public Keys + 2FA (password login not tested).

Installed from this github repository.

My config is:

# /etc/ssh/sshd_config
Port 22
Protocol 2

HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_dsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key

UsePrivilegeSeparation yes

KeyRegenerationInterval 3600
ServerKeyBits 1024

SyslogFacility AUTH
LogLevel DEBUG

LoginGraceTime 120
PermitRootLogin prohibit-password
StrictModes yes

RSAAuthentication yes
PubkeyAuthentication yes

AuthenticationMethods publickey,keyboard-interactive

IgnoreRhosts yes
RhostsRSAAuthentication no
HostbasedAuthentication no

PermitEmptyPasswords no

ChallengeResponseAuthentication yes

PasswordAuthentication no

X11Forwarding yes
X11DisplayOffset 10
PrintMotd no
PrintLastLog yes
TCPKeepAlive yes

AcceptEnv LANG LC_*

Subsystem sftp /usr/lib/openssh/sftp-server

UsePAM yes
# /etc/pam.d/sshd
account    required     pam_nologin.so

@include common-account

session [success=ok ignore=ignore module_unknown=ignore default=bad]        pam_selinux.so close

session    required     pam_loginuid.so
session    optional     pam_keyinit.so force revoke

@include common-session

session    optional     pam_motd.so  motd=/run/motd.dynamic
session    optional     pam_motd.so noupdate
session    required     pam_limits.so
session    required     pam_env.so user_readenv=1 envfile=/etc/default/locale

session [success=ok ignore=ignore module_unknown=ignore default=bad]        pam_selinux.so open

@include common-password

auth required /usr/local/lib/security/pam_google_authenticator.so debug no_increment_hotp

Current ~/.google_authenticator file:

$ cat .google_authenticator 
XXXXXXXXXXXXXXXXXXXXXXXXX
" RATE_LIMIT 3 30 1487083853
" WINDOW_SIZE 17
" HOTP_COUNTER 1
85643588
84843086
17384850
55980155
72039762

Google Authenticator APP:

CODE 574 642
TIMES 1

google-authenticator setup:

Do you want authentication tokens to be time-based (y/n) n

Do you want me to update your "/root/.google_authenticator" file? (y/n) y

By default, three tokens are valid at any one time.  This accounts for
generated-but-not-used tokens and failed login attempts. In order to
decrease the likelihood of synchronization problems, this window can be
increased from its default size of 3 to 17. Do you want to do so? (y/n) y

If the computer that you are logging into isn't hardened against brute-force
login attempts, you can enable rate-limiting for the authentication module.
By default, this limits attackers to no more than 3 login attempts every 30s.
Do you want to enable rate-limiting? (y/n) y

Code inserted 721690

Debug starting at line 1570:

      int pw_len = strlen(pw);
      int expected_len = mode & 1 ? 8 : 6;
      char ch;
log_message(LOG_INFO, pamh, "DEBUG: pw %s", pw);
log_message(LOG_INFO, pamh, "DEBUG: pw_len %d", pw_len);
log_message(LOG_INFO, pamh, "DEBUG: expected_len %d", expected_len);
log_message(LOG_INFO, pamh, "DEBUG: mode %d", mode);
      if (pw_len < expected_len ||
          // Verification are six digits starting with '0'..'9',
          // scratch codes are eight digits starting with '1'..'9'
          (ch = pw[pw_len - expected_len]) > '9' ||
          ch < (expected_len == 8 ? '1' : '0')) {
      invalid:
log_message(LOG_INFO, pamh, "DEBUG: INVALID");
        memset(pw, 0, pw_len);
        free(pw);
        pw = NULL;
        continue;
      }
log_message(LOG_INFO, pamh, "DEBUG: VALID");

Debug:

sshd(pam_google_authenticator)[2480]: debug: start of google_authenticator for "root"
sshd(pam_google_authenticator)[2480]: Secret file permissions are 0400. Allowed permissions are 0600
sshd(pam_google_authenticator)[2480]: debug: "/root/.google_authenticator" read
sshd(pam_google_authenticator)[2480]: debug: shared secret in "/root/.google_authenticator" processed
sshd[2128]: Postponed keyboard-interactive for root from XXX.XXX.XXX.XXX port 44988 ssh2: RSA XXX [preauth]
sshd(pam_google_authenticator)[2480]: DEBUG: pw #010#012#015IN
sshd(pam_google_authenticator)[2480]: DEBUG: pw_len 6
sshd(pam_google_authenticator)[2480]: DEBUG: expected_len 6
sshd(pam_google_authenticator)[2480]: DEBUG: mode 2
sshd(pam_google_authenticator)[2480]: DEBUG: INVALID
sshd(pam_google_authenticator)[2480]: DEBUG: pw #010#012#015IN
sshd(pam_google_authenticator)[2480]: DEBUG: pw_len 6
sshd(pam_google_authenticator)[2480]: DEBUG: expected_len 8
sshd(pam_google_authenticator)[2480]: DEBUG: mode 3
sshd(pam_google_authenticator)[2480]: DEBUG: INVALID
sshd(pam_google_authenticator)[2480]: Invalid verification code for root
sshd(pam_google_authenticator)[2480]: debug: "/root/.google_authenticator" written

Thanks :)

ThomasHabets commented 7 years ago

This may just be because you have PermitRootLogin prohibit-password.

Your password is IN and some presumably unprintable character, which is oddly specific.

Could you try replacing with PermitRootLogin yes and also try setting this up for a different user?

I'm thinking that OpenSSH probably disallows keyboard-interactive for root if prohibit-password.

ThomasHabets commented 7 years ago

If this is the problem, then the PAM module should log this special case password for easier future troubleshooting.

ThomasHabets commented 7 years ago

Yup, that looks like it. https://github.com/openssh/openssh-portable/blob/master/auth-pam.c#L862

eusonlito commented 7 years ago

Ok, let me try :)

eusonlito commented 7 years ago

Confirmed, with PermitRootLogin yes I can login :+1:

ThomasHabets commented 7 years ago

I've added a friendly log message that should make this much easier to debug next time.

eusonlito commented 7 years ago

Thanks!