Making UFW (firewalls) work inside containers? Or share log directory from container to main host?

As of today, I noticed that all UFW rules I add inside a container, simply are not working.I forgot there’s no “proxy” set up for the firewall to see which IP’s are connecting to the container, with the exception of nginx which is set up to reverse the ip address.

Is there anyway I can make this work? If not, if there’s a way for me to share a specific directory on the container, with the main host?

I’ve tried:

config device add container name disk source=xxxxxx path=xxxxxx

But that shares the host directory with the container, not the other way around. Unless I need to make it so the container can also write/read to the directory?

In this particular case, I’d like to share the web container access log files for fail2ban to read and to deny/reject on the main hosts firewall, if I can’t get the container firewall sorted.

Why not simply do all the firewalling and fail2ban processing inside the CT, instead of trying to access ssh/web/etc logs from the host? Personally I am not using UFW, but plain iptables works fine inside LXD containers (Debian 9 and 10) apart from the LOG functionality.

When using the lxdbr0 bridge (and thus NATted RFC1918 IPs for the CTs), I simply port-fwd the needed ports (e.g. 22, 25, 80, 443, 110 etc) from the host to the CT and then do all the packet filtering inside the CT (including ipsets).

When using macvlan (and thus a public IP for the CT), I configure iptables like any standalone system.

Well I’d like for my nginx-proxy to handle the firewall rules, but thus far I’m unable to get that working. It’s a bit hard if only nginx has been set-up for reverse proxy, any other IP address (for eg firewall) will be seen as the containers IP address.

So, you are saying I should NAT forward the ports (main hosts IP) to the container so expose the IP address of the host?

I actually install and configure iptables at both the host (filter + NAT) and the container (filter only). Although LXD can do masquerading (NAT) on the bridge, I usually prefer to handle it manually with prerouting & postrouting rules.

I prefer use the right tool for the job: iptables (+ipsets +modules) for firewalling and nginx for webserving.

Problem is I cannot set NAT on a device when proxy protocol exists on the device. I’m currently way too used in simplified firewall rules, as I truly find iptables over-complicated. They really should make it easier.

Anyway you can walk me to the process? As none of the firewalls on containers are working.

I use Ufw in the host (basic firewalling and natting to the containers) and I leave default iptables setup in the containers. If I setup fail2ban in a container I have always found it worked without problem, in the context I use containers, that is, always default bridge, and natting with ufw in the host. Never tried ipset in containers, not even explicit iptables rules, only the ones generated by fail2ban.

Problem is I use proxy protocol to get nginx to work. If I switch over to NAT, proxy no longer works

I don’t get it in your first post you were saying that while proxying with Nginx it worked so I understood that it was not working when not using Nginx :slight_smile: and so in this case you were using NAT (if not what else ?).
My post was just saying it was working for me with NAT. The IP banning with fail2ban in the container works for Natted accesses because the container sees the origin IP address.

I’m sure it’ll work when using NAT. But the problem is that I cannot use NAT on a device that’s already using proxy protocol. And my nginx proxy container is relying on the proxy protocol device to make it work.

So I assume, I have to include iptables rules with NAT device to make it work.

Just to clarify… I wish to replace the device “proxy protocol” with NAT. The only thing I need to know is what to include in the iptables to make the nginx proxy container to work again with the web containers when using NAT.


You know what… will make things easier… I’ll install nginx proxy device on my main host. Much easier.

First of all. UFW works fine in a container, but you can’t access the kernel logging from the container to the host without special permissions. Your problem is not clear.

You cannot use Fail2ban with UFW in unprivileged containers together. We can use NFLOG, but it is not supported at the moment in combination with UFW.

You can use NFLOG with IPTABLES and Fail2ban in an unprivileged container to secure it.

So I have to change the container to be privileged?

You can try that and test it. UFW uses iptables underwater. So it is not recommended to do this.

My advice is to just create a few iptable rules.
Use this guide.

After this:
apt-get install iptables-persistent
sudo /etc/init.d/iptables-persistent save
sudo /etc/init.d/iptables-persistent reload

to make it persistent.

UFW is the easiest way to actually manage the firewall… IPTables is just too complicated. Though it does appear to be “simple” to deny/reject or accept an IP address. I’d need to add port rules from the host IP to the containers IP address. Which is a tad more complicated, from my perspective.

Not to mention, I do enjoy using UFW as my main firewall (for fail2ban as well) for easier overview. Not sure why there isn’t any simplified GUI for iptables that makes these things… simple.

Give me the ports you need. I will give you the rules. It’s so simple to do this.

Only ports the firewall would have to read/listen to is 80/443. The web ports :slight_smile:

But currently proxy protocol exists on the config device to communicate with the web containers.

apt-get install iptables-persistent
Do not save the firewall rules when they ask for it.

Disable UFW:
ufw disable
systemctl disable ufw

Reboot the container and paste the following in your container:

iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p icmp -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
iptables -P INPUT DROP
iptables -P FORWARD DROP

Save the config:
sudo netfilter-persistent save

After this, your firewall is up & running. You can add rules in:
nano /etc/iptables/rules.v4
You can use this file to manage all IPv4 iptable configurations and reload it with:
sudo netfilter-persistent reload

Install fail2ban and configure it for NGINX.

Optional: apt-get install -y ulogd2 for iptables logging.

I use loglevel 5 in uglod2
nano /etc/ulogd.conf
Log-level: 5

Disable duplicate message filter to catch all the warnings:
nano /etc/rsyslog.conf
$RepeatedMsgReduction off

1 Like

Wow that’s a lot of rules, thanks. Will try it out.

I am curious though. What happens if the container is privileged? Are such rules still required? So I would know this for other containers in the future. If I would need it.

I think it is still a problem for privileged containers, but you dont want to use privileged containers with webservers inside. You don’t want the containers to have permissions on the host os. You want to separate web servers from each other, so that if one container is hacked for example, it does not hit the other containers or host directly.

This is the only nginx proxy container. Doesn’t contain any web related files. I do find it surprising though such rules are required to get firewalls up and running inside containers. I “attempted” (before you replied) to run nginx on the main host and with a proxy forward to the web containers, but I kept getting site errors. The nginx logs were showing some strange symbols.