Skip to content

Commit

Permalink
refactor: make a place for reverting /etc/resolv.conf
Browse files Browse the repository at this point in the history
  • Loading branch information
ReactorScram committed Mar 1, 2024
1 parent ed38112 commit 2b99970
Show file tree
Hide file tree
Showing 8 changed files with 53 additions and 22 deletions.
19 changes: 16 additions & 3 deletions rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions rust/connlib/shared/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ edition = "2021"
mock = []

[dependencies]
# Will be needed to safely modify `/etc/resolv.conf`
atomicwrites = "0.4.3"
secrecy = { workspace = true, features = ["serde", "bytes"] }
base64 = { version = "0.21", default-features = false, features = ["std"] }
boringtun = { workspace = true }
Expand All @@ -22,6 +24,7 @@ os_info = { version = "3", default-features = false }
parking_lot = "0.12"
rand = { version = "0.8", default-features = false, features = ["std"] }
rand_core = { version = "0.6.4", default-features = false, features = ["std"] }
resolv-conf = "0.7.0"
serde = { version = "1.0", default-features = false, features = ["derive", "std"] }
serde_json = { version = "1.0", default-features = false, features = ["std"] }
thiserror = { version = "1.0", default-features = false }
Expand All @@ -44,7 +47,9 @@ snownet = { workspace = true }
log = "0.4"

[dev-dependencies]
anyhow = "1.0"
itertools = "0.12"
tempfile = "3.10.0"

[target.'cfg(any(target_os = "macos", target_os = "ios"))'.dependencies]
swift-bridge = { workspace = true }
Expand Down
5 changes: 2 additions & 3 deletions rust/connlib/shared/src/linux.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@

const FIREZONE_DNS_CONTROL: &str = "FIREZONE_DNS_CONTROL";

pub const ETC_RESOLV_CONF: &str = "/etc/resolv.conf";
pub const ETC_RESOLV_CONF_BACKUP: &str = "/etc/resolv.conf.firezone-backup";
pub mod etc_resolv_conf;

#[derive(Clone, Debug)]
pub enum DnsControlMethod {
Expand All @@ -12,7 +11,7 @@ pub enum DnsControlMethod {
/// Only suitable for the Alpine CI containers and maybe something like an
/// embedded system
EtcResolvConf,
/// Cooperate with NetworkManager
/// Cooperate with NetworkManager (TODO)
NetworkManager,
/// Cooperate with `systemd-resolved`
///
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
use connlib_shared::{
linux::{ETC_RESOLV_CONF, ETC_RESOLV_CONF_BACKUP},
Error, Result,
};
use crate::{Error, Result};
use std::{net::IpAddr, path::Path};
use tokio::io::AsyncWriteExt;

/// Back up `/etc/resolve.conf` and then modify it in-place
pub const ETC_RESOLV_CONF: &str = "/etc/resolv.conf";
pub const ETC_RESOLV_CONF_BACKUP: &str = "/etc/resolv.conf.firezone-backup";

/// Back up `/etc/resolv.conf`(sic) and then modify it in-place
///
/// This is async because it's called in a Tokio context and it's nice to use their
/// `fs` module
pub async fn configure_dns(dns_config: &[IpAddr]) -> Result<()> {
configure_dns_at_paths(
dns_config,
Expand All @@ -15,6 +18,15 @@ pub async fn configure_dns(dns_config: &[IpAddr]) -> Result<()> {
.await
}

/// Revert changes Firezone made to `/etc/resolv.conf`
///
/// This is sync because it's called from the Linux CLI client where we don't have our own
/// Tokio context.
pub fn unconfigure_dns() -> Result<()> {
tracing::debug!("Unconfiguring `/etc/resolv.conf` not implemented yet");
Ok(())
}

async fn configure_dns_at_paths(
dns_config: &[IpAddr],
resolv_path: &Path,
Expand Down
3 changes: 0 additions & 3 deletions rust/connlib/tunnel/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ pnet_packet = { version = "0.34" }
futures-bounded = { workspace = true }
hickory-resolver = { workspace = true, features = ["tokio-runtime"] }
bimap = "0.6"
resolv-conf = "0.7.0"
socket2 = { version = "0.5" }
snownet = { workspace = true }
quinn-udp = { git = "https://github.com/quinn-rs/quinn", branch = "main"}
Expand All @@ -37,9 +36,7 @@ hex = "0.4.3"
log = "0.4"

[dev-dependencies]
anyhow = "1.0"
serde_json = "1.0"
tempfile = "3.10.0"

# Linux tunnel dependencies
[target.'cfg(target_os = "linux")'.dependencies]
Expand Down
5 changes: 3 additions & 2 deletions rust/connlib/tunnel/src/device_channel/tun_linux.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use crate::device_channel::ioctl;
use crate::FIREZONE_MARK;
use connlib_shared::{
linux::DnsControlMethod, messages::Interface as InterfaceConfig, Callbacks, Error, Result,
linux::{etc_resolv_conf, DnsControlMethod},
messages::Interface as InterfaceConfig,
Callbacks, Error, Result,
};
use futures::TryStreamExt;
use futures_util::future::BoxFuture;
Expand All @@ -28,7 +30,6 @@ use std::{
};
use tokio::io::unix::AsyncFd;

mod etc_resolv_conf;
mod utils;

pub(crate) const SIOCGIFMTU: libc::c_ulong = libc::SIOCGIFMTU;
Expand Down
2 changes: 2 additions & 0 deletions rust/linux-client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
# Will be needed to safely revert `/etc/resolv.conf`
atomicwrites = "0.4.3"
secrecy = { workspace = true }
connlib-client-shared = { workspace = true }
connlib-shared = { workspace = true }
Expand Down
14 changes: 8 additions & 6 deletions rust/linux-client/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
use anyhow::{Context, Result};
use clap::Parser;
use connlib_client_shared::{file_logger, Callbacks, Session};
use connlib_shared::linux::{
get_dns_control_from_env, DnsControlMethod, ETC_RESOLV_CONF, ETC_RESOLV_CONF_BACKUP,
};
use connlib_shared::linux::{etc_resolv_conf, get_dns_control_from_env, DnsControlMethod};
use firezone_cli_utils::{block_on_ctrl_c, setup_global_subscriber, CommonArgs};
use secrecy::SecretString;
use std::{net::IpAddr, path::PathBuf, str::FromStr};
Expand All @@ -17,7 +15,7 @@ fn main() -> Result<()> {

let dns_control_method = get_dns_control_from_env();
let callbacks = CallbackHandler {
dns_control_method,
dns_control_method: dns_control_method.clone(),
handle,
};

Expand All @@ -35,6 +33,10 @@ fn main() -> Result<()> {

block_on_ctrl_c();

if let Some(DnsControlMethod::EtcResolvConf) = dns_control_method {
etc_resolv_conf::unconfigure_dns()?;
}

session.disconnect(None);
Ok(())
}
Expand Down Expand Up @@ -92,8 +94,8 @@ impl Callbacks for CallbackHandler {
fn get_system_default_resolvers_resolv_conf() -> Result<Vec<IpAddr>> {
// Assume that `configure_resolv_conf` has run in `tun_linux.rs`

let s = std::fs::read_to_string(ETC_RESOLV_CONF_BACKUP)
.or_else(|_| std::fs::read_to_string(ETC_RESOLV_CONF))
let s = std::fs::read_to_string(etc_resolv_conf::ETC_RESOLV_CONF_BACKUP)
.or_else(|_| std::fs::read_to_string(etc_resolv_conf::ETC_RESOLV_CONF))
.context("`resolv.conf` should be readable")?;
let parsed = resolv_conf::Config::parse(s).context("`resolv.conf` should be parsable")?;

Expand Down

0 comments on commit 2b99970

Please sign in to comment.