diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 2e594fa..ffebbd1 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -31,7 +31,7 @@ variables: - cd ../ # - mv ansible-role-$ROLE_NAME ryandaniels.$ROLE_NAME # - cd ryandaniels.$ROLE_NAME - - ln -s ansible-role-$ROLE_NAME ryandaniels.$ROLE_NAME + - ln -s ansible-role-iptables-docker ryandaniels.$ROLE_NAME - cd ryandaniels.$ROLE_NAME script: - ansible-lint diff --git a/README.md b/README.md index 8962a12..130867f 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,11 @@ There could be unknown problems with this.. use at your own risk! See also: And about Docker's use of the INPUT chain: -Currently tested and working on CentOS/RHEL 7. +Currently tested and working on: + +* CentOS/RHEL 7 +* Ubuntu 18.04 +* Ubuntu 20.04 ## Features @@ -82,6 +86,8 @@ Tested in normal Docker mode, and with a 3 node Docker Swarm cluster. ## Distros tested * CentOS: 7.7, 7.8 +* Ubuntu 18.04 +* Ubuntu 20.04 ## Dependencies @@ -422,7 +428,7 @@ List iptables that are active: iptables -nvL --line-numbers ``` -Misc useful commands: +Misc CentOS/RHEL useful commands: ```bash cat /etc/sysconfig/ipset.d/ip_allow.set @@ -439,7 +445,20 @@ iptables -S DOCKER-USER iptables -S FILTERS ``` -## Manual Commands +Misc Ubuntu useful commands: + +```bash +vi /etc/iptables/ipsets +#Manually add 'flush' before add, if removing IPs manually. + +/usr/sbin/netfilter-persistent reload + +cat /etc/iptables/ipsets + +cat /etc/iptables/rules.v4 +``` + +## Manual Commands (CentOS/RHEL) Check what iptables rules you already have. Make note in case they are lost! @@ -566,7 +585,7 @@ Don't miss the Warnings from above! Especially about SELinux. * [x] add automatic list of docker IPs in allowed list (uses IPs from inventory group docker_hosts) * [x] Change auto Docker server trusted IPs so can override * [x] confirm "when" and "tags" are ok -* [ ] Ubuntu? Ubuntu doesn't have iptables-services or ipset-service. has iptables-persistent and ipset-? Easy to add ufw support? +* [x] Ubuntu? Ubuntu doesn't have iptables-services or ipset-service. has iptables-persistent and ipset-? No ufw support * [ ] ipv6?? This is for ipv4 only * [x] test TCP, UDP Docker container and OS port work * [x] test outound traffic from Docker containers work diff --git a/defaults/main.yml b/defaults/main.yml index a9b778f..56a4a8b 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -15,11 +15,15 @@ iptables_docker_packages: - ipset - ipset-service - policycoreutils-python #required for semodule + iptables_docker_copy_ipset_force: false iptables_docker_copy_iptables_force: false +iptables_docker_iptables_persistent_svc: iptables +iptables_docker_iptables_save_cmd: "/usr/libexec/iptables/iptables.init save" iptables_docker_iptables_config_save: /etc/sysconfig/iptables iptables_docker_iptables_config: /etc/sysconfig/iptables-config iptables_docker_ipset_config_dir: /etc/sysconfig/ipset.d +iptables_docker_ipset_save_file: ip_allow.set iptables_docker_ipset_maxelem: 65536 # Optional override. If not set, IPs will be determined from docker_hosts group in Ansible inventory diff --git a/files/ubuntu/iptables-persistent_1.0.14/LICENSE b/files/ubuntu/iptables-persistent_1.0.14/LICENSE new file mode 100644 index 0000000..a28d877 --- /dev/null +++ b/files/ubuntu/iptables-persistent_1.0.14/LICENSE @@ -0,0 +1,25 @@ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: iptables-persistent +Upstream-Contact: Jonathan Wiltshire + +Files: * +Copyright: © 2009, Simon Richter + © 2010, Chris Silva + © 2010, Jonathan Wiltshire + © 2018, gustavo panizzo +License: GPL-3 + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + . + This package is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + . + You should have received a copy of the GNU General Public License + along with this program. If not, see . + . + On Debian systems, the complete text of the GNU General + Public License version 3 can be found in `/usr/share/common-licenses/GPL-3'. diff --git a/files/ubuntu/iptables-persistent_1.0.14/plugins/10-ipset b/files/ubuntu/iptables-persistent_1.0.14/plugins/10-ipset new file mode 100755 index 0000000..38c4d0b --- /dev/null +++ b/files/ubuntu/iptables-persistent_1.0.14/plugins/10-ipset @@ -0,0 +1,72 @@ +#!/bin/sh + +# This file is part of netfilter-persistent +# (was iptables-persistent) +# Copyright (C) 2018, gustavo panizzo +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, either version 3 +# of the License, or (at your option) any later version. + +# This script saves and/or restores ipset(s) to/from a file +# Flush is implemented in another script, as it has to run after +# iptables flush + +set -e + +PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin + +# Source configuration +if [ -f "/etc/default/netfilter-persistent" ]; then + . /etc/default/netfilter-persistent +fi + +# Create the ipsets and populate them +load_sets () +{ + #load ipset rules + if [ ! -f /etc/iptables/ipsets ]; then + echo "Warning: skipping IPv4 (no rules to load)" + else + ipset restore -exist < /etc/iptables/ipsets + fi +} + +# Save current contents of the ipsets to file +save_sets () +{ + if [ ! "${IPSET_SKIP_SAVE}x" = "yesx" ]; then + touch /etc/iptables/ipsets + chmod 0640 /etc/iptables/ipsets + ipset save > /etc/iptables/ipsets + fi +} + +# flush sets +flush_sets () +{ + : +} + + +case "$1" in +start|restart|reload|force-reload) + load_sets + ;; +save) + save_sets + ;; +stop) + # While it makes sense to stop (delete) ipsets we keep the same + # semanthics as ip(6)?tables rules + echo "Automatic flushing disabled, use \"flush\" instead of \"stop\"" + ;; +flush) + flush_sets + ;; +*) + echo "Usage: $0 {start|restart|reload|force-reload|save|flush}" >&2 + exit 1 + ;; +esac diff --git a/files/ubuntu/iptables-persistent_1.0.14/plugins/15-ip4tables b/files/ubuntu/iptables-persistent_1.0.14/plugins/15-ip4tables new file mode 100755 index 0000000..fc77032 --- /dev/null +++ b/files/ubuntu/iptables-persistent_1.0.14/plugins/15-ip4tables @@ -0,0 +1,78 @@ +#!/bin/sh + +# This file is part of netfilter-persistent +# (was iptables-persistent) +# Copyright (C) 2009, Simon Richter +# Copyright (C) 2010, 2014 Jonathan Wiltshire +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, either version 3 +# of the License, or (at your option) any later version. + +set -e + +PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin + +# Source configuration +if [ -f "/etc/default/netfilter-persistent" ]; then + . /etc/default/netfilter-persistent +fi + +load_rules() +{ + #load IPv4 rules + if [ ! -f /etc/iptables/rules.v4 ]; then + echo "Warning: skipping IPv4 (no rules to load)" + else + iptables-restore < /etc/iptables/rules.v4 + fi +} + +save_rules() +{ + if [ ! "${IPTABLES_SKIP_SAVE}x" = "yesx" ]; then + touch /etc/iptables/rules.v4 + chmod 0640 /etc/iptables/rules.v4 + iptables-save > /etc/iptables/rules.v4 + fi +} + +flush_rules() +{ + TABLES=$(iptables-save | sed -E -n 's/^\*//p') + for table in $TABLES + do + CHAINS=$(iptables-save -t $table | sed -E -n 's/^:([A-Z]+).*/\1/p') + for chain in $CHAINS + do + # policy can't be set on user-defined chains + iptables -t $table -P $chain ACCEPT || true + done + iptables -t $table -F + iptables -t $table -Z + iptables -t $table -X + done +} + +case "$1" in +start|restart|reload|force-reload) + load_rules + ;; +save) + save_rules + ;; +stop) + # Why? because if stop is used, the firewall gets flushed for a variable + # amount of time during package upgrades, leaving the machine vulnerable + # It's also not always desirable to flush during purge + echo "Automatic flushing disabled, use \"flush\" instead of \"stop\"" + ;; +flush) + flush_rules + ;; +*) + echo "Usage: $0 {start|restart|reload|force-reload|save|flush}" >&2 + exit 1 + ;; +esac diff --git a/files/ubuntu/iptables-persistent_1.0.14/plugins/25-ip6tables b/files/ubuntu/iptables-persistent_1.0.14/plugins/25-ip6tables new file mode 100755 index 0000000..40c48be --- /dev/null +++ b/files/ubuntu/iptables-persistent_1.0.14/plugins/25-ip6tables @@ -0,0 +1,76 @@ +#!/bin/sh + +# This file is part of netfilter-persistent +# (was iptables-persistent) +# Copyright (C) 2009, Simon Richter +# Copyright (C) 2010, 2014 Jonathan Wiltshire +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, either version 3 +# of the License, or (at your option) any later version. + +set -e + +PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin + +# Exit fast if IPv6 is disabled +test -e /proc/sys/net/ipv6 || exit 0 + +load_rules() +{ + #load IPv6 rules + if [ ! -f /etc/iptables/rules.v6 ]; then + echo "Warning: skipping IPv6 (no rules to load)" + else + ip6tables-restore < /etc/iptables/rules.v6 + fi +} + +save_rules() +{ + if [ ! "${IPTABLES_SKIP_SAVE}x" = "yesx" ]; then + touch /etc/iptables/rules.v6 + ip6tables-save > /etc/iptables/rules.v6 + chmod 0640 /etc/iptables/rules.v6 + fi +} + +flush_rules() +{ + TABLES=$(ip6tables-save | sed -E -n 's/^\*//p') + for table in $TABLES + do + CHAINS=$(ip6tables-save -t $table | sed -E -n 's/^:([A-Z]+).*/\1/p') + for chain in $CHAINS + do + # policy can't be set on user-defined chains + ip6tables -t $table -P $chain ACCEPT || true + done + ip6tables -t $table -F + ip6tables -t $table -Z + ip6tables -t $table -X + done +} + +case "$1" in +start|restart|reload|force-reload) + load_rules + ;; +save) + save_rules + ;; +stop) + # Why? because if stop is used, the firewall gets flushed for a variable + # amount of time during package upgrades, leaving the machine vulnerable + # It's also not always desirable to flush during purge + echo "Automatic flushing disabled, use \"flush\" instead of \"stop\"" + ;; +flush) + flush_rules + ;; +*) + echo "Usage: $0 {start|restart|reload|force-reload|save|flush}" >&2 + exit 1 + ;; +esac diff --git a/files/ubuntu/iptables-persistent_1.0.14/plugins/40-ipset b/files/ubuntu/iptables-persistent_1.0.14/plugins/40-ipset new file mode 100755 index 0000000..dc4b374 --- /dev/null +++ b/files/ubuntu/iptables-persistent_1.0.14/plugins/40-ipset @@ -0,0 +1,62 @@ +#!/bin/sh + +# This file is part of netfilter-persistent +# (was iptables-persistent) +# Copyright (C) 2018, gustavo panizzo +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, either version 3 +# of the License, or (at your option) any later version. + +# This script only implement flush of rules as ipset have to flushed after +# there are no more references to it (iptables rules calling them) + +set -e + +PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin + +# Source configuration +if [ -f "/etc/default/netfilter-persistent" ]; then + . /etc/default/netfilter-persistent +fi + +# Create the ipsets and populate them +load_sets () +{ + : +} + +# Save current contents of the ipsets to file +save_sets () +{ + : +} + +# flush sets +flush_sets () +{ + ipset destroy +} + + +case "$1" in +start|restart|reload|force-reload) + load_sets + ;; +save) + save_sets + ;; +stop) + # While it makes sense to stop (delete) ipsets we keep the same + # semanthics as ip(6)?tables rules + echo "Automatic flushing disabled, use \"flush\" instead of \"stop\"" + ;; +flush) + flush_sets + ;; +*) + echo "Usage: $0 {start|restart|reload|force-reload|save|flush}" >&2 + exit 1 + ;; +esac diff --git a/files/ubuntu/iptables-persistent_1.0.14/source.txt b/files/ubuntu/iptables-persistent_1.0.14/source.txt new file mode 100644 index 0000000..80f5750 --- /dev/null +++ b/files/ubuntu/iptables-persistent_1.0.14/source.txt @@ -0,0 +1 @@ +https://packages.ubuntu.com/focal/ipset-persistent \ No newline at end of file diff --git a/meta/main.yml b/meta/main.yml index dfc597f..c6c8b9c 100644 --- a/meta/main.yml +++ b/meta/main.yml @@ -9,6 +9,10 @@ galaxy_info: - name: EL versions: - 7 + - name: Ubuntu + versions: + - bionic + - focal galaxy_tags: - iptables - docker diff --git a/tasks/main.yml b/tasks/main.yml index 0ef1830..3cd1f9c 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -1,4 +1,21 @@ --- +- name: Add Ubuntu override variables + include_vars: "ubuntu.yml" + when: + - ansible_distribution == "Ubuntu" + - iptables_docker_managed|bool + tags: + - always + +- name: Add Ubuntu 20.04 override variables + include_vars: "ubuntu2004.yml" + when: + - ansible_distribution == "Ubuntu" + - ansible_distribution_version == "20.04" + - iptables_docker_managed|bool + tags: + - always + - name: iptables Docker | Set Docker server IPs for allow list set_fact: iptables_docker_server_ip_allow_set: "{{ iptables_docker_server_ip_allow_set | default(groups['docker_hosts'] | map('extract', hostvars, ['ansible_host']) | list) }}" # noqa 204 @@ -145,11 +162,11 @@ package: name: "{{ iptables_docker_packages|default([]) }}" update_cache: yes - state: installed + state: present environment: "{{ proxy_env }}" when: # - ansible_os_family == "RedHat" -# - ansible_distribution_major_version == '7' + # - ansible_distribution_major_version == '7' - iptables_docker_managed|bool - iptables_docker_managed_pkg|bool tags: @@ -161,7 +178,8 @@ file: path: "{{ iptables_docker_ipset_config_dir }}" state: directory - when: iptables_docker_managed|bool + when: + - iptables_docker_managed|bool tags: - iptables_docker - iptables_config @@ -170,14 +188,15 @@ - name: iptables Docker | Generate ipset config template: src: templates/ip_allow.set.j2 - dest: "{{ iptables_docker_ipset_config_dir }}/ip_allow.set" + dest: "{{ iptables_docker_ipset_config_dir }}/{{ iptables_docker_ipset_save_file }}" # validate: haproxy -f %s -c -q # environment: # PATH: "/usr/sbin:/usr/local/sbin:/sbin:{{ install_haproxy_bin_dir }}" register: stat_iptables_docker_copy_ipset # notify: # - reload ipset - when: iptables_docker_managed|bool + when: + - iptables_docker_managed|bool tags: - iptables_docker - iptables_config @@ -189,6 +208,8 @@ state: started enabled: yes when: + - ansible_os_family == "RedHat" + - ansible_distribution_major_version == '7' - iptables_docker_managed|bool - stat_iptables_docker_copy_ipset.changed or iptables_docker_copy_ipset_force|bool tags: @@ -201,6 +222,8 @@ name: ipset state: reloaded when: + - ansible_os_family == "RedHat" + - ansible_distribution_major_version == '7' - iptables_docker_managed|bool - stat_iptables_docker_copy_ipset.changed or iptables_docker_copy_ipset_force|bool tags: @@ -208,6 +231,36 @@ - iptables_config - iptables_config_ipset +#source: https://packages.ubuntu.com/focal/ipset-persistent +- name: iptables Docker | Copy ipset plugins for netfilter (Ubuntu <= 18.04) + copy: + src: "files/ubuntu/iptables-persistent_1.0.14/plugins/{{ item }}" + dest: "/usr/share/netfilter-persistent/plugins.d/{{ item }}" + mode: 0755 + register: stat_iptables_ubuntu_ipset_persistent_files + with_items: + - 10-ipset + - 40-ipset + when: + - ansible_distribution == "Ubuntu" + - ansible_distribution_version <= "18.04" + - iptables_docker_managed|bool + tags: + - iptables_docker + - iptables_config + - iptables_config_iptables + +- name: iptables Docker | Reload ipset (Ubuntu) + command: /usr/sbin/netfilter-persistent reload + when: + - ansible_distribution == "Ubuntu" + - iptables_docker_managed|bool + - stat_iptables_docker_copy_ipset.changed or iptables_docker_copy_ipset_force|bool + tags: + - iptables_docker + - iptables_config + - iptables_config_iptables + #Change iptables config: /etc/sysconfig/iptables-config - name: iptables Docker | Modify iptables config lineinfile: @@ -219,6 +272,8 @@ - {regex: '^IPTABLES_SAVE_ON_STOP=.*', line: 'IPTABLES_SAVE_ON_STOP="yes"'} - {regex: '^IPTABLES_SAVE_ON_RESTART=.*', line: 'IPTABLES_SAVE_ON_RESTART="yes"'} when: + - ansible_os_family == "RedHat" + - ansible_distribution_major_version == '7' - iptables_docker_managed|bool tags: - iptables_docker @@ -240,6 +295,8 @@ mode: 0644 register: stat_iptables_selinux_iptables_save when: + - ansible_os_family == "RedHat" + - ansible_distribution_major_version == '7' - ansible_selinux is defined - ansible_selinux.status == 'enabled' - iptables_docker_managed|bool @@ -251,6 +308,8 @@ - name: iptables Docker | Fix SELinux permissions for iptables save and chmod command: semodule -i /root/selinux_iptables_save_chmod.pp when: + - ansible_os_family == "RedHat" + - ansible_distribution_major_version == '7' - ansible_selinux is defined - ansible_selinux.status == 'enabled' - stat_iptables_selinux_iptables_save.changed @@ -333,7 +392,7 @@ - block: - name: iptables Docker | iptables save # command: service iptables save warn=false # noqa 303 - command: /usr/libexec/iptables/iptables.init save + command: "{{ iptables_docker_iptables_save_cmd }}" # shell: | # set -o pipefail # iptables-save -t filter \ @@ -351,9 +410,9 @@ - iptables_config - iptables_config_iptables -- name: iptables Docker | Start iptables service +- name: iptables Docker | Start iptables (persistent) service systemd: - name: iptables + name: "{{ iptables_docker_iptables_persistent_svc }}" state: started enabled: yes when: diff --git a/templates/ip_allow.set.j2 b/templates/ip_allow.set.j2 index 27ebdcd..6459e6c 100644 --- a/templates/ip_allow.set.j2 +++ b/templates/ip_allow.set.j2 @@ -1,6 +1,10 @@ # Recreate the ipset if needed, and flush all entries create -exist ip_allow hash:ip family inet hashsize 1024 maxelem {{ iptables_docker_ipset_maxelem }} -#flush + +{% if ansible_distribution == "Ubuntu" %} +flush +{% endif %} + # Give access to specific ips # add ip_allow 192.168.100.0/24 # add ip_allow 192.168.101.0/24 diff --git a/vars/ubuntu.yml b/vars/ubuntu.yml new file mode 100644 index 0000000..b449af4 --- /dev/null +++ b/vars/ubuntu.yml @@ -0,0 +1,13 @@ +--- +iptables_docker_packages: + - iptables + - iptables-persistent + - netfilter-persistent + - ipset + # - ipset-persistent + +iptables_docker_ipset_config_dir: /etc/iptables +iptables_docker_ipset_save_file: ipsets +iptables_docker_iptables_persistent_svc: netfilter-persistent +iptables_docker_iptables_save_cmd: "/usr/sbin/netfilter-persistent save" +iptables_docker_iptables_config_save: /etc/iptables/rules.v4 diff --git a/vars/ubuntu2004.yml b/vars/ubuntu2004.yml new file mode 100644 index 0000000..a663761 --- /dev/null +++ b/vars/ubuntu2004.yml @@ -0,0 +1,7 @@ +--- +iptables_docker_packages: + - iptables + - iptables-persistent + - netfilter-persistent + - ipset + - ipset-persistent