Setup guide
MikroTik adlist blocklist of malicious domains, fetched with your API key
No credit card required · Free API key
On this page08
What you get
A DNS adlist takes plain domain files and keeps every name in the DNS cache, about 75 bytes each. The category lists below fit a router; the 2 million critical domains do not.
| List | Entries | Rebuilt | Plans |
|---|---|---|---|
| blocklist-domains-c2.txtDefault adlist: command-and-control domains reported by C2 trackers. | about 22,000 | every 12 h | Basic, Pro, and Enterprise |
| blocklist-domains-ransomware.txtDomains in the ransomware category, whatever their level. | about 3,600 | every 12 h | Basic, Pro, and Enterprise |
| blocklist-domains-cryptomining.txtDomains in the cryptomining category, whatever their level. | about 6,100 | every 12 h | Basic, Pro, and Enterprise |
Entries rounded from the build of ; each list is rebuilt every 12 hours. Today’s counts are public and need no key.
What each plan receives
- FreeFree account, or no key: the first 10% of each list, marked
X-Blocklist-Version: lite. - Basic, Pro, and EnterpriseBasic, Pro, and Enterprise: every list in full.
- Pro and EnterpriseTAXII 2.1 collections, for platforms that read STIX indicators: Pro and Enterprise.
GET https:/
Full list or 10% sample
| Field | Basic, Pro, and Enterprise | Free |
|---|---|---|
X-Blocklist-Version: | full | lite |
X-Blocklist-Percentage: | 100 | 10 |
Total entries: | <COUNT> | <COUNT> |
First lines of the file
# IsMalicious.com Blocklist - Domains (All Levels)
# Format: Plain
# Generated: <BUILD_TIME>
# Total entries: <COUNT>
# Update frequency: every 12 hours
# Category: C2
# Threat level: All Levels
# Website: https://ismalicious.com
# © <YEAR> IsMalicious (compilation). Licensed to the downloading account under https://ismalicious.com/terms; redistribution of the compilation prohibited. Third-party entries remain under their providers' licences — see https://ismalicious.com/sources.
# Filtered by category: c2
#Values in angle brackets are set by each build.
Prerequisites
- RouterOS 7.16 or later: DNS adlists arrived in 7.15, and 7.16 fixed how fetch handles a 401.
- Fetch and the scheduler allowed by the device mode: home routers that ship with RouterOS 7.17 or later come in home mode, which turns both off (step 2).
- The router’s clock set by NTP: certificate checks compare the certificate dates with it.
- An isMalicious API key and secret, from Account › API access.
- Outbound HTTPS (TCP 443) over IPv4 from MikroTik to
api.ismalicious.com, which has no IPv6 address.
Set it up
Copy your API key and secret
Open Account › API access and copy the API Key and the API Secret. The full list needs a Basic, Pro, or Enterprise plan; a Free key, or a lapsed plan, loads the 10% sample.Allow fetch and the scheduler
Check the device mode with/system/device-mode/print. If fetch or scheduler isno, run/, then press the reset or mode button, or unplug the power, within 5 minutes: the router applies the change only after that confirmation.system/ device-mode/ update fetch= yes scheduler= yes Device mode (home routers, 7. 17+)RouterOS # Home routers that ship with RouterOS 7.17 or later come in home mode, # which turns off fetch and the scheduler. Check: /system/device-mode/print # If fetch or scheduler shows no: /system/device-mode/update fetch=yes scheduler=yes # then press the reset or mode button, or unplug the power, within 5 minutes.Trust the Let’s Encrypt roots
RouterOS 7.19 and later have a built-in trust store that fetch uses. Run the manual fetch under Verify first: if it ends withstatus: finished, skip this step; if it fails withno, import both roots, then compare their fingerprints with the values below, since that first download cannot be verified. That is always needed on 7.15 to 7.18, and on hAP lite, hAP lite TC and hAP mini before 7.23.3.trusted CA certificate found Let’s Encrypt roots, when the trust store lacks themRouterOS # Only when the manual fetch under Verify fails with "no trusted CA certificate found". /tool/fetch url="https://letsencrypt.org/certs/isrgrootx1.pem" dst-path=isrgrootx1.pem /tool/fetch url="https://letsencrypt.org/certs/isrg-root-x2.pem" dst-path=isrg-root-x2.pem /certificate/import file-name=isrgrootx1.pem trusted=yes /certificate/import file-name=isrg-root-x2.pem trusted=yes # The download above cannot be verified yet: compare the SHA-256 fingerprints. /certificate/print detail where common-name~"^ISRG Root X" # ISRG Root X1 96bcec06264976f37460779acf28c5a7cfe8a3c0aae11a8ffcee05c0bddf08c6 # ISRG Root X2 69729b8e15a86efc177a57afb7171dfc64add28c2fca8cf1507e34453ccb1470 # If either differs: /certificate/remove [find common-name~"^ISRG Root X"]Make the router your clients’ resolver
Allow DNS requests to the router and raise the DNS cache, which holds the adlist names: 8 MiB leaves room for the C2 list. Clients must use the router as their resolver: hand it out through DHCP (/the router’s address); a client with its own resolver or DNS over HTTPS bypasses the adlist. Without the default firewall, add the rules below so the router does not answer DNS from the internet.ip/ dhcp-server/ network/ set … dns-server= ResolverRouterOS /ip/dns/set allow-remote-requests=yes cache-size=8192 # Only without the default firewall, which already drops DNS from the WAN. # Put these above any rule that accepts it (place-before): /ip/firewall/filter/add chain=input in-interface-list=WAN protocol=udp dst-port=53 action=drop comment="drop DNS from WAN" /ip/firewall/filter/add chain=input in-interface-list=WAN protocol=tcp dst-port=53 action=drop comment="drop DNS from WAN" /ipv6/firewall/filter/add chain=input in-interface-list=WAN protocol=udp dst-port=53 action=drop comment="drop DNS from WAN" /ipv6/firewall/filter/add chain=input in-interface-list=WAN protocol=tcp dst-port=53 action=drop comment="drop DNS from WAN"Download the list and add the adlist
Fetch the list into a file with the API key asuserand the API secret aspassword, withcheck-certificate=yes, then add the file as an adlist. An adlist URL takes no credentials, which is why the file comes first.First loadRouterOS /tool/fetch url="https://api.ismalicious.com/blocklist/download/blocklist-domains-c2.txt" \ user="<API_KEY>" password="<API_SECRET>" check-certificate=yes \ dst-path=ismalicious-c2.txt /ip/dns/adlist/add file=ismalicious-c2.txtRefresh it on a schedule
- Add the refresh as a script, run at startup and every 6 hours: it downloads the list again, then removes and re-adds the adlist, so the new file is read.
- A failed download (an HTTP error, a timeout, a certificate error) stops the script before it touches the adlist.
- A 200 answer replaces the names whatever it holds, the 10% sample included: check name-count after any plan or key change.
- On a router with a flash folder, write the file under
flash/: elsewhere it sits on a RAM disk and is lost at reboot. - The 90-second delay at startup may be short for a PPPoE or LTE uplink.
Refresh script and scheduleRouterOS /system/script/add name=ismalicious-dns policy=ftp,read,write,test source={ /tool/fetch url="https://api.ismalicious.com/blocklist/download/blocklist-domains-c2.txt" \ user="<API_KEY>" password="<API_SECRET>" check-certificate=yes \ dst-path=ismalicious-c2.txt /ip/dns/adlist/remove [find file="ismalicious-c2.txt"] /ip/dns/adlist/add file=ismalicious-c2.txt } /system/scheduler/add name=ismalicious-dns-boot start-time=startup interval=0s \ policy=ftp,read,write,test on-event=":delay 90s; /system/script/run ismalicious-dns" /system/scheduler/add name=ismalicious-dns-6h start-time=00:20:00 interval=6h \ policy=ftp,read,write,test on-event="/system/script/run ismalicious-dns"
Verify it works
/ip/dns/adlist/printshowsname-count, the names imported, andmatch-count, the queries blocked.name-countmatches the list’scountin /blocklist/stats, give or take one rebuild. About a tenth of it is the 10% sample.- A manual fetch of the list ends with
status: finished. - The
fetchlog topic records each download and its errors.
# Names imported (name-count) and queries blocked (match-count):
/ip/dns/adlist/print
# The download itself, outside the schedule, without keeping a copy:
/tool/fetch url="https://api.ismalicious.com/blocklist/download/blocklist-domains-c2.txt" \
user="<API_KEY>" password="<API_SECRET>" check-certificate=yes \
output=noneTroubleshooting
not allowed by device-mode
The router is in home mode, which turns off fetch and the scheduler. Run the device-mode update of step 2 and confirm it with the reset or mode button, or a power cycle, within 5 minutes.
The fetch fails with a 401
The key or the secret is wrong or incomplete. The script stops and the adlist keeps its names. The response body reads “Blocklist not found or empty”; trust the status code. Copy both values again from Account › API access: regenerating the key there invalidates the old pair.
name-count is about a tenth of the list
No credential reached the server, or the plan is Free or lapsed: past due, unpaid, canceled, incomplete or paused counts as Free. The downloaded file’s Total entries line then says Lite Version.
adlist read: max cache size reached
Raise cache-size, then remove and re-add the adlist: raising it afterwards does not complete the list.
Header lines in the adlist
The adlist ignores lines that start with #, so the header is not loaded. Never give it an -adguard or -dnsmasq file: it reads plain names or hosts lines.
no trusted CA certificate found
Set the clock first. Then import ISRG Root X1 and X2 (step 3): always on 7.15 to 7.18, and on hAP lite, hAP lite TC and hAP mini before 7.23.3. From 7.19, check that fetch still uses the built-in trust store: the setting is builtin-trust-anchors on 7.19 and 7.20, builtin-trust-store from 7.21.
not enough permissions (9)
The script or the scheduler entry lacks a policy: fetch needs ftp and test, and the adlist commands read and write.
403 from ismalicious.com
The ismalicious.com edge refuses some sources. Use api.ismalicious.com.
Limits
- No IP address list loader is published yet. RouterOS cannot load a plain list into an address list without a script that adds each line, and the one we drafted has not been run on a router.
- An adlist blocks the exact names only, not their subdomains, and answers A and AAAA queries only: TXT, MX and HTTPS records still resolve upstream.
- The API secret sits in the script in clear text, and an export prints it: restrict who can read the configuration.
- No CIDR, no
.rscand no other RouterOS format is served: the adlist reads the plain list. - The 10% sample is the first tenth of an unsorted file, not the riskiest tenth.
Questions
Can RouterOS fetch a blocklist with an API key?
Yes. /tool/fetch takes user and password and sends them as HTTP Basic with the first request: the API key is the user, the API secret the password. The DNS adlist itself takes no credentials, so fetch the list into a file and load the file.
Can I load the IP lists into a MikroTik address list?
Not with a published script yet. An address list needs a script that adds each line, and the loader we drafted has not been tested on a router, so this guide covers the DNS adlist only.
Does the adlist block subdomains?
No. A RouterOS adlist blocks the exact names it holds, not their subdomains.
How often should the router refresh the list?
At startup and every 6 hours, as the schedule in this guide does. The lists are rebuilt every 12 hours.
How large should the DNS cache be?
Each adlist name takes about 75 bytes of DNS cache, and the default cache is 2 MiB. The C2 list needs about 1.6 MiB on its own, so the guide raises the cache to 8 MiB.
Related
IP and domain feeds with basic authentication
External Dynamic Lists sized to PAN-OS limits
A URL Table alias or pfBlockerNG feed through a relay
URL Table aliases with Basic authorization
Threat IPs as nftables sets on any Linux host
Keep firewall blocklists current
Every list, level and category
TAXII 2.1 collections for SIEMs and TIPs
Authentication, endpoints and limits
Check one domain before you block it
Get Started
Ready to get started?
No credit card required · Free API key