WIP
This commit is contained in:
parent
2947383d1a
commit
97e7da22fb
|
|
@ -42,6 +42,16 @@ pub enum Target {
|
|||
Host,
|
||||
}
|
||||
|
||||
impl Target {
|
||||
pub fn is_ipv4_default_route(&self) -> bool {
|
||||
matches!(self, Target::Prefix(prefix) if *prefix == Ipv4Net::zero())
|
||||
}
|
||||
|
||||
pub fn is_mac_address(&self) -> bool {
|
||||
matches!(self, Target::MacAddress(_))
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for Target {
|
||||
type Err = ipnet::AddrParseError;
|
||||
|
||||
|
|
@ -69,17 +79,11 @@ impl Proxy<'_> {
|
|||
vm_fd: RawFd,
|
||||
vm_mac_address: MacAddress,
|
||||
vm_net_type: NetType,
|
||||
enable_isolation: bool,
|
||||
allow: Vec<Target>,
|
||||
block: Vec<Target>,
|
||||
exposed_ports: Vec<ExposedPort>,
|
||||
) -> Result<Proxy<'proxy>> {
|
||||
let allowing_all_ipv4 = allow.contains(&Target::Prefix(Ipv4Net::zero()));
|
||||
let using_mac_filtering = allow
|
||||
.iter()
|
||||
.chain(block.iter())
|
||||
.any(|target| matches!(target, Target::MacAddress(_)));
|
||||
let enable_isolation = !allowing_all_ipv4 && !using_mac_filtering;
|
||||
|
||||
let vm = VM::new(vm_fd)?;
|
||||
let host = Host::new(vm_net_type, enable_isolation)?;
|
||||
let poller_timeout = Duration::from_millis(100);
|
||||
|
|
@ -226,7 +230,7 @@ impl Proxy<'_> {
|
|||
mod tests {
|
||||
use crate::NetType;
|
||||
use crate::dhcp_snooper::Lease;
|
||||
use crate::proxy::{Action, Proxy};
|
||||
use crate::proxy::{Action, Proxy, Target};
|
||||
use ipnet::Ipv4Net;
|
||||
use mac_address::MacAddress;
|
||||
use nix::sys::socket::{AddressFamily, SockFlag, SockType, socketpair};
|
||||
|
|
@ -329,18 +333,24 @@ mod tests {
|
|||
.unwrap();
|
||||
let vm_fd = Box::leak(Box::new(vm_fd));
|
||||
|
||||
let allow: Vec<Target> = allow
|
||||
.into_iter()
|
||||
.map(|cidr| cidr.parse().unwrap())
|
||||
.collect();
|
||||
let block: Vec<Target> = block
|
||||
.into_iter()
|
||||
.map(|cidr| cidr.parse().unwrap())
|
||||
.collect();
|
||||
let enable_isolation = !allow.iter().any(Target::is_ipv4_default_route)
|
||||
&& !allow.iter().chain(block.iter()).any(Target::is_mac_address);
|
||||
|
||||
let mut proxy = Proxy::new(
|
||||
vm_fd.as_raw_fd(),
|
||||
MacAddress::from_str("02:00:00:00:00:01").unwrap(),
|
||||
NetType::Nat,
|
||||
allow
|
||||
.into_iter()
|
||||
.map(|cidr| cidr.parse().unwrap())
|
||||
.collect(),
|
||||
block
|
||||
.into_iter()
|
||||
.map(|cidr| cidr.parse().unwrap())
|
||||
.collect(),
|
||||
enable_isolation,
|
||||
allow,
|
||||
block,
|
||||
Vec::default(),
|
||||
)
|
||||
.unwrap();
|
||||
|
|
|
|||
52
src/main.rs
52
src/main.rs
|
|
@ -194,11 +194,14 @@ fn try_main() -> anyhow::Result<()> {
|
|||
// Set bootpd(8) min/max lease time while still having the root privileges
|
||||
set_bootpd_lease_time(args.bootpd_lease_time);
|
||||
|
||||
let enable_isolation = bridge_isolation_enabled(&args.allow, &args.block);
|
||||
|
||||
// Initialize the proxy while still having the root privileges
|
||||
let mut proxy = Proxy::new(
|
||||
args.vm_fd as RawFd,
|
||||
args.vm_mac_address,
|
||||
args.vm_net_type,
|
||||
enable_isolation,
|
||||
args.allow,
|
||||
args.block,
|
||||
args.expose,
|
||||
|
|
@ -231,6 +234,14 @@ fn sudo_escalation_works() -> bool {
|
|||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
fn bridge_isolation_enabled(allow: &[Target], block: &[Target]) -> bool {
|
||||
let disables_isolation_for_compat = allow.iter().any(Target::is_ipv4_default_route);
|
||||
let disables_isolation_for_mac_filtering =
|
||||
allow.iter().chain(block.iter()).any(Target::is_mac_address);
|
||||
|
||||
!(disables_isolation_for_compat || disables_isolation_for_mac_filtering)
|
||||
}
|
||||
|
||||
fn set_bootpd_lease_time(lease_time: u32) {
|
||||
let prefs = SCPreferences::group(
|
||||
&CFString::new("softnet"),
|
||||
|
|
@ -252,3 +263,44 @@ fn set_bootpd_lease_time(lease_time: u32) {
|
|||
SCPreferencesCommitChanges(prefs.as_concrete_TypeRef());
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
fn targets(values: &[&str]) -> Vec<Target> {
|
||||
values.iter().map(|value| value.parse().unwrap()).collect()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bridge_isolation_disabled_for_legacy_allow_default_route() {
|
||||
assert!(!bridge_isolation_enabled(
|
||||
&targets(&["0.0.0.0/0"]),
|
||||
&targets(&[])
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bridge_isolation_disabled_for_legacy_allow_default_route_even_when_blocked() {
|
||||
assert!(!bridge_isolation_enabled(
|
||||
&targets(&["0.0.0.0/0"]),
|
||||
&targets(&["0.0.0.0/0"])
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bridge_isolation_kept_for_block_default_route_only() {
|
||||
assert!(bridge_isolation_enabled(
|
||||
&targets(&[]),
|
||||
&targets(&["0.0.0.0/0"])
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bridge_isolation_disabled_for_mac_filtering() {
|
||||
assert!(!bridge_isolation_enabled(
|
||||
&targets(&[]),
|
||||
&targets(&["02:00:00:00:00:02"])
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue