Phaze Relay
===========

The Phaze Relay forwards UDP traffic between Phaze hosts and clients.
When a host is assigned to a relay location via the admin panel, all
connections to that host will flow through one of the online relays
configured for that location.


Contents
--------
  phaze-relay            Static Linux binary
  phaze-relay.service    systemd unit (template; install.sh fills in your key)
  install.sh             Install / update / repair script. Run from this
                         directory the first time; afterwards the same
                         script is reachable as
                         /usr/local/bin/phaze-relay-update.
  readme.txt             This file


Requirements
------------
  - Linux x86_64 or arm64
  - One inbound UDP port (default 41000) reachable from hosts and clients
  - Outbound TCP 443 to relay.phaze.app (the default --ws-host; if you
    set --ws-host to a different signaling host, allow that one instead)
  - A relay key (phz_rk_...) from the Phaze admin panel
  - systemd (standard on most Linux distros)
  - Tools available on PATH: curl, unzip, sha256sum (used by the updater)


Verifying the download
======================

Before installing, confirm the archive matches the published checksum:

    sha256sum -c SHA256SUMS

Each line should print "OK". If anything else appears, re-download the
archive from the original source — do not proceed.


Installation
============

The bundled install.sh script handles install end-to-end:

    sudo ./install.sh

It walks through seven steps with narration:

    [1/7] Prompt for your relay key
    [2/7] Create the 'phaze-relay' system user (if missing)
    [3/7] Install /usr/local/bin/phaze-relay
    [4/7] Install /usr/local/bin/phaze-relay-update
    [5/7] Install /etc/systemd/system/phaze-relay.service (key inserted)
    [6/7] Raise the UDP socket buffer limits (see Appendix A Step 5)
    [7/7] Enable and start the service

When it finishes, the relay should appear as "online" in the admin
panel within a few seconds. Tail logs with:

    sudo journalctl -u phaze-relay -f


Non-interactive install
-----------------------
For cloud-init, Ansible, or any automated provisioning, pass the key
on the command line and skip the prompt:

    sudo ./install.sh --key=phz_rk_...


Reinstalling
------------
Re-running install.sh on an already-configured host prints a hint and
exits. To reinstall from scratch using the files in this zip
(regenerates the unit file with a fresh key prompt), pass --force:

    sudo ./install.sh --force


Manual install
--------------
If you'd rather wire things up by hand — for instance, to slot the
relay into an existing configuration-management workflow — see
Appendix A.


Updating
========

After the install above, applying a new release is one command:

    sudo /usr/local/bin/phaze-relay-update

The update script:
  - Fetches the latest version from the Phaze CDN
  - Verifies its SHA-256 checksum
  - Stops the service, swaps the binary, restarts it
  - Replaces itself with the newer version of the script
  - Saves the previous binary to /usr/local/bin/phaze-relay.prev for
    manual rollback if anything goes wrong

If the bundled phaze-relay.service template has changed (e.g. new
hardening directives), the script saves it as
/etc/systemd/system/phaze-relay.service.new and prints a notice. Your
live unit (which contains your relay key) is never modified. Review and
merge changes manually if desired.

Force a reinstall even if you are already on the latest version:

    sudo /usr/local/bin/phaze-relay-update --force


If you forgot to set your relay key
-----------------------------------
If phaze-relay.service still contains REPLACE_WITH_YOUR_RELAY_KEY (for
example, because the unit was installed manually without filling in the
key), running the updater interactively will detect this, prompt for
the key, patch the unit, reload systemd, and start the service:

    sudo /usr/local/bin/phaze-relay-update

If you reach that state on a non-interactive machine (cloud-init,
configuration management, etc.), the script exits with a clear error
pointing at the placeholder. Replace it in
/etc/systemd/system/phaze-relay.service before re-running.


Common Operations
=================

Status and live logs:
    sudo systemctl status phaze-relay
    sudo journalctl -u phaze-relay -f

Restart after editing the unit file:
    sudo systemctl daemon-reload
    sudo systemctl restart phaze-relay

Stop / start / disable:
    sudo systemctl stop    phaze-relay
    sudo systemctl start   phaze-relay
    sudo systemctl disable phaze-relay

Roll back to the previous binary:
    sudo systemctl stop phaze-relay
    sudo mv /usr/local/bin/phaze-relay.prev /usr/local/bin/phaze-relay
    sudo systemctl start phaze-relay

Uninstall completely:
    sudo systemctl disable --now phaze-relay
    sudo rm /etc/systemd/system/phaze-relay.service
    sudo systemctl daemon-reload
    sudo rm -f /usr/local/bin/phaze-relay /usr/local/bin/phaze-relay.prev
    sudo rm -f /usr/local/bin/phaze-relay-update
    sudo userdel phaze-relay


Troubleshooting
===============

The first thing to check, in nearly every case, is the service status
and recent logs:

    sudo systemctl status phaze-relay
    sudo journalctl -u phaze-relay -e


The service won't start
-----------------------
Most common causes:

  - The relay key is missing or still set to the placeholder. The
    easiest fix is to re-run the updater, which detects this and
    prompts for the key:
        sudo /usr/local/bin/phaze-relay-update
    Or edit /etc/systemd/system/phaze-relay.service by hand, then:
        sudo systemctl daemon-reload
        sudo systemctl restart phaze-relay

  - The "phaze-relay" user doesn't exist. install.sh creates it; if you
    installed manually, see Appendix A Step 2.

  - The UDP port is already in use by another process. Find what's
    holding it:
        sudo ss -ulnp | grep ':41000'
    Stop that process or change the relay's --udp-port (see below).


Logs show "unauthorized" at startup
-----------------------------------
The relay key is invalid or has been revoked. Generate a new one in the
admin panel, update /etc/systemd/system/phaze-relay.service, then:

    sudo systemctl daemon-reload
    sudo systemctl restart phaze-relay


The relay shows as offline in the admin panel
---------------------------------------------
Check, in this order:

  1. The service is actually running:
        sudo systemctl status phaze-relay

  2. Outbound TCP 443 is allowed by your firewall.

  3. DNS resolves the signaling host. By default this is
     relay.phaze.app:
        host relay.phaze.app
     If you've overridden --ws-host in phaze-relay.service, check that
     hostname instead.

  4. The relay's public address configured in the admin panel matches
     a real address that hosts and clients can reach from the internet.


No connections are arriving
---------------------------
  - Confirm the UDP port (default 41000) is open for inbound traffic on
    the host firewall and any upstream firewall/NAT:

        # Ubuntu / Debian
        sudo ufw allow 41000/udp

        # RHEL / Fedora / Rocky
        sudo firewall-cmd --add-port=41000/udp --permanent
        sudo firewall-cmd --reload

  - Confirm the public address registered in the admin panel is correct
    and reachable from the public internet (not just from inside your
    network).

  - If the relay sits behind NAT (for example, on a private network
    behind a router), confirm that the public UDP port configured in
    the admin panel is forwarded to the relay machine on the port the
    relay is listening on. The two ports do not have to match — for
    example, the admin panel can advertise UDP/443 publicly while your
    router forwards UDP/443 to the relay's UDP/41000 — but the forward
    must be in place. Reachability of the public IP alone is not
    enough; without the port forward, packets reach your router and
    are dropped.

  - Increase log verbosity (see below) and watch the journal while a
    client tries to connect — you should see incoming packets logged.


Increase log verbosity
----------------------
Edit /etc/systemd/system/phaze-relay.service and add --log-level debug
to the ExecStart line, then:

    sudo systemctl daemon-reload
    sudo systemctl restart phaze-relay
    sudo journalctl -u phaze-relay -f

Switch back to "info" once you're done — debug logs are noisy.


Logs warn "UDP socket buffers smaller than requested"
-----------------------------------------------------
All relayed traffic shares one UDP socket, so the relay asks the kernel
for 8 MiB send and receive buffers. Most distros cap socket buffers at
208 KiB, and a relay stuck at that size drops packets during bursts,
which shows up as stutter or dropped connections under load.

install.sh raises the caps on install and on every update. A relay
updated by an older version of the script picks them up from the next
run of the updater, which restarts the relay to apply them:

    sudo /usr/local/bin/phaze-relay-update

To raise them by hand instead, see Appendix A Step 5, then:

    sudo systemctl restart phaze-relay


Change the UDP port
-------------------
Edit /etc/systemd/system/phaze-relay.service, change the --udp-port
value, then:

    sudo systemctl daemon-reload
    sudo systemctl restart phaze-relay

Open the new port in your firewall and update the relay configuration
in the admin panel to match.


Where are settings stored?
--------------------------
All configuration lives on the ExecStart line in
/etc/systemd/system/phaze-relay.service. There is no separate config
file. Relay state is in-memory; it is lost on restart but reconstructed
automatically as hosts and clients reconnect.


An update went wrong — how do I roll back?
------------------------------------------
See "Roll back to the previous binary" under Common Operations.


Appendix A — Manual installation
================================

These are the steps install.sh runs. Use them when you need finer control
over the install — e.g. to integrate with configuration management, or
to install on a system where running an opaque shell script isn't
acceptable. Run every command from a shell that can use sudo.

Step 1 — Unzip the archive
--------------------------
    unzip phaze-relay-linux-amd64.zip -d phaze-relay
    cd phaze-relay


Step 2 — Create the dedicated user
----------------------------------
The systemd unit runs as the "phaze-relay" user. Create it once:

    sudo useradd --system --no-create-home \
        --shell /usr/sbin/nologin phaze-relay

If your distro doesn't ship /usr/sbin/nologin, substitute /sbin/nologin
or /bin/false. If the user already exists, useradd exits non-zero —
that is harmless.


Step 3 — Install the binary and update script
---------------------------------------------
    sudo install -m 0755 phaze-relay /usr/local/bin/phaze-relay
    sudo install -m 0755 install.sh  /usr/local/bin/phaze-relay-update


Step 4 — Configure the systemd unit
-----------------------------------
Open phaze-relay.service in a text editor and replace
REPLACE_WITH_YOUR_RELAY_KEY on the ExecStart line with your relay key
(phz_rk_...). Save and exit, then install it:

    sudo install -m 0644 phaze-relay.service /etc/systemd/system/


Step 5 — Raise the socket buffer limits
---------------------------------------
Allow the relay its 8 MiB UDP socket buffers. Check the current limits
first:

    sysctl net.core.rmem_max net.core.wmem_max

If either is already larger than 8388608, use that value for it below
instead.

    printf 'net.core.rmem_max = 8388608\nnet.core.wmem_max = 8388608\n' \
        | sudo tee /etc/sysctl.d/90-phaze-relay.conf
    sudo sysctl -p /etc/sysctl.d/90-phaze-relay.conf


Step 6 — Enable and start the service
-------------------------------------
    sudo systemctl daemon-reload
    sudo systemctl enable --now phaze-relay


Step 7 — Verify it is running
-----------------------------
    sudo systemctl status phaze-relay

Expect "active (running)". Watch live logs with:

    sudo journalctl -u phaze-relay -f


Support
-------
  https://help.phaze.app/
