DEV Community

Cover image for UFW and Docker Security on Linux machine
Andy Lim
Andy Lim

Posted on

UFW and Docker Security on Linux machine

Uncomplicated Firewall (UFW) is served as a frontend tool for iptables in Linux-based machine. It's used to provide easy interface to manage firewall so you don't have to manage them through complicated iptables and netfilter commands.

So today I tried experimenting UFW with NGINX running as a Docker container on Amazon Linux 2 EC2 instance in my AWS environments.

Before this, I have launched an Amazon Linux 2 EC2 instance and have SSH and TCP port 80 allowed for incoming request in the security group attached to the instance.

Install UFW

First, ssh into the EC2 instance.

$ ssh -i example.pem ec2-user@1.23.45.678
Enter fullscreen mode Exit fullscreen mode

By default, UFW is not pre-installed on Amazon Linux 2 and not available in RHEL repository. We will need to install EPEL repository to our system.

$ sudo yum update -y 
$ sudo yum install epel-release -y
Enter fullscreen mode Exit fullscreen mode

Then, install UFW by running command below:

$ sudo yum install --enablerepo="epel" ufw -y
Enter fullscreen mode Exit fullscreen mode

Then, start UFW service and enable it to start on boot time.

$ sudo ufw enable
Enter fullscreen mode Exit fullscreen mode

Run command below to ensure UFW is running:

$ sudo ufw status
Enter fullscreen mode Exit fullscreen mode

Install Docker

Next, install Docker runtime in the instance:

$ sudo amazon-linux-extras install docker
$ sudo service docker start
$ sudo usermod -a -G docker ec2-user
Enter fullscreen mode Exit fullscreen mode

Confirm Docker is installed and you see version as output:

$ sudo docker -v

Docker version 20.10.7, build f0df350
Enter fullscreen mode Exit fullscreen mode

Then, run a NGINX container using command below:

$ sudo docker run -d --name my-nginx -p 80:80 nginx
Enter fullscreen mode Exit fullscreen mode

This command will pull the Docker image from Docker Hub and run as a container on local Docker runtime. Run command below to see if my-nginx container is running:

$ sudo docker ps

CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS                               NAMES
c3aee3db60f1   nginx     "/docker-entrypoint.…"   22 seconds ago   Up 21 seconds   0.0.0.0:80->80/tcp, :::80->80/tcp   my-nginx
Enter fullscreen mode Exit fullscreen mode

Next, run curl command to see if your website is running perfect or go to your browser and search.

$ curl -L 1.23.45.678:80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

You will see a beautiful NGINX website in front of you!
Nginx

Problem arises

Next, here is something fun: I want to deny anyone looking for this website through UFW!

Go back to your EC2 instance. Run the command below to enable the rule of denying incoming request with port 80 in UFW:

$ sudo ufw deny 80


Rule updated
Rule updated (v6)
Enter fullscreen mode Exit fullscreen mode

Validate the deny rule is enabled:

$ sudo ufw status
Status: active

To                         Action      From
--                         ------      ----
SSH                        ALLOW       Anywhere
224.0.0.251 mDNS           ALLOW       Anywhere
22                         ALLOW       Anywhere
80                         DENY        Anywhere
SSH (v6)                   ALLOW       Anywhere (v6)
ff02::fb mDNS              ALLOW       Anywhere (v6)
22 (v6)                    ALLOW       Anywhere (v6)
80 (v6)                    DENY        Anywhere (v6)

Enter fullscreen mode Exit fullscreen mode

Now, test on your host machine and check again. You should not be able to see the NGINX website on your host machine!

$ curl -L 1.23.45.678:80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

Why are you still here.....

Nginx-2

What's the problem and how to fix it

From Docker documentation, I only learned that by default, Docker directly manipulates iptables for network isolation.

There are several ways to disable this. One of it is that we don't expose the port 80.

Another way is, we can disable this Docker behaviour by creating or modifying /etc/docker/daemon.json.

$ sudo vi /etc/docker/daemon.json

{ "iptables": false }

$ sudo service docker restart
Enter fullscreen mode Exit fullscreen mode

By this, we don't have to worry if other port is exposed and open when we run another container with different ports exposed.

Last, try to connect again:

$ curl -L 1.23.45.678:80

curl: (7) Failed to connect to 1.23.45.678 port 80: Operation timed out
Enter fullscreen mode Exit fullscreen mode

Done!

Conclusion

This article may not explain well about the fundamental of Linux security and you may think why do I need UFW when there's security group attached on EC2 instance and you can configure the allow/deny rules easily from security group.

Well, it's for experiment purpose! I never learned about UFW or security related topics in Linux and I thought security group is the only solution to secure my instances.

Let me know in the comments about your thoughts too!

Happy coding! 💻

Discussion (2)

Collapse
rtribaldos profile image
Ricardo Tribaldos

This is a very bad idea, if you run multiple services in Docker they won't be able to talk to each other.. For more info github.com/chaifeng/ufw-docker

Collapse
andylim0221 profile image
Andy Lim Author • Edited

Thank you for the comment and the Github link. I wasn't aware of this issue.. It definitely helps and I can use this for my next experiment. ;)