Split-domain WebFinger
Hollo supports a split-domain WebFinger setup: your fediverse handles
live under one domain (e.g. @alice@example.com) while the actual
ActivityPub server runs under another (e.g. https://ap.example.com).
This is the same pattern Mastodon documents under “hosting WebFinger
at the root domain” and that GoToSocial calls
host-meta-based host swapping.
This is implemented on top of Fedify’s origin configuration option.
Why split the domain?
Section titled “Why split the domain?”The typical reason is that you already own a nice short domain
(example.com) and want your handles to look like
@alice@example.com, but you don’t want to host Hollo at the apex of
that domain — the apex is reserved for a homepage, a different web app,
or an existing service.
In a split-domain setup:
- Users address you as
@alice@example.comeverywhere in the fediverse. - Hollo itself is served from
https://ap.example.com. The web UI, the Mastodon-compatible API, OAuth, and the actor URIs all live there. - The apex domain
example.comonly needs to handle one thing: redirecting/.well-known/webfingerrequests over toap.example.com.
Configuration
Section titled “Configuration”Set both of these environment variables on your Hollo instance:
HANDLE_HOST— the bare hostname used in handles (no scheme, no path), e.g.example.com.WEB_ORIGIN— the scheme + host where Hollo runs, e.g.https://ap.example.com.
Both must be set together; setting only one causes Hollo to refuse to start.
HANDLE_HOST=example.comWEB_ORIGIN=https://ap.example.comWith this in place, Fedify takes care of the rest:
- WebFinger responses use
acct:alice@example.comas the subject. - Actor URIs are built under
https://ap.example.com/@alice. - The Mastodon-compatible
/api/v1/instanceand/api/v2/instanceendpoints reportexample.comas the instance domain, so clients display the correct handle.
Reverse proxy redirect
Section titled “Reverse proxy redirect”Hollo itself only listens on the WEB_ORIGIN host. Remote servers
that look up @alice@example.com will send their WebFinger query to
https://example.com/.well-known/webfinger, so you must configure
that domain’s reverse proxy to redirect those requests to Hollo.
A 301 redirect that preserves the query string is enough. Send
/.well-known/nodeinfo and /.well-known/host-meta along as well,
since some implementations probe those during discovery.
server { listen 443 ssl; server_name example.com; # … your normal site config …
location /.well-known/webfinger { return 301 https://ap.example.com$request_uri; } location /.well-known/nodeinfo { return 301 https://ap.example.com$request_uri; } location /.well-known/host-meta { return 301 https://ap.example.com$request_uri; }}example.com { # … your normal site config …
redir /.well-known/webfinger* https://ap.example.com{uri} permanent redir /.well-known/nodeinfo* https://ap.example.com{uri} permanent redir /.well-known/host-meta* https://ap.example.com{uri} permanent}You do not need to redirect the /@username path or any actor
URLs — those URLs live on ap.example.com and remote servers will go
straight there after resolving the WebFinger response.
Verifying the setup
Section titled “Verifying the setup”After deploying, three quick checks confirm everything is wired up:
-
WebFinger from the handle domain redirects:
curl -i "https://example.com/.well-known/webfinger?resource=acct:alice@example.com"should return a 301 to
https://ap.example.com/.well-known/webfinger?.... -
WebFinger from the server domain responds:
curl "https://ap.example.com/.well-known/webfinger?resource=acct:alice@example.com"should return a JRD whose
subjectisacct:alice@example.comand whoseselflink points athttps://ap.example.com/@alice. -
The instance endpoint reports the handle domain:
curl https://ap.example.com/api/v2/instance | jq .domainshould print
"example.com".
For a more thorough audit, point Julian Fietkau’s WebFinger Canary at your handle domain. Mastodon and Fedify-based servers handle split-domain setups correctly today; Misskey and Pixelfed currently do not.