Configuring ufw for Flynn
This posting might be a bit niche but could be nice for someone facing the same problem. :)
It is about how to configure your Uncomplicated Firewall (ufw) on machines running a Flynn cluster.
Flynn is a self hosted platform as a service which is easy to setup and operate. So lets ease the firewall configuration a bit.
We’ve choosen ufw as it is really rather uncomplicated. So the implementation sounds easy enough, but comes with a few gotchas which is why I write this article in order to complement the official documentation.
The Goal
The documentation defines the goal of our firewall setup. Quote:
A firewall preventing external access must always be configured on or in front of Flynn hosts, only these ports should be allowed:
- 80 (HTTP) - 443 (HTTPS) - 3000 to 3500 (user-defined TCP services, optional)
Internal cross-host cluster communication happens on a variety of UDP and TCP ports and should not be restricted.
Outbound Internet access is required to deploy apps using many of the default buildpacks.
The Implementation
All firewall rules stated here must be executed on each node of the Flynn cluster. We run currently a cluster of three nodes and they all have the same firewall configuration.
First of all, lets open up the list of ports to the world:
sudo ufw allow ssh
sudo ufw allow http
sudo ufw allow https
sudo ufw allow 3000:3500/tcp
I added ssh so I still can maintain the machines.
And now, the nodes itself need to communicate on different ports:
sudo ufw allow from x1.y1.z1.w1
sudo ufw allow from x2.y2.z2.w2
sudo ufw allow from x3.y3.z3.w3
Those “x1.y1.z1.w1”s are placeholders for the nodes IP addresses.
Don’t forget to turn the firewall on:
sudo ufw enable
And that’s it according to the documentation I thought. But the bootstrapping of the cluster failed with timeouts. So there must be something left which brings me to the first gotcha:
After installing Flynn and starting the flynn-host daemon, some network interfaces are created which must be allowed:
sudo ufw allow in on flynnbr0
sudo ufw allow in on flannel.1
The second gotcha:
And as all Flynn applications run in Docker, also the internal ones like the router or Postgres, ufw needs to forward some traffic. So you need to edit ufw’s configuration file on each host:
sudo nano /etc/default/ufw
There you set the forwarding:
DEFAULT_FORWARD_POLICY=”ACCEPT”
Now all which is left over is to reload the firewall:
sudo ufw reload
The Result
That should be it, the Flynn cluster bootstrapped just fine after this set of configuration. My final ufw ruleset looks like this:
sudo ufw status verbose
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), allow (routed)
New profiles: skip
To Action From
– —— —-
22 ALLOW IN Anywhere
80 ALLOW IN Anywhere
443 ALLOW IN Anywhere
3000:3500/tcp ALLOW IN Anywhere
Anywhere ALLOW IN x1.y1.z1.w1
Anywhere ALLOW IN x2.y2.z2.w2
Anywhere ALLOW IN x3.y3.z3.w3
Anywhere on flynnbr0 ALLOW IN Anywhere
22 (v6) ALLOW IN Anywhere (v6)
80 (v6) ALLOW IN Anywhere (v6)
443 (v6) ALLOW IN Anywhere (v6)
3000:3500/tcp (v6) ALLOW IN Anywhere (v6)
Anywhere (v6) on flynnbr0 ALLOW IN Anywhere (v6)
Anywhere (v6) on flannel.1 ALLOW IN Anywhere (v6)
One final note (also to myself): If you add nodes to your cluster in advance, you have to add the new IP address(es) to all your nodes firewalls.
At some point I might turn this posting into a FAQ entry of the Flynn documentation and make a pull request.