First Windows plan

This commit is contained in:
Dennis Schwerdel 2020-12-20 23:36:27 +01:00
parent edd0e7a29f
commit 82e3ffedf3
5 changed files with 83 additions and 101 deletions

70
Cargo.lock generated
View File

@ -43,12 +43,6 @@ version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
[[package]]
name = "boxfnonce"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5988cb1d626264ac94100be357308f29ff7cbdd3b36bda27f450a4ee3f713426"
[[package]]
name = "bumpalo"
version = "3.4.0"
@ -106,16 +100,6 @@ version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd51eab21ab4fd6a3bf889e2d0958c0a6e3a61ad04260325e919e652a2a62826"
[[package]]
name = "daemonize"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70c24513e34f53b640819f0ac9f705b673fcf4006d7aab8778bee72ebfc89815"
dependencies = [
"boxfnonce",
"libc",
]
[[package]]
name = "discard"
version = "1.0.4"
@ -267,31 +251,6 @@ version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
[[package]]
name = "nix"
version = "0.14.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c722bee1037d430d0f8e687bbdbf222f27cc6e4e68d5caf630857bb2b6dbdce"
dependencies = [
"bitflags",
"cc",
"cfg-if 0.1.10",
"libc",
"void",
]
[[package]]
name = "nix"
version = "0.19.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b2ccba0cfe4fdf15982d1674c69b1fd80bad427d293849982668dfe454bd61f2"
dependencies = [
"bitflags",
"cc",
"cfg-if 1.0.0",
"libc",
]
[[package]]
name = "once_cell"
version = "1.5.2"
@ -310,16 +269,6 @@ version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
[[package]]
name = "privdrop"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ebd4c2739642e70439d1c0d9545beec45c1e54128739b3cda29bf2c366028c87"
dependencies = [
"libc",
"nix 0.19.1",
]
[[package]]
name = "proc-macro-error"
version = "1.0.4"
@ -555,16 +504,6 @@ version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d"
[[package]]
name = "signal"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2f6ce83b159ab6984d2419f495134972b48754d13ff2e3f8c998339942b56ed9"
dependencies = [
"libc",
"nix 0.14.1",
]
[[package]]
name = "smallvec"
version = "1.5.1"
@ -838,29 +777,20 @@ version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"
[[package]]
name = "void"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
[[package]]
name = "vpncloud"
version = "2.0.1"
dependencies = [
"byteorder",
"daemonize",
"fnv",
"igd",
"libc",
"log",
"privdrop",
"rand 0.8.0",
"ring",
"serde",
"serde_derive",
"serde_yaml",
"signal",
"smallvec",
"structopt",
"tempfile",

View File

@ -18,15 +18,15 @@ serde = "1.0"
serde_derive = "1.0"
serde_yaml = "0.8"
log = { version = "0.4", features = ["std"] }
signal = "0.7"
#signal = "0.7"
libc = "0.2"
rand = "0.8"
fnv = "1"
yaml-rust = "0.4"
igd = { version = "0.11", optional = true }
daemonize = "0.4"
#daemonize = "0.4"
ring = "0.16"
privdrop = "0.5"
#privdrop = "0.5"
byteorder = "1.3"
thiserror = "1.0"
smallvec = "1.5"

76
WINDOWS.md Normal file
View File

@ -0,0 +1,76 @@
# VpnCloud for Windows
## Toolchain
rustup target add x86_64-pc-windows-gnu
rustup toolchain install stable-x86_64-pc-windows-gnu
apt-get install mingw64
## Problems
### Running VpnCloud
**Problem:**
- Library "daemonize" does not compile
- Windows uses "Services" instead of daemonized processes
- Library "privdrop" does not compile
- Is dropping privileges in Windows services even a thing?
- Library "signal" does not compile
- Windows services work differently, no Ctrl-C handling needed
- Normal Windows programs can't stay active when the user logs out
**Potential solution:**
- Wrap VpnCloud as Windows service
- https://github.com/mullvad/windows-service-rs
- Do not support dropping privileges under Windows
### Polling solution
**Problem:**
- Epoll is Linux only
- RawFd is Unix only
**Potential solution:**
Use multi-threading to remove the need to wait on multiple events at the same time:
- One thread waits on the device and sends to the socket
- One thread waits on the socket and sends to the device and handles the control traffic
Problems to solve:
- Synchronization is slow
- Do not use locking in hot code, cache shared data locally and synchronize periodically
### Tun/Tap devices
**Problem:**
Tun/Tap works completely different on Windows
- Drivers need to be signed by Microsoft, complicated process
**Potential solution:**
Use existing Tun & Tap drivers:
- (Old) TapWindows from OpenVPN project
- https://community.openvpn.net/openvpn/wiki/GettingTapWindows
- https://github.com/Tazdevil971/tap-windows
- (New) WinTun from Wireguard
- https://www.wintun.net/
### Configuration
**Problem:**
- Windows users are not used to write config files and execute commands
- Windows setup is more complicated than in Linux (install Drivers, register Services, etc.)
**Potential solution:**
- Create configuration UI

View File

@ -189,30 +189,9 @@ fn run<P: Protocol>(config: Config) {
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);
// Give child process some time to write PID file
daemonize = daemonize.exit_action(|| thread::sleep(std::time::Duration::from_millis(10)));
}
try_fail!(daemonize.start(), "Failed to daemonize: {}");
error!("Daemonize not supported under windows");
} else if config.user.is_some() || config.group.is_some() {
info!("Dropping privileges");
let mut pd = privdrop::PrivDrop::default();
if let Some(user) = config.user {
pd = pd.user(user);
}
if let Some(group) = config.group {
pd = pd.group(group);
}
try_fail!(pd.apply(), "Failed to drop privileges: {}");
error!("Privdrop not supported under windows");
}
cloud.run();
if let Some(script) = config.ifdown {

View File

@ -12,7 +12,6 @@ use crate::error::Error;
#[cfg(not(target_os = "linux"))] use time;
use signal::{trap::Trap, Signal};
use smallvec::SmallVec;
use std::time::Instant;
@ -272,7 +271,6 @@ impl fmt::Display for Bytes {
pub struct CtrlC {
dummy_time: Instant,
trap: Trap
}
impl CtrlC {
@ -281,15 +279,14 @@ impl CtrlC {
}
pub fn was_pressed(&self) -> bool {
self.trap.wait(self.dummy_time).is_some()
false
}
}
impl Default for CtrlC {
fn default() -> Self {
let dummy_time = Instant::now();
let trap = Trap::trap(&[Signal::SIGINT, Signal::SIGTERM, Signal::SIGQUIT]);
Self { dummy_time, trap }
Self { dummy_time }
}
}