diff --git a/CHANGELOG.md b/CHANGELOG.md index ee889cf..7abe08c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ Each release is tagged in Git and on the Docker repository Backwards-incompatible database schema changes happen on on major version upgrades, e.g. `0.6.x` -> `0.7.x`. The config file format and -[API](design/api.md) currently have no stability guarantees, so they may change +[API](ref/api.md) currently have no stability guarantees, so they may change even on minor releases, e.g. `0.7.5` -> `0.7.6`. ## unreleased @@ -28,7 +28,7 @@ even on minor releases, e.g. `0.7.5` -> `0.7.6`. * expanded `POST /users/` endpoint, including password and permissions. * `DELETE /users/` endpoint to delete a user -* improved API documentation in `design/api.md`. +* improved API documentation in [`ref/api.md`](ref/api.md). ## 0.7.5 (2022-05-09) diff --git a/README.md b/README.md index ca68200..8a0a000 100644 --- a/README.md +++ b/README.md @@ -66,11 +66,15 @@ could use to make this possible: with [GPL-3.0-linking-exception](https://spdx.org/licenses/GPL-3.0-linking-exception.html) for OpenSSL. * [Change log](CHANGELOG.md) / release notes. -* [Guides](guide/) +* [Guides](guide/), including: * [Installing](guide/install.md) * [Building from source](guide/build.md) + * [Securing Moonfire NVR and exposing it to the Internet](guide/secure.md) * [UI Development](guide/developing-ui.md) * [Troubleshooting](guide/troubleshooting.md) +* [References](ref/), including: + * [Configuration file](refs/config.md) + * [JSON API](refs/api.md) * [Design documents](design/) * [Wiki](https://github.com/scottlamb/moonfire-nvr/wiki) has hardware recommendations, notes on several camera models, etc. Please add more! diff --git a/design/README.md b/design/README.md new file mode 100644 index 0000000..bd2fb45 --- /dev/null +++ b/design/README.md @@ -0,0 +1,2 @@ +Design documents and [Architectural Decision Records](https://adr.github.io/) +for Moonfire NVR. Meant for developers. diff --git a/design/glossary.md b/design/glossary.md index d44bc7b..c614973 100644 --- a/design/glossary.md +++ b/design/glossary.md @@ -33,8 +33,9 @@ Source: https://www.best-microcontroller-projects.com/ppm.html *recording:* the video from a (typically 1-minute) portion of an RTSP session. RTSP sessions are divided into recordings as a detail of the storage schema. See [schema.md](schema.md) for details. This concept is exposed -to the frontend code through the API; see [api.md](api.md). It's not exposed in -the user interface; videos are reconstructed from segments automatically. +to the frontend code through the API; see [../ref/api.md](../ref/api.md). It's +not exposed in the user interface; videos are reconstructed from segments +automatically. *run:* all the recordings from a single RTSP session. These are all from the same *stream* and could be reassembled into a single video with no gaps. If the @@ -51,7 +52,8 @@ sample files for one or more streams. Typically there is one directory per disk. *segment:* part or all of a recording. An API request might ask for a video of recordings 1–4 starting 80 seconds in. If each recording is exactly 60 seconds, this would correspond to three segments: recording 2 from 20 seconds in to -the end, all of recording 3, and all of recording 4. See [api.md](api.md). +the end, all of recording 3, and all of recording 4. See +[../ref/api.md](../ref/api.md). *session:* a set of authenticated Moonfire NVR requests defined by the use of a given credential (`s` cookie). Each user may have many credentials and thus @@ -60,9 +62,10 @@ nothing to do with RTSP sessions; those more closely match a *run*. *signal:* a timeseries with an enum value. Signals might represent a camera's motion detection or day/night status. They could also represent an external -input such as a burglar alarm system's zone status. See [api.md](api.md). -Note signals are still under development and not yet exposed in Moonfire NVR's -UI. See [#28](https://github.com/scottlamb/moonfire-nvr/issues/28) for more +input such as a burglar alarm system's zone status. See +[../ref/api.md](../ref/api.md). Note signals are still under development and +not yet exposed in Moonfire NVR's UI. See +[#28](https://github.com/scottlamb/moonfire-nvr/issues/28) for more information. *stream:* the "main" or "sub" stream from a given camera. Moonfire NVR expects diff --git a/guide/README.md b/guide/README.md new file mode 100644 index 0000000..35409f7 --- /dev/null +++ b/guide/README.md @@ -0,0 +1 @@ +Guides to using and contributing to Moonfire NVR. diff --git a/guide/install.md b/guide/install.md index a1b06ab..7bac1b2 100644 --- a/guide/install.md +++ b/guide/install.md @@ -67,7 +67,7 @@ $ sudo nano /usr/local/bin/nvr $ sudo chmod a+rx /usr/local/bin/nvr ``` -`/etc/moonfire-nvr.toml`: +`/etc/moonfire-nvr.toml` (see [ref/config.md](../ref/config.md) for more explanation): ```toml [[binds]] ipv4 = "0.0.0.0:8080" diff --git a/guide/secure.md b/guide/secure.md index 5fa8757..67ad4be 100644 --- a/guide/secure.md +++ b/guide/secure.md @@ -182,6 +182,8 @@ This change has two effects: and `X-Forwarded-Proto` headers as added by the webserver configuration in the next section. +See also [ref/config.md](../ref/config.md) for more about the configuration file. + If the webserver is running on the same machine as Moonfire NVR, you might also change `--publish=8080:8080` to `--publish=127.0.0.1:8080:8080` in your `/usr/local/bin/nvr` script, preventing other machines on the network from diff --git a/ref/README.md b/ref/README.md new file mode 100644 index 0000000..a6e1f0a --- /dev/null +++ b/ref/README.md @@ -0,0 +1 @@ +Reference documentation for Moonfire NVR. diff --git a/design/api.md b/ref/api.md similarity index 100% rename from design/api.md rename to ref/api.md diff --git a/ref/config.md b/ref/config.md new file mode 100644 index 0000000..01773b5 --- /dev/null +++ b/ref/config.md @@ -0,0 +1,87 @@ +# Moonfire NVR Configuration File + +Moonfire NVR has a small runtime configuration file. By default it's called +`/etc/moonfire-nvr.toml`. You can specify a different path on the commandline, +e.g. as follows: + +```console +$ moonfire-nvr run --config /path/to/config.toml +``` + +`.toml` refers to [Tom's Obvious Minimal Language](https://toml.io/en/). This +is a line-based config format with `[section]` boundaries and `# comment` +lines, meant to be more easily edited by humans. + +## Examples + +The following is a starter config which allows connecting and viewing video with no authentication: + +```toml +[[binds]] +ipv4 = "0.0.0.0:8080" +allowUnauthenticatedPermissions = { viewVideo = true } + +[[binds]] +unix = "/var/lib/moonfire-nvr/sock" +ownUidIsPrivileged = true +``` + +The following is for a more secure setup with authentication and a TLS proxy +server in front, as in [guide/secure.md](../guide/secure.md). + +```toml +[[binds]] +ipv4 = "0.0.0.0:8080" +trustForwardHeaders = true + +[[binds]] +unix = "/var/lib/moonfire-nvr/sock" +ownUidIsPrivileged = true +``` + +## Reference + +At the top level, before any `[[bind]]` lines, the following +keys are understood: + +* `dbDir`: path to the SQLite database directory. Defaults to `/var/lib/moonfire-nvr/db`. +* `uiDir`: path to the UI to serve. Defaults to `/usr/local/lib/moonfire-nvr/ui`. +* `workerThreads`: number of [tokio](https://tokio.rs/) worker threads to + use. Defaults to the number of CPUs on the system. This normally does not + need to be changed, but reducing it may slightly lower idle CPU usage. + +A useful config will bind at least one socket for clients to connect to. Each +should start with a `[[binds]]` line and specify one of the following: + +* `ipv4`: an IPv4 socket address. `0.0.0.0:8080` would allow connections from outside the machine; + `127.0.0.1:8080` would allow connections only from the local host. +* `ipv6`: an IPv6 socket address. [::0]:8080` would allow connections from outside the machine; + `[[::1]:8080` would allow connections from only the local host. +* `unix`: a path in the local filesystem where a UNIX-domain socket can be created. Permissions on the + enclosing directories control which users are allowed to connect to it. Web browsers typically don't + support directly connecting to UNIX domain sockets, but other tools do, e.g.: + * `curl --unix-socket /var/lib/moonfire-nvr/sock http://nvr/api/` will + issue a request from the commandline. (The hostname in the URL doesn't + matter.) + * `ssh -L localhost:8080:/var/lib/moonfire-nvr/sock moonfire-nvr@nvr-host` + will allow a web browser on your local machine to connect to the + Moonfire NVR instance on `nvr-host` via https://localhost:8080/. If + `ownUidIsPrivileged` is specified (see below), it will additionally + have all permissions. + +Additional options within `[[binds]]`: + +* `ownUidIsPrivileged` (UNIX domain sockets only): boolean. If true, a client + running as Moonfire NVR's own uid can perform any action without additional + authentication. Once the configuration UI is complete, this will be a handy + way to set up the first user accounts. +* `allowUnauthenticatedPermissions`: dictionary. Clients connecting to this + bind will have the specified permissions, even without UID or session + authentication. The supported permissions are as in the [`Permissions` + section of api.md](api.md#permissions). +* `trustForwardHeaders`: boolean. Moonfire NVR will look for `X-Real-IP` and + `X-Forwarded-Proto` headers added by a proxy server to determine the + client's IP address and protocol (`http` or `https`). See + [guide/secure.md](../guide/secure.md) for more information. *Note:* when + using this option, ensure that untrusted clients can't bypass the proxy + server, or they will be able to disguise their true origin. diff --git a/server/db/proto/schema.proto b/server/db/proto/schema.proto index a24e783..eb87bc4 100644 --- a/server/db/proto/schema.proto +++ b/server/db/proto/schema.proto @@ -60,7 +60,7 @@ message DirMeta { Open in_progress_open = 4; } -// Permissions to perform actions. See description in design/api.md. +// Permissions to perform actions. See description in ref/api.md. // // This protobuf form is stored in user and session rows. message Permissions { diff --git a/server/src/cmds/run/config.rs b/server/src/cmds/run/config.rs index 6913c0e..0a45e36 100644 --- a/server/src/cmds/run/config.rs +++ b/server/src/cmds/run/config.rs @@ -3,6 +3,7 @@ // SPDX-License-Identifier: GPL-v3.0-or-later WITH GPL-3.0-linking-exception. //! Runtime configuration file (`/etc/moonfire-nvr.toml`). +//! See `ref/config.md` for more description. use std::path::PathBuf; diff --git a/server/src/json.rs b/server/src/json.rs index cb5db23..1f3320b 100644 --- a/server/src/json.rs +++ b/server/src/json.rs @@ -55,7 +55,7 @@ impl Session { } /// JSON serialization wrapper for a single camera when processing `/api/` and -/// `/api/cameras//`. See `design/api.md` for details. +/// `/api/cameras//`. See `ref/api.md` for details. #[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] pub struct Camera<'a> { diff --git a/server/src/web/view.rs b/server/src/web/view.rs index d4a7d67..10c09cc 100644 --- a/server/src/web/view.rs +++ b/server/src/web/view.rs @@ -230,7 +230,7 @@ fn num<'a, T: FromStr>() -> impl FnMut(&'a str) -> IResult<&'a str, T> { } impl Segments { - /// Parses the `s` query parameter to `view.mp4` as described in `design/api.md`. + /// Parses the `s` query parameter to `view.mp4` as described in `ref/api.md`. /// Doesn't do any validation. fn parse(i: &str) -> IResult<&str, Segments> { // Parse START_ID[-END_ID] into Range. diff --git a/ui/src/api.ts b/ui/src/api.ts index cc5c938..597633b 100644 --- a/ui/src/api.ts +++ b/ui/src/api.ts @@ -5,7 +5,7 @@ /** * @file Convenience wrapper around the Moonfire NVR API layer. * - * See design/api.md for a description of the API. Some of the + * See ref/api.md for a description of the API. Some of the * documentation is copied into the docstrings here for convenience, but * that doc is authoritative. * diff --git a/ui/src/types.ts b/ui/src/types.ts index c6272ed..8cab3b8 100644 --- a/ui/src/types.ts +++ b/ui/src/types.ts @@ -4,7 +4,7 @@ /** * @file Types from the Moonfire NVR API. - * See descriptions in design/api.md. + * See descriptions in ref/api.md. */ export type StreamType = "main" | "sub";