Oh wow that's nice. So we can use compressed files throughout. This seems to me to further favour @mth404's suggested approach.
Wow, great! That I was looking for - but, how do we add that option to the dnsmasq config? Do we need to edit /etc/dnsmasq.conf, or is there some nicer way?
Edit: I think I have a solution for it:
In /tmp/dnsmasq.d, place a file (e.g. "adb_script") with content:
conf-script=/tmp/dnsmasq-uncompress-ads /tmp/adb_list.overall.gz
In /tmp/dnsmasq-uncompress-ads, I just used "zcat ${1}" for now - don't forget to chmod +x it...
Seems, it is working! Great! Now, we do not even need the uncompressed final config file in /tmp.
Edit2:
Ah - sry, dnsmasq is running - but, seems without any config... Have to try further...
Edit3:
Ok, now, truth came out - I'm still on OpenWRT v21 - my dnsmasq does not have the option "--conf-script". So, could any body with v22 or v23 do a short check?
dnsmasq --help | grep conf-script
It won’t be easy due to the ujail constraints imposed on dnsmasq.
Sure:
root@OpenWrt-1:~# dnsmasq --help | grep conf-script
--conf-script=<path> Execute file and read configuration from stdin.
Time to upgrade, surely?
Sorry, this is partly wrong. The size (here 50% of the total RAM) is the maximum size the tmpfs can occupy. It just eats so much RAM as needed.
You can change the maximum size of a tmpfs on the fly by remounting the tmpsf with another size value. Just use this command:
mount -t tmpfs -o remount,rw,nosuid,nodev,noatime,size="$size" tmpfs /tmp
What about uniq -d to delete duplicate entries?
We've compared (see here):
awk '!seen[$0]++'
with:
sort -u
and it seems sort -u is mostly faster with a lower memory footprint.
Might uniq -d
beat sort -u
?
AFAIK uniq expects a sorted input file, so you have to use both commands:
sort < unsorted-input-file-with-duplicates | uniq -d > sorted-output-file-without-duplicates
Note: 'uniq' does not detect repeated lines unless they are adjacent. You may want to sort the input first, or use 'sort -u' without 'uniq'.
So, I think, this is not an option for us - but, we could test
sort | uniq -d
-u, --unique
with -c, check for strict ordering; without -c, output only the first of an equal run
sort does check strict order, but does it also enforce strict order?
I haven't tested it.
That's the nice thing about /tmp/dnsmasq.d/
, it's already in the jail, so anything you put there is already accessible. (I have a txt_records.conf
for my servers there and gets sucked up automatically without any hacking of the jail setup.)
So, I upgraded my Archer C7v4 to v23, and started to have a fight with that ujail.
Finally, I found a way to use those conf-script option from dnsmasq (usable since v23) - but it is quite a hack and uggly - hopefully, we will find a better solution.
Feel free to give it a test - I tried to get closer to productive adblock-lean, but priority has the function first.
Simply copy adblock-lean.sh to /tmp and start via "/tmp/adblock-lean.sh start", and stop it again with "/tmp/adblock-lean.sh stop"
If you have OpenWRT<v23, the blocklist will be fully extracted.
adblock-lean.sh
#!/bin/sh /etc/rc.common
# misc
# /etc/init.d/dnsmasq restart
# ubus call dnsmasq metrics
# https://d3ward.github.io/toolz/adblock.html
# https://thekelleys.org.uk/dnsmasq/docs/dnsmasq-man.html
# Init Scripts
START=99 #this means the file will be symlinked as /etc/rc.d/Sxxexample - in other words, it will start after the init scripts with START=9 and below, but before START=11 and above.
#STOP=4 #this means the file will be symlinked as /etc/rc.d/Kyyexample - this means it will be stopped after the init scripts with STOP=14 and below, but before STOP=16 and above. This is optional.
extra_command "restart" "start blocklist reload immediately"
extra_command "reload" "start blocklist reload immediately"
EXTRA_COMMANDS="status pause resume delayed_reload gen_stats gen_config"
EXTRA_HELP="
adblock-lean custom commands:
status check dnsmasq and good line count of existing blocklist
pause pause adblock-lean
resume resume adblock-lean
delayed_reload random delayed blocklist reload
gen_stats generate dnsmasq stats for system log
gen_config generate default config"
abl_parse_config()
{
# parse config
[ -f /etc/conf/adblock-lean ] && . /etc/conf/adblock-lean
# Define Default Values
: "${WORKDIR:=/tmp/adblock-lean}"
: "${DL_URL_LIST:=https://big.oisd.nl/dnsmasq2 https://raw.githubusercontent.com/hagezi/dns-blocklists/main/dnsmasq/pro.txt}"
: "${MAX_SINGLE_BLOCKLIST_SIZE:=50m}"
: "${MIN_BLOCKLIST_LINES:=1000}"
# create Workdir
mkdir -p ${WORKDIR} &> /dev/null
}
abl_clean_dnsmasq_blocklist()
{
nice -n 19 sed -n "s~^\(local\|address\)=/\([^/]*\)/.*~\2~p" | sed "y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/"
}
abl_dl_url()
{
fn=$( echo "${1}" | tr -cd '[a-zA-Z0-9]' )
echo "start DL of $1" >&2
REPCOUNT=0
while [ $REPCOUNT -le 3 ]
do
# download, clean and limit rule file to a compressed file
uclient-fetch "${1}" -O- --timeout=2 2> ${WORKDIR}/uclient-fetch_err | abl_clean_dnsmasq_blocklist | head -c "${MAX_SINGLE_BLOCKLIST_SIZE}" | nice -n 19 gzip > ${WORKDIR}/${fn}.new.gz
res=$?
if [ $res -eq 0 ]
then
mv ${WORKDIR}/${fn}.new.gz ${WORKDIR}/${fn}.gz
grep "^Download completed" ${WORKDIR}/uclient-fetch_err >&2
break
else
rm ${WORKDIR}/${fn}.new.gz
echo "Download failed" >&2
fi
REPCOUNT=$( expr $REPCOUNT + 1 )
sleep 20
done
rm -f ${WORKDIR}/uclient-fetch_err
# download ok or backup file there - keep file and decompress to stdout
# return false if file does not exist
nice -n 19 gunzip -ck ${WORKDIR}/${fn}.gz 2>/dev/null
}
abl_dl_all_urls()
{
echo "start DL LIST" >&2
echo "DEBUG: List: ${DL_URL_LIST}"
failed=0
for url in ${DL_URL_LIST}
do
abl_dl_url $url || failed=$( expr $failed + 1 )
done
echo "end DL LIST" >&2
return $failed
}
abl_add_blacklist()
{
echo "start add block" >&2
cat
[ -f ${WORKDIR}/blocklist ] && cat ${WORKDIR}/blocklist
echo "end add block" >&2
}
abl_remove_duplicate()
{
echo "start dedup" >&2
failed=0
#nice -n 19 awk '!seen[$0]++' || failed=100
nice -n 19 sort -u || failed=100
echo "end dedup" >&2
return $failed
}
abl_remove_allow()
{
echo "start remove allow" >&2
if [ -f ${WORKDIR}/allowlist ]
then
nice -n 19 grep -F -x -v -f ${WORKDIR}/allowlist
else
cat
fi
echo "end remove allow" >&2
}
abl_check_min_line_count()
{
nice -n 19 awk -v min=${MIN_BLOCKLIST_LINES} '{print $0; C++};END{ exit(C<min) }'
}
abl_format_output()
{
nice -n 19 sed -e 's:^:address=/:' -e 's:$:/:'
}
# Init Scripts - start
start()
{
echo "start OVERALL" >&2
abl_parse_config
set -o pipefail
# Fail, if one pipe member fails - not only on error on last pipe member
# ( false | true ) ; echo $? # -> 0
# ( set -o pipefail; false | true ) ; echo $? # -> 1
abl_dl_all_urls | abl_add_blacklist | abl_remove_duplicate | abl_remove_allow | abl_check_min_line_count | abl_format_output | nice -n 19 gzip > ${WORKDIR}/adblock-lean-blocklist.new.gz
res=$?
if [ $res -eq 0 ]
then
mv ${WORKDIR}/adblock-lean-blocklist.new.gz /tmp/dnsmasq.d/adblock-lean-blocklist.gz~
OWRTMV="$(sed -n -e "s/^DISTRIB_RELEASE=.\([0-9]\+\).*/\1/p" /etc/openwrt_release)" # detect Major OpenWRT Version
if [ -n "${OWRTMV}" -a "${OWRTMV}" -ge 23 ]
then
# OpenWRT >= v23, with conf-script -> script to extract on daemon load
#echo -e "nice -n 19 zcat $1 | nice -n 19 sed -e 's:^:address=/:' -e 's:$:/:'\n:" > ${WORKDIR}/dnsmasq-uncompress-ads
#chmod +x ${WORKDIR}/dnsmasq-uncompress-ads
cp /bin/busybox /tmp/dnsmasq.d/busybox~
echo "conf-script=/tmp/dnsmasq.d/busybox~ zcat /tmp/dnsmasq.d/adblock-lean-blocklist.gz~" > /tmp/dnsmasq.d/adblock-lean-conf
else # <= v21
# OpenWRT <= v22 -> decompressed file
nice -n 19 gunzip -ck /tmp/dnsmasq.d/adblock-lean-blocklist.gz~ > /tmp/dnsmasq.d/adblock-lean-blocklist
fi
/etc/init.d/dnsmasq running && /etc/init.d/dnsmasq restart
echo "finished OVERALL with success" >&2
else
rm -f ${WORKDIR}/adblock-lean-blocklist.new.gz
echo "finished OVERALL with ERROR $res" >&2
fi
return $res
}
# Init Scripts - stop
stop()
{
abl_parse_config
# remove all adblock-lean files and restart if dnsmasq is running
rm -f /tmp/dnsmasq.d/adblock-lean-conf /tmp/dnsmasq.d/busybox~ /tmp/dnsmasq.d/adblock-lean-blocklist /tmp/dnsmasq.d/adblock-lean-blocklist.gz~
for url in ${DL_URL_LIST}
do
fn=$( echo "${url}" | tr -cd '[a-zA-Z0-9]' )
rm -f ${WORKDIR}/${fn}.gz
done
/etc/init.d/dnsmasq running && /etc/init.d/dnsmasq restart
}
restart()
{
start
}
reload()
{
start
}
delayed_reload()
{
abl_parse_config
# do random delay
random_delay_mins=$(($(hexdump -n 1 -e '"%u"' </dev/urandom)%60))
echo "Delaying download by ${random_delay_mins} minutes \(thundering herd prevention\)." >&2
sleep "${random_delay_mins}m"
start
}
pause()
{
abl_parse_config
# remove all but current compressed blocklist adblock-lean files and restart if dnsmasq is running
rm -f /tmp/dnsmasq.d/adblock-lean-conf /tmp/dnsmasq.d/busybox~ /tmp/dnsmasq.d/adblock-lean-blocklist
/etc/init.d/dnsmasq running && /etc/init.d/dnsmasq restart
}
resume()
{
start
}
status()
{
# TODO
:
}
gen_stats()
{
# TODO
:
}
gen_config()
{
# TODO
:
}
We could place a script there, but would need to tell dnsmasq not to treat it as a conf file.
uci set dhcp.@dnsmasq[0].confdir='/tmp/dnsmasq.d,*.conf'
Really all these gyrations come down to being honest and choosing sensibly sized list(s) for routers with less RAM. With 8GB RAM on x86, I still only use Oisd small without any regrets.
So, I tried hard, but I was not able to start a script at all via "--conf-script" - only thing I was able to manage was to directly uncompress via zcat - for this, I need to copy busybox to /tmp/dnsmasq.d/busybox~ (inside ujail, like efahl wrote). Filenames ending with ~ will be ignored as config file...
The script I provided will do all this things for you if you are on v23.
So, someone needs to update the ujail config to allow executing scripts - but, it was done to isolate dnsmasq for security reason, and adding holes in it is maybe not desired...
Imagine, a hacker has controll over dnsmasq - and now he can also use busybox with all the tools...
Some other Idea would be to process completly outside the ujail, e.g. with named pipes. But. currently, dnsmasq is ignoring named pipes as a config file...
so, finally, I got the script working...
Is somebody still interested in this?
Here the current version:
adblock-lean.sh
#!/bin/sh /etc/rc.common
# misc
# /etc/init.d/dnsmasq restart
# ubus call dnsmasq metrics
# https://d3ward.github.io/toolz/adblock.html # web site to check block
# https://thekelleys.org.uk/dnsmasq/docs/dnsmasq-man.html
# https://lwn.net/Articles/649955/ # ujail background
# Changed in dnsmasq-2.32 on 2006-06-09 22:02:31 in commit 849a8357ba2ea8c8f9e030b2b3a4418c054fb38c
# dnsmasq-2.89\src\option.c:
# 2107: /* only reg files allowed. */
# 2108: if (S_ISREG(buf.st_mode))
# ==> can't use named pipe as config file
# Init Scripts
START=99 #this means the file will be symlinked as /etc/rc.d/Sxxexample - in other words, it will start after the init scripts with START=9 and below, but before START=11 and above.
#STOP=4 #this means the file will be symlinked as /etc/rc.d/Kyyexample - this means it will be stopped after the init scripts with STOP=14 and below, but before STOP=16 and above. This is optional.
extra_command "restart" "start blocklist reload immediately"
extra_command "reload" "start blocklist reload immediately"
EXTRA_COMMANDS="status pause resume delayed_reload gen_stats gen_config"
EXTRA_HELP="
adblock-lean custom commands:
status check dnsmasq and good line count of existing blocklist
pause pause adblock-lean
resume resume adblock-lean
delayed_reload random delayed blocklist reload
gen_stats generate dnsmasq stats for system log
gen_config generate default config"
# load config and set default values where missing
abl_parse_config()
{
# parse config
[ -f /etc/conf/adblock-lean ] && . /etc/conf/adblock-lean
# Define Default Values
: "${DL_URL_LIST:=https://big.oisd.nl/dnsmasq2 https://raw.githubusercontent.com/hagezi/dns-blocklists/main/dnsmasq/pro.txt}"
: "${MAX_SINGLE_BLOCKLIST_SIZE:=50m}"
: "${MIN_BLOCKLIST_LINES:=1000}"
: "${MIN_DL_AGE_MINUTES:=1000}"
# create Workdir
mkdir -p /tmp/adblock-lean-wd &> /dev/null
}
# Idea: other blocklist formats could be added
# Output is one domain per line without any config
abl_clean_dnsmasq_blocklist()
{
nice -n 19 sed -n "s~^\(local\|address\)=/\([^/]*\)/.*~\2~p" | sed "y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/"
}
# download one blocklist - if successfully, store as gz
# if possible, output uncompressed cleaned "one-domain-per-line" list
abl_dl_url()
{
fn=$( echo "${1}" | tr -cd '[a-zA-Z0-9]' )
if find /tmp/adblock-lean-wd -name ${fn}.gz -mmin -${MIN_DL_AGE_MINUTES} | grep -q .
then
echo "skip DL of $1" >&2
else
echo "start DL of $1" >&2
REPCOUNT=0
while :
do
# download, clean and limit rule file to a compressed file
uclient-fetch "${1}" -O- --timeout=2 2> /tmp/adblock-lean-wd/uclient-fetch_err | abl_clean_dnsmasq_blocklist | head -c "${MAX_SINGLE_BLOCKLIST_SIZE}" | nice -n 19 gzip > /tmp/adblock-lean-wd/${fn}.new.gz
res=$?
if [ $res -eq 0 ]
then
mv /tmp/adblock-lean-wd/${fn}.new.gz /tmp/adblock-lean-wd/${fn}.gz
grep "^Download completed" /tmp/adblock-lean-wd/uclient-fetch_err >&2
break
else
rm /tmp/adblock-lean-wd/${fn}.new.gz
echo "Download failed" >&2
fi
REPCOUNT=$( expr $REPCOUNT + 1 )
[ $REPCOUNT -gt 3 ] && break
echo "retry download in 20s"
sleep 20
done
rm -f /tmp/adblock-lean-wd/uclient-fetch_err
fi
# download ok or backup file there - keep file and decompress to stdout
# return false if file does not exist
nice -n 19 gunzip -ck /tmp/adblock-lean-wd/${fn}.gz 2>/dev/null
}
# download a list of blocklists
# idea: there could be mor formats with different clear-functions
abl_dl_all_urls()
{
echo "start DL LIST" >&2
echo "DEBUG: List: ${DL_URL_LIST}"
failed=0
for url in ${DL_URL_LIST}
do
abl_dl_url $url || failed=$( expr $failed + 1 )
done
echo "end DL LIST" >&2
return $failed
}
# append user defined blacklist to current blocklist
abl_add_blacklist()
{
echo "start add block" >&2
cat
[ -f /tmp/adblock-lean-blocklist ] && cat /tmp/adblock-lean-blocklist
echo "end add block" >&2
}
# remove duplicates
abl_remove_duplicate()
{
echo "start dedup" >&2
failed=0
# sort -u seems to need less ram - but could be configurable if really needen
#nice -n 19 awk '!seen[$0]++' || failed=100
nice -n 19 sort -u || failed=100
echo "end dedup" >&2
# OOM could be a error reason
return $failed
}
# filter user defined witelist from currend blocklist
abl_remove_allow()
{
echo "start remove allow" >&2
if [ -f /tmp/adblock-lean-allowlist ]
then
nice -n 19 grep -F -x -v -f /tmp/adblock-lean-allowlist
else
cat
fi
echo "end remove allow" >&2
}
# check if final blacklist has minimum count of lines
abl_check_min_line_count()
{
nice -n 19 awk -v min=${MIN_BLOCKLIST_LINES} '{print $0; C++};END{ exit(C<min) }'
}
# convert one domain per line to a dnsmasq config line
abl_format_output()
{
nice -n 19 sed -e 's:^:address=/:' -e 's:$:/:'
}
# Init Scripts - start
start()
{
echo "start OVERALL" >&2
abl_parse_config
if find /tmp/dnsmasq.d -name .adblock-lean-blocklist.gz -mmin -${MIN_DL_AGE_MINUTES} | grep -q .
then
echo "finished OVERALL - found current blocklist.gz skip DL and regenerate - use stop/start to force" >&2
res=0
else
set -o pipefail
# Fail, if one pipe member fails - not only on error on last pipe member
# ( false | true ) ; echo $? # -> 0
# ( set -o pipefail; false | true ) ; echo $? # -> 1
abl_dl_all_urls | abl_add_blacklist | abl_remove_duplicate | abl_remove_allow | abl_check_min_line_count | nice -n 19 gzip > /tmp/adblock-lean-wd/adblock-lean-blocklist.new.gz
res=$?
if [ $res -eq 0 ]
then
mv /tmp/adblock-lean-wd/adblock-lean-blocklist.new.gz /tmp/dnsmasq.d/.adblock-lean-blocklist.gz
if dnsmasq --help | grep -q conf-script
then # with conf-script -> script to extract blocklist.gz on daemon load
# Because of ujail, we need busybox on a dnsmasq-mounted dir.
# As busybox can't be renamed to e.g. /tmp/dnsmasq.d/.adblock-lean-busybox,
# and /tmp/dnsmasq.d/busybox would cause busybox bin file to be interpreted as conf file for dnsmasq,
# use dnsmasq pid directory for busybox copy.
cp /bin/busybox /var/run/dnsmasq/busybox
# dnsmasq conf-script runs inside ujail - so use /var/run/dnsmasq/busybox, and use nice
# in .adblock-lean-blocklist.gz, there are only domains - use sed to format correct dnsmasq config files
{
echo "/var/run/dnsmasq/busybox nice -n 19 /var/run/dnsmasq/busybox zcat /tmp/dnsmasq.d/.adblock-lean-blocklist.gz |\\"
echo " /var/run/dnsmasq/busybox nice -n 19 /var/run/dnsmasq/busybox sed -e 's:^:address=/:' -e 's:$:/:'"
echo "exit 0"
} > /tmp/dnsmasq.d/.adblock-lean-uncompress
echo 'conf-script="/var/run/dnsmasq/busybox sh /tmp/dnsmasq.d/.adblock-lean-uncompress"' > /tmp/dnsmasq.d/adblock-lean-conf
else # without conf-script -> decompressed file
nice -n 19 gunzip -ck /tmp/dnsmasq.d/.adblock-lean-blocklist.gz | abl_format_output > /tmp/dnsmasq.d/adblock-lean-blocklist
fi
else
rm -f /tmp/adblock-lean-wd/adblock-lean-blocklist.new.gz
echo "finished OVERALL with ERROR $res" >&2
fi
fi
if /etc/init.d/dnsmasq running
then
if [ $res -eq 0 ]
then
/etc/init.d/dnsmasq restart
sleep 3
if /etc/init.d/dnsmasq running
then
echo "finished OVERALL with success" >&2
else
echo "finished OVERALL - start of dnsmasq failed"
mv /tmp/dnsmasq.d/adblock-lean-blocklist /tmp/dnsmasq.d/.adblock-lean-blocklist &>/dev/null
mv /tmp/dnsmasq.d/adblock-lean-conf /tmp/dnsmasq.d/.adblock-lean-conf &>/dev/null
/etc/init.d/dnsmasq restart
sleep 3
if /etc/init.d/dnsmasq running
then
echo "finished OVERALL - start of dnsmasq without adblock-lean successfully"
res=1
else
echo "finished OVERALL - FATAL: start of dnsmasq without adblock-lean FAILED also"
res=64
fi
fi
fi
else
echo "finished OVERALL - but dnsmasq is not running - skip dnsmasq restart" >&2
fi
return $res
}
# Init Scripts - stop
stop()
{
# remove all adblock-lean files and restart if dnsmasq is running
rm -rf /var/run/dnsmasq/busybox /tmp/adblock-lean-wd /tmp/dnsmasq.d/adblock-lean* /tmp/dnsmasq.d/.adblock-lean*
/etc/init.d/dnsmasq running && /etc/init.d/dnsmasq restart
}
restart()
{
start
}
reload()
{
start
}
delayed_reload()
{
# do random delay
random_delay_mins=$(($(hexdump -n 1 -e '"%u"' </dev/urandom)%60))
echo "Delaying download by ${random_delay_mins} minutes \(thundering herd prevention\)." >&2
sleep "${random_delay_mins}m"
start
}
pause()
{
[ -f /tmp/dnsmasq.d/adblock-lean-blocklist ] && mv /tmp/dnsmasq.d/adblock-lean-blocklist /tmp/dnsmasq.d/.adblock-lean-blocklist
[ -f /tmp/dnsmasq.d/adblock-lean-conf ] && mv /tmp/dnsmasq.d/adblock-lean-conf /tmp/dnsmasq.d/.adblock-lean-conf
# rename blocklist or conf file
echo "adblock-lean pause" >&2
/etc/init.d/dnsmasq running && /etc/init.d/dnsmasq restart
}
resume()
{
[ -f /tmp/dnsmasq.d/.adblock-lean-blocklist ] && mv /tmp/dnsmasq.d/.adblock-lean-blocklist /tmp/dnsmasq.d/adblock-lean-blocklist
[ -f /tmp/dnsmasq.d/.adblock-lean-conf ] && mv /tmp/dnsmasq.d/.adblock-lean-conf /tmp/dnsmasq.d/adblock-lean-conf
if [ -f /tmp/dnsmasq.d/adblock-lean-blocklist ] || [ -f /tmp/dnsmasq.d/adblock-lean-conf -a -x /var/run/dnsmasq/busybox ]
then
echo "adblock-lean resume" >&2
/etc/init.d/dnsmasq running && /etc/init.d/dnsmasq restart
else
start
fi
}
status()
{
# TODO
:
}
gen_stats()
{
# TODO
:
}
gen_config()
{
# TODO
:
}
I’m always looking for ways to improve the code @Wizballs and I have been working on, which for me and I think several other users has been working very robustly.
Responsive to your contributions, I have not yet got round to thinking through whether or how to adapt the existing code to work with the compression techniques without compromising on the various logging and error checking aspects. I spent a bit of time today. One obvious and straightforward improvement is to switch from awk to sort -u for the reasons discussed above.
How does the CPU and memory performance of what you’ve put together compare?
Thanks, so, CPU could be easily compared by runtime with original code - original should be faster, but, at least for me, it does not matter, because new blocklist will be created, and when finished, it will be loaded. Only after reboot it could be interesting...
For the memory, I do not know exactly how to check. Are there some users who had OOM problems with original code? Maybe they could test - or, you could add some more big blocklists for a stress test and always compare to the original...
Yes @a-z had exactly this issue - see here - and had to compromise with smaller list. So your compression technique would be ideal for him. @a-z would you be interested in testing @mth404’s script?
With the new dnsmasq blocklists the memory requirements really aren’t that big anymore even for gigantic lists. But still, the whole point of adblock-lean is to be light on resources. So all of this seems very much worth the effort.
@mth404 might not a simpler option be just to set up zram-swap temporarily for operating in in terms of processing?