# this custom script sets FILTER_MARK to specified source ips # NOTE !!! SCRIPT REQUIRES FILTER_MARK VAR IN CONFIG FILE !!! # NOTE !!! WITHOUT FILTER_MARK IT DOES NOTHING !!! # NOTE !!! ON NON-OPENWRT SYSTEMS SCRIPT REQUIRES IFACE_LAN VAR IN CONFIG FILE !!! # can override in config : # LAN ip/cidr list to be fooled. elements are space separated FILTER_LAN_IP="${FILTER_LAN_IP:-192.168.0.0/16}" FILTER_LAN_IP6="${FILTER_LAN_IP6:-fc00::/7}" # allow fooling from local system (0|1) ? FILTER_LAN_ALLOW_OUTPUT="${FILTER_LAN_ALLOW_OUTPUT:-1}" FILTER_LAN_SET="lanfilter" FILTER_LAN_SET6="${FILTER_LAN_SET}6" FILTER_LAN_IPSET_SIZE=${FILTER_LAN_IPSET_SIZE:-256} FILTER_LAN_IPSET_OPT="${FILTER_LAN_IPSET_OPT:-hash:net hashsize 8192 maxelem $FILTER_LAN_IPSET_SIZE}" filter_mark_check() { [ -n "$FILTER_MARK" ] || { echo "WARNING ! lan filter cannot work without FILTER_MARK set in config" return 1 } [ "$DISABLE_IPV4" = 1 -a "$DISABLE_IPV6" = 1 ] && return 1 return 0 } zapret_custom_firewall() { # $1 - 1 - run, 0 - stop filter_mark_check || return local subnet lanifs rule local setmark="-j MARK --set-mark $FILTER_MARK/$FILTER_MARK" local filt4="-m set --match-set $FILTER_LAN_SET src" local filt6="-m set --match-set $FILTER_LAN_SET6 src" get_lanif lanifs [ "$DISABLE_IPV4" != 1 ] && { [ "$FILTER_LAN_ALLOW_OUTPUT" = 1 ] && { ipt_print_op $1 "$setmark" "filter output" ipt_add_del $1 OUTPUT -t mangle $setmark } [ -n "$lanifs" ] && { [ "$1" = 1 ] && { ipset create $FILTER_LAN_SET $FILTER_LAN_IPSET_OPT family inet 2>/dev/null ipset flush $FILTER_LAN_SET for subnet in $FILTER_LAN_IP; do echo add $FILTER_LAN_SET $subnet done | ipset -! restore } for lan in $lanifs; do rule="-i $lan $filt4 $setmark" ipt_print_op $1 "$rule" "filter forward" ipt_add_del $1 FORWARD -t mangle $rule done } } [ "$DISABLE_IPV6" != 1 ] && { [ "$FILTER_LAN_ALLOW_OUTPUT" = 1 ] && { ipt_print_op $1 "$setmark" "filter output" 6 ipt6_add_del $1 OUTPUT -t mangle $setmark } [ -n "$lanifs" ] && { [ "$1" = 1 ] && { ipset create $FILTER_LAN_SET6 $FILTER_LAN_IPSET_OPT family inet6 2>/dev/null ipset flush $FILTER_LAN_SET6 for subnet in $FILTER_LAN_IP6; do echo add $FILTER_LAN_SET6 $subnet done | ipset -! restore } for lan in $lanifs; do rule="-i $lan $filt6 $setmark" ipt_print_op $1 "$rule" "filter forward" 6 ipt6_add_del $1 FORWARD -t mangle $rule done } } [ "$1" = 1 ] || { ipset destroy $FILTER_LAN_SET 2>/dev/null ipset destroy $FILTER_LAN_SET6 2>/dev/null } } zapret_custom_firewall_nft() { filter_mark_check || return local subnets rule local setmark="meta mark set meta mark or $FILTER_MARK" local filt4="ip saddr == @$FILTER_LAN_SET" local filt6="ip6 saddr == @$FILTER_LAN_SET6" local lanif="iifname @lanif" nft_add_chain forward_lan_filter "type filter hook forward priority mangle;" nft_flush_chain forward_lan_filter if [ "$FILTER_LAN_ALLOW_OUTPUT" = 1 ]; then nft_add_chain output_lan_filter "type filter hook output priority mangle;" nft_flush_chain output_lan_filter nft_print_op "$setmark" "filter output" "4+6" nft_add_rule output_lan_filter $setmark else nft_del_chain output_lan_filter 2>/dev/null fi [ "$DISABLE_IPV4" != 1 ] && { make_comma_list subnets $FILTER_LAN_IP nft_create_set $FILTER_LAN_SET "type ipv4_addr; size $FILTER_LAN_IPSET_SIZE; auto-merge; flags interval;" nft_flush_set $FILTER_LAN_SET nft_add_set_element $FILTER_LAN_SET "$subnets" rule="$lanif $filt4 $setmark" nft_print_op "$rule" "filter forward" "4" nft_add_rule forward_lan_filter $rule } [ "$DISABLE_IPV6" != 1 ] && { make_comma_list subnets $FILTER_LAN_IP6 nft_create_set $FILTER_LAN_SET6 "type ipv6_addr; size $FILTER_LAN_IPSET_SIZE; auto-merge; flags interval;" nft_flush_set $FILTER_LAN_SET6 nft_add_set_element $FILTER_LAN_SET6 "$subnets" rule="$lanif $filt6 $setmark" nft_print_op "$rule" "filter forward" "6" nft_add_rule forward_lan_filter $rule } } zapret_custom_firewall_nft_flush() { # this function is called after all nft fw rules are deleted # however sets are not deleted. it's desired to clear sets here. nft_del_chain forward_lan_filter 2>/dev/null nft_del_chain output_lan_filter 2>/dev/null nft_del_set $FILTER_LAN_SET 2>/dev/null nft_del_set $FILTER_LAN_SET6 2>/dev/null }