Self-written network filter module installation script

Hello community!

Wrote following script for devices that cannot handle AdGuard Home or Pi-Hole.

Minimal requirements 20 MB of storage.

This script should just be run once and it will setup LuCI web interface automatically.

I will be very pleased if you will share your fixes or feedback.

#!/bin/sh

FILTERING_PACKAGE="adblock"
UPDATE_SCRIPT="/usr/local/bin/adblock-update.sh"
AUTO_UPDATE_SCRIPT="/usr/local/bin/adblock-auto-update.sh"

install_package() {
 if ! opkg list-installed | grep -q "^${FILTERING_PACKAGE}$"; then
    opkg update
    opkg install "${FILTERING_PACKAGE}"
 fi
}

enable_service() {
 if ! /etc/init.d/"${FILTERING_PACKAGE}" enabled; then
    /etc/init.d/"${FILTERING_PACKAGE}" enable 
 fi
}

configure_package() {
 uci set "${FILTERING_PACKAGE}".config.auto_update=0
 uci set "${FILTERING_PACKAGE}".config.block_malware=0
 uci set "${FILTERING_PACKAGE}".config.block_iploggers=0
 uci set "${FILTERING_PACKAGE}".config.enable_adblock=0
 uci commit "${FILTERING_PACKAGE}"
}

create_update_script() {
 cat > "${UPDATE_SCRIPT}" << EOF
#!/bin/sh
URL="https://raw.githubusercontent.com/AdguardTeam/AdguardFilters/master/Filters/filter.txt"
MALWARE_URLS="https://raw.githubusercontent.com/DandelionSprout/adfilt/master/Alternate%20versions%20Anti-Malware%20List/AntiMalwareAdGuardHome.txt https://raw.githubusercontent.com/AdguardTeam/FiltersRegistry/master/filters/ThirdParty/filter_255_Phishing_URL_Blocklist/filter.txt https://raw.githubusercontent.com/AdguardTeam/FiltersRegistry/master/filters/ThirdParty/filter_256_Scam_Blocklist/filter.txt"
IPLOGGER_URL="https://raw.githubusercontent.com/Konnor88/anti-grabify/master/url_list.txt"
FILE="/etc/adblock/adblock.conf"
. /etc/uci-defaults/40-adblock
update_filter() {
 if [ "\$(uci get ${FILTERING_PACKAGE}.config.auto_update)" = "1" ]; then
    wget -O /tmp/filter.txt "\$URL"
    sed -i '/^!/d' "\$FILE"
    cat /tmp/filter.txt >> "\$FILE"
    if [ "\$(uci get ${FILTERING_PACKAGE}.config.block_malware)" = "1" ]; then
      for url in \$MALWARE_URLS; do
        wget -O - "\$url" >> "\$FILE"
      done
    fi
    if [ "\$(uci get ${FILTERING_PACKAGE}.config.block_iploggers)" = "1" ]; then
      wget -O - "\$IPLOGGER_URL" >> "\$FILE"
    fi
 fi
}
restart_service() {
 /etc/init.d/${FILTERING_PACKAGE} restart
}
update_filter
restart_service
EOF
 chmod +x "${UPDATE_SCRIPT}"
}

create_auto_update_script() {
 cat > "${AUTO_UPDATE_SCRIPT}" << EOF
#!/bin/sh
if [ "\$(uci get ${FILTERING_PACKAGE}.config.auto_update)" = "1" ]; then
    (crontab -l 2>/dev/null; echo "0 0 */5 * * /usr/local/bin/adblock-update.sh") | crontab -
else
    (crontab -l | grep -v '/usr/local/bin/adblock-update.sh' || true) | crontab -
fi
EOF
 chmod +x "${AUTO_UPDATE_SCRIPT}"
}

create_luci_interface() {
 cat > "/usr/lib/lua/luci/controller/network_filtering.lua" << EOF
module("luci.controller.network_filtering", package.seeall)
function index()
 entry({"admin", "network", "network_filtering"}, cbi("network_filtering"), _("Network filtering"))  
end
EOF

 cat > "/usr/lib/lua/luci/view/network_filtering/cbi.lua" << EOF
require "luci.util"
m = Map("adblock", translate("Network filtering"))
s = m:section(TypedSection, "adblock")
s.anonymous = true
btn = s:option(Button, "update", translate("Update"))
btn.inputtitle = translate("Update")
btn.inputstyle = "apply"
btn.write = function()
 luci.sys.call("/usr/local/bin/adblock-update.sh")
 luci.http.redirect(luci.dispatcher.build_url("admin", "network", "network_filtering"))
end
auto_update = s:option(Flag, "auto_update", translate("Auto Update"))
auto_update.default = 0
block_malware = s:option(Flag, "block_malware", translate("Block Malicious Websites"))
block_malware.default = 0
block_iploggers = s:option(Flag, "block_iploggers", translate("Block IP Loggers"))
block_iploggers.default = 0
enable_adblock = s:option(Flag, "enable_adblock", translate("Enable AdBlocking"))
enable_adblock.default = 0
return m
EOF
}

install_package
enable_service  
configure_package
create_update_script
create_auto_update_script

/etc/init.d/luci-module load network_filtering
/etc/init.d/luci-mod-admin restart

echo "Installation complete. Please configure the Network filtering settings through the LuCI web interface."
echo "This script is one-time use for installation. Manual updates can be performed through the GUI."

rm -- "$0"

exit 0

Uninstall script

#!/bin/sh

FILTERING_PACKAGE="adblock"
UPDATE_SCRIPT="/usr/local/bin/adblock-update.sh"
AUTO_UPDATE_SCRIPT="/usr/local/bin/adblock-auto-update.sh"

uninstall_package() {
 if opkg list-installed | grep -q "^${FILTERING_PACKAGE}$"; then
    opkg remove "${FILTERING_PACKAGE}"
 fi
}

disable_service() {
 if /etc/init.d/"${FILTERING_PACKAGE}" enabled; then
    /etc/init.d/"${FILTERING_PACKAGE}" disable 
 fi
}

remove_update_script() {
 if [ -f "${UPDATE_SCRIPT}" ]; then
    rm "${UPDATE_SCRIPT}"
 fi
}

remove_auto_update_script() {
 if [ -f "${AUTO_UPDATE_SCRIPT}" ]; then
    rm "${AUTO_UPDATE_SCRIPT}"
 fi
}

remove_luci_interface() {
 rm -f "/usr/lib/lua/luci/controller/network_filtering.lua"
 rm -f "/usr/lib/lua/luci/view/network_filtering/cbi.lua"
}

remove_cron_jobs() {
 crontab -l | grep -v '/usr/local/bin/adblock-update.sh' | crontab -
}

echo "Starting Network Filtering uninstallation..."

uninstall_package
disable_service
remove_update_script
remove_auto_update_script
remove_luci_interface
remove_cron_jobs

echo "Uninstallation complete. Network Filtering has been removed."

rm -- "$0"

exit 0
1 Like

I only looked at the 1st script. A few comments on it:

  • Overall the code looks pretty good.

  • AFAIK the path /usr/local does not exist on OpenWrt by default. So you might want to consider using /usr/bin instead. Or if you want to specifically use /usr/local then you should probably create the directory, otherwise I doubt that your script will work on devices other than your own.

  • Your script is relying on the cron service but that service may or may not be enabled and running. So ideally you should check whether it's running and if not then handle that situation. You can see how I'm handling this in geoip-shell:

https://github.com/friendly-bits/geoip-shell/blob/main/lib/geoip-shell-lib-common.sh

line 773 - check_cron_compat(), line 752 - check_cron()
(note that geoip-shell works on any Linux device, so the code is not specifically tailored for OpenWrt, but it works on OpenWrt)

  • Current OpenWrt release deprecates lua-based LuCi. Developers are expected to use js instead. I think (?) lua-based plugins will still work if required lua packages are installed. So your script should probably check for these packages and handle situation where they are not installed.