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.

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.

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 both services at start-up.
VariableDefaultWhy 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_BIND127.0.0.1:8444The same, for the rendezvous service.
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_BINDloopbackMetrics must never be publicly reachable. Same for NEX_RELAY_METRICS_BIND.
NEX_LOGhandlers at warnRequest handlers at info would log paths containing queue identifiers, which is exactly what must never be recorded.

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-cardPrint your own contact card so a peer can reach you. Requires a mailbox, since a card names the queue it grants access to.
Pointing a daemon at your own mailboxyour machine
the mailbox origin can be given as a flag or an environment variablenex-daemon --mailbox https://mail.example.org/nmx --issue-cardor, for a service unit:NEX_MAILBOX_URL=https://mail.example.org/nmx 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.