finish nebula impl

This commit is contained in:
c0repwn3r 2023-03-30 10:43:09 -04:00
parent bb9db54113
commit 7513eb8318
Signed by: core
GPG Key ID: FDBF740DADDCEECF
5 changed files with 135 additions and 30 deletions

20
Cargo.lock generated
View File

@ -2139,6 +2139,19 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "serde_yaml"
version = "0.9.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f82e6c8c047aa50a7328632d067bcae6ef38772a79e28daf32f735e0e4f3dd10"
dependencies = [
"indexmap",
"itoa",
"ryu",
"serde",
"unsafe-libyaml",
]
[[package]] [[package]]
name = "sha1" name = "sha1"
version = "0.10.5" version = "0.10.5"
@ -2472,6 +2485,7 @@ dependencies = [
"reqwest", "reqwest",
"serde", "serde",
"serde_json", "serde_json",
"serde_yaml",
"sha2", "sha2",
"simple_logger", "simple_logger",
"tar", "tar",
@ -2889,6 +2903,12 @@ dependencies = [
"subtle", "subtle",
] ]
[[package]]
name = "unsafe-libyaml"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad2024452afd3874bf539695e04af6732ba06517424dbf958fdb16a01f3bef6c"
[[package]] [[package]]
name = "url" name = "url"
version = "2.3.1" version = "2.3.1"

View File

@ -25,6 +25,7 @@ chrono = "0.4.24"
ipnet = "2.7.1" ipnet = "2.7.1"
base64-serde = "0.7.0" base64-serde = "0.7.0"
dnapi-rs = { version = "0.1.6", path = "../dnapi-rs" } dnapi-rs = { version = "0.1.6", path = "../dnapi-rs" }
serde_yaml = "0.9.19"
[build-dependencies] [build-dependencies]
serde = { version = "1.0.157", features = ["derive"] } serde = { version = "1.0.157", features = ["derive"] }

View File

@ -15,7 +15,7 @@ use crate::dirs::{get_cdata_dir, get_cdata_file, get_config_dir, get_config_file
pub const DEFAULT_PORT: u16 = 8157; pub const DEFAULT_PORT: u16 = 8157;
fn default_port() -> u16 { DEFAULT_PORT } fn default_port() -> u16 { DEFAULT_PORT }
#[derive(Serialize, Deserialize, Clone)] #[derive(Serialize, Deserialize, Clone, Debug)]
pub struct TFClientConfig { pub struct TFClientConfig {
#[serde(default = "default_port")] #[serde(default = "default_port")]
pub listen_port: u16 pub listen_port: u16
@ -23,7 +23,7 @@ pub struct TFClientConfig {
#[derive(Serialize, Deserialize, Clone)] #[derive(Serialize, Deserialize, Clone)]
pub struct TFClientData { pub struct TFClientData {
pub dh_privkey: Option<[u8; 32]>, pub dh_privkey: Option<Vec<u8>>,
pub creds: Option<Credentials>, pub creds: Option<Credentials>,
pub meta: Option<EnrollMeta> pub meta: Option<EnrollMeta>
} }
@ -98,7 +98,7 @@ pub fn save_cdata(instance: &str, data: TFClientData) -> Result<(), Box<dyn Erro
Ok(()) Ok(())
} }
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize, Clone, Debug)]
pub struct NebulaConfig { pub struct NebulaConfig {
pub pki: NebulaConfigPki, pub pki: NebulaConfigPki,
#[serde(default = "empty_hashmap")] #[serde(default = "empty_hashmap")]
@ -141,7 +141,7 @@ pub struct NebulaConfig {
pub local_range: Option<Ipv4Net> pub local_range: Option<Ipv4Net>
} }
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize, Clone, Debug)]
pub struct NebulaConfigPki { pub struct NebulaConfigPki {
pub ca: String, pub ca: String,
pub cert: String, pub cert: String,
@ -154,7 +154,7 @@ pub struct NebulaConfigPki {
pub disconnect_invalid: bool pub disconnect_invalid: bool
} }
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize, Clone, Debug)]
pub struct NebulaConfigLighthouse { pub struct NebulaConfigLighthouse {
#[serde(default = "bool_false")] #[serde(default = "bool_false")]
#[serde(skip_serializing_if = "is_bool_false")] #[serde(skip_serializing_if = "is_bool_false")]
@ -178,7 +178,7 @@ pub struct NebulaConfigLighthouse {
pub local_allow_list: HashMap<Ipv4Net, bool>, // `interfaces` is not supported pub local_allow_list: HashMap<Ipv4Net, bool>, // `interfaces` is not supported
} }
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize, Clone, Debug)]
pub struct NebulaConfigLighthouseDns { pub struct NebulaConfigLighthouseDns {
pub host: Ipv4Addr, pub host: Ipv4Addr,
#[serde(default = "u16_53")] #[serde(default = "u16_53")]
@ -186,7 +186,7 @@ pub struct NebulaConfigLighthouseDns {
pub port: u16 pub port: u16
} }
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize, Clone, Debug)]
pub struct NebulaConfigListen { pub struct NebulaConfigListen {
#[serde(default = "ipv4_0000")] #[serde(default = "ipv4_0000")]
#[serde(skip_serializing_if = "is_ipv4_0000")] #[serde(skip_serializing_if = "is_ipv4_0000")]
@ -203,7 +203,7 @@ pub struct NebulaConfigListen {
pub write_buffer: Option<u32> pub write_buffer: Option<u32>
} }
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize, Clone, Debug)]
pub struct NebulaConfigPunchy { pub struct NebulaConfigPunchy {
#[serde(default = "bool_false")] #[serde(default = "bool_false")]
#[serde(skip_serializing_if = "is_bool_false")] #[serde(skip_serializing_if = "is_bool_false")]
@ -216,7 +216,7 @@ pub struct NebulaConfigPunchy {
pub delay: String pub delay: String
} }
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize, Clone, Debug)]
pub enum NebulaConfigCipher { pub enum NebulaConfigCipher {
#[serde(rename = "aes")] #[serde(rename = "aes")]
Aes, Aes,
@ -224,7 +224,7 @@ pub enum NebulaConfigCipher {
ChaChaPoly ChaChaPoly
} }
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize, Clone, Debug)]
pub struct NebulaConfigRelay { pub struct NebulaConfigRelay {
#[serde(default = "empty_vec")] #[serde(default = "empty_vec")]
#[serde(skip_serializing_if = "is_empty_vec")] #[serde(skip_serializing_if = "is_empty_vec")]
@ -237,7 +237,7 @@ pub struct NebulaConfigRelay {
pub use_relays: bool pub use_relays: bool
} }
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize, Clone, Debug)]
pub struct NebulaConfigTun { pub struct NebulaConfigTun {
#[serde(default = "bool_false")] #[serde(default = "bool_false")]
#[serde(skip_serializing_if = "is_bool_false")] #[serde(skip_serializing_if = "is_bool_false")]
@ -264,13 +264,13 @@ pub struct NebulaConfigTun {
pub unsafe_routes: Vec<NebulaConfigTunUnsafeRoute> pub unsafe_routes: Vec<NebulaConfigTunUnsafeRoute>
} }
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize, Clone, Debug)]
pub struct NebulaConfigTunRouteOverride { pub struct NebulaConfigTunRouteOverride {
pub mtu: u64, pub mtu: u64,
pub route: Ipv4Net pub route: Ipv4Net
} }
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize, Clone, Debug)]
pub struct NebulaConfigTunUnsafeRoute { pub struct NebulaConfigTunUnsafeRoute {
pub route: Ipv4Net, pub route: Ipv4Net,
pub via: Ipv4Addr, pub via: Ipv4Addr,
@ -282,7 +282,7 @@ pub struct NebulaConfigTunUnsafeRoute {
pub metric: i64 pub metric: i64
} }
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize, Clone, Debug)]
pub struct NebulaConfigLogging { pub struct NebulaConfigLogging {
#[serde(default = "loglevel_info")] #[serde(default = "loglevel_info")]
#[serde(skip_serializing_if = "is_loglevel_info")] #[serde(skip_serializing_if = "is_loglevel_info")]
@ -298,7 +298,7 @@ pub struct NebulaConfigLogging {
pub timestamp_format: String pub timestamp_format: String
} }
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize, Clone, Debug)]
pub enum NebulaConfigLoggingLevel { pub enum NebulaConfigLoggingLevel {
#[serde(rename = "panic")] #[serde(rename = "panic")]
Panic, Panic,
@ -314,7 +314,7 @@ pub enum NebulaConfigLoggingLevel {
Debug Debug
} }
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize, Clone, Debug)]
pub enum NebulaConfigLoggingFormat { pub enum NebulaConfigLoggingFormat {
#[serde(rename = "json")] #[serde(rename = "json")]
Json, Json,
@ -322,7 +322,7 @@ pub enum NebulaConfigLoggingFormat {
Text Text
} }
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize, Clone, Debug)]
pub struct NebulaConfigSshd { pub struct NebulaConfigSshd {
#[serde(default = "bool_false")] #[serde(default = "bool_false")]
#[serde(skip_serializing_if = "is_bool_false")] #[serde(skip_serializing_if = "is_bool_false")]
@ -334,7 +334,7 @@ pub struct NebulaConfigSshd {
pub authorized_users: Vec<NebulaConfigSshdAuthorizedUser> pub authorized_users: Vec<NebulaConfigSshdAuthorizedUser>
} }
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize, Clone, Debug)]
pub struct NebulaConfigSshdAuthorizedUser { pub struct NebulaConfigSshdAuthorizedUser {
pub user: String, pub user: String,
#[serde(default = "empty_vec")] #[serde(default = "empty_vec")]
@ -342,7 +342,7 @@ pub struct NebulaConfigSshdAuthorizedUser {
pub keys: Vec<String> pub keys: Vec<String>
} }
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize, Clone, Debug)]
#[serde(tag = "type")] #[serde(tag = "type")]
pub enum NebulaConfigStats { pub enum NebulaConfigStats {
#[serde(rename = "graphite")] #[serde(rename = "graphite")]
@ -351,7 +351,7 @@ pub enum NebulaConfigStats {
Prometheus(NebulaConfigStatsPrometheus) Prometheus(NebulaConfigStatsPrometheus)
} }
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize, Clone, Debug)]
pub struct NebulaConfigStatsGraphite { pub struct NebulaConfigStatsGraphite {
#[serde(default = "string_nebula")] #[serde(default = "string_nebula")]
#[serde(skip_serializing_if = "is_string_nebula")] #[serde(skip_serializing_if = "is_string_nebula")]
@ -369,7 +369,7 @@ pub struct NebulaConfigStatsGraphite {
pub lighthouse_metrics: bool pub lighthouse_metrics: bool
} }
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize, Clone, Debug)]
pub enum NebulaConfigStatsGraphiteProtocol { pub enum NebulaConfigStatsGraphiteProtocol {
#[serde(rename = "tcp")] #[serde(rename = "tcp")]
Tcp, Tcp,
@ -377,7 +377,7 @@ pub enum NebulaConfigStatsGraphiteProtocol {
Udp Udp
} }
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize, Clone, Debug)]
pub struct NebulaConfigStatsPrometheus { pub struct NebulaConfigStatsPrometheus {
pub listen: String, pub listen: String,
pub path: String, pub path: String,
@ -396,7 +396,7 @@ pub struct NebulaConfigStatsPrometheus {
pub lighthouse_metrics: bool pub lighthouse_metrics: bool
} }
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize, Clone, Debug)]
pub struct NebulaConfigFirewall { pub struct NebulaConfigFirewall {
#[serde(default = "none")] #[serde(default = "none")]
#[serde(skip_serializing_if = "is_none")] #[serde(skip_serializing_if = "is_none")]
@ -411,7 +411,7 @@ pub struct NebulaConfigFirewall {
pub outbound: Option<Vec<NebulaConfigFirewallRule>>, pub outbound: Option<Vec<NebulaConfigFirewallRule>>,
} }
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize, Clone, Debug)]
pub struct NebulaConfigFirewallConntrack { pub struct NebulaConfigFirewallConntrack {
#[serde(default = "string_12m")] #[serde(default = "string_12m")]
#[serde(skip_serializing_if = "is_string_12m")] #[serde(skip_serializing_if = "is_string_12m")]
@ -424,7 +424,7 @@ pub struct NebulaConfigFirewallConntrack {
pub default_timeout: String pub default_timeout: String
} }
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize, Clone, Debug)]
pub struct NebulaConfigFirewallRule { pub struct NebulaConfigFirewallRule {
#[serde(default = "none")] #[serde(default = "none")]
#[serde(skip_serializing_if = "is_none")] #[serde(skip_serializing_if = "is_none")]

View File

@ -91,7 +91,7 @@ pub fn daemon_main(name: String, server: String) {
let transmitter_nebula = transmitter.clone(); let transmitter_nebula = transmitter.clone();
let name_nebula = name.clone(); let name_nebula = name.clone();
let nebula_thread = thread::spawn(move || { let nebula_thread = thread::spawn(move || {
nebulaworker_main(config_nebula, name, transmitter_nebula, rx_nebula); nebulaworker_main(config_nebula, name_nebula, transmitter_nebula, rx_nebula);
}); });
info!("Starting timer thread..."); info!("Starting timer thread...");
@ -101,8 +101,9 @@ pub fn daemon_main(name: String, server: String) {
}); });
info!("Starting socket worker thread..."); info!("Starting socket worker thread...");
let name_socket = name.clone();
let socket_thread = thread::spawn(move || { let socket_thread = thread::spawn(move || {
socketworker_main(config, name.clone(), transmitter, rx_socket); socketworker_main(config, name_socket, transmitter, rx_socket);
}); });
info!("Waiting for socket thread to exit..."); info!("Waiting for socket thread to exit...");

View File

@ -1,15 +1,36 @@
// Code to handle the nebula worker // Code to handle the nebula worker
use std::error::Error;
use std::fs;
use std::sync::mpsc::{Receiver, TryRecvError}; use std::sync::mpsc::{Receiver, TryRecvError};
use log::{error, info}; use log::{debug, error, info};
use crate::config::{load_cdata, save_cdata, TFClientConfig}; use crate::config::{load_cdata, NebulaConfig, save_cdata, TFClientConfig};
use crate::daemon::ThreadMessageSender; use crate::daemon::ThreadMessageSender;
use crate::dirs::get_nebulaconfig_file;
use crate::embedded_nebula::run_embedded_nebula;
pub enum NebulaWorkerMessage { pub enum NebulaWorkerMessage {
Shutdown, Shutdown,
ConfigUpdated ConfigUpdated
} }
fn insert_private_key(instance: &str) -> Result<(), Box<dyn Error>> {
let cdata = load_cdata(instance)?;
let key = cdata.dh_privkey.ok_or("Missing private key")?;
let config_str = fs::read_to_string(get_nebulaconfig_file(instance).ok_or("Could not get config file location")?)?;
let mut config: NebulaConfig = serde_yaml::from_str(&config_str)?;
config.pki.key = String::from_utf8(key)?;
debug!("inserted private key into config: {:?}", config);
let config_str = serde_yaml::to_string(&config)?;
fs::write(get_nebulaconfig_file(instance).ok_or("Could not get config file location")?, config_str)?;
Ok(())
}
pub fn nebulaworker_main(_config: TFClientConfig, instance: String, _transmitter: ThreadMessageSender, rx: Receiver<NebulaWorkerMessage>) { pub fn nebulaworker_main(_config: TFClientConfig, instance: String, _transmitter: ThreadMessageSender, rx: Receiver<NebulaWorkerMessage>) {
let cdata = match load_cdata(&instance) { let cdata = match load_cdata(&instance) {
Ok(data) => data, Ok(data) => data,
@ -20,6 +41,28 @@ pub fn nebulaworker_main(_config: TFClientConfig, instance: String, _transmitter
} }
}; };
info!("fixing config...");
match insert_private_key(&instance) {
Ok(_) => {
info!("config fixed (private-key embedded)");
},
Err(e) => {
error!("unable to fix config: {}", e);
error!("nebula thread exiting with error");
return;
}
}
info!("starting nebula child...");
let mut child = match run_embedded_nebula(&["-config".to_string(), get_nebulaconfig_file(&instance).unwrap().to_str().unwrap().to_string()]) {
Ok(c) => c,
Err(e) => {
error!("unable to start embedded nebula binary: {}", e);
error!("nebula thread exiting with error");
return;
}
};
info!("nebula process started");
// dont need to save it, because we do not, in any circumstance, write to it // dont need to save it, because we do not, in any circumstance, write to it
loop { loop {
match rx.try_recv() { match rx.try_recv() {
@ -27,10 +70,50 @@ pub fn nebulaworker_main(_config: TFClientConfig, instance: String, _transmitter
match msg { match msg {
NebulaWorkerMessage::Shutdown => { NebulaWorkerMessage::Shutdown => {
info!("recv on command socket: shutdown, stopping"); info!("recv on command socket: shutdown, stopping");
info!("shutting down nebula binary");
match child.kill() {
Ok(_) => {
debug!("nebula process exited");
},
Err(e) => {
error!("nebula process already exited: {}", e);
}
}
info!("nebula shut down");
break; break;
}, },
NebulaWorkerMessage::ConfigUpdated => { NebulaWorkerMessage::ConfigUpdated => {
info!("our configuration has been updated - reloading"); info!("our configuration has been updated - restarting");
debug!("killing existing process");
match child.kill() {
Ok(_) => {
debug!("nebula process exited");
},
Err(e) => {
error!("nebula process already exited: {}", e);
}
}
debug!("fixing config...");
match insert_private_key(&instance) {
Ok(_) => {
debug!("config fixed (private-key embedded)");
},
Err(e) => {
error!("unable to fix config: {}", e);
error!("nebula thread exiting with error");
return;
}
}
debug!("restarting nebula process");
child = match run_embedded_nebula(&["-config".to_string(), get_nebulaconfig_file(&instance).unwrap().to_str().unwrap().to_string()]) {
Ok(c) => c,
Err(e) => {
error!("unable to start embedded nebula binary: {}", e);
error!("nebula thread exiting with error");
return;
}
};
debug!("nebula process restarted");
} }
} }
}, },