I recently came across a strange issue where the Google Authenticator we use suddenly stopped working. It worked fine on my dev environment, however the production environment consistently refused the code i gave it.
As you can imagine, this left me scratching my head as to what the problem could be. Two days prior there were no issues and there had been no code changes which could have possibly affected it.
I took to some live debugging on the server to try and figure out what was going on. Not ideal i know, but the problem couldn't be replicated locally.
Debugging the Google Authenticator
In a nut-shell, the Google Authenticator takes a code generated from the app which you input into your website which then generates a code based on the current time. (See this wiki article on TOTP for a much better explanation) If the two codes match, access is granted!
So my first port of call was to compare the code i was giving it vs the code it generated. As expected the two codes were different. At the time I had no idea how the authenticator actually worked. I had to look up a few things which lead me to believe it could be something to do with the web server's time being out of sync.
Checking the server time
I logged into the web server via ssh and issued the following command:
date > Fri Oct 27 14:31:04 UTC 2017
The "date" command literally does what it says, gives you the current server time and date. I compared the server time with the time given on https://time.is/UTC and it was at least 1 minute fast!
The next step was to check if the server was actively syncing the time, to do this, type the following in your terminal:
timedatectl > Local time: Fri 2017-10-27 14:41:33 UTC > Universal time: Fri 2017-10-27 14:41:33 UTC > RTC time: Fri 2017-10-27 14:41:33 > Time zone: Etc/UTC (UTC, +0000) > Network time on: yes > NTP synchronized: no > RTC in local TZ: no
The value you are looking for is NTP synchronized. If yours has a value of "no" there is a good chance that your server will be out of sync. However, fear not. The fix is really easy.
Synchronising Server Time
To make the NTP synchronized value equal "yes" we need to enable it. To do that, type the this command in your terminal:
sudo timedatectl set-ntp on
This can take up to a minute or so for the server to sync, so keep checking by running the the timedatectl command. However, if like me you might get an warning message about NTP package not being installed. You need to install it. Do so by pasting this command in:
sudo apt-get install ntp
This will pull down and install the NTP package for you. After installing, I didn't actually have to run the "sudo timedatectl set-ntp on" command. I checked the server time again by using "timedatectl" and NTP synchronized: yes appeared and my server's time was now synchronised!
I tried the Google Authenticator once more and it worked first time!
Finally on a server related note. I use Digital Ocean for my hosting. They offer SSD cloud based hosting at decent rates. If you sign up via this link, you'll get $10 free credit as well as any other Digital Ocean vouchers codes you can find too!