X-Git-Url: http://git.squeep.com/?p=firewall-squeep;a=blobdiff_plain;f=common.sh;h=5c2ed1a56e052dc5b53a08e20dfeb4e4099e49d0;hp=4bb66ff664b0a8be18b419a9eda030f0abc78680;hb=HEAD;hpb=0f864e054ebdb2c6606721dc49db867fe93cb61e diff --git a/common.sh b/common.sh index 4bb66ff..5c2ed1a 100644 --- a/common.sh +++ b/common.sh @@ -5,9 +5,21 @@ set -e IPTABLES=$(which iptables) IP6TABLES=$(which ip6tables) IPSET=$(which ipset) +TC=$(which tc) + +err(){ + echo "$@" 1>&2 +} + +die(){ + local status=$1 + shift + err "$@" + exit ${status} +} function decommentcat(){ - sed 's/\s*#.*$//;/^\s*$/d' "$@" + cat "$@" | sed 's/\s*#.*$//;/^\s*$/d' } function create_set(){ @@ -20,3 +32,146 @@ function create_set(){ fi } +function create_drop_chain(){ + local chain="$1" + + if ! $IPTABLES -L "${chain}" >/dev/null 2>&1 + then + echo "initializing chain '${chain}'" + $IPTABLES -N "${chain}" || $IPTABLES -F "${chain}" + $IPTABLES -A "${chain}" -m conntrack --ctstate ESTABLISHED,RELATED -j RETURN + $IPTABLES -A "${chain}" -j REJECT --reject-with icmp-port-unreachable + $IPTABLES -v -L "${chain}" + fi + + if ! $IP6TABLES -L "${chain}" >/dev/null 2>&1 + then + echo "initializing chain '${chain}' ipv6" + $IP6TABLES -N "${chain}" || $IP6TABLES -F "${chain}" + $IP6TABLES -A "${chain}" -m conntrack --ctstate ESTABLISHED,RELATED -j RETURN + $IP6TABLES -A "${chain}" -j REJECT --reject-with icmp6-port-unreachable + $IP6TABLES -v -L "${chain}" + fi +} + +function insert_setmatch_rules(){ + local single=0 + if [ "x$1" = "x-single-set" ] + then + single=1 + shift + fi + local ipt set_name="$1" + shift + for v in '' '6' + do + eval ipt="\$IP${v}TABLES" + if [ $single -eq 1 ] + then + v='' + fi + if ! $ipt -C INPUT -m set --match-set "${set_name}${v}" src "$@" >/dev/null 2>&1 + then + echo "initializing rule '${set_name}${v}'" + $ipt -I INPUT -m set --match-set "${set_name}${v}" src "$@" + fi + done +} + +# try to recreate sets faster than one-at-a-time by generating restore rules +function ipset_restore_from_cidr(){ + local vmatch + local set_name="$1" + + for v in '' '6' + do + case "$v" in + 6) vmatch=':';; + *) vmatch='\.';; + esac + # extract existing set configuration to create temporary set + (set -o pipefail; $IPSET save "${set_name}${v}" 2>/dev/null | grep -m 1 '^create ' | sed "s/\(create ${set_name}${v}\)/\1-tmp/") || continue + # populate with new data + decommentcat "${set_name}.cidr" "${set_name}.cidr.$(hostname -s)" 2>/dev/null | sed -n 's/\(.*'"${vmatch}"'.*\)/add '"${set_name}${v}-tmp"' \1/p' | sort -n | uniq + done +} + +function reload_cidr_sets(){ + local v n + local set_name="$1" + + ipset_restore_from_cidr "${set_name}" | ipset restore + for v in '' 6 + do + n="${set_name}${v}" + $IPSET swap "${n}-tmp" "${n}" + $IPSET destroy "${n}-tmp" + $IPSET list -t "${n}" + done +} + +function _old_reload_cidr_sets(){ + local sfx n s v + local set_name="$1" + shift + + # init new temporary sets + echo "updating set '${set_name}'" + + create_set "${set_name}-tmp" hash:net "$@" + create_set "${set_name}6-tmp" hash:net "$@" family inet6 + + # populate them + for sfx in '' .$(hostname -s) + do + cidrfile="${set_name}.cidr${sfx}" + if [ -e "${cidrfile}" ] + then + for s in $(decommentcat "${cidrfile}") + do + case "${s}" in + *.*) table="${set_name}-tmp" ;; + *:*) table="${set_name}6-tmp" ;; + *) + echo "unknown entry '${s}' in '${cidrfile}'" 1>&2 + continue + ;; + esac + $IPSET add "${table}" "${s}" + done + fi + done + + # take new sets live + for v in '' 6 + do + n="${set_name}${v}" + $IPSET swap "${n}-tmp" "${n}" + $IPSET destroy "${n}-tmp" + $IPSET list -t "${n}" + done +} + +function add_service_entry(){ + local port proto + port=$(echo "$1" | cut -d/ -f1) + proto=$(echo "$1" | cut -d/ -f2) + $IPSET -exist add allowed_${proto} ${port} +} + +function allow_services(){ + local s + for s in "$@" + do + case "${s}" in + */*) add_service_entry "${s}" + ;; + *) for svc in $(egrep "^${s}\s+" /etc/services | decommentcat | awk '{print $2}') + do + add_service_entry "${svc}" + done + ;; + esac + done +} +