Skip to content

Commit

Permalink
Added dns-servers and ignore-dns-servers options
Browse files Browse the repository at this point in the history
  • Loading branch information
ancwrd1 committed Dec 20, 2024
1 parent 49a5296 commit 90f70b5
Show file tree
Hide file tree
Showing 9 changed files with 149 additions and 23 deletions.
2 changes: 2 additions & 0 deletions options.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
| `cert-id=<cert_id>` | hexadecimal ID of PKCS11 certificate, bytes could be optionally separated with colon |
| `search-domains=<search_domains>` | additional search domains for DNS resolver, comma-separated |
| `ignore-search-domains=<ignored_domains>` | acquired search domains to ignore |
| `dns-servers=<dns_servers>` | additional DNS servers, comma-separated |
| `ignore-dns-servers=<ignored_dns>` | acquired DNS servers to ignore, comma-separated |
| `default-route=true\|false` | set default route through the VPN tunnel, default is false |
| `no-routing=true\|false` | ignore all routes acquired from the VPN server, default is false |
| `add-routes=<routes>` | additional static routes, comma-separated, in the format of x.x.x.x/x |
Expand Down
68 changes: 66 additions & 2 deletions snx-rs-gui/src/settings.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use std::{path::Path, rc::Rc, sync::Arc, time::Duration};

use anyhow::anyhow;
use async_channel::Sender;
use gtk::{
Expand All @@ -8,6 +6,8 @@ use gtk::{
Align, ButtonsType, DialogFlags, MessageType, Orientation, ResponseType, WindowPosition,
};
use ipnet::Ipv4Net;
use std::net::Ipv4Addr;
use std::{path::Path, rc::Rc, sync::Arc, time::Duration};
use tracing::warn;

use crate::tray::TrayCommand;
Expand Down Expand Up @@ -43,6 +43,8 @@ struct MyWidgets {
no_dns: gtk::CheckButton,
search_domains: gtk::Entry,
ignored_domains: gtk::Entry,
dns_servers: gtk::Entry,
ignored_dns_servers: gtk::Entry,
no_routing: gtk::CheckButton,
default_routing: gtk::CheckButton,
add_routes: gtk::Entry,
Expand Down Expand Up @@ -101,6 +103,20 @@ impl MyWidgets {
self.esp_lifetime.text().parse::<u32>()?;
self.ike_port.text().parse::<u16>()?;

let dns_servers = self.dns_servers.text();
if !dns_servers.is_empty() {
for r in dns_servers.split(',') {
r.parse::<Ipv4Addr>()?;
}
}

let ignored_dns_servers = self.ignored_dns_servers.text();
if !ignored_dns_servers.is_empty() {
for r in ignored_dns_servers.split(',') {
r.parse::<Ipv4Addr>()?;
}
}

let add_routes = self.add_routes.text();
if !add_routes.is_empty() {
for r in add_routes.split(',') {
Expand Down Expand Up @@ -155,6 +171,30 @@ impl SettingsDialog {
.text(params.ignore_search_domains.join(","))
.build();

let dns_servers = gtk::Entry::builder()
.placeholder_text("Comma-separated IP addresses")
.text(
params
.dns_servers
.iter()
.map(|r| r.to_string())
.collect::<Vec<_>>()
.join(","),
)
.build();

let ignored_dns_servers = gtk::Entry::builder()
.placeholder_text("Comma-separated IP addresses")
.text(
params
.ignore_dns_servers
.iter()
.map(|r| r.to_string())
.collect::<Vec<_>>()
.join(","),
)
.build();

let no_routing = gtk::CheckButton::builder().active(params.no_routing).build();
let default_routing = gtk::CheckButton::builder().active(params.default_route).build();

Expand Down Expand Up @@ -336,6 +376,8 @@ impl SettingsDialog {
no_dns,
search_domains,
ignored_domains,
dns_servers,
ignored_dns_servers,
no_routing,
default_routing,
add_routes,
Expand Down Expand Up @@ -418,6 +460,20 @@ impl SettingsDialog {
.split(',')
.map(|s| s.trim().to_owned())
.collect();
params.dns_servers = self
.widgets
.dns_servers
.text()
.split(',')
.flat_map(|s| s.trim().parse().ok())
.collect();
params.ignore_dns_servers = self
.widgets
.ignored_dns_servers
.text()
.split(',')
.flat_map(|s| s.trim().parse().ok())
.collect();
params.no_routing = self.widgets.no_routing.is_active();
params.default_route = self.widgets.default_routing.is_active();
params.add_routes = self
Expand Down Expand Up @@ -580,6 +636,14 @@ impl SettingsDialog {
no_dns.pack_start(&self.widgets.no_dns, false, true, 0);
dns_box.pack_start(&no_dns, false, true, 6);

let dns_servers = self.form_box("Additional DNS servers");
dns_servers.pack_start(&self.widgets.dns_servers, false, true, 0);
dns_box.pack_start(&dns_servers, false, true, 6);

let ignored_dns_servers = self.form_box("Ignored DNS servers");
ignored_dns_servers.pack_start(&self.widgets.ignored_dns_servers, false, true, 0);
dns_box.pack_start(&ignored_dns_servers, false, true, 6);

let search_domains = self.form_box("Additional search domains");
search_domains.pack_start(&self.widgets.search_domains, false, true, 0);
dns_box.pack_start(&search_domains, false, true, 6);
Expand Down
28 changes: 26 additions & 2 deletions snx-rs/src/cmdline.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::{path::PathBuf, time::Duration};

use clap::Parser;
use ipnet::Ipv4Net;
use std::net::Ipv4Addr;
use std::{path::PathBuf, time::Duration};
use tracing::level_filters::LevelFilter;

use snxcore::model::params::{CertType, OperationMode, TunnelParams, TunnelType};
Expand Down Expand Up @@ -52,6 +52,22 @@ pub struct CmdlineParams {
)]
pub ignore_search_domains: Vec<String>,

#[clap(
long = "dns-servers",
short = 'D',
value_delimiter = ',',
help = "Additional DNS servers"
)]
pub dns_servers: Vec<Ipv4Addr>,

#[clap(
long = "ignore-dns-servers",
short = 'G',
value_delimiter = ',',
help = "Ignore specified DNS servers from the acquired list"
)]
pub ignore_dns_servers: Vec<Ipv4Addr>,

#[clap(
long = "default-route",
short = 't',
Expand Down Expand Up @@ -215,6 +231,14 @@ impl CmdlineParams {
other.ignore_search_domains = self.ignore_search_domains;
}

if !self.dns_servers.is_empty() {
other.dns_servers = self.dns_servers;
}

if !self.ignore_dns_servers.is_empty() {
other.ignore_dns_servers = self.ignore_dns_servers;
}

if let Some(default_route) = self.default_route {
other.default_route = default_route;
}
Expand Down
38 changes: 32 additions & 6 deletions snxcore/src/model/params.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
use anyhow::anyhow;
use base64::Engine;
use directories_next::ProjectDirs;
use ipnet::Ipv4Net;
use serde::{Deserialize, Serialize};
use std::net::Ipv4Addr;
use std::{
fmt, fs,
io::{Cursor, Write},
path::{Path, PathBuf},
str::FromStr,
time::Duration,
};

use anyhow::anyhow;
use base64::Engine;
use directories_next::ProjectDirs;
use ipnet::Ipv4Net;
use serde::{Deserialize, Serialize};
use tracing::warn;

use crate::util;
Expand Down Expand Up @@ -202,6 +202,8 @@ pub struct TunnelParams {
pub log_level: String,
pub search_domains: Vec<String>,
pub ignore_search_domains: Vec<String>,
pub dns_servers: Vec<Ipv4Addr>,
pub ignore_dns_servers: Vec<Ipv4Addr>,
pub default_route: bool,
pub no_routing: bool,
pub add_routes: Vec<Ipv4Net>,
Expand Down Expand Up @@ -239,6 +241,8 @@ impl Default for TunnelParams {
log_level: "off".to_owned(),
search_domains: Vec::new(),
ignore_search_domains: Vec::new(),
dns_servers: Vec::new(),
ignore_dns_servers: Vec::new(),
default_route: false,
no_routing: false,
add_routes: Vec::new(),
Expand Down Expand Up @@ -289,6 +293,10 @@ impl TunnelParams {
"ignore-search-domains" => {
params.ignore_search_domains = v.split(',').map(|s| s.trim().to_owned()).collect();
}
"dns-servers" => params.dns_servers = v.split(',').flat_map(|s| s.trim().parse().ok()).collect(),
"ignore-dns-servers" => {
params.ignore_dns_servers = v.split(',').flat_map(|s| s.trim().parse().ok()).collect();
}
"default-route" => params.default_route = v.parse().unwrap_or_default(),
"no-routing" => params.no_routing = v.parse().unwrap_or_default(),
"add-routes" => params.add_routes = v.split(',').flat_map(|s| s.trim().parse().ok()).collect(),
Expand Down Expand Up @@ -341,6 +349,24 @@ impl TunnelParams {
)?;
writeln!(buf, "search-domains={}", self.search_domains.join(","))?;
writeln!(buf, "ignore-search-domains={}", self.ignore_search_domains.join(","))?;
writeln!(
buf,
"dns-servers={}",
self.dns_servers
.iter()
.map(|r| r.to_string())
.collect::<Vec<_>>()
.join(",")
)?;
writeln!(
buf,
"ignore-dns-servers={}",
self.ignore_dns_servers
.iter()
.map(|r| r.to_string())
.collect::<Vec<_>>()
.join(",")
)?;
writeln!(buf, "default-route={}", self.default_route)?;
writeln!(buf, "no-routing={}", self.no_routing)?;
writeln!(
Expand Down
2 changes: 1 addition & 1 deletion snxcore/src/model/proto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ impl Serialize for AuthenticationAlgorithm {
pub struct OfficeMode {
pub ipaddr: String,
pub keep_address: Option<bool>,
pub dns_servers: Option<Vec<String>>,
pub dns_servers: Option<Vec<Ipv4Addr>>,
pub dns_suffix: Option<QuotedStringList>,
}

Expand Down
2 changes: 1 addition & 1 deletion snxcore/src/platform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ async fn udp_send_receive(socket: &UdpSocket, data: &[u8], timeout: Duration) ->
#[derive(Debug, Clone, Default, PartialEq)]
pub struct ResolverConfig {
pub search_domains: Vec<String>,
pub dns_servers: Vec<String>,
pub dns_servers: Vec<Ipv4Addr>,
}

#[async_trait]
Expand Down
12 changes: 7 additions & 5 deletions snxcore/src/platform/linux/resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ impl ResolverConfigurator for SystemdResolvedConfigurator {
crate::util::run_command("resolvectl", args).await?;
crate::util::run_command("resolvectl", ["default-route", &self.device, "false"]).await?;

let mut args = vec!["dns", &self.device];
let mut args = vec!["dns".to_owned(), self.device.clone()];

let servers = config.dns_servers.iter().map(|s| s.trim()).collect::<Vec<_>>();
let servers = config.dns_servers.iter().map(|s| s.to_string()).collect::<Vec<_>>();

args.extend(servers);

Expand Down Expand Up @@ -118,7 +118,9 @@ impl ResolvConfConfigurator {

let existing_nameservers = conf
.lines()
.filter(|line| line.starts_with("nameserver") && !config.dns_servers.iter().any(|s| line.contains(s)))
.filter(|line| {
line.starts_with("nameserver") && !config.dns_servers.iter().any(|s| line.contains(&s.to_string()))
})
.collect::<Vec<_>>();

let other_lines = conf
Expand Down Expand Up @@ -339,7 +341,7 @@ mod tests {

let config = ResolverConfig {
search_domains: vec!["dom1.com".to_owned(), "dom2.net".to_owned()],
dns_servers: vec!["192.168.1.1".to_owned(), "192.168.1.2".to_owned()],
dns_servers: vec!["192.168.1.1".parse().unwrap(), "192.168.1.2".parse().unwrap()],
};
cut.configure(&config).await.unwrap();

Expand All @@ -358,7 +360,7 @@ mod tests {

let config = ResolverConfig {
search_domains: vec!["dom1.com".to_owned(), "dom2.net".to_owned()],
dns_servers: vec!["192.168.1.1".to_owned(), "192.168.1.2".to_owned()],
dns_servers: vec!["192.168.1.1".parse().unwrap(), "192.168.1.2".parse().unwrap()],
};

cut.cleanup(&config).await.unwrap();
Expand Down
4 changes: 3 additions & 1 deletion snxcore/src/platform/linux/xfrm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,9 @@ impl XfrmConfigurator {
.ipsec_session
.dns
.iter()
.map(|server| server.to_string())
.chain(self.tunnel_params.dns_servers.iter())
.filter(|s| !self.tunnel_params.ignore_dns_servers.iter().any(|d| *d == **s))
.cloned()
.collect::<Vec<_>>();

let resolver = new_resolver_configurator(&self.name)?;
Expand Down
16 changes: 11 additions & 5 deletions snxcore/src/tunnel/ssl/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,17 @@ impl TunDevice {
Vec::new()
};

let dns_servers = if let Some(ref servers) = self.reply.office_mode.dns_servers {
servers.clone()
} else {
Vec::new()
};
let dns_servers = self
.reply
.office_mode
.dns_servers
.clone()
.unwrap_or_default()
.iter()
.chain(params.dns_servers.iter())
.filter(|s| !params.ignore_dns_servers.iter().any(|d| *d == **s))
.cloned()
.collect::<Vec<_>>();

let config = ResolverConfig {
search_domains,
Expand Down

0 comments on commit 90f70b5

Please sign in to comment.