Sharing an X11 Server Across Hosts with FamilyWild

Aug 03, 2026 03:26 AM - 2 hours ago 1

2026-08-02

Ever tried moving an X11 exertion from wrong a container, a chroot, aliases over ssh pinch a bind-mounted .Xauthority — only to beryllium greeted by the ever-helpful Authorization required, but nary authorization protocol specified?

The record is correct there, mounted read-only wherever the customer expects it, and yet X refuses the connection. The logic is subtle, and the hole is simply a azygous statement of sed.


Why the cooky is rejected

An .Xauthority record is simply a database of cookies, and each introduction is keyed by a family and a hostname. When a customer connects, it doesn't conscionable drawback the first cooky it finds — it looks for the introduction whose hostname matches the machine the customer believes it's moving on.

That's precisely what breaks the infinitesimal the customer runs location different than where the cooky was minted. Inside a instrumentality the hostname is different; complete an un-forwarded socket the customer resolves a different sanction entirely. The cooky is present and valid, but its hostname doesn't match, truthful the customer ne'er offers it and X falls backmost to "no authorization protocol."

You tin spot the family/hostname keying for yourself:

$ xauth list myhost/unix:0 MIT-MAGIC-COOKIE-1 a1b2c3d4e5f6...

That starring myhost/unix:0 is the problem — it pins the cooky to myhost.


FamilyWild to the rescue

X has a wildcard family, FamilyWild, whose numeric worth is 0xffff. A cookie in this family matches any hostname. So alternatively of trying to make the client's hostname lucifer the cookie, we rewrite the cooky to lucifer each host.

xauth nlist prints entries successful a numeric format wherever the first section is the 4-hex-digit family. Overwrite it pinch ffff and merge the consequence into a fresh file:

: > /tmp/portable.Xauthority && xauth nlist :0 | \ sed 's/^..../ffff/' | xauth -f /tmp/portable.Xauthority nmerge - # Replace :0 pinch your $DISPLAY value

The alteration is simply a azygous field

It's worthy seeing conscionable really mini the edit is. An .Xauthority introduction is simply a packed binary record: a 2-byte family, past length-prefixed address, show number, auth name, and the cooky itself. Dump the original record and the family sits in the very first 2 bytes — 0100, i.e. FamilyLocal:

00000000: 0100 0006 6d79 686f 7374 0001 3000 124d ....myhost..0..M 00000010: 4954 2d4d 4147 4943 2d43 4f4f 4b49 452d IT-MAGIC-COOKIE- 00000020: 3100 10a1 b2c3 d4e5 f607 1829 3a4b 5c6d 1..........):K\m 00000030: 7e8f 90 ~..

Now dump the FamilyWild type we conscionable built. Everything is byte-for-byte identical — aforesaid myhost address, aforesaid cooky — isolated from those first 2 bytes, now flipped to ffff:

00000000: ffff 0006 6d79 686f 7374 0001 3000 124d ....myhost..0..M 00000010: 4954 2d4d 4147 4943 2d43 4f4f 4b49 452d IT-MAGIC-COOKIE- 00000020: 3100 10a1 b2c3 d4e5 f607 1829 3a4b 5c6d 1..........):K\m 00000030: 7e8f 90 ~..

That 1 section is the full trick: the reside bytes still spell myhost, but X no longer cares, because family 0xffff matches unconditionally.

Bind-mount (or scp) /tmp/portable.Xauthority wherever the customer runs, point XAUTHORITY astatine it, and the relationship is accepted sloppy of the hostname mismatch.


What astir xhost +?

You'll often spot xhost + suggested arsenic the "just make it work" answer, and it does — by turning host-based entree power disconnected entirely. Every customer from every big tin past link to your show without immoderate cooky astatine all.

On a single-user instrumentality that sounds harmless, but X has nary isolation between clients: anyone who tin scope the server tin publication your keystrokes, drawback the contents of immoderate window, and inject synthetic input. xhost + hands that capability to each section personification and, if your server listens connected TCP, to the network. Even the narrower xhost +local: still trusts each UID connected the box.

The FamilyWild cooky keeps the doorway locked — a customer still has to present the secret — while removing only the hostname constraint that was getting successful the way. Reach for it alternatively of xhost +, and support the cooky record astatine 0600.


One caveat

A FamilyWild cooky is deliberately little circumstantial than the 1 it replaces: anyone who tin some scope your X socket and publication this record tin talk to your display. Hand it only to the environments that really request it, and don't leave copies lying astir connected shared machines.

This instrumentality is 1 mini portion of a larger setup — I usage it to guardant X into unprivileged LXC containers, which I wrote up successful item in Enhancing x11 Application Security pinch LXC.

More