mirror of
https://github.com/scottlamb/moonfire-nvr.git
synced 2025-01-26 22:23:16 -05:00
tweak config format (#133)
* switch from json to toml. I think this will be more user-friendly. It allows comments and has less punctuation. Fewer surprises than yaml (which has e.g. the "Norway problem"). I might have stayed with JSON if I could see a good serde json library that allows comments, but hson is unmaintained and serde-json strictly follows the spec. * switch from camelCase to snake_case. Seems more idiomatic for TOML and matches the Rust source. * forbid unknown keys. Better to spot errors sooner. * rename "trust_forward_hdrs" to "trust_forward_headers". Nothing else is abbreviated.
This commit is contained in:
parent
de28f6eed3
commit
892427592e
@ -8,7 +8,7 @@ Each release is tagged in Git and on the Docker repository
|
|||||||
|
|
||||||
## unreleased
|
## unreleased
|
||||||
|
|
||||||
* introduce a configuration file `/etc/moonfire-nvr.json`; you will need
|
* introduce a configuration file `/etc/moonfire-nvr.toml`; you will need
|
||||||
to create one when upgrading.
|
to create one when upgrading.
|
||||||
* bump minimum Rust version from 1.53 to 1.56.
|
* bump minimum Rust version from 1.53 to 1.56.
|
||||||
* fix [#187](https://github.com/scottlamb/moonfire-nvr/issues/187):
|
* fix [#187](https://github.com/scottlamb/moonfire-nvr/issues/187):
|
||||||
|
@ -299,27 +299,20 @@ BlockIOAccounting=true
|
|||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
```
|
```
|
||||||
|
|
||||||
You'll also need a `/etc/moonfire-nvr.json`:
|
You'll also need a `/etc/moonfire-nvr.toml`:
|
||||||
|
|
||||||
```json
|
```toml
|
||||||
{
|
[[binds]]
|
||||||
"binds": [
|
ipv4 = "0.0.0.0:8080"
|
||||||
{
|
allow_unauthenticated_permissions = { view_video = true }
|
||||||
"ipv4": "0.0.0.0:8080",
|
|
||||||
"allowUnauthenticatedPermissions": {
|
[[binds]]
|
||||||
"viewVideo": true
|
unix = "/var/lib/moonfire-nvr/sock"
|
||||||
}
|
own_uid_is_privileged = true
|
||||||
},
|
|
||||||
{
|
|
||||||
"unix": "/var/lib/moonfire-nvr/sock",
|
|
||||||
"ownUidIsPrivileged": true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Note this configuration is insecure. You can change that via replacing the
|
Note this configuration is insecure. You can change that via replacing the
|
||||||
`allowUnauthenticatedPermissions` here as described in [Securing Moonfire NVR
|
`allow_unauthenticated_permissions` here as described in [Securing Moonfire NVR
|
||||||
and exposing it to the Internet](secure.md).
|
and exposing it to the Internet](secure.md).
|
||||||
|
|
||||||
Some handy commands:
|
Some handy commands:
|
||||||
|
@ -56,33 +56,26 @@ and managing a long-lived Docker container for its web interface.
|
|||||||
As you set up this script, adjust the `tz` variable as appropriate for your
|
As you set up this script, adjust the `tz` variable as appropriate for your
|
||||||
time zone.
|
time zone.
|
||||||
|
|
||||||
Use your favorite editor to create `/etc/moonfire-nvr.json` and
|
Use your favorite editor to create `/etc/moonfire-nvr.toml` and
|
||||||
`/usr/local/bin/nvr`, starting from the configurations below:
|
`/usr/local/bin/nvr`, starting from the configurations below:
|
||||||
|
|
||||||
```console
|
```console
|
||||||
$ sudo nano /etc/moonfire-nvr.json
|
$ sudo nano /etc/moonfire-nvr.toml
|
||||||
(see below for contents)
|
(see below for contents)
|
||||||
$ sudo nano /usr/local/bin/nvr
|
$ sudo nano /usr/local/bin/nvr
|
||||||
(see below for contents)
|
(see below for contents)
|
||||||
$ sudo chmod a+rx /usr/local/bin/nvr
|
$ sudo chmod a+rx /usr/local/bin/nvr
|
||||||
```
|
```
|
||||||
|
|
||||||
`/etc/moonfire-nvr.json`:
|
`/etc/moonfire-nvr.toml`:
|
||||||
```json
|
```toml
|
||||||
{
|
[[binds]]
|
||||||
"binds": [
|
ipv4 = "0.0.0.0:8080"
|
||||||
{
|
|
||||||
"ipv4": "0.0.0.0:8080",
|
[[binds]]
|
||||||
"allowUnauthenticatedPermissions": {
|
unix = "/var/lib/moonfire-nvr/sock"
|
||||||
"viewVideo": true
|
allow_unauthenticated_permissions: { "view_video": true }
|
||||||
}
|
own_uid_is_privileged = true
|
||||||
},
|
|
||||||
{
|
|
||||||
"unix": "/var/lib/moonfire-nvr/sock",
|
|
||||||
"ownUidIsPrivileged": true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
`/usr/local/bin/nvr`:
|
`/usr/local/bin/nvr`:
|
||||||
@ -97,7 +90,7 @@ image_name="scottlamb/moonfire-nvr:latest"
|
|||||||
container_name="moonfire-nvr"
|
container_name="moonfire-nvr"
|
||||||
common_docker_run_args=(
|
common_docker_run_args=(
|
||||||
--mount=type=bind,source=/var/lib/moonfire-nvr,destination=/var/lib/moonfire-nvr
|
--mount=type=bind,source=/var/lib/moonfire-nvr,destination=/var/lib/moonfire-nvr
|
||||||
--mount=type=bind,source=/etc/moonfire-nvr.json,destination=/etc/moonfire-nvr.json
|
--mount=type=bind,source=/etc/moonfire-nvr.toml,destination=/etc/moonfire-nvr.toml
|
||||||
|
|
||||||
# Add additional mount lines here for each sample file directory
|
# Add additional mount lines here for each sample file directory
|
||||||
# outside of /var/lib/moonfire-nvr, eg:
|
# outside of /var/lib/moonfire-nvr, eg:
|
||||||
|
@ -162,24 +162,23 @@ your browser. See [How to secure Nginx with Let's Encrypt on Ubuntu
|
|||||||
## 6. Reconfigure Moonfire NVR
|
## 6. Reconfigure Moonfire NVR
|
||||||
|
|
||||||
If you follow the recommended Docker setup, your `/etc/moonfire-nvr.json`
|
If you follow the recommended Docker setup, your `/etc/moonfire-nvr.json`
|
||||||
will contain these lines:
|
will contain this line:
|
||||||
|
|
||||||
```json
|
```toml
|
||||||
"allowUnauthenticatedPermissions": {
|
allow_unauthenticated_permissions = { view_video = true }
|
||||||
"viewVideo": true
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Replace them with the following:
|
Replace it with the following:
|
||||||
|
|
||||||
```json
|
```toml
|
||||||
"trustForwardHdrs": true
|
trust_forward_headers = true
|
||||||
```
|
```
|
||||||
|
|
||||||
This change has two effects:
|
This change has two effects:
|
||||||
|
|
||||||
* No `allowUnauthenticatePermissions` means that web users must authenticate.
|
* No `allow_unauthenticated_permissions` means that web users must
|
||||||
* `trustForwardHdrs` means that Moonfire NVR will look for `X-Real-IP`
|
authenticate.
|
||||||
|
* `trust-forward-headers` means that Moonfire NVR will look for `X-Real-IP`
|
||||||
and `X-Forwarded-Proto` headers as added by the webserver configuration
|
and `X-Forwarded-Proto` headers as added by the webserver configuration
|
||||||
in the next section.
|
in the next section.
|
||||||
|
|
||||||
@ -205,8 +204,9 @@ desired DNS name. Now finalize its configuration:
|
|||||||
|
|
||||||
* redirect all `http` traffic to `https`
|
* redirect all `http` traffic to `https`
|
||||||
* proxy `https` traffic to Moonfire NVR
|
* proxy `https` traffic to Moonfire NVR
|
||||||
* when proxying, add a `X-Real-IP` header with the original IP address
|
* when proxying, set the `X-Real-IP` header to the original IP address
|
||||||
* when proxying, add a `X-Forwarded-Proto` header with the original
|
(removing any previous occurrences of this header)
|
||||||
|
* when proxying, set the `X-Forwarded-Proto` header to the original
|
||||||
protocol (which should be `https` if you've configured everything
|
protocol (which should be `https` if you've configured everything
|
||||||
correctly).
|
correctly).
|
||||||
|
|
||||||
|
10
server/Cargo.lock
generated
10
server/Cargo.lock
generated
@ -1138,6 +1138,7 @@ dependencies = [
|
|||||||
"tokio",
|
"tokio",
|
||||||
"tokio-stream",
|
"tokio-stream",
|
||||||
"tokio-tungstenite",
|
"tokio-tungstenite",
|
||||||
|
"toml",
|
||||||
"tracing",
|
"tracing",
|
||||||
"url",
|
"url",
|
||||||
"uuid",
|
"uuid",
|
||||||
@ -2118,6 +2119,15 @@ dependencies = [
|
|||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml"
|
||||||
|
version = "0.5.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tower-service"
|
name = "tower-service"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
|
@ -60,6 +60,7 @@ time = "0.1"
|
|||||||
tokio = { version = "1.0", features = ["macros", "parking_lot", "rt-multi-thread", "signal", "sync", "time"] }
|
tokio = { version = "1.0", features = ["macros", "parking_lot", "rt-multi-thread", "signal", "sync", "time"] }
|
||||||
tokio-stream = "0.1.5"
|
tokio-stream = "0.1.5"
|
||||||
tokio-tungstenite = "0.17.1"
|
tokio-tungstenite = "0.17.1"
|
||||||
|
toml = "0.5"
|
||||||
tracing = { version = "0.1", features = ["log"] }
|
tracing = { version = "0.1", features = ["log"] }
|
||||||
url = "2.1.1"
|
url = "2.1.1"
|
||||||
uuid = { version = "0.8", features = ["serde", "std", "v4"] }
|
uuid = { version = "0.8", features = ["serde", "std", "v4"] }
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// Copyright (C) 2022 The Moonfire NVR Authors; see AUTHORS and LICENSE.txt.
|
// Copyright (C) 2022 The Moonfire NVR Authors; see AUTHORS and LICENSE.txt.
|
||||||
// SPDX-License-Identifier: GPL-v3.0-or-later WITH GPL-3.0-linking-exception.
|
// SPDX-License-Identifier: GPL-v3.0-or-later WITH GPL-3.0-linking-exception.
|
||||||
|
|
||||||
//! Runtime configuration file (`/etc/moonfire-nvr.conf`).
|
//! Runtime configuration file (`/etc/moonfire-nvr.toml`).
|
||||||
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
@ -18,7 +18,7 @@ fn default_ui_dir() -> PathBuf {
|
|||||||
|
|
||||||
/// Top-level configuration file object.
|
/// Top-level configuration file object.
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct ConfigFile {
|
pub struct ConfigFile {
|
||||||
pub binds: Vec<BindConfig>,
|
pub binds: Vec<BindConfig>,
|
||||||
|
|
||||||
@ -46,7 +46,7 @@ pub struct ConfigFile {
|
|||||||
|
|
||||||
/// Per-bind configuration.
|
/// Per-bind configuration.
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct BindConfig {
|
pub struct BindConfig {
|
||||||
/// The address to bind to.
|
/// The address to bind to.
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
@ -66,7 +66,7 @@ pub struct BindConfig {
|
|||||||
/// and that no untrusted requests bypass the proxy server. You may want to
|
/// and that no untrusted requests bypass the proxy server. You may want to
|
||||||
/// specify a localhost bind address.
|
/// specify a localhost bind address.
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub trust_forward_hdrs: bool,
|
pub trust_forward_headers: bool,
|
||||||
|
|
||||||
/// On Unix-domain sockets, treat clients with the Moonfire NVR server's own
|
/// On Unix-domain sockets, treat clients with the Moonfire NVR server's own
|
||||||
/// effective UID as privileged.
|
/// effective UID as privileged.
|
||||||
@ -75,7 +75,8 @@ pub struct BindConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "lowercase")]
|
||||||
|
#[serde(deny_unknown_fields)]
|
||||||
pub enum AddressConfig {
|
pub enum AddressConfig {
|
||||||
/// IPv4 address such as `0.0.0.0:8080` or `127.0.0.1:8080`.
|
/// IPv4 address such as `0.0.0.0:8080` or `127.0.0.1:8080`.
|
||||||
Ipv4(std::net::SocketAddrV4),
|
Ipv4(std::net::SocketAddrV4),
|
||||||
@ -91,7 +92,7 @@ pub enum AddressConfig {
|
|||||||
|
|
||||||
/// JSON analog of `Permissions` defined in `db/proto/schema.proto`.
|
/// JSON analog of `Permissions` defined in `db/proto/schema.proto`.
|
||||||
#[derive(Debug, Default, Deserialize)]
|
#[derive(Debug, Default, Deserialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct Permissions {
|
pub struct Permissions {
|
||||||
view_video: bool,
|
view_video: bool,
|
||||||
read_camera_configs: bool,
|
read_camera_configs: bool,
|
||||||
|
@ -27,13 +27,13 @@ mod config;
|
|||||||
|
|
||||||
#[derive(StructOpt)]
|
#[derive(StructOpt)]
|
||||||
pub struct Args {
|
pub struct Args {
|
||||||
#[structopt(short, long, default_value = "/etc/moonfire-nvr.json")]
|
#[structopt(short, long, default_value = "/etc/moonfire-nvr.toml")]
|
||||||
config: PathBuf,
|
config: PathBuf,
|
||||||
|
|
||||||
/// Open the database in read-only mode and disables recording.
|
/// Open the database in read-only mode and disables recording.
|
||||||
///
|
///
|
||||||
/// Note this is incompatible with session authentication; consider adding
|
/// Note this is incompatible with session authentication; consider adding
|
||||||
/// a bind with `allowUnauthenticatedPermissions` your config.
|
/// a bind with `allow_unauthenticated_permissions` to your config.
|
||||||
#[structopt(long)]
|
#[structopt(long)]
|
||||||
read_only: bool,
|
read_only: bool,
|
||||||
}
|
}
|
||||||
@ -129,7 +129,7 @@ struct Syncer {
|
|||||||
|
|
||||||
fn read_config(path: &Path) -> Result<ConfigFile, Error> {
|
fn read_config(path: &Path) -> Result<ConfigFile, Error> {
|
||||||
let config = std::fs::read(path)?;
|
let config = std::fs::read(path)?;
|
||||||
let config = serde_json::from_slice(&config)?;
|
let config = toml::from_slice(&config)?;
|
||||||
Ok(config)
|
Ok(config)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -370,7 +370,7 @@ async fn inner(
|
|||||||
.allow_unauthenticated_permissions
|
.allow_unauthenticated_permissions
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(Permissions::as_proto),
|
.map(Permissions::as_proto),
|
||||||
trust_forward_hdrs: b.trust_forward_hdrs,
|
trust_forward_hdrs: b.trust_forward_headers,
|
||||||
time_zone_name: time_zone_name.clone(),
|
time_zone_name: time_zone_name.clone(),
|
||||||
privileged_unix_uid: b.own_uid_is_privileged.then(|| own_euid),
|
privileged_unix_uid: b.own_uid_is_privileged.then(|| own_euid),
|
||||||
})?);
|
})?);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user