Minimalistic ansible role to configure firewalld service on a server running Red Hat 8 and 9. Cant be use for a router or gateway.
Firewalld is a zone based firewall with lot of features. We just want deny all traffic and accept specific ip+port in "zero-trust" like mode. We set two policies, INPUT and OUTPUT that override every other configuration.
More info about firewalld policies :
- https://firewalld.org/documentation/man-pages/firewalld.policies.html
- https://firewalld.org/documentation/man-pages/firewalld.policy.html
- Red Hat 9 (firewalld 1.0) supported
- Red Hat 8 (firewalld 0.9) supported
- Red Hat 7 (firewalld 0.6) NOT supported
Actually, there are a know issue on Red Hat 8, output nftable chain dont have implicit accept rule for conn_track state related and established, we cant use reject target on this chain without broke input accept rules. More about this issue : https://bugzilla.redhat.com/show_bug.cgi?id=2156831
Policy objects was introduce since version 0.9.0 : https://firewalld.org/2020/09/policy-objects-introduction
Firewalld variables available (see default/main.yml for more) :
firewalld_enable
: Enable firewalld custom policies, boolean (default false).firewalld_input_only
: Disable output filtering, boolean (default false). Mandatory for EL8firewalld_logdenied_all
: Enable auditing all rejected traffic (including noise like multicast, icmp, etc), boolean (default false).
There are two groups of rules, the commons one and server role specific. This groups are available for input and output chains. Use role rules in each inventory to address envrionnment based rules (production, stagging, testing).
firewalld_common_input_rules
: Dict contains global input rules, optionalfirewalld_role_input_rules
: Dict contains specific input rules, optionalfirewalld_common_output_rules
: Dict contains global output rules, optionalfirewalld_role_output_rules
: Dict contains specific output rules, optional
You can use "dry mode" to verify all legitimate traffic dont be rejected. Packets not explicitly accepted are audited.
firewalld_input_dry
: Enable dry mode on input chain, audit traffic but dont reject, boolean (default false).firewalld_output_dry
: Enable dry mode on output chain, audit traffic but dont reject, boolean (default true).
Rule syntax are same for input and output chain, common and role groups. Rule can use a service name (see /usr/lib/firewalld/services/), a port/protocol couple or a ip protocol (see /etc/protocols). Others variables are optionnal. If no ip is provide, all traffic is accepted on this service/port/protocol.
- service: firewalld service OR
- port: port number if firewalld service not exist
proto: optional, used with port, tcp or udp (default tcp) OR
- proto : ip protocol name
ip: (optional dict, if absent, any ip accepted)
- ip_addr
desc: optional, string description
audit_reject: optional, booelan (default true)
audit_accept: optional, booelan (default false)
Example with a http reverse proxy with vrrp failover and admin access :
firewalld_common_input_rules:
- service: ssh
desc: 'admin'
ip:
- 192.168.10.1
- 192.168.10.2
- service: snmp
ip:
- 192.168.10.2
- proto: icmp
ip:
- 192.168.10.2
firewalld_role_input_rules:
- port: 443
desc: "https from any"
- proto: vrrp
ip:
- 192.168.0.1
- 192.168.0.2
AGPLv3
Gilian GAMBINI @ DSI-CNRS