__iptables*: add IPv6 support

Because it currently only support IPv4. To implement this, it falls back
to IPv4 for backward compatibilty, but now supports rules for IPv6 and
both protocols at the same time.
This commit is contained in:
matze 2020-11-30 20:29:51 +01:00
parent 23e0da521c
commit 84172550df
4 changed files with 140 additions and 25 deletions

View file

@ -1,4 +1,25 @@
#!/bin/sh #!/bin/sh
#
# 2013 Nico Schottelius (nico-cdist at schottelius.org)
# 2020 Matthias Stecher (matthiasstecher at gmx.de)
#
# This file is distributed with cdist.
#
# cdist 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.
#
# cdist 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 cdist. If not, see <http://www.gnu.org/licenses/>.
#
#
# Originally written by:
# Nico Schottelius # Nico Schottelius
# Zürisee, Mon Sep 2 18:38:27 CEST 2013 # Zürisee, Mon Sep 2 18:38:27 CEST 2013
# #
@ -15,33 +36,60 @@
### END INIT INFO ### END INIT INFO
# Read files and execute the content with the given commands
#
# Arguments:
# 1: Directory
# 2..n: Commands which should be used to execute the file content
gothrough() {
cd "$1" || return
shift
# iterate through all rules and continue if it's not a file
for rule in *; do
[ -f "$rule" ] || continue
echo "Appling iptables rule $rule ..."
# execute it with all commands specificed
ruleparam="$(cat "$rule")"
for cmd in "$@"; do
# Command and Rule should be split.
# shellcheck disable=SC2046
command $cmd $ruleparam
done
done
}
# Shortcut for iptables command to do IPv4 and v6
iptables() {
command iptables "$@"
command ip6tables "$@"
}
basedir=/etc/iptables.d basedir=/etc/iptables.d
status="${basedir}/.pre-start" status4="${basedir}/.pre-start"
status6="${basedir}/.pre-start6"
case $1 in case $1 in
start) start)
# Save status # Save status
iptables-save > "$status" iptables-save > "$status4"
ip6tables-save > "$status6"
# Apply our ruleset # Apply our ruleset
cd "$basedir" || exit gothrough "$basedir" iptables
count="$(find . ! -name . -prune | wc -l)" #gothrough "$basedir/v4" iptables # conflicts with $basedir
gothrough "$basedir/v6" ip6tables
# Only do something if there are rules gothrough "$basedir/all" iptables ip6tables
if [ "$count" -ge 1 ]; then
for rule in *; do
echo "Applying iptables rule $rule ..."
# Rule should be split.
# shellcheck disable=SC2046
iptables $(cat "$rule")
done
fi
;; ;;
stop) stop)
# Restore from status before, if there is something to restore # Restore from status before, if there is something to restore
if [ -f "$status" ]; then if [ -f "$status4" ]; then
iptables-restore < "$status" iptables-restore < "$status4"
fi
if [ -f "$status6" ]; then
ip6tables-restore < "$status6"
fi fi
;; ;;
restart) restart)

View file

@ -25,6 +25,24 @@ state
'present' or 'absent', defaults to 'present' 'present' or 'absent', defaults to 'present'
BOOLEAN PARAMETERS
------------------
All rules without any of this parameter will be threaten like ``--v4`` because
of backward compatibility.
v4
Explicitly set it as rule for IPv4. If IPv6 is set, too, it will be
threaten like ``--all``. Will be the default if nothing else is set.
v6
Explicitly set it as rule for IPv6. If IPv4 is set, too, it will be
threaten like ``--all``.
all
Set the rule for both IPv4 and IPv6. It will be saved separately from the
other rules.
EXAMPLES EXAMPLES
-------- --------
@ -48,6 +66,16 @@ EXAMPLES
--state absent --state absent
# IPv4-only rule for ICMPv4
__iptables_rule icmp-v4 --v4 --rule "-A INPUT -p icmp -j ACCEPT"
# IPv6-only rule for ICMPv6
__iptables_rule icmp-v6 --v6 --rule "-A INPUT -p icmpv6 -j ACCEPT"
# doing something for the dual stack
__iptables_rule fwd-eth0-eth1 --v4 --v6 --rule "-A INPUT -i eth0 -o eth1 -j ACCEPT"
__iptables_rule fwd-eth1-eth0 --all --rule "-A -o eth1 -i eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT"
SEE ALSO SEE ALSO
-------- --------
:strong:`cdist-type__iptables_apply`\ (7), :strong:`iptables`\ (8) :strong:`cdist-type__iptables_apply`\ (7), :strong:`iptables`\ (8)
@ -56,11 +84,13 @@ SEE ALSO
AUTHORS AUTHORS
------- -------
Nico Schottelius <nico-cdist--@--schottelius.org> Nico Schottelius <nico-cdist--@--schottelius.org>
Matthias Stecher <matthiasstecher--@--gmx.de>
COPYING COPYING
------- -------
Copyright \(C) 2013 Nico Schottelius. You can redistribute it Copyright \(C) 2013 Nico Schottelius.
and/or modify it under the terms of the GNU General Public License as Copyright \(C) 2020 Matthias Stecher.
published by the Free Software Foundation, either version 3 of the You can redistribute it and/or modify it under the terms of the GNU
License, or (at your option) any later version. General Public License as published by the Free Software Foundation,
either version 3 of the License, or (at your option) any later version.

View file

@ -1,6 +1,7 @@
#!/bin/sh -e #!/bin/sh -e
# #
# 2013 Nico Schottelius (nico-cdist at schottelius.org) # 2013 Nico Schottelius (nico-cdist at schottelius.org)
# 2020 Matthias Stecher (matthiasstecher at gmx.de)
# #
# This file is part of cdist. # This file is part of cdist.
# #
@ -24,12 +25,36 @@ base_dir=/etc/iptables.d
name="$__object_id" name="$__object_id"
state="$(cat "$__object/parameter/state")" state="$(cat "$__object/parameter/state")"
if [ -f "$__object/parameter/v4" ]; then
only_v4="yes"
# $specific_dir is $base_dir
fi
if [ -f "$__object/parameter/v6" ]; then
only_v6="yes"
specific_dir="$base_dir/v6"
fi
# If rules should be set for both protocols
if ([ "$only_v4" = "yes" ] && [ "$only_v6" = "yes" ]) \
|| [ -f "$__object/parameter/all" ]; then
# all to a specific directory
specific_dir="$base_dir/all"
fi
# set rule directory based on if it's the base or subdirectory
rule_dir="${specific_dir:-$base_dir}"
################################################################################ ################################################################################
# Basic setup # Basic setup
# #
__directory "$base_dir" --state present __directory "$base_dir" --state present
# sub-directory if required
if [ "$specific_dir" ]; then
require="__directory/$base_dir" __directory "$specific_dir" --state present
fi
# Have apply do the real job # Have apply do the real job
require="$__object_name" __iptables_apply require="$__object_name" __iptables_apply
@ -37,6 +62,15 @@ require="$__object_name" __iptables_apply
# The rule # The rule
# #
require="__directory/$base_dir" __file "$base_dir/${name}" \ for dir in "$base_dir" "$base_dir/v6" "$base_dir/all"; do
# defaults to absent except the directory that should contain the file
if [ "$rule_dir" = "$dir" ]; then
curr_state="$state"
else
curr_state="absent"
fi
require="__directory/$rule_dir" __file "$dir/$name" \
--source "$__object/parameter/rule" \ --source "$__object/parameter/rule" \
--state "$state" --state "$curr_state"
done

View file

@ -0,0 +1,3 @@
all
v4
v6