• Skip to main content
  • Skip to footer

Andrew Roderos

Networking and Security

  • Blog
  • Resources
    • Book List
    • Freebies
  • About
  • Contact

Deploying TACACS+ on a Docker container

11/21/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
tacacs+ docker container

Back in 2011, I wrote how to configure tac_plus (TACACS+ daemon) on an Ubuntu server. Then two years ago, I wrote an article about adding two-factor authentication (2FA) to TACACS+. Today, I’m going to talk about deploying TACACS+ on a Docker container.

While I’ve written migrating FreeRADIUS with 2FA to a Docker container article in the past, I’d still consider myself a newbie. I don’t deal with Docker daily to be well-versed.

Related: VMware ESXi Home Lab – Intel NUC 10 (Frost Canyon)

Since I’m still a newbie, I make mistakes writing a Dockerfile and sometimes get stuck when the container keeps restarting. Part of the problem is I’m still learning Linux even though I’ve been using it for many years.

Another part is I have yet to sit down and read a book about Docker, like this one. The book has a high rating on Amazon and seems like a good buy if you’re trying to learn it.

Yes, I could download someone else’s Docker container. However, I don’t like doing that. When I write the Dockerfile from scratch, it forces me to learn both Docker and Linux.

Docker Installation

Before we can deploy a TACACS+ container, we need to install the Docker software. Docker’s documentation has the steps on how to do it on your preferred OS. For this tutorial, I’m using the Ubuntu Server 18.04 as my OS of choice.

andrew@networkjutsu:~$ sudo apt-get update
andrew@networkjutsu:~$ sudo apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common -y
andrew@networkjutsu:~$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
andrew@networkjutsu:~$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
andrew@networkjutsu:~$ sudo apt-get install docker-ce docker-ce-cli containerd.io -y
andrew@networkjutsu:~$ sudo apt autoremove -y
andrew@networkjutsu:~$ docker --version
Docker version 19.03.4, build 9013bf583a

Alternatively, we can install the Docker version that Ubuntu is using in their repo. Installing from Ubuntu’s repo is the easiest way to install Docker.

andrew@networkjutsu:~$ sudo apt install docker.io -y
Reading package lists... Done
Building dependency tree
Reading state information... Done
<-- output="" omitted="" for="" brevity="" --="">
andrew@networkjutsu:~$ docker --version
Docker version 18.09.7, build 2d0083d

Docker Compose installation

I like to use the docker-compose command to run multiple containers in one syntax. That said, I have that installed on my Ubuntu server. This step is optional, but I highly recommend using it. If you have a different OS, then visit this page.

andrew@networkjutsu:~$ sudo curl -L "https://github.com/docker/compose/releases/download/1.24.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
andrew@networkjutsu:~$ sudo chmod +x /usr/local/bin/docker-compose
andrew@networkjutsu:~$ docker-compose --version
docker-compose version 1.24.1, build 4667896b

Dockerfile

I like to separate my files for each Docker containers that I want to deploy. That said, I created new directories for each of them.

andrew@networkjutsu:~$ mkdir tacacs

Once I’ve created the directory, it’s time to write the Dockerfile. Since I’m more familiar with VIM than any other text editor on Linux, that’s what I use. Please feel free to use your favorite Linux text editor.

andrew@networkjutsu:~$ vi tacacs/Dockerfile

Once VIM is running, we can now write the contents of our Dockerfile. Here’s a sample of my TACACS+ Dockerfile.


Do you find this content useful? If so, consider buying me a coffee! ☕



# Use Base Ubuntu image
FROM ubuntu:18.04
# Author of this Dockerfile
MAINTAINER Andrew Roderos 
# Update & upgrades
RUN apt-get update && apt-get upgrade -y
# Install tacacs+ and Google Authenticator
RUN apt-get install tacacs+ libpam-google-authenticator -y
# Clear local repo
RUN apt-get clean
# Create a user with home directory
RUN useradd -m -d /home/andrew -s /bin/bash andrew
# Add password to andrew account
RUN echo "andrew:makemypasswordgreatagain" | chpasswd
# Copy Google secret key from host's volume to tacacs+ container
COPY .google_authenticator /home/andrew
# Change file owner
RUN chown andrew:andrew /home/andrew/.google_authenticator
# Copy tac_plus configuration file from host to the container
COPY tac_plus.conf /etc/tacacs+/tac_plus.conf
# Add tac_plus PAM
RUN touch /etc/pam.d/tac_plus
RUN echo auth requisite pam_google_authenticator.so forward_pass >> /etc/pam.d/tac_plus
RUN echo auth required pam_unix.so use_first_pass >> /etc/pam.d/tac_plus
# Run tac_plus as foreground process and use /etc/tacacas+/tac_plus.conf as the config file
CMD ["tac_plus", "-G", "-C", "/etc/tacacs+/tac_plus.conf"]

Preliminary steps

Before we can build the TACACS+ Docker container, we need to do some preliminary steps. As you can see from the Dockerfile, it will copy some files that I already have in the current directory. Without these files, the docker build command will error out.

Google Authenticator secret key

The first file we need is the .google_authenticator file. This file contains all the necessary parameters for our TOTP (Time-based One Time Password).

Since I use Google Authenticator at home, I just copied my existing file for this lab. If you don’t have one, you may want to generate one from another host. I covered the generation of the secret key in this article.

Once you’ve generated the secret key, we can now copy the .google_authenticator file in the home directory. Please copy it to the tacacs directory.

andrew@networkjutsu:~$ cp .google_authenticator tacacs

TACACS+ configuration file

The next file we need is the tac_plus.conf file. This file gets generated when you install tac_plus software. Since I’ve covered this topic before, I already have a configuration file that I can use. If you don’t have one, then you can use my configuration files from here and here.

If you do create this from scratch, make sure the owner and permissions are the same as the one below.

andrew@networkjutsu:~/tacacs$ ls -l tac_plus.conf
-rw------- 1 root root 3108 Nov 4 18:43 tac_plus.conf

Depending on how you create the file, the owner and permissions are different. For example, I created the tac_plus.conf file using a non-root account.

andrew@networkjutsu:~/tacacs$ ls -l tac_plus.conf
-rw-rw-r-- 1 networkjutsu networkjutsu 3108 Nov 4 20:41 tac_plus.conf

There are multiple options to fix this minor issue. One option is by deleting the file and recreating it using the root account.

andrew@networkjutsu:~/tacacs$ rm tac_plus.conf
andrew@networkjutsu:~/tacacs$ sudo vi tac_plus.conf
andrew@networkjutsu:~/tacacs$ sudo chmod 600 tac_plus.conf
andrew@networkjutsu:~/tacacs$ ls -l tac_plus.conf
-rw------- 1 root root 3108 Nov 4 20:44 tac_plus.conf

Another option is adding some lines to the Dockerfile to change the owner and permissions. Add the following lines after the COPY tac_plus.conf /etc/tacacs+/tac_plus.conf line.

# Change owner from andrew to root
RUN chown root:root /etc/tacacs+/tac_plus.conf
# Change permission to root only access
RUN chmod 600 /etc/tacacs+/tac_plus.conf

Creating a Docker image

Once done with the preliminary steps, we can now create our TACACS+ Docker image. Creating a Docker image is pretty straightforward. All we need to do is issue the command below.

andrew@networkjutsu:~/tacacs$ docker build -t tacacs .
Sending build context to Docker daemon  8.192kB
Step 1/14 : FROM ubuntu:18.04
 ---> 452a96d81c30
Step 2/14 : MAINTAINER Andrew Roderos 
 ---> Using cache
 ---> 1c717e03db89
<-- output="" omitted="" for="" brevity="" --="">

Once the building process is done, you can verify that the Docker image is ready by issuing the command below.

andrew@networkjutsu:~/tacacs$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
tacacs              latest              32a7bc92b24a        2 minutes ago       205MB
radius              latest              c558d1437285        33 hours ago        248MB

Docker Compose

We’re now ready to run the Docker image. If you prefer to use docker run syntax, then feel free to use that one. I happen to like to use the docker-compose command when starting up Docker containers. That said, we need to edit my existing docker-compose.yml file before we can run the Docker container.

andrew@networkjutsu:~/tacacs$ vi ../docker-compose.yml

The file should look like the one below.

andrew@networkjutsu:~/tacacs$ cat ../docker-compose.yml
version: "3"
services:
  radius:
    container_name: radius
    image: radius
    ports:
    - "192.168.200.51:1812:1812/udp"
    - "192.168.200.51:1813:1813/udp"
    - "192.168.200.51:18120:18120/udp"
    environment:
    - VIRTUAL_HOST=radius.networkjutsu.local
    restart: always
    volumes:
    - /etc/timezone:/etc/timezone:ro
    - /etc/localtime:/etc/localtime:ro
  tacacs:
    container_name: tacacs
    image: tacacs
    ports:
    - "192.168.200.49:49:49/tcp"
    environment:
    - VIRTUAL_HOST=tacacs.networkjutsu.local
    restart: always
    volumes:
    - /etc/timezone:/etc/timezone:ro
    - /etc/localtime:/etc/localtime:ro

Now, we’re ready to run our TACACS+ Docker container.

andrew@networkjutsu:~$ docker-compose up -d
Creating tacacs ...
radius is up-to-date
Creating tacacs ... done
andrew@networkjutsu:~/tacacs$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                                                      NAMES
1a6eb28498d6        tacacs              "tac_plus -G -C /etc…"   14 seconds ago      Up 13 seconds       192.168.200.49:49->49/tcp                                                  tacacs
946d992dddb5        radius              "freeradius -f"          17 hours ago        Up 17 hours         192.168.200.51:1812-1813->1812-1813/udp, 192.168.200.51:18120->18120/udp   radius

If the status says Restarting, then that means there’s something wrong with the tac_plus.conf file or Dockerfile. You might have to spend some time troubleshooting if your config isn’t the same as mine.

Note: The instructions covered here are not recommended for production use since it’s running the container as root.

Verification

Once the Docker container is running, then we’re now ready to verify if our TACACS+ is working as expected. This step assumes that you already have an IOS device with a TACACS+ configuration. If you need a sample configuration, please check out my article.

R1 con0 is now available
Press RETURN to get started.
User Access Verification
Username: andrew
Password & verification code: makemypasswordgreatagain468792
R1>en
Password: makemypasswordgreatagain
R1#

Note: The example above was done using the CSR 1000v and may not represent what the prompt would look like on regular IOS-based devices.

Final Words

OS-level virtualization, such as Docker, offers a lot of advantages over server virtualization. One of the benefits of OS-level virtualization is that it consumes fewer system resources compared to VMs. It is the major reason why I run containers for my FreeRADIUS and TACACS+ services.

Additionally, if done right, it’s faster for me to deploy something on Docker than provisioning new VMs. Though, with the mistakes I’ve done in the past, I am sure I could’ve provisioned new VMs a lot faster.

Just because everyone is doing Docker containers, doesn’t mean you should follow suit. Make sure to weigh in the pros and cons of running services, such as TACACS+, on Docker.

You might like to read

VMware ESXi Home Lab – Intel NUC (Frost Canyon)
Blocking ads network-wide
How to implement Duo Security MFA


BUY ME COFFEE ☕

Did you find this content useful? If so, show your appreciation by buying me a coffee!



Disclosure

AndrewRoderos.com is a participant of a few referral programs, an affiliate advertising program designed to provide a means for sites to earn advertising fees by advertising and linking to company websites.

  • 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

Filed Under: Open Source Tagged With: Docker, Linux, TACACS+, Ubuntu

About Andrew Roderos

I am a network security engineer with a passion for networking and security. Follow me on Twitter, LinkedIn, and Instagram.

Footer

WANT TO REACH ME?

Let’s talk!

CONTACT ME

Copyright © 2019–2023 · Andrew Roderos · All Rights Reserved · Privacy Policy · Terms of Use