WabiLink Server
Everything a WabiLink server can be set to, from the command line on the server itself: its accounts and what each may use, shares, tunnels, databases, the desktop, WabiOne, and every setting.
As root: sudo wabilink-server .... The settings are the service's: run without
sudo, a command changes a server of your own instead, and the service doesn't see it.
In PowerShell opened as administrator (Win+X
→ Terminal (Admin)), in the server's folder (cd "C:\Program Files\WabiLink\wabilink-server"):
.\wabilink-service .... Not as administrator, it stops and says so.
max-connections-per-session apply at the next start (restarting it).help lists them all, with their options.--json; user add and
user passwd take --password-stdin (one line, read from standard input) instead of asking. The
exit code says how it went: 0 done, 1 failed, 2 a wrong command or a change refused,
3 the server could not start, 4 it needs root or an administrator, 5 no such user,
share or setting.user unlock and share grant.8010, an administrator's account), change the same,
except what is marked this machine only below. For an AI assistant, wabilink mcp
in the command-line client does it too.sudo wabilink-server help
sudo wabilink-server config show
The server's own accounts: a name and a password of WabiLink's, not the machine's.
sudo wabilink-server user list
sudo wabilink-server user add ann # asks for a password, twice
sudo wabilink-server user add ann --admin # and an administrator: may open Server settings
sudo wabilink-server user add bob --must-change # chooses a new password at the first login
sudo wabilink-server user passwd ann # a new password
sudo wabilink-server user passwd bob --must-change
sudo wabilink-server user unlock ann # locked after too many failed logins
sudo wabilink-server user disable bob # kept, but may not log in; user enable bob lets them again
sudo wabilink-server user remove bob
From a script, the password from a file or a secret store, never on the command line:
sudo wabilink-server user add carol --password-stdin < password.txt
Get-Content password.txt | .\wabilink-service user add carol --password-stdin
--no-password makes an account with no password: it cannot log in until it gets one with user passwd.
An account has no shares until it is given some (Shares).
What each account may use beyond its shares. Each needs its part of the server turned on as well (Settings).
sudo wabilink-server user admin ann yes # Server settings, in the app, on port 8010
sudo wabilink-server user terminal ann yes # terminals, once terminals-enabled is yes
sudo wabilink-server user login-terminal ann yes # login terminals, once login-terminals-enabled is yes
sudo wabilink-server user desktop ann yes # this machine's desktop, once desktop-enabled is yes
sudo wabilink-server user desktop-login ann yes # a login screen of its own (Linux, GNOME with GDM 46 and later)
sudo wabilink-server user tunnel ann nas-web yes # a tunnel, by its name
sudo wabilink-server user db ann reporting read # a database connection, at a level
sudo wabilink-server user rights ann # what each part gives them, their groups' too
Each of these is a right of one of the server's parts (modules), and can also be given by its own
name: user right NAME MODULE RIGHT VALUE. The terminals' rights are open and login,
the desktop's use and login, the tunnels' tunnels.
sudo wabilink-server user right ann terminals open yes
Groups are made, and given their shares, in Server settings, in the WabiLink app. Here, what every member is given:
sudo wabilink-server group list
sudo wabilink-server group rights support
sudo wabilink-server group right support desktop use yes
A TCP service on this machine or near it, reached by the people you allow through a local port of theirs. Tunnels are made here only; Server settings, in the app, give them to people.
sudo wabilink-server tunnel presets # the common services on this machine, with their ports
sudo wabilink-server tunnel add ssh ssh # this machine's SSH, as the tunnel "ssh"
sudo wabilink-server tunnel add nas-web 192.168.1.20:443 --description "The NAS's web page"
sudo wabilink-server tunnel list
sudo wabilink-server user tunnel ann nas-web yes
sudo wabilink-server tunnel remove nas-web
| Preset | Port on this machine | Service |
|---|---|---|
ssh | 22 | SSH |
http, https | 80, 443 | A web page |
web8080 | 8080 | A web app on 8080 |
postgres | 5432 | PostgreSQL |
mysql | 3306 | MySQL, MariaDB |
mssql | 1433 | Microsoft SQL Server |
redis | 6379 | Redis |
mongodb | 27017 | MongoDB |
Then, on someone's computer: wabilink tunnel -p work nas-web --local-port 8443, or the app's
Tunnels. A tunnel hands over the port itself: for a database, a database
connection keeps its password on the server and holds each person to a level.
PostgreSQL and MySQL (and MariaDB), opened by the server for the people you give a connection to. The database's address and password stay on the server. Connections are made on this machine only.
sudo wabilink-server db add reporting postgres db.internal:5432 --user wabilink_reporting --database reporting
# asks for the account's password
sudo wabilink-server db add shop mysql /run/mysqld/mysqld.sock --user wabilink_shop --database shop
sudo wabilink-server db test reporting # logs in as people's sessions will: version, TLS, what the account may do
sudo wabilink-server db list
sudo wabilink-server db password reporting # a new password for the account
sudo wabilink-server db remove shop
sudo wabilink-server user db ann reporting read # may query it
sudo wabilink-server user db bob reporting write --export yes # and change rows, and export them
sudo wabilink-server user db ann reporting none # taken away
| Level | May |
|---|---|
read | SELECT, SHOW, EXPLAIN, describing the database, in a read-only transaction |
write | and INSERT, UPDATE, DELETE, MERGE, transactions |
schema | and CREATE, ALTER, DROP of tables, views and functions; TRUNCATE |
admin | and roles and grants, other sessions, server settings, databases, maintenance |
--export yes lets rows out whole (export, dump); --import yes lets them in whole (a CSV import with
write, a restore with schema). Give the connection's account no more than the most anyone should do: the database holds
every session to that account's rights too.
sudo wabilink-server db set reporting --tls verify-full --ca /etc/ssl/db-ca.pem
sudo wabilink-server db set reporting --databases sales,stats # other databases sessions may move to; * for all
sudo wabilink-server db set reporting --max-rows 50000 --timeout 120 --log-text yes
| Option | Default | What it is |
|---|---|---|
--tls | verify-full on the network, prefer on this machine | disable, prefer, require, verify-ca or verify-full; --ca FILE for a database with a certificate of its own |
--max-rows | 10000 | Rows of a result |
--timeout | 60 | A statement's time, in seconds |
--max-value-kb | 1024 | A value; the rest is cut, and marked |
--max-result-mb | 64 | A result |
--max-sessions | 8 | Sessions per person on the connection |
--idle-minutes | 30 | An idle session is closed after |
--log-text | no | Log each statement's text too, passwords in it masked; every statement is logged either way, never its values |
--tools-dir | Where pg_dump or mysqldump is, if not on the PATH |
0 for a limit is its default.
The server's own settings, and those of its parts.
sudo wabilink-server config show # all of them, as they are now; --json for scripts
sudo wabilink-server config set terminals-enabled yes
sudo wabilink-server config set max-sessions-per-user 5
| Setting | Default | What it is |
|---|---|---|
file-port | 8009 | The port the apps connect on. From the next start. |
admin-port | 8010 | The admin port: Server settings, in the app. From the next start. |
private-share-path | UserShares in the data folder | Where each account's private share is kept. |
max-sessions-per-user | 3 | Sessions one account may have open at once. |
max-connections-per-session | 10 | Connections one session may open, 1 to 10; 0 is 10. From the next start. |
log-folder-limit-mb | 1024 | How big the log folder may grow, in MB; 0 is the default. |
shares-allow-system-folders | no | Whether a share may be a system folder. this machine only |
rendezvous-url | none | A rendezvous, for the apps to reach the server behind a router (below); none takes it away. this machine only |
rendezvous-admin | no | Whether the admin port is reached through the rendezvous too, past the machine's firewall and router. this machine only |
rendezvous-trust-relayed | no | Whether a relayed login's address, as the rendezvous gives it, is held to users' IP filters. Not trusted, it is unknown, and a user with IP filters is not let in relayed. this machine only |
wabione-machine-settings | no | Whether WabiOne's console may set what only this machine sets otherwise: the terminals' shell and privileged terminals, shares in system folders, the desktop's consent and locks. Set before registering. this machine only |
auto-update | yes | A newer version, signed by WabiLink's key, installed between 03:00 and 05:00 (below). |
terminals-enabled | no | Terminals offered at all; each account then needs user terminal. |
terminals-allow-privileged | no | Where the server runs as root or SYSTEM (the Windows service does), its terminals would too: refused unless yes. this machine only |
terminal-shell | picked | The terminals' shell. Not set: the account's login shell, else bash or sh; on Windows PowerShell 7, else Windows PowerShell, else cmd. this machine only |
max-terminals-per-user | 4 | Terminals one account may have open, 0 to 100; 0 is the default. |
max-terminals | 32 | Terminals open on the server in all, 0 to 1000; 0 is the default. |
terminal-max-processes | 256 | Processes per terminal, on Windows. On Linux the service's unit limits the server and its terminals together. |
terminal-max-memory-mb | 4096 | Memory per terminal, in MB, on Windows. |
login-terminals-enabled | no | Login terminals: an SSH login to this machine as one of its accounts, with that account's password; each WabiLink account then needs user login-terminal. |
terminals-beside-login-terminals | no | Ordinary terminals while login terminals are on. Both run as the server's account, and an ordinary terminal could read what is typed into a login terminal; off, ordinary terminals are refused while login terminals are on. this machine only |
login-terminal-ssh-host | localhost | The SSH server login terminals connect to. this machine only |
login-terminal-ssh-port | 22 | Its port; 0 is 22. this machine only |
desktop-enabled | no | This machine's desktop offered at all; each account then needs user desktop. |
desktop-user | none | Linux: the account whose session is shown; not set, what is on the machine's screen. desktop-setup sets it. |
desktop-consent | yes | Linux: ask the person at the machine before their open session is shown. this machine only |
desktop-lock-on-leave | yes | Lock a session viewers signed in to when the last viewer has gone. this machine only |
desktop-lock-at-login | no | Linux: lock an automatic login at once. desktop-setup --login sets it. this machine only |
this machine only: Server settings, in the app, show it and cannot change it, so that an administrator elsewhere cannot turn off a protection of the machine and of the person at it.
The server's parts: files, terminals, tunnels, desktop and
databases. Each is on unless turned off here.
sudo wabilink-server module list
sudo wabilink-server module off tunnels # refused from the next login, and taken from sessions open
sudo wabilink-server module on tunnels # offered again from the next login
A part turned off is gone from the apps altogether, whatever rights people have: on a server that should never offer it, turn it off rather than giving it to nobody.
This machine's own screen, seen and used from the app, inside the WabiLink session.
sudo wabilink-server config set desktop-enabled yes
sudo wabilink-server user desktop ann yes
On Windows that is all. On macOS the server also needs Screen & System Audio Recording and Accessibility in System Settings → Privacy & Security. On Linux a desktop agent runs in each session (the packages and the install script set it up), and GNOME on Wayland or any X11 session is shown.
sudo wabilink-server desktop-setup ann --login # ann logged in at boot on the machine's screen, locked at once
sudo wabilink-server desktop-setup ann # or: ann's own session at boot, on a virtual monitor, locked
sudo wabilink-server desktop-setup --off # either, stopped, and not at boot
sudo wabilink-server user desktop-login ann yes # or a login screen of its own for each viewer (GDM 46 and later)
sudo wabilink-server login-probe # whether this machine can show one
These are for Linux; switch to Linux and macOS above to see them.
Checking, on Linux: desktop-check in a desktop session opens it as the agent would and takes one
picture; sudo wabilink-server console-probe says whether the machine's screen can be read for its login and
lock screens. To turn the console helper off, with anyone connected cut off within a second:
sudo mkdir -p /etc/wabilink && sudo touch /etc/wabilink/console.disabled; the login helper, likewise,
with /etc/wabilink/login.disabled.
Registered with WabiOne, the server is managed in WabiOne's console: its people, shares and every setting, and people sign in with their WabiOne account. The console's Servers → Add server gives the code, good once for 15 minutes.
sudo wabilink-server register K7M2-QX9P-4HRT --name build-box # its name in the console; else the host name
sudo wabilink-server home # registered, with whom, managed, connected? --json for scripts
sudo wabilink-server unregister # forgotten: the server's own settings are back
From a release script or a CI pipeline, with no code to copy: an API token that may Register servers, made by an admin of the organization in the console's API tokens. It registers any number of servers until it expires (after 30 to 365 days, or never) or is revoked there. It goes on standard input, never on the command line, where every account on the machine could read it. Registered already, the server is left as it is: registering again would drop what the console set.
sudo wabilink-server home >/dev/null || printf '%s\n' "$WABIONE_REGISTRATION_TOKEN" | sudo wabilink-server register --token-stdin
.\wabilink-service home *> $null
if ($LASTEXITCODE -ne 0) { $env:WABIONE_REGISTRATION_TOKEN | .\wabilink-service register --token-stdin }
The token is a secret of the pipeline's, given to the step as an environment variable: in GitHub Actions,
env: WABIONE_REGISTRATION_TOKEN: ${{ secrets.WABIONE_REGISTRATION_TOKEN }}. A token WabiOne refuses - revoked
or expired - fails with exit 1, saying so. On AWS, the first-boot scripts do all of this, the token
read from Parameter Store.
--home https://wabione.example.com.The apps connect straight to the server where they can. Where they can't, a rendezvous introduces them, and both connect to each other through the routers (hole punching), with no port forwarded and no traffic through the rendezvous.
Registered with WabiOne, the server uses WabiOne's rendezvous, with nothing to set. Otherwise, with a rendezvous of your own:
sudo wabilink-server config set rendezvous-url https://rv.example.com:8443 # none takes it away
sudo wabilink-server home # the rendezvous, and whether it is connected
The server needs UDP 3478 out to the rendezvous. Some networks (some mobile and carrier networks) let no punch
through: from those, forward TCP 8009 on the router to the server, or use a VPN.
Let the app wake this machine from sleep (Wake-on-LAN), for good: its wired network cards' waking turned on, and kept on.
sudo wabilink-server wake-setup
sudo wabilink-server wake-setup --status # say how it is, change nothing
sudo wabilink-server wake-setup --off
A server updates itself: each night, between 03:00 and 05:00 its own time, it installs a newer version if there is one. The service restarts, so anyone connected is dropped for a few seconds and their app connects again.
sudo wabilink-server update --check # this version, the newest, and how this server is updated
sudo wabilink-server update # install the newest now
sudo wabilink-server config set auto-update no # never by itself; update still installs it
wabilink-update.timer, runs it as root, through dnf or apt
for the packages. macOS: a launchd job, com.wabilink.update; its log is
/Library/Logs/WabiLink/update.log.C:\ProgramData\WabiLink\Update.log.Installed as the guides say, the server runs as a service that starts at boot.
systemctl status wabilink
sudo systemctl restart wabilink # for the ports, and max-connections-per-session
journalctl -u wabilink -f # its log
Installed from the archive by hand: sudo wabilink-server install-systemd makes the wabilink
account, the data folder and the unit, and starts it (--no-start not yet);
uninstall-systemd removes it and keeps the data; systemd-unit prints the unit, to install it
yourself.
sudo launchctl print system/com.wabilink.server | grep state
sudo launchctl kickstart -k system/com.wabilink.server # restart it
tail -f /Library/Logs/WabiLink/server.log
sudo wabilink-server install-launchd installs the service and the desktop agent;
uninstall-launchd removes them and keeps the data.
.\wabilink-service status
.\wabilink-service restart # for the ports, and max-connections-per-session
.\wabilink-service stop
.\wabilink-service start
.\wabilink-service install --start registers the service, starting with Windows, as LocalSystem;
--account "NT SERVICE\WabiLink" runs it as an account of its own instead, and
--account NAME --password-stdin as a Windows account, its password on standard input (it is checked, and
the account given the right to run a service, before anything is installed). uninstall removes it
and keeps the data. Its log is in C:\ProgramData\WabiLink\Server\logs, and warnings and errors in the
Application event log, as WabiLink.
& '.\wabilink-setup-1.1.29-windows.exe' --quiet | Out-Host # install, or update what is installed
& '.\wabilink-setup-1.1.29-windows.exe' --quiet --account service | Out-Host # as NT SERVICE\WabiLink
'P@ssw0rd' | & '.\wabilink-setup-1.1.29-windows.exe' --quiet --account alex --password-stdin | Out-Host
& 'C:\Program Files\WabiLink\WabiLink Setup.exe' --uninstall --quiet | Out-Host # --delete-data: its users, settings and identity too
From a prompt opened as administrator, or a deployment tool that runs as one. --from FOLDER takes the
wabilink-server and wabilink-client zips from a folder (a share, say) instead of this site. It exits
0 when done, 1 when not (saying why), 2 for wrong options and 4 when not run as administrator, in
$LASTEXITCODE; what it did is in %TEMP%\WabiLink Setup.log. Setup is a program with a window:
| Out-Host is what makes PowerShell wait for it, and show what it says.
sudo wabilink-server run --port 9009 --admin-port 9010 -v
Until stopped, to try settings before installing it, with the service stopped (only one can hold the ports). While it runs,
type status, sessions, disconnect ID or disconnect USER, and
stop. --no-admin opens no admin port at all; --data-dir DIR runs it on another data
folder.
sudo wabilink-server identity # the fingerprint the apps check
sudo wabilink-server paths # where the data, identity and logs are
sudo wabilink-server version
The data folder holds the accounts, the settings and the identity key: keep it in your backups. A server reinstalled without it has a new identity, which every app is then asked to accept again.
A few things have no command here, and are set in the WabiLink app (This PC's server, on this machine; or Server settings, from your desk, on port
8010):