diff --git a/src/utils/tools.rs b/src/utils/tools.rs index 865f96c..8a7afc5 100644 --- a/src/utils/tools.rs +++ b/src/utils/tools.rs @@ -4,14 +4,19 @@ use crate::utils::tls::CertificateConfig; use dashmap::DashMap; use log::{error, info}; use notify::{event::ModifyKind, Config, EventKind, RecommendedWatcher, RecursiveMode, Watcher}; +use port_check::is_port_reachable; +use privdrop::PrivDrop; use sha2::{Digest, Sha256}; use std::any::type_name; use std::collections::{HashMap, HashSet}; use std::fmt::Write; -use std::fs; +use std::net::SocketAddr; +use std::os::unix::fs::MetadataExt; +use std::str::FromStr; use std::sync::atomic::AtomicUsize; use std::sync::mpsc::{channel, Sender}; use std::time::{Duration, Instant}; +use std::{fs, process, thread, time}; #[allow(dead_code)] pub fn print_upstreams(upstreams: &UpstreamsDashMap) { @@ -221,3 +226,40 @@ pub fn watch_folder(path: String, sender: Sender>) -> not } } } + +pub fn drop_priv(user: String, group: String, http_addr: String, tls_addr: Option) { + thread::sleep(time::Duration::from_millis(10)); + loop { + thread::sleep(time::Duration::from_millis(10)); + if is_port_reachable(http_addr.clone()) { + break; + } + } + if let Some(tls_addr) = tls_addr { + loop { + thread::sleep(time::Duration::from_millis(10)); + if is_port_reachable(tls_addr.clone()) { + break; + } + } + } + info!("Dropping ROOT privileges to: {}:{}", user, group); + if let Err(e) = PrivDrop::default().user(user).group(group).apply() { + error!("Failed to drop privileges: {}", e); + process::exit(1) + } +} + +pub fn check_priv(addr: String) { + let port = SocketAddr::from_str(&addr).map(|sa| sa.port()).unwrap(); + match port < 1024 { + true => { + let meta = std::fs::metadata("/proc/self").map(|m| m.uid()).unwrap(); + if meta != 0 { + error!("Running on privileged port requires to start as ROOT"); + process::exit(1) + } + } + false => {} + } +} diff --git a/src/web/start.rs b/src/web/start.rs index ca49071..51b58e3 100644 --- a/src/web/start.rs +++ b/src/web/start.rs @@ -12,13 +12,9 @@ use pingora::tls::ssl::{SslAlert, SslRef}; use pingora_core::listeners::tls::TlsSettings; use pingora_core::prelude::{background_service, Opt}; use pingora_core::server::Server; -use port_check::is_port_reachable; -use privdrop::PrivDrop; -use std::os::unix::fs::MetadataExt; use std::sync::mpsc::{channel, Receiver, Sender}; use std::sync::Arc; -use std::{thread, time}; - +use std::thread; pub fn run() { // default_provider().install_default().expect("Failed to install rustls crypto provider"); let parameters = Some(Opt::parse_args()).unwrap(); @@ -57,10 +53,13 @@ pub fn run() { let bg_srvc = background_service("bgsrvc", lb.clone()); let mut proxy = pingora_proxy::http_proxy_service(&server.configuration, lb.clone()); let bind_address_http = cfg.proxy_address_http.clone(); - let bind_address_tls = cfg.proxy_address_tls.clone(); + + check_priv(bind_address_http.clone()); + match bind_address_tls { Some(bind_address_tls) => { + check_priv(bind_address_tls.clone()); let (tx, rx): (Sender>, Receiver>) = channel(); let certs_path = cfg.proxy_certificates.clone().unwrap(); thread::spawn(move || { @@ -115,36 +114,3 @@ pub fn run() { rx.recv().expect("Could not receive from channel."); info!("Signal received ! Exiting..."); } -fn drop_priv(user: String, group: String, http_addr: String, tls_addr: Option) { - thread::sleep(time::Duration::from_millis(10)); - loop { - thread::sleep(time::Duration::from_millis(10)); - if is_port_reachable(http_addr.clone()) { - break; - } - } - if let Some(tls_addr) = tls_addr { - loop { - thread::sleep(time::Duration::from_millis(10)); - if is_port_reachable(tls_addr.clone()) { - break; - } - } - } - - if std::fs::metadata("/proc/self").map(|m| m.uid()).unwrap_or(1) == 0 { - info!("Dropping ROOT privileges to: {}:{}", user, group); - if let Err(e) = PrivDrop::default().user(user).group(group).apply() { - panic!("Failed to drop privileges: {}", e); - } - } - - // if let (Some(u), Some(g)) = (user, group) { - // if std::fs::metadata("/proc/self").map(|m| m.uid()).unwrap_or(1) == 0 { - // info!("Dropping ROOT privileges to: {}:{}", u, g); - // if let Err(e) = PrivDrop::default().user(u).group(g).apply() { - // panic!("Failed to drop privileges: {}", e); - // } - // } - // } -}