Skip to content

Commit

Permalink
Merge pull request #242 from jamesmcm/create_netns_only
Browse files Browse the repository at this point in the history
Add create-netns-only argument for debugging + firejail usage
  • Loading branch information
jamesmcm authored Nov 26, 2023
2 parents 688cbe3 + 18ea6c2 commit d28845d
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 33 deletions.
16 changes: 16 additions & 0 deletions USERGUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,22 @@ entire shell sessions inside vopono.
Note that the order of command-line arguments matters, as the `--dns`
argument can take a list of DNS servers for example.

### Creating only Network Namespace

You can run vopono to create only the network namespace using the
`--create-netns-only` argument, the application related arguments are
then ignored (pass anything as the application name). This can be useful
for debugging connection issues.

This can also be used to launch an application without sudo via firejail
- e.g. (where `none` is passed as the dummy application):

```bash
$ vopono -v exec --provider protonvpn --server japan --protocol openvpn --create-netns-only none
2023-11-26T11:17:52.623Z INFO vopono::exec > Created netns vo_pr_japan - will leave network namespace alive until ctrl+C received
$ firejail --netns=vo_pr_japan firefox-developer-edition
```
### Configuration file
You can save default configuration options in the config file
Expand Down
4 changes: 4 additions & 0 deletions src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,10 @@ pub struct ExecCommand {
/// Enable port forwarding for ProtonVPN connections
#[clap(long = "protonvpn-port-forwarding")]
pub protonvpn_port_forwarding: bool,

/// Only create network namespace (does not run application)
#[clap(long = "create-netns-only")]
pub create_netns_only: bool,
}

#[derive(Parser)]
Expand Down
73 changes: 47 additions & 26 deletions src/exec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,17 @@ pub fn exec(command: ExecCommand, uiclient: &dyn UiClient) -> anyhow::Result<()>
command.protonvpn_port_forwarding
};

// Create netns only
let create_netns_only = if !command.create_netns_only {
vopono_config_settings
.get("create-netns-only")
.map_err(|_e| anyhow!("Failed to read config file"))
.ok()
.unwrap_or(false)
} else {
command.create_netns_only
};

// Assign DNS server from args or vopono config file
let base_dns = command.dns.clone().or_else(|| {
vopono_config_settings
Expand Down Expand Up @@ -551,15 +562,6 @@ pub fn exec(command: ExecCommand, uiclient: &dyn UiClient) -> anyhow::Result<()>
vopono_core::util::open_ports(&ns, &[pmpc.local_port], firewall)?;
}

let application = ApplicationWrapper::new(
&ns,
&command.application,
user,
group,
working_directory.map(PathBuf::from),
natpmpc,
)?;

// Launch TCP proxy server on other threads if forwarding ports
// TODO: Fix when running as root
let mut proxy = Vec::new();
Expand All @@ -580,27 +582,46 @@ pub fn exec(command: ExecCommand, uiclient: &dyn UiClient) -> anyhow::Result<()>
}
}

let pid = application.handle.id();
info!(
"Application {} launched in network namespace {} with pid {}",
&command.application, &ns.name, pid
);
if !create_netns_only {
let application = ApplicationWrapper::new(
&ns,
&command.application,
user,
group,
working_directory.map(PathBuf::from),
natpmpc,
)?;

if let Some(pmpc) = application.protonvpn_port_forwarding.as_ref() {
info!("ProtonVPN Port Forwarding on port {}", pmpc.local_port)
}
let output = application.wait_with_output()?;
io::stdout().write_all(output.stdout.as_slice())?;
let pid = application.handle.id();
info!(
"Application {} launched in network namespace {} with pid {}",
&command.application, &ns.name, pid
);

// Allow daemons to leave namespace open
if vopono_core::util::check_process_running(pid) {
if let Some(pmpc) = application.protonvpn_port_forwarding.as_ref() {
info!("ProtonVPN Port Forwarding on port {}", pmpc.local_port)
}
let output = application.wait_with_output()?;
io::stdout().write_all(output.stdout.as_slice())?;

// Allow daemons to leave namespace open
if vopono_core::util::check_process_running(pid) {
info!(
"Process {} still running, assumed to be daemon - will leave network namespace {} alive until ctrl+C received",
pid, &ns.name
);
stay_alive(Some(pid), signals);
} else if command.keep_alive {
info!(
"Keep-alive flag active - will leave network namespace {} alive until ctrl+C received", &ns.name
);
stay_alive(None, signals);
}
} else {
info!(
"Process {} still running, assumed to be daemon - will leave network namespace alive until ctrl+C received",
pid
"Created netns {} - will leave network namespace alive until ctrl+C received",
&ns.name
);
stay_alive(Some(pid), signals);
} else if command.keep_alive {
info!("Keep-alive flag active - will leave network namespace alive until ctrl+C received");
stay_alive(None, signals);
}

Expand Down
9 changes: 4 additions & 5 deletions vopono_core/src/network/shadowsocks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ use log::{debug, error};
use rand::seq::SliceRandom;
use regex::Regex;
use serde::{Deserialize, Serialize};
use std::convert::TryFrom;
use std::fs::read_to_string;
use std::net::{IpAddr, Ipv4Addr};
use std::path::Path;
Expand Down Expand Up @@ -95,9 +94,9 @@ pub fn uses_shadowsocks(openvpn_config: &Path) -> anyhow::Result<Option<(IpAddr,
}
debug!("socks-proxy detected, will launch Shadowsocks server");
Ok(Some((
IpAddr::try_from(Ipv4Addr::from_str(
IpAddr::from(Ipv4Addr::from_str(
cap.as_ref().unwrap().get(1).unwrap().as_str(),
)?)?,
)?),
cap.unwrap().get(2).unwrap().as_str().parse::<u16>()?,
)))
}
Expand All @@ -113,9 +112,9 @@ pub fn get_routes_from_config(path: &Path) -> anyhow::Result<Vec<IpAddr>> {
let caps = re.captures_iter(&file_string);

for cap in caps {
output_vec.push(IpAddr::try_from(Ipv4Addr::from_str(
output_vec.push(IpAddr::from(Ipv4Addr::from_str(
cap.get(1).unwrap().as_str(),
)?)?);
)?));
}

if output_vec.is_empty() {
Expand Down
3 changes: 1 addition & 2 deletions vopono_core/src/util/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -353,8 +353,7 @@ pub fn elevate_privileges(askpass: bool) -> anyhow::Result<()> {
.status()
.context(format!("Executing sudo {} {:?}", sudo_flags, &args))?;

// Deprecated - do we need to handle flag here?
// cleanup::cleanup_signal(SIGINT)?;
// TODO: Could handle executing with non-sudo firejail here

if terminated.load(Ordering::SeqCst) {
// we received a sigint,
Expand Down

0 comments on commit d28845d

Please sign in to comment.