Compare commits

...

3 Commits

Author SHA1 Message Date
Dan Church 1a97ec8365
Add support for allowlists 2022-11-25 16:17:54 -06:00
Dan Church fd8061714f
Use a common method of reading lines
Adds comment support for domain lists.
2022-11-25 15:40:20 -06:00
Dan Church 59ef0fd513
Limit file clobbering during update
Don't clobber files in-place unless there's actual changes.
2022-11-25 14:58:27 -06:00
4 changed files with 75 additions and 48 deletions

6
allowlists/.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
# Ignore everything in this directory
*
# Except this file
!.gitignore
# ... And some others
!/allowlist.domains.example

View File

@ -0,0 +1,8 @@
# Omit these domains from the blocklist.
#
# Must be in a file called *.domains in this directory.
# Comments are allowed. One domain per line.
#
# Examples:
# domain1.example.com
# domain2.example.com

View File

@ -23,15 +23,10 @@ use FindBin qw//;
my %domains;
my $dupes = 0;
my $skip = 0;
my $removed_allowed = 0;
sub add_domain_list {
my $file = shift;
open my $fni, '<', $file
or die "Failed to open file $file for reading: $!";
foreach my $line (<$fni>) {
chomp $line;
$line =~ s/^\s+|\s+$//;
foreach my $line (&read_stripped($file)) {
my $domain = lc $line;
++$dupes if defined $domains{$domain};
$domains{$domain} = 1;
@ -40,15 +35,7 @@ sub add_domain_list {
sub add_host_file {
my $file = shift;
open my $fni, '<', $file
or die "Failed to open file $file for reading: $!";
foreach my $line (<$fni>) {
chomp $line;
# strip whitespace and comments
$line =~ s/^\s+|\s+$|\s*#.*$//;
next unless $line;
foreach my $line (&read_stripped($file)) {
my @parts = split /\s+/, $line;
die "Malformed line in $file: $line; @parts"
unless @parts > 1;
@ -66,6 +53,20 @@ sub add_host_file {
}
}
sub read_stripped {
my $file = shift;
open my $fni, '<', $file
or die "Failed to open file $file for reading: $!";
map {
chomp;
# Strip whitespace and comments
s/^\s+|\s+$|\s*#.*$//;
$_ || ()
} <$fni>;
}
MAIN: {
my $out;
my $block_ip = '0.0.0.0 ::1';
@ -82,6 +83,7 @@ MAIN: {
my @domain_lists = glob "$workdir/lists/*.domains";
my @hosts_lists = glob "$workdir/lists/*.hosts";
my @allow_lists = glob "$workdir/allowlists/*.domains";
foreach my $listfile (@domain_lists) {
&add_domain_list($listfile);
@ -90,6 +92,16 @@ MAIN: {
&add_host_file($hostfile);
}
# Apply allowlists
my @allow_domains;
foreach my $allowlist (@allow_lists) {
push @allow_domains, &read_stripped($allowlist);
}
my $before = %domains;
delete %domains{@allow_domains};
# Count number removed
$removed_allowed = $before - %domains;
my $written = 0;
my $fho = \*STDOUT;
if (defined $out && length $out) {
@ -109,5 +121,6 @@ MAIN: {
printf STDERR " - %d .domains files\n", (scalar @domain_lists);
printf STDERR " - %d .hosts files\n", (scalar @hosts_lists);
printf STDERR "(%d duplicates)\n", $dupes if $dupes;
printf STDERR "(%d domains removed via allowlist)\n", $removed_allowed if $removed_allowed;
printf STDERR "(%d skipped)\n", $skip if $skip;
}

View File

@ -36,6 +36,34 @@ cleanup() {
}
trap 'cleanup' EXIT
copy_perms() {
local -r FROM=$1 TO=$2
chmod --reference="$FROM" -- "$TO"
if [[ $UID -eq 0 ]]; then
chown --reference="$FROM" -- "$TO"
fi
}
replace_with() {
local -r ORIG=$1 NEW=$2
if ! diff -q -- "$ORIG" "$NEW" &>/dev/null; then
# There's a change
if [[ -f $ORIG ]]; then
copy_perms "$ORIG" "$NEW"
if [[ -n $BACKUPSUFFIX ]]; then
mv -- "$ORIG" "$ORIG$BACKUPSUFFIX"
fi
else
mkdir -p -- "${ORIG%/*}"
fi
mv -- "$NEW" "$ORIG"
else
printf 'File "%s" not modified\n' \
"$ORIG" \
>&2
fi
}
(cd "$WORKDIR" && git submodule update --init --remote)
for (( I = 0 ; I < ${#OUT[@]} ; ++I )); do
@ -52,44 +80,16 @@ for (( I = 0 ; I < ${#OUT[@]} ; ++I )); do
TEMP_OUT=$(mktemp -p "$TEMP_DIR")
if [[ -f $MY_OUT ]]; then
cp -a -- "$MY_OUT" "$TEMP_OUT"
fi
wget \
-O "$TEMP_OUT" \
"$MY_URL"
if [[ -f $MY_OUT ]]; then
chmod --reference="$MY_OUT" "$TEMP_OUT"
if [[ -n $BACKUPSUFFIX ]]; then
mv -- "$MY_OUT" "$MY_OUT$BACKUPSUFFIX"
fi
fi
mkdir -p -- "${MY_OUT%/*}"
mv -- "$TEMP_OUT" "$MY_OUT"
# If the old one is the same, don't keep it around
if [[ -n $BACKUPSUFFIX && -f $MY_OUT$BACKUPSUFFIX ]]; then
if diff -q "$MY_OUT" "$MY_OUT$BACKUPSUFFIX"; then
rm -f -- "$MY_OUT$BACKUPSUFFIX"
fi
fi
replace_with "$MY_OUT" "$TEMP_OUT"
done
if [[ -n $BACKUPSUFFIX && -f $BLOCKLIST ]]; then
mv -- "$BLOCKLIST" "$BLOCKLIST$BACKUPSUFFIX"
fi
"$WORKDIR/make-block.pl" --out="$BLOCKLIST"
# If the old one is the same the same, don't keep it around
if [[ -n $BACKUPSUFFIX && -f $BLOCKLIST$BACKUPSUFFIX ]]; then
if diff -q "$BLOCKLIST" "$BLOCKLIST$BACKUPSUFFIX"; then
rm -f -- "$BLOCKLIST$BACKUPSUFFIX"
fi
fi
TEMP_BLOCKLIST=$(mktemp -p "$TEMP_DIR")
"$WORKDIR/make-block.pl" --out="$TEMP_BLOCKLIST"
replace_with "$BLOCKLIST" "$TEMP_BLOCKLIST"
if [[ ${#DNSMASQ_RESTART_COMMAND[@]} -gt 0 ]]; then
"${DNSMASQ_RESTART_COMMAND[@]}"