# README
#+TITLE: blocker - Domain blocker plugin for CoreDNS
=blocker= is a CoreDNS plugin which can be used to block a list of domains provided in the =/etc/hosts= file format. The blocklist will be loaded into memory at start-up and the file's modified time will be checked periodically. When the blocklist file is updated, the in-memory blocklist will be updated by scanning the blocklist file.
Updating the blocklist file is beyond the scope of this plugin. I recommend a bash script which downloads [[https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts][common]] [[http://hosts.oisd.nl/][blocklists]] and updates them into a format without comments. The script [[file:blocklist-file-preparer.sh]] included with this repository is an example of how this can be done using bash and GNU utils.
Example blocklist file: ([[https://github.com/AdguardTeam/AdGuardHome/wiki/Hosts-Blocklists#adblock-style][AdBlock Plus syntax]])
#+begin_src text ||buyer.revsci.net^ ||ww92.impfr.tradedoubler.com^ ||next.chartboost.com^ ||pl16442154.alternativecpmgate.com^ ||denturesauaid.com^ ||pdx-p-con-336.saas.appdynamics.com^ ||cdn.ad.citynews.it^ ||xxxxxxxamob.acs86.com^ ||www.globalhotsale.su^ ||zipuploads.com^ #+end_src
- Usage
** CoreDNS Binary
You can include blocker in your CoreDNS just as you would include any other CoreDNS plugin.
#+begin_src sh
Clone coredns to a local location
$ git clone [email protected]:coredns/coredns.git ~/dns-server/coredns
Clone blocker plugin to a close location
$ git clone [email protected]:icyflame/blocker.git ~/dns-server/blocker
Symlink blocker location into coredns/plugin/blocker
$ cd ~/dns-server/coredns/plugin $ ln -s ../blocker ./blocker
Update plugin.cfg and put the line "blocker:blocker" before the "forward:forward" line
Build CoreDNS
$ cd ~/dns-server/coredns $ go generate $ make $ ./coredns -conf Corefile #+end_src
** Corefile
The =blocker= directive inside Corefile requires two arguments. The first argument is the absolute path to the blocklist file. The second argument is the frequency at which the blocklist file is checked for updates.
The frequency is specified as a string and the value should be a valid argument to the [[https://pkg.go.dev/time#ParseDuration][time.ParseDuration]] function.
#+begin_src conf blocker /home/user/blocklist_file 1h abp #+end_src
This is a sample Corefile including the =blocker= directive. It will block domains that are specified in the blocklist and forward everything else to a full DNS server.
#+begin_src conf .:53 { metadata
# prometheus records metrics regarding incoming requests
prometheus
# log writes 1 line to the log for every DNS request
# The last word in the log line will be YES if the request was blocked and NO if it was not
# blocked.
# This behaviour is supported by the metadata plugin.
log . "{common} {/blocker/request-blocked}"
# blocker blocks domains which are specified in the blocklist
blocker /home/user/blocklist_file 1h hosts
# forward handles any request that is not blocked by blocker
forward . 127.0.0.1:9053
} #+end_src
** plugin.cfg
This is a sample middleware configuration file. The order of plugins here is important. This is the order in which plugins will be executed for incoming requests.
#+begin_src conf metadata:metadata prometheus:metrics log:log blocker:blocker forward:forward #+end_src
- Interaction with Other CoreDNS Plugins
** =metadata=
The blocker plugin will write the metadata value with the label =blocker/request-blocked=. This is a boolean value whose value will be either =YES= (if the request was blocked and the empty IP address was returned as a result to the user) and =NO= when the request was not blocked.