diff --git a/src/config.rs b/src/config.rs new file mode 100644 index 0000000..aa5cf54 --- /dev/null +++ b/src/config.rs @@ -0,0 +1,101 @@ +use std::{ + net::{IpAddr, Ipv4Addr, Ipv6Addr}, + path::PathBuf, + time::Duration, +}; + +use axum_client_ip::SecureClientIpSource; + +use crate::IpType; + +#[derive(Debug, serde::Deserialize)] +struct Config { + // --- Server Settings -- + /// Ip address of the server + #[serde(default = "default_address")] + address: IpAddr, + + /// Port of the server + #[serde(default = "default_port")] + port: u16, + + /// Data directory + #[serde(default = "default_data_dir")] + data_dir: PathBuf, + + // --- Password Configuration -- + /// File containing password to match against + /// + /// Should be of the format `username:password` and contain a single password + #[serde(default)] + password_file: Option, + + /// Salt to get more unique hashed passwords and prevent table based attacks + #[serde(default = "default_salt")] + salt: String, + + // --- Records Configuration --- + /// Time To Live (in seconds) to set on the DNS records + #[serde(default = "default_ttl")] + ttl: Duration, + + /// List of domain names for which to update the IP when an update is requested + #[serde(default)] + records: Vec, + + /// If provided, when an IPv6 prefix is provided with an update, this will be used to derive + /// the full IPv6 address of the client + #[serde(default)] + client_id: Option, + + /// If a client id is provided the ipv6 update will be ignored (only the prefix will be used). + /// This domain will point to the ipv6 address instead of the address derived from the client + /// id (usually this is the router). + #[serde(default)] + router_domain: Option, + + /// Set client IP source + /// + /// see: + #[serde(default = "default_ip_source")] + ip_source: SecureClientIpSource, + + /// Set which IPs to allow updating (ipv4, ipv6 or both) + #[serde(default = "default_ip_type")] + ip_type: IpType, + + // --- Nsupdate Configuration --- + /// Keyfile `nsupdate` should use + /// + /// If specified, then `webnsupdate` must have read access to the file + #[serde(default)] + key_file: Option, +} + +fn default_ttl() -> Duration { + super::DEFAULT_TTL +} + +fn default_salt() -> String { + super::DEFAULT_SALT.into() +} + +fn default_data_dir() -> PathBuf { + PathBuf::from(".") +} + +fn default_address() -> IpAddr { + IpAddr::V4(Ipv4Addr::LOCALHOST) +} + +fn default_port() -> u16 { + 5353 +} + +fn default_ip_source() -> SecureClientIpSource { + SecureClientIpSource::RightmostXForwardedFor +} + +fn default_ip_type() -> IpType { + IpType::Both +} diff --git a/src/main.rs b/src/main.rs index cf37707..3b2917b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -20,6 +20,7 @@ use tracing::{debug, error, info}; use tracing_subscriber::EnvFilter; mod auth; +mod config; mod nsupdate; mod password; mod records; @@ -93,7 +94,7 @@ struct Opts { subcommand: Option, } -#[derive(Debug, Default, Clone, Copy)] +#[derive(Debug, Default, Clone, Copy, serde::Deserialize)] enum IpType { #[default] Both,