I stumbled upon this old git repo that initializes an iptables base with LXC and web, ftp containers. I tested it, and it works without issues.
DHCP, DNS for container creation OK.
Internet in containers OK.
There are NAT forwarding rules to direct traffic 80,443 to the containers, let’s set aside this rule, but what about the rest?
My question is : With an Incus in 2024, is it still relevant to implement the entire set of iptables rules from this file? Or is it completely useless? Does it not provide any additional security benefits ?
In writing, here is what all the rules do
(Of course, we replace lxdbr0 with incusbr0)
* We reject nmap scans of type fragment, null, xmas and all "NEW" connections that do not start with a SYN
* We allow the Debian machine to communicate with the container on DHCP/DNS protocols
* We allow traffic on localhost
* We accept all outgoing connections from Debian
* We allow outgoing traffic from the container
* We accept INPUT and FORWARD traffic from the public interface of the Debian server (ens33) on ports 80 (container HTTP), 443 (container HTTPS), 2121 (container FTP)
* We accept INPUT traffic from the public interface of the Debian server (ens33) on ports 2202 (Debian SSH), 8000 (Debian Apache in HTTPS)
* We log all INPUT/OUTPUT/FORWARD Denied traffic
* We reject all INPUT/FORWARD traffic that does not match the previous rules
* We route packets destined for ports 80, 443, 2121 to the container
* We transform the IP of packets coming from the 10.0.10.0/24 subnet (container's private network) to a "public" IP
# /sbin/iptables-fw.sh
cat > /sbin/iptables-fw.sh << EOF
#!/bin/bash
# iptables firewall
# iptables configuration
fw_start() {
# Make sure NEW incoming tcp connections are SYN packets; otherwise we need to drop them:
iptables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP
# Packets with incoming fragments drop them
iptables -A INPUT -f -j DROP
# Incoming malformed XMAS packets drop them:
iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP
# Incoming malformed NULL packets:
iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
# DNS/DHCP lxc-net
iptables -A INPUT -i lxcbr0 -p tcp -m tcp --dport 53 -j ACCEPT
iptables -A INPUT -i lxcbr0 -p udp -m udp --dport 53 -j ACCEPT
iptables -A INPUT -i lxcbr0 -p tcp -m tcp --dport 67 -j ACCEPT
iptables -A INPUT -i lxcbr0 -p udp -m udp --dport 67 -j ACCEPT
iptables -A FORWARD -o lxcbr0 -j ACCEPT
iptables -A FORWARD -i lxcbr0 -j ACCEPT
# localhost traffic
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
# Accepts all established inbound connections
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
# Allows all outbound traffic:
iptables -A OUTPUT -j ACCEPT
# Allow all outbound traffic from Linux Containers:
#iptables -A FORWARD -i lxcbr0 -j ACCEPT
# Allow HTTP traffic (to be forwarded to the Linux Container hosting the server) :
iptables -A INPUT -i ens33 -p tcp --dport 80 -j ACCEPT
iptables -A FORWARD -i ens33 -p tcp --dport 80 -j ACCEPT
# Allow HTTPS traffic (to be forwarded to the Linux Container hosting the server) :
iptables -A INPUT -i ens33 -p tcp --dport 443 -j ACCEPT
iptables -A FORWARD -i ens33 -p tcp --dport 443 -j ACCEPT
# Allow FTP traffic (to be forwarded to the Linux Container hosting the server) :
iptables -A INPUT -i ens33 -p tcp --dport 2121 -j ACCEPT
iptables -A FORWARD -i ens33 -p tcp --dport 2121 -j ACCEPT
# Allows SSH to the host:
iptables -A INPUT -p tcp -m state --state NEW --dport 2202 -j ACCEPT
# Allows HTTP 8000 to the host:
iptables -A INPUT -p tcp -m state --state NEW --dport 8000 -j ACCEPT
# Allow ping
iptables -A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT
# log iptables denied calls (access via 'dmesg' command)
iptables -A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables INPUT denied: " --log-level 7
iptables -A OUTPUT -m limit --limit 5/min -j LOG --log-prefix "iptables OUTPUT denied: " --log-level 7
iptables -A FORWARD -m limit --limit 5/min -j LOG --log-prefix "iptables FORWARD denied: " --log-level 7
# Reject all other inbound - default deny unless explicitly allowed policy:
iptables -A INPUT -j DROP
iptables -A FORWARD -j DROP
# Forward HTTP traffic to the Linux Container running it:
iptables -t nat -A PREROUTING -i ens33 -p tcp -m tcp --dport 80 -j DNAT --to-destination 10.0.10.2:80
# Forward HTTPS traffic to the Linux Container running it:
iptables -t nat -A PREROUTING -i ens33 -p tcp -m tcp --dport 443 -j DNAT --to-destination 10.0.10.2:443
# Forward FTP traffic to the Linux Container running it:
iptables -t nat -A PREROUTING -i ens33 -p tcp -m tcp --dport 2121 -j DNAT --to-destination 10.0.10.2:2121
# Allow LXC subnet net access.
iptables -t nat -A POSTROUTING -s 10.0.10.0/24 -j MASQUERADE
}
# clear iptables configuration
fw_stop() {
iptables -F
iptables -X
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT
}
# execute action
case "\$1" in
start|restart)
echo "Starting firewall"
fw_stop
fw_start
;;
stop)
echo "Stopping firewall"
fw_stop
;;
esac
EOF
# /etc/systemd/system/iptables-fw.service
cat > /etc/systemd/system/iptables-fw.service << EOF
[Unit]
Description=iptables firewall service
After=network.target
[Service]
Type=oneshot
ExecStart=/sbin/iptables-fw.sh start
RemainAfterExit=true
ExecStop=/sbin/iptables-fw.sh stop
StandardOutput=journal
[Install]
WantedBy=multi-user.target
EOF
chmod 755 /sbin/iptables-fw.sh
systemctl enable iptables-fw
systemctl start iptables-fw