• 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

Network Security

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

Securing Cisco IOS SSH server

12/16/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

Back in 2011, I wrote a post on how to enable SSH on Cisco routers and switches. Unfortunately, it didn’t contain any of the advanced configurations that will harden Cisco IOS SSH server. To be fair, there were older IOS software versions that didn’t include advanced SSH commands that I will cover here. With this post, I’d like to share at least the minimum advanced SSH configuration that network engineers should consider adding to their template.

SSH Encryption Algorithms

If you’re a macOS 10.13.2 user and you use it to connect to Cisco routers and switches, you may have seen this error message already.

Mac mini:~ networkjutsu$ ssh router01
Unable to negotiate with 192.168.100.200 port 22: no matching cipher found. Their offer: aes128-cbc,3des-cbc,aes192-cbc,aes256-cbc

The issue here is that OpenSSH has deprecated the weaker ciphers in the default SSH configuration of the newest version of macOS. Unfortunately, older Cisco IOS software uses AES 3DES-CBC for the SSH server, by default. Below is an example of a Cisco router running an older version of IOS which uses default SSH configuration.

router01>sh ssh
Connection Version Mode Encryption  Hmac	     State	               Username
0          2.0     IN   3des-cbc    hmac-sha1    Session started       networkjutsu
0          2.0     OUT  3des-cbc    hmac-sha1    Session started       networkjutsu
%No SSHv1 server connections running.

There are two options to get rid of the error message. One of the options is by configuring the client side to accept the legacy ciphers. The right course of action, in my opinion, is to change SSH server configurations. However, we still need to be able to connect to our Cisco IOS devices to correct the issue.

SSH client options

A quick fix here is to keep using compatible ciphers that the client would accept. There are three options that one could use for this workaround. Technically, they are all doing the same thing but just different approach.

Option #1

With this option, the user just needs to specify the cipher and KEX algorithms in the SSH command when connecting to an SSH server. One could create an alias to include all the necessary command flags for shorter keystrokes.

Mac mini:~ networkjutsu$ ssh -oKexAlgorithms=diffie-hellman-group1-sha1 -c 3des-cbc router01
Password:
router01>

Option #2

With this option, the user does not need to create an alias or type the whole command shown above. The .ssh/config file is a user-specific configuration file. OpenSSH receives its configuration from this file when the command issued doesn’t include command flags.

Mac mini:~ networkjutsu$ cat .ssh/config
# ***
# *** General settings (these apply to all connections)
# ***
HostkeyAlgorithms +ssh-dss
KexAlgorithms +diffie-hellman-group1-sha1
Ciphers +3des-cbc

Option #3

With this option, all users are affected by this configuration file. However, the command issued and user-specific configuration file take precedence over the global configuration file.

Mac mini:~ networkjutsu$ cat /etc/ssh/ssh_config
HostkeyAlgorithms +ssh-dss
KexAlgorithms +diffie-hellman-group1-sha1
Ciphers +3des-cbc

SSH server options

As mentioned earlier, the server side option is the correct course of action. However, one still needs to connect the Cisco IOS devices to fix the issue. That said, the SSH client workaround still plays an important role.

SSH encryption algorithm

The command shown below is used to change SSH encryption key algorithm used on a Cisco IOS device. If one gets an error message, then the command is not available in that IOS version.

router01(config)#ip ssh server algorithm encryption ?
  3des-cbc    Three-key 3DES in CBC mode
  aes128-cbc  AES with 128-bit key in CBC mode
  aes128-ctr  AES with 128-bit key in CTR mode
  aes192-cbc  AES with 192-bit key in CBC mode
  aes192-ctr  AES with 192-bit key in CTR mode
  aes256-cbc  AES with 256-bit key in CBC mode
  aes256-ctr  AES with 256-bit key in CTR mode
router01(config)#ip ssh server algorithm encryption aes256-ctr

In this particular IOS version, the SSH server supports the encryption algorithms: AES-CTR, AES-CBC, and 3DES. According to this thread, use EAX or GCM, if available. If not, the author said to use CTR over CBC mode. By specifying the encryption algorithm, we’re telling Cisco IOS to only offer the AES-256-CTR mode to any clients that try to connect to it.

Below shows the verbose output of a Cisco IOS device using default SSH configuration.

Mac mini:~ networkjutsu$ ssh -vvv router01
OpenSSH_7.6p1, LibreSSL 2.6.2
<-- Output omitted for brevity -->
debug2: peer server KEXINIT proposal
debug2: ciphers ctos: aes128-cbc,3des-cbc,aes192-cbc,aes256-cbc
debug2: ciphers stoc: aes128-cbc,3des-cbc,aes192-cbc,aes256-cbc

Below shows the verbose output of a Cisco IOS device using the SSH configuration mentioned above.

Mac-mini:~ networkjutsu$ ss -vvv router01
OpenSSH_7.6p1, LibreSSL 2.6.2
<-- Output omitted for brevity -->
debug2: peer server KEXINIT proposal
debug2: ciphers ctos: aes256-ctr
debug2: ciphers stoc: aes256-ctr

SSH MAC algorithm

To change the default SSH MAC algorithm used on a Cisco IOS device, use the command below.

router01(config)#ip ssh server algorithm mac ?
  hmac-sha1     HMAC-SHA1 (digest length = key length = 160 bits)
  hmac-sha1-96  HMAC-SHA1-96 (digest length = 96 bits, key length = 160 bits)
router01(config)#ip ssh server algorithm mac hmac-sha1

UPDATE: Newer IOS supports higher than SHA1.

router01(config)#ip ssh server algorithm mac ?
  hmac-sha1      HMAC-SHA1 (digest length = key length = 160 bits)
  hmac-sha1-96   HMAC-SHA1-96 (digest length = 96 bits, key length = 160 bits)
  hmac-sha2-256  HMAC-SHA2-256 (digest length = 256 bits, key length = 256 bits)
  hmac-sha2-512  HMAC-SHA2-512 (digest length = 512 bits, key length = 512 bits)
router01(config)#ip ssh server algorithm mac hmac-sha2-512

In this particular IOS version, the SSH server supports two Message Authentication Code (MAC) algorithms: HMAC-SHA1 and HMAC-SHA1-96. The difference between the two algorithms is the digest length. The HMAC-SHA1-96 is a truncated message digest. From my limited understanding, the HMAC-SHA1-96 is the weakened version of HMAC-SHA1 due to the shortened message digest.

Below shows the verbose output of a Cisco IOS device using default SSH configuration.

Mac-mini:~ networkjutsu$ ss -vvv router01
OpenSSH_7.6p1, LibreSSL 2.6.2
<-- Output omitted for brevity -->
debug2: MACs ctos: hmac-sha1,hmac-sha1-96,hmac-md5,hmac-md5-96
debug2: MACs stoc: hmac-sha1,hmac-sha1-96,hmac-md5,hmac-md5-96

Below shows the verbose output of a Cisco IOS device using the SSH configuration mentioned above.

Mac-mini:~ networkjutsu$ ss -vvv router01
OpenSSH_7.6p1, LibreSSL 2.6.2
<-- Output omitted for brevity -->
debug2: peer server KEXINIT proposal
debug2: MACs ctos: hmac-sha1
debug2: MACs stoc: hmac-sha1

UPDATE: Configured with SHA2

Mac-mini:~ networkjutsu$ ss -vvv router01
OpenSSH_7.6p1, LibreSSL 2.6.2
<-- Output omitted for brevity -->
debug2: MACs ctos: hmac-sha2-512
debug2: MACs stoc: hmac-sha2-512

Key Exchange Algorithm

If my memory serves me right, even before macOS High Sierra, OpenSSH also deprecated the use of Diffie-Hellman key exchange with SHA-1. That said, users that tried to connect to Cisco IOS devices with default SSH configurations were greeted by an error message, like the one below.

Mac mini:~ networkjutsu$ ssh router01
Unable to negotiate with 192.168.100.200 port 22: no matching key exchange method found. Their offer: diffie-hellman-group1-sha1

The real issue is that most of the Cisco IOS versions use 1024-bit key size for Diffie-Hellman used for key exchange, by default. Though, there are old Cisco IOS versions that use 768-bit DH key size, by default. Prior the year of 2016, 1024-bit key size is adequate. However, NIST’s recommendation is to use 2048-bit key size or higher. Furthermore, the authors of the LogJam paper believes that it may be possible for a nation-state to break 1024-bit groups. Therefore, the authors recommend disabling DH Group 1.

router01(config)#sh ip ssh
<-- Output omitted for brevity -->
Minimum expected Diffie Hellman key size : 1024 bits
router01(config)#ip ssh dh min size ?
  1024  Diffie Group 1 1024-bit key
  2048  Diffie Group 14 2048-bit key
  4096  Diffie Group 16 4096-bit key
router01(config)#ip ssh dh min size 4096

Below shows the verbose output of a Cisco IOS device using the SSH configuration mentioned above.

Mac-mini:~ networkjutsu$ ss -vvv router01
OpenSSH_7.6p1, LibreSSL 2.6.2
<-- Output omitted for brevity -->
debug1: kex: algorithm: diffie-hellman-group-exchange-sha1
debug1: kex: host key algorithm: ssh-rsa
debug1: kex: server->client cipher: aes256-ctr MAC: hmac-sha1 compression: none
debug1: kex: client->server cipher: aes256-ctr MAC: hmac-sha1 compression: none

Note: Changing the DH key size to 4096 value may break some applications that connect to Cisco IOS devices. For example, HPE Opsware Network Automation (now Micro Focus) uses a Java-based SSH client that is incompatible with SSH servers that use higher than 2048-bit DH key.

Additional SSH configuration

The commands covered here deserves consideration since they increase the level of protection to Cisco IOS SSH server.

RSA keys

As covered in this post, I used 4096-bit modulus in the second example. Cisco IOS users should consider generating higher than NIST’s recommendation of the 2048-bit modulus. Generating higher than the recommended value may take a minute or two (depending on the platform). Additionally, it may take few seconds to get the prompt when connecting to a Cisco IOS device. That said, make sure to take the two facts into consideration before using higher than the recommended value. In theory, newer Cisco platforms could handle the higher values without a significant impact on performance.

router01(config)#crypto key gen rsa mod ?
  <360-4096>  size of the key modulus [360-4096]
router01(config)#crypto key gen rsa modulus 4096 label SSH_KEY
The name for the keys will be: SSH_KEY
% The key modulus size is 4096 bits
% Generating 4096 bit RSA keys, keys will be non-exportable...
[OK] (elapsed time was 103 seconds)

If you’re confused about the difference between RSA and DH mentioned here, then I recommend you to read this article. The article did a great job explaining the SSH connection process. If you just want to know the difference between the RSA and DH, then skip to the Negotiating Encryption for the Session section.

SSH authentication timeout

There is no reason to have a high authentication timeout, so it is recommended to lower the value to 60 seconds or less. This particular router has the SSH authentication timeout set to 120 seconds. We’ll change it to 30 seconds.

router01#sh ip ssh
SSH Enabled - version 2.0
Authentication methods:publickey,keyboard-interactive,password
Authentication timeout: 120 secs; Authentication retries: 3
<-- Output omitted for brevity -->
router01#conf t
Enter configuration commands, one per line.  End with CNTL/Z.
router01(config)#ip ssh time-out 30
router01(config)#do sh ip ssh
SSH Enabled - version 2.0
Authentication methods:publickey,keyboard-interactive,password
Authentication timeout: 30 secs; Authentication retries: 3
<-- Output omitted for brevity -->

Line VTY

There four Cisco IOS features under VTY configuration that deserves consideration because they provide an increased level of protection to networking devices.

SSH transport protocols

As mentioned in this post, by default, Cisco IOS still allows telnet connection when the user doesn’t disable it. To disable, please issue the command below. If you only need 5 vty lines, I suggest disabling the remaining vty lines.

router01(config)#line vty 0 4
router01(config-line)#transport input ssh
router01(config)#line vty ?
  <0-98>  First Line number
router01(config)#line vty 5 98
router01(config-line)#transport input none

SSH ACL

Creating and applying ACL to SSH is best practice, so I decided to cover it here, even though this is considered very basic security.

router01(config)#access-list 1 permit 172.16.0.0 0.0.0.63
router01(config)#access-list 1 permit 192.168.100.0 0.0.0.255
router01(config)#line vty 0 4
router01(config-line)#access-class 1 in

Session timeout

I think this is one of the controversial settings that require some discussions with the networking team. The STIG recommends to set it to 10 minutes or less. By default, Cisco IOS uses 10 minutes for this setting. Please feel free to change it to something else that follows your security policy or suggested setting by the networking team.

router01#sh run all | sec line vty
line vty 0 4
 motd-banner
 exec-banner
 exec-timeout 10 0
<-- Output omitted for brevity -->
router01(config)#line vty 0 4
router01(config-line)#exec-timeout ?
  <0-35791>  Timeout in minutes
router01(config-line)#exec-timeout 5 ?
  <0-2147483>  Timeout in seconds
router01(config-line)#exec-timeout 5 0

Final Words

All of the configurations covered here are what I’d say minimum security standard for all Cisco IOS devices. My advice for my fellow network engineers looking to secure network devices against management plane attacks must consider including this in their configuration template. Though, this blog post is just a small part of protecting the management plane. That said, I urge my fellow network engineers to research more about other settings that protect the management plane.

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.

Want to learn more about securing Cisco IOS?

CCNP Security Secure 642-637 Official Cert Guide

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

Hardening EdgeRouter Lite – Part 4

12/06/2016 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

This blog post is part of a series on EdgeRouter Lite. You may want to check them all out!

DateTitleDescription
03/13/16My Home Router – EdgeRouter LiteQuick introduction to EdgeRouter Lite
04/09/16Ubiquiti’s EdgeOS CLI IntroductionEdgeOS CLI Primer
05/01/16How to configure EdgeRouter Lite via CLI – Part 1EdgeOS configuration guide for CLI junkies
05/01/16How to configure EdgeRouter Lite via CLI – Part 2EdgeOS configuration guide for CLI junkies
12/03/16Hardening EdgeRouter Lite – Part 1Basic management hardening
12/04/16Hardening EdgeRouter Lite – Part 2EdgeOS with two-factor authentication
12/05/16Hardening EdgeRouter Lite – Part 3Management ACL

Introduction

In my How to configure EdgeRouter Lite via CLI – Part 2 post, there is an L2TP via IPsec section. The commands shown in that blog post works great. However, there are security concerns with that configuration. The remote-access VPN configuration uses pre-shared secret for machine authentication and user authentication with no two-factor authentication (2FA). In this post, I will demonstrate how to harden remote-access VPN connectivity on EdgeRouter Lite.

User Authentication with 2FA

As mentioned in my how-to configure guide, I prefer L2TP over IPsec, so this post will only cover that. The configuration demonstrated here requires a RADIUS server, such as FreeRADIUS. Check my blog post about it if you want to create your own. If you chose the local Google Authenticator route, there might be a way to tie that with user authentication. That is, however, out of the scope of this post.

The EdgeOS has two L2TP modes for user authentication, local and RADIUS. In my how-to guide, it showed the use of the local account which is separate from device management. As previously discussed, username and password are no longer considered secure today. That said, we’re going to add another factor of authentication to the account.

EdgeOS Commands

The first command is to change user authentication mode to RADIUS.

set vpn l2tp remote-access authentication mode radius

The second command is to point the device to the RADIUS server and enter the key you want to use.

set vpn l2tp remote-access authentication radius-server 192.168.250.250 key supersecretkey

The last command is to change the default protocol from MS-CHAPv2 to PAP. Unfortunately, Google Authenticator will only work with PAP, as far as I know.

set vpn l2tp remote-access authentication require pap

Don’t forget to commit and save the configuration. Issue the commit;save command.

FreeRADIUS Configuration

In my FreeRADIUS blog post, there were only a few lines that needed to be changed or added to the config files. Aside from those modifications the files were left in the default state. That’s okay for the most part. However, when we try to access VPN, it takes a bit longer than using the local account. In this section, we’re going to make some optimizations to speed up the process of authentication.

Related: How to implement Duo Security MFA

I am a FreeRADIUS newbie, so I do not know what all of these lines mean, but I commented them out to speed up the process of authentication. I just looked at the debug using sudo freeradius -X command and tried to interpret what it was saying. The lines that included noop, I figured they are not needed for my environment, so I commented them out. Every time I made the change, I tested my VPN to make sure I was able to log in still. If you are currently using or going to use this FreeRADIUS instance for other purposes, then be careful of what you comment out because it may break. Remember, I only use this for remote access VPN and device authentication.

Edit the /etc/freeradius/sites-enabled/default file.

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

Find the following and comment them out.

authorize {
#      chap
#      mschap
#      suffix
#      eap {
#              ok = return
#      }
#      expiration
#      logintime
#      pap
authenticate {
#      Auth-Type PAP {
#              pap
#      }
#      Auth-Type CHAP {
#              chap
#      }
#      Auth-Type MS-CHAP {
#              mschap
#      }
#      digest
#      eap
preacct {
#      suffix
#      files
accounting {
#      exec
post-auth {
#      exec

Next step is to edit the clients.conf file. From what I can tell, this is kind of like an ACL. If you do not add the router’s source IP address, then FreeRADIUS will ignore the traffic from the router. Once you open the file using VI or your favorite text editor, look for the client localhost { line and add the lines listed below.

$ sudo vi /etc/freeradius/clients.conf
client rtr {
        ipaddr = 192.168.1.1
        secret = secretkey
}
client localhost {

Since we made changes to the files, we need to restart the service for it to take effect.

$ sudo service freeradius restart

Verification

Now, go ahead and test your VPN connectivity to see if it works. If everything works, then you can now delete the local account from the configuration. Remember, the format for the password is password+TOTP.

delete vpn l2tp remote-access authentication local-users username unique-username-here password your-unique-password-here

Troubleshooting

When you are troubleshooting FreeRADIUS, it is very helpful to use the freeradius -X command. This helped me figure out some issues that I’ve encountered when setting this up. This command may be different in other Linux distro, though. Just check the documentation for the right command. From what I can tell, all Debian-based Linux distro uses this command.

Before you can issue the debug command, you need to stop FreeRADIUS service first or you will get an error, as shown below.

$ sudo freeradius -X
<-- Output omitted for brevity -->
Failed binding to authentication address * port 1812: Address already in use
/etc/freeradius/radiusd.conf[273]: Error binding to port for 0.0.0.0 port 1812
$ sudo service freeradius stop
$ sudo freeradius -X
<-- Output omitted for brevity -->
Listening on authentication address * port 1812
Listening on accounting address * port 1813
Listening on authentication address 127.0.0.1 port 18120 as server inner-tunnel
Listening on proxy address * port 1814
Ready to process requests.

Once you’re done with troubleshooting, make sure to start the service back up with sudo service freeradius start command.

Final Words

The problem with local authentication is that we need to enter user account details within EdgeOS. That said, anyone who has admin-level access on EdgeOS will be able to view the password of the users. Changing the remote access VPN authentication from local to RADIUS is a more secure option. On top of that, we can add another factor of authentication.

For the most part, this is secure enough. In fact, I’ve seen a lot of organizations that use a similar setup. However, some organizations or people want to implement the securest method possible for their remote access VPN. That said, they need to implement certificate-based machine authentication. Heck, they may even combine both 2FA and certificate-based machine authentication for maximum security.

If I ever get the L2TP over IPsec working using certificates, then I will cover it in my next blog post. I know it’s possible, but my client is stuck in IKE Phase 1. The problem is most likely my certificates.

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

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 Previous Page
  • Go to page 1
  • Go to page 2
  • Go to page 3
  • Go to page 4
  • Go to page 5
  • 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