diff --git a/Cargo.toml b/Cargo.toml index 467b3fa..484db05 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,6 +17,7 @@ byteorder = "1.4.2" clap = { version = "2.33.3", default-features = false, features = ["wrap_help"] } clockpro-cache = "0.1.10" coarsetime = "0.1.18" +daemonize-simple = "0.1.5" derivative = "2.2.0" dnsstamps = "0.1.6" env_logger = { version = "0.8.3", default-features = false, features = ["humantime"] } diff --git a/example-encrypted-dns.toml b/example-encrypted-dns.toml index ab12063..24237dd 100644 --- a/example-encrypted-dns.toml +++ b/example-encrypted-dns.toml @@ -90,6 +90,16 @@ cache_ttl_error = 600 client_ttl_holdon = 60 +## Run as a background process + +daemonize = false + + +## Log file, when running as a background process + +# log_file = "/tmp/encrypted-dns.log" + + ## PID file # pid_file = "/tmp/encrypted-dns.pid" diff --git a/src/config.rs b/src/config.rs index 9d54adf..f3c9776 100644 --- a/src/config.rs +++ b/src/config.rs @@ -78,6 +78,7 @@ pub struct Config { pub filtering: FilteringConfig, pub dnscrypt: DNSCryptConfig, pub tls: TLSConfig, + pub daemonize: bool, pub pid_file: Option, pub log_file: Option, pub my_ip: Option, diff --git a/src/main.rs b/src/main.rs index feb73ee..7389ff2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -466,6 +466,9 @@ fn bind_listeners( } fn privdrop(config: &Config) -> Result<(), Error> { + if config.daemonize && config.metrics.is_some() { + bail!("Metrics are incompatible with daemonization - set 'daemonize = false' in the configuration file if you need metrics."); + } let mut pd = PrivDrop::default(); if let Some(user) = &config.user { pd = pd.user(user); @@ -474,12 +477,27 @@ fn privdrop(config: &Config) -> Result<(), Error> { pd = pd.group(group); } if let Some(chroot) = &config.chroot { - pd = pd.chroot(chroot); + if !config.daemonize { + pd = pd.chroot(chroot); + } } if config.user.is_some() || config.group.is_some() || config.chroot.is_some() { info!("Dropping privileges"); pd.apply()?; } + if config.daemonize { + let mut daemon = daemonize_simple::Daemonize::default(); + daemon.stdout_file = config.log_file.clone(); + daemon.stderr_file = config.log_file.clone(); + daemon.pid_file = config.pid_file.clone(); + if let Some(chroot) = &config.chroot { + daemon.chdir = Some(chroot.into()); + daemon.chroot = true; + } + daemon + .doit() + .map_err(|e| anyhow!("Unable to daemonize: [{}]", e))?; + } Ok(()) }