Elimited Daemonize dependency

This commit is contained in:
Mathias Hall-Andersen
2020-05-17 22:07:59 +02:00
parent 8d53b0f5c1
commit 16f21989b4
5 changed files with 117 additions and 37 deletions

17
Cargo.lock generated
View File

@@ -95,11 +95,6 @@ dependencies = [
"opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "boxfnonce"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "bumpalo" name = "bumpalo"
version = "3.2.1" version = "3.2.1"
@@ -212,15 +207,6 @@ dependencies = [
"zeroize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "zeroize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "daemonize"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"boxfnonce 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "digest" name = "digest"
version = "0.8.1" version = "0.8.1"
@@ -1129,7 +1115,6 @@ dependencies = [
"clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"cpuprofiler 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "cpuprofiler 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-channel 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-channel 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"daemonize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", "generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1223,7 +1208,6 @@ dependencies = [
"checksum bitflags 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4f67931368edf3a9a51d29886d245f1c3db2f1ef0dcc9e35ff70341b78c10d23" "checksum bitflags 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4f67931368edf3a9a51d29886d245f1c3db2f1ef0dcc9e35ff70341b78c10d23"
"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" "checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
"checksum blake2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "94cb07b0da6a73955f8fb85d24c466778e70cda767a568229b104f0264089330" "checksum blake2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "94cb07b0da6a73955f8fb85d24c466778e70cda767a568229b104f0264089330"
"checksum boxfnonce 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5988cb1d626264ac94100be357308f29ff7cbdd3b36bda27f450a4ee3f713426"
"checksum bumpalo 3.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "12ae9db68ad7fac5fe51304d20f016c911539251075a214f8e663babefa35187" "checksum bumpalo 3.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "12ae9db68ad7fac5fe51304d20f016c911539251075a214f8e663babefa35187"
"checksum byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" "checksum byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
"checksum byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" "checksum byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
@@ -1238,7 +1222,6 @@ dependencies = [
"checksum crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" "checksum crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8"
"checksum crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5" "checksum crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5"
"checksum curve25519-dalek 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "26778518a7f6cffa1d25a44b602b62b979bd88adb9e99ffec546998cf3404839" "checksum curve25519-dalek 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "26778518a7f6cffa1d25a44b602b62b979bd88adb9e99ffec546998cf3404839"
"checksum daemonize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "70c24513e34f53b640819f0ac9f705b673fcf4006d7aab8778bee72ebfc89815"
"checksum digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" "checksum digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
"checksum env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36" "checksum env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36"
"checksum error-chain 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d371106cc88ffdfb1eabd7111e432da544f16f3e2d7bf1dfe8bf575f1df045cd" "checksum error-chain 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d371106cc88ffdfb1eabd7111e432da544f16f3e2d7bf1dfe8bf575f1df045cd"

View File

@@ -25,7 +25,6 @@ aead = "^0.2"
clear_on_drop = "0.2.3" clear_on_drop = "0.2.3"
env_logger = "0.7" env_logger = "0.7"
num_cpus = "^1.10" num_cpus = "^1.10"
daemonize = "0.4.1"
crossbeam-channel = "0.4" crossbeam-channel = "0.4"
cpuprofiler = { version = "*", optional = true } cpuprofiler = { version = "*", optional = true }

View File

@@ -87,6 +87,9 @@ ip0 link set wg1 netns $netns1
n0 $program wg2 n0 $program wg2
ip0 link set wg2 netns $netns2 ip0 link set wg2 netns $netns2
# wait for programs to start
sleep 0.1
key1="$(pp wg genkey)" key1="$(pp wg genkey)"
key2="$(pp wg genkey)" key2="$(pp wg genkey)"
pub1="$(pp wg pubkey <<<"$key1")" pub1="$(pp wg pubkey <<<"$key1")"
@@ -102,6 +105,8 @@ configure_peers() {
ip2 addr add 192.168.241.2/24 dev wg2 ip2 addr add 192.168.241.2/24 dev wg2
ip2 addr add fd00::2/24 dev wg2 ip2 addr add fd00::2/24 dev wg2
n0 wg
n0 wg set wg1 \ n0 wg set wg1 \
private-key <(echo "$key1") \ private-key <(echo "$key1") \
listen-port 10000 \ listen-port 10000 \
@@ -120,9 +125,9 @@ configure_peers() {
ip1 link set up dev wg1 ip1 link set up dev wg1
ip2 link set up dev wg2 ip2 link set up dev wg2
sleep 1
echo "ready" echo "ready"
} }
configure_peers configure_peers
tests() { tests() {

View File

@@ -13,9 +13,9 @@ mod configuration;
mod platform; mod platform;
mod wireguard; mod wireguard;
use log; mod util;
use daemonize::Daemonize; use log;
use std::env; use std::env;
use std::process::exit; use std::process::exit;
@@ -62,14 +62,14 @@ fn main() {
let mut foreground = false; let mut foreground = false;
let mut args = env::args(); let mut args = env::args();
args.next(); // skip path (argv[0]) // skip path (argv[0])
args.next();
for arg in args { for arg in args {
match arg.as_str() { match arg.as_str() {
"--foreground" | "-f" => { "--foreground" | "-f" => {
foreground = true; foreground = true;
} }
"--root" => { "--disable-drop-privileges" => {
drop_privileges = false; drop_privileges = false;
} }
dev => name = Some(dev.to_owned()), dev => name = Some(dev.to_owned()),
@@ -97,16 +97,26 @@ fn main() {
exit(-3); exit(-3);
}); });
// daemonize // drop privileges
if drop_privileges {
match util::drop_privileges() {
Ok(_) => (),
Err(e) => {
eprintln!("Failed to drop privileges: {}", e);
exit(-4);
}
}
}
// daemonize to background
if !foreground { if !foreground {
let daemonize = Daemonize::new() match util::daemonize() {
.pid_file(format!("/tmp/wireguard-rs-{}.pid", name)) Ok(_) => (),
.chown_pid_file(true) Err(e) => {
.working_directory("/tmp") eprintln!("Failed to daemonize: {}", e);
.user("nobody") exit(-5);
.group("daemon") }
.umask(0o777); }
daemonize.start().expect("Failed to daemonize");
} }
// start logging // start logging
@@ -114,10 +124,7 @@ fn main() {
.try_init() .try_init()
.expect("Failed to initialize event logger"); .expect("Failed to initialize event logger");
log::info!("starting {} wireguard device", name); log::info!("Starting {} WireGuard device.", name);
// drop privileges
if drop_privileges {}
// start profiler (if enabled) // start profiler (if enabled)
#[cfg(feature = "profiler")] #[cfg(feature = "profiler")]

86
src/util.rs Normal file
View File

@@ -0,0 +1,86 @@
use std::fmt;
use std::process::exit;
use libc::{c_char, chdir, chroot, fork, getpwnam, getuid, setgid, setsid, setuid, umask};
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
pub enum DaemonizeError {
Fork,
SetSession,
SetGroup,
SetUser,
Chroot,
Chdir,
}
impl fmt::Display for DaemonizeError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
DaemonizeError::Fork => "unable to fork",
DaemonizeError::SetSession => "unable to create new process session",
DaemonizeError::SetGroup => "unable to set group (drop privileges)",
DaemonizeError::SetUser => "unable to set user (drop privileges)",
DaemonizeError::Chroot => "unable to enter chroot jail",
DaemonizeError::Chdir => "failed to change directory",
}
.fmt(f)
}
}
fn fork_and_exit() -> Result<(), DaemonizeError> {
let pid = unsafe { fork() };
if pid < 0 {
Err(DaemonizeError::Fork)
} else if pid == 0 {
Ok(())
} else {
exit(0);
}
}
pub fn daemonize() -> Result<(), DaemonizeError> {
// fork from the original parent
fork_and_exit()?;
// avoid killing the child when this parent dies
if unsafe { setsid() } < 0 {
return Err(DaemonizeError::SetSession);
}
// fork again to create orphan
fork_and_exit()
}
pub fn drop_privileges() -> Result<(), DaemonizeError> {
// retrieve nobody's uid & gid
let usr = unsafe { getpwnam("nobody\x00".as_ptr() as *const c_char) };
if usr.is_null() {
return Err(DaemonizeError::SetGroup);
}
// change root directory
let uid = unsafe { getuid() };
if uid == 0 && unsafe { chroot("/tmp\x00".as_ptr() as *const c_char) } != 0 {
return Err(DaemonizeError::Chroot);
}
// set umask for files
unsafe { umask(0) };
// change directory
if unsafe { chdir("/\x00".as_ptr() as *const c_char) } != 0 {
return Err(DaemonizeError::Chdir);
}
// set group id to nobody
if unsafe { setgid((*usr).pw_gid) } != 0 {
return Err(DaemonizeError::SetGroup);
}
// set user id to nobody
if unsafe { setuid((*usr).pw_uid) } != 0 {
Err(DaemonizeError::SetUser)
} else {
Ok(())
}
}