mirror of https://github.com/dswd/vpncloud.git
First Windows plan
This commit is contained in:
parent
edd0e7a29f
commit
82e3ffedf3
|
@ -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",
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
25
src/main.rs
25
src/main.rs
|
@ -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 {
|
||||
|
|
|
@ -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 }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue