Setup iptables firewall from scratch or on a per-rule basis. A rollback feature ensures the Ansible Controller will not be locked out of the target host.
SUMMARY
- Description
- Requirements
- Role Variables
- Template Variables
- Dependencies
- Example Playbook
- Install
- License
- Author Information
This role populates target's iptables ruleset from a template, also flushing (the default) or keeping existing rules; or modifies current ruleset by adding or removing service-specific rules. If the next task fails, meaning that the target is not reachable anymore, the firewall is restarted with its initial configuration, so the ansible controller, at least, is not locked out of its target.
This role comes with the following features:
- rollback in case of failure
- full firewall configuration from scratch
- blind firewall sanitization by inserting a core of sanity rules before the current ones, that remain unchanged but may as well never be reached anymore.
- per-rule firewall management, allowing other roles to add or remove rules when installing or uninstalling services respectively.
- easy-to-write rules, with a list of dictionaries with only two mandatory parameters.
This role ships a custom ansible module iptables_state
to manage saving and
restoring firewall state to/from a file.
Firewall management service (iptables
or netfilter-persistent
) must be
installed apart.
All variables used by the role are explicitly declared either in defaults or in vars directories. Those declared in vars shouldn't be overridden in almost all cases (and can't be overridden from inventory). So this section is divided in two parts, Common Variables and Advanced Variables
Only a few variables control the behaviour of this role. See Template Variables for variables applying to the template provided by the role.
-
The action to perform when playing the role. Defaults to
template
. When the value isappend
,insert
ordelete
, current iptables ruleset is the starting point, andiptables_apply__rules
the rules to be appended, inserted or deleted. Also note that like with the iptables module, the rules that already exist in a chain are not moved within this chain. But they can be updated if only one of their destination port(s) or comment string has changed.The action
flush
is also supported. It removes all rules and resets policy to ACCEPT for all chains of the tables listed in the variableiptables_apply__flush_tables
(filter by default). This action makes that the service is stopped and disabled.
iptables_apply__action: template
-
The iptables rules to
append
/insert
to, or todelete
from the current rules, depending oniptables_apply__action
value. This is a list of dictionaries accepting the following keys:key mandatory type choices default description chain
no keyword INPUT
,FORWARD
,OUTPUT
INPUT
The chain the rule will be added to. dport
yes string or integer Port number, port range, or comma-separated list of port numbers and port ranges. jump
no keyword ACCEPT
,DROP
,REJECT
ACCEPT
What to do with packets matching the rule. name
yes string Used as the rule's comment. protocol
no keyword tcp
,udp
tcp
The protocol packets have to match. saddr
no string The IP source address packets have to match. Defaults to an empty list (
[]
). Example:
iptables_apply__rules:
- name: PostgreSQL
dport: 5432
saddr: 10.122.43.21
#protocol: tcp
#chain: INPUT
#jump: ACCEPT
- name: Knot DNS
dport: 53,953
protocol: udp
- Whether or not to make the currently applied ruleset persistent across reboots.
iptables_apply__persist: true
- The following variable defines the firewall's service name. As the
implementation may vary a lot, only two services are currently supported:
iptables
for Redhat family, andnetfilter-persistent
for Debian family.
iptables_apply__service: iptables
- This variable defines the path of the file to save firewall state into, to make the currently applied ruleset persistent across reboots.
iptables_apply__service_ruleset: /etc/sysconfig/iptables
- The two following variables are about firewall's service management.
Running state defaults to
true
, activation state defaults totrue
.
iptables_apply__service_enabled: true
iptables_apply__service_started: true
- The following variable defines the path of a temporary file that will be
used as buffer, starting with initial state of the firewall (table filter
for actions
append
,delete
orinsert
), or with templated rules (with actionstemplate
orflush
).
iptables_apply__path_buffer: /run/iptables.buffer
The following variables refer to the template that comes with the role. They
make sense as long as iptables_apply__action
's value is template
.
All variables used by the role are explicitly declared either in defaults or in vars directories. Those declared in vars shouldn't be overridden in almost all cases (and can't be overridden from inventory). So this section is divided in two parts, Common Templating and Advanced Templating
- This defines the path of a template file that once evaluated is used as input
for the command
iptables-restore
. Defaults to the template shipped with the role.
iptables_apply__template: iptables_apply.j2
- The iptables rules to apply in addition to the sanity rules provided by the
template. This is a list of dictionaries with the same keys than
iptables_apply__rules
, and defaults to the same value.
iptables_apply__template_rules: "{{ iptables_apply__rules }}"
- If
True
, current iptables ruleset is not flushed and rules from the template (the one shipped with the role) are inserted before the current ones. This variable is silently ignored if the current running state of iptables already containsiptables_apply__template_mark
's value, that makes it usable as a one-shot-option, avoiding to duplicate rules too much (thus, without modifying the playbook nor its commandline call).
iptables_apply__template_noflush: false
- Whether or not to apply the core ruleset provided by the template. The core
rules, a.k.a. sanity rules, are inserted to ensure they will be evaluated
first even if
iptables_apply__template_noflush
is true. Defaults totrue
.
iptables_apply__template_core: true
- The default policy to apply for each chain of the filter table. If a policy
is undefined in this variable, then it will be changed to
ACCEPT
on the target. For example, to blank all current policies:iptables_apply__template_policy: {}
iptables_apply__template_policy:
input: DROP
forward: DROP
output: ACCEPT
- As the templating of a temporary file can't be idempotent, and as the
templating of iptables is in itself very agressive, there must be a way to
not replay the template action to not loose application rules appended
between two plays. This is the purpose of this variable. Set it to
false
to force a replay.
iptables_apply__template_once: true
- This variable defines a string that should be found in the
iptables-save
output to know/decide if the templated ruleset is already in use. Defaults to the rule dropping TCP packets in stateNEW
and not coming with only theSYN
flag. NOTE that there is a short writing of this rule, but the output is always the same:
# short writing: '-A INPUT -p tcp -m tcp ! --syn -m comment --comment "bad NEWs" -j DROP'
iptables_apply__template_mark: '-A INPUT -p tcp -m tcp ! --tcp-flags FIN,SYN,RST,ACK SYN -m comment --comment "bad NEWs" -j DROP'
- This defines the path of an alternative template used to flush rules and
reset policies to ACCEPT all packets. It is only effective when
iptables_apply__action
is set toflush
.
iptables_apply__flush: iptables_flush.j2
- This lists the tables to flush when evaluating
iptables_flush.j2
, i.e. either wheniptables_apply__action = flush
andiptables_apply__flush = iptables_flush.j2
, or wheniptables_apply__template = iptables_flush.j2
. It accepts either a keyword (table name orall
) or a list of these keywords. Defaults tofilter
.
# choices: all, filter, nat, mangle, raw, security
iptables_apply__flush_tables: filter
None.
Apply the core ruleset, ensuring a secure base setup with ssh access allowed and no more.
---
- hosts: servers
become: yes
roles:
- role: iptables_apply
Apply the same ruleset on an already configured firewall you want to keep.
---
- hosts: servers
become: yes
roles:
- role: iptables_apply
iptables_apply__template_noflush: yes
Apply core ruleset and some passing rules for monitoring tools.
---
- hosts: servers
become: yes
roles:
- role: iptables_apply
iptables_apply__template_rules:
- name: NRPE
dport: 5666
- name: SNMP
dport: 161
- name: SNMP
dport: 161
protocol: udp
Add a single and simple passing rule. Replace append
by delete
to remove it.
---
- hosts: dns-servers
become: yes
roles:
- role: iptables_apply
iptables_apply__action: append
iptables_apply__rules:
- name: Knot DNS
dport: 53,953
protocol: udp
Do almost whatever you want, and bypass the rollback feature, by calling a
tasks file that uses ansible's iptables
module. The action of the role
(iptables_apply__action
) doesn't matter here, unless you explicitly map
rule's action
and state
to it.
---
- hosts: db-servers
become: yes
tasks:
- include_role:
name: iptables_apply
tasks_from: iptables.yml
vars:
iptables_apply__iptables:
- action: insert
chain: INPUT
protocol: tcp
source: 10.112.43.21,10.75.43.21
source_port: "1024:"
destination_port: 5432
ctstate: NEW
syn: match
comment: "postgresql.service"
jump: ACCEPT
state: present
Do whatever you want with a custom template. It may as well include policies and rules for any table, not only the filter one.
---
- hosts: routers
become: yes
roles:
- role: iptables_apply
iptables_apply__template: iptables/routers.j2
Manage persistence of the current ruleset:
---
- hosts: all
become: yes
tasks:
- include_role:
name: iptables_apply
tasks_from: iptables_state.yml
vars:
iptables_state__state: saved
iptables_state__path: /etc/sysconfig/iptables
Or manage the service (for example disable it and keep it started):
---
- hosts: all
become: yes
tasks:
- include_role:
name: iptables_apply
tasks_from: iptables-service.yml
vars:
iptables_apply__service_enabled: false
iptables_apply__service_started: true
You may also want to play this role from another one (here, say from foobar
):
- include_role:
name: iptables_apply
vars:
iptables_apply__action: "{{ 'append' if foobar__action == 'setup' else 'delete' }}"
iptables_apply__rules:
- name: FooBar over HTTP/HTTPS
dport: "{{ foobar__http_port }},{{ foobar__https_port }}"
To make use of this role as a galaxy role, put the following lines in
requirements.yml
:
- name: iptables_apply
src: https://github.com/quidame/ansible-role-iptables_apply.git
version: 5.1.0
scm: git
and then
ansible-galaxy install -r requirements.yml
GPLv3