Simple ACL rules in CumulusLinux without "--RELATED,ESTABLISHED"

  • 2
  • Article
  • Updated 2 years ago
  • (Edited)
I've wanted to create a simple enough ACL/IPTables rule: to allow HTTP/HTTPS (ports 80 and 443) traffic though to my cluster from greater net, allow all communication from specific hosts and networks and DROP everything else. (assuming eth1 is my public interface)
Generally, with iptables, I'd do something like that:
-A INPUT -i eth1 -s 10.10.0.50/32 -j ACCEPT
-A INPUT -i eth1 -p tcp --dport 80 -j ACCEPT 
-A INPUT -i eth1 -p tcp --dport 443 -j ACCEPT
-A INPUT -i eth1 -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i eth1 -j DROP
Which allows HTTP and HTTPS traffic explicitly, as well as my hand-picked host (10.10.0.50). If I have more hosts, I'd add them all to another chain with "-j ACCEPT" and would add that custom chain to the INPUT for interfaces of my choosing. Adding "RELATED, ESTABLISHED" state tracking allows for outgoing connections to work (though on the central network device with many connections going through it could cause issues, since connection tracking tables may get overloaded pretty quickly)

In CumulusLinux, however, you must use cl-acltool to validate and install ACL rules, iptables, ip6tables and ebtables. And it WILL REJECT rules not supported (accelerated) by the hardware. Software-only rules are not allowed.
And "--state RELATED,ESTABLISHED" is not supported by the hardware at the moment.

@MikeBrown of CumulusLinux Support provided solution that relies on TCP flags to achieve the same thing.

UPLINK=swp1,swp2
MYNETWORK=10.10.0.50/32
[iptables] 
# allow all new sessions from office network
-A INPUT,FORWARD --in-interface $UPLINK -p tcp -s $MYNETWORK --syn -j ACCEPT
# allow all new http sessions requested on this interface
-A INPUT,FORWARD --in-interface $UPLINK -p tcp --dport 80 --syn -j ACCEPT 
# allow all new https sessions requested on this interface
-A INPUT,FORWARD --in-interface $UPLINK -p tcp --dport 443 --syn -j ACCEPT 
# block all other new tcp sessions requested on this interface
-A INPUT,FORWARD --in-interface $UPLINK -p tcp --syn -j DROP

Since all new TCP sessions begin with SYN flag, blocking SYN from anywhere except selected IPs effectively disallows new connections to be established. Allowing SYN on specific ports, opens them up as well.

Hopefully, this  might help and save you some time writing your own rules.

~~~~~

P.S.

While trying this out in CumulusLinux VM, cl-acltool will not be available, so you'd have to use pure IPTables rules:

*filter:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
# INPUT
-A INPUT --in-interface eth0 -p tcp -s 10.10.0.50/32 --syn -j ACCEPT
-A INPUT --in-interface eth0 -p tcp --dport 80 --syn -j ACCEPT
-A INPUT --in-interface eth0 -p tcp --dport 443 --syn -j ACCEPT
-A INPUT --in-interface eth0 -p tcp --syn -j DROP
# FORWARD
-A FORWARD --in-interface eth0 -p tcp -s 10.10.0.50/32 --syn -j ACCEPT
-A FORWARD --in-interface eth0 -p tcp --dport 80 --syn -j ACCEPT
-A FORWARD --in-interface eth0 -p tcp --dport 443 --syn -j ACCEPT
-A FORWARD --in-interface eth0 -p tcp --syn -j DROP
COMMIT
Photo of Anastas Dancha

Anastas Dancha

  • 90 Points 75 badge 2x thumb
  • amused

Posted 2 years ago

  • 2
Photo of Anastas Dancha

Anastas Dancha

  • 90 Points 75 badge 2x thumb
P.P.S.
Source: https://support.cumulusnetworks.com/hc/en-us/articles/201941607-Cumulus-Linux-ACL-Example-Rules
Warning: 'iptables' rules sometimes get confused by the user since they were originally envisioned with a host in mind.
The INPUT chain means traffic TO THE BOX, not traffic going through the box.  Please use the FORWARD chain to control traffic going THROUGH THE BOX. Please read the documentation for more explanation and hardware limitations.
(Edited)