Add a local unix socket for root on the server
jarld also listens on /run/jarl/jarl.sock (socket in jarl.yaml). Requests on it from root or jarld's own user need no token and act as an administrator; the kernel's SO_PEERCRED says who is connecting, and anyone else must send a token. The jarl CLI uses the socket when no server is configured, or with -s local, so 'sudo jarl status' works on the server with nothing set up and a lost token or password never locks root out. Changes are audited under the system user's name via "socket". The systemd unit creates /run/jarl (0750). Socket paths over 107 bytes are refused with a clear message. The docs explain the socket and what happens when a token is revoked. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
f528c2aa9c
commit
cf49df0346
22 files changed
+570
-26
No files matched your search
+49
-1
@@ -7,6 +7,7 @@
|
||||
| People in the web UI | Username + password → session cookie | argon2id password hashes. The session cookie is HttpOnly and SameSite=Strict and lasts 12h (2h idle). Every change also needs the session's CSRF token, which the UI sends in `X-CSRF-Token`. Changing a password logs out the user's other sessions. |
|
||||
| CLI, scripts, certbot | API token: `Authorization: Bearer jarl_...` | Shown once at creation, stored hashed. Optional expiry. Revocable. Last use time and IP are recorded. |
|
||||
| lego / Traefik (`httpreq`) | HTTP Basic: the token's user and the API token | Only on `/api/v1/acme/httpreq/...`, only when `acme.httpreq.enabled` is set, and by default only over HTTPS ([acme.md](acme.md)). The token's grants apply as usual. |
|
||||
| Root on the server, with the CLI | jarld's local socket (`/run/jarl/jarl.sock`): no token | `sudo jarl ...` with no server configured. The kernel tells jarld which system user is connecting; root and the `jarl` user are administrators, anyone else must send a token. Audited as the system user (e.g. `root`) via `socket`. See [The local socket](#the-local-socket). |
|
||||
| Root on the server | `jarld` subcommands (`init`, `user`, `import`, `adopt`, `check`, `resync`, `backup`) | Work directly on the database. They are for bootstrapping and recovery, and are audited as "local". |
|
||||
|
||||
API tokens are how you give a script, a tool or a person limited access:
|
||||
@@ -161,9 +162,56 @@ In the web UI, the **Rotate** button next to each token asks how long the
|
||||
old secret should keep working and how long the token should last, then
|
||||
shows the new secret once.
|
||||
|
||||
## The local socket
|
||||
|
||||
jarld also listens on a unix socket, `/run/jarl/jarl.sock` (`socket` in
|
||||
jarl.yaml; systemd creates `/run/jarl`). It serves the same API, but a
|
||||
request on it without a token is trusted by **who sent it**: the kernel
|
||||
reports the connecting process's user (`SO_PEERCRED`), and
|
||||
|
||||
| Connecting user | Without a token | With a token |
|
||||
|--|--|--|
|
||||
| root | administrator | the token's permissions |
|
||||
| `jarl` (jarld's own user) | administrator | the token's permissions |
|
||||
| anyone else | refused (401) | the token's permissions |
|
||||
|
||||
This gives root nothing it doesn't already have: root can read Jarl's
|
||||
database, run `jarld user token` and edit named.conf directly. What it adds
|
||||
is convenience and a way back in: on the server, `sudo jarl status` and
|
||||
every other command work with nothing configured and no token stored in a
|
||||
file, even after every token has been revoked and every password
|
||||
forgotten.
|
||||
|
||||
* The socket file is mode 0600 in a 0750 directory owned by `jarl`, so
|
||||
other users can't even connect; the user check doesn't depend on that.
|
||||
* Changes made this way are in the history and audit log under the system
|
||||
user's name (`root`) with `socket` as the method. That name isn't a Jarl
|
||||
user, so it has no tokens of its own: `sudo jarl token create laptop
|
||||
--user admin` makes one for a real user.
|
||||
* The CLI uses the socket only when no server is configured at all, or
|
||||
with `-s local`, so a configured server is never silently swapped for
|
||||
the local one ([cli.md](cli.md#on-the-server-itself)).
|
||||
* Turn it off with `socket: ""` in jarl.yaml.
|
||||
|
||||
## Recovering access
|
||||
|
||||
On the server, as root or the `jarl` user:
|
||||
Revoking a token never locks you out: tokens and web sessions are
|
||||
separate. Revoking the token your CLI uses stops only the programs that
|
||||
use it; you stay logged in to the web UI with your password, with all your
|
||||
rights, and can make a new token under Account → API tokens. Jarl also
|
||||
refuses to delete, disable or demote the last administrator.
|
||||
|
||||
On the server, root can always use the CLI through the local socket,
|
||||
without a token:
|
||||
|
||||
```sh
|
||||
sudo jarl whoami
|
||||
sudo jarl token create laptop --user admin # a new token for admin
|
||||
sudo jarl user update admin --password # a new password
|
||||
```
|
||||
|
||||
The `jarld` subcommands work even when jarld isn't running. As root or the
|
||||
`jarl` user:
|
||||
|
||||
```sh
|
||||
sudo -u jarl jarld user list
|
||||
|
||||
Reference in new issue
Block a user