Remote Access

A Rex server on Linux listens only on Unix sockets on that machine by default. To use it from Rex for Mac or another computer, you must specify a network listener. This page covers the listeners, who each one lets in, and how to add the server to a client.

Rex trusts a caller based only on how they connect today, so it can’t check who someone is unless the network tells it. That’s why servers listen only locally by default and why every listener below is cautious about who it lets in. This is a short-term limitation. A full authentication and authorization system is planned, including support for existing SSH keys.

Until then, we recommend Tailscale. It tells Rex who each caller is, which is how Rex decides who gets in, and for the login server, which account they get. Tailscale has powerful ACLs that you can use to safely restrict access for multiple users at the network level.

ListenerNeedsWorks withIdentifies callers
Built-in TailscaleA Tailscale accountPersonal and shared serverYes
Tailscale ServeTailscale on the machineShared and login serverYes
Tailnet addressTailscale on the machineShared and login serverYes
Plain HTTP--allow-anonymousEvery modeNo

Built-in Tailscale

With --tailscale, the server joins your tailnet as its own device, using Tailscale built into Rex. The machine doesn’t need Tailscale installed.

rex server start --tailscale

The first time, the server needs to sign in to Tailscale. Its sign-in link appears in rex server status and the server’s log. To sign in without a browser, pass a one-time auth key with --tailscale-auth-key-file FILE, or - to read it from standard input. The server keeps its login, so it needs the key only once.

The device is named rex unless you choose another name with --tailscale-hostname. Its address is https://rex.<tailnet>.ts.net. Your tailnet must have MagicDNS and HTTPS certificates turned on.

To sign it in as a tagged device, add --tailscale-advertise-tag tag:NAME. A tagged device has no owner, so this also needs --tailscale-allow-tailnet-members. See Who Can Connect.

For the shared server, add these options to the service’s command line, as in the next section.

Tailscale Serve

If the machine already runs Tailscale, Tailscale Serve can forward HTTPS connections to a socket that Rex listens on. This is the usual way to reach the shared server or the login server.

Run sudo systemctl edit rex.service (or rex-login-server.service) and add the socket to its command line. Package upgrades keep this file. For the shared server:

[Unit]
After=tailscaled.service
Requires=tailscaled.service

[Service]
ExecStart=
ExecStart=/usr/bin/rex server run --listen /run/rex/server.sock \
  --state-dir /var/lib/rex --socket-mode 0660 --log-format text \
  --extra-listen tailnet-serve:///run/rex/serve.sock

For the login server, the command line is:

ExecStart=
ExecStart=/usr/bin/rex login-server --listen unix:///run/rex/login-server.sock \
  --accounts /etc/rex/accounts.jsonc --runtime-root /run/rex --log-format text \
  --pam-service rex-login-server --extra-listen tailnet-serve:///run/rex/serve.sock

On Alpine, set command_args in /etc/conf.d/rex (or /etc/conf.d/rex-login-server) to the same command line, without /usr/bin/rex. rc_need takes the place of After= and Requires=. For the shared server:

command_args="server run --listen /run/rex/server.sock \
  --state-dir /var/lib/rex --socket-mode 0660 --log-format text \
  --extra-listen tailnet-serve:///run/rex/serve.sock"
rc_need="tailscale"

Then point Tailscale Serve at the socket:

sudo tailscale serve --bg --https=443 unix:/run/rex/serve.sock

The address is the machine’s own tailnet name, such as https://build.<tailnet>.ts.net.

Tailscale Serve doesn’t tell Rex who a tagged device is, so tagged devices such as CI runners can’t connect this way. Use a tailnet address for them instead.

Tailnet Address

A server can also listen directly on the machine’s tailnet addresses, using the machine’s own Tailscale to identify callers. Add this to the server’s command line, the same way as the Serve socket above:

--extra-listen tailnet://:7297

The port is required. The connection is plain HTTP, encrypted by Tailscale, at http://build.<tailnet>.ts.net:7297.

Who Can Connect

A connection to a server can do anything that server can, including starting programs as its account. Control access with care.

For a personal server or the shared server, only the Tailscale user who owns the machine (or the Rex device, with built-in Tailscale) is let in by default. To let in other people:

ListenerOptionLets in
Built-in Tailscale--tailscale-allow-tailnet-membersAnyone on the tailnet your ACLs allow
Serve or address--tailnet-allow-identifiedAnyone Tailscale can identify

A tagged machine or device has no owner, so it needs one of these options to let anyone in.

The login server is different. It lets in everyone Tailscale can identify, because its accounts file decides which accounts each person may use.

To see who’s connected to a server, run rex client ls on it. Its principal column shows the identity of each client.

Plain HTTP

A plain HTTP listener can’t tell callers apart, so Rex refuses one unless you also pass --allow-anonymous:

rex server start --extra-listen :7297 --allow-anonymous

Every connection then has full access. Only do this on a network you completely control. The login server lets such callers use only accounts whose principals include anonymous, and never root.

Again, this is super dangerous and you probably shouldn’t do it. This option exists because sophisticated users can pair this with their own network options such as their own corporate VPN, ZeroTier, etc. to provide stronger guarantees.

Adding the Server to a Client

In Rex for Mac, choose Add Remote Host… and enter the server’s address.

On the command line, pass the address with -S, or save it as a host and use its label:

rex -S https://build.example.ts.net ls
rex hosts add build https://build.example.ts.net
rex -S build ls

A bare host name, such as build.example.ts.net, tries HTTPS on port 443, then HTTPS on port 7297, then HTTP on port 7297.

To connect to the login server as a specific account, put it before the host, such as https://root@build.example.ts.net. See Choosing an Account.

Note: rex hosts today is CLI-only. It doesn’t sync to your GUI client or across machines. This will change in the future.

NixOS

The NixOS module has options for each listener:

OptionSets up
services.rex.tailscale.enableBuilt-in Tailscale, with hostname, authKeyFile, and advertiseTags
services.rex.tailscaleServe.enableTailscale Serve for the shared server
services.rex.loginServer.tailscaleServe.enableTailscale Serve for the login server
services.rex.allowAnonymousPlain HTTP for the shared server. openFirewall opens its port.
services.rex.loginServer.allowAnonymousPlain HTTP listeners for the login server