diff --git a/Cargo.toml b/Cargo.toml index e2980bd..e3e8f93 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,6 +16,7 @@ byteorder = "1.3.2" clap = { version="2.33.0", features=["wrap_help", "nightly"] } clockpro-cache = "0.1.8" coarsetime = "0.1.11" +daemonize-simple = "0.1.1" derivative = "1.0.3" dnsstamps = "0.1.1" env_logger = "0.6.2" diff --git a/encrypted-dns.toml b/encrypted-dns.toml index c07f85d..becf830 100644 --- a/encrypted-dns.toml +++ b/encrypted-dns.toml @@ -71,6 +71,16 @@ cache_ttl_max = 86400 cache_ttl_error = 600 +## Run as a background process + +daemonize = false + + +## PID file + +# pid_file = "/tmp/encrypted-dns.pid" + + ## User name to drop privileges to, when started as root. # user = "nobody" diff --git a/src/config.rs b/src/config.rs index d81dc76..76259f3 100644 --- a/src/config.rs +++ b/src/config.rs @@ -39,6 +39,8 @@ pub struct Config { pub chroot: Option, pub dnscrypt: DNSCryptConfig, pub tls: TLSConfig, + pub daemonize: bool, + pub pid_file: Option, } impl Config { diff --git a/src/main.rs b/src/main.rs index fc839e3..158dc18 100644 --- a/src/main.rs +++ b/src/main.rs @@ -325,6 +325,37 @@ async fn start(globals: Arc, runtime: Arc) -> Result<(), Error Ok(()) } +fn privdrop(config: &Config) -> Result<(), Error> { + let mut pd = PrivDrop::default(); + if let Some(user) = &config.user { + pd = pd.user(user); + } + if let Some(group) = &config.group { + pd = pd.group(group); + } + if let Some(chroot) = &config.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.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| format_err!("Unable to daemonize: [{}]", e))?; + } + Ok(()) +} + fn main() -> Result<(), Error> { env_logger::Builder::from_default_env() .default_format_module_path(false) @@ -359,26 +390,13 @@ fn main() -> Result<(), Error> { let config_path = matches.value_of("config").unwrap(); let config = Config::from_path(config_path)?; - let provider_name = match config.dnscrypt.provider_name { + let provider_name = match &config.dnscrypt.provider_name { provider_name if provider_name.starts_with("2.dnscrypt-cert.") => provider_name.to_string(), provider_name => format!("2.dnscrypt-cert.{}", provider_name), }; let external_addr = SocketAddr::new(config.external_addr, 0); - let mut pd = PrivDrop::default(); - if let Some(user) = &config.user { - pd = pd.user(user); - } - if let Some(group) = &config.group { - pd = pd.group(group); - } - if let Some(chroot) = &config.chroot { - pd = pd.chroot(chroot); - } - if config.user.is_some() || config.group.is_some() || config.chroot.is_some() { - info!("Dropping privileges"); - pd.apply()?; - } + privdrop(&config)?; let mut runtime_builder = tokio::runtime::Builder::new(); runtime_builder.name_prefix("encrypted-dns-");