• Skip to main content
  • Skip to footer

NetworkJutsu

Networking & Security Services | San Francisco Bay Area

  • Blog
  • Services
  • Testimonials
  • About
    • About Us
    • Terms of Use
    • Privacy Policy
  • Contact Us

2FA

What is multi-factor authentication (MFA)?

02/28/2019 By Andrew Roderos Leave a Comment

  • Share on Twitter Share on Twitter
  • Share on Facebook Share on Facebook
  • Share on LinkedIn Share on LinkedIn
  • Share on Reddit Share on Reddit
  • Share via Email Share via Email

What is MFA?

If you haven’t been living under the rock these past few years, you’ve probably heard of multi-factor authentication (MFA) or two-factor authentication (2FA) by now. In the last few years, MFA has gained enormous popularity in companies that are improving their cybersecurity posture.

Before we delve into MFA, lets define what is authentication. In simplest terms, it is a process to confirm if someone is in fact who they say they are.

A lot of people make mistakes that the combination of username and password is authentication. However, it is actually a combination of identification (username) and authentication (password). The username is used to claim an identity, while the password is used to verify the identity.

Authentication factors

There are three basic methods of authentication:

Type 1: Something you know – password, PIN, etc.
Type 2: Something you have – smart card, hardware token, smartphone, etc.
Type 3: Something you are or something you do – biometrics, signature, keystroke dynamics, etc.

Out of these three methods of authentication, Type 1 is the weakest and Type 3 being the strongest. Malicious actors, however, can still bypass some of the Type 3 authentication factors. For example, some fingerprint readers can easily be fooled by a duplicate fingerprint on a gummy bear candy1.

Single-factor authentication (SFA)

As the name implies, single-factor authentication only requires one method of authentication. For many years, accounts for our email, web, social media, etc. were protected by this single form of authentication.

For a time, passwords were enough to secure the accounts. However, as cybercriminals become more successful in stealing credentials, it became clear that passwords alone were no longer enough to protect accounts.

Multi-factor authentication (MFA)

As you might have guessed, multi-factor authentication requires at least two methods of authentication. It can be a combination of any two or perhaps all three of Type 1, 2, and 3.

The use of two methods of authentication is called two-factor authentication (2FA), which is a subset of MFA. 2FA is the most popular method that is currently available on a lot of websites, applications, etc.

The concept of multi-factor authentication is not new. In fact, you’ve probably been using it but didn’t realize that you were. If you’ve ever withdrawn money from an ATM, then you’ve used MFA.

Withdrawing from an ATM requires you to present two forms of authentication: something you know (PIN) and something you have (debit card). Satisfying these two requirements will give you access to withdraw money from your account – assuming you have sufficient funds.

Importance of MFA

52% of the users have reused the same passwords

Protecting accounts with passwords has been unsuccessful for many years. A lot of people use easily guessable passwords for their accounts and in some cases have them written down within an arm’s length. The reuse of passwords across multiple accounts is also common. In a Virginia Tech University paper, they found in a study that 52% of users have reused the same passwords or modified existing passwords instead of coming up with something new2. What’s worse is that these users are also using the same passwords for their personal and work-related accounts.

Related: WebAuthn: Moving to a passwordless world

Password reuse creates huge risks and undermines security for both individuals and businesses. Some organizations are starting to offer free password manager software to their employees to combat this issue. This is a way of potentially arming their employees with the ability to practice good security in both their personal and professional lives.

The use of a password manager helps immensely in improving password security. It allows users to create unique and strong passwords without memorizing them. In fact, a few weeks ago, there was a data dump of 2.2 billion accounts3. Stolen credentials from personal accounts could be used to try and compromise business accounts as well.

81% of hacking-related breaches leveraged either stolen or weak passwords

There have been many instances where cybercriminals successfully acquired account credentials. In fact, according to Verizon 2017 DBIR, 81% of hacking-related breaches leveraged either stolen or weak passwords4. Reducing this number by implementing MFA solutions should be one of the top priorities of companies.

Common MFA methods

There are many approaches to MFA that companies take. Unfortunately, some of the approaches are weaker than others. We’re going to examine the most commonly used MFA methods.

OTP hardware-based

OTP-based hardware tokens, also known as security tokens or hard tokens, are one of the oldest MFA methods that are still in use today. RSA SecurID was very popular back in the early 90s.

There are drawbacks in using hardware tokens. Since they are small devices, they can be lost, stolen, or forgotten. When this happens, users won’t be able to access their accounts.

This scenario brings another disadvantage of hardware tokens. It can be hard to manage since it costs money to replace and logistics of delivering the hardware token.

The possibility of key extraction from a hardware token is another downside5. Additionally, cybercriminals can target manufacturers to steal information that could be used to compromise the security of the hardware tokens6.

OTP software-based

OTP-based software tokens are one of the most deployed MFA methods. It is very much the same as hardware tokens, but more convenient and less expensive. Assuming that users have smartphones – not everyone has one7. Instead of carrying another device, the user installs an app on their smartphone. The app generates six-digit passcodes for authentication.

Same as the hardware token, there are drawbacks to OTP software-based token. Smartphones get lost, stolen, or forgotten. In contrast, users are less likely to forget their smartphones at home than lose a hardware token. One can assume that users are more attentive with their smartphones than they may be with a hardware token.

Another thing to consider is the reliance on a smartphone’s battery life. Users won’t have access to the app to get their codes when smartphones are out of battery. It is also true that OTP-based hardware tokens also run on batteries, but their batteries can last anywhere from five to ten years.

Similar to hardware tokens, the seed value (or secret key) on a software-based token is vulnerable to theft, but in this case by smartphone malware or malware on the server. When malicious actors get a hold of the seed value, then they can replicate this to their own smartphone.

Both hardware and software tokens can suffer from a MITM (man-in-the-middle) attacks. To describe this attack, imagine a cybercriminal creates a fake bank website. Then launches a phishing campaign that entices users to give up their credentials including OTP. The server captures everything and passes your credentials to the real website. If done right, the server will maintain the session until the attacker is ready to make fraudulent transactions.

OTP SMS-based

Receiving one-time passwords (OTP) SMS (or text message) is another popular MFA method – possibly the most popular. With this method, upon successful first-step authentication, the user receives an SMS message with a random code.

Sometime in 2016, NIST (National Institute of Standards and Technology) seemingly deprecated SMS-based authentication but eventually softened their stance in the SP 800-63B (Digital Identity Guidelines) document8.

The key takeaway is to verify that the OOB (out-of-band) device is uniquely tied to a device. This means that users should not use VoIP-based services (Google Voice, for example) to receive passcodes.

While it is still acceptable to use OTP via SMS per NIST, it doesn’t mean users should keep using it. There are vulnerabilities in using this method such as SIM swap, SS7 (Signaling System No. 7) vulnerabilities, etc.

To highlight the insecurity of using this method, one virtual currency investor lost around $150,000 after the cybercriminal took control of his phone number9. Another instance where SMS-based 2FA was ineffective to protect the account was when Reddit got hacked via SMS intercept10.

Push-based notification

This method is taking the best of both worlds from SMS-based and mobile-app based MFA. The main advantage of this method over others is the balance between security and convenience.

The push-based method has been gaining popularity in the enterprise. In fact, Cisco Systems invested $2.35 billion to acquire Duo Security, an industry leader in the MFA space11.

The beauty of this method is that when the user sees a push notification, the user can choose to allow or deny the authentication attempt. If it was the user who initiated the authentication attempt, then it gets approved. Authentication attempts not initiated by the user can be rejected.

Push technology, in theory, is a more secure method, but it doesn’t mean it is immune to attacks. One possible attack is by social engineering. Imagine a cybercriminal gets a hold of a user’s credential and tries to access the account. When the cybercriminal is ready to send the push, he/she can call the user impersonating a trusted entity such as an IT personnel convincing the user to accept the push.

Universal 2nd Factor (U2F)

Google and Yubico initially developed U2F, but now it is an open authentication standard supported by the FIDO (Fast IDentity Online) Alliance. It aims to provide strong second-factor authentication while also enabling users to quickly and securely access websites.

When a user wants to authenticate to a website (that the U2F is registered), the user will need to insert the USB token as the second-factor authentication. It is not vulnerable to phishing attacks, session hijacking, and MITM attacks.

Same as the OTP-based hardware token; however, it can be forgotten, lost, or stolen. It can get costly when supplying or replacing these tokens to all employees in large organizations.

Conclusion

While MFA is not perfect, it is still better than not having it at all. Our recommendation is to enable it wherever possible. Especially, when it comes to systems, websites, or applications that contain sensitive data.

When choosing an MFA method for your organization, you must strike a balance between security and convenience. The MFA strategy must be easy to use and sustainable. Without these factors, users may find ways to circumvent it, which in turn undermines the security provided by the second-factor authentication.

Are you ready to improve your network security?

Let us answer more questions by contacting us. We’re here to listen and provide solutions that are right for you.

ENGAGE US

NetworkJutsu provides networking and network security consulting services for startups, a more established small and medium-sized business (SMB), or large business throughout the San Francisco Bay Area.

You might also like to read

How to improve your cybersecurity

______________________________________________________________________________________________________________________________
1 Passwords: 4 Biometric Tokens and How They Can Be Beaten
2 The Next Domino to Fall: Empirical Analysis of User Passwords across Online Services
3 2.2 Billion Accounts Found In Biggest Ever Data Dump — How To Check If You’re A Victim
4 Verizon 2017 Data Breach Investigation Report
5 Efficient Padding Oracle Attacks on Cryptographic Hardware
6 RSA breach leaks data for hacking SecurID tokens
7 Smartphone penetration rate
8 Questions…and buzz surrounding draft NIST Special Publication 800-63-3
9 Identity Thieves Hijack Cellphone Accounts to Go After Virtual Currency
10 We had a security incident. Here’s what you need to know.
11 Cisco Completes Acquisition of Duo Security

  • Share on Twitter Share on Twitter
  • Share on Facebook Share on Facebook
  • Share on LinkedIn Share on LinkedIn
  • Share on Reddit Share on Reddit
  • Share via Email Share via Email

FreeRADIUS 3.0 with Two-Factor Authentication (2FA)

06/01/2018 By Andrew Roderos 13 Comments

  • Share on Twitter Share on Twitter
  • Share on Facebook Share on Facebook
  • Share on LinkedIn Share on LinkedIn
  • Share on Reddit Share on Reddit
  • Share via Email Share via Email

Last year, I talked about migrating my FreeRADIUS server with two-factor authentication (2FA) to a Docker container. Today, I will cover how to configure FreeRADIUS 3.0 with two-factor authentication using Google Authenticator in a Docker container with Ubuntu 18.04 image.

Related: What is multi-factor authentication (MFA)?

The new version of Ubuntu Server LTS edition (18.04 at this time of writing) changed the FreeRADIUS version from 2.x to 3.0. The change made my old post as invalid. With that said, I want to share my working configuration with you.

If you wish to learn more about FreeRADIUS, there is a book out there available for purchase. However, it is an older book, so you may need to do some more research. Though, one of the Amazon reviews mentioned that the difference between 2.x and 3.0 are minor so it may still be helpful.

Writing FreeRADIUS 3.0 Dockerfile

I am sure there are FreeRADIUS 3.0 Docker images out there, but I like to write my own as much as I can. By writing a Dockerfile, it helps me learn more about Linux and Docker. I do, however, recognize that I am running the Docker container as root. As I learn more about this, I will eventually write one that isn’t using root. If you decide to copy this Dockerfile, beware the security risks running root on your container.

Without further ado, below is my Dockerfile that I wrote that satisfies my needs.

# Use Base Ubuntu image
FROM ubuntu:18.04
# Author of this Dockerfile
MAINTAINER NetworkJutsu <networkjutsu.com>
# Update & upgrades
RUN apt-get update && apt-get dist-upgrade -y
# Install FreeRADIUS and Google Authenticator
RUN apt-get install freeradius libpam-google-authenticator -y
# Clear local repo
RUN apt-get clean
# Add user to container with home directory
RUN useradd -m -d /home/networkjutsu -s /bin/bash networkjutsu
# Add password to networkjutsu account
RUN echo 'networkjutsu:letsmakemypasswordgreatagain' | chpasswd
# Edit /etc/pam.d/radiusd file
RUN sed -i 's/@include/#@include/g' /etc/pam.d/radiusd
RUN echo "auth requisite pam_google_authenticator.so forward_pass secret=/etc/freeradius/3.0/networkjutsu/.google_authenticator user=freerad" >> /etc/pam.d/radiusd
RUN echo "auth required pam_unix.so use_first_pass" >> /etc/pam.d/radiusd
# Edit /etc/freeradius/3.0/mods-config/files/authorize file
# This is the real file for /etc/freeradius/3.0/users
RUN sed -i '1s/^/# Instruct FreeRADIUS to use PAM to authenticate users\n/' /etc/freeradius/3.0/mods-config/files/authorize
RUN sed -i '2s/^/DEFAULT Auth-Type := PAM\n/' /etc/freeradius/3.0/mods-config/files/authorize
# Copy existing /etc/freeradius/sites-available/default file to container
# This is the real file for /etc/freeradius/3.0/sites-enabled/default
COPY default /etc/freeradius/3.0/sites-available/default
# Change owner of the file to freerad
RUN chown freerad:freerad /etc/freeradius/3.0/sites-available/default
# Copy existing /etc/freeradius/clients.conf file to container
COPY clients.conf /etc/freeradius/3.0/clients.conf
# Copy existing .google_authenticator file to container
COPY .google_authenticator /home/networkjutsu
# Create a symbolic link
RUN ln -s /etc/freeradius/3.0/mods-available/pam /etc/freeradius/3.0/mods-enabled/pam
# Create a folder in /etc/freeradius equal to the user name
RUN mkdir /etc/freeradius/3.0/networkjutsu
# Change owner of the directory to freerad
RUN chown freerad:freerad /etc/freeradius/3.0/networkjutsu
# Copy .google_authenticator file to /etc/freeradius/networkjutsu
RUN cp /home/networkjutsu/.google_authenticator /etc/freeradius/3.0/networkjutsu
# Change owner to freerad
RUN chown freerad:freerad /etc/freeradius/3.0/networkjutsu/.google_authenticator
# Expose the port
EXPOSE 1812/udp 1813/udp 18120/udp
# Run FreeRADIUS as a foreground process
CMD ["freeradius","-f"]

FreeRADIUS changes in Ubuntu

If you compare my old post and this post, you could tell that the directories have changed from /etc/freeradius to /etc/freeradius/3.0. One of the reasons why my old post would not work in Ubuntu 18.04.

Another change is the /etc/freeradius/3.0/users file. It is now a symbolic link compared to a regular file in Ubuntu 16.04. That said, I had to edit the original file and not the symbolic link.

The last change, at least for my purposes, is the requirement to create a symbolic link for the /etc/freeradius/3.0/mods-available/pam file. We need this file to enable PAM, without it the two-factor authentication wouldn’t work.

FreeRADIUS configuration files

I copied a lot of configuration files to the container because it was much faster for me to do it in a text editor than trying to figure out the proper sed commands. I am still new to sed command so it will take me several minutes or hours to figure out a simple thing to do in VI editor. While it will help me learn more about it, I haven’t had much time on my hands lately.

Some of the configuration files may have changed contents as a result of the upgrade. However, my old post covered all the changes I’ve made to them. Well, you could say I revised /etc/freeradius/3.0/radiusd file. The revision was very minor. I only did it because I wanted to show how to edit files without using a text editor, like VI editor.

Final Words

The changes to FreeRADIUS in Ubuntu 18.04 is minor, at least for my purposes. However, if you decide to upgrade your host or edit the Dockerfile to use the latest Ubuntu version without making the changes covered here, then it will break your instance.

A few weeks ago, I made a mistake of just changing the FROM ubuntu:16.04 to FROM ubuntu:18.04 and broke my FreeRADIUS container. If the FreeRADIUS version didn’t change, upgrading the OS would’ve been easy and fast compared to a VM. One of the reasons why I like to use Docker container as much as possible.

With this FreeRADIUS container, you could point your devices to this server as your primary RADIUS server. Since this server also makes use of Google Authenticator, you gain two-factor authentication feature. I use this container for my remote access VPN at home and also pointing my networking devices that support RADIUS authentication.

Are you ready to improve your network security?

Let us answer more questions by contacting us. We’re here to listen and provide solutions that are right for you.

ENGAGE US

You might also like to read

Adding Two-Factor Authentication to FreeRADIUS
Securing SSH with Google Authenticator
Adding Two-Factor Authentication to TACACS+

Disclosure

NetworkJutsu.com is a participant in the Amazon Services LLC Associates Program, an affiliate advertising program designed to provide a means for sites to earn advertising fees by advertising and linking to Amazon.com.

  • Share on Twitter Share on Twitter
  • Share on Facebook Share on Facebook
  • Share on LinkedIn Share on LinkedIn
  • Share on Reddit Share on Reddit
  • Share via Email Share via Email

Migrated FreeRADIUS with Google Authenticator to a Docker container

07/16/2017 By Andrew Roderos 4 Comments

  • Share on Twitter Share on Twitter
  • Share on Facebook Share on Facebook
  • Share on LinkedIn Share on LinkedIn
  • Share on Reddit Share on Reddit
  • Share via Email Share via Email

The number of virtual machines in my two-node ESXi cluster is growing and my 32GB RAM Intel NUC ESXi build will be out of memory soon if I don’t make changes. That said, I had to find a way to cut down my RAM usage to squeeze more out of this build. I don’t want to spend a couple of thousand dollars on another build. The ESXi build that I am looking at is Supermicro X10SDV-TLN4F-O which is a combination of motherboard, Intel Xeon D-1541, and 128GB ECC RDIMM RAM, an expensive ESXi build. Yes, I could buy a used server on eBay for less, but I don’t want those servers because they are too bulky and loud.

Update: FreeRADIUS 3.0 with Two-Factor Authentication using Google Authenticator

Enter Docker

What is Docker? Docker is an open-source software platform that allows users to package software into containers, allowing them to be portable among different operating systems (Windows, Linux, and macOS).

Here’s a ten-minute video that further explains what Docker is. If you want to watch an hour long video, here’s one from Docker, Inc.

Currently, I have three VMs running Ubuntu server edition for FreeRADIUS and tac_plus (TACACS+ daemon). On top of that, I was planning to set up another VM for Pi-hole (running it as a Docker container now). Sure, I could easily install it on one of the existing VMs that I have, but I want separation. With Docker, I could easily have all the separation I want but with fewer system resources and efficient use of it.

My base VM for Ubuntu server has the following assigned resources: 256MB RAM, 1 x vCPU, and 8GB of disk space. Depending on what I want to do with the new VM, I could change the resources assigned to it. If I assign it with too little of RAM, then the VM will use the disk for additional memory. Swapping is not ideal, so I usually add more RAM, which means there will be some free RAM just waiting to get used.

With Docker, I could assign 1GB of RAM to my Ubuntu VM with Docker installed and not worry about the efficient use of it. I know that eventually, the system will use the resources as I continue to add more containers. If the VM begins to swap, I could easily add more RAM.

Another advantage of Docker is the speed of spinning up new containers. With VMs, I need to clone the base image, create the VMX file, turn it on, etc. These processes would take several minutes. With Docker, I could write a one-line Dockerfile to create the Docker image and start the container. Starting up the container takes less than one second compared to the minutes spent on processes that I have to do when creating VMs.

Docker Installation

If you’re a returning visitor, you probably already know that I use Ubuntu. With that said, the Docker image will use Ubuntu as the OS. The installation could be a one-liner, but I wanted to install the newest version. Docker has the how-to guide, so just follow that if you want. Though, I will still list all of the things I did since I skipped a step or so.

$ sudo apt-get update
$ sudo apt-get install apt-transport-https ca-certificates curl software-properties-common -y
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
$ sudo apt-get update
$ sudo apt-get install docker-ce -y
$ docker --version
Docker version 17.06.0-ce, build 02c1d87

Docker Compose Installation

In this next section, we will install Docker Compose. While this is optional, I like the Docker compose because it makes it easier for me to run multiple containers in one command.

$ sudo -i
# curl -L https://github.com/docker/compose/releases/download/1.14.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
# chmod +x /usr/local/bin/docker-compose
# exit
$ docker-compose --version
docker-compose version 1.14.0, build c7bdf9e

FreeRADIUS Docker Image

There are plenty of FreeRADIUS Docker images on Docker Hub, but I wanted to learn how to create one on my own. Having said that, I read several websites, including Docker’s documentation page, to get an idea on how to create my own image. It took me several tries to get my FreeRADIUS Docker image working, since I am, after all, a Docker newbie.

Writing Dockerfile

When I was ready to write my Dockerfile, one question that I had was where do I put it. For testing, I decided to create a directory in my home directory and put any files related to this Docker image. I then switched to the new directory and created my Dockerfile there. In the future, I will still create a new directory just for the sake of separation. Though, it doesn’t really matter where you put the Dockerfile.

$ mkdir radius
$ cd radius
$ vi Dockerfile

Once I have VIM running, I started writing my Dockerfile. At first, I only started with few lines since I haven’t used the Ubuntu Docker image. I wanted to make sure that I could run all the commands I need to put in the Dockerfile. Once everything worked in the container, I started to write the rest. Here’s the complete Dockerfile that I wrote.

# Use Base Ubuntu image
FROM ubuntu:16.04
# Author of this Dockerfile
MAINTAINER NetworkJutsu <networkjutsu.com>
# Update & upgrades
RUN apt-get update && apt-get dist-upgrade -y
# Install FreeRADIUS and Google Authenticator
RUN apt-get install freeradius libpam-google-authenticator -y
# Add user to container with home directory
RUN useradd -m -d /home/networkjutsu -s /bin/bash networkjutsu
# Add password to networkjutsu account.
# Obviously, you wouldn't want to do this in production.
# Go to the container and add the password there then commit the changes to the container.
RUN echo "networkjutsu:letsmakemypasswordgreatagain" | chpasswd
# Edit /etc/pam.d/radiusd file
RUN sed -i 's/@include/#@include/g' /etc/pam.d/radiusd
RUN echo "auth requisite pam_google_authenticator.so forward_pass secret=/etc/freeradius/networkjutsu/.google_authenticator user=freerad" >> /etc/pam.d/radiusd
RUN echo "auth required pam_unix.so use_first_pass" >> /etc/pam.d/radiusd
# Edit /etc/freeradius/users file
RUN sed -i '1s/^/# Instruct FreeRADIUS to use PAM to authenticate users\n/' /etc/freeradius/users
RUN sed -i '2s/^/DEFAULT Auth-Type := PAM\n/' /etc/freeradius/users
# Copy existing /etc/freeradius/sites-enabled/default file to container
COPY default /etc/freeradius/sites-enabled/default
# Copy existing /etc/freeradius/clients.conf file to container
COPY clients.conf /etc/freeradius/clients.conf
# Copy existing .google_authenticator file to container
COPY .google_authenticator /home/networkjutsu
# Create a folder in /etc/freeradius equal to the user name
RUN mkdir /etc/freeradius/networkjutsu
# Copy .google_authenticator file to /etc/freeradius/networkjutsu
RUN cp /home/networkjutsu/.google_authenticator /etc/freeradius/networkjutsu
# Change owner to freerad
RUN chown freerad:freerad /etc/freeradius/networkjutsu && chown freerad:freerad /etc/freeradius/networkjutsu/.google_authenticator
# Expose the port
EXPOSE 1812/udp 1813/udp 18120/udp
# Run FreeRADIUS
CMD freeradius -f

The lines where I instructed Docker engine to copy existing FreeRADIUS files, those files are based on the configuration covered in my past blog posts. If you’re curious about the config files, please check this post and this one. I could’ve copied everything from my existing RADIUS server, but I wanted to show other ways of writing the Dockerfile and how to edit the config files.

Building Docker Image

Once done with the Dockerfile, the next step is to build the Docker image. Creating the Docker image is pretty straightforward. We just need to issue the build command, and it will create the Docker image based on the Dockerfile that we wrote. The -t flag allows us to tag the Docker image with a friendly name.

$ sudo docker build -t radius1 .

If we don’t tag the image with a friendly name, it would look like this.

$ sudo docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                        PORTS               NAMES
bb3ad23725a6        9ea220058853        "/bin/sh -c 'apt-g..."   32 minutes ago      Exited (100) 32 minutes ago                       adoring_poitras

If there are errors in the Dockerfile, the image will not get built. The Docker engine is good about telling the user where it failed. Here’s an example where I took some lines out of the Dockerfile.

networkjutsu@ubuntu:~$ sudo docker build -t radius1 .
Sending build context to Docker daemon  27.65kB
Step 1/10 : RUN apt-get install freeradius libpam-google-authenticator -y
Please provide a source image with `from` prior to run
networkjutsu@ubuntu:~$ sudo docker build -t radius .
Sending build context to Docker daemon  27.65kB
Step 1/12 : FROM ubuntu:16.04
<-- Output omitted for brevity -->
Step 2/12 : MAINTAINER Network Jutsu <networkjutsu.com>
<-- Output omitted for brevity -->
Step 3/12 : RUN apt-get install freeradius libpam-google-authenticator -y
<-- Output omitted for brevity -->
E: Unable to locate package freeradius
E: Unable to locate package libpam-google-authenticator
The command '/bin/sh -c apt-get install freeradius libpam-google-authenticator -y' returned a non-zero code: 100
networkjutsu@ubuntu:~$

If there are no errors, it should look something like below. The image created here is from a modified Dockerfile where I excluded the COPY commands because I do not have those files in this VM.

networkjutsu@ubuntu:~$ sudo docker build -t radius1 .
Sending build context to Docker daemon  27.65kB
Step 1/13 : FROM ubuntu:16.04
<-- Output omitted for brevity -->
Step 2/13 : MAINTAINER Network Jutsu <networkjutsu.com>
<-- Output omitted for brevity -->
Step 3/13 : RUN apt-get update && apt-get dist-upgrade -y
<-- Output omitted for brevity -->
Step 4/13 : RUN apt-get install freeradius libpam-google-authenticator -y
<-- Output omitted for brevity -->
Step 5/13 : RUN useradd -m -d /home/networkjutsu -s /bin/bash networkjutsu
<-- Output omitted for brevity -->
Step 6/13 : RUN echo "networkjutsu:letsmakemypasswordgreatagain" | chpasswd
<-- Output omitted for brevity -->Removing intermediate container 356f78c72b6c
Step 7/13 : RUN sed -i 's/@include/#@include/g' /etc/pam.d/radiusd
<-- Output omitted for brevity -->
Step 8/13 : RUN echo "auth requisite pam_google_authenticator.so forward_pass secret=/etc/freeradius/networkjutsu/.google_authenticator user=freerad" >> /etc/pam.d/radiusd
<-- Output omitted for brevity -->Removing intermediate container a1baec16ec31
Step 9/13 : RUN echo "auth required pam_unix.so use_first_pass" >> /etc/pam.d/radiusd
<-- Output omitted for brevity -->
Step 10/13 : RUN sed -i '1s/^/# Instruct FreeRADIUS to use PAM to authenticate users\n/' /etc/freeradius/users
<-- Output omitted for brevity -->
Step 11/13 : RUN sed -i '2s/^/DEFAULT Auth-Type := PAM\n/' /etc/freeradius/users
<-- Output omitted for brevity -->
Step 12/13 : EXPOSE 1812/udp 1813/udp 18120/udp
<-- Output omitted for brevity -->
Step 13/13 : CMD freeradius -f
<-- Output omitted for brevity -->
Successfully built c227ded15dcd
Successfully tagged radius:latest
networkjutsu@ubuntu:~$

Verification

To see the Docker images in our system, issue the command below. Notice that there is an Ubuntu image. This is the result of the FROM ubuntu:16.04 line from our Dockerfile.

$ sudo docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
radius1             latest              c227ded15dcd        27 minutes ago      246MB
ubuntu              16.04               d355ed3537e9        3 weeks ago         119MB

Docker Compose

We’re now ready to run the Docker image. We could issue the docker run command, however, I like running the Docker image using Docker Compose. In this section, we’re going to write what we need for our docker-compose.yml file to run the Docker image. The YML file doesn’t need to be in the radius directory. In my case, I just put my file in my home directory. Remember though, when you run the docker-compose command, it will look for the YML file. Be sure to run the command in the directory where you stored the YML file.

$ vi docker-compose.yml
version: "3"
services:
  radius1:
    container_name: radius1
    image: radius1
    ports:
    - "192.168.0.100:1812:1812/udp"
    - "192.168.0.100:1813:1813/udp"
    - "192.168.0.100:18120:18120/udp"
    environment:
    - VIRTUAL_HOST=radius1.networkjutsu.lan
    restart: always
    volumes:
    - /etc/timezone:/etc/timezone:ro
    - /etc/localtime:/etc/localtime:ro
  radius2:
    container_name: radius2
    image: radius2
    ports:
    - "192.168.0.101:1812:1812/udp"
    - "192.168.0.101:1813:1813/udp"
    - "192.168.0.101:18120:18120/udp"
    environment:
    - VIRTUAL_HOST=radius2.networkjutsu.lan
    restart: always
    volumes:
    - /etc/timezone:/etc/timezone:ro
    - /etc/localtime:/etc/localtime:ro

Ports

For this section, I included an IP address. By default, the container will use the host’s IP address. If one wants to use the default IP address, then the line would look like – “1812:1812/udp”. In this case, I wanted to use a different IP address than the host. This will allow me to create another Docker container using the same ports. Since the host doesn’t have this particular IP address assigned to it, we need to set up the host machine to have another IP address (IP aliasing). Editing the network interface config means that we want the changes to be persistent even after a reboot. I think I don’t need the other lines in the alias section since it will use the main interface configs. However, I still included it in the config just in case.

$ sudo vi /etc/network/interfaces
# Host machine
auto ens160
iface ens160 inet static
address 192.168.0.200
netmask 255.255.255.0
network 192.168.0.200
broadcast 192.168.0.255
gateway 192.168.0.1
dns-nameserver 192.168.200.53
dns-search networkjutsu.lan
# First IP alias
# IP address for radius1
auto ens160:0
iface ens160:0 inet static
address 192.168.0.100
netmask 255.255.255.0
network 192.168.0.0
broadcast 192.168.0.255
gateway 192.168.0.1
dns-nameserver 192.168.200.53
dns-search networkjutsu.lan
# Second IP alias
# IP address for raduius2
auto ens160:1
iface ens160:1 inet static
address 192.168.0.101
netmask 255.255.255.0
network 192.168.0.0
broadcast 192.168.0.255
gateway 192.168.0.1
dns-nameserver 192.168.200.53
dns-search networkjutsu.lan
$ sudo service networking restart

Volumes

As I was verifying everything in my FreeRADIUS Docker container, I noticed that the time was incorrect even after setting the environment with the right time zone. During my search, I came across a thread that talks about how to set the time zone correctly. There are several ways of doing it, but I settled on this way. With this config, the container syncs with the host machine’s time. Having said that, the host needs to sync with NTP servers. Having correct time is important because my Google Authenticator is TOTP-based.

Starting the container

Once done with the YML file, we’re now ready to run our image with docker-compose command. The -d flag instructs Docker engine to run the container(s) as a daemon.

$ sudo docker-compose up -d
$ sudo docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                                        NAMES
2edac8f51819        radius              "/bin/sh -c 'freer..."   39 seconds ago      Up 38 seconds       192.168.0.100:1812-1813->1812-1813/udp, 192.168.0.100:18120->18120/udp   radius

Stopping the container

If for whatever reason, you want to stop the container, you can issue the docker stop command.

$ sudo docker stop 2edac8f51819
2edac8f51819

Final Words

My FreeRADIUS Docker image is by no means perfect. I am still a Docker newbie, so I am pretty sure if a Docker expert looks at my Dockerfile there will be some comments. But, I’ve tested this already with my PA-200, and it worked perfectly.

With Docker, it will allow me to turn off multiple VMs running on my ESXi host. On top of that, I will now be able to spin up new services quickly without going through the processes that I use to create a new VM with Ubuntu as the OS.

Are you ready to improve your network security?

Let us answer more questions by contacting us. We’re here to listen and provide solutions that are right for you.

ENGAGE US

You might also like to read

FreeRADIUS 3.0 with Two-Factor Authentication (2FA)
Adding Two-Factor Authentication to FreeRADIUS
Securing SSH with Google Authenticator
Adding Two-Factor Authentication to TACACS+

Disclosure

NetworkJutsu.com is a participant in the Amazon Services LLC Associates Program, an affiliate advertising program designed to provide a means for sites to earn advertising fees by advertising and linking to Amazon.com.

  • Share on Twitter Share on Twitter
  • Share on Facebook Share on Facebook
  • Share on LinkedIn Share on LinkedIn
  • Share on Reddit Share on Reddit
  • Share via Email Share via Email

Adding Two-Factor Authentication to TACACS+

06/02/2017 By Andrew Roderos Leave a Comment

  • Share on Twitter Share on Twitter
  • Share on Facebook Share on Facebook
  • Share on LinkedIn Share on LinkedIn
  • Share on Reddit Share on Reddit
  • Share via Email Share via Email

Several months ago, I covered how to add two-factor authentication (2FA) to FreeRADIUS using Google Authenticator. Today, I will cover the TACACS+ version of it.

Related: What is multi-factor authentication (MFA)?

I’ve written a blog post on how to build tac_plus server using Ubuntu. The guide was written in 2011, while it’s an old blog post, the instructions are still valid using Ubuntu Server 16.04. Please use that guide on how to build one, then use this guide to add multi-factor authentication (MFA) to TACACS+.

Related: Deploying TACACS+ on a Docker container

Installing Google Authenticator PAM

It is super easy to install Google Authenticator on Ubuntu. Below is the command we need to install Google Authenticator PAM on Ubuntu.

$ sudo apt-get install libpam-google-authenticator -y

Configure tac_plus

As mentioned earlier, the instructions in my old blog post are still valid. We’re going to use only some of them in this post for the purpose of demonstration only.

By default, the /etc/tacacs+/tac_plus.conf file looks like this:

accounting file = /var/log/tac_plus.acct
key = testing123
user = DEFAULT {
       login = PAM
       service = ppp protocol = ip {}
}

Let’s change the key and user information fields to look something like this:

accounting file = /var/log/tac_plus.acct
key = tacacskey1234
user = tacacsuser {
        member = Administrators
}
group = Administrators {
        default service = permit
        login = PAM
        enable = file /etc/passwd
}

Restart TACACS+ daemon

Since we made a change to our tac_plus config file, we need to restart the service for our changes to take effect. Issue the command below.

$ sudo /etc/init.d/tacacs_plus restart
[ ok ] Restarting tacacs_plus (via systemctl): tacacs_plus.service.

An alternative command is shown below.

$ sudo service tacacs+ restart

Generating Google Authenticator Secret Key

This step is covered in my old blog post so head over there and skip to the generating the secret key section. Alternatively, we could use the same secret key(s) from another system with Google Authenticator. However, this is not the recommended practice.

To get the secret key from another system, just copy and paste the ~/.google_authenticator file of each user, like the one below.

tacacsuser@tacplus:~$ more .google_authenticator
UXQLCMOLT2QLSMVE
" RATE_LIMIT 3 30 1436015893
" DISALLOW_REUSE 39787632
" TOTP_AUTH
55312114
13740459
80118802
81859009
79311140

If you copy and paste it to a file, make sure that the permission is set to read only.

tacacsuser@tacplus:~$ ls -l .google_authenticator
-rw-rw-r-- 1 tacacsuser tacacsuser 129 May 29 17:54 .google_authenticator
tacacsuser@tacplus:~$ chmod 400 .google_authenticator
tacacsuser@tacplus:~$ ls -l .google_authenticator
-r-------- 1 tacacsuser tacacsuser 129 May 29 17:54 .google_authenticator

Configuring TACACS+ PAM

Since we instructed tac_plus to use PAM, we now need to create a file called /etc/pam.d/tac_plus, so PAM knows what to do. The file should look like:

$ more /etc/pam.d/tac_plus
auth requisite pam_google_authenticator.so forward_pass
auth required pam_unix.so use_first_pass

IOS configuration

Before we can verify that our tac_plus config is working, let’s configure a CSR1000V router running IOS-XE.

R1#conf t
Enter configuration commands, one per line.  End with CNTL/Z.
R1(config)#aaa new-model
R1(config)#aaa authentication login default group tacacs+ enable
R1(config)#aaa authentication enable default group tacacs+ enable
R1(config)#aaa session-id common
R1(config)#tacacs-server host 192.168.250.250
 Warning: The cli will be deprecated soon
 'tacacs-server host 192.168.250.250'
 Please move to 'tacacs server <name>' CLI
R1(config)#tacacs-server directed-request
R1(config)#tacacs-server key tacacskey1234
R1(config)#end
R1#

While the configuration above still works, it is a good idea to move towards the new way of doing things. Here’s the new way of configuring TACACS+:

R1#conf t
Enter configuration commands, one per line.  End with CNTL/Z.
R1(config)#aaa new-model
R1(config)#aaa authentication login default group tacacs+ enable
R1(config)#aaa authentication enable default group tacacs+ enable
R1(config)#aaa session-id common
R1(config)#tacacs server tac_plus
R1(config-server-tacacs)# address ipv4 192.168.250.250
R1(config-server-tacacs)# key tacacskey1234
R1(config-server-tacacs)#end
R1#

Verification

This CSR1000V router is using version 15.4(2)S image. The output may vary depending on what platform and the IOS version.

$ ssh tacacsuser@192.168.250.250
Password & verification code:
R1>en
Password:
R1#

For completeness sake, I will list the passwords entered in the example above. The tacacsuser account is a valid account on the Ubuntu server running TACACS+ daemon. For example, the tacacsuser account has a password of tacacsuserpassword1234. Next, the verification code is the six-digit number displayed on Google Authenticator app. For example, the six-digit number is 567 890. With this example, the user will enter tacacsuserpassword1234567890 in the password & verification prompt.

For entering the privileged EXEC mode, we’ll again use tacacsuser’s password. If we look at the tac_plus config file, the enable = file /etc/passwd is what we defined.

Final Words

I am quite biased towards TACACS+. One of the reasons why is because of the command authorization piece. TACACS+ authentication and authorization are completely separate. That said, we could assign different command authorization level for the user or group.

With RADIUS, it combines authentication and authorization. Once the user authenticates successfully, the access-accept packet sent by RADIUS server to the device contain authorization information as well. If we configure the device similar to the example here, then the user will have full access.

To overcome RADIUS’ drawback, we could configure the device to use a local enable secret. This password is then shared only with the necessary user(s) or group(s). The issue with this approach is that the password is then a shared password. A lot of information security professionals do not like shared passwords because it is insecure.

Having said all that, I think it’s better to use TACACS+, especially with the Cisco-centric environment. While a lot of vendors support TACACS+, there might be some limitations on the authorization piece.

Are you ready to improve your network security?

Let us answer more questions by contacting us. We’re here to listen and provide solutions that are right for you.

ENGAGE US

You might also like to read

How to build tac_plus server
TACACS+ (tac_plus daemon) ACL
How to configure AAA on Cisco router/switches
Enabling AAA on Cisco ASA
Deploying TACACS+ on a Docker container

Disclosure

NetworkJutsu.com is a participant in the Amazon Services LLC Associates Program, an affiliate advertising program designed to provide a means for sites to earn advertising fees by advertising and linking to Amazon.com.

  • Share on Twitter Share on Twitter
  • Share on Facebook Share on Facebook
  • Share on LinkedIn Share on LinkedIn
  • Share on Reddit Share on Reddit
  • Share via Email Share via Email

Adding Two-Factor Authentication to FreeRADIUS

10/21/2016 By Andrew Roderos 16 Comments

  • Share on Twitter Share on Twitter
  • Share on Facebook Share on Facebook
  • Share on LinkedIn Share on LinkedIn
  • Share on Reddit Share on Reddit
  • Share via Email Share via Email

In my previous post, I talked about enabling two-factor authentication (2FA) for my public facing Linux host. In today’s post, I will talk about integrating Google Authenticator PAM to FreeRADIUS. As a result, any hosts that are pointed to my RADIUS server will have the 2FA functionality.

Update: Migrated FreeRADIUS with Google Authenticator to a Docker container
Update: FreeRADIUS 3.0 with Two-Factor Authentication (2FA)

Installing FreeRADIUS and Google Authenticator PAM

While there are several RADIUS software out there, FreeRADIUS is one of the most popular RADIUS software of choice in Linux. Since it has PAM library, this is also perfect for integrating it with Google Authenticator PAM. If you want to know more about FreeRADIUS, you might want to check this book out. I have not read it so read through the reviews to see if that will work for your needs.

Related: What is multi-factor authentication (MFA)?

Installing FreeRADIUS and Google Authenticator on Ubuntu 16.04 is very easy. All we need is to issue one line command. I added NTP package here since my Google Authenticator configuration is TOTP based. If one went through the Ubuntu installation properly, there might not be a need for this so long as the system is syncing to the time correctly.

$ sudo apt-get install freeradius libpam-google-authenticator -y

Configuring FreeRADIUS

After the package installation, the next step is to set up FreeRADIUS by editing configuration files. There are four config files we need to edit to complete this setup. By no means, one needs to follow the order.

First config file

The first config file that we need to edit is the /etc/freeradius/radiusd.conf file. There are two ways in configuring this and it seems that the most popular option is the one with FreeRADIUS running as root. For some people, this is not acceptable so I included instructions below where we’ll leave it as the default configuration.

Option 1 – Run as root

According to my limited research, the need to change the user and group to root is because of how both FreeRADIUS and Google Authenticator PAM works. My observation seems to indicate that FreeRADIUS will also need to access the secret key (.google_authenticator) in each user’s home directory – I could be totally wrong with this. My Linux boxes have encrypted home directories so only the owner and root can access these. That said, letting FreeRADIUS run as root will have access to the necessary files.

$ sudo vi /etc/freeradius/radiusd.conf

We’ll now need to find the lines user = and group =. The default configuration is set to freerad. Change both of them to root.

user = root
group = root

Option 2 – Use default configuration

As mentioned, we can just leave the file as default. I will explain more about this once we get to the section where we need to edit the /etc/pam.d/radiusd file.

Second config file

The the next config file that we need to edit is the /etc/freeradius/users file. This file will instruct FreeRADIUS to use PAM libraries to authenticate users as the default.

$ sudo vi /etc/freeradius/users

Add the lines found below. I usually like to add lines at the end of the file. Add the line after all the commented text of the file, just before the DEFAULT Framed Protocol == PPP line. This will ensure that this line will take precedence. I found out the hard way when I was troubleshooting an issue with L2TP over IPsec authentication.

# Instruct FreeRADIUS to use PAM to authenticate users
DEFAULT Auth-Type := PAM

Third config file

The second to the last config file on our list to be edited is the /etc/freeradius/sites-enabled/default file. This file tells FreeRADIUS to enable PAM authentication. We just need to edit one line here.

$ sudo vi /etc/freeradius/sites-enabled/default

Once the file is open, look for the following lines:

        #  Pluggable Authentication Modules.
#        pam

We now need to uncomment the pam line to enable it. It should look like this now:

        #  Pluggable Authentication Modules.
        pam

Fourth config file

Finally, the last FreeRADIUS config file that we need to change is the /etc/freeradius/clients.conf. This is where we can set up our secret key that is used by the clients to connect to the RADIUS server. Please change the default secret key to random alphanumeric characters. Use a key generator to generate the secret to make things life a little easier. For demo purposes, I will be using the default secret. To change the secret, look for secret = testing123 line.

$ sudo vi /etc/freeradius/clients.conf
<-- Output omitted for brevity -->
secret          = my_super_awesome_strong_secret
client rtr {
	ipaddr = 192.168.200.1
	secret = my_super_awesome_strong_secret 
}
Related: How to implement Duo Security MFA

As usual in Linux, when a configuration file has been changed, then the service needs to be restarted for the changes to take effect. To restart FreeRADIUS daemon, issue the sudo service freeradius restart command.

Configuring FreeRADIUS PAM

Since we instructed FreeRADIUS to use PAM to authenticate users, we need to configure the /etc/pam.d/radiusd file and instruct it to integrate Google Authenticator PAM. By default, the file will look something like this:

<-- Output omitted for brevity -->
@include common-auth
@include common-account
@include common-password
@include common-session

Option 1

If you picked the first option in the FreeRADIUS configuration section, then you need to comment those four lines above and add two lines. The file should look like this:

#@include common-auth
#@include common-account
#@include common-password
#@include common-session
auth requisite pam_google_authenticator.so forward_pass
auth required pam_unix.so use_first_pass

Option 2

If you left the /etc/freeradius/radiusd.conf file alone, then it becomes a little bit more complicated setup. Also, you will notice that my instructions are what I will consider a workaround to AppArmor (I am guessing this is the real issue). You will see why later in the next section, after the generating Google Authenticator secret key. Anyway, the /etc/pam.d/radiusd file should look like this:

#@include common-auth
#@include common-account
#@include common-password
#@include common-session
auth requisite pam_google_authenticator.so forward_pass secret=/etc/freeradius/${USER}/.google_authenticator user=freerad
auth required pam_unix.so use_first_pass

Google Authenticator Secret Key

I’ve already covered the generation of the secret key in my previous post, so look for the generating Google Authenticator secret key section. Once you are done generating secret keys, come back to this page. If you picked the first option throughout this tutorial, then skip this section and go to the verification section.

If you picked the second option, then we’ll need to do additional steps to make this work. Again, you do not have to follow the order in which they are listed here.

We first need to create a directory equal to the user account that we’re working on. In this scenario, we’ll use user account named test.

$ sudo mkdir /etc/freeradius/test

Then, we need to change the owner of the directory that we just created.

$ sudo chown freerad:freerad /etc/freeradius/test

The second to the last step is to copy the secret key to the directory that we just created.

$ sudo cp .google_authenticator /etc/freeradius/test/.google_authenticator

Finally, we need to change the owner of the file.

$ sudo chown freerad:freerad /etc/freeradius/test/.google_authenticator

If I ever learn more about AppArmor, then I will update this blog post because I think this is the real issue why it’s failing. I did try creating an AppArmor profile, but testing shows that I was still failing. When I looked at the /var/log/auth.log file, I saw an error message that looked like this:

Oct 10 21:24:53 radius radiusd(pam_google_authenticator)[18433]: Failed to update secret file "/etc/freeradius/test/.google_authenticator"

Verification

We now need to test to make sure that we can successfully authenticate. FreeRADIUS software package includes a simple tool that we can use to directly query the daemon with requests. The command format is radtest test <password+google authenticator token> localhost 18120 <RADIUS secret key>. The password and Google Authenticator token should not have space in between. Below shows the syntax that I used to test my configuration and the test result.

$ radtest test testing1234803732 localhost 18120 testing123
Sending Access-Request of id 79 to 127.0.0.1 port 1812
	User-Name = "test"
	User-Password = "testing1234803732"
	NAS-IP-Address = 127.0.1.1
	NAS-Port = 18120
	Message-Authenticator = 0x00000000000000000000000000000000
rad_recv: Access-Accept packet from host 127.0.0.1 port 1812, id=79, length=20

Final Words

I’d like to speculate that a lot of people would pick the first option since the second option involves a lot more steps. Also, this isn’t a scalable solution so I think it will turn off quite a number of people. Imagine doing the steps above for multiple accounts. It’s going to be a lot of administrative work. For my purpose, this is a perfectly acceptable solution because I only have one account in my RADIUS server. It is probably an overkill to be creating a FreeRADIUS server instance for home use, but some may argue that nothing is overkill in security. The more secure you are, the better.

Are you ready to improve your network security?

Let us answer more questions by contacting us. We’re here to listen and provide solutions that are right for you.

ENGAGE US

You might also like to read

FreeRADIUS 3.0 with Two-Factor Authentication
Securing SSH with Google Authenticator

Migrated FreeRADIUS with Google Authenticator to a Docker container
Adding Two-Factor Authentication to TACACS+

References

Integrating Google Authenticator PAM module with FreeRADIUS Server
Freeradius and Google Authenticator
GitHub Google Authenticator

Disclosure

NetworkJutsu.com is a participant in the Amazon Services LLC Associates Program, an affiliate advertising program designed to provide a means for sites to earn advertising fees by advertising and linking to Amazon.com.

  • Share on Twitter Share on Twitter
  • Share on Facebook Share on Facebook
  • Share on LinkedIn Share on LinkedIn
  • Share on Reddit Share on Reddit
  • Share via Email Share via Email
  • Go to page 1
  • Go to page 2
  • Go to Next Page »

Footer

WORK WITH US

Schedule a free consultation now!

LET’S TALK

Copyright © 2011–2023 · NetworkJutsu · All Rights Reserved · Privacy Policy · Terms of Use