Google Authenticator For SSH

Discussion in 'Linux Security' started by Eric Hansen, Sep 11, 2013.

  1. Eric Hansen

    Eric Hansen Moderator Staff Writer

    Messages:
    124
    Likes Received:
    87
    Trophy Points:
    28
    For a long time its been stated that to secure your Linux machine you should change the default port number of services such as SSH and your favorite web server. While this is still a good step to take if you’re overly paranoid (or tired of port scanning alerts…), there’s got to be better ways to do this, right? Well, you would be correct! Here we will secure SSH with Google Authenticator to create a two-factor authentication method.

    What Is Needed
    I’ll be doing this on an Ubuntu system, if you’re not then please make the appropriate adjustments. We’ll be also starting from scratch and right now you should be able to SSH to the server (if not please make sure you can if you’re going to be following along).

    I’ll be doing this as root because it’ll be needed later on and the machine is segregated from the Internet. Keep this mind if you’re not jumping right into root (which isn’t really advisable anyways, I’m doing it for sake of ease).

    Lastly, you need the Google Authenticator app installed on your phone. Its available for Android and iPhone for sure, check your software store for availability.

    Installing the Necessities
    Before we make the magic happen we’ll need to be installing some software. Here’s a list of what’s needed on Ubuntu 13.04:
    Code:
    root@sshtest:/usr/local/src# apt-get install build-essential make libpam0g-dev libpam0g
    We need to install build-essential because we’ll be compiling the authenticator from source (its available in the package manager but is missing PAM support). make is used to do the compiling, linking and installing. Since we’re making a PAM module we need the development libraries (libpam0g-dev) and I prefer to include the regular library as well just for safe measure. Sometimes it's needed, others not.


    After that we’ll cd to /usr/local/src and get to the grunt work:
    Code:
    root@sshtest:/usr/local/src# cd /usr/local/src
    root@sshtest:/usr/local/src# wget https://google-authenticator.googlecode.com/files/libpam-google-authenticator-1.0-source.tar.bz2 -O googleauth.tar.bz2
    root@sshtest:/usr/local/src# tar -xf googleauth.tar.bz2 && rm googleauth.tar.bz2
    root@sshtest:/usr/local/src# cd libpam-google-authenticator-1.0/
    Modifying the Source
    This is the reason why we downloaded and are compiling from source: we need PAM support. Ironically, it might work for some systems, but for Ubuntu we need to specify linking to the PAM module. While this isn’t difficult it is needed. Open up the “Makefile” file in your favorite editor and above the line “VERSION := 1.0” put the following:
    Code:
    LDFLAGS="-lpam"
    Now save and exit.

    Compiling and Installing
    Now, typically compiling the source is slightly more in-depth than this but thankfully Google made it super easy! Run make:
    Code:
    root@sshtest:/usr/local/src/libpam-google-authenticator-1.0# make
    gcc --std=gnu99 -Wall -O2 -g -fPIC -c  -fvisibility=hidden  -o google-authenticator.o google-authenticator.c
    gcc --std=gnu99 -Wall -O2 -g -fPIC -c  -fvisibility=hidden  -o base32.o base32.c
    gcc --std=gnu99 -Wall -O2 -g -fPIC -c  -fvisibility=hidden  -o hmac.o hmac.c
    gcc --std=gnu99 -Wall -O2 -g -fPIC -c  -fvisibility=hidden  -o sha1.o sha1.c
    gcc -g  "-lpam" -o google-authenticator google-authenticator.o base32.o hmac.o sha1.o  -ldl
    gcc --std=gnu99 -Wall -O2 -g -fPIC -c  -fvisibility=hidden  -o pam_google_authenticator.o pam_google_authenticator.c
    gcc -shared -g  "-lpam" -o pam_google_authenticator.so pam_google_authenticator.o base32.o hmac.o sha1.o -lpam
    gcc --std=gnu99 -Wall -O2 -g -fPIC -c  -fvisibility=hidden  -o demo.o demo.c
    gcc -DDEMO --std=gnu99 -Wall -O2 -g -fPIC -c  -fvisibility=hidden  -o pam_google_authenticator_demo.o pam_google_authenticator.c
    gcc -g  "-lpam" -rdynamic -o demo demo.o pam_google_authenticator_demo.o base32.o hmac.o sha1.o  -ldl
    gcc -DTESTING --std=gnu99 -Wall -O2 -g -fPIC -c  -fvisibility=hidden  \
    -o pam_google_authenticator_testing.o pam_google_authenticator.c
    gcc -shared -g  "-lpam" -o pam_google_authenticator_testing.so pam_google_authenticator_testing.o base32.o hmac.o sha1.o -lpam
    gcc --std=gnu99 -Wall -O2 -g -fPIC -c  -fvisibility=hidden  -o pam_google_authenticator_unittest.o pam_google_authenticator_unittest.c
    gcc -g  "-lpam" -rdynamic -o pam_google_authenticator_unittest pam_google_authenticator_unittest.o base32.o hmac.o sha1.o -lc  -ldl
    The important thing to make note of is the last few lines where it has “-lpam”, which states that the PAM library is being compiling with it, thus making it PAM module usable. Next, we need to install it, which is just as easy:
    Code:
    root@sshtest:/usr/local/src/libpam-google-authenticator-1.0# make install
    Set Up Google Authenticator
    Before we go into configuring SSH lets first set up Google Authenticator. Simply run the “google-authenticator” program as the user you wish to log in with via SSH. You’ll be prompted with a few questions.
    Code:
    Do you want authentication tokens to be time-based (y/n)
    Tokens can either be time-based or one-time used. Time-based is the more secure method in that it changes every 30 seconds, whereas one-time means that the token doesn’t change until its been used. For various reasons we’ll be using time-based tokens.
    Code:
    Do you want to disallow multiple uses of the same authentication
    token? This restricts you to one login about every 30s, but it increases
    your chances to notice or even prevent man-in-the-middle attacks (y/n)
    Expanding on what was just said, basically once the token is used by the user it won’t allow you to use it again. Given there is roughly 10^6 = 1,000,000 possibilities, I think its a safe bet we don’t have to worry about issues if we want to be a bit more secure. Fun fact: while the last sentence doesn’t directly have a relation to this, its still fun to point out and address just how secure we are in that there’s a 1 in 1,000,000 (0.000001%) chance that the same token will be chosen in a 30 second window.
    Code:
    By default, tokens are good for 30 seconds and in order to compensate for
    possible time-skew between the client and the server, we allow an extra
    token before and after the current time. If you experience problems with poor
    time synchronization, you can increase the window from its default
    size of 1:30min to about 4min. Do you want to do so (y/n)
    I chose no, but since we are using time-based tokens it might be beneficial to enable. Side note if you wish to change this in the future edit ~/.google_authenticator and add the following line just above “DISALLOW_REUSE”:
    Code:
    " WINDOW_SIZE 17
    I don’t know how to edit the variable to change it, but that is the difference between enabling and disabling that option.
    Code:
    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)
    I enabled, because I know how tricky and persistent “hackers” can be.

    Now, you’ll notice before the questions were asked you got something like this:
    Code:
    https://www.google.com/chart?chs=200x200&chld=M|0&cht=qr&chl=otpauth://totp/root@sshtest%3Fsecret%3D3AKID...GJTP
    Your new secret key is: 3AKID...GJTP
    Your verification code is 46...73
    Your emergency scratch codes are:
    <snipped numbers>
    Copy and paste the URL into your browser and scan the QR code that pops up (please use your own specific URL as mine won’t work for you). If you can’t scan the barcode then you can enter the information manually with the secret key and verification code.

    Configure PAM
    Next few steps are going to be quick and easy, so lets first set up SSH’s PAM. Edit the file /etc/pam.d/sshd and add the following line to the end:
    Code:
    auth required pam_google_authenticator.so
    This states that in order for authentication to succeed the user must have Google Authenticator tied to their account. Keep this in mind for later.

    Configure SSH
    Another quick edit, open up /etc/ssh/sshd_config and edit this line:
    Code:
    ChallengeResponseAuthentication no
    Change the “no” to “yes”. This enables use of PAM modules for authentication purposes.

    Now restart SSH:
    Code:
    service ssh restart
    Testing
    Lets test a user who we didn’t set Google Authenticator up with. Lets say this user’s name is “bob”:
    Code:
    root@sshtest:/usr/local/src/libpam-google-authenticator-1.0# ssh bob@localhost
    Password:
    Password:
    Replace “localhost” with the hostname or IP of the server you installed Google Authenticator and SSH to. If you notice, I typed in the user’s password (masked, but I did) and it bounced back wanting the password again. That’s because of that “required” line we put into the /etc/pam.d/ssh file.

    Now, since I set this up with root we’ll try to log in as root:
    Code:
    root@sshtest:/usr/local/src/libpam-google-authenticator-1.0# ssh root@localhost
    Password:
    Verification code:
    
    Welcome to Ubuntu 13.04 (GNU/Linux 3.8.0-19-generic x86_64)
    
    * Documentation:  https://help.ubuntu.com/
    
    Last login: Wed Sep 11 23:55:22 2013 from localhost
    root@sshtest:~# who
    ubuntu  lxc/tty1  2013-09-11 22:49
    root  pts/0  2013-09-11 23:58 (localhost)
    root@sshtest:~#
    It asked me for the password and the token (“verification code”) in the app on my phone, then it verified me and logged me in. I ran the “who” command to show I was logged in via SSH (the last line).

    Attached Files:

    • slide.jpg
      slide.jpg
      File size:
      37.2 KB
      Views:
      100,003
    ryanvade and Rob like this.
  2. ryanvade

    ryanvade Administrator Staff Member Staff Writer

    Messages:
    1,391
    Likes Received:
    454
    Trophy Points:
    83
    What if you have a dumb phone??
    Rob likes this.
  3. Eric Hansen

    Eric Hansen Moderator Staff Writer

    Messages:
    124
    Likes Received:
    87
    Trophy Points:
    28
    There's apps that try to mimick the functionality (as well as I'm sure some scripts) but unfortunately I can't recommend any. As much as it does suck most IT is geared towards the assumption you have a smart phone.

Share This Page