diff --git a/trifid-api/Cargo.toml b/trifid-api/Cargo.toml index 56f9ffb..fa3c0a2 100644 --- a/trifid-api/Cargo.toml +++ b/trifid-api/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "trifid-api" -version = "0.1.0" +version = "0.1.1" edition = "2021" description = "Pure-rust Defined Networking compatible management server" license = "GPL-3.0-or-later" diff --git a/trifid-api/src/codegen/mod.rs b/trifid-api/src/codegen/mod.rs index 101a046..05579c8 100644 --- a/trifid-api/src/codegen/mod.rs +++ b/trifid-api/src/codegen/mod.rs @@ -17,7 +17,8 @@ use crate::AppState; use ed25519_dalek::SigningKey; use ipnet::Ipv4Net; use log::{debug, error}; -use sea_orm::{ColumnTrait, EntityTrait, QueryFilter}; +use sea_orm::{ColumnTrait, Condition, EntityTrait, QueryFilter}; +use serde_yaml::{Mapping, Value}; use trifid_api_entities::entity::{ firewall_rule, host, host_config_override, host_static_address, network, organization, signing_ca, @@ -156,7 +157,7 @@ pub async fn generate_config( punchy: Some(NebulaConfigPunchy { punch: true, respond: true, - delay: "".to_string(), + delay: "1s".to_string(), }), cipher: NebulaConfigCipher::Aes, preferred_ranges: vec![], @@ -191,36 +192,68 @@ pub async fn generate_config( cidr: None, }]), }), - routines: 0, + routines: 1, stats: None, local_range: None, }; - // Merge with config overrides and re-parse - let config_str = serde_yaml::to_string(&nebula_config)?; - let mut value: serde_yaml::Value = serde_yaml::from_str(&config_str)?; + let mut val = Mapping::new(); - for (key, kv_value) in &info.config_overrides { - // split up the key - // a.b.c.d = ['a']['b']['c']['d'] = value - let key_split = key.split('.'); + for (k, v) in &info.config_overrides { + let key_split = k.split('.').collect::>(); - let mut current_val = &mut value; + let mut value = &mut val; - for key_iter in key_split { - current_val = current_val.get_mut(key_iter).ok_or("Invalid key-value override")?; + for ks_k in &key_split[..key_split.len()-1] { + if !value.contains_key(ks_k) { + value.insert(Value::String(ks_k.to_string()), Value::Mapping(Mapping::new())); + } + + value = value.get_mut(ks_k).ok_or("Invalid key-value pair")?.as_mapping_mut().unwrap(); } - *current_val = serde_yaml::from_str(kv_value)?; + value.insert(Value::String(key_split[key_split.len()-1].to_string()), serde_yaml::from_str(&v)?); } - let config_str_merged = serde_yaml::to_string(&value)?; + let overrides_value = Value::Mapping(val); - let nebula_config = serde_yaml::from_str(&config_str_merged)?; + debug!("{:?}", overrides_value); + + let mut value = serde_yaml::to_value(nebula_config)?; + + debug!("{:?}", value); + + merge_yaml(&mut value, overrides_value); + + debug!("{:?}", value); + + let nebula_config = serde_yaml::from_value(value)?; Ok((nebula_config, cert)) } +// This cursed abomination credit https://stackoverflow.com/questions/67727239/how-to-combine-including-nested-array-values-two-serde-yamlvalue-objects +fn merge_yaml(a: &mut serde_yaml::Value, b: serde_yaml::Value) { + match (a, b) { + (a @ &mut serde_yaml::Value::Mapping(_), serde_yaml::Value::Mapping(b)) => { + let a = a.as_mapping_mut().unwrap(); + for (k, v) in b { + if v.is_sequence() && a.contains_key(&k) && a[&k].is_sequence() { + let mut _b = a.get(&k).unwrap().as_sequence().unwrap().to_owned(); + _b.append(&mut v.as_sequence().unwrap().to_owned()); + a[&k] = serde_yaml::Value::from(_b); + continue; + } + if !a.contains_key(&k) {a.insert(k.to_owned(), v.to_owned());} + else { merge_yaml(&mut a[&k], v); } + + } + + } + (a, b) => *a = b, + } +} + pub async fn collect_info<'a>( db: &'a Data, host: &'a str, @@ -237,12 +270,12 @@ pub async fn collect_info<'a>( }; let host_config_overrides = trifid_api_entities::entity::host_config_override::Entity::find() - .filter(host_config_override::Column::Id.eq(&host.id)) + .filter(host_config_override::Column::Host.eq(&host.id)) .all(&db.conn) .await?; let _host_static_addresses = trifid_api_entities::entity::host_static_address::Entity::find() - .filter(host_static_address::Column::Id.eq(&host.id)) + .filter(host_static_address::Column::Host.eq(&host.id)) .all(&db.conn) .await?; @@ -267,8 +300,7 @@ pub async fn collect_info<'a>( let hosts = trifid_api_entities::entity::host::Entity::find() .filter(host::Column::Network.eq(&network.id)) - .filter(host::Column::IsRelay.eq(true)) - .filter(host::Column::IsLighthouse.eq(true)) + .filter(Condition::any().add(host::Column::IsRelay.eq(true)).add(host::Column::IsLighthouse.eq(true))) .all(&db.conn) .await?; @@ -356,7 +388,7 @@ pub async fn collect_info<'a>( } else { format!("{}-{}", u.port_range_from, u.port_range_to) }), - proto: Some(u.protocol.clone()), + proto: Some(u.protocol.clone().to_lowercase()), ca_name: None, ca_sha: None, host: if u.allowed_role_id.is_some() { diff --git a/trifid-api/trifid_data/tfks.toml b/trifid-api/trifid_data/tfks.toml deleted file mode 100644 index e527be7..0000000 --- a/trifid-api/trifid_data/tfks.toml +++ /dev/null @@ -1,361 +0,0 @@ -[[hosts]] -id = "host-IPNHZ2XBXJDY2WYOYG7709CBJ8" -current_signing_key = 1 -current_client_key = 2 -current_config = 2 -current_cert = 2 - -[[hosts.certs]] -id = 1 - -[hosts.certs.cert] -signature = [112, 198, 103, 65, 58, 33, 254, 185, 255, 1, 204, 111, 236, 234, 55, 143, 24, 27, 104, 53, 89, 106, 209, 53, 201, 35, 248, 55, 109, 120, 219, 26, 171, 234, 181, 70, 174, 177, 12, 121, 190, 67, 73, 104, 218, 2, 139, 120, 116, 174, 106, 120, 56, 162, 143, 162, 143, 199, 237, 151, 215, 129, 245, 8] - -[hosts.certs.cert.details] -name = "asd" -ips = ["10.17.2.3/15"] -subnets = [] -groups = ["role:role-A4YTNBOMCFJNK5OAKHQCUUVIL8"] -public_key = [10, 175, 118, 186, 191, 43, 172, 0, 152, 238, 83, 31, 38, 79, 189, 76, 149, 38, 157, 84, 200, 210, 0, 95, 37, 169, 196, 77, 214, 209, 91, 10] -is_ca = false -issuer = "9a4dd7cb5c3a086b0173f126bbf20b85ac7886a2129d2f8573acc2e20f09ec1f" - -[hosts.certs.cert.details.not_before] -secs_since_epoch = 1684171628 -nanos_since_epoch = 68795993 - -[hosts.certs.cert.details.not_after] -secs_since_epoch = 1716312428 -nanos_since_epoch = 68796023 - -[[hosts.certs]] -id = 2 - -[hosts.certs.cert] -signature = [134, 249, 92, 208, 133, 181, 164, 230, 242, 79, 132, 140, 164, 28, 159, 165, 55, 176, 140, 73, 208, 50, 53, 184, 178, 242, 62, 90, 55, 187, 245, 231, 22, 89, 161, 9, 181, 56, 135, 163, 93, 102, 69, 34, 51, 139, 158, 181, 5, 207, 2, 87, 100, 236, 215, 116, 109, 43, 186, 148, 200, 235, 99, 7] - -[hosts.certs.cert.details] -name = "addsd" -ips = ["10.17.2.3/15"] -subnets = [] -groups = ["role:role-A4YTNBOMCFJNK5OAKHQCUUVIL8"] -public_key = [78, 139, 195, 146, 198, 211, 251, 196, 238, 154, 134, 158, 111, 25, 198, 228, 195, 108, 242, 146, 16, 45, 98, 155, 152, 116, 114, 218, 226, 137, 182, 11] -is_ca = false -issuer = "9a4dd7cb5c3a086b0173f126bbf20b85ac7886a2129d2f8573acc2e20f09ec1f" - -[hosts.certs.cert.details.not_before] -secs_since_epoch = 1684171718 -nanos_since_epoch = 140841799 - -[hosts.certs.cert.details.not_after] -secs_since_epoch = 1716312518 -nanos_since_epoch = 140841859 - -[[hosts.config]] -id = 1 - -[hosts.config.config] -routines = 0 - -[hosts.config.config.pki] -ca = """ ------BEGIN NEBULA CERTIFICATE-----\r -Cl0KK2NvcmVAY29yZWRvZXMuZGV2J3MgT3JnYW5pemF0aW9uIFNpZ25pbmcgQ0Eo\r -y7iEowYwy+2S0AY6II2RV3kVBopKoTe3j+aT1LbZuWTR/5oQGra185GB5W63QAES\r -QGRgfmRuJOzhtWwwU4BGMo47uoncMGV41sz1NYcvwmruwhJDaYYJ51DLz3v5bYZV\r -LCxfFB661cvoq1OZ7G5ZcgY=\r ------END NEBULA CERTIFICATE-----\r -""" -cert = """ ------BEGIN NEBULA CERTIFICATE-----\r -CoYBCgNhc2QSCYOExFCAgPj/DyIkcm9sZTpyb2xlLUE0WVROQk9NQ0ZKTks1T0FL\r -SFFDVVVWSUw4KOzWiaMGMOyys7IGOiAKr3a6vyusAJjuUx8mT71MlSadVMjSAF8l\r -qcRN1tFbCkogmk3Xy1w6CGsBc/Emu/ILhax4hqISnS+Fc6zC4g8J7B8SQHDGZ0E6\r -If65/wHMb+zqN48YG2g1WWrRNckj+DdteNsaq+q1Rq6xDHm+Q0lo2gKLeHSuang4\r -oo+ij8ftl9eB9Qg=\r ------END NEBULA CERTIFICATE-----\r -""" -disconnect_invalid = true - -[hosts.config.config.lighthouse] -interval = 60 - -[hosts.config.config.listen] -host = "[::]" -read_buffer = 10485760 -write_buffer = 10485760 - -[hosts.config.config.punchy] -punch = true -respond = true -delay = "" - -[hosts.config.config.relay] - -[hosts.config.config.tun] -dev = "trifid1" -drop_local_broadcast = true -drop_multicast = true - -[hosts.config.config.firewall] -inbound = [] - -[[hosts.config.config.firewall.outbound]] -port = "any" -proto = "any" -host = "any" - -[[hosts.config]] -id = 2 - -[hosts.config.config] -routines = 0 - -[hosts.config.config.pki] -ca = """ ------BEGIN NEBULA CERTIFICATE-----\r -Cl0KK2NvcmVAY29yZWRvZXMuZGV2J3MgT3JnYW5pemF0aW9uIFNpZ25pbmcgQ0Eo\r -y7iEowYwy+2S0AY6II2RV3kVBopKoTe3j+aT1LbZuWTR/5oQGra185GB5W63QAES\r -QGRgfmRuJOzhtWwwU4BGMo47uoncMGV41sz1NYcvwmruwhJDaYYJ51DLz3v5bYZV\r -LCxfFB661cvoq1OZ7G5ZcgY=\r ------END NEBULA CERTIFICATE-----\r -""" -cert = """ ------BEGIN NEBULA CERTIFICATE-----\r -CogBCgVhZGRzZBIJg4TEUICA+P8PIiRyb2xlOnJvbGUtQTRZVE5CT01DRkpOSzVP\r -QUtIUUNVVVZJTDgoxteJowYwxrOzsgY6IE6Lw5LG0/vE7pqGnm8ZxuTDbPKSEC1i\r -m5h0ctriibYLSiCaTdfLXDoIawFz8Sa78guFrHiGohKdL4VzrMLiDwnsHxJAhvlc\r -0IW1pObyT4SMpByfpTewjEnQMjW4svI+Wje79ecWWaEJtTiHo11mRSIzi561Bc8C\r -V2Ts13RtK7qUyOtjBw==\r ------END NEBULA CERTIFICATE-----\r -""" -disconnect_invalid = true - -[hosts.config.config.lighthouse] -interval = 60 - -[hosts.config.config.listen] -host = "[::]" -read_buffer = 10485760 -write_buffer = 10485760 - -[hosts.config.config.punchy] -punch = true -respond = true -delay = "" - -[hosts.config.config.relay] - -[hosts.config.config.tun] -dev = "trifid1" -drop_local_broadcast = true -drop_multicast = true - -[hosts.config.config.firewall] -inbound = [] - -[[hosts.config.config.firewall.outbound]] -port = "any" -proto = "any" -host = "any" - -[[hosts.signing_keys]] -id = 0 -key = [108, 174, 65, 117, 166, 239, 62, 150, 81, 111, 185, 79, 158, 206, 104, 43, 163, 224, 206, 219, 147, 71, 158, 88, 103, 149, 113, 152, 123, 41, 78, 255] - -[[hosts.signing_keys]] -id = 1 -key = [119, 226, 183, 227, 53, 121, 14, 141, 125, 165, 249, 103, 28, 60, 102, 111, 242, 63, 26, 52, 87, 29, 29, 114, 11, 62, 138, 121, 213, 245, 193, 212] - -[[hosts.client_keys]] -id = 1 -dh_pub = [10, 175, 118, 186, 191, 43, 172, 0, 152, 238, 83, 31, 38, 79, 189, 76, 149, 38, 157, 84, 200, 210, 0, 95, 37, 169, 196, 77, 214, 209, 91, 10] -ed_pub = [135, 237, 110, 71, 189, 155, 246, 66, 50, 229, 80, 254, 93, 99, 35, 29, 87, 138, 132, 193, 118, 216, 218, 60, 142, 178, 42, 126, 182, 25, 31, 103] - -[[hosts.client_keys]] -id = 2 -dh_pub = [78, 139, 195, 146, 198, 211, 251, 196, 238, 154, 134, 158, 111, 25, 198, 228, 195, 108, 242, 146, 16, 45, 98, 155, 152, 116, 114, 218, 226, 137, 182, 11] -ed_pub = [178, 77, 253, 159, 81, 137, 20, 14, 184, 230, 73, 111, 130, 129, 15, 184, 114, 90, 133, 147, 178, 252, 197, 75, 82, 33, 21, 5, 38, 238, 57, 84] - -[[hosts]] -id = "host-2PXIOHLPQA3CQL8O7XD6CXMMRM" -current_signing_key = 1 -current_client_key = 2 -current_config = 2 -current_cert = 2 - -[[hosts.certs]] -id = 1 - -[hosts.certs.cert] -signature = [160, 205, 80, 112, 16, 205, 155, 249, 221, 26, 47, 128, 2, 59, 15, 102, 153, 174, 61, 35, 207, 233, 42, 242, 212, 28, 133, 40, 189, 1, 234, 67, 24, 109, 152, 248, 130, 96, 48, 104, 69, 0, 178, 30, 103, 76, 33, 179, 216, 92, 191, 89, 6, 236, 136, 216, 9, 208, 189, 16, 140, 132, 209, 2] - -[hosts.certs.cert.details] -name = "testhost4" -ips = ["10.17.4.2/15"] -subnets = [] -groups = ["role:role-A4YTNBOMCFJNK5OAKHQCUUVIL8"] -public_key = [40, 175, 28, 13, 183, 102, 108, 21, 53, 79, 113, 191, 101, 74, 77, 151, 66, 146, 250, 155, 196, 38, 178, 44, 41, 186, 71, 1, 152, 237, 245, 93] -is_ca = false -issuer = "9a4dd7cb5c3a086b0173f126bbf20b85ac7886a2129d2f8573acc2e20f09ec1f" - -[hosts.certs.cert.details.not_before] -secs_since_epoch = 1684172253 -nanos_since_epoch = 219759539 - -[hosts.certs.cert.details.not_after] -secs_since_epoch = 1716313053 -nanos_since_epoch = 219759579 - -[[hosts.certs]] -id = 2 - -[hosts.certs.cert] -signature = [54, 210, 5, 3, 189, 187, 221, 142, 238, 142, 175, 248, 12, 128, 6, 58, 99, 44, 248, 198, 51, 3, 152, 118, 113, 46, 41, 191, 138, 15, 120, 103, 170, 24, 229, 27, 241, 182, 236, 220, 51, 117, 224, 118, 191, 25, 84, 111, 100, 15, 53, 234, 132, 214, 213, 66, 95, 8, 44, 162, 212, 60, 151, 13] - -[hosts.certs.cert.details] -name = "testhost4" -ips = ["10.17.4.2/15"] -subnets = [] -groups = ["role:role-A4YTNBOMCFJNK5OAKHQCUUVIL8"] -public_key = [4, 249, 63, 6, 25, 145, 63, 132, 106, 48, 243, 192, 249, 159, 185, 160, 196, 146, 24, 7, 241, 160, 121, 122, 212, 249, 19, 213, 158, 105, 142, 86] -is_ca = false -issuer = "9a4dd7cb5c3a086b0173f126bbf20b85ac7886a2129d2f8573acc2e20f09ec1f" - -[hosts.certs.cert.details.not_before] -secs_since_epoch = 1684172313 -nanos_since_epoch = 739770378 - -[hosts.certs.cert.details.not_after] -secs_since_epoch = 1716313113 -nanos_since_epoch = 739770429 - -[[hosts.config]] -id = 1 - -[hosts.config.config] -routines = 0 - -[hosts.config.config.pki] -ca = """ ------BEGIN NEBULA CERTIFICATE-----\r -Cl0KK2NvcmVAY29yZWRvZXMuZGV2J3MgT3JnYW5pemF0aW9uIFNpZ25pbmcgQ0Eo\r -y7iEowYwy+2S0AY6II2RV3kVBopKoTe3j+aT1LbZuWTR/5oQGra185GB5W63QAES\r -QGRgfmRuJOzhtWwwU4BGMo47uoncMGV41sz1NYcvwmruwhJDaYYJ51DLz3v5bYZV\r -LCxfFB661cvoq1OZ7G5ZcgY=\r ------END NEBULA CERTIFICATE-----\r -""" -cert = """ ------BEGIN NEBULA CERTIFICATE-----\r -CowBCgl0ZXN0aG9zdDQSCYKIxFCAgPj/DyIkcm9sZTpyb2xlLUE0WVROQk9NQ0ZK\r -Tks1T0FLSFFDVVVWSUw4KN3biaMGMN23s7IGOiAorxwNt2ZsFTVPcb9lSk2XQpL6\r -m8QmsiwpukcBmO31XUogmk3Xy1w6CGsBc/Emu/ILhax4hqISnS+Fc6zC4g8J7B8S\r -QKDNUHAQzZv53RovgAI7D2aZrj0jz+kq8tQchSi9AepDGG2Y+IJgMGhFALIeZ0wh\r -s9hcv1kG7IjYCdC9EIyE0QI=\r ------END NEBULA CERTIFICATE-----\r -""" -disconnect_invalid = true - -[hosts.config.config.lighthouse] -am_lighthouse = true -interval = 60 - -[hosts.config.config.listen] -host = "[::]" -port = 5679 -read_buffer = 10485760 -write_buffer = 10485760 - -[hosts.config.config.punchy] -punch = true -respond = true -delay = "" - -[hosts.config.config.relay] - -[hosts.config.config.tun] -dev = "trifid1" -drop_local_broadcast = true -drop_multicast = true - -[hosts.config.config.firewall] -inbound = [] - -[[hosts.config.config.firewall.outbound]] -port = "any" -proto = "any" -host = "any" - -[[hosts.config]] -id = 2 - -[hosts.config.config] -routines = 0 - -[hosts.config.config.pki] -ca = """ ------BEGIN NEBULA CERTIFICATE-----\r -Cl0KK2NvcmVAY29yZWRvZXMuZGV2J3MgT3JnYW5pemF0aW9uIFNpZ25pbmcgQ0Eo\r -y7iEowYwy+2S0AY6II2RV3kVBopKoTe3j+aT1LbZuWTR/5oQGra185GB5W63QAES\r -QGRgfmRuJOzhtWwwU4BGMo47uoncMGV41sz1NYcvwmruwhJDaYYJ51DLz3v5bYZV\r -LCxfFB661cvoq1OZ7G5ZcgY=\r ------END NEBULA CERTIFICATE-----\r -""" -cert = """ ------BEGIN NEBULA CERTIFICATE-----\r -CowBCgl0ZXN0aG9zdDQSCYKIxFCAgPj/DyIkcm9sZTpyb2xlLUE0WVROQk9NQ0ZK\r -Tks1T0FLSFFDVVVWSUw4KJnciaMGMJm4s7IGOiAE+T8GGZE/hGow88D5n7mgxJIY\r -B/GgeXrU+RPVnmmOVkogmk3Xy1w6CGsBc/Emu/ILhax4hqISnS+Fc6zC4g8J7B8S\r -QDbSBQO9u92O7o6v+AyABjpjLPjGMwOYdnEuKb+KD3hnqhjlG/G27NwzdeB2vxlU\r -b2QPNeqE1tVCXwgsotQ8lw0=\r ------END NEBULA CERTIFICATE-----\r -""" -disconnect_invalid = true - -[hosts.config.config.lighthouse] -am_lighthouse = true -interval = 60 - -[hosts.config.config.listen] -host = "[::]" -port = 5677 -read_buffer = 10485760 -write_buffer = 10485760 - -[hosts.config.config.punchy] -punch = true -respond = true -delay = "" - -[hosts.config.config.relay] - -[hosts.config.config.tun] -dev = "trifid1" -drop_local_broadcast = true -drop_multicast = true - -[hosts.config.config.firewall] -inbound = [] - -[[hosts.config.config.firewall.outbound]] -port = "any" -proto = "any" -host = "any" - -[[hosts.signing_keys]] -id = 0 -key = [255, 84, 221, 121, 87, 225, 7, 12, 236, 8, 209, 175, 98, 20, 119, 146, 92, 177, 79, 121, 24, 243, 247, 113, 106, 212, 183, 155, 208, 55, 219, 135] - -[[hosts.signing_keys]] -id = 1 -key = [98, 159, 193, 58, 183, 156, 75, 17, 70, 103, 112, 6, 71, 197, 167, 152, 99, 210, 199, 40, 49, 13, 101, 72, 57, 34, 221, 237, 142, 29, 144, 175] - -[[hosts.client_keys]] -id = 1 -dh_pub = [40, 175, 28, 13, 183, 102, 108, 21, 53, 79, 113, 191, 101, 74, 77, 151, 66, 146, 250, 155, 196, 38, 178, 44, 41, 186, 71, 1, 152, 237, 245, 93] -ed_pub = [247, 172, 97, 223, 43, 24, 248, 133, 118, 219, 227, 72, 95, 25, 167, 179, 115, 225, 73, 211, 161, 216, 95, 140, 151, 59, 118, 39, 122, 136, 144, 245] - -[[hosts.client_keys]] -id = 2 -dh_pub = [4, 249, 63, 6, 25, 145, 63, 132, 106, 48, 243, 192, 249, 159, 185, 160, 196, 146, 24, 7, 241, 160, 121, 122, 212, 249, 19, 213, 158, 105, 142, 86] -ed_pub = [55, 82, 153, 75, 220, 207, 87, 221, 50, 200, 77, 9, 242, 136, 64, 91, 60, 96, 31, 100, 58, 162, 150, 147, 109, 109, 117, 188, 164, 217, 248, 140]