Enhance IPv6 ban functionality: add dynamic mask handling and prevent banning own addresses

This commit is contained in:
2026-10-27 22:26:12 +01:00
parent fbe10b43d0
commit f6660709ce
5 changed files with 116 additions and 2 deletions
+56 -1
View File
@@ -448,6 +448,29 @@ fi
# ---
# - ICMPv6 Neighbor Discovery and Packet Too Big
# ---
# Accept these before any rule blocking by source address (blocked_ips,
# ban_ipv6.list). Otherwise a blocked network containing a router of the
# own link breaks neighbor discovery - the router can no longer reach this host.
#
# 2 = packet-too-big
# 133= router-solicitation
# 134= router-advertisement
# 135= neighbor-solicitation
# 136= neighbor-advertisement
# ---
echononl "\tICMPv6 neighbor discovery / packet-too-big (before blocking rules).."
for t in 2 133 134 135 136 ; do
$ip6t -A INPUT -p ipv6-icmp --icmpv6-type $t -j ACCEPT
done
if $kernel_forward_between_interfaces ; then
$ip6t -A FORWARD -p ipv6-icmp --icmpv6-type 2 -j ACCEPT
fi
echo_done
# -------------
# --- Block IPs / Networks / Interfaces
# -------------
@@ -509,6 +532,19 @@ if [[ -f "$conf_ban_ipv6_list" ]] ; then
declare -a ban_ipv6_arr=()
declare -a no_valid_ipv6=()
declare -a own_ipv6_banned_arr=()
if [[ -z "$ban_ipv6_mask" || ! "$ban_ipv6_mask" =~ ^[0-9]+$ ]] || [[ $ban_ipv6_mask -gt 128 ]] ; then
ban_ipv6_mask=${default_ban_ipv6_mask:-128}
fi
# Own global IPv6 addresses (read at runtime, also covers SLAAC addresses).
# Entries covering one of them would block the own prefix including its routers.
#
declare -a own_ipv6_arr=()
for _own_ip in $(ip -6 -o addr show scope global | awk '{split($4, a, "/"); print a[1]}') ; do
own_ipv6_arr+=("$_own_ip")
done
# Regex valid ipv6 address
#
@@ -568,7 +604,7 @@ if [[ -f "$conf_ban_ipv6_list" ]] ; then
fi
fi
else
mask=64
mask=$ban_ipv6_mask
is_valid_mask=true
fi
@@ -586,6 +622,22 @@ if [[ -f "$conf_ban_ipv6_list" ]] ; then
continue
fi
# Never ban a network containing an own address
#
_covers_own_ip=false
for _own_ip in "${own_ipv6_arr[@]}" ; do
if ipv6_in_net "$_own_ip" "$ipv6" "$mask" ; then
_covers_own_ip=true
break
fi
done
if $_covers_own_ip ; then
if ! containsElement "$_ip" "${own_ipv6_banned_arr[@]}" ; then
own_ipv6_banned_arr+=("$_ip")
fi
continue
fi
for _dev in ${ext_if_arr[@]} ; do
if $log_blocked_ip || $log_all ; then
$ip6t -A INPUT -i $_dev -s $_ip -j $LOG_TARGET $tag_log_prefix "$log_prefix Blocked by ban_ipv6.list: "
@@ -614,6 +666,9 @@ if [[ -f "$conf_ban_ipv6_list" ]] ; then
if [[ ${#no_valid_ipv6_arr[@]} -gt 0 ]]; then
warn "Ignored: ${no_valid_ipv6_arr[@]}"
fi
if [[ ${#own_ipv6_banned_arr[@]} -gt 0 ]]; then
warn "Ignored (covers own address): ${own_ipv6_banned_arr[@]}"
fi
else
echo_skipped
fi