diff --git a/Cargo.lock b/Cargo.lock index 9373a873..18398d10 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -589,7 +589,6 @@ dependencies = [ "defguard_version", "defguard_wireguard_rs", "env_logger", - "gethostname", "ipnetwork", "libc", "log", @@ -597,6 +596,7 @@ dependencies = [ "nftnl", "nix 0.31.2", "prost", + "prost-types", "serde", "syslog", "thiserror 2.0.18", @@ -940,16 +940,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "gethostname" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bd49230192a3797a9a4d6abe9b3eed6f7fa4c8a8a4947977c6f80025f92cbd8" -dependencies = [ - "rustix", - "windows-link", -] - [[package]] name = "getrandom" version = "0.2.17" diff --git a/Cargo.toml b/Cargo.toml index 990eb7d9..74228c5c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,11 +12,11 @@ defguard_certs = { git = "https://github.com/DefGuard/defguard.git", rev = "0195 defguard_version = { git = "https://github.com/DefGuard/defguard.git", rev = "01957186101fc105803d56f1190efbdb5102df2f" } defguard_wireguard_rs = "0.9" env_logger = "0.11" -gethostname = "1.0" ipnetwork = "0.21" libc = { version = "0.2", default-features = false } log = "0.4" prost = "0.14" +prost-types = "0.14" serde = { version = "1.0", features = ["derive"] } syslog = "7.0" thiserror = "2.0" diff --git a/build.rs b/build.rs index 5731502f..901f5a44 100644 --- a/build.rs +++ b/build.rs @@ -11,10 +11,10 @@ fn main() -> Result<(), Box> { // compiling protos using path on build time .compile_protos( &[ - "proto/wireguard/gateway.proto", - "proto/enterprise/firewall/firewall.proto", + "proto/v2/gateway.proto", + "proto/enterprise/v2/firewall/firewall.proto", ], - &["proto/wireguard", "proto/enterprise/firewall"], + &["proto"], )?; println!("cargo:rerun-if-changed=proto"); Ok(()) diff --git a/flake.lock b/flake.lock index 9889879c..f5286636 100644 --- a/flake.lock +++ b/flake.lock @@ -20,11 +20,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1761907660, - "narHash": "sha256-kJ8lIZsiPOmbkJypG+B5sReDXSD1KGu2VEPNqhRa/ew=", + "lastModified": 1774106199, + "narHash": "sha256-US5Tda2sKmjrg2lNHQL3jRQ6p96cgfWh3J1QBliQ8Ws=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "2fb006b87f04c4d3bdf08cfdbc7fab9c13d94a15", + "rev": "6c9a78c09ff4d6c21d0319114873508a6ec01655", "type": "github" }, "original": { @@ -48,11 +48,11 @@ ] }, "locked": { - "lastModified": 1762137611, - "narHash": "sha256-sTqb10FR/YQCuGbw16qxliX0NFlYg6evSEjN8w+9IYE=", + "lastModified": 1774408260, + "narHash": "sha256-Jn9d9r85dmf3gTMnSRt6t+DP2nQ5uJns/MMXg2FpzfM=", "owner": "oxalica", "repo": "rust-overlay", - "rev": "3a0ebe5d2965692f990cb27e62f501ad35e3deeb", + "rev": "d6471ee5a8f470251e6e5b83a20a182eb6c46c9b", "type": "github" }, "original": { diff --git a/proto b/proto index faebcc54..7adfe3bf 160000 --- a/proto +++ b/proto @@ -1 +1 @@ -Subproject commit faebcc5449ae803e15cf5faf838c0c508401caf1 +Subproject commit 7adfe3bfd1b7b701e58d25ddadd0c0c7a4a3e046 diff --git a/src/enterprise/firewall/mod.rs b/src/enterprise/firewall/mod.rs index dee55ab4..87c7dc84 100644 --- a/src/enterprise/firewall/mod.rs +++ b/src/enterprise/firewall/mod.rs @@ -14,6 +14,7 @@ use std::{ use ipnetwork::{IpNetwork, Ipv4Network, Ipv6Network}; use iprange::{IpAddrRange, IpAddrRangeError}; use thiserror::Error; +use tracing::error; use crate::proto; @@ -161,7 +162,7 @@ impl Protocol { proto::enterprise::firewall::Protocol::Udp => Ok(Self::Udp), proto::enterprise::firewall::Protocol::Icmp => Ok(Self::Icmp), // TODO: IcmpV6 - proto::enterprise::firewall::Protocol::Invalid => { + proto::enterprise::firewall::Protocol::Unspecified => { Err(FirewallError::UnsupportedProtocol(proto as u8)) } } @@ -196,10 +197,14 @@ impl From for Policy { impl Policy { #[must_use] - pub const fn from_proto(verdict: proto::enterprise::firewall::FirewallPolicy) -> Self { + pub fn from_proto(verdict: proto::enterprise::firewall::FirewallPolicy) -> Self { match verdict { proto::enterprise::firewall::FirewallPolicy::Allow => Self::Allow, proto::enterprise::firewall::FirewallPolicy::Deny => Self::Deny, + proto::enterprise::firewall::FirewallPolicy::Unspecified => { + error!("Received invalid gRPC FirewallPolicy. Falling back to Deny."); + Self::Deny + } } } } diff --git a/src/gateway.rs b/src/gateway.rs index 70800273..53806904 100644 --- a/src/gateway.rs +++ b/src/gateway.rs @@ -13,7 +13,6 @@ use defguard_version::{ ComponentInfo, DefguardComponent, Version, get_tracing_variables, server::DefguardVersionLayer, }; use defguard_wireguard_rs::{WireguardInterfaceApi, net::IpAddrMask}; -use gethostname::gethostname; use tokio::{ sync::{mpsc, oneshot}, time::interval, @@ -35,9 +34,12 @@ use crate::{ }, error::GatewayError, execute_command, mask, - proto::gateway::{ - Configuration, ConfigurationRequest, CoreRequest, CoreResponse, LogEntry, Peer, Update, - core_request, core_response, gateway_server, update, + proto::{ + common::LogEntry, + gateway::{ + Configuration, CoreRequest, CoreResponse, Peer, Update, core_request, core_response, + gateway_server, update, + }, }, setup::run_setup, version::is_core_version_supported, @@ -110,7 +112,7 @@ pub async fn run_gateway_loop( #[derive(Clone, PartialEq)] struct InterfaceConfiguration { name: String, - prvkey: String, + private_key: String, addresses: Vec, port: u16, mtu: u32, @@ -127,7 +129,7 @@ impl From for InterfaceConfiguration { .collect(); Self { name: config.name, - prvkey: config.prvkey, + private_key: config.private_key, addresses, port: config.port as u16, mtu: config.mtu, @@ -384,7 +386,7 @@ impl Gateway { ); trace!( "Received configuration: {:?}", - mask!(new_configuration, prvkey) + mask!(new_configuration, private_key) ); // check if new configuration is different than current one @@ -405,7 +407,7 @@ impl Gateway { ); trace!( "Reconfigured WireGuard interface. Configuration: {:?}", - mask!(new_configuration, prvkey) + mask!(new_configuration, private_key) ); // store new configuration and peers self.interface_configuration = Some(new_interface_configuration); @@ -685,20 +687,11 @@ impl gateway_server::Gateway for GatewayServer { } let (tx, rx) = mpsc::unbounded_channel(); - let Ok(hostname) = gethostname().into_string() else { - error!("Unable to get hostname"); - return Err(Status::internal("failed to get hostname")); - }; // First, send configuration request. - #[allow(deprecated)] - let payload = ConfigurationRequest { - name: None, // TODO: remove? - hostname, - }; let req = CoreRequest { id: self.message_id.fetch_add(1, Ordering::Relaxed), - payload: Some(core_request::Payload::ConfigRequest(payload)), + payload: Some(core_request::Payload::ConfigRequest(())), }; match tx.send(Ok(req)) { @@ -906,7 +899,7 @@ mod tests { async fn test_configuration_comparison() { let old_config = InterfaceConfiguration { name: "gateway".to_string(), - prvkey: "FGqcPuaSlGWC2j50TBA4jHgiefPgQQcgTNLwzKUzBS8=".to_string(), + private_key: "FGqcPuaSlGWC2j50TBA4jHgiefPgQQcgTNLwzKUzBS8=".to_string(), addresses: vec!["10.6.1.1/24".parse().unwrap()], port: 50051, mtu: 1420, @@ -954,7 +947,7 @@ mod tests { // only interface config is different let new_config = InterfaceConfiguration { name: "gateway".to_string(), - prvkey: "FGqcPuaSlGWC2j50TBA4jHgiefPgQQcgTNLwzKUzBS8=".to_string(), + private_key: "FGqcPuaSlGWC2j50TBA4jHgiefPgQQcgTNLwzKUzBS8=".to_string(), addresses: vec!["10.6.1.2/24".parse().unwrap()], port: 50051, mtu: 1420, diff --git a/src/lib.rs b/src/lib.rs index ae80a6af..cebcb217 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,13 +4,40 @@ pub mod gateway; pub mod server; mod version; +pub mod generated { + pub mod defguard { + pub mod common { + pub mod v2 { + tonic::include_proto!("defguard.common.v2"); + } + } + pub mod gateway { + pub mod v2 { + + tonic::include_proto!("defguard.gateway.v2"); + } + } + pub mod enterprise { + pub mod firewall { + pub mod v2 { + + tonic::include_proto!("defguard.enterprise.firewall.v2"); + } + } + } + } +} + pub mod proto { + pub mod common { + pub use crate::generated::defguard::common::v2::*; + } pub mod gateway { - tonic::include_proto!("gateway"); + pub use crate::generated::defguard::gateway::v2::*; } pub mod enterprise { pub mod firewall { - tonic::include_proto!("enterprise.firewall"); + pub use crate::generated::defguard::enterprise::firewall::v2::*; } } } @@ -23,6 +50,7 @@ use std::{process::Command, str::FromStr, time::SystemTime}; use config::Config; use defguard_wireguard_rs::{InterfaceConfiguration, net::IpAddrMask, peer::Peer}; use error::GatewayError; +use prost_types::Timestamp; use syslog::{BasicLogger, Facility, Formatter3164}; pub mod enterprise; @@ -102,7 +130,7 @@ impl From for InterfaceConfiguration { .collect(); InterfaceConfiguration { name: config.name, - prvkey: config.prvkey, + prvkey: config.private_key, addresses, port: config.port as u16, peers, @@ -150,9 +178,13 @@ impl From<&Peer> for proto::gateway::PeerStats { .endpoint .map_or(String::new(), |endpoint| endpoint.to_string()), allowed_ips: peer.allowed_ips.iter().map(ToString::to_string).collect(), - latest_handshake: peer.last_handshake.map_or(0, |ts| { + latest_handshake: peer.last_handshake.and_then(|ts| { ts.duration_since(SystemTime::UNIX_EPOCH) - .map_or(0, |duration| duration.as_secs()) + .ok() + .map(|d| Timestamp { + seconds: d.as_secs() as i64, + nanos: d.subsec_nanos() as i32, + }) }), download: peer.rx_bytes, upload: peer.tx_bytes, diff --git a/src/logging.rs b/src/logging.rs index a7945407..ac912c08 100644 --- a/src/logging.rs +++ b/src/logging.rs @@ -3,7 +3,7 @@ use tokio::sync::mpsc::Sender; use tracing::{Event, Subscriber}; use tracing_subscriber::{Layer, layer::SubscriberExt, util::SubscriberInitExt}; -use crate::proto::gateway::LogEntry; +use crate::proto::common::LogEntry; pub fn init_tracing(own_version: &Version, level: &str, logs_tx: Option>) { let subscriber = tracing_subscriber::registry(); diff --git a/src/setup.rs b/src/setup.rs index 2a12a061..c3936f54 100644 --- a/src/setup.rs +++ b/src/setup.rs @@ -16,7 +16,10 @@ use crate::{ config::Config, error::GatewayError, gateway::TlsConfig, - proto::gateway::{CertificateInfo, DerPayload, LogEntry, gateway_setup_server}, + proto::{ + common::{CertificateInfo, DerPayload, LogEntry}, + gateway::gateway_setup_server, + }, }; const AUTH_HEADER: &str = "authorization";