← Честа питања

Честа питања су написана на енглеском и холандском; приказана су на енглеском.

Честа питања

Server Admin

FAQ › EUZOS Server › Server Admin · Nederlands

What is it?

Server Admin (srvadmin) is the app with which an admin manages EUZOS servers from an EUZOS PC (EUZOS Desktop). It is a signed native EUZOS program from the app catalogue, installed into apps/, and the only program that gets the permission server_admin. The app itself sees no key and no token: it hands the kernel a request, and the kernel does the cryptography and the network. It talks to the server over the admin protocol: HTTPS (TLS 1.3, pinned key) on TCP port 8446, separate from the cache port 8445, so the firewall can open them separately.

A production EUZOS Server is managed only this way: it has no SSH, and its own console can only view the firewall.

How do I…?

How do I install and start Server Admin?

On an EUZOS PC, logged in with an account with admin rights:

apps install srvadmin
serveradmin

Without logging in: "log in first (an account with admin rights)". If the app is missing: "(to install: apps install srvadmin)". Server Admin runs on x86-64 only.

After apps install srvadmin, Server Admin is also in the menu (column APPS) as a graphical app: see below.

How do I use the graphical app Server Admin?

Open Server Admin from the menu. It is only there when the signed app srvadmin is installed (only admins get a download token) and you are logged in; otherwise the window says "Only for admins". Managing is possible only from an EUZOS PC: there is no web administration and no other operating system.

  • Servers: the servers of your organisation (from the profile server): name, online or offline, address, external address, ID, version, installed on and by, and the packages on or off. Click a server (or arrows and Enter).
  • A server, with tabs: Status (version, running for, disk, LAN, sign-in, traffic; Sign in and check now, Restart server; the public keys), Packages (a switch per package), Firewall (rules with Close, package suggestions with Open, open a rule), Network (adapters with Use DHCP, a static address, the external address), Ports (a switch per network adapter, USB port and USB class; Ports), Backup (state, retention, quota, usage per account and device), File server (shares, permissions, groups, quota, trash), Web server (sites, certificates with ACME status and expiry, proxy rules, upload from My files, log), Package cache (contents, usage, empty, which apps), Log (see below), Activity (see below), Terminal (one console command at a time, off by default) and Updates (planned, UPDATES.md).
  • Log (T-1333): the server filters, the app gets one page (50 lines, newest first; Newer and Older page through). Filter by type (Web, DNS, SSH, Admin and audit, PostgreSQL, Node.js, System; several at once, or only Warnings and errors), by day (All days, Today, Yesterday, Last 7 days, or a date YYYY-MM-DD), by time of day From–To (HH:MM; From after To wraps over midnight) and by a text. Every line shows its time (the server's local time), its type and its text; warnings are amber, errors red. Web lines come from the access log (its day files, so also older days within its retention); the other types from the server's journal since boot (4096 lines) and the refusals before authentication. The persistent audit log stays below (Show).
  • Activity (T-1334): live graphs over the last 5, 15 or 60 minutes, updated every 2 seconds while the tab is open: HTTP requests per second by status class (2xx, 3xx, 4xx, 5xx; all websites or one), requests per second per website, TCP connections (open, new per second), network traffic in and out, DNS queries per second, SSH sessions, CPU and memory, and PostgreSQL connections over the network when it runs. The server samples once a second (the last hour); counting on the request paths is a relaxed atomic add, never a lock.
  • Every change asks for confirmation first, showing the exact command (e.g. pakket-uit web bevestig); Esc or Cancel does nothing. The outcome appears as a green or red card at the top of the tab, with the reason code explained (e.g. "this needs Workplace management on this server").
  • Keyboard: Left/Right switch tabs, Tab goes to the first field (and on), Enter carries out the field, Esc leaves the field or goes back to the servers. The on-screen keyboard appears for a field. Light and dark theme and all 34 languages.

The app uses the same admin actions as serveradmin (the Terminal tab uses console, console-set and console-check): every command gets an admin proof from the profile server and is signed with the device key. An admin proof is reused for 5 minutes (it is valid for 10 minutes and only usable with a fresh challenge and this PC's device key); logging out wipes it. The PC's log gets only the action name, never arguments, replies, tokens or keys; the installer's registration code is not shown.

How do I use the Terminal tab (run a command on a server)?

Server Admin has a Terminal tab per server. It is not SSH and no new port: each command is one signed request with its reply over the existing admin protocol (port 8446), with your admin proof and this PC's key. There is no interactive session and no process stays attached.

  • Off by default. A server accepts nothing until an admin turns the terminal on: Turn on in the tab (with a confirmation), or serveradmin <id> console-set on confirm. Turn off (or console-set off) stops it again. The setting is the file \EOS\FW\CONSOLE.TXT on the server; a missing or odd file means off.
  • Type a command and press Enter or Run. The server first says how it classifies the command (console-check):
    • read-only (on the server's list: help, pci, usb, ports, disks, sysinfo, ps, mem, ip, network, packages, log [n], audit [n], and a few more): it runs at once;
    • everything else (changes something, restarts, or is not on the list): the app asks first and shows the exact command; only after Run it goes out. This is the default for any unknown command;
    • denied: it never runs, not even confirmed (reason command_denied).
  • The deny list: nothing that prints or changes secrets or keys (pckey, sign, hostkey, wifi, vpn, vault, tpm, profile, workplace, smb, sshd, bootvar, and others), nothing that reads or writes files (cat, type, get, put, read, dump, copy), and any command that names a key file or a secret (PCKEY, HOSTKEY, WPKEY, AUDKEY, *KEY.TXT, *TLS.TXT, secret, token, password, seed). The exact lists are DENIED, SECRET_WORDS and READ_ONLY in libs/workplace/src/console.rs. Only the console commands the server already has can run, and only those its own console rules allow (a production server has a short list).
  • The reply is limited to 48 KiB and ends with [... output truncated after 48 KiB] when cut. The app keeps the last 8 outputs (300 lines each).
  • History: Up and Down in the command field step through the commands typed before (the last 50).
  • Every command is in the audit log (Audit log) with your account and this PC; of a denied command only its first word is written (it could carry a secret). Refused attempts (terminal off, denied) are in it too.
  • Selecting and copying: Server Admin has no text selection yet, so the output cannot be selected or copied from the window.
  • Reasons are shown as in the other tabs: console_off ("the terminal is off on this server"), command_denied, confirmation_needed.

What does the PC need?

  • a device key: pckey create writes \EOS\FW\PCKEY.TXT (on the ESP of the internal disk); pckey shows the public key and fingerprint;
  • the PC registered with the organisation on the profile server (pc-register '<name>' <key> <organisation>, see CLI);
  • an account that is an admin of the organisation the server belongs to.

How do I list the servers I may manage?

serveradmin (or serveradmin list). Per server: id (16 hex), name, LAN address, state, and (newer servers) who installed it, when, and the external address.

How do I give a command to a server?

serveradmin <server-id> <action> [arg], for example serveradmin <id> status or serveradmin <id> firewall-open allow tcp 8445 lan. All actions are in the table below.

Why was my command refused?

Server Admin prints "refused or failed:" with an explanation of the reason code, for example: not logged in, no admin rights for this organisation, no device key, PC not registered or revoked, PC/server/admin not in the same organisation, unknown or revoked workplace server, server without an organisation, the admin proof expired (clock?), the challenge did not match, or the server has not signed in at the profile server yet.

Details

A command takes four steps (crate::server_admin::execute_with):

  1. Admin proof: the kernel asks the profile server, with the PC token of the logged-in user, for an admin proof (POST …/admin-proof, body werkplek=<id>, pcsleutel=<device key>). The reply holds ok, lan= (the server's LAN URL), tls= (its TLS pin) and the proof document EUZOS-werkplek-beheerbewijs-v1, signed by the profile server and valid for 10 minutes.
  2. Challenge: POST /beheer/v1/uitdaging on port 8446 of the server (falls back to the LAN URL's port for older servers), with the TLS key pinned. Reply: ok, uitdaging=<32 hex> (one-time, valid 60 s).
  3. Command: the kernel builds EUZOS-werkplek-opdracht-v1 and signs it with the PC's device key (crate::device_key::sign_command).
  4. Send: POST /beheer/v1/opdracht with the proof followed by the command. The server checks (euzos_workplace::admin::check): the profile server's key (from PROFILE.TXT), environment and server, its own id and organisation, the time, the PC signature (same PC key as in the proof) and the challenge. Then it executes the action and logs who did what from which PC.

Threat model in short

Only on an EUZOS PC (the system call does not exist elsewhere and the keys are in the kernel); only by an admin of the server's organisation (the proof); only from a registered PC (the device key); fresh (challenge, short validity).

Reference

Console commands

CommandArgumentsWhat it does
serveradmin– or list (legacy lijst)the servers you may manage (desktop only)
serveradmin<server-id> <action> [arg]send an action; the rest of the line is the argument
pckey[create] (legacy maak)show or create the PC's device key (desktop only)
apps install srvadmin–install Server Admin from the catalogue

Server Admin actions

The command word is English; the old Dutch word (the wire name) is still accepted on the command line. On the wire the Dutch name is used and signed.

Command wordWire nameArgumentChanges?What it does
statusstatus–noversion, uptime (with the seconds in parentheses), disk, sign-in, organisation, address, pin, traffic
cachecache–noapps and versions in the cache
fillvul–yessign in now and check the cache
appsapps<a,b> (≤ 4)yeswhich apps the cache keeps (writes apps= in WORKPLC.TXT)
networknetwerk–noLAN URL, adapters, SSH state and the network overview
network-setnetwerk-zet<adapter> dhcp | <adapter> statisch <ip>/<prefix> <gateway|-> <dns1> [<dns2>] | extern <address>|geenyeschange the network file and apply it
loglogboek–nothe last 100 lines of the server's log
logslogs[type=web,dns,…] [level=warn] [day=today|yesterday|week|YYYY-MM-DD] [from=HH:MM] [to=HH:MM] [page=<n>] [n=<1-200>] [q=<text>]nothe logs filtered on the server, one page newest first: total=, page=, per=, offset= (local time minus UTC), now=, then <unix>\t<type>\t<level>\t<text> per line; q= takes the rest of the line (T-1333)
activityactivitywindow=<s> step=<s> since=<unix>nothe live activity in buckets of step seconds from since (or the window's start) on: offset=, now=, step=, window=, sites=, memory=, then b <t> <n> <tcp-open> <tcp-new> <rx> <tx> <dns> <ssh> <cpu‰> <mem‰> <pg|-> <site…> (T-1334); not written to the server log
auditaudit[n]nothe persistent audit log, verified (hash chain and MACs), then the newest n records (Audit log)
rebootherstart–yesreboot in 2 s
revokeintrekken–yeswipe the keys and WORKPLC.TXT: an ordinary PC after reboot; also revoke on the profile server
resetopnieuw–yesnew keys; register again and reboot
firewallfirewall–norules, package suggestions, blocked count
firewall-openfirewall-open<rule>yesadd a rule at the front
firewall-closefirewall-sluit<rule>yesremove exactly that rule
firewall-setfirewall-zet<rule>; <rule>; …yesreplace all rules (the admin protocol must stay allowed)
packagespakketten–nothe Packages screen
package-onpakket-aan<id>yesturn a package on
package-offpakket-uit<id> [confirm]yeswithout confirm only shows what will happen; confirm (legacy/wire bevestig) does it
cache-clearcache-clear[confirm]yesempty the package cache (Package cache); without confirm only shows what will happen
filesfiles[<sub-command>]yesthe File server: shares, quota, rights, groups, usage (File server)
webweb<sub-command>dependsthe Web server package: sites, proxy rules, certificates, log, uploads (see Web server)
backupbackup–nothe package Backup: state, retention, quota, usage per account and device (Backup)
backup-setbackup-setdaily=<n> weekly=<n> monthly=<n> quota-account-gib=<n> quota-device-gib=<n>yesretention and quota of Backup (written to BACKUP.TXT; the retention job runs shortly)
portsports–nonetwork adapters, USB ports and USB classes with their state (Ports)
ports-setports-setnet <adapter> on|off [confirm], usb <position> on|off [confirm], usb-class <class> on|off [confirm]yesswitch one on or off (written to PORTS.TXT); never the adapter of the admin connection or the boot stick's port; the last adapter and the only keyboard need confirm
console-checkconsole-check[<command>]nothe terminal's state (console=on|off) and, for a command, its class (read, confirm, denied)
console-setconsole-seton confirm | offyesturn the terminal on (needs confirm) or off; written to CONSOLE.TXT; off by default
consoleconsole[confirm] <command>yesrun one console command and return its output (≤ 48 KiB); only when the terminal is on, never a denied command, and a command that is not read-only only with confirm

Rule syntax: allow|deny tcp|udp|icmp <port|from-to|-> lan|anywhere|<ip>[/<prefix>] (legacy toestaan|weigeren, overal) (see Network and firewall).

Functions and modules

ItemRole
user/srvadmin (main.rs)the app: parses the command line, shows replies, explains reason codes
system call 0x100a (crate::server_admin::syscall)request from the app to the kernel; only with PERM_SERVER_ADMIN
crate::server_admin::execute, execute_withproof, challenge, signing, sending
crate::server_admin::commandthe serveradmin console command (starts the app)
crate::device_key::{public_key, sign_command, command}the PC's device key (PCKEY.TXT)
crate::workplace::admin, executethe server side: challenge and command handling, the actions
euzos_workplace::admin::{Proof, Command, Action, check, CONFIRM}the document formats and the check
crate::app_store::SERVER_ADMINthe app name srvadmin
euzos_ui::apps::server_adminthe graphical app: state, layout (a plan of what lies where), drawing, clicks, keys
euzos_ui::apps::server_admin_datareading the replies: server list, lines, packages, firewall, network, reason codes
crate::server_admin_appthe kernel side of the app: only with srvadmin installed, requests in a thread of their own via crate::server_admin::execute
euzos_workplace::console (libs/workplace/src/console.rs)the terminal's policy: off by default, deny list, classification, size limit (host-tested)
crate::server_console (kernel/src/server/console.rs)the server side of the terminal: the CONSOLE.TXT setting, running the command with its output captured
crate::server_admin::forgeton logout: the reused admin proofs gone
euzos-ui-preview serverbeheer <dir>renders of every screen (nl/en, 1366×768 and 1920×1080; make ui → build/ui/serverbeheer)

Config files

FileWhereMeaning
\EOS\FW\PCKEY.TXTthe PCthe device key seed (64 hex, secret)
\EOS\FW\WPKEY.TXT, WPTLS.TXTthe serverthe server's keys (secret)
\EOS\FW\PROFILE.TXTthe serverthe profile server and its public key, used to check the proof

API endpoints

On the profile server (called by the PC's kernel with the PC token; the kernel uses the legacy paths):

MethodEnglish pathLegacy pathPurpose
GET/api/workplace/v1/admin-list?token=/api/werkplek/v1/beheerlijstthe servers this admin may manage
POST/api/workplace/v1/admin-proof?token=/api/werkplek/v1/beheerbewijsan admin proof for one server; rate-limited

On the server, port 8446 (HTTPS, pinned TLS key; POST only):

MethodPathBodyReply
POST/beheer/v1/uitdagingemptyok\nuitdaging=<32 hex>\n
POST/beheer/v1/opdrachtproof document + command documentok\n<text> or fout\nreden=<code>\n

The admin paths answer only on 8446 and the cache paths only on the cache port; otherwise 404 pad.

Protocol messages and formats

App ↔ kernel request (system call 0x100a, ≤ 1024 bytes):

actie=lijst
werkplek=<16 hex>
actie=<wire action>
arg=<text>

Admin proof (signed by the profile server):

EUZOS-werkplek-beheerbewijs-v1
omgeving=<environment>
server=<profile server>
werkplek=<id>
organisatie=<organisation>
pcsleutel=<64 hex>
account=<e-mail of the admin>
beheer=werkplek
uitgegeven=<unix time>
geldig-tot=<unix time>
sleutel-id=<16 hex>
handtekening=<128 hex>

Command (signed with the PC's device key):

EUZOS-werkplek-opdracht-v1
werkplek=<id>
pcsleutel=<64 hex>
uitdaging=<32 hex>
actie=<wire action>
arg=<text, ≤ 256>
handtekening=<128 hex>

The signature is Ed25519 over <kind>\0 + all bytes up to and including the \n before handtekening=. A document is at most 4096 bytes; each key at most once. A proof is valid at most 10 minutes (+120 s clock slack).

Reason codes (wire values): from the server's check ongeldig, bewijs_handtekening, pc_handtekening, actie_onbekend, omgeving_onjuist, andere_werkplek, andere_organisatie, bewijs_verlopen, andere_pc, uitdaging_onjuist; from the admin port geen_willekeur, te_vaak, geen_serversleutel, niet_aangemeld, klok, pad; from the actions geen_rol, pakket_onbekend, pakket_binnenkort, confirmation_needed, package_not_installed, console_off, command_denied; from the PC's kernel niet_ingelogd, geen_apparaatsleutel, werkplek_zonder_adres, werkplek_geen_uitdaging; from the profile server among others geen_beheerder, pc_onbekend, pc_ingetrokken, werkplek_onbekend, werkplek_ingetrokken, werkplek_zonder_organisatie, te_vaak.

List line (actie=lijst): werkplek=<id>\t<name>\t<lan>\t<actief|niet actief>\t<installed by>\t<date>\t<external address>.

See also