Remove exposed Postgres/Stratux ports on public boxes
Demo server (135.181.254.90) was affected by this.
---
Docker, when exposing ports, binds directly to the network interfaces. It then adds rules to `iptables`' `PREROUTING` chain. `ufw` adds rules into the filter table, and since the packets have already been rewritten by the `PREROUTING` rules, `ufw`'s rules are never even evaluated.
The previous solution involving simple filters like:
```
-A DOCKER-USER -p tcp --dport 6379 ! -s 135.181.254.90 -j DROP
```
have worked properly for Redis and Postgres, but they have not worked for Stratux. Explanation below.
---
As an alternative solution, I have setup [`ufw-docker`](https://github.com/chaifeng/ufw-docker) on the server, which made all Docker containers shut off by default, just like `ufw` does by default. It works by hooking into `DOCKER-USER` chain, which sits before `ufw`'s chains, and overrides stuff there, and adding routes as needed. It uses data from `docker` engine, allowing specific containers to be exposed and routed to, by their specific Docker internal IPs.
This matters a lot, as the "universal" rules we used below would not apply to Stratux. Something in the `PREROUTING` table caused Stratux to be exposed whenever the frontend container was exposed.
Frontend container is exposed by its port `80` to port `80` (config: `80:80`), and Stratux is also exposed by its port `80`, but to port `8080` (config: `8080:80`). When switching to `ufw-docker`'s route-based blocking (but without using the `ufw-docker` script), and going a simple `ufw allow 80`, that command allowed both to be accessed, then deleting the rule caused both to be inaccessible.
What `ufw-docker` does, is actually map to a specific container, routing packets where they should actually go, regardless of the configuration and preventing this sort of issue at the very start.
However, neither Docker nor Compose provide any predictability in what internal IP is going to be assigned to what container. That means that, after a reboot or `docker compose down && docker compose up`, the allow rule would very likely effectively stop working.
Here comes the MR. As on the demo machine, we only need frontend and backend containers to be exposed to the public, I have assigned static IPs only to them, so that the `ufw-docker` rules are actually working across reboots (and space and time :D).
---
Changes from the linked MR have been applied. After that, these commands were run (as root):
```
# Reset UFW to defaults
ufw --force reset
reboot
# Install ufw-docker
wget -O /usr/local/bin/ufw-docker \
https://github.com/chaifeng/ufw-docker/raw/master/ufw-docker
chmod +x /usr/local/bin/ufw-docker
# Set it up
ufw-docker install
#
# Setup the firewall rules
#
ufw-docker allow frontend 80
# Output:
# $ ufw-docker allow frontend 80
# allow frontend 80/tcp whitebox-net
# ufw route allow proto tcp from any to 10.38.130.2 port 80 comment allow frontend 80/tcp whitebox-net
# Rule added
ufw-docker allow backend 8000
# Output:
# $ ufw-docker allow backend 8000
# allow backend 8000/tcp whitebox-net
# ufw route allow proto tcp from any to 10.38.130.1 port 8000 comment allow backend 8000/tcp whitebox-net
# Rule added
```
---
You can now test accessibility of running services:
```
# Should work
nc -zv 135.181.254.90 80 -w 3
nc -zv 135.181.254.90 8000 -w 3
# Should not work
nc -zv 135.181.254.90 6379 -w 3
nc -zv 135.181.254.90 5432 -w 3
nc -zv 135.181.254.90 8080 -w 3
```
# MRs
- https://gitlab.com/whitebox-aero/whitebox/-/merge_requests/231
issue