Creating Mastodon account identity aliases with Apache

  • By nygren
  • Sat 26 November 2022

Update 2022-11-30: added a RewriteMap to unescape URI-encoding, per @jered@convivian.com's comment and added a pointer to webfinger.net.

Update 2022-12-16: fixed a syntax error for host-meta XML and added in the proper content-type

I've long operated email forwarding (eg, of the form "username@personaldomain.example") which forwards on to my actual email service. This means I can switch backend email service providers without needing to tell everyone my new address. While Mastodon is federated and allows migrating accounts and followers between servers (as long as the server you are migrating from is still available), it wasn't immediately obvious how to setup a stable "identity" on my own domain without running my own server. (While I considered running one, I really don't want to have to be the SRE for yet another personal service, and hence joined the well-operated Hachyderm server.)

It is possible, as described below to, easily setup forwarding of a fediverse account name from a personal domain/server to a third-party operated fediverse (eg, Mastodon) server.

While this allows for discovery (eg, you can put "@username@personaldomain.example" into a Mastodon search field to find your account), this is still just a redirection. Followers and posts are still associated with the underlying Mastodon server.

Finger pointing at a mastodon and the world in space

Background

Mastodon and other "fediverse" services provide federated social networking and microblogging built on top of the ActivityPub and WebFinger and HTTP protocols. While many people have been used to centralized social network services such as Twitter and Facebook, the fediverse is much closer to email and websites which have always been federated (even if there are popular big operators).

Naming in the fediverse leverages the DNS (Domain Name System), again the same as email and websites. The security model also relies on PKIX (the Public Key infrastructure underlying HTTPS where Certificate Authorities validate ownership over DNS names and sign keyparts used to authenticate TLS connections).

Mastodon/fediverse/ActivityPub/WebFinger use "acct:" scheme URIs to name accounts. The WebFinger protocol (RFC 7033) is used to map from an acct: URI to the various ActivityPub service endpoints by making an HTTPS request to a well-known URI.

Warnings/Caveats

One warning before we start: this breaks the abstraction barrier of the target server you are forwarding to. They usually return the WebFinger configuration listing their endpoints, and by copying and modifying them it means things could break if the target server adds new endpoints or needs to change its URIs.

The forwarding also only works initially and subsequent interactions are with the target server. This could be confusing for users, especially if the username changes substantially.

At the same time, you can add additional WebFinger information in if you wanted to, such as phone numbers or similar. I'm curious what real use-cases for this might be.

WebFinger forwarding with Apache

The easiest way to setup WebFinger forwarding is to use mod_rewrite. If it's not enabled:

a2enmod rewrite

Then in the VirtualHost stanza for the Apache2 configuration for your domain include:

   RewriteEngine on
   RewriteMap unescape int:unescape
   RewriteCond ${unescape:%{QUERY_STRING}} ^(rel=[^&]*&)*resource=acct:([a-z0-9-]+)@example.org(&rel=[^&]*)*$
   RewriteRule ^/.well-known/webfinger$ /.well-known/_webfinger/%2.json [L,QSD]

   <Location "/.well-known/host-meta">
      ForceType application/xrd+xml
   </Location>

Replace "example.org" with your personal domain name (eg, "personaldomain.example"). This says to rewrite URLs of the form "https://example.org/.well-known/webfinger?resource=acct:username@example.org" to instead serve files from "/.well-known/_webfinger/username". (It also ignores any rel= query string attributes, per the RFC.)

Note: the RewriteMap to unescape URI-encoding is needed for some clients. Thanks to @jered@convivian.com for pointing this out.

Next, create a file in /.well-known/_webfinger/username.json (replacing "username" with yours) containing:

{
   "aliases" : [
      "https://mastodon-server.example/@username",
      "https://mastodon-server.example/users/username",
      "acct:username@mastodon-server.example"
   ],
   "links" : [
      {
         "href" : "https://mastodon-server.example/@username",
         "rel" : "http://webfinger.net/rel/profile-page",
         "type" : "text/html"
      },
      {
         "href" : "https://mastodon-server.example/users/username",
         "rel" : "self",
         "type" : "application/activity+json"
      },
      {
         "rel" : "http://ostatus.org/schema/1.0/subscribe",
         "template" : "https://mastodon-server.example/authorize_interaction?uri={uri}"
      }
   ],
   "subject" : "acct:username@personaldomain.example"
}

In that, replace "mastodon-server.example" with the URL of your mastodon server, "username" with your username, and "username@personaldomain.example" with your full vanity domain account thatyou want to redirect over.

Note that the above corresponds to at least one Mastodon 4.0 server. You may need to periodically update this to match the configuration for your mastodon server. For example, fetch with:

curl https://mastodon-server.example/.well-known/webfinger?resource=acct:username@mastodon-server.example | json_pp

and start with that instead.

Purely optional: If you want, you can add additional link relations with additional metadata under "links". See here for a registry with other link relations.

You may also need to add a file /.well-known/host-meta with a URI template for some webfinger clients to use, also replacing "personaldomain.example" with your domain name:

<?xml version="1.0" encoding="UTF-8"?>
<XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0">
  <Link rel="lrdd" template="https://personaldomain.example/.well-known/webfinger?resource={uri}" type="application/xrd+xml" />
</XRD>

Once these are in-place, reload your apache configuration (eg, "apache2ctl graceful") and then test:

curl 'https://personaldomain.example/.well-known/webfinger?resource=acct:username@personaldomain.example'

which should return the json document.

You can also test by entering in your account name at webfinger.net.

You should be able to then follow "@username@personaldomain.example" into a search box in a Mastodon client would then bring up "@username@mastodon-server.example".

As an example, "@erik@nygren.org" is setup this way and points to "@nygren@hachyderm.io".

Other Implementations

Some other implementations that may be helpful:

Acknowledgements

Some useful posts which pointed me in the right direction: