Am 23.03.20 um 14:14 schrieb Pablo Neira Ayuso: > On Mon, Mar 23, 2020 at 01:43:45PM +0100, Reindl Harald wrote: > [...] >> {LAN_BASE_IPV4} depends on a shell variable which depends on $HOSTNAME >> and so on...... >> >> [root@firewall:/scripts/firewall]$ cat ipset_ADMIN_CLIENTS.txt >> # Supported: >> # - Single IP (192.168.1.1) >> # - CIDR-Ranges (192.168.1.0/24) >> # - From-To (192.168.1.10-192.168.1.20) >> # >> # Substitution: >> # - {LAN_BASE_IPV4} >> # - {WAN_BASE_IPV4} >> # - {IPV6_PREFIX} >> >> {LAN_BASE_IPV4}.244 >> {LAN_BASE_IPV4}.103 > > Could you provide a bit mode details on this substitution feature you > implemented in your scripts? well, i try at least :-) see "ipset-function.txt" which is the core function shared by the script which resets/builds the ruleset from scratch and by the admin interface in summary that's the result of "the firewall i want to have and can't buy anywhere" -------------------- [root@firewall:~]$ firewall_status.sh | grep "add\-set" | wc -l 4 [root@firewall:~]$ firewall_status.sh | grep "match\-set" | wc -l 43 -------------------- basicly the whole stuff is 4000 lines bash code building up a corporate firewall for a /24 network with servers and clients with a bash TUI backend in a nested ESXi we have a 1:1 copy of the firewall-vm, one vm with a whole /24 on the lan interface and a vm on the wan interface test rulesets and the substitution is based on the hostname so you can do "synch-from-live.sh", implement stuff, test it and be sure that "synch-to-live.sh" and aplly "firewall.sh" at production behaves identical * NAT * ratelimits - xt_recent in different stages (mangle/filter/raw) - first limit just drops - second limit adds to ipset in -t "raw" * connlimits * honeypot machines * honeypot ports * ipset to split ruleset and data * ipset to get performance with large dynamic blacklists -------------------- the TUI interface besides a lot of statistics based on iptables --list and grep/awk/bc-magic also controls ipsets and shows statistics and entries if one of the textfiles was changed by "nano" called from the TUI a reload is triggered -> strip out comments, check with "ipcalc" if it's a valid ip/cidr and if it's ipv4/ipv6 so it builds a temporary ipset for ipv4 *and* ipv6 if loaded and then switchs between old and new to add new ipsets just create a textfile and add it to "config.inc.sh", it will get laoded and appear automatically in the TUI and with hooks in "custom.inc.sh" you place iptables rules the whole stuff is designed to use iptables or ip6tables automatically and use the _IPV4 or _IPV6 suffixed ipset -------------------- RULES: 256 IPV4 total 203 IPV4 filter 31 IPV4 mangle 14 IPV4 raw 8 IPV4 nat CHAINS: 64 IPV4 total 52 IPV4 filter 9 IPV4 mangle 2 IPV4 raw 1 IPV4 nat -------------------- [root@firewall:/scripts/firewall]$ /bin/ls -1 config.inc.sh custom.inc.sh firewall.sh ipset_ADMIN_CLIENTS.txt ipset_BAYES_SYNC.txt ipset_BLOCKED.txt ipset_EXCLUDES.txt ipset_HONEYPOT_IPS.txt ipset_HONEYPOT_PORTS.txt ipset_IANA_RESERVED.txt ipset_IPERF.txt ipset_JABBER.txt ipset_LAN_VPN_FORWARDING.txt ipset_OUTBOUND_BLOCKED_PORTS.txt ipset_OUTBOUND_BLOCKED_SRC.txt ipset_PORTSCAN_PORTS.txt ipset_PORTS_MAIL.txt ipset_PORTS_RESTRICTED.txt ipset_RBL_SYNC.txt ipset_RESTRICTED.txt ipset_SFTP_22.txt ipset_SSH_HOSTING.txt shared.inc.sh tui.sh update-blocked-feed.sh
function ipset_load_iplist() { debug_msg "FUNCTION: ipset_load_iplist $1" local ITEM LEFT RIGHT FILE="$FIREWALL_BASEDIR/ipset_$1.txt" if [ -f "$FILE" ]; then if [ "$2" == 1 ]; then echo -e "$IPSET -exist create ${1}_IPV4_TMP $IPSET_IPLIST_PARAMS family inet" echo -e "$IPSET ${COLOR_CODE}flush${COLOR_STOP} ${1}_IPV4_TMP\n" if [ "$IPV6_LOADED" == 1 ]; then echo -e "$IPSET -exist create ${1}_IPV6_TMP $IPSET_IPLIST_PARAMS family inet6" echo -e "$IPSET ${COLOR_CODE}flush${COLOR_STOP} ${1}_IPV6_TMP\n" fi fi $IPSET -exist create "${1}_IPV4" $IPSET_IPLIST_PARAMS family inet $IPSET -exist create "${1}_IPV4_TMP" $IPSET_IPLIST_PARAMS family inet $IPSET flush "${1}_IPV4_TMP" if [ "$IPV6_LOADED" == 1 ]; then $IPSET -exist create "${1}_IPV6" $IPSET_IPLIST_PARAMS family inet6 $IPSET -exist create "${1}_IPV6_TMP" $IPSET_IPLIST_PARAMS family inet6 $IPSET flush "${1}_IPV6_TMP" fi for ITEM in $(read_file_fw "$FILE" 1); do if [[ $ITEM == *'-'* ]]; then read LEFT RIGHT <<< "${ITEM//-/ }" if ipcalc --silent -c -4 "${LEFT}"; then if [ "$2" == 1 ]; then echo -e "$IPSET add ${1}_IPV4_TMP ${COLOR_CODE}${ITEM}${COLOR_STOP}"; fi $IPSET add "${1}_IPV4_TMP" "$ITEM" else if [ "$IPV6_LOADED" == 1 ]; then if [ "$2" == 1 ]; then echo -e "$IPSET add ${1}_IPV6_TMP ${COLOR_CODE}${ITEM}${COLOR_STOP}"; fi $IPSET add "${1}_IPV6_TMP" "$ITEM" fi fi else if ipcalc --silent -c -4 "$ITEM"; then if [ "$2" == 1 ]; then echo -e "$IPSET add ${1}_IPV4_TMP ${COLOR_CODE}${ITEM}${COLOR_STOP}"; fi $IPSET add "${1}_IPV4_TMP" "$ITEM" else if [ "$IPV6_LOADED" == 1 ]; then if [ "$2" == 1 ]; then echo -e "$IPSET add ${1}_IPV6_TMP ${COLOR_CODE}${ITEM}${COLOR_STOP}"; fi $IPSET add "${1}_IPV6_TMP" "$ITEM" fi fi fi done if [ "$2" == 1 ]; then echo -e "\n${COLOR_CODE}$IPSET swap${COLOR_STOP} ${1}_IPV4_TMP ${1}_IPV4" echo -e "${COLOR_CODE}$IPSET destroy${COLOR_STOP} ${1}_IPV4_TMP\n" if [ "$IPV6_LOADED" == 1 ]; then echo -e "${COLOR_CODE}$IPSET swap${COLOR_STOP} ${1}_IPV6_TMP ${1}_IPV6" echo -e "${COLOR_CODE}$IPSET destroy${COLOR_STOP} ${1}_IPV6_TMP\n" fi fi $IPSET swap "${1}_IPV4_TMP" "${1}_IPV4" $IPSET destroy "${1}_IPV4_TMP" if [ "$IPV6_LOADED" == 1 ]; then $IPSET swap "${1}_IPV6_TMP" "${1}_IPV6" $IPSET destroy "${1}_IPV6_TMP" fi if [ "$2" == 1 ]; then $IPSET -terse list "${1}_IPV4" if [ "$IPV6_LOADED" == 1 ]; then echo ''; $IPSET -terse list "${1}_IPV6"; fi fi else echo -e "\n$(date_time)\e[31mERROR:\e[0m file '$FILE' not found\n" > '/dev/stderr'; fi }