Skip to content

Docs

Run it on your own infrastructure.

Nothing about Nex requires our servers. A mailbox is a queue that holds sealed bytes for a bounded time; running your own is a supported configuration, not a workaround.

Three services, deliberately separate

Mailbox

Sealed ciphertext, at most fourteen days, deleted on acknowledgement. Plus directory labels, if you enable them.

Store-and-forward for the case where the other device is offline. It holds payloads it cannot read, one queue per recipient device, and deletes an item when the recipient acknowledges it rather than when they fetch it — so a client that crashes mid-download does not lose mail. It can also publish an opt-in directory of user-chosen labels; that is off by default and is the only thing it stores that is not ciphertext.

Rendezvous

Nothing durable. Address hints in memory, at most two minutes.

How two devices find each other. It is the more sensitive of the two services despite holding less, because lookups reveal who is interested in whom. Keep it a separate process; that separation is what makes "holds nothing" verifiable.

Packet relay

Packets in flight only.

When two devices cannot reach each other directly, this carries their encrypted packets without being able to open them. It is a standard component run on its own hostname and port.

Configuration contract

These names are fixed. A deployment that changes them is not the same deployment the service units and proxy configuration were written for.

Read by the mailbox environment or the rendezvous command line at start-up.
SettingDefault / supplied unitWhy it matters
NEX_MAILBOX_BIND127.0.0.1:8443Loopback only. The reverse proxy is the sole public listener; the service unit enforces this at the kernel level as well.
nex-relay --bind0.0.0.0:8443 (unit: 127.0.0.1:8444)The rendezvous binary reads argv, not NEX_RELAY_* variables. The supplied systemd unit overrides the public default and binds it to loopback behind the proxy.
NEX_MAILBOX_WAIT_TIMEOUT_SECS55How long a waiting client is held open. Your proxy read timeout must be derived from this — 75s for the default. The usual 60s leaves five seconds of headroom and produces load-dependent gateway timeouts.
NEX_MAILBOX_METRICS_BIND / nex-relay --metrics-binddisabled (units: loopback)Metrics must never be publicly reachable. The mailbox setting is an environment variable; rendezvous uses a loopback-only flag and rejects public metric addresses.
NEX_LOG / RUST_LOGrequest handlers at warnThe mailbox reads NEX_LOG and rendezvous reads RUST_LOG. Raising request handlers can expose queue identifiers or the lookup graph, so the supplied units keep them at warn.
NEX_MAILBOX_DIRECTORYoffOpt the service in to publishing a directory of user-chosen labels. Off unless set to one of on/1/true/yes/enabled; anything else, including a typo, leaves it off. Enabling it means you hold personal data — read the obligations section below before you do.

Reverse-proxy rules that are not optional

  • Bind both services to loopback and let the proxy be the only public listener. A service reachable directly is a service whose rate limits and body-size caps are not enforced.
  • Derive the proxy read timeout from the wait timeout. With the default 55-second wait, use 75 seconds; the usual 60 produces timeouts that appear only under load.
  • Turn the access log off for both service paths, or use a format that drops the path. The default format records queue identifiers.
  • Long-lived subscriptions need application-level pings roughly every minute, or the proxy closes them silently and a client sees “no new mail” instead of an error.
  • After any proxy change: test the configuration, reload, then check that the other sites on the machine still resolve. A bad server-name block takes down its neighbours.
  • Plain HTTP on loopback behind a TLS-terminating proxy is the recommended topology, and request binding is designed to work through it.

Pointing a client at your own mailbox

One flag, or one environment variable. There is no account to move and nothing to migrate.

Passed to nex-daemon.
FlagEnvironmentWhat it does
--mailbox <URL>NEX_MAILBOX_URLOrigin of the mailbox, http:// or https:// with no path. Without it the daemon is direct-only: messages are delivered when the peer is reachable and not at all when it is not.
--mailbox-cert <PATH>NEX_MAILBOX_CERTPin a certificate for an https mailbox. Useful for a development certificate; refused if no mailbox is set.
--peer-card <PATH>—Accept a contact card: a peer’s mailbox, a ticket that authorises you to write to their queue, and their direct address. Self-checked on load.
--issue-card—Print your own contact card so a peer can reach you. Requires a mailbox, since a card names the queue it grants access to.
—NEX_DISCOVERYOff unless set to on/1/true/yes. Turns on local discovery: the daemon browses for other Nex devices on the network and publishes an mDNS record of its own. That record is blinded and redrawn every 15 minutes, but it carries this machine’s address, so switching this on makes the machine visible as a Nex device to anyone listening on that network. It is also what opens the pairing listener.
—NEX_DISCOVERY_BINDAddress for the pairing listener that discovery advertises. Defaults to 0.0.0.0:0 — every interface, kernel-chosen port. Narrow it to one interface if the machine is on more than one network and you only mean to be findable on one of them.
—NEX_DEVICE_LABELA name for this machine, shown only on your own row in your own device list. It is never broadcast: the blinded record has no name field, and the separate five-minute “discoverable to anyone” window uses a label typed per window instead.
Pointing a daemon at your own mailboxyour machine
the mailbox origin can be given as a flag or an environment variablenex-daemon --mailbox https://mailbox.example.org --issue-cardor, for a service unit:NEX_MAILBOX_URL=https://mailbox.example.org nex-daemonan empty value means "no mailbox", not "a mailbox at the empty URL"NEX_MAILBOX_URL= nex-daemon      # direct-only, deliberately

Before you accept a stranger’s ciphertext

Running a mailbox for other people makes you a service provider, wherever you are.

A mailbox used only by you and people you know is a private service. The moment it accepts mail from strangers, obligations attach — a contact point, a risk assessment, a way of handling legal requests — and they attach regardless of the fact that you cannot read what you are storing. Your only real levers are quota, expiry and blocking a queue, because content-based moderation is impossible by construction. Decide which of the two you are running before you open it up.