ソースを参照

Add support for using iptables-restore to apply the rules

This will not save or flush current iptables rules so that it makes the
iptables-restore provider compatible with docker or similar software
that manage their own rules in iptables.
pull/16/head
Bruno Binet 7年前
コミット
3c703cd9af
7個のファイルの変更555行の追加1行の削除
  1. +101
    -0
      iptables/files/ip4tables
  2. +101
    -0
      iptables/files/ip6tables
  3. +135
    -0
      iptables/files/rules.v4
  4. +135
    -0
      iptables/files/rules.v6
  5. +1
    -1
      iptables/map.jinja
  6. +57
    -0
      iptables/rules.sls
  7. +25
    -0
      iptables/service.sls

+ 101
- 0
iptables/files/ip4tables ファイルの表示

@@ -0,0 +1,101 @@
#!/bin/sh

# This file is part of netfilter-persistent
# (was iptables-persistent)
# Copyright (C) 2009, Simon Richter <sjr@debian.org>
# Copyright (C) 2010, 2014 Jonathan Wiltshire <jmw@debian.org>
#
# 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.

rc=0

load_rules()
{
#load IPv4 rules
if [ ! -f /etc/iptables/rules.v4 ]; then
echo "Warning: skipping IPv4 (no rules to load)"
else
{%- if provider == 'iptables-restore' %}
iptables-restore --test < /etc/iptables/rules.v4 2> /dev/null
if [ $? -ne 0 ]; then
rc=1
else
iptables-save > /etc/iptables/rules.v4.bak
grep -v __saltstack__ /etc/iptables/rules.v4.bak | iptables-restore 2> /dev/null
iptables-restore --noflush < /etc/iptables/rules.v4 2> /dev/null
if [ $? -ne 0 ]; then
rc=1
iptables-restore < /etc/iptables/rules.v4.bak 2> /dev/null
fi
fi
{%- else %}
iptables-restore < /etc/iptables/rules.v4 2> /dev/null
if [ $? -ne 0 ]; then
rc=1
fi
{%- endif %}
fi
}

save_rules()
{
#save IPv4 rules
#need at least iptable_filter loaded:
/sbin/modprobe -q iptable_filter
if [ ! -f /proc/net/ip_tables_names ]; then
echo "Warning: skipping IPv4 (no modules loaded)"
elif [ -x /sbin/iptables-save ]; then
touch /etc/iptables/rules.v4
chmod 0640 /etc/iptables/rules.v4
iptables-save > /etc/iptables/rules.v4
if [ $? -ne 0 ]; then
rc=1
fi
fi
}

flush_rules()
{
if [ ! -f /proc/net/ip_tables_names ]; then
log_action_cont_msg "Warning: skipping IPv4 (no module loaded)"
elif [ -x /sbin/iptables ]; then
for param in F Z X; do /sbin/iptables -$param; done
for table in $(cat /proc/net/ip_tables_names)
do
/sbin/iptables -t $table -F
/sbin/iptables -t $table -Z
/sbin/iptables -t $table -X
done
for chain in INPUT FORWARD OUTPUT
do
/sbin/iptables -P $chain ACCEPT
done
fi
}

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

exit $rc

+ 101
- 0
iptables/files/ip6tables ファイルの表示

@@ -0,0 +1,101 @@
#!/bin/sh

# This file is part of netfilter-persistent
# (was iptables-persistent)
# Copyright (C) 2009, Simon Richter <sjr@debian.org>
# Copyright (C) 2010, 2014 Jonathan Wiltshire <jmw@debian.org>
#
# 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.

rc=0

load_rules()
{
#load IPv6 rules
if [ ! -f /etc/iptables/rules.v6 ]; then
echo "Warning: skipping IPv6 (no rules to load)"
else
{%- if provider == 'iptables-restore' %}
ip6tables-restore --test < /etc/iptables/rules.v6 2> /dev/null
if [ $? -ne 0 ]; then
rc=1
else
ip6tables-save > /etc/iptables/rules.v6.bak
grep -v __saltstack__ /etc/iptables/rules.v6.bak | ip6tables-restore 2> /dev/null
ip6tables-restore --noflush < /etc/iptables/rules.v6 2> /dev/null
if [ $? -ne 0 ]; then
rc=1
ip6tables-restore < /etc/iptables/rules.v6.bak 2> /dev/null
fi
fi
{%- else %}
ip6tables-restore < /etc/iptables/rules.v6 2> /dev/null
if [ $? -ne 0 ]; then
rc=1
fi
{%- endif %}
fi
}

save_rules()
{
#save IPv6 rules
#need at least ip6table_filter loaded:
/sbin/modprobe -q ip6table_filter
if [ ! -f /proc/net/ip6_tables_names ]; then
log_action_cont_msg "Warning: skipping IPv6 (no modules loaded)"
elif [ -x /sbin/ip6tables-save ]; then
touch /etc/iptables/rules.v6
chmod 0640 /etc/iptables/rules.v6
ip6tables-save > /etc/iptables/rules.v6
if [ $? -ne 0 ]; then
rc=1
fi
fi
}

flush_rules()
{
if [ ! -f /proc/net/ip6_tables_names ]; then
echo "Warning: skipping IPv6 (no module loaded)"
elif [ -x /sbin/ip6tables ]; then
for param in F Z X; do /sbin/ip6tables -$param; done
for table in $(cat /proc/net/ip6_tables_names)
do
/sbin/ip6tables -t $table -F
/sbin/ip6tables -t $table -Z
/sbin/ip6tables -t $table -X
done
for chain in INPUT FORWARD OUTPUT
do
/sbin/ip6tables -P $chain ACCEPT
done
fi
}

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

exit $rc

+ 135
- 0
iptables/files/rules.v4 ファイルの表示

@@ -0,0 +1,135 @@
# This file is managed by SaltStack

*filter
{%- for chain_name, chain in chains.iteritems() %}
:{{ chain_name | upper }} {{ chain.get('policy', '-') | upper }}
{%- endfor %}

{%- for chain_name, chain in chains.iteritems() %}
{%- for rule in chain.rules %}
{%- if rule.get('table', 'filter').lower() == 'filter' and rule.get('family', 'ipv4') == 'ipv4' %}
{%- set r = {
'full': 'True',
'table': 'filter',
'chain': chain_name.upper(),
'command': 'A',
'family': 'ipv4',
'comment': rule.get('comment', '') + '__saltstack__',
} %}
{%- if rule.position is defined %}
{%- do r.update({
'command': 'I',
'position': rule['position'],
}) %}
{%- endif %}
{%- if rule.jump is defined %}
{%- do r.update({'jump': rule.jump}) %}
{%- endif %}
{%- if rule.match is defined %}
{%- do r.update({'match': rule.match}) %}
{%- endif %}
{%- if rule.connection_state is defined %}
{%- do r.update({'connstate': rule.connection_state}) %}
{%- endif %}
{%- if rule.protocol is defined %}
{%- do r.update({'proto': rule.protocol}) %}
{%- endif %}
{%- if rule.destination_port is defined %}
{%- do r.update({'dport': rule.destination_port}) %}
{%- endif %}
{%- if rule.source_port is defined %}
{%- do r.update({'sport': rule.source_port}) %}
{%- endif %}
{%- if rule.in_interface is defined %}
{%- do r.update({'in-interface': rule.in_interface}) %}
{%- endif %}
{%- if rule.out_interface is defined %}
{%- do r.update({'out-interface': rule.out_interface}) %}
{%- endif %}
{%- if rule.to_destination is defined %}
{%- do r.update({'to-destination': rule.to_destination}) %}
{%- endif %}
{%- if rule.to_port is defined %}
{%- do r.update({'to-port': rule.to_port}) %}
{%- endif %}
{%- if rule.to_source is defined %}
{%- do r.update({'to-source': rule.to_source}) %}
{%- endif %}
{%- if rule.source_network is defined %}
{%- do r.update({'source': rule.source_network}) %}
{%- endif %}
{%- if rule.destination_network is defined %}
{%- do r.update({'destination': rule.destination_network}) %}
{%- endif %}
{{ salt['iptables.build_rule'](**r) | regex_replace('^.*-t filter ', '') }}
{%- endif %}
{%- endfor %}
{%- endfor %}
COMMIT

*nat
{%- for chain_name, chain in chains.iteritems() %}
:{{ chain_name | upper }} {{ chain.get('policy', '-') | upper }}
{%- endfor %}

{%- for chain_name, chain in chains.iteritems() %}
{%- for rule in chain.rules %}
{%- if rule.get('table', 'filter').lower() == 'nat' and rule.get('family', 'ipv4') == 'ipv4' %}
{%- set r = {
'full': 'True',
'table': 'nat',
'chain': chain_name.upper(),
'command': 'A',
'family': 'ipv4',
'comment': rule.get('comment', '') + '__saltstack__',
} %}
{%- if rule.position is defined %}
{%- do r.update({
'command': 'I',
'position': rule['position'],
}) %}
{%- endif %}
{%- if rule.jump is defined %}
{%- do r.update({'jump': rule.jump}) %}
{%- endif %}
{%- if rule.match is defined %}
{%- do r.update({'match': rule.match}) %}
{%- endif %}
{%- if rule.connection_state is defined %}
{%- do r.update({'connstate': rule.connection_state}) %}
{%- endif %}
{%- if rule.protocol is defined %}
{%- do r.update({'proto': rule.protocol}) %}
{%- endif %}
{%- if rule.destination_port is defined %}
{%- do r.update({'dport': rule.destination_port}) %}
{%- endif %}
{%- if rule.source_port is defined %}
{%- do r.update({'sport': rule.source_port}) %}
{%- endif %}
{%- if rule.in_interface is defined %}
{%- do r.update({'in-interface': rule.in_interface}) %}
{%- endif %}
{%- if rule.out_interface is defined %}
{%- do r.update({'out-interface': rule.out_interface}) %}
{%- endif %}
{%- if rule.to_destination is defined %}
{%- do r.update({'to-destination': rule.to_destination}) %}
{%- endif %}
{%- if rule.to_port is defined %}
{%- do r.update({'to-port': rule.to_port}) %}
{%- endif %}
{%- if rule.to_source is defined %}
{%- do r.update({'to-source': rule.to_source}) %}
{%- endif %}
{%- if rule.source_network is defined %}
{%- do r.update({'source': rule.source_network}) %}
{%- endif %}
{%- if rule.destination_network is defined %}
{%- do r.update({'destination': rule.destination_network}) %}
{%- endif %}
{{ salt['iptables.build_rule'](**r) | regex_replace('^.*-t nat ', '') }}
{%- endif %}
{%- endfor %}
{%- endfor %}
COMMIT

+ 135
- 0
iptables/files/rules.v6 ファイルの表示

@@ -0,0 +1,135 @@
# This file is managed by SaltStack

*filter
{%- for chain_name, chain in chains.iteritems() %}
:{{ chain_name | upper }} {{ chain.get('policy', '-') | upper }}
{%- endfor %}

{%- for chain_name, chain in chains.iteritems() %}
{%- for rule in chain.rules %}
{%- if rule.get('table', 'filter').lower() == 'filter' and rule.get('family', 'ipv4') == 'ipv6' %}
{%- set r = {
'full': 'True',
'table': 'filter',
'chain': chain_name.upper(),
'command': 'A',
'family': 'ipv6',
'comment': rule.get('comment', '') + '__saltstack__',
} %}
{%- if rule.position is defined %}
{%- do r.update({
'command': 'I',
'position': rule['position'],
}) %}
{%- endif %}
{%- if rule.jump is defined %}
{%- do r.update({'jump': rule.jump}) %}
{%- endif %}
{%- if rule.match is defined %}
{%- do r.update({'match': rule.match}) %}
{%- endif %}
{%- if rule.connection_state is defined %}
{%- do r.update({'connstate': rule.connection_state}) %}
{%- endif %}
{%- if rule.protocol is defined %}
{%- do r.update({'proto': rule.protocol}) %}
{%- endif %}
{%- if rule.destination_port is defined %}
{%- do r.update({'dport': rule.destination_port}) %}
{%- endif %}
{%- if rule.source_port is defined %}
{%- do r.update({'sport': rule.source_port}) %}
{%- endif %}
{%- if rule.in_interface is defined %}
{%- do r.update({'in-interface': rule.in_interface}) %}
{%- endif %}
{%- if rule.out_interface is defined %}
{%- do r.update({'out-interface': rule.out_interface}) %}
{%- endif %}
{%- if rule.to_destination is defined %}
{%- do r.update({'to-destination': rule.to_destination}) %}
{%- endif %}
{%- if rule.to_port is defined %}
{%- do r.update({'to-port': rule.to_port}) %}
{%- endif %}
{%- if rule.to_source is defined %}
{%- do r.update({'to-source': rule.to_source}) %}
{%- endif %}
{%- if rule.source_network is defined %}
{%- do r.update({'source': rule.source_network}) %}
{%- endif %}
{%- if rule.destination_network is defined %}
{%- do r.update({'destination': rule.destination_network}) %}
{%- endif %}
{{ salt['iptables.build_rule'](**r) | regex_replace('^.*-t filter ', '') }}
{%- endif %}
{%- endfor %}
{%- endfor %}
COMMIT

*nat
{%- for chain_name, chain in chains.iteritems() %}
:{{ chain_name | upper }} {{ chain.get('policy', '-') | upper }}
{%- endfor %}

{%- for chain_name, chain in chains.iteritems() %}
{%- for rule in chain.rules %}
{%- if rule.get('table', 'filter').lower() == 'nat' and rule.get('family', 'ipv4') == 'ipv6' %}
{%- set r = {
'full': 'True',
'table': 'nat',
'chain': chain_name.upper(),
'command': 'A',
'family': 'ipv6',
'comment': rule.get('comment', '') + '__saltstack__',
} %}
{%- if rule.position is defined %}
{%- do r.update({
'command': 'I',
'position': rule['position'],
}) %}
{%- endif %}
{%- if rule.jump is defined %}
{%- do r.update({'jump': rule.jump}) %}
{%- endif %}
{%- if rule.match is defined %}
{%- do r.update({'match': rule.match}) %}
{%- endif %}
{%- if rule.connection_state is defined %}
{%- do r.update({'connstate': rule.connection_state}) %}
{%- endif %}
{%- if rule.protocol is defined %}
{%- do r.update({'proto': rule.protocol}) %}
{%- endif %}
{%- if rule.destination_port is defined %}
{%- do r.update({'dport': rule.destination_port}) %}
{%- endif %}
{%- if rule.source_port is defined %}
{%- do r.update({'sport': rule.source_port}) %}
{%- endif %}
{%- if rule.in_interface is defined %}
{%- do r.update({'in-interface': rule.in_interface}) %}
{%- endif %}
{%- if rule.out_interface is defined %}
{%- do r.update({'out-interface': rule.out_interface}) %}
{%- endif %}
{%- if rule.to_destination is defined %}
{%- do r.update({'to-destination': rule.to_destination}) %}
{%- endif %}
{%- if rule.to_port is defined %}
{%- do r.update({'to-port': rule.to_port}) %}
{%- endif %}
{%- if rule.to_source is defined %}
{%- do r.update({'to-source': rule.to_source}) %}
{%- endif %}
{%- if rule.source_network is defined %}
{%- do r.update({'source': rule.source_network}) %}
{%- endif %}
{%- if rule.destination_network is defined %}
{%- do r.update({'destination': rule.destination_network}) %}
{%- endif %}
{{ salt['iptables.build_rule'](**r) | regex_replace('^.*-t nat ', '') }}
{%- endif %}
{%- endfor %}
{%- endfor %}
COMMIT

+ 1
- 1
iptables/map.jinja ファイルの表示

@@ -1,7 +1,7 @@

{% set service = salt['grains.filter_by']({
'Debian': {
'pkgs': ['iptables','iptables-persistent' ],
'pkgs': ['iptables','netfilter-persistent' ],
'service': 'netfilter-persistent',
},
'RedHat': {

+ 57
- 0
iptables/rules.sls ファイルの表示

@@ -1,6 +1,62 @@
{% from "iptables/map.jinja" import service with context %}
{%- if grains.get('virtual_subtype', None) not in ['Docker', 'LXC'] %}

{%- if grains.os_family == 'Debian' and service.get('provider') == "iptables-restore" %}
/etc/iptables/rules.v4.tmp:
file.managed:
- source: salt://iptables/files/rules.v4
- template: jinja
- makedirs: True
- defaults:
chains: {{ service.get('chain', {}) }}
- require:
- pkg: iptables_packages
- file: /usr/share/netfilter-persistent/plugins.d/15-ip4tables
iptables-restore --test /etc/iptables/rules.v4.tmp:
cmd.run:
- onchanges:
- file: /etc/iptables/rules.v4.tmp
cp -a /etc/iptables/rules.v4.tmp /etc/iptables/rules.v4:
cmd.run:
- onchanges:
- cmd: "iptables-restore --test /etc/iptables/rules.v4.tmp"
- watch_in:
- service: iptables_services
cp -a /etc/iptables/rules.v4 /etc/iptables/rules.v4.tmp:
cmd.run:
- onfail:
- cmd: "iptables-restore --test /etc/iptables/rules.v4.tmp"

{%- if grains.ipv6|default(False) and service.ipv6|default(True) %}
/etc/iptables/rules.v6.tmp:
file.managed:
- source: salt://iptables/files/rules.v6
- template: jinja
- makedirs: True
- defaults:
chains: {{ service.get('chain', {}) }}
- require:
- pkg: iptables_packages
- file: /usr/share/netfilter-persistent/plugins.d/25-ip6tables
- watch_in:
- service: iptables_services
ip6tables-restore --test /etc/iptables/rules.v6.tmp:
cmd.run:
- onchanges:
- file: /etc/iptables/rules.v6.tmp
cp -a /etc/iptables/rules.v6.tmp /etc/iptables/rules.v6:
cmd.run:
- onchanges:
- cmd: "ip6tables-restore --test /etc/iptables/rules.v6.tmp"
- watch_in:
- service: iptables_services
cp -a /etc/iptables/rules.v6 /etc/iptables/rules.v6.tmp:
cmd.run:
- onfail:
- cmd: "ip6tables-restore --test /etc/iptables/rules.v6.tmp"
{%- endif %}
{%- else %}

{%- for chain_name, chain in service.get('chain', {}).iteritems() %}

iptables_{{ chain_name }}:
@@ -69,3 +125,4 @@ iptables_{{ chain_name }}_ipv6_policy:

{%- endfor %}
{%- endif %}
{%- endif %}

+ 25
- 0
iptables/service.sls ファイルの表示

@@ -9,6 +9,31 @@ iptables_packages:
pkg.installed:
- names: {{ service.pkgs }}

{%- if grains.os_family == 'Debian' %}
/usr/share/netfilter-persistent/plugins.d/15-ip4tables:
file.managed:
- source: salt://iptables/files/ip4tables
- mode: 755
- template: jinja
- defaults:
provider: {{ service.get('provider') }}
- require:
- pkg: iptables_packages
- watch_in:
- service: iptables_services
/usr/share/netfilter-persistent/plugins.d/25-ip6tables:
file.managed:
- source: salt://iptables/files/ip6tables
- mode: 755
- template: jinja
- defaults:
provider: {{ service.get('provider') }}
- require:
- pkg: iptables_packages
- watch_in:
- service: iptables_services
{%- endif %}

iptables_services:
{%- if grains.init == 'systemd' %}
service.running:

読み込み中…
キャンセル
保存