One of the popular uses of Dnsmasq is for blocking ads and malware at the network level. By configuring Dnsmasq to act as a lightweight ad blocker, it can block access to known ad-serving domains and malicious websites, preventing ads and potential threats from reaching your devices.
In this article, I will show you how to configure Dnsmasq to act as ads and malware blocker to protect the whole network provided by the raspberry pi
You can refer to this article if you need help setting up raspberry pi as an Access Point:
In addition, a fully automated script is created to be used with crontab to ensure the block lists are always up-to-date.
Dnsmasq configuration
DNS blocking works by intercepting DNS queries for specific domain names and preventing them from resolving to their intended IP addresses. Instead, the DNS blocking mechanism redirects the queries to a different IP address, usually an IP associated with a null address.
The config file is normally located at /etc/dnsmasq.conf . I am going to add a line to point to our block list by appending the following to the config file:
conf-file=/opt/block-lists/final.list
This will instruct Dnsmasq to load an external config file which is /opt/block-lists/blocklist.list.
This will be our block list and it should have a very specific format.
Config file syntax
In order for Dnsmsaq to work correctly, it's essential to have a specific file format.
For example, if you need to block zzmalwo.pl domain, we have to make sure the domain will not be resolved to the intended IP address. Resolving this to anything else will prevent zzmalwo.pl from reaching the official server.
The syntax will look like:
address=/zzmalwo.pl/#
This will resolve zzmalwo.pl to # which is actually a null value, causing it to be effectively blocked.
Idea behind the script
The script will fetch the block lists from multiple sources in different formats and using regular expression they will be converted to a Dnsmasq syntax files. Eventually, they will be combined together and duplicates will be removed to keep the best performance.
Overview of the features:
- Auto update the block lists using crontab
- Update the block lists based on a pre-defined variable (see script usage section for more informations)
- Enable/disable categories easily
- Enable/disabled sources inside the category
- Reduced write operations to increase disk/SD card lifespane
- To enhance availability and mitigate potential failures with the newly generated block list, the system will automatically revert to the old block list in the event of any issues
- Send alerts using telegram in case of failures
Script usage
You can find all variables in the variables.conf file.
- BLOCK_LIST_DIR_PATH is where the lists will be saved. This includes the original source, the Dnsmasq format of the sources and a final list for each category. Each category will have two directories like:
├── dnsmasq
│ ├── AdguardDNS.txt-686383571809957389084160079794
│ ├── Admiral.txt-359420893045275572093702155731
│ ├── ADS.final
└── original
├── AdguardDNS.txt-587929608660802231040210542967
├── Admiral.txt-771924596289503074944790087620
As you see, the AdguardDNS.txt-686383571809957389084160079794 is the Dnsmasq syntax of AdguardDNS.txt-587929608660802231040210542967
- TMP_BLOCK_LIST_DIR_PATH specifies the temporary storage location for the block list before it is applied. For optimal performance on Raspberry Pi, it is highly recommended to set this variable to a tmpfs location. By utilizing a tmpfs location, the block list operations can benefit from the faster read and write speeds of the RAM, resulting in improved overall performance when applying the block list.
- TELEGRAM_BOT_ENABLED is utilized to enable notification functionality. When enabled, the script can send an alert if Dnsmasq encounters an issue after updating the block list. However, to enable this feature, you must ensure that the BOT_TOKEN and BOT_CHAT_ID are correctly set. Please make sure to set them accurately to ensure the successful operation of the notification system.
- UPDATE_INTERVAL is used to prevent the list from being downloaded on every script run. The recommended usage is to set this variable to 24 (which equals 24 hours) and execute the script with crontab every 3 minutes. By doing so, any modifications made to the variables.conf file will take effect after 3 minutes without requiring the sources to be downloaded again.If you enable or disable sources, the script will continue using the sources from the dnsmasq directory without downloading the original source again until the UPDATE_INTERVAL is passed. To force an update of the lists on every run, you can set the UPDATE_INTERVAL variable to zero.
- FINAL_BLOCKLIST_PATH is the definitive blocklist intended for use by dnsmasq. This list comprises a merged collection of all active blocklists, ensuring there are no duplicate entries. If your dnsmasq configuration specifies conf-file=/opt/block-lists/blocklist.list, then the FINAL_BLOCKLIST_PATH variable should be set to /opt/block-lists/blocklist.list.
Note: the more sources you add, the more execution time is required. It's highly recommended to set the crontab value to meet your requirements.
Configure blocking categories
By default, I have included recommended lists and categories.
Taking an example of a block list category:
ADS_LISTS=(
"https://adaway.org/hosts.txt"
"https://v.firebog.net/hosts/AdguardDNS.txt"
)
When the script is executed, the lists are downloaded from these resources, transformed to dnsmasq format then used by dnsmasq. The script will take care of all the required configurations.
In case you need to disable one of them, you can comment out the line with the hashtag (#) character, like:
ADS_LISTS=(
"https://adaway.org/hosts.txt"
# "https://v.firebog.net/hosts/AdguardDNS.txt"
)
This will disable the second source. The script will not reconfigure everything from scratch, instead it will just ignore this source and update the FINAL_BLOCKLIST_PATH to meet the requirements.
You can even disable the whole category like:
#ADS_LISTS=(
# "https://adaway.org/hosts.txt"
# "https://v.firebog.net/hosts/AdguardDNS.txt"
#)
The script will set the ADS category to a disabled status and update the FINAL_BLOCKLIST_PATH.
Configure a new category
Adding a new category is simple. You can just define a new list in the variables.conf file like:
TEST_LIST=(
"first source"
"second source"
)
Then call the configure_category function inside the script:
configure_category "${TEST_LIST[@]}" "TEST"
This will add a new category called TEST with sources defined in the TEST_LIST.
Note: The sources should be a raw list URL or text file ready to be downloaded like:
https://raw.githubusercontent.com/anudeepND/blacklist/master/adservers.txt
https://v.firebog.net/hosts/AdguardDNS.txt
Run the script with Crontab
To run the script every 3 minutes, you can execute crontab -e and add the following:
*/3 * * * * $HOME/dns-shield/dns-shield.sh &> /dev/null
You can redirect the output of the script to any log file you need if required.
In conclusion, the use of dnsmasq in combination with regularly updated and reputable blocklists can significantly reduce the risk of users inadvertently accessing harmful websites and being exposed to malware threats. It can also complement other security measures like antivirus software and firewalls to provide a multi-layered defense against cyberattacks.