mirror of https://github.com/dswd/vpncloud.git
Daemonizing and proper systemd support
This commit is contained in:
parent
4497ddaf13
commit
88f5272023
|
@ -7,6 +7,10 @@ This project follows [semantic versioning](http://semver.org).
|
||||||
- [added] Support for automatic port forwarding via UPnP
|
- [added] Support for automatic port forwarding via UPnP
|
||||||
- [added] Added `-s` shorthand for `--subnet`
|
- [added] Added `-s` shorthand for `--subnet`
|
||||||
- [added] Support for YAML config file via `--config`
|
- [added] Support for YAML config file via `--config`
|
||||||
|
- [added] Support for running in the background
|
||||||
|
- [added] Support for dropping permissions
|
||||||
|
- [added] Support for writing a pid file
|
||||||
|
- [added] Support for writing logs to logfile
|
||||||
- [changed] Not overriding recently learnt addresses in switch mode
|
- [changed] Not overriding recently learnt addresses in switch mode
|
||||||
- [changed] Caching resolved addresses to increase performance
|
- [changed] Caching resolved addresses to increase performance
|
||||||
- [changed] Configurable magic header is now used instead of Network-ID (**incompatible**)
|
- [changed] Configurable magic header is now used instead of Network-ID (**incompatible**)
|
||||||
|
|
|
@ -4,6 +4,7 @@ version = "0.7.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aligned_alloc 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"aligned_alloc 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"daemonize 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"docopt 0.6.86 (registry+https://github.com/rust-lang/crates.io-index)",
|
"docopt 0.6.86 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"gcc 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gcc 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -11,11 +12,10 @@ dependencies = [
|
||||||
"libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"net2 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)",
|
"net2 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"nix 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"pkg-config 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"pkg-config 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustc-serialize 0.3.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc-serialize 0.3.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"signal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"signal 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"siphasher 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"siphasher 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"yaml-rust 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"yaml-rust 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -63,6 +63,14 @@ dependencies = [
|
||||||
"url 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"url 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "daemonize"
|
||||||
|
version = "0.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "docopt"
|
name = "docopt"
|
||||||
version = "0.6.86"
|
version = "0.6.86"
|
||||||
|
@ -272,7 +280,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "signal"
|
name = "signal"
|
||||||
version = "0.2.0"
|
version = "0.3.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -422,6 +430,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
"checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d"
|
"checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d"
|
||||||
"checksum cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de1e760d7b6535af4241fca8bd8adf68e2e7edacc6b29f5d399050c5e48cf88c"
|
"checksum cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de1e760d7b6535af4241fca8bd8adf68e2e7edacc6b29f5d399050c5e48cf88c"
|
||||||
"checksum cookie 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0e3d6405328b6edb412158b3b7710e2634e23f3614b9bb1c412df7952489a626"
|
"checksum cookie 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0e3d6405328b6edb412158b3b7710e2634e23f3614b9bb1c412df7952489a626"
|
||||||
|
"checksum daemonize 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0239832c1b4ca406d5ec73728cf4c7336d25cf85dd32db9e047e9e706ee0e935"
|
||||||
"checksum docopt 0.6.86 (registry+https://github.com/rust-lang/crates.io-index)" = "4a7ef30445607f6fc8720f0a0a2c7442284b629cf0d049286860fae23e71c4d9"
|
"checksum docopt 0.6.86 (registry+https://github.com/rust-lang/crates.io-index)" = "4a7ef30445607f6fc8720f0a0a2c7442284b629cf0d049286860fae23e71c4d9"
|
||||||
"checksum fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc484842f1e2884faf56f529f960cc12ad8c71ce96cc7abba0a067c98fee344"
|
"checksum fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc484842f1e2884faf56f529f960cc12ad8c71ce96cc7abba0a067c98fee344"
|
||||||
"checksum gcc 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)" = "553f11439bdefe755bf366b264820f1da70f3aaf3924e594b886beb9c831bcf5"
|
"checksum gcc 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)" = "553f11439bdefe755bf366b264820f1da70f3aaf3924e594b886beb9c831bcf5"
|
||||||
|
@ -448,7 +457,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
"checksum rustc-serialize 0.3.21 (registry+https://github.com/rust-lang/crates.io-index)" = "bff9fc1c79f2dec76b253273d07682e94a978bd8f132ded071188122b2af9818"
|
"checksum rustc-serialize 0.3.21 (registry+https://github.com/rust-lang/crates.io-index)" = "bff9fc1c79f2dec76b253273d07682e94a978bd8f132ded071188122b2af9818"
|
||||||
"checksum rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "c5f5376ea5e30ce23c03eb77cbe4962b988deead10910c372b226388b594c084"
|
"checksum rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "c5f5376ea5e30ce23c03eb77cbe4962b988deead10910c372b226388b594c084"
|
||||||
"checksum semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)" = "d4f410fedcf71af0345d7607d246e7ad15faaadd49d240ee3b24e5dc21a820ac"
|
"checksum semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)" = "d4f410fedcf71af0345d7607d246e7ad15faaadd49d240ee3b24e5dc21a820ac"
|
||||||
"checksum signal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "beb615e58999635b6063277cf520f2d88824955c1056cf4f166b0f55b218512d"
|
"checksum signal 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "904a4bba60e8e7a53b7a7eec8f59084a9ceafe3df5aa9d24846a83a5e351aa34"
|
||||||
"checksum siphasher 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b1c3c58c9ac43c530919fe6bd8ef11ae2612f64c2bf8eab9346f5b71ce0617f2"
|
"checksum siphasher 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b1c3c58c9ac43c530919fe6bd8ef11ae2612f64c2bf8eab9346f5b71ce0617f2"
|
||||||
"checksum solicit 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "172382bac9424588d7840732b250faeeef88942e37b6e35317dce98cafdd75b2"
|
"checksum solicit 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "172382bac9424588d7840732b250faeeef88942e37b6e35317dce98cafdd75b2"
|
||||||
"checksum strsim 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "67f84c44fbb2f91db7fef94554e6b2ac05909c9c0b0bc23bb98d3a1aebfe7f7c"
|
"checksum strsim 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "67f84c44fbb2f91db7fef94554e6b2ac05909c9c0b0bc23bb98d3a1aebfe7f7c"
|
||||||
|
|
|
@ -15,8 +15,7 @@ time = "0.1"
|
||||||
docopt = "0.6"
|
docopt = "0.6"
|
||||||
rustc-serialize = "0.3"
|
rustc-serialize = "0.3"
|
||||||
log = "0.3"
|
log = "0.3"
|
||||||
signal = "0.2"
|
signal = "0.3"
|
||||||
nix = "0.6"
|
|
||||||
libc = "0.2"
|
libc = "0.2"
|
||||||
aligned_alloc = "0.1"
|
aligned_alloc = "0.1"
|
||||||
rand = "0.3"
|
rand = "0.3"
|
||||||
|
@ -26,6 +25,7 @@ bitflags = "0.7"
|
||||||
yaml-rust = "0.3"
|
yaml-rust = "0.3"
|
||||||
igd = "0.5"
|
igd = "0.5"
|
||||||
siphasher = "0.1"
|
siphasher = "0.1"
|
||||||
|
daemonize = "0.2"
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
gcc = "0.3"
|
gcc = "0.3"
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
vpncloud/debian/files
|
vpncloud/debian/files
|
||||||
vpncloud/debian/vpncloud
|
vpncloud/debian/vpncloud
|
||||||
|
vpncloud/debian/debhelper*
|
||||||
vpncloud/vpncloud
|
vpncloud/vpncloud
|
||||||
vpncloud-nocrypto/debian/vpncloud*
|
|
||||||
vpncloud-nocrypto/debian/files
|
|
||||||
vpncloud-nocrypto/vpncloud
|
|
||||||
*.deb
|
*.deb
|
||||||
*.build
|
*.build
|
||||||
*.changes
|
*.changes
|
||||||
|
|
|
@ -11,3 +11,5 @@ install:
|
||||||
install -d $(DESTDIR)/usr/bin
|
install -d $(DESTDIR)/usr/bin
|
||||||
install -m 755 vpncloud $(DESTDIR)/usr/bin/vpncloud
|
install -m 755 vpncloud $(DESTDIR)/usr/bin/vpncloud
|
||||||
install -m 755 vpncloud-control $(DESTDIR)/usr/bin/vpncloud-control
|
install -m 755 vpncloud-control $(DESTDIR)/usr/bin/vpncloud-control
|
||||||
|
install -d $(DESTDIR)/lib/systemd/system
|
||||||
|
install -m 644 vpncloud@.service $(DESTDIR)/lib/systemd/system/vpncloud@.service
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
7
|
9
|
||||||
|
|
|
@ -2,7 +2,7 @@ Source: vpncloud
|
||||||
Section: misc
|
Section: misc
|
||||||
Priority: extra
|
Priority: extra
|
||||||
Maintainer: Dennis Schwerdel <schwerdel@informatik.uni-kl.de>
|
Maintainer: Dennis Schwerdel <schwerdel@informatik.uni-kl.de>
|
||||||
Build-Depends: debhelper (>= 7), ruby-ronn
|
Build-Depends: debhelper (>= 9), ruby-ronn
|
||||||
Standards-Version: 3.8.3
|
Standards-Version: 3.8.3
|
||||||
|
|
||||||
Package: vpncloud
|
Package: vpncloud
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
[Unit]
|
[Unit]
|
||||||
Description=VpnCloud networks
|
Description=VpnCloud
|
||||||
|
Before=systemd-user-sessions.service
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=forking
|
ExecStartPre=/bin/echo "Please use instantiated services (vpncloud@NAME) instead."
|
||||||
ExecStart=/usr/bin/vpncloud-control start
|
ExecStart=/bin/false
|
||||||
ExecStop=/usr/bin/vpncloud-control stop
|
|
||||||
RemainAfterExit=yes
|
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=multi-user.target
|
WantedBy=
|
||||||
|
|
|
@ -38,7 +38,7 @@ start() {
|
||||||
# 2 if daemon could not be started
|
# 2 if daemon could not be started
|
||||||
for net in $NETWORKS; do
|
for net in $NETWORKS; do
|
||||||
[ -f "$NETCONFIGS/$net.net" ] || continue
|
[ -f "$NETCONFIGS/$net.net" ] || continue
|
||||||
start-stop-daemon --start --pidfile /run/$NAME-$net.pid --make-pidfile --name $NAME --background --startas /bin/sh -- -c "exec $DAEMON --config $NETCONFIGS/$net.net >/var/log/vpncloud-$net.log 2>&1"
|
start-stop-daemon --start --pidfile /run/$NAME-$net.pid --name $NAME -- "$DAEMON --daemon --config $NETCONFIGS/$net.net --pid-file /run/$NAME-$net.pid"
|
||||||
done
|
done
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ use std::time::Instant;
|
||||||
use std::cmp::{min, max};
|
use std::cmp::{min, max};
|
||||||
|
|
||||||
use fnv::FnvHasher;
|
use fnv::FnvHasher;
|
||||||
use nix::sys::signal::{SIGTERM, SIGQUIT, SIGINT};
|
use libc::{SIGTERM, SIGQUIT, SIGINT};
|
||||||
use signal::trap::Trap;
|
use signal::trap::Trap;
|
||||||
use rand::{random, sample, thread_rng};
|
use rand::{random, sample, thread_rng};
|
||||||
use net2::UdpBuilder;
|
use net2::UdpBuilder;
|
||||||
|
|
|
@ -25,6 +25,10 @@ pub struct Config {
|
||||||
pub dst_timeout: Duration,
|
pub dst_timeout: Duration,
|
||||||
pub subnets: Vec<String>,
|
pub subnets: Vec<String>,
|
||||||
pub port_forwarding: bool,
|
pub port_forwarding: bool,
|
||||||
|
pub daemonize: bool,
|
||||||
|
pub pid_file: Option<String>,
|
||||||
|
pub user: Option<String>,
|
||||||
|
pub group: Option<String>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Config {
|
impl Default for Config {
|
||||||
|
@ -37,7 +41,11 @@ impl Default for Config {
|
||||||
port: 3210, peers: vec![], peer_timeout: 1800,
|
port: 3210, peers: vec![], peer_timeout: 1800,
|
||||||
mode: Mode::Normal, dst_timeout: 300,
|
mode: Mode::Normal, dst_timeout: 300,
|
||||||
subnets: vec![],
|
subnets: vec![],
|
||||||
port_forwarding: true
|
port_forwarding: true,
|
||||||
|
daemonize: false,
|
||||||
|
pid_file: None,
|
||||||
|
user: None,
|
||||||
|
group: None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -86,6 +94,15 @@ impl Config {
|
||||||
if let Some(val) = file.port_forwarding {
|
if let Some(val) = file.port_forwarding {
|
||||||
self.port_forwarding = val;
|
self.port_forwarding = val;
|
||||||
}
|
}
|
||||||
|
if let Some(val) = file.pid_file {
|
||||||
|
self.pid_file = Some(val);
|
||||||
|
}
|
||||||
|
if let Some(val) = file.user {
|
||||||
|
self.user = Some(val);
|
||||||
|
}
|
||||||
|
if let Some(val) = file.group {
|
||||||
|
self.group = Some(val);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn merge_args(&mut self, mut args: Args) {
|
pub fn merge_args(&mut self, mut args: Args) {
|
||||||
|
@ -131,6 +148,18 @@ impl Config {
|
||||||
if args.flag_no_port_forwarding {
|
if args.flag_no_port_forwarding {
|
||||||
self.port_forwarding = false;
|
self.port_forwarding = false;
|
||||||
}
|
}
|
||||||
|
if args.flag_daemon {
|
||||||
|
self.daemonize = true;
|
||||||
|
}
|
||||||
|
if let Some(val) = args.flag_pid_file {
|
||||||
|
self.pid_file = Some(val);
|
||||||
|
}
|
||||||
|
if let Some(val) = args.flag_user {
|
||||||
|
self.user = Some(val);
|
||||||
|
}
|
||||||
|
if let Some(val) = args.flag_group {
|
||||||
|
self.group = Some(val);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_magic(&self) -> HeaderMagic {
|
pub fn get_magic(&self) -> HeaderMagic {
|
||||||
|
@ -169,5 +198,8 @@ pub struct ConfigFile {
|
||||||
pub mode: Option<Mode>,
|
pub mode: Option<Mode>,
|
||||||
pub dst_timeout: Option<Duration>,
|
pub dst_timeout: Option<Duration>,
|
||||||
pub subnets: Option<Vec<String>>,
|
pub subnets: Option<Vec<String>>,
|
||||||
pub port_forwarding: Option<bool>
|
pub port_forwarding: Option<bool>,
|
||||||
|
pub pid_file: Option<String>,
|
||||||
|
pub user: Option<String>,
|
||||||
|
pub group: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
57
src/main.rs
57
src/main.rs
|
@ -10,7 +10,6 @@ extern crate time;
|
||||||
extern crate docopt;
|
extern crate docopt;
|
||||||
extern crate rustc_serialize;
|
extern crate rustc_serialize;
|
||||||
extern crate signal;
|
extern crate signal;
|
||||||
extern crate nix;
|
|
||||||
extern crate libc;
|
extern crate libc;
|
||||||
extern crate aligned_alloc;
|
extern crate aligned_alloc;
|
||||||
extern crate rand;
|
extern crate rand;
|
||||||
|
@ -19,6 +18,7 @@ extern crate net2;
|
||||||
extern crate yaml_rust;
|
extern crate yaml_rust;
|
||||||
extern crate igd;
|
extern crate igd;
|
||||||
extern crate siphasher;
|
extern crate siphasher;
|
||||||
|
extern crate daemonize;
|
||||||
#[cfg(feature = "bench")] extern crate test;
|
#[cfg(feature = "bench")] extern crate test;
|
||||||
|
|
||||||
#[macro_use] pub mod util;
|
#[macro_use] pub mod util;
|
||||||
|
@ -38,8 +38,12 @@ pub mod port_forwarding;
|
||||||
|
|
||||||
use docopt::Docopt;
|
use docopt::Docopt;
|
||||||
|
|
||||||
|
use std::sync::Mutex;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::path::Path;
|
||||||
|
use std::io::{self, Write};
|
||||||
|
|
||||||
use device::{Device, Type};
|
use device::{Device, Type};
|
||||||
use ethernet::SwitchTable;
|
use ethernet::SwitchTable;
|
||||||
|
@ -77,13 +81,31 @@ pub struct Args {
|
||||||
flag_ifup: Option<String>,
|
flag_ifup: Option<String>,
|
||||||
flag_ifdown: Option<String>,
|
flag_ifdown: Option<String>,
|
||||||
flag_version: bool,
|
flag_version: bool,
|
||||||
flag_no_port_forwarding: bool
|
flag_no_port_forwarding: bool,
|
||||||
|
flag_daemon: bool,
|
||||||
|
flag_pid_file: Option<String>,
|
||||||
|
flag_user: Option<String>,
|
||||||
|
flag_group: Option<String>,
|
||||||
|
flag_log_file: Option<String>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct SimpleLogger;
|
struct DualLogger {
|
||||||
|
file: Mutex<Option<File>>
|
||||||
|
}
|
||||||
|
|
||||||
impl log::Log for SimpleLogger {
|
impl DualLogger {
|
||||||
|
pub fn new<P: AsRef<Path>>(path: Option<P>) -> Result<Self, io::Error> {
|
||||||
|
if let Some(path) = path {
|
||||||
|
let file = try!(File::create(path));
|
||||||
|
Ok(DualLogger{file: Mutex::new(Some(file))})
|
||||||
|
} else {
|
||||||
|
Ok(DualLogger{file: Mutex::new(None)})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl log::Log for DualLogger {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn enabled(&self, _metadata: &log::LogMetadata) -> bool {
|
fn enabled(&self, _metadata: &log::LogMetadata) -> bool {
|
||||||
true
|
true
|
||||||
|
@ -92,11 +114,12 @@ impl log::Log for SimpleLogger {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn log(&self, record: &log::LogRecord) {
|
fn log(&self, record: &log::LogRecord) {
|
||||||
if self.enabled(record.metadata()) {
|
if self.enabled(record.metadata()) {
|
||||||
println!("{} - {} - {}",
|
println!("{} - {}", record.level(), record.args());
|
||||||
time::strftime("%F %T", &time::now()).expect("Failed to format timestamp"),
|
let mut file = self.file.lock().expect("Lock poisoned");
|
||||||
record.level(),
|
if let &mut Some(ref mut file) = &mut file as &mut Option<File> {
|
||||||
record.args()
|
let time = time::strftime("%F %T", &time::now()).expect("Failed to format timestamp");
|
||||||
);
|
writeln!(file, "{} - {} - {}", time, record.level(), record.args()).expect("Failed to write to logfile");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -153,6 +176,20 @@ fn run<T: Protocol> (config: Config) {
|
||||||
try_fail!(cloud.connect(&addr as &str), "Failed to send message to {}: {}", &addr);
|
try_fail!(cloud.connect(&addr as &str), "Failed to send message to {}: {}", &addr);
|
||||||
cloud.add_reconnect_peer(addr);
|
cloud.add_reconnect_peer(addr);
|
||||||
}
|
}
|
||||||
|
if config.daemonize {
|
||||||
|
info!("Running process as daemon");
|
||||||
|
let mut daemonize = daemonize::Daemonize::new();
|
||||||
|
if let Some(user) = config.user {
|
||||||
|
daemonize = daemonize.user(&user as &str);
|
||||||
|
}
|
||||||
|
if let Some(group) = config.group {
|
||||||
|
daemonize = daemonize.group(&group as &str);
|
||||||
|
}
|
||||||
|
if let Some(pid_file) = config.pid_file {
|
||||||
|
daemonize = daemonize.pid_file(pid_file).chown_pid_file(true);
|
||||||
|
}
|
||||||
|
try_fail!(daemonize.start(), "Failed to daemonize: {}");
|
||||||
|
}
|
||||||
cloud.run();
|
cloud.run();
|
||||||
if let Some(script) = config.ifdown {
|
if let Some(script) = config.ifdown {
|
||||||
run_script(script, cloud.ifname());
|
run_script(script, cloud.ifname());
|
||||||
|
@ -180,7 +217,7 @@ fn main() {
|
||||||
} else {
|
} else {
|
||||||
max_log_level.set(log::LogLevelFilter::Info);
|
max_log_level.set(log::LogLevelFilter::Info);
|
||||||
}
|
}
|
||||||
Box::new(SimpleLogger)
|
Box::new(try_fail!(DualLogger::new(args.flag_log_file.as_ref()), "Failed to open logfile: {}"))
|
||||||
}).unwrap();
|
}).unwrap();
|
||||||
let mut config = Config::default();
|
let mut config = Config::default();
|
||||||
if let Some(ref file) = args.flag_config {
|
if let Some(ref file) = args.flag_config {
|
||||||
|
|
|
@ -23,7 +23,13 @@ Options:
|
||||||
--ifup <command> A command to setup the network interface.
|
--ifup <command> A command to setup the network interface.
|
||||||
--ifdown <command> A command to bring down the network
|
--ifdown <command> A command to bring down the network
|
||||||
interface.
|
interface.
|
||||||
|
--pid-file <file> Store the process id in this file when
|
||||||
|
daemonizing.
|
||||||
|
--user <user> Run as other user when daemonizing.
|
||||||
|
--group <group> Run as other group when daemonizing.
|
||||||
|
--log-file <file> Print logs also to this file.
|
||||||
--no-port-forwarding Disable automatic port forward.
|
--no-port-forwarding Disable automatic port forward.
|
||||||
|
--daemon Run the process in the background.
|
||||||
-v, --verbose Print debug information.
|
-v, --verbose Print debug information.
|
||||||
-q, --quiet Only print errors and warnings.
|
-q, --quiet Only print errors and warnings.
|
||||||
-h, --help Display the help.
|
-h, --help Display the help.
|
||||||
|
|
40
vpncloud.md
40
vpncloud.md
|
@ -88,6 +88,8 @@ vpncloud(1) -- Peer-to-peer VPN
|
||||||
parameter to `sh -c`) when the device has been created to configure it.
|
parameter to `sh -c`) when the device has been created to configure it.
|
||||||
The name of the allocated device will be available via the environment
|
The name of the allocated device will be available via the environment
|
||||||
variable `IFNAME`.
|
variable `IFNAME`.
|
||||||
|
Please note that this command is executed with the full permissions of the
|
||||||
|
caller.
|
||||||
|
|
||||||
* `--ifdown <command>`:
|
* `--ifdown <command>`:
|
||||||
|
|
||||||
|
@ -95,6 +97,36 @@ vpncloud(1) -- Peer-to-peer VPN
|
||||||
parameter to `sh -c`) to remove any configuration from the device.
|
parameter to `sh -c`) to remove any configuration from the device.
|
||||||
The name of the allocated device will be available via the environment
|
The name of the allocated device will be available via the environment
|
||||||
variable `IFNAME`.
|
variable `IFNAME`.
|
||||||
|
Please note that this command is executed with the (limited) permissions of
|
||||||
|
the user and group given as `--user` and `--group`.
|
||||||
|
|
||||||
|
* `--pid-file <file>`:
|
||||||
|
|
||||||
|
Store the process id in this file when running in the background. If set,
|
||||||
|
the given file will be created containing the process id of the new
|
||||||
|
background process. This option is only used when running in background.
|
||||||
|
|
||||||
|
* `--user <user>`:
|
||||||
|
* `--group <group>`:
|
||||||
|
|
||||||
|
Change the user and/or group of the process once all the setup has been
|
||||||
|
done and before spawning the background process. This option is only used
|
||||||
|
when running in background.
|
||||||
|
|
||||||
|
* `--log-file <file>`:
|
||||||
|
|
||||||
|
If set, print logs also to the given file. The file will be created and
|
||||||
|
truncated if is exists.
|
||||||
|
|
||||||
|
* `--daemon`:
|
||||||
|
|
||||||
|
Spawn a background process instead of running the process in the foreground.
|
||||||
|
If this flag is set, the process will first carry out all the
|
||||||
|
initialization, then drop permissions if `--user` or `--group` is used and
|
||||||
|
then spawn a background process and write its process id to a file if
|
||||||
|
`--pid-file` is set. Then, the main process will exit and the background
|
||||||
|
process continues to provide the VPN. At the time, when the main process
|
||||||
|
exits, the interface exists and is properly configured to be used.
|
||||||
|
|
||||||
* `--no-port-forwarding`:
|
* `--no-port-forwarding`:
|
||||||
|
|
||||||
|
@ -245,6 +277,9 @@ detailed descriptions of the options.
|
||||||
* `dst_timeout`: Switch table entry timeout in seconds. Same as `--dst-timeout`
|
* `dst_timeout`: Switch table entry timeout in seconds. Same as `--dst-timeout`
|
||||||
* `subnets`: A list of local subnets to use. See `--subnet`
|
* `subnets`: A list of local subnets to use. See `--subnet`
|
||||||
* `port_forwarding`: Whether to activate port forwardig. See `--no-port-forwarding`
|
* `port_forwarding`: Whether to activate port forwardig. See `--no-port-forwarding`
|
||||||
|
* `user`: The name of a user to run the background process under. See `--user`
|
||||||
|
* `group`: The name of a group to run the background process under. See `--group`
|
||||||
|
* `pid_file`: The path of the pid file to create. See `--pid-file`
|
||||||
|
|
||||||
|
|
||||||
### Example
|
### Example
|
||||||
|
@ -263,6 +298,9 @@ mode: normal
|
||||||
subnets:
|
subnets:
|
||||||
- 10.0.1.0/24
|
- 10.0.1.0/24
|
||||||
port_forwarding: true
|
port_forwarding: true
|
||||||
|
user: nobody
|
||||||
|
group: nogroup
|
||||||
|
pid_file: /run/vpncloud.pid
|
||||||
|
|
||||||
|
|
||||||
## NETWORK PROTOCOL
|
## NETWORK PROTOCOL
|
||||||
|
@ -297,7 +335,7 @@ Every packet sent over UDP contains the following header (in order):
|
||||||
`libsodium::crypto_aead_aes256gcm` method, using the 8 byte header
|
`libsodium::crypto_aead_aes256gcm` method, using the 8 byte header
|
||||||
as additional data.
|
as additional data.
|
||||||
|
|
||||||
* 2 `reserved bytes` that are currently unused
|
* 2 `reserved bytes` that are currently unused and set to 0
|
||||||
|
|
||||||
* 1 byte for the `message type`
|
* 1 byte for the `message type`
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue