diff --git a/update_blocklist.nix b/update_blocklist.nix index f248295..bca753a 100755 --- a/update_blocklist.nix +++ b/update_blocklist.nix @@ -1,6 +1,6 @@ { pkgs, config }: let - inherit (pkgs) ipset wget; + inherit (pkgs) ipset wget dig; inherit (config.services.blocklist-updater) blocklists ipSetName @@ -10,7 +10,7 @@ let in '' # Clear ipset from previous address. - # Ignore if it fails, because we don't care + # Ignore if it fails, because we don't care set -e urls=( @@ -40,16 +40,47 @@ in # Create an ip set and add each ip to it one by one # IPv4 and IPv6 regex patterns with CIDR notation support - WARNING: might not be correct for all IPs (e.g. ignore valid ones or accept wrong ones), but seems to work fine + # Also supports hosts files, as well as plain lists of domains. ipv4_regex="^([0-9]{1,3}\.){3}[0-9]{1,3}(\/[0-9]{1,2})?$" ipv6_regex="^([0-9a-fA-F:]+::?[0-9a-fA-F]*)+(\/[0-9]{1,3})?$" + domain_regex='^[a-zA-Z0-9.-]*\.[a-zA-Z][a-zA-Z0-9.-]+$' + host_regex="^0\\.0\\.0\\.0 ''${domain_regex:1}" + + blockIPv4 () { + echo -exist add "${ipSetName}" "$1" + } + + blockIPv6 () { + echo -exist add "${ipV6SetName}" "$1" + } + + blockDomain () { + ${dig}/bin/dig "$1" A +short | + while IFS= read -r IP; do + if [[ $IP =~ $ipv4_regex ]]; then + blockIPv4 "$IP" + fi + done + + ${dig}/bin/dig $1 AAAA +short | + while IFS= read -r IP; do + if [[ "$IP" =~ $ipv6_regex ]]; then + blockIPv6 "$IP" + fi + done + } # Use a temporary buffer to improve performance { while IFS= read -r IP; do if [[ $IP =~ $ipv4_regex ]]; then - echo -exist add "${ipSetName}" "$IP" - elif [[ $IP =~ $ipv6_regex ]]; then - echo -exist add "${ipV6SetName}" "$IP" + blockIPv4 "$IP" + elif [[ "$IP" =~ $ipv6_regex ]]; then + blockIPv6 "$IP" + elif [[ "$IP" =~ $host_regex ]]; then + blockDomain ''${IP:8} + elif [[ "$IP" =~ $domain_regex ]]; then + blockDomain "$IP" else echo "Warning: Invalid line skipped -> $IP" >&2 fi