YUME operations
This page covers the release, deployment, and service workflows that operators need after the first successful connection.
Release verification
Each release is expected to publish:
- client and daemon artifacts for supported targets
- per-artifact
.sha256files - per-artifact
.md5files - aggregate
SHA256SUMS.txtandMD5SUMS.txt release-manifest.json- optional
.sigdetached signatures when GPG secrets are configured
Recommended verification:
sha256sum -c SHA256SUMS.txt
md5sum -c MD5SUMS.txt
gpg --verify yumed-amd64-linux.sig yumed-amd64-linux
The manifest records file size, OS, architecture, component, linkage, hashes, and signature sidecars. Treat missing mandatory hashes as a release problem.
BaseFWX pinning
YUME depends on BaseFWX for post-quantum and AEAD primitives. The release and
CI workflows read its repository, exact commit, and minimum compatible version
from config/dependencies.json, then fail preflight if the commit is not
reachable. Keep production revisions immutable; use
scripts/yume_dependencies.py get basefwx revision instead of copying the
commit into another script or workflow.
For normal local development, ezbuild.sh preserves an existing attached
BaseFWX branch and builds its current files in place. It does not shallow the
repository or detach the branch. Use BASEFWX_SYNC_MODE=pinned ./ezbuild.sh
for release evidence; pinned mode refuses a dirty BaseFWX worktree instead of
overwriting it. BASEFWX_SYNC_MODE=worktree makes the no-fetch behavior
explicit.
Fetchability alone does not prove that a SHA belongs to the intended release
lineage after a history rewrite. Before a stable release, also verify that the
pin is the chosen canonical tag/commit and build YUME against a clean checkout
of that exact object; a build against the local sibling’s main is not proof
of the pinned dependency.
Service deployment
A minimal systemd service can run the daemon with a dedicated user:
[Unit]
Description=YUME daemon
After=network-online.target
Wants=network-online.target
[Service]
User=yume
Group=yume
AmbientCapabilities=CAP_NET_BIND_SERVICE
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
NoNewPrivileges=true
ExecStart=/usr/local/bin/yumed --listen 443 --cert /etc/yume/server.crt --key /etc/yume/server.key --auth-keys /etc/yume/authorized_keys --obfs-secret-file /etc/yume/secrets/admission.hex --inner-psk-file /etc/yume/secrets/inner.hex --real-backend loopback://127.0.0.1:3000
Restart=on-failure
RestartSec=3
[Install]
WantedBy=multi-user.target
The Node.js 24 LTS cover site is a separate service bound only to the configured
loopback address. Start and health-check it before yumed; do not expose its
port publicly. Keep auth_keys.meta, TLS private keys, and both 32-byte secret
files readable only by the daemon user. Each secret file is exactly 64 lowercase
hex characters with no group/world permission bits.
Capacity, fairness, and process limits
Set egress_mbps at or below the server’s measured upload/link capacity. Leave
headroom for TLS overhead, the cover service, SSH, and normal host traffic. For
example, start around 900 on a stable 1-Gbit/s link or 2200 on a 2.5-Gbit/s
link, then verify from a remote client. 0 disables shaping and is not
recommended for a shared public server.
{
"threads": 8,
"transport_profile": "chrome151-node24-v1",
"max_sessions": 256,
"bulk_key_max_sessions": 64,
"security_mode": "extreme",
"rekey_window": 8,
"accept_rate_limit": 100,
"egress_mbps": 900,
"filter_memory_mib": 64
}
transport_profile is mandatory protocol identity, not presentation metadata.
Dev6 accepts only chrome151-node24-v1; a stale or missing supported identity
cannot be negotiated or silently downgraded.
The matching CLI flags are --threads, --max-sessions,
--bulk-key-max-sessions, --rekey-window, --accept-rate-limit,
--egress-mbps, and --filter-memory-mib. rekey_window is the number of
concurrent directional epoch offers accepted from one session and the ceiling
on the server’s own sending window (1..64, default 8). It is what lifts
per-round-trip throughput on high-latency links — under Extreme each prepared
epoch adds 256 KiB per rekey round trip — and it bounds how much ML-KEM work
one peer can request. Under the default Extreme security mode, the 256 KiB,
512-frame, and 500 ms per-epoch limits are the same at every depth. See
docs/YUME_2_0_WAN_BEHAVIOR.md. The daemon defaults to 256
live sessions and 64 authenticated sessions per bulk key. An administrator can
explicitly use --max-sessions 0 to remove the global cap, but should normally
raise a finite limit instead.
Security mode selection is currently a JSON configuration contract. Use
extreme, normal, soft, or the complete ultimate object documented in
docs/SECURITY_MODES.md; there is no partial Ultimate fallback.
threads bounds YUME worker concurrency; it is not a hard machine-wide CPU
percentage. Per-session queue bounds, the filter memory limit, and session
limits constrain known allocations, but no portable
in-process setting can guarantee a final RSS ceiling for OpenSSL, the C++
runtime, socket buffers, and plugins. Use systemd/cgroup controls for hard
process limits:
# systemctl edit yume-daemon.service (unit name may be yumed.service)
[Service]
# At most eight logical CPUs.
CPUQuota=800%
# Reclaim/throttle pressure before the hard limit.
MemoryHigh=768M
# Hard cgroup memory ceiling.
MemoryMax=1G
TasksMax=1024
LimitNOFILE=65536
Run systemctl daemon-reload && systemctl restart yume-daemon, then confirm
with systemctl show yume-daemon -p CPUQuotaPerSecUSec -p MemoryHigh -p
MemoryMax -p TasksMax. Keep MemoryMax comfortably above expected
session/socket, TLS, and runtime-library memory; setting it too tightly can
cause the kernel to terminate the daemon rather than gently reject work.
With egress_mbps enabled, active identities receive weighted shares. Put a
top-level decimal weight in the fingerprint’s metadata; 1.5 receives 1.5
times the share of a simultaneously active 1.0 identity. Individual and
operator keys form one identity each. Every authenticated bulk-key session is
counted separately and receives its own fair-share slot. See
docs/PERMISSIONS.md for safe bulk/operator examples and restrictions. The
packet-native TUN uplink must additionally be capped on its TUN/physical
interface with Linux tc; it does not traverse every socket-shaper hook.
For an optional, reversible TUN/NAT/UFW setup, review and apply the separate host helper instead of granting firewall privileges to the daemon:
yume-packet-quick up --listen build-host.example:8443 \
--allow-from 192.168.1.0/24 --dry-run
sudo yume-packet-quick up --listen build-host.example:8443 \
--allow-from 192.168.1.0/24
sudo yume-packet-quick down
The helper refuses existing TUN/nft objects, does not flush firewall state or
change default policies, and stores the exact resources it owns under /run.
yumed itself never invokes it.
Key and permission operations
For new deployments, yume-setup init creates the protected admission/inner
secret files, TLS and operator-identity chain, safe key stores, configs, and a
first device profile in one owner-only directory. yume-setup issue-key
handles individual, bounded bulk, and separate admin/operator credentials
without manual PEM concatenation or JSON editing. See docs/QUICKSTART.md.
List keys and aliases:
yumed --auth-keys /etc/yume/authorized_keys --keys-list
Add a generated key:
yumed --auth-keys /etc/yume/authorized_keys --keys-gen ./keys/user1 --keys-gen-add
Prefer yume-setup issue-key. The --keys-gen command creates both files
exclusively at mode 0600, refuses to overwrite either path, and removes the
private half if it cannot complete the pair. A private 0700 output directory
still protects file names and other provisioning artifacts.
Remove a key or alias:
yumed --auth-keys /etc/yume/authorized_keys --keys-remove alice
authorized_keys and auth_keys.meta control regular admission and policy.
Controller keys live separately in operator_keys and operator_keys.meta.
Restart after editing, or use the authenticated reload operation; reload swaps
all four files as one validated snapshot and preserves the previous snapshot if
any new file is malformed.
Public endpoint policy
Public endpoints should publish:
- hostname and port
- daemon release tag
- TLS certificate identity
- YUME public key or expected key fingerprint
- allowed modes and fair-use limits
- operator CA and delegated-server-certificate SHA-256 fingerprints/serial
- whether the operator advertises privacy-minimizing mode (a policy claim, not remotely provable)
- whether the endpoint accepts only SOCKS/forwarding or also admin/file/chat channels
Do not advertise a public endpoint until users can pin enough metadata to detect replacement or downgrade.
Website documentation mirror
The GitHub Pages site at website/ publishes a subset of docs/ for
browser reading. The canonical copies live in the repository root
docs/ tree; website/docs/ is a curated mirror, not a second source
of truth.
Current mirrored pages (under website/docs/):
QUICKSTART.mdSTEALTH.mdPERFORMANCE.mdOPERATIONS.mdPERMISSIONS.md
When you change an operator-facing doc that appears on the site, update
the matching file under website/docs/ in the same commit, or remove
the page from the site index until it is synced. Release and packaging
docs (PACKAGING.md, man pages, ARCHITECTURE.md) stay repo-only
unless explicitly added to the mirror list.
Troubleshooting
If the client cannot connect:
- confirm direct TCP reachability to the daemon port
- confirm no HTTP proxy is terminating TLS in front of
yumed - ensure client and server use the same
--obfs-secret-fileand--inner-psk-filecontents; there is no accepted 2.0 no-inner/no-obfs mode - verify the separately supervised Node cover is listening on the configured
loopback IP and passes
yumed’s startup health check - check that the client’s public key is present in
authorized_keys - verify that the server certificate chain matches what the client expects
If forwarding connects but cannot reach a target:
- check
auth_keys.metafor LAN/private-IP permission if the target is RFC1918 or loopback - confirm the release was built with the required feature switch
- confirm the daemon was started with the matching runtime flag
- inspect daemon logs for an auth-policy denial