惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Blog — PlanetScale
Blog — PlanetScale
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Vercel News
Vercel News
B
Blog
腾讯CDC
P
Proofpoint News Feed
Google DeepMind News
Google DeepMind News
N
Netflix TechBlog - Medium
L
LangChain Blog
F
Fortinet All Blogs
T
The Blog of Author Tim Ferriss
人人都是产品经理
人人都是产品经理
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
I
InfoQ
IT之家
IT之家
酷 壳 – CoolShell
酷 壳 – CoolShell
aimingoo的专栏
aimingoo的专栏
D
DataBreaches.Net
Stack Overflow Blog
Stack Overflow Blog
The Cloudflare Blog
Last Week in AI
Last Week in AI
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
博客园 - 三生石上(FineUI控件)
T
Tailwind CSS Blog

alexwlchan’s notes

What is WS11 1DB? How to type a Spanish question mark (¿) on a Mac Non-overlapping type comparisons and Python type checkers Why does t.Setenv panic after t.Parallel? Use Path.glob() and Path.rglob() for typed versions of glob.glob() Curious clocks and colourful eyes Track which templates are used by Jinja2 Archeologists distinguish between “sherds” and “shards” A single command to test all my changed Go packages Disable the new message animations in WhatsApp Finding high-churn folders that bother Backblaze Always-on SSH agent forwarding with my Git pushes Managing the caption of a photo with AppleScript (but not PhotoKit) Goodhart’s and Campbell’s Law are different Notes from The Cornishman No. 176 (Spring 2026) Notes from The Cornishman No. 176 (Spring 2026) GitUp can’t diff text files larger than 8MB Home Testing the width of a page on a mobile device using Playwright Disable AirPods charging notifications Start a Caddy server in a subprocess during a Python session Filter a list of JSON object based on a list of tags HOME_GET_ME_HOME is a Citymapper Shortcuts action The FileExistsError exception exposes a filename attribute The red-lined bubble snail Why can’t Python connect to example.com? Useful type hints for Python How to truncate the middle of long command output AirPlay Receiver can interfere with Flask apps What’s the main prefix in SQLite queries?
Blocking referrers with Caddy
2026-09-03 · via alexwlchan’s notes

Create a matcher on the Referer header, followed by a hard-coded respond directive.

Every so often, somebody tells me that I’ve hit the front page of Hacker News. They always imagine I’ll be excited, but it just fills me with a sense of dread. Orange site commenters are a stain on my inbox: arrogant, rude, and condescending. I also get misgendered on the regular, a combination of ignorance and transphobia. Fun!

I’ve finally done what I should have done years ago: block all requests from Hacker News.

The block works by looking for news.ycombinator.com in the Referer header. This is trivial to circumvent, but most commenters will give up if a page doesn’t load on the first click. Even if some find their way to the site, it’ll tank the number of upvotes and minimise the number of readers who see the link.

Everybody wins: Hacker News commenters don’t have to read posts which are so obviously beneath them, and I don’t have to deal with their bile.

How it works

This is straightforward with my web server, which is Caddy. I define a request matcher which checks the Referer header, then use a respond directive to send a hard-coded error:

alexwlchan.net {
	@hacker_news {
		header Referer *ycombinator.com*
	}
	respond @hacker_news "Forbidden" 403

	root * /home/alexwlchan/sites/alexwlchan.net/_out
	file_server
}

Initially I used Caddy’s abort directive, which terminates the entire connection, but that made it a bit too easy to evade the block. If the server drops the connection and the browser reloads, the browser discards the previous value of the Referer header and gets a successful response. But if the server returns an error response and the browser reloads, it sends the same request and gets the same error.