Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pull in upstream changes #2

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
.vagrant
*~
25 changes: 25 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
BSD 2-Clause License

Copyright (c) 2017, Mike Gleason jr Couturier
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 changes: 24 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,13 @@ After I found out `UFW` was too limited in terms of functionalities, I tried sev

This role is an attempt to solve these requirements.

It supports **ipv4** and **ipv6*** on Debian and RedHat distributions.

*ipv6 support was brought up thanks to [@maloddon](https://github.com/maloddon). It is currently in early stages and knowledgable people should review the [default rules](https://github.com/mikegleasonjr/ansible-role-firewall/blob/master/defaults/main.yml). ipv6 rules are not configured by default. If you which to use them, don't forget to set `firewall_v6_configure` to `true`.
It supports **ipv4** and **ipv6*** on Debian and RedHat distributions. ipv6 rules are not configured by default. If you which to use them, don't forget to set `firewall_v6_configure` to `true`.

Requirements
------------

`iptables` (installed by default on all official Debian and RedHat distributions)
* Ansible 2.4.0.0
* `iptables` (installed by default on all official Debian and RedHat distributions)

Installation
------------
Expand All @@ -35,9 +34,19 @@ Role Variables
`defaults/main.yml`:

```
---
firewall_v4_configure: true
firewall_v6_configure: false

firewall_v4_flush_rules:
- -F
- -X
- -t raw -F
- -t raw -X
- -t nat -F
- -t nat -X
- -t mangle -F
- -t mangle -X
firewall_v4_default_rules:
001 default policies:
- -P INPUT ACCEPT
Expand All @@ -57,6 +66,15 @@ firewall_v4_default_rules:
firewall_v4_group_rules: {}
firewall_v4_host_rules: {}

firewall_v6_flush_rules:
- -F
- -X
- -t raw -F
- -t raw -X
- -t nat -F
- -t nat -X
- -t mangle -F
- -t mangle -X
firewall_v6_default_rules:
001 default policies:
- -P INPUT ACCEPT
Expand All @@ -75,18 +93,17 @@ firewall_v6_default_rules:
- -P INPUT DROP
firewall_v6_group_rules: {}
firewall_v6_host_rules: {}

```

The keys to the `*_rules` dictionaries (`001 default policies`, `002 allow loopback`, ...) can be anything. They are only used for rules **ordering** and **overriding**. On rules generation, the keys are sorted alphabetically. That's why I chose here the 001s and 999s.
The keys to the `*_rules` dictionaries, except the flush rules, can be anything. They are only used for rules **ordering** and **overriding**. On rules generation, the keys are sorted alphabetically. That's why I chose here the 001s and 999s.

Those defaults will generate the following script to be executed on the host (for ipv4):

```
#!/bin/sh
# Ansible managed: <redacted>

# flush rules & delete user-defined chains
# flush rules
iptables -F
iptables -X
iptables -t raw -F
Expand Down
18 changes: 18 additions & 0 deletions defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@
firewall_v4_configure: true
firewall_v6_configure: false

firewall_v4_flush_rules:
- -F
- -X
- -t raw -F
- -t raw -X
- -t nat -F
- -t nat -X
- -t mangle -F
- -t mangle -X
firewall_v4_default_rules:
001 default policies:
- -P INPUT ACCEPT
Expand All @@ -21,6 +30,15 @@ firewall_v4_default_rules:
firewall_v4_group_rules: {}
firewall_v4_host_rules: {}

firewall_v6_flush_rules:
- -F
- -X
- -t raw -F
- -t raw -X
- -t nat -F
- -t nat -X
- -t mangle -F
- -t mangle -X
firewall_v6_default_rules:
001 default policies:
- -P INPUT ACCEPT
Expand Down
6 changes: 3 additions & 3 deletions tasks/main.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
---
- include: rules.yml
- include_tasks: rules.yml

- include: persist-debian.yml
- include_tasks: persist-debian.yml
when: ansible_os_family == 'Debian'

- include: persist-redhat.yml
- include_tasks: persist-redhat.yml
when: ansible_os_family == 'RedHat'
10 changes: 7 additions & 3 deletions tasks/persist-debian.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,21 @@
- name: Install iptables-persistent
apt: name=iptables-persistent state=present

- name: Install ipset-persistent
apt: name=ipset-persistent state=present

- name: Check if netfilter-persistent is present
shell: which netfilter-persistent
register: is_netfilter
when: v4_script|changed or v6_script|changed
when: v4_script is changed or v6_script is changed
changed_when: false
ignore_errors: yes
check_mode: no

- name: Save rules (netfilter-persistent)
command: netfilter-persistent save
when: (v4_script|changed or v6_script|changed) and is_netfilter.rc == 0
when: not ansible_check_mode and (v4_script is changed or v6_script is changed) and is_netfilter.rc == 0

- name: Save rules (iptables-persistent)
command: /etc/init.d/iptables-persistent save
when: (v4_script|changed or v6_script|changed) and is_netfilter.rc == 1
when: not ansible_check_mode and (v4_script is changed or v6_script is changed) and is_netfilter.rc == 1
4 changes: 2 additions & 2 deletions tasks/persist-redhat.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
---
- name: Save v4 rules (/etc/sysconfig/iptables)
shell: iptables-save -c > /etc/sysconfig/iptables
when: v4_script|changed
when: v4_script is changed

- name: Save v6 rules (/etc/sysconfig/ip6tables)
shell: ip6tables-save -c > /etc/sysconfig/ip6tables
when: v6_script|changed
when: v6_script is changed

- name: Ensure iptables service is installed
yum: name=iptables-services state=present
Expand Down
14 changes: 10 additions & 4 deletions tasks/rules.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@
- name: Load v4 rules
command: /etc/iptables.v4.generated
register: v4_script_load_result
failed_when: v4_script_load_result.rc != 0 or 'unknown option' in v4_script_load_result.stderr
when: v4_script|changed
failed_when: >-
v4_script_load_result.rc != 0 or
'unknown option' in v4_script_load_result.stderr or
'Table does not exist' in v4_script_load_result.stderr
when: v4_script is changed

- name: Generate v6 rules
template: src=generated.v6.j2 dest=/etc/iptables.v6.generated owner=root group=root mode=755
Expand All @@ -18,5 +21,8 @@
- name: Load v6 rules
command: /etc/iptables.v6.generated
register: v6_script_load_result
failed_when: v6_script_load_result.rc != 0 or 'unknown option' in v6_script_load_result.stderr
when: v6_script|changed
failed_when: >-
v6_script_load_result.rc != 0 or
'unknown option' in v6_script_load_result.stderr or
'Table does not exist' in v6_script_load_result.stderr
when: v6_script is changed
13 changes: 4 additions & 9 deletions templates/generated.v4.j2
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,10 @@
{% set _ = merged.update(firewall_v4_group_rules) %}
{% set _ = merged.update(firewall_v4_host_rules) %}

# flush rules & delete user-defined chains
iptables -F
iptables -X
iptables -t raw -F
iptables -t raw -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
# flush rules
{% for rule in firewall_v4_flush_rules %}
iptables {{ rule }}
{% endfor %}

{% for group, rules in merged|dictsort %}
# {{ group }}
Expand Down
13 changes: 4 additions & 9 deletions templates/generated.v6.j2
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,10 @@
{% set _ = merged.update(firewall_v6_group_rules) %}
{% set _ = merged.update(firewall_v6_host_rules) %}

# flush rules & delete user-defined chains
ip6tables -F
ip6tables -X
ip6tables -t raw -F
ip6tables -t raw -X
ip6tables -t nat -F
ip6tables -t nat -X
ip6tables -t mangle -F
ip6tables -t mangle -X
# flush rules
{% for rule in firewall_v6_flush_rules %}
ip6tables {{ rule }}
{% endfor %}

{% for group, rules in merged|dictsort %}
# {{ group }}
Expand Down
28 changes: 27 additions & 1 deletion tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,17 @@
become: true

roles:
- role: .
- role: '{{playbook_dir}}'
firewall_v6_configure: true

firewall_v4_flush_rules:
- -F
- -X
- -t raw -F
- -t raw -X
- -t mangle -F
- -t mangle -X

firewall_v4_group_rules:
400 allow http:
- -A INPUT -p tcp --dport http -j ACCEPT
Expand All @@ -14,6 +22,14 @@
firewall_v4_host_rules:
400 allow 7890: []

firewall_v6_flush_rules:
- -F
- -X
- -t raw -F
- -t raw -X
- -t mangle -F
- -t mangle -X

firewall_v6_group_rules:
400 allow http:
- -A INPUT -p tcp --dport http -j ACCEPT
Expand All @@ -27,32 +43,42 @@
command: iptables -L -n
changed_when: false
register: v4_rules
when: not ansible_check_mode
- name: Check that INPUT policy has been applied
assert:
that: "'Chain INPUT (policy DROP' in v4_rules.stdout"
when: not ansible_check_mode
- name: Check that a default rule has been applied
assert:
that: "'tcp dpt:22' in v4_rules.stdout"
when: not ansible_check_mode
- name: Check that a group rule has been applied
assert:
that: "'tcp dpt:80' in v4_rules.stdout"
when: not ansible_check_mode
- name: Check that deleted rules are deleted
assert:
that: "'tcp dpt:7890' not in v4_rules.stdout"
when: not ansible_check_mode

- name: Retrieve v6 rules
command: ip6tables -L -n
changed_when: false
register: v6_rules
when: not ansible_check_mode
- name: Check that INPUT policy has been applied
assert:
that: "'Chain INPUT (policy DROP' in v6_rules.stdout"
when: not ansible_check_mode
- name: Check that a default rule has been applied
assert:
that: "'tcp dpt:22' in v6_rules.stdout"
when: not ansible_check_mode
- name: Check that a group rule has been applied
assert:
that: "'tcp dpt:80' in v6_rules.stdout"
when: not ansible_check_mode
- name: Check that deleted rules are deleted
assert:
that: "'tcp dpt:7890' not in v6_rules.stdout"
when: not ansible_check_mode