1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
|
#![feature(test)]
#[macro_use] extern crate failure;
#[macro_use] extern crate structopt_derive;
#[macro_use] extern crate log;
extern crate chrono;
extern crate colored;
extern crate daemonize;
extern crate fern;
extern crate nix;
extern crate structopt;
extern crate wireguard;
use daemonize::Daemonize;
use failure::Error;
use fern::colors::{Color, ColoredLevelConfig};
use wireguard::interface::Interface;
use structopt::StructOpt;
#[derive(StructOpt, Debug)]
#[structopt(name = "wgrs", about = "WireGuard - a network tunnel")]
struct Opt {
/// A flag, true if used in the command line.
#[structopt(short = "d", long = "debug", help = "Activate debug mode")]
debug: bool,
/// An argument of type float, with a default value.
#[structopt(short = "f", long = "foreground", help = "Run in the foreground")]
foreground: bool,
/// Needed parameter, the first on the command line.
#[structopt(help = "WireGuard interface name", default_value = "utun4")]
interface: String,
/// An optional parameter, will be `None` if not present on the
/// command line.
#[structopt(help = "Output file, stdout if not present")]
output: Option<String>,
}
fn main() {
let opt = Opt::from_args();
let interface = opt.interface.clone();
let colors = ColoredLevelConfig::new()
.debug(Color::Magenta)
.info(Color::BrightBlue)
.warn(Color::BrightYellow)
.error(Color::BrightRed);
fern::Dispatch::new()
.format(move |out, message, record| {
let pad = record.level() == log::Level::Warn || record.level() == log::Level::Info;
out.finish(format_args!(
"{} {} {}{} {}",
chrono::Local::now().format("%H:%M:%S%.3f"),
interface,
colors.color(record.level()),
if pad { " " } else { "" },
message,
))
})
.level(log::LevelFilter::Warn)
// .level_for("wireguard", log::LevelFilter::Debug)
.chain(std::io::stdout())
.apply().unwrap();
if !opt.foreground {
daemonize().expect("failed to daemonize");
}
if let Err(e) = Interface::new(&opt.interface).start() {
error!("failed to start interface: {}", e);
}
}
fn daemonize() -> Result<(), Error> {
if !nix::unistd::getuid().is_root() {
bail!("You are not the root user which can spawn the daemon.");
}
debug!("Starting daemon.");
let daemonize = Daemonize::new()
.stream_redirect("/var/log/wireguard.log");
daemonize.start()?;
Ok(())
}
|