mirror of
https://github.com/YGGverse/aquatic.git
synced 2026-04-01 18:25:30 +00:00
aquatic: add setting for dropping privileges after opening sockets
This commit is contained in:
parent
e0526ac828
commit
6110017980
6 changed files with 89 additions and 1 deletions
30
Cargo.lock
generated
30
Cargo.lock
generated
|
|
@ -35,6 +35,7 @@ dependencies = [
|
||||||
"mio",
|
"mio",
|
||||||
"net2",
|
"net2",
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
|
"privdrop",
|
||||||
"quickcheck",
|
"quickcheck",
|
||||||
"quickcheck_macros",
|
"quickcheck_macros",
|
||||||
"rand",
|
"rand",
|
||||||
|
|
@ -425,6 +426,19 @@ dependencies = [
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nix"
|
||||||
|
version = "0.16.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dd0eaf8df8bab402257e0a5c17a254e4cc1f72a93588a1ddfb5d356c801aa7cb"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"cc",
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"void",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nodrop"
|
name = "nodrop"
|
||||||
version = "0.1.14"
|
version = "0.1.14"
|
||||||
|
|
@ -587,6 +601,16 @@ version = "0.2.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b"
|
checksum = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "privdrop"
|
||||||
|
version = "0.3.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "939fa7cbfef9c15c65cf2fb3ed57f3f2a14dca1757a556aa1ba4a7f998b2b479"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"nix",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.10"
|
version = "1.0.10"
|
||||||
|
|
@ -839,6 +863,12 @@ version = "0.9.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "078775d0255232fb988e6fccf26ddc9d1ac274299aaedcedce21c6f72cc533ce"
|
checksum = "078775d0255232fb988e6fccf26ddc9d1ac274299aaedcedce21c6f72cc533ce"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "void"
|
||||||
|
version = "1.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasi"
|
name = "wasi"
|
||||||
version = "0.9.0+wasi-snapshot-preview1"
|
version = "0.9.0+wasi-snapshot-preview1"
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,11 @@ interval = 5
|
||||||
interval = 30
|
interval = 30
|
||||||
max_peer_age = 1200
|
max_peer_age = 1200
|
||||||
max_connection_age = 300
|
max_connection_age = 300
|
||||||
|
|
||||||
|
[privileges]
|
||||||
|
drop_privileges = false
|
||||||
|
chroot_path = '.'
|
||||||
|
user = 'nobody'
|
||||||
```
|
```
|
||||||
|
|
||||||
To adjust the settings, save this text to a file and make your changes. The
|
To adjust the settings, save this text to a file and make your changes. The
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ mimalloc = { version = "0.1", default-features = false }
|
||||||
mio = { version = "0.7", features = ["udp", "os-poll", "os-util"] }
|
mio = { version = "0.7", features = ["udp", "os-poll", "os-util"] }
|
||||||
net2 = "0.2"
|
net2 = "0.2"
|
||||||
parking_lot = "0.10"
|
parking_lot = "0.10"
|
||||||
|
privdrop = "0.3"
|
||||||
rand = { version = "0.7", features = ["small_rng"] }
|
rand = { version = "0.7", features = ["small_rng"] }
|
||||||
serde = { version = "1", features = ["derive"] }
|
serde = { version = "1", features = ["derive"] }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ pub struct Config {
|
||||||
pub handlers: HandlerConfig,
|
pub handlers: HandlerConfig,
|
||||||
pub statistics: StatisticsConfig,
|
pub statistics: StatisticsConfig,
|
||||||
pub cleaning: CleaningConfig,
|
pub cleaning: CleaningConfig,
|
||||||
|
pub privileges: PrivilegeConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -80,6 +81,18 @@ pub struct CleaningConfig {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
|
#[serde(default)]
|
||||||
|
pub struct PrivilegeConfig {
|
||||||
|
/// Chroot and switch user after binding to sockets
|
||||||
|
pub drop_privileges: bool,
|
||||||
|
/// Chroot to this path
|
||||||
|
pub chroot_path: String,
|
||||||
|
/// User to switch to after chrooting
|
||||||
|
pub user: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
impl Default for Config {
|
impl Default for Config {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
|
@ -89,6 +102,7 @@ impl Default for Config {
|
||||||
handlers: HandlerConfig::default(),
|
handlers: HandlerConfig::default(),
|
||||||
statistics: StatisticsConfig::default(),
|
statistics: StatisticsConfig::default(),
|
||||||
cleaning: CleaningConfig::default(),
|
cleaning: CleaningConfig::default(),
|
||||||
|
privileges: PrivilegeConfig::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -136,3 +150,14 @@ impl Default for CleaningConfig {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl Default for PrivilegeConfig {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
drop_privileges: false,
|
||||||
|
chroot_path: ".".to_string(),
|
||||||
|
user: "nobody".to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
|
use std::sync::{Arc, atomic::{AtomicUsize, Ordering}};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use std::thread::Builder;
|
use std::thread::Builder;
|
||||||
|
|
||||||
use crossbeam_channel::unbounded;
|
use crossbeam_channel::unbounded;
|
||||||
|
use privdrop::PrivDrop;
|
||||||
|
|
||||||
pub mod common;
|
pub mod common;
|
||||||
pub mod config;
|
pub mod config;
|
||||||
|
|
@ -35,11 +37,14 @@ pub fn run(config: Config){
|
||||||
).expect("spawn request worker");
|
).expect("spawn request worker");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let num_bound_sockets = Arc::new(AtomicUsize::new(0));
|
||||||
|
|
||||||
for i in 0..config.socket_workers {
|
for i in 0..config.socket_workers {
|
||||||
let state = state.clone();
|
let state = state.clone();
|
||||||
let config = config.clone();
|
let config = config.clone();
|
||||||
let request_sender = request_sender.clone();
|
let request_sender = request_sender.clone();
|
||||||
let response_receiver = response_receiver.clone();
|
let response_receiver = response_receiver.clone();
|
||||||
|
let num_bound_sockets = num_bound_sockets.clone();
|
||||||
|
|
||||||
Builder::new().name(format!("socket-{:02}", i + 1)).spawn(move ||
|
Builder::new().name(format!("socket-{:02}", i + 1)).spawn(move ||
|
||||||
network::run_socket_worker(
|
network::run_socket_worker(
|
||||||
|
|
@ -48,6 +53,7 @@ pub fn run(config: Config){
|
||||||
i,
|
i,
|
||||||
request_sender,
|
request_sender,
|
||||||
response_receiver,
|
response_receiver,
|
||||||
|
num_bound_sockets,
|
||||||
)
|
)
|
||||||
).expect("spawn socket worker");
|
).expect("spawn socket worker");
|
||||||
}
|
}
|
||||||
|
|
@ -67,6 +73,24 @@ pub fn run(config: Config){
|
||||||
).expect("spawn statistics thread");
|
).expect("spawn statistics thread");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if config.privileges.drop_privileges {
|
||||||
|
loop {
|
||||||
|
let sockets = num_bound_sockets.load(Ordering::SeqCst);
|
||||||
|
|
||||||
|
if sockets == config.socket_workers {
|
||||||
|
PrivDrop::default()
|
||||||
|
.chroot(config.privileges.chroot_path)
|
||||||
|
.user(config.privileges.user)
|
||||||
|
.apply()
|
||||||
|
.expect("drop privileges");
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
::std::thread::sleep(Duration::from_millis(10));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
::std::thread::sleep(Duration::from_secs(config.cleaning.interval));
|
::std::thread::sleep(Duration::from_secs(config.cleaning.interval));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use std::sync::atomic::Ordering;
|
use std::sync::{Arc, atomic::{AtomicUsize, Ordering}};
|
||||||
use std::io::{Cursor, ErrorKind};
|
use std::io::{Cursor, ErrorKind};
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
@ -23,6 +23,7 @@ pub fn run_socket_worker(
|
||||||
token_num: usize,
|
token_num: usize,
|
||||||
request_sender: Sender<(Request, SocketAddr)>,
|
request_sender: Sender<(Request, SocketAddr)>,
|
||||||
response_receiver: Receiver<(Response, SocketAddr)>,
|
response_receiver: Receiver<(Response, SocketAddr)>,
|
||||||
|
num_bound_sockets: Arc<AtomicUsize>,
|
||||||
){
|
){
|
||||||
let mut buffer = [0u8; MAX_PACKET_SIZE];
|
let mut buffer = [0u8; MAX_PACKET_SIZE];
|
||||||
|
|
||||||
|
|
@ -35,6 +36,8 @@ pub fn run_socket_worker(
|
||||||
.register(&mut socket, Token(token_num), interests)
|
.register(&mut socket, Token(token_num), interests)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
num_bound_sockets.fetch_add(1, Ordering::SeqCst);
|
||||||
|
|
||||||
let mut events = Events::with_capacity(config.network.poll_event_capacity);
|
let mut events = Events::with_capacity(config.network.poll_event_capacity);
|
||||||
|
|
||||||
let mut requests: Vec<(Request, SocketAddr)> = Vec::new();
|
let mut requests: Vec<(Request, SocketAddr)> = Vec::new();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue