mirror of
https://codeberg.org/icewind/netnsd.git
synced 2026-06-03 09:04:07 +02:00
copy ipv6 privacy settings into namespace
This commit is contained in:
parent
68bdbfab9b
commit
88f168b9e1
2 changed files with 100 additions and 2 deletions
|
|
@ -1,10 +1,12 @@
|
||||||
mod handle;
|
mod handle;
|
||||||
mod raw;
|
mod raw;
|
||||||
|
mod sysctl;
|
||||||
|
|
||||||
use crate::config::{DeviceName, NamespaceName};
|
use crate::config::{DeviceName, NamespaceName};
|
||||||
use crate::link::{LinkError, link_up, move_all_links, move_link_into};
|
use crate::link::{LinkError, link_up, move_all_links, move_link_into};
|
||||||
pub use crate::namespace::handle::{NamespaceHandle, NamespaceHandleError};
|
pub use crate::namespace::handle::{NamespaceHandle, NamespaceHandleError};
|
||||||
use crate::namespace::raw::{NamespaceSetupError, create_network_namespace};
|
use crate::namespace::raw::{NamespaceSetupError, create_network_namespace};
|
||||||
|
use crate::namespace::sysctl::{CtlError, NamespaceCtl};
|
||||||
use either::Either;
|
use either::Either;
|
||||||
use nix::errno::Errno;
|
use nix::errno::Errno;
|
||||||
use nix::mount::{MntFlags, MsFlags, mount, umount2};
|
use nix::mount::{MntFlags, MsFlags, mount, umount2};
|
||||||
|
|
@ -154,8 +156,12 @@ impl NetNs {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup_interfaces(&self) -> Result<(), NamespaceError> {
|
fn setup_interfaces(&self) -> Result<(), NamespaceError> {
|
||||||
self.handle
|
let ctl = NamespaceCtl::read()?;
|
||||||
.run_in(move || link_up("lo").map_err(NamespaceError::from))??;
|
self.handle.run_in(move || {
|
||||||
|
link_up("lo").map_err(NamespaceError::from)?;
|
||||||
|
dbg!(ctl).apply()?;
|
||||||
|
Ok::<_, NamespaceError>(())
|
||||||
|
})??;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -218,6 +224,8 @@ pub enum NamespaceError {
|
||||||
Enter(#[from] NamespaceEnterError),
|
Enter(#[from] NamespaceEnterError),
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Link(#[from] LinkError),
|
Link(#[from] LinkError),
|
||||||
|
#[error("Failed to setup sysctl for namespace: {0:#}")]
|
||||||
|
Sysctl(#[from] CtlError),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NamespaceError {
|
impl NamespaceError {
|
||||||
|
|
|
||||||
90
src/namespace/sysctl.rs
Normal file
90
src/namespace/sysctl.rs
Normal file
|
|
@ -0,0 +1,90 @@
|
||||||
|
use std::fmt::Display;
|
||||||
|
use std::fs::{File, OpenOptions};
|
||||||
|
use std::io::Write;
|
||||||
|
use std::io::{Error as IoError, ErrorKind, Read};
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
use std::str::FromStr;
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct NamespaceCtl {
|
||||||
|
use_temp_addr: u32,
|
||||||
|
temp_valid_lft: u32,
|
||||||
|
temp_preferred_lft: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
const PATH_TEMP_ADDR: &str = "/proc/sys/net/ipv6/conf/default/use_tempaddr";
|
||||||
|
const PATH_VALID_LFT: &str = "/proc/sys/net/ipv6/conf/default/temp_valid_lft";
|
||||||
|
const PATH_PREFERRED_LFT: &str = "/proc/sys/net/ipv6/conf/default/temp_prefered_lft";
|
||||||
|
|
||||||
|
impl NamespaceCtl {
|
||||||
|
pub fn read() -> Result<NamespaceCtl, CtlError> {
|
||||||
|
Ok(NamespaceCtl {
|
||||||
|
use_temp_addr: read_sysctl(PATH_TEMP_ADDR)?,
|
||||||
|
temp_valid_lft: read_sysctl(PATH_VALID_LFT)?,
|
||||||
|
temp_preferred_lft: read_sysctl(PATH_PREFERRED_LFT)?,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn apply(&self) -> Result<(), CtlError> {
|
||||||
|
write_sysctl(PATH_TEMP_ADDR, self.use_temp_addr)?;
|
||||||
|
write_sysctl(PATH_VALID_LFT, self.temp_valid_lft)?;
|
||||||
|
write_sysctl(PATH_PREFERRED_LFT, self.temp_preferred_lft)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_sysctl<T: FromStr, P: AsRef<Path>>(path: P) -> Result<T, CtlError>
|
||||||
|
where
|
||||||
|
<T as FromStr>::Err: Display,
|
||||||
|
{
|
||||||
|
let path = path.as_ref();
|
||||||
|
let mut buff = [0; 16];
|
||||||
|
let mut file = File::open(path).map_err(|error| CtlError::Read {
|
||||||
|
path: path.into(),
|
||||||
|
error,
|
||||||
|
})?;
|
||||||
|
let read = file.read(&mut buff).map_err(|error| CtlError::Read {
|
||||||
|
path: path.into(),
|
||||||
|
error,
|
||||||
|
})?;
|
||||||
|
let data = &buff[0..read];
|
||||||
|
let str = str::from_utf8(data)
|
||||||
|
.map_err(|_| CtlError::Read {
|
||||||
|
path: path.into(),
|
||||||
|
error: IoError::new(ErrorKind::InvalidData, "stream did not contain valid UTF-8"),
|
||||||
|
})?
|
||||||
|
.trim();
|
||||||
|
T::from_str(str).map_err(|error| CtlError::Parse {
|
||||||
|
path: path.into(),
|
||||||
|
error: error.to_string(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write_sysctl<T: Display, P: AsRef<Path>>(path: P, value: T) -> Result<(), CtlError> {
|
||||||
|
let path = path.as_ref();
|
||||||
|
|
||||||
|
let mut file = OpenOptions::new()
|
||||||
|
.create(false)
|
||||||
|
.truncate(true)
|
||||||
|
.write(true)
|
||||||
|
.open(path)
|
||||||
|
.map_err(|error| CtlError::Write {
|
||||||
|
path: path.into(),
|
||||||
|
error,
|
||||||
|
})?;
|
||||||
|
writeln!(&mut file, "{value}").map_err(|error| CtlError::Write {
|
||||||
|
path: path.into(),
|
||||||
|
error,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
pub enum CtlError {
|
||||||
|
#[error("failed to read sysctl option {}: {error:#}", path.display())]
|
||||||
|
Read { path: PathBuf, error: IoError },
|
||||||
|
#[error("failed to read sysctl option {}: {error}", path.display())]
|
||||||
|
Parse { path: PathBuf, error: String },
|
||||||
|
#[error("failed to write sysctl option {}: {error:#}", path.display())]
|
||||||
|
Write { path: PathBuf, error: IoError },
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue