Integration guide

Use an IP blocklist on pfSense and OPNsense

Both pfSense and OPNsense can fetch a plain list of addresses from a URL on a schedule and keep it in a pf table: a URL Table alias. That is the right mechanism here: no scripts on the firewall, no packages, and the table is updated by the firewall itself.

The one thing to plan for is authentication. A URL-table alias fetches a URL and cannot attach an Authorization header, so the feed URL has to carry the key as a query parameter:

https://api.sciscope.ee/v1/feeds/blocklist.txt?key=YOUR_KEY

That works, and it is why the API accepts ?key= at all. Read where the key ends up below before you paste it, because it does end up in more places than you might expect.

pfSense

1. Firewall → Aliases → URLs → Add. 2. Name: SciScope_Blocklist (no spaces or hyphens; pfSense uses the name as a table name). 3. Type: URL Table (IPs). 4. URL: the feed URL above, with your key. 5. Update frequency: 1 day is the minimum the interface offers, and it is enough. The feed rebuilds hourly, but for a blocking table a daily refresh of a list whose whole purpose is persistent hostile infrastructure is a reasonable trade. If you want it hourly, fetch it with cron on another host and serve the file internally, then point the alias at that. 6. Save, then Apply changes. 7. Firewall → Rules → WAN → Add, at the very top: Action Block, Interface WAN, Address Family IPv4, Protocol any, SourceSingle host or aliasSciScope_Blocklist, Destination any. Tick Log while you are evaluating it. 8. Save and Apply changes.

Verify that the table actually populated: Diagnostics → Tables, pick SciScope_Blocklist, and check the entry count. An empty table means the fetch failed; the usual cause is a wrong or expired key, and Status → System Logs → General will show it.

OPNsense

1. Firewall → Aliases → Add. 2. Type: URL Table (IPs). 3. Name: SciScope_Blocklist. 4. Content: the feed URL with your key. 5. Refresh Frequency: set the days field to 1 (OPNsense also exposes hours; 0 days and 1 hour matches the feed's rebuild cadence exactly, and stays well inside the Entry rate limit). 6. Save, then Apply. 7. Firewall → Rules → WAN → Add: Action Block, direction in, Source SciScope_Blocklist, destination any. Move it to the top of the list. 8. Apply.

Check it under Firewall → Diagnostics → Aliases, which shows the resolved contents and the entry count.

Where the key ends up

A key in a URL is a key in a lot of places, and on a firewall specifically:

None of that is catastrophic, since the key reads a feed, cannot change anything, and costs one email to rotate. But treat the config backups of a firewall carrying a ?key= URL as secrets, and rotate the key if a backup goes anywhere you would not send a password. Mail hello@sciscope.ee and a replacement is issued immediately.

If your security posture does not allow a key in a URL at all, the alternative is the cron-and-serve pattern: a small internal host fetches the list hourly with a proper Authorization header (see the nftables guide for the script) and publishes the resulting file on the LAN over plain HTTP. The alias then points at an internal URL with no credential in it.

Sizing and limits

pf tables hold hundreds of thousands of entries without complaint, and the feed is far smaller than that. On a firewall with a small pf table limit (some appliance builds ship conservative values) raise System → Advanced → Firewall & NAT → Firewall Maximum Table Entries above the size of all your tables combined, or the load silently truncates.

Do not put this alias in a floating rule with quick disabled and expect it to win against a permissive rule above it. Rule order decides everything; the block rule belongs at the top of the WAN inbound list.

Or let the feed do it for you

Keeping these lists current is exactly the work the SciScope Scanner Feed takes off your hands: every crawler above is screened out of the feed continuously, and the opt-in crawler-identity list tells you which of them you are looking at.

How the feed works or request a trial