From c43bd0eed508f0fb5060d8b4975a370ac3091f95 Mon Sep 17 00:00:00 2001 From: Mesar Hameed Date: Tue, 5 Jan 2021 23:14:29 +0000 Subject: [PATCH] Add new type: __ipset --- cdist/conf/type/__ipset/explorer/content | 26 ++++++ cdist/conf/type/__ipset/explorer/state | 26 ++++++ cdist/conf/type/__ipset/explorer/type | 26 ++++++ .../conf/type/__ipset/files/ipset-persistent | 48 +++++++++++ cdist/conf/type/__ipset/files/ipsets-restore | 28 +++++++ cdist/conf/type/__ipset/files/ipsets-save | 28 +++++++ cdist/conf/type/__ipset/gencode-remote | 79 +++++++++++++++++++ cdist/conf/type/__ipset/man.rst | 69 ++++++++++++++++ cdist/conf/type/__ipset/manifest | 45 +++++++++++ .../conf/type/__ipset/parameter/default/state | 1 + cdist/conf/type/__ipset/parameter/optional | 1 + .../type/__ipset/parameter/optional_multiple | 2 + cdist/conf/type/__ipset/parameter/required | 1 + 13 files changed, 380 insertions(+) create mode 100755 cdist/conf/type/__ipset/explorer/content create mode 100755 cdist/conf/type/__ipset/explorer/state create mode 100755 cdist/conf/type/__ipset/explorer/type create mode 100755 cdist/conf/type/__ipset/files/ipset-persistent create mode 100755 cdist/conf/type/__ipset/files/ipsets-restore create mode 100755 cdist/conf/type/__ipset/files/ipsets-save create mode 100755 cdist/conf/type/__ipset/gencode-remote create mode 100644 cdist/conf/type/__ipset/man.rst create mode 100755 cdist/conf/type/__ipset/manifest create mode 100644 cdist/conf/type/__ipset/parameter/default/state create mode 100644 cdist/conf/type/__ipset/parameter/optional create mode 100644 cdist/conf/type/__ipset/parameter/optional_multiple create mode 100644 cdist/conf/type/__ipset/parameter/required diff --git a/cdist/conf/type/__ipset/explorer/content b/cdist/conf/type/__ipset/explorer/content new file mode 100755 index 00000000..7c9f131e --- /dev/null +++ b/cdist/conf/type/__ipset/explorer/content @@ -0,0 +1,26 @@ +#!/bin/sh +# +# 2021 Mesar Hameed (mesar.hameed at gmail.com) +# +# This file is part of 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 . +# + +name="$__object_id" +if ipset -t list | grep -qP "Name: $name"; then + ipset list "$name" | tail -n +9 +else + echo "x_missing_x" +fi diff --git a/cdist/conf/type/__ipset/explorer/state b/cdist/conf/type/__ipset/explorer/state new file mode 100755 index 00000000..9ece28df --- /dev/null +++ b/cdist/conf/type/__ipset/explorer/state @@ -0,0 +1,26 @@ +#!/bin/sh +# +# 2021 Mesar Hameed (mesar.hameed at gmail.com) +# +# This file is part of 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 . +# + +name="$__object_id" +if ipset -t list "$name" >/dev/null; then + echo "present" +else + echo "absent" +fi diff --git a/cdist/conf/type/__ipset/explorer/type b/cdist/conf/type/__ipset/explorer/type new file mode 100755 index 00000000..5b943c86 --- /dev/null +++ b/cdist/conf/type/__ipset/explorer/type @@ -0,0 +1,26 @@ +#!/bin/sh +# +# 2021 Mesar Hameed (mesar.hameed at gmail.com) +# +# This file is part of 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 . +# + +name="$__object_id" +if ipset -t list | grep -qP "Name: $name"; then + ipset -t list "$name" | grep -P "^Type: " | awk '{print $2}' +else + echo "x_missing_x" +fi diff --git a/cdist/conf/type/__ipset/files/ipset-persistent b/cdist/conf/type/__ipset/files/ipset-persistent new file mode 100755 index 00000000..e812c30f --- /dev/null +++ b/cdist/conf/type/__ipset/files/ipset-persistent @@ -0,0 +1,48 @@ +#!/bin/sh +# +# 2021 Mesar Hameed (mesar.hameed at gmail.com) +# +# This file is part of 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 . +# +# +### BEGIN INIT INFO +# Provides: ipset +# Required-Start: $local_fs $remote_fs +# Required-Stop: $local_fs $remote_fs +# X-Start-Before: iptables +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Create ipset lists before iptables rules require them +# Description: Applies lists found in /etc/ipset.d/*.saved +# and saves/restores previous status +### END INIT INFO + +case $1 in + start) + # Restore previous state: + /usr/local/bin/ipsets-restore + ;; + stop) + # Save current state before exiting: + /usr/local/bin/ipsets-save + ;; + restart) + "$0" stop && "$0" start + ;; + reset) + ipset flush + ;; +esac diff --git a/cdist/conf/type/__ipset/files/ipsets-restore b/cdist/conf/type/__ipset/files/ipsets-restore new file mode 100755 index 00000000..30df3a13 --- /dev/null +++ b/cdist/conf/type/__ipset/files/ipsets-restore @@ -0,0 +1,28 @@ +#!/bin/sh +# +# 2021 Mesar Hameed (mesar.hameed at gmail.com) +# +# This file is part of 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 . +# + +mkdir -p /etc/ipset.d/ +if [ -n "$1" ]; then + ipset -! restore < "/etc/ipset.d/$1" +else +find /etc/ipset.d/ -iname "*.saved" | while read s; do + ipset -! restore <$s +done +fi diff --git a/cdist/conf/type/__ipset/files/ipsets-save b/cdist/conf/type/__ipset/files/ipsets-save new file mode 100755 index 00000000..2aed28ec --- /dev/null +++ b/cdist/conf/type/__ipset/files/ipsets-save @@ -0,0 +1,28 @@ +#!/bin/sh +# +# 2021 Mesar Hameed (mesar.hameed at gmail.com) +# +# This file is part of 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 . +# + +mkdir -p /etc/ipset.d/ +if [ -n "$1" ]; then + ipset save "$1" > "/etc/ipset.d/${1}.saved" +else +ipset -t list | grep -P "^Name:" | awk '{print $2}' | while read s; do + ipset save $s > /etc/ipset.d/$s.saved +done +fi diff --git a/cdist/conf/type/__ipset/gencode-remote b/cdist/conf/type/__ipset/gencode-remote new file mode 100755 index 00000000..f3ec8c2a --- /dev/null +++ b/cdist/conf/type/__ipset/gencode-remote @@ -0,0 +1,79 @@ +#!/bin/bash -e +# +# 2021 Mesar Hameed (mesar.hameed at gmail.com) +# +# This file is part of 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 . +# + +e="$__object/explorer" +p="$__object/parameter" +name="$__object_id" +type_is="$(cat "$e/type")" +type_should="$(cat "$p/type")" +state_is="$(cat "$e/state")" +state_should="$(cat "$p/state")" +needToSave=0 + +case $state_should in + present) + if [ "$state_is" = "absent" ]; then + echo ipset create "$name" "$type_should" + needToSave=1 + elif [ "$state_is" = "present" ] && [ "$type_is" != "$type_should" ]; then + echo ipset destroy "$name" + echo "rm \"/etc/ipset.d/${name}.saved\" || true" + echo ipset create "$name" "$type_should" + needToSave=1 + fi + ;; + absent) + if [ "$state_is" = "present" ]; then + echo ipset destroy "$name" + echo "rm \"/etc/ipset.d/${name}.saved\" || true" + fi + ;; + *) + echo "Unknown state: $state_should" >&2 + exit 1 + ;; +esac + +if [ "$state_should" = "present" ]; then + if [ -f "$p/add" ]; then + while read -r value; do + if ! grep -q "$value" "$e/content"; then + echo "ipset add $name $value" + needToSave=1 + fi + done < "$p/add" + fi + + if [ -f "$p/del" ]; then + while read -r value; do + if grep -q "$value" "$e/content"; then + echo "ipset del $name $value" + needToSave=1 + fi + done < "$p/del" + fi +elif [ "$state_should" = "absent" ] && \( [ -f "$p/add" ] || [ -f "$p/del" ] \); then + echo "Error: ipset state absent is incompatible with --add or --del" >&2 + exit 1 +fi + +if [ $needToSave -ne 0 ]; then + echo /usr/local/bin/ipsets-save "$name" +fi diff --git a/cdist/conf/type/__ipset/man.rst b/cdist/conf/type/__ipset/man.rst new file mode 100644 index 00000000..f376470e --- /dev/null +++ b/cdist/conf/type/__ipset/man.rst @@ -0,0 +1,69 @@ +cdist-type__ipset(7) +==================== + +NAME +---- +cdist-type__ipset - Manage ipset sets + +DESCRIPTION +----------- +Making use of ipset sets in iptable rules can make your rules more expressive, maintainable and efficient. + +REQUIRED PARAMETERS +------------------- +type + One of the supported ipset set types, for a full list see: + + ``ipset help`` + +OPTIONAL PARAMETERS +------------------- +add + The entry that must exist in the given set. + + Can be used multiple times. +del + The entry that must not exist in the given set. + + Can be used multiple times. +state + Can be: + + - ``present``: ensure that the given set exists. + - ``absent``: ensure the given set doesn't exist. + +BOOLEAN PARAMETERS +------------------ +None. + +EXAMPLES +-------- + +.. code-block:: sh + + # Make sure a set with the given name/type exists: + __ipset testset1 --type hash:ip + + # Ensure allowed_ssh_clients contains private range: + __ipset allowed_ssh_hosts --type hash:net \ + --add 192.168.0.0/24 --add 10.0.0.0/8 + + # Make sure host is not on the blocked list: + __ipset blocked_hosts --type hash:ip \ + --del 1.2.3.4 + + +SEE ALSO +-------- +:strong:`cdist-type__iptables_rule`\ (7), :strong:`iptables`\ (8) + +AUTHORS +------- +Mesar Hameed + +COPYING +------- +Copyright \(C) 2021 Mesar Hameed. 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. diff --git a/cdist/conf/type/__ipset/manifest b/cdist/conf/type/__ipset/manifest new file mode 100755 index 00000000..769a50b8 --- /dev/null +++ b/cdist/conf/type/__ipset/manifest @@ -0,0 +1,45 @@ +#!/bin/sh -e +# +# 2021 Mesar Hameed (mesar.hameed at gmail.com) +# +# This file is part of 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 . +# + +os=$(cat "$__global/explorer/os") +case "$os" in + debian) + : + ;; + ubuntu) + : + ;; + *) + echo "OS $os currently not supported" >&2 + exit 1 + ;; +esac + +export CDIST_ORDER_DEPENDENCY=on + +# install packages +__package ipset + +__file /etc/init.d/ipset-persistent --mode 0755 --source "${__type}/files/ipset-persistent" +__file /usr/local/bin/ipsets-restore --mode 0755 --source "${__type}/files/ipsets-restore" +__file /usr/local/bin/ipsets-save --mode 0755 --source "${__type}/files/ipsets-save" +__systemd_unit ipset-persistent --enablement-state enabled --restart + +unset CDIST_ORDER_DEPENDENCY diff --git a/cdist/conf/type/__ipset/parameter/default/state b/cdist/conf/type/__ipset/parameter/default/state new file mode 100644 index 00000000..e7f6134f --- /dev/null +++ b/cdist/conf/type/__ipset/parameter/default/state @@ -0,0 +1 @@ +present diff --git a/cdist/conf/type/__ipset/parameter/optional b/cdist/conf/type/__ipset/parameter/optional new file mode 100644 index 00000000..ff72b5c7 --- /dev/null +++ b/cdist/conf/type/__ipset/parameter/optional @@ -0,0 +1 @@ +state diff --git a/cdist/conf/type/__ipset/parameter/optional_multiple b/cdist/conf/type/__ipset/parameter/optional_multiple new file mode 100644 index 00000000..4f890061 --- /dev/null +++ b/cdist/conf/type/__ipset/parameter/optional_multiple @@ -0,0 +1,2 @@ +add +del diff --git a/cdist/conf/type/__ipset/parameter/required b/cdist/conf/type/__ipset/parameter/required new file mode 100644 index 00000000..aa80e646 --- /dev/null +++ b/cdist/conf/type/__ipset/parameter/required @@ -0,0 +1 @@ +type