fix: the shell runs as the console account of each member of admins, a local account or the user's own POSIX account in the directory, which also signs in with SSH and sudo, instead of one web.shell_user.
Release / release (push) Successful in 28s
Release / release (push) Successful in 28s
This commit is contained in:
1 parent
2e1eb89f52
commit
ec93bc6a2d
12 files changed
+432
-51
No files matched your search
@@ -128,9 +128,9 @@ must have the type shown below; an unknown section or setting is an error.
|
||||
| `web` | `database` | string | | A PostgreSQL connection string for the refresh tokens; without it, the `vpn-router` database on this host that the web service creates |
|
||||
| `web` | `trusted_proxies` | list | the address the call came in on | Addresses whose `X-Forwarded-For` header names the client for the `/auth` rate limit and the Client IP of the status |
|
||||
| `web` | `status_content` | string | `basic` | What `/` and `/status` show: `basic`, `standard` or `full` (see Status web service) |
|
||||
| `web` | `shell` | boolean | `false` | `/shell` opens a login shell of `shell_user` for a member of `admins` (see The shell) |
|
||||
| `web` | `shell_user` | string | | The system user the shell runs as, not `root`; required by `shell` |
|
||||
| `web` | `shell` | boolean | `false` | `/shell` opens a login shell for a member of `admins` with console login (see The shell) |
|
||||
| `web` | `shell_idle_minutes` | integer | `15` | Minutes without a keystroke after which a shell is closed, 1 to 1440 |
|
||||
| `ssh` | `ldap_login` | boolean | `false` | sshd accepts the directory password of the console accounts in the directory (see Console login and SSH) |
|
||||
| `https` | `enabled` | boolean | `true` | Caddy serves the status web service and the Router Manager over HTTPS for `wan.local_fqdn` |
|
||||
| `https` | `email` | string | | The e-mail address of the Let's Encrypt account |
|
||||
| `https` | `web_port` | integer | `7444` | HTTPS port of the status web service |
|
||||
@@ -705,6 +705,7 @@ vpn-router-user otp-remove alice
|
||||
| `otp-new <name>` | A new TOTP secret and its `otpauth://` URI, issued by `wan.local_fqdn`, for an authenticator app; nothing is stored |
|
||||
| `otp-enrol <name> <code>` | Stores the secret read from standard input when the code is a current code of it, replacing a secret the user has |
|
||||
| `otp-remove <name>` | Removes the user's TOTP secret |
|
||||
| `console <name> (--posix \| --account LOCAL \| --off)` | Switches the console login of a member of `admins` on, as the user's own POSIX account or a local account, or off (see Console login and SSH) |
|
||||
|
||||
A user name is 1 to 32 lowercase letters, digits and hyphens, starting with a letter; a
|
||||
password has 8 to 128 characters; a first or last name has 1 to 64 printable characters; an
|
||||
@@ -725,6 +726,38 @@ the file.
|
||||
The certificate is also accepted by road-warrior (IKEv2 EAP-TLS) access, which checks
|
||||
certificates only, so `disable` does not affect it; `remove` revokes the certificate for both.
|
||||
|
||||
### Console login and SSH
|
||||
|
||||
A member of `admins` may have console login: the Router Manager's Shell page (see The shell),
|
||||
and, for the user's own POSIX account, SSH and sudo. Only root on the router switches it, with
|
||||
`vpn-router-user console` or a token of `vpn-router-token`, as for the group `admins`:
|
||||
|
||||
```sh
|
||||
vpn-router-user console alice --posix
|
||||
vpn-router-user console bob --account azureuser
|
||||
vpn-router-user console alice --off
|
||||
vpn-config-edit set ssh.ldap_login true
|
||||
```
|
||||
|
||||
- **Own POSIX account** (`--posix`): the user's entry becomes a `posixAccount` of the directory
|
||||
with the user's name, a uid from 20000 up, the local group `vpn-router-console` as its group,
|
||||
`/home/<name>` and `/bin/bash`. `nslcd` makes it known to the system over slapd's local socket
|
||||
and checks its password by binding as the user, so a user enrolled for TOTP types the password
|
||||
followed by a current code, failed logins count towards the lockout, and a disabled user cannot
|
||||
sign in. The home is created at the first login and kept when the user is removed. Members of
|
||||
`vpn-router-console` may run any command with sudo, with the same password. A local account of
|
||||
the same name is refused.
|
||||
- **Local account** (`--account`): the console runs as an existing local account with a uid from
|
||||
1000 to 19999, such as the VM's admin user; its SSH keys and sudo rights stay as they are.
|
||||
- **Off** (`--off`): the system no longer knows the user's own POSIX account, and its sessions
|
||||
end; its uid is kept for the next time. Leaving `admins`, or removing or renaming the group,
|
||||
switches the console login of the members off.
|
||||
|
||||
While `ssh.ldap_login` is `true`, setup lets sshd accept the password of the members of
|
||||
`vpn-router-console` (`/etc/ssh/sshd_config.d/vpn-router.conf`); other accounts keep sshd's
|
||||
settings. A password change is made in the Router Manager or with `vpn-router-user passwd`, not
|
||||
with `passwd`.
|
||||
|
||||
### Managing groups
|
||||
|
||||
`vpn-router-group` manages the groups. A group has a name, with the rules of a user name, an
|
||||
@@ -928,12 +961,12 @@ every service and tunnel while the public status page shows less.
|
||||
|
||||
### The shell
|
||||
|
||||
While `web.shell` is `true`, `/shell` gives a member of `admins` a login shell on the router, as
|
||||
the system user `web.shell_user`, for the Router Manager's Shell page. It is off by default and
|
||||
switched on and off on the router only:
|
||||
While `web.shell` is `true`, `/shell` gives a member of `admins` whose console login is on (see
|
||||
Console login and SSH) a login shell on the router, as the user's console account, for the
|
||||
Router Manager's Shell page. It is off by default and switched on and off on the router only:
|
||||
|
||||
```sh
|
||||
vpn-config-edit set web.shell_user azureuser
|
||||
vpn-router-user console alice --posix
|
||||
vpn-config-edit set web.shell true
|
||||
```
|
||||
|
||||
@@ -943,12 +976,12 @@ vpn-config-edit set web.shell true
|
||||
| `GET /shell?ticket=<ticket>` | a WebSocket handshake | the terminal |
|
||||
|
||||
`POST /shell` needs an access token of `/auth`, not one of `vpn-router-token`, and signs its user
|
||||
in again: a wrong password or code gets 403 and counts as a failed login. The ticket opens one
|
||||
in again: a wrong password or code gets 403 and counts as a failed login; it gets 403 too while
|
||||
`web.shell` is `false` or the user's console login is off. The ticket opens one
|
||||
shell for the same user within 30 seconds. Over the WebSocket, binary messages of the client
|
||||
are keystrokes, a text message `{"cols", "rows"}` sets the window size, and binary messages of
|
||||
the router are the terminal's output. The shell is a PAM login session of `web.shell_user`, run
|
||||
by `systemd-run` in a transient unit `vpn-router-shell-<id>`; sudo works as the user's sudoers
|
||||
entry allows. It is closed after `web.shell_idle_minutes` without a keystroke, when the shell
|
||||
the router are the terminal's output. The shell is a PAM login session of the console account,
|
||||
run by `systemd-run` in a transient unit `vpn-router-shell-<id>`; sudo works as for SSH. It is closed after `web.shell_idle_minutes` without a keystroke, when the shell
|
||||
exits, or when the connection closes; the router then sends a close frame with the reason. The
|
||||
journal of `vpn-router-web` records who opened each shell, from which address, in which unit,
|
||||
when it ended and why.
|
||||
@@ -984,7 +1017,7 @@ and answer bodies are JSON; a request body is at most 65536 bytes.
|
||||
|
||||
| Request | Body | Answer |
|
||||
| --- | --- | --- |
|
||||
| `GET /users` | | `{"users": [{"name", "manager_only", "service", "internal", "enabled", "locked", "certificate", "otp", "first_name", "last_name", "email"}, ...]}` |
|
||||
| `GET /users` | | `{"users": [{"name", "manager_only", "service", "internal", "enabled", "locked", "certificate", "otp", "console", "first_name", "last_name", "email"}, ...]}`; `console` is `null` or `{"enabled", "account", "local", "uid"}` |
|
||||
| `POST /users` | `{"name", "password", "first_name", "last_name", "email"}` for a VPN user; `{"name", "password", "email"?}` for a Manager-only account | 201 and the user |
|
||||
| `PUT /users/<name>` | any of `{"first_name", "last_name", "email"}`; for a Manager-only account only `{"email"}`, `""` removing it | the user |
|
||||
| `PUT /users/<name>/password` | `{"password": ...}` | the user |
|
||||
@@ -996,6 +1029,7 @@ and answer bodies are JSON; a request body is at most 65536 bytes.
|
||||
| `POST /users/<name>/otp` | | `{"name", "secret", "uri"}`, a new TOTP secret; nothing is stored |
|
||||
| `PUT /users/<name>/otp` | `{"secret", "code"}` | the user, once the code matches the secret |
|
||||
| `DELETE /users/<name>/otp` | | the user |
|
||||
| `PUT /users/<name>/console` | `{"enabled", "account"?}`; only with a token of `vpn-router-token` | the user |
|
||||
|
||||
A failure is `{"error": ...}` with 400 for an invalid request, 404 for a user that does not
|
||||
exist or is a service account, 409 for a user that exists and 500 otherwise. `/users` does not
|
||||
|
||||
Reference in new issue
Block a user