Host Firewall rules
Host Firewall rules¶
We want to enforce iptables rules on all servers fleet, including on the ones behind a corporate firewall (and so using NAT for outgoing connections and/or DNAT for incoming ones)
Baseline¶
The ansible-role-iptables is one of the few roles that isn't applied through a group membership at the ansible inventory level, but is deployed/imported in our baseline (see the import_role
task to import iptables rules)
The basic iptables role would (both for ipv4 and ipv6):
- only allow sshd (tcp/22) from some known bastion hosts
- create an iptables rules for
ipset
(centos-blocked-manual) - install ipset service
- block all the rest
It creates a skeleton of other rules to be assembled by iptables (see /etc/sysconfig/iptables.d
) to be then reloaded.
That means that from there, any other ansible role would just have to drop his iptables rules file , assemble new config file and reload.
One example is from baseline
role itself, importing zabbix-agent :
- name: Configuring iptables rules
include_role:
name: iptables
tasks_from: custom-policy
vars:
iptables_policy_name: zabbix-agent
iptables_protocol: tcp
iptables_port: "10050"
iptables_source: "{{ zabbix_server_ip }}"
tags:
- iptables
As you can see, the zabbix-agent role, is just importing the custom-policy.yml
tasks from iptables role, with some variables (in our case, mentioning that we only accept traffic from zabbix server on tcp/10050 on the agent side). It's quite modular and other roles follow the same principles (usually). Behind the scene that means that :
- it's creating the /etc/sysconfig/iptables.d/01-input-service-policy-zabbix-agent (from jinja2 ansible template)
- using the
assemble
ansible module to concat all snippet files under /etc/sysconfig/iptables.d/ - restarting iptables with new ruleset
Custom rules (including NAT/DNAT)¶
Probably better to read the defaults/main.yml to see other features that you can apply with the iptables rules but there are some other features (speicific to host/group variables and not role
bound :
Defining custom local rules (empty by default):
iptables_local_input_rules:
- source: 192.168.0.0/24
dport: 80
protocol: tcp
- dport: 25 # would open for all tcp/25
Should the node be used as gateway/router/firewall itself, we can control that through the following variables (see the main.yml files for examples :
- iptables_gw (boolean, default is False)
- iptables_forward_allow
- iptables_nat_postrouting_allow
- iptables_nat_prerouting_allow
- iptables_redirects (local port)
Ipset¶
One of the main advantage with ipset is that if you need to add a lot of hosts in a deny list (either for DROP or REJECT rules) , it's faster to just use ipset in memory than iptables rules for all these IP addresses. That means that you can just create one (or mutiple) iptables rules just pointing to ipset rules.
As said above, our basic iptables rule would at least create one iptable rule pointing to the centos-blocked-manual
ipset list (empty), but that means that adding an ip directly into ipset would work without having to reload the whole iptables service/ruleset (ipset add blocked-centos-manual $ip
)
We also can use/update some public lists from services like Firehol.org.
See again the defaults/main.yml
iptables file to see some example but by default ipset_block_lists
is empty and so not using any of these lists