2021-12-01 23:42:10 +01:00
|
|
|
|
Galene is a videoconferencing server that is easy to deploy and requires
|
|
|
|
|
moderate server resources. It is described at <https://galene.org>.
|
|
|
|
|
|
|
|
|
|
|
2020-05-29 17:49:23 +02:00
|
|
|
|
# Installation
|
|
|
|
|
|
2021-08-06 16:59:46 +02:00
|
|
|
|
See the file INSTALL in this directory for installation instructions.
|
2020-05-29 17:49:23 +02:00
|
|
|
|
|
2021-05-10 23:24:18 +02:00
|
|
|
|
|
2021-01-08 15:36:23 +01:00
|
|
|
|
# Usage
|
|
|
|
|
|
|
|
|
|
## Locations
|
2020-05-31 23:16:08 +02:00
|
|
|
|
|
|
|
|
|
There is a landing page at the root of the server. It contains a form
|
|
|
|
|
for typing the name of a group, and a clickable list of public groups.
|
|
|
|
|
|
2023-04-04 23:05:52 +02:00
|
|
|
|
Groups are available under `/group/groupname/`. You may share this URL
|
2020-05-31 23:16:08 +02:00
|
|
|
|
with others, there is no need to go through the landing page.
|
|
|
|
|
|
2023-04-04 23:05:52 +02:00
|
|
|
|
Recordings can be accessed under `/recordings/groupname/`. This is only
|
2020-05-31 23:16:08 +02:00
|
|
|
|
available to the administrator of the group.
|
|
|
|
|
|
2021-04-30 20:33:23 +02:00
|
|
|
|
Some statistics are available under `/stats.json`, with a human-readable
|
|
|
|
|
version at `/stats.html`. This is only available to the server administrator.
|
2020-05-31 23:16:08 +02:00
|
|
|
|
|
2021-05-10 23:24:18 +02:00
|
|
|
|
|
2023-04-04 23:05:52 +02:00
|
|
|
|
## Main interface
|
|
|
|
|
|
|
|
|
|
After logging in, the user is confronted with the main interface.
|
|
|
|
|
|
|
|
|
|
### Buttons
|
|
|
|
|
|
|
|
|
|
There are up to three buttons at the top. The *Enable*/*Disable* button
|
|
|
|
|
enables either or both the camera and the microphone (depending on the
|
|
|
|
|
options set in the side menu, see below). The *Mute* button mutes or
|
|
|
|
|
unmutes the microphone. The *Share Screen* button shares the screen or
|
|
|
|
|
a window.
|
|
|
|
|
|
|
|
|
|
### Side menu
|
2021-01-08 15:36:23 +01:00
|
|
|
|
|
|
|
|
|
There is a menu on the right of the user interface. This allows choosing
|
|
|
|
|
the camera and microphone and setting the video throughput. The
|
|
|
|
|
*Blackboard mode* checkbox increases resolution and sacrifices framerate
|
|
|
|
|
in favour of image quality. The *Play local file* dialog allows streaming
|
|
|
|
|
a video from a local file.
|
2020-05-31 23:16:08 +02:00
|
|
|
|
|
2023-04-04 23:05:52 +02:00
|
|
|
|
### User list
|
|
|
|
|
|
|
|
|
|
There is a user list on the left. Clicking on a user opens a menu with
|
|
|
|
|
actions that can be applied to that user. Clicking on ones own username
|
|
|
|
|
opens a menu with actions that are global to the group.
|
2021-05-10 23:24:18 +02:00
|
|
|
|
|
2023-04-04 23:05:52 +02:00
|
|
|
|
### Text box
|
2021-01-08 15:36:23 +01:00
|
|
|
|
|
2023-04-04 23:05:52 +02:00
|
|
|
|
Typing a string in the text box at the bottom of the chat pane sends
|
|
|
|
|
a broadcast message to all of the users in the group.
|
|
|
|
|
|
|
|
|
|
Typing a line starting with a slash `/` in the text box causes a command
|
|
|
|
|
to be sent to the server. Type `/help` to get the list of available
|
|
|
|
|
commands; the output depends on whether you are an operator or not.
|
2020-05-29 17:49:23 +02:00
|
|
|
|
|
|
|
|
|
|
2021-10-26 20:10:24 +02:00
|
|
|
|
# The global configuration file
|
|
|
|
|
|
|
|
|
|
The server may be configured in the JSON file `data/config.json`. This
|
|
|
|
|
file may look as follows:
|
|
|
|
|
|
|
|
|
|
{
|
2023-05-16 18:54:35 +02:00
|
|
|
|
"admin":[{"username":"root","password":"secret"}],
|
|
|
|
|
"canonicalHost": "galene.example.org"
|
2021-10-26 20:10:24 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
The fields are as follows:
|
|
|
|
|
|
|
|
|
|
- `admin` defines the users allowed to look at the `/stats.html` file; it
|
|
|
|
|
has the same syntax as user definitions in groups (see below).
|
2023-07-10 20:40:42 +02:00
|
|
|
|
- `publicServer`: if true, then cross-origin access to the server is
|
|
|
|
|
allowed. This is safe if the server is on the public Internet, but not
|
|
|
|
|
necessarily so if it is on a private network.
|
2023-04-04 23:05:52 +02:00
|
|
|
|
- `proxyURL`: if running behind a reverse proxy, this specifies the
|
|
|
|
|
address of the proxy.
|
2022-10-21 13:28:11 +02:00
|
|
|
|
- `canonicalHost`: the canonical name of the host running the server; this
|
|
|
|
|
will cause clients to be redirected if they use a different hostname to
|
|
|
|
|
access the server.
|
2021-10-26 20:10:24 +02:00
|
|
|
|
|
|
|
|
|
|
2021-08-06 16:59:46 +02:00
|
|
|
|
# Group definitions
|
2021-01-08 15:36:23 +01:00
|
|
|
|
|
|
|
|
|
Groups are defined by files in the `./groups` directory (this may be
|
|
|
|
|
configured by the `-groups` command-line option, try `./galene -help`).
|
|
|
|
|
The definition for the group called *groupname* is in the file
|
2021-01-26 22:59:19 +01:00
|
|
|
|
`groups/groupname.json`; it does not contain the group name, which makes
|
2021-01-08 15:36:23 +01:00
|
|
|
|
it easy to copy or link group definitions. You may use subdirectories:
|
|
|
|
|
a file `groups/teaching/networking.json` defines a group called
|
2021-05-22 16:58:09 +02:00
|
|
|
|
*teaching/networking*.
|
2021-01-08 15:36:23 +01:00
|
|
|
|
|
2023-05-03 14:47:06 +02:00
|
|
|
|
|
|
|
|
|
## Examples
|
|
|
|
|
|
2021-08-06 16:59:46 +02:00
|
|
|
|
A typical group definition file looks like this:
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
"op":[{"username":"jch","password":"1234"}],
|
|
|
|
|
"allow-recording": true,
|
|
|
|
|
"allow-subgroups": true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
This defines a group with the operator (administrator) username *jch* and
|
|
|
|
|
password *1234*, empty username and password for presenters (ordinary
|
|
|
|
|
users with the right to enable their camera and microphone). The
|
|
|
|
|
`allow-recording` entry says that the operator is allowed to record videos
|
|
|
|
|
to disk, and the `allow-subgroups` entry says that subgroups will be
|
2023-05-03 14:47:06 +02:00
|
|
|
|
created automatically. This particular group does not allow password
|
|
|
|
|
login for ordinary users, and is suitable if you use invitations (see
|
|
|
|
|
*Stateful Token* below) for ordinary users.
|
|
|
|
|
|
|
|
|
|
In order to allow password login for ordinary users, add a list of users
|
|
|
|
|
as the entry `presenter`:
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
"op": [{"username":"jch","password":"1234"}],
|
|
|
|
|
"presenter": [{"username":"john", "password": "secret"}]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
If the group is to be publicly accessible, you may allow logins with any
|
|
|
|
|
username and an empty password:
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
"op": [{"username":"jch","password":"1234"}],
|
|
|
|
|
"presenter": [{}],
|
|
|
|
|
"public": true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
The empty dictionary `{}` is a wildcard entry: it matches any username and
|
|
|
|
|
any password. Setting `public` causes the group to be displayed in the
|
|
|
|
|
list of public groups on the landing page
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## Reference
|
2021-08-06 16:59:46 +02:00
|
|
|
|
|
2023-05-03 14:47:06 +02:00
|
|
|
|
Every group definition file contains a single JSON directory (a list of
|
|
|
|
|
entries between `{' and `}'). All fields are optional, but unless you
|
|
|
|
|
specify at least one user definition (`op`, `presenter`, or `other`),
|
|
|
|
|
nobody will be able to join the group. The following fields are allowed:
|
2020-05-29 17:49:23 +02:00
|
|
|
|
|
|
|
|
|
- `op`, `presenter`, `other`: each of these is an array of user
|
2021-10-29 23:37:05 +02:00
|
|
|
|
definitions (see *Authorisation* below) and specifies the users allowed
|
|
|
|
|
to connect respectively with operator privileges, with presenter
|
|
|
|
|
privileges, and as passive listeners;
|
2022-02-19 23:58:31 +01:00
|
|
|
|
- `authKeys`, `authServer` and `authPortal`: see *Authorisation* below;
|
2023-05-03 14:47:06 +02:00
|
|
|
|
- `public`: if true, then the group is listed on the landing page;
|
2021-07-16 19:41:00 +02:00
|
|
|
|
- `displayName`: a human-friendly version of the group name;
|
2020-09-24 22:03:41 +02:00
|
|
|
|
- `description`: a human-readable description of the group; this is
|
|
|
|
|
displayed on the landing page for public groups;
|
2021-01-13 23:00:48 +01:00
|
|
|
|
- `contact`: a human-readable contact for this group, such as an e-mail
|
|
|
|
|
address;
|
|
|
|
|
- `comment`: a human-readable string;
|
2020-05-29 17:49:23 +02:00
|
|
|
|
- `max-clients`: the maximum number of clients that may join the group at
|
|
|
|
|
a time;
|
2020-10-08 14:38:33 +02:00
|
|
|
|
- `max-history-age`: the time, in seconds, during which chat history is
|
|
|
|
|
kept (default 14400, i.e. 4 hours);
|
2020-05-30 01:18:00 +02:00
|
|
|
|
- `allow-recording`: if true, then recording is allowed in this group;
|
2023-04-10 14:42:01 +02:00
|
|
|
|
- `unrestricted-tokens`: if true, then ordinary users (without the "op"
|
|
|
|
|
privilege) are allowed to create tokens;
|
2021-01-08 15:36:23 +01:00
|
|
|
|
- `allow-anonymous`: if true, then users may connect with an empty username;
|
2020-11-22 19:54:54 +01:00
|
|
|
|
- `allow-subgroups`: if true, then subgroups of the form `group/subgroup`
|
2021-01-08 15:36:23 +01:00
|
|
|
|
are automatically created when first accessed;
|
2021-01-14 03:56:37 +01:00
|
|
|
|
- `autolock`: if true, the group will start locked and become locked
|
|
|
|
|
whenever there are no clients with operator privileges;
|
2021-01-17 21:29:07 +01:00
|
|
|
|
- `autokick`: if true, all clients will be kicked out whenever there are
|
2021-01-17 21:52:26 +01:00
|
|
|
|
no clients with operator privileges; this is not recommended, prefer
|
|
|
|
|
the `autolock` option instead;
|
2020-09-10 13:55:57 +02:00
|
|
|
|
- `redirect`: if set, then attempts to join the group will be redirected
|
2021-01-08 15:36:23 +01:00
|
|
|
|
to the given URL; most other fields are ignored in this case;
|
2020-12-25 17:33:44 +01:00
|
|
|
|
- `codecs`: this is a list of codecs allowed in this group. The default
|
2023-09-01 16:00:09 +02:00
|
|
|
|
is `["vp8", "opus"]`.
|
2021-01-08 15:36:23 +01:00
|
|
|
|
|
|
|
|
|
Supported video codecs include:
|
|
|
|
|
|
2023-09-01 16:00:09 +02:00
|
|
|
|
- `"vp8"` (compatible with all supported browsers);
|
|
|
|
|
- `"vp9"` (better video quality, but incompatible with Safari);
|
|
|
|
|
- `"av1"` (even better video quality, only supported by some browsers,
|
|
|
|
|
recording is not supported, SVC is not supported);
|
2021-07-30 16:02:36 +02:00
|
|
|
|
- `"h264"` (incompatible with Debian and with some Android devices, SVC
|
2021-07-30 13:55:04 +02:00
|
|
|
|
is not supported).
|
2021-01-08 15:36:23 +01:00
|
|
|
|
|
|
|
|
|
Supported audio codecs include `"opus"`, `"g722"`, `"pcmu"` and `"pcma"`.
|
2021-07-30 13:55:04 +02:00
|
|
|
|
Only Opus can be recorded to disk. There is no good reason to use
|
|
|
|
|
anything except Opus.
|
2020-05-29 17:49:23 +02:00
|
|
|
|
|
2021-10-29 23:37:05 +02:00
|
|
|
|
|
|
|
|
|
## Client Authorisation
|
|
|
|
|
|
2023-04-04 23:05:52 +02:00
|
|
|
|
Galene implements three authorisation methods: a simple username/password
|
|
|
|
|
authorisation scheme, a scheme using stateful tokens and a mechanism based
|
|
|
|
|
on cryptographic tokens that are generated by an external server. The
|
|
|
|
|
former two mechanism are intended to be used in standalone installations,
|
|
|
|
|
while the server-based mechanism is designed to allow easy integration
|
|
|
|
|
with an existing authorisation infrastructure (such as LDAP, OAuth2, or
|
|
|
|
|
even Unix passwords).
|
2021-10-29 23:37:05 +02:00
|
|
|
|
|
|
|
|
|
### Password authorisation
|
|
|
|
|
|
|
|
|
|
When password authorisation is used, authorised usernames and password are
|
|
|
|
|
defined directly in the group configuration file, in the `op`, `presenter`
|
|
|
|
|
and `other` arrays. Each member of the array is a dictionary, that may
|
|
|
|
|
contain the fields `username` and `password`:
|
|
|
|
|
|
|
|
|
|
- if `username` is present, then the entry only matches clients that
|
|
|
|
|
specify this exact username; otherwise, any username matches;
|
|
|
|
|
- if `password` is present, then the entry only matches clients that
|
|
|
|
|
specify this exact password; otherwise, any password matches.
|
|
|
|
|
|
|
|
|
|
For example, the entry
|
2020-05-29 17:49:23 +02:00
|
|
|
|
|
2021-01-08 15:36:23 +01:00
|
|
|
|
{"username": "jch", "password": "1234"}
|
|
|
|
|
|
2021-10-29 23:37:05 +02:00
|
|
|
|
specifies username *jch* with password *1234*, while
|
2021-01-08 15:36:23 +01:00
|
|
|
|
|
|
|
|
|
{"password": "1234"}
|
2020-05-29 17:49:23 +02:00
|
|
|
|
|
2021-10-29 23:37:05 +02:00
|
|
|
|
allows any username with password *1234*, and
|
2020-05-29 17:49:23 +02:00
|
|
|
|
|
2021-01-08 15:36:23 +01:00
|
|
|
|
{}
|
2020-05-29 17:49:23 +02:00
|
|
|
|
|
2021-10-29 23:37:05 +02:00
|
|
|
|
allows any username with any password.
|
|
|
|
|
|
|
|
|
|
By default, empty usernames are forbidden; set the `allow-anonymous`
|
|
|
|
|
option to allow empty usernames. By default, recording is forbidden;
|
|
|
|
|
specify the `allow-recording` option to allow operators to record.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### Hashed passwords
|
2021-01-08 15:36:23 +01:00
|
|
|
|
|
|
|
|
|
If you don't wish to store cleartext passwords on the server, you may
|
2021-10-29 23:37:05 +02:00
|
|
|
|
generate hashed passwords with the `galene-password-generator` utility. A
|
2021-01-08 15:36:23 +01:00
|
|
|
|
user entry with a hashed password looks like this:
|
2020-05-29 17:49:23 +02:00
|
|
|
|
|
2020-11-29 14:26:42 +01:00
|
|
|
|
{
|
|
|
|
|
"username": "jch",
|
|
|
|
|
"password": {
|
|
|
|
|
"type": "pbkdf2",
|
|
|
|
|
"hash": "sha-256",
|
|
|
|
|
"key": "f591c35604e6aef572851d9c3543c812566b032b6dc083c81edd15cc24449913",
|
|
|
|
|
"salt": "92bff2ace56fe38f",
|
|
|
|
|
"iterations": 4096
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-05-29 17:49:23 +02:00
|
|
|
|
|
2023-04-04 23:05:52 +02:00
|
|
|
|
### Stateful tokens
|
|
|
|
|
|
|
|
|
|
Stateful tokens allow to temporarily grant access to a user. In order to
|
|
|
|
|
generate a stateful token, the group administrator types
|
|
|
|
|
|
|
|
|
|
/invite user period
|
|
|
|
|
|
|
|
|
|
where `user` is the username granted to the temporary user, and `period`
|
|
|
|
|
is the time period for which the token will be valid (for example `2d`
|
|
|
|
|
meaning 2 days). The server replies with a link, valid the given time
|
|
|
|
|
period, that may be sent to the temporary user for example by e-mail.
|
|
|
|
|
|
|
|
|
|
Tokens may also be granted without imposing a specific username:
|
|
|
|
|
|
|
|
|
|
/invite '' 2d
|
|
|
|
|
|
|
|
|
|
Stateful tokens are revokable (use the `/revoke` command) and their
|
|
|
|
|
lifetime may be extended (use the `/reinvite` command).
|
|
|
|
|
|
2021-05-10 23:24:18 +02:00
|
|
|
|
|
2021-10-29 23:37:05 +02:00
|
|
|
|
### Authorisation servers
|
|
|
|
|
|
|
|
|
|
Galene is able to delegate authorisation decisions to an external
|
|
|
|
|
authorisation server. This makes it possible to integrate Galene with an
|
|
|
|
|
existing authentication and authorisation infrastructure, such as LDAP,
|
|
|
|
|
OAuth2 or even Unix passwords.
|
|
|
|
|
|
|
|
|
|
When an authorisation server is used, the group configuration file
|
2022-02-19 23:58:31 +01:00
|
|
|
|
specifies one or more public keys in JWK format. In addition, it may
|
|
|
|
|
specify either an authorisation server or an authorisation portal.
|
2021-10-29 23:37:05 +02:00
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
"authKeys": [{
|
|
|
|
|
"kty": "oct",
|
|
|
|
|
"alg": "HS256",
|
|
|
|
|
"k": "MYz3IfCq4Yq-UmPdNqWEOdPl4C_m9imHHs9uveDUJGQ",
|
|
|
|
|
"kid": "20211030"
|
|
|
|
|
}, {
|
|
|
|
|
"kty": "EC",
|
|
|
|
|
"alg": "ES256",
|
|
|
|
|
"crv": "P-256",
|
|
|
|
|
"x": "dElK9qBNyCpRXdvJsn4GdjrFzScSzpkz_I0JhKbYC88",
|
|
|
|
|
"y": "pBhVb37haKvwEoleoW3qxnT4y5bK35_RTP7_RmFKR6Q",
|
|
|
|
|
"kid": "20211101"
|
|
|
|
|
}]
|
2022-02-19 23:58:31 +01:00
|
|
|
|
"authServer": "https://auth.example.org",
|
2021-10-29 23:37:05 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
The `kid` field serves to distinguish among multiple keys, and must match
|
|
|
|
|
the value provided by the authorisation server. If the server doesn't
|
|
|
|
|
provide a `kid`, the first key with a matching `alg` field will be used.
|
|
|
|
|
|
2022-02-19 23:58:31 +01:00
|
|
|
|
If an authorisation server is specified, then the default client, after it
|
|
|
|
|
prompts for a password, will request a token from the authorisation server
|
|
|
|
|
and will join the group using token authentication. The password is never
|
|
|
|
|
communicated to the server.
|
|
|
|
|
|
|
|
|
|
If an authorisation portal is specified, then the default client will
|
|
|
|
|
redirect initial client connections to the authorisation portal. The
|
|
|
|
|
authorisation portal is expected to authorise the client and then redirect
|
|
|
|
|
it to Galene with the `username` and `token` query parameters set.
|
|
|
|
|
|
2021-10-29 23:37:05 +02:00
|
|
|
|
|
2021-01-24 16:57:26 +01:00
|
|
|
|
# Further information
|
|
|
|
|
|
|
|
|
|
Galène's web page is at <https://galene.org>.
|
|
|
|
|
|
2021-08-02 02:50:29 +02:00
|
|
|
|
Answers to common questions and issues are at <https://galene.org/faq.html>.
|
2021-01-24 16:57:26 +01:00
|
|
|
|
|
2021-05-10 23:24:18 +02:00
|
|
|
|
|
2021-01-18 20:24:52 +01:00
|
|
|
|
-- Juliusz Chroboczek <https://www.irif.fr/~jch/>
|