// Tutorial //

How to Configure the Linux Firewall for Docker Swarm on Ubuntu 16.04

Published on January 9, 2017
Default avatar
By finid
Developer and author at DigitalOcean.
How to Configure the Linux Firewall for Docker Swarm on Ubuntu 16.04

Introduction

Docker Swarm is a feature of Docker that makes it easy to run Docker hosts and containers at scale. A Docker Swarm, or Docker cluster, is made up of one or more Dockerized hosts that function as manager nodes, and any number of worker nodes. Setting up such a system requires careful manipulation of the Linux firewall.

The network ports required for a Docker Swarm to function correctly are:

  • TCP port 2376 for secure Docker client communication. This port is required for Docker Machine to work. Docker Machine is used to orchestrate Docker hosts.
  • TCP port 2377. This port is used for communication between the nodes of a Docker Swarm or cluster. It only needs to be opened on manager nodes.
  • TCP and UDP port 7946 for communication among nodes (container network discovery).
  • UDP port 4789 for overlay network traffic (container ingress networking).

Note: Aside from those ports, port 22 (for SSH traffic) and any other ports needed for specific services to run on the cluster have to be open.

In this article, you’ll learn how to configure the Linux firewall on Ubuntu 16.04 using the different firewall management applications available on all Linux distributions. Those firewall management applications are FirewallD, IPTables Tools, and UFW, the Uncomplicated Firewall. UFW is the default firewall application on Ubuntu distributions, including Ubuntu 16.04. While this tutorial covers three methods, each one delivers the same outcome, so you can choose the one you are most familiar with.

Prerequisites

Before proceeding with this article, you should:

Note: You’ll notice that the commands (and all the commands in this article) are not prefixed with sudo. That’s because it’s assumed that you’re logged into the server using the docker-machine ssh command after provisioning it using Docker Machine.

Method 1 — Opening Docker Swarm Ports Using UFW

If you just set up your Docker hosts, UFW is already installed. You just need to enable and configure it. Follow this guide to learn more about using UFW on Ubuntu 16.04.

Execute the following commands on the nodes that will function as Swarm managers:

  1. ufw allow 22/tcp
  2. ufw allow 2376/tcp
  3. ufw allow 2377/tcp
  4. ufw allow 7946/tcp
  5. ufw allow 7946/udp
  6. ufw allow 4789/udp

Afterwards, reload UFW:

  1. ufw reload

If UFW isn’t enabled, do so with the following command:

  1. ufw enable

This might not be necessary, but it never hurts to restart the Docker daemon anytime you make changes to and restart the firewall:

systemctl restart docker

Then on each node that will function as a worker, execute the following commands:

  1. ufw allow 22/tcp
  2. ufw allow 2376/tcp
  3. ufw allow 7946/tcp
  4. ufw allow 7946/udp
  5. ufw allow 4789/udp

Afterwards, reload UFW:

  1. ufw reload

If UFW isn’t enabled, enable it:

  1. ufw enable

Then restart the Docker daemon:

systemctl restart docker

That’s all you need to do to open the necessary ports for Docker Swarm using UFW.

Method 2 — Opening Docker Swarm Ports Using FirewallD

FirewallD is the default firewall application on Fedora, CentOS and other Linux distributions that are based on them. But FirewallD is also available on other Linux distributions, including Ubuntu 16.04.

If you opt to use FirewallD instead of UFW, first uninstall UFW:

  1. apt-get purge ufw

Then install FirewallD:

  1. apt-get install firewalld

Verify that it’s running:

  1. systemctl status firewalld

If it’s not running, start it:

  1. systemctl start firewalld

Then enable it so that it starts on boot:

  1. systemctl enable firewalld

On the node that will be a Swarm manager, use the following commands to open the necessary ports:

  1. firewall-cmd --add-port=22/tcp --permanent
  2. firewall-cmd --add-port=2376/tcp --permanent
  3. firewall-cmd --add-port=2377/tcp --permanent
  4. firewall-cmd --add-port=7946/tcp --permanent
  5. firewall-cmd --add-port=7946/udp --permanent
  6. firewall-cmd --add-port=4789/udp --permanent

Note: If you make a mistake and need to remove an entry, type: firewall-cmd --remove-port=port-number/tcp —permanent.

Afterwards, reload the firewall:

  1. firewall-cmd --reload

Then restart Docker.

  1. systemctl restart docker

Then on each node that will function as a Swarm worker, execute the following commands:

  1. firewall-cmd --add-port=22/tcp --permanent
  2. firewall-cmd --add-port=2376/tcp --permanent
  3. firewall-cmd --add-port=7946/tcp --permanent
  4. firewall-cmd --add-port=7946/udp --permanent
  5. firewall-cmd --add-port=4789/udp --permanent

Afterwards, reload the firewall:

  1. firewall-cmd --reload

Then restart Docker.

systemctl restart docker

You’ve successfully used FirewallD to open the necessary ports for Docker Swarm.

Method 3 — Opening Docker Swarm Ports Using IPTables

To use IPtables on any Linux distribution, you’ll have to first uninstall any other firewall utilities. If you’re switching from FirewallD or UFW, first uninstall them.

Then install the iptables-persistent package, which manages the automatic loading of IPtables rules:

  1. apt-get install iptables-persistent

Next, flush any existing rules using this command:

  1. netfilter-persistent flush

Now you can add rules using the iptables utility. This first set of command should be executed on the nodes that will serve as Swarm managers.

  1. iptables -A INPUT -p tcp --dport 22 -j ACCEPT
  2. iptables -A INPUT -p tcp --dport 2376 -j ACCEPT
  3. iptables -A INPUT -p tcp --dport 2377 -j ACCEPT
  4. iptables -A INPUT -p tcp --dport 7946 -j ACCEPT
  5. iptables -A INPUT -p udp --dport 7946 -j ACCEPT
  6. iptables -A INPUT -p udp --dport 4789 -j ACCEPT

After you enter all of the commands, save the rules to disk:

  1. netfilter-persistent save

Then restart Docker.

  1. sudo systemctl restart docker

On the nodes that will function as Swarm workers, execute these commands:

  1. iptables -A INPUT -p tcp --dport 22 -j ACCEPT
  2. iptables -A INPUT -p tcp --dport 2376 -j ACCEPT
  3. iptables -A INPUT -p tcp --dport 7946 -j ACCEPT
  4. iptables -A INPUT -p udp --dport 7946 -j ACCEPT
  5. iptables -A INPUT -p udp --dport 4789 -j ACCEPT

Save these new rules to disk:

  1. netfilter-persistent save

Then restart Docker:

  1. sudo systemctl restart docker

That’s all it takes to open the necessary ports for Docker Swarm using IPTables. You can learn more about how these rules work in the tutorial How the Iptables Firewall Works.

If you wish to switch to FirewallD or UFW after using this method, the proper way to go about it is to first stop the firewall:

  1. sudo netfilter-persistent stop

Then flush the rules:

  1. sudo netfilter-persistent flush

Finally, save the now empty tables to disk:

  1. sudo netfilter-persistent save

Then you can switch to UFW or FirewallD.

Conclusion

FirewallD, IPTables Tools and UFW are the three firewall management applications in the Linux world. You just learned how to use each to open the network ports needed to set up Docker Swarm. Which method you use is just a matter of personal preference, as they are all equally capable.

If you’ve enjoyed this tutorial and our broader community, consider checking out our DigitalOcean products which can also help you achieve your development goals.

Learn more here


About the authors
Default avatar
finid

author

Developer and author at DigitalOcean.

Default avatar
Developer and author at DigitalOcean.

Still looking for an answer?

Was this helpful?
6 Comments

This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Also note, with encrypted overlay networks you will need to allow inbound traffic on the workers for the ESP protocol.

sudo ufw allow proto esp

I’m having a tough time getting docker-machine to work properly, able to docker-machine ssh to a node but unable to use docker-machine env. And, my swarm is able to spin up containers on a worker, but unable to redirect traffic from a web browser to any services located only on a worker.

I’m now trying to add security group permissions based on this chart https://docs.docker.com/datacenter/ucp/2.2/guides/admin/install/system-requirements/#ports-used and the ports you suggested… but can you help explain why 4789 is not on the list and why the other ports you mentioned aren’t detailed with ingress and egress?

I have to log into EACH AND EVERY SERVER to configure the firewall ? What if I have 200 servers ? Or something I don’t get here ?

I ran a series of “ufw allow” commands, restarted docker, checked “ufw status” and see the firewall rules there. When I look at the droplet in my DO dashboard, the Networking->Firewalls section says “You haven’t applied any Firewalls to this Droplet yet.” Is the droplet firewall something different?

When I follow the instructions for setting up a swarm, the swarm works initially, but after a few minutes it becomes unreachable from docker cloud and from the docker for mac application. It says “Docker Cloud is receiving heartbeats, but cannot connect to the swarm Resolution: Swarm is not publicly reachable, it may be behind a firewall or NAT”

Anything else I should try? This is my ufw configuration:

22/tcp                     ALLOW       Anywhere
2376/tcp                   ALLOW       Anywhere
2377/tcp                   ALLOW       Anywhere
7946/tcp                   ALLOW       Anywhere
7946/udp                   ALLOW       Anywhere
4789/udp                   ALLOW       Anywhere
6783/tcp                   ALLOW       Anywhere
6783/udp                   ALLOW       Anywhere
2375/tcp                   ALLOW       Anywhere
443/tcp                    ALLOW       Anywhere
80/tcp                     ALLOW       Anywhere
8080/tcp                   ALLOW       Anywhere
9000/tcp                   ALLOW       Anywhere
9000/udp                   DENY        Anywhere
22/tcp (v6)                ALLOW       Anywhere (v6)
2376/tcp (v6)              ALLOW       Anywhere (v6)
2377/tcp (v6)              ALLOW       Anywhere (v6)
7946/tcp (v6)              ALLOW       Anywhere (v6)
7946/udp (v6)              ALLOW       Anywhere (v6)
4789/udp (v6)              ALLOW       Anywhere (v6)
6783/tcp (v6)              ALLOW       Anywhere (v6)
6783/udp (v6)              ALLOW       Anywhere (v6)
2375/tcp (v6)              ALLOW       Anywhere (v6)
443/tcp (v6)               ALLOW       Anywhere (v6)
80/tcp (v6)                ALLOW       Anywhere (v6)
8080/tcp (v6)              ALLOW       Anywhere (v6)
9000/tcp (v6)              ALLOW       Anywhere (v6)

Did you notice that when using ufw as a firewall and for example:

  • You have blocked all the ports with UFW except 22
  • You have docker container running with port binding “80:80”

The traffic will still go through to your docker container. Docker does some fancy stuff with iptables when running the containers. This does not seem very secure. Either you need to have your docker virtual networks carefully crafted or you need to bind the ports to 127.0.0.1:PORT:PORT, which I’m not sure how well with works in multi node swarm mode.

// JKON