From 2a9ca15253eec06a2b7039ca9972f884fc6fa43d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20W=C3=B3jcik?= Date: Wed, 3 Sep 2025 13:58:29 +0200 Subject: [PATCH 01/13] adjust socket file permissions --- src-tauri/src/service/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src-tauri/src/service/mod.rs b/src-tauri/src/service/mod.rs index 371a3e39..211055ce 100644 --- a/src-tauri/src/service/mod.rs +++ b/src-tauri/src/service/mod.rs @@ -350,8 +350,8 @@ pub async fn run_server(config: Config) -> anyhow::Result<()> { let uds = UnixListener::bind(DAEMON_SOCKET_PATH)?; // Set socket permissions to allow client access - // 0o666 allows read/write for owner, group, and others - fs::set_permissions(DAEMON_SOCKET_PATH, fs::Permissions::from_mode(0o666))?; + // 0o660 allows read/write for owner and group only + fs::set_permissions(DAEMON_SOCKET_PATH, fs::Permissions::from_mode(0o660))?; let uds_stream = UnixListenerStream::new(uds); From c4b4c9808fc6eac0f38d09a08a8eeb41da27b974 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20W=C3=B3jcik?= Date: Thu, 4 Sep 2025 12:35:39 +0200 Subject: [PATCH 02/13] run daemon service under defguard group --- resources-linux/defguard-service.service | 1 + 1 file changed, 1 insertion(+) diff --git a/resources-linux/defguard-service.service b/resources-linux/defguard-service.service index bce9f07b..cdfb3dc7 100644 --- a/resources-linux/defguard-service.service +++ b/resources-linux/defguard-service.service @@ -5,6 +5,7 @@ Wants=network-online.target After=network-online.target [Service] +Group=defguard ExecReload=/bin/kill -HUP $MAINPID ExecStart=/usr/sbin/defguard-service KillMode=process From b0bf69efb384f4cec151f71a172632a9aa5adaca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20W=C3=B3jcik?= Date: Thu, 4 Sep 2025 14:26:49 +0200 Subject: [PATCH 03/13] setup group in postinstall script --- resources-linux/postinst | 39 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/resources-linux/postinst b/resources-linux/postinst index fabecdca..799bf0bf 100644 --- a/resources-linux/postinst +++ b/resources-linux/postinst @@ -1,3 +1,36 @@ -systemctl daemon-reload -systemctl enable defguard-service -systemctl start defguard-service +#!/bin/sh +set -e + +GROUP_NAME="defguard" + +case "$1" in + configure) + # Create the group if it doesn't exist + if ! getent group "$GROUP_NAME" >/dev/null; then + addgroup --system "$GROUP_NAME" + echo "Created group $GROUP_NAME" + fi + + # Determine target user + TARGET_USER="" + if [ -n "$SUDO_USER" ] && [ "$SUDO_USER" != "root" ]; then + TARGET_USER="$SUDO_USER" + elif [ -n "$USER" ] && [ "$USER" != "root" ]; then + TARGET_USER="$USER" + fi + + # Add user to group if we found a valid target + if [ -n "$TARGET_USER" ]; then + if getent passwd "$TARGET_USER" >/dev/null; then + usermod -a -G "$GROUP_NAME" "$TARGET_USER" + echo "Added user $TARGET_USER to group $GROUP_NAME" + fi + fi + ;; + + # Enable and start background service + systemctl daemon-reload + systemctl enable defguard-service + systemctl start defguard-service +esac + From f8eb0186d35fa745354f65b6d4dd62761f18fa81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20W=C3=B3jcik?= Date: Thu, 4 Sep 2025 15:20:03 +0200 Subject: [PATCH 04/13] adjust service handling in postinstall script --- resources-linux/postinst | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/resources-linux/postinst b/resources-linux/postinst index 799bf0bf..6183fbef 100644 --- a/resources-linux/postinst +++ b/resources-linux/postinst @@ -2,6 +2,7 @@ set -e GROUP_NAME="defguard" +SERVICE_NAME="defguard-service" case "$1" in configure) @@ -26,11 +27,28 @@ case "$1" in echo "Added user $TARGET_USER to group $GROUP_NAME" fi fi - ;; - # Enable and start background service - systemctl daemon-reload - systemctl enable defguard-service - systemctl start defguard-service + # Handle systemd service + if [ -d /run/systemd/system ]; then + # Reload systemd to recognize new service file + systemctl daemon-reload + + # Enable service to start on boot + systemctl enable "$SERVICE_NAME" + + # Start the service now + systemctl start "$SERVICE_NAME" + fi + ;; + + abort-upgrade|abort-remove|abort-deconfigure) + # On failed operations, ensure service is running if it should be + if [ -d /run/systemd/system ]; then + systemctl daemon-reload + if systemctl is-enabled "$SERVICE_NAME" >/dev/null 2>&1; then + systemctl start "$SERVICE_NAME" || true + fi + fi + ;; esac From e460d53c08862ae9d1c193c531e26ca4cccbae86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20W=C3=B3jcik?= Date: Thu, 4 Sep 2025 15:43:18 +0200 Subject: [PATCH 05/13] also handle cleanup when removing package --- resources-linux/postinst | 2 ++ resources-linux/postrm | 25 ++++++++++++++++++++++++- resources-linux/prerm | 17 +++++++++++++++-- 3 files changed, 41 insertions(+), 3 deletions(-) diff --git a/resources-linux/postinst b/resources-linux/postinst index 6183fbef..0b6bac1a 100644 --- a/resources-linux/postinst +++ b/resources-linux/postinst @@ -52,3 +52,5 @@ case "$1" in ;; esac +#DEBHELPER# + diff --git a/resources-linux/postrm b/resources-linux/postrm index 9b76642f..6fb17532 100644 --- a/resources-linux/postrm +++ b/resources-linux/postrm @@ -1 +1,24 @@ -systemctl daemon-reload +#!/bin/sh +set -e + +GROUP_NAME="defguard" +SERVICE_NAME="defguard-service" + +case "$1" in + remove) + # Service file still exists, just disable it + if [ -d /run/systemd/system ]; then + systemctl disable "$SERVICE_NAME" || true + systemctl daemon-reload + fi + ;; + + purge) + # Complete removal - clean up group too + if getent group "$GROUP_NAME" >/dev/null; then + delgroup "$GROUP_NAME" || true + fi + ;; +esac + +#DEBHELPER# diff --git a/resources-linux/prerm b/resources-linux/prerm index aaf1ae3c..3c602373 100644 --- a/resources-linux/prerm +++ b/resources-linux/prerm @@ -1,2 +1,15 @@ -systemctl stop defguard-service -systemctl disable defguard-service +#!/bin/sh +set -e + +SERVICE_NAME="defguard-service" + +case "$1" in + remove|upgrade|deconfigure) + if [ -d /run/systemd/system ]; then + # Stop the service before removal/upgrade + systemctl stop "$SERVICE_NAME" || true + fi + ;; +esac + +#DEBHELPER# From 4ce574a1a1fd0036ac7d1ac4b65bb51781192ec2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20W=C3=B3jcik?= Date: Thu, 4 Sep 2025 17:59:54 +0200 Subject: [PATCH 06/13] add missing dependency --- nix/package.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/nix/package.nix b/nix/package.nix index 64ec315f..8c01ad24 100644 --- a/nix/package.nix +++ b/nix/package.nix @@ -35,6 +35,7 @@ webkitgtk_4_1 openssl libayatana-appindicator + desktop-file-utils ]; nativeBuildInputs = with pkgs; [ From c0aa39ff36701d9b381098f44ecde01be3dc0009 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20W=C3=B3jcik?= Date: Fri, 5 Sep 2025 08:04:17 +0200 Subject: [PATCH 07/13] adjust daemon group --- src-tauri/resources-macos/resources/net.defguard.plist | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src-tauri/resources-macos/resources/net.defguard.plist b/src-tauri/resources-macos/resources/net.defguard.plist index 696d5cd5..e2a059e2 100644 --- a/src-tauri/resources-macos/resources/net.defguard.plist +++ b/src-tauri/resources-macos/resources/net.defguard.plist @@ -16,5 +16,7 @@ http://www.apple.com/DTDs/PropertyList-1.0.dtd > RunAtLoad + GroupName + defguard From 75da7d857e397746f25d4195871c03c9243a4576 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Ciarcin=CC=81ski?= Date: Fri, 5 Sep 2025 15:34:34 +0200 Subject: [PATCH 08/13] macOS: change group to staff --- src-tauri/resources-macos/resources/net.defguard.plist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src-tauri/resources-macos/resources/net.defguard.plist b/src-tauri/resources-macos/resources/net.defguard.plist index e2a059e2..479b9737 100644 --- a/src-tauri/resources-macos/resources/net.defguard.plist +++ b/src-tauri/resources-macos/resources/net.defguard.plist @@ -17,6 +17,6 @@ http://www.apple.com/DTDs/PropertyList-1.0.dtd > RunAtLoad GroupName - defguard + staff From 54c9864072cb4aaa522c55642e60f03da80724b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20W=C3=B3jcik?= Date: Mon, 8 Sep 2025 11:37:41 +0200 Subject: [PATCH 09/13] enforce group ownership on macos --- src-tauri/src/service/mod.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src-tauri/src/service/mod.rs b/src-tauri/src/service/mod.rs index 211055ce..4d5527d0 100644 --- a/src-tauri/src/service/mod.rs +++ b/src-tauri/src/service/mod.rs @@ -6,6 +6,8 @@ pub mod utils; #[cfg(windows)] pub mod windows; +#[cfg(target_os = "macos")] +use nix::unistd::{chown, Group}; #[cfg(windows)] use std::net::{Ipv4Addr, SocketAddr}; use std::{ @@ -57,6 +59,9 @@ pub(super) const DAEMON_BASE_URL: &str = "http://localhost:54127"; #[cfg(unix)] pub(super) const DAEMON_SOCKET_PATH: &str = "/var/run/defguard.socket"; +#[cfg(target_os = "macos")] +pub(super) const DAEMON_SOCKET_GROUP: &str = "staff"; + #[derive(Error, Debug)] pub enum DaemonError { #[error(transparent)] @@ -349,6 +354,17 @@ pub async fn run_server(config: Config) -> anyhow::Result<()> { let uds = UnixListener::bind(DAEMON_SOCKET_PATH)?; + // change owner group for socket file + #[cfg(target_os = "macos")] + { + // get the group ID by name + let group = Group::from_name(DAEMON_SOCKET_GROUP)? + .ok_or_else(|| format!("Group '{}' not found", DAEMON_SOCKET_GROUP))?; + + // change ownership - keep current user, change group + chown(DAEMON_SOCKET_PATH, None, Some(group.gid))?; + } + // Set socket permissions to allow client access // 0o660 allows read/write for owner and group only fs::set_permissions(DAEMON_SOCKET_PATH, fs::Permissions::from_mode(0o660))?; From 0f0955ab026728a4d406e3ec1784396834865c8c Mon Sep 17 00:00:00 2001 From: Aleksander <170264518+t-aleksander@users.noreply.github.com> Date: Mon, 8 Sep 2025 13:12:10 +0200 Subject: [PATCH 10/13] adapt to macos --- src-tauri/Cargo.lock | 1 + src-tauri/Cargo.toml | 1 + src-tauri/src/service/mod.rs | 15 +++++++++------ 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index f3041a9f..3c867eec 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -1246,6 +1246,7 @@ dependencies = [ "dirs-next", "hyper-util", "log", + "nix", "prost", "regex", "reqwest", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index cfce992a..c9b985ed 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -102,6 +102,7 @@ semver = "1.0.26" tokio-stream = "0.1" tower = "0.5" hyper-util = "0.1" +nix = { version = "0.30.1", features = ["user", "fs"] } [target.'cfg(windows)'.dependencies] winapi = { version = "0.3", features = ["winsvc", "winerror"] } diff --git a/src-tauri/src/service/mod.rs b/src-tauri/src/service/mod.rs index 4d5527d0..bbb4ed80 100644 --- a/src-tauri/src/service/mod.rs +++ b/src-tauri/src/service/mod.rs @@ -6,8 +6,6 @@ pub mod utils; #[cfg(windows)] pub mod windows; -#[cfg(target_os = "macos")] -use nix::unistd::{chown, Group}; #[cfg(windows)] use std::net::{Ipv4Addr, SocketAddr}; use std::{ @@ -17,6 +15,8 @@ use std::{ str::FromStr, time::{Duration, SystemTime, UNIX_EPOCH}, }; +#[cfg(unix)] +use std::{fs, os::unix::fs::PermissionsExt, path::Path}; #[cfg(not(target_os = "macos"))] use defguard_wireguard_rs::Kernel; @@ -29,12 +29,12 @@ use defguard_wireguard_rs::{ net::IpAddrMask, InterfaceConfiguration, WGApi, WireguardInterfaceApi, }; +#[cfg(target_os = "macos")] +use nix::unistd::{chown, Group}; use proto::{ desktop_daemon_service_server::{DesktopDaemonService, DesktopDaemonServiceServer}, CreateInterfaceRequest, InterfaceData, ReadInterfaceDataRequest, RemoveInterfaceRequest, }; -#[cfg(unix)] -use std::{fs, os::unix::fs::PermissionsExt, path::Path}; use thiserror::Error; #[cfg(unix)] use tokio::net::UnixListener; @@ -50,6 +50,7 @@ use tracing::{debug, error, info, info_span, Instrument}; use self::config::Config; use super::VERSION; +use crate::error::Error; #[cfg(windows)] const DAEMON_HTTP_PORT: u16 = 54127; @@ -358,8 +359,10 @@ pub async fn run_server(config: Config) -> anyhow::Result<()> { #[cfg(target_os = "macos")] { // get the group ID by name - let group = Group::from_name(DAEMON_SOCKET_GROUP)? - .ok_or_else(|| format!("Group '{}' not found", DAEMON_SOCKET_GROUP))?; + let group = Group::from_name(DAEMON_SOCKET_GROUP)?.ok_or_else(|| { + error!("Group '{}' not found", DAEMON_SOCKET_GROUP); + Error::InternalError(format!("Group '{}' not found", DAEMON_SOCKET_GROUP)) + })?; // change ownership - keep current user, change group chown(DAEMON_SOCKET_PATH, None, Some(group.gid))?; From e1412b3761b5f52ab1e87a8199c56bcf498a21b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20W=C3=B3jcik?= Date: Tue, 9 Sep 2025 10:39:42 +0200 Subject: [PATCH 11/13] add more explicit message on group membership change --- resources-linux/postinst | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/resources-linux/postinst b/resources-linux/postinst index 0b6bac1a..00c814e9 100644 --- a/resources-linux/postinst +++ b/resources-linux/postinst @@ -23,8 +23,22 @@ case "$1" in # Add user to group if we found a valid target if [ -n "$TARGET_USER" ]; then if getent passwd "$TARGET_USER" >/dev/null; then - usermod -a -G "$GROUP_NAME" "$TARGET_USER" - echo "Added user $TARGET_USER to group $GROUP_NAME" + # Try to add user to group and check if it succeeded + if usermod -a -G "$GROUP_NAME" "$TARGET_USER"; then + echo "Added user $TARGET_USER to group $GROUP_NAME" + + # Only show reboot message if user was actually added + echo "================================================" + echo " IMPORTANT: Reboot or Re-login Required" + echo "================================================" + echo "The user has been added to the defguard group." + echo "Please reboot or log out and back in for the" + echo "group membership changes to take effect." + echo "================================================" + else + echo "Warning: Failed to add user $TARGET_USER to group $GROUP_NAME" + exit 1 + fi fi fi From 88d0b165fb075e5df771facc58407d8944ad3083 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20W=C3=B3jcik?= Date: Tue, 9 Sep 2025 11:53:15 +0200 Subject: [PATCH 12/13] also set group explicitly on linux --- src-tauri/src/service/mod.rs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src-tauri/src/service/mod.rs b/src-tauri/src/service/mod.rs index bbb4ed80..c571b5af 100644 --- a/src-tauri/src/service/mod.rs +++ b/src-tauri/src/service/mod.rs @@ -29,7 +29,7 @@ use defguard_wireguard_rs::{ net::IpAddrMask, InterfaceConfiguration, WGApi, WireguardInterfaceApi, }; -#[cfg(target_os = "macos")] +#[cfg(unix)] use nix::unistd::{chown, Group}; use proto::{ desktop_daemon_service_server::{DesktopDaemonService, DesktopDaemonServiceServer}, @@ -63,6 +63,9 @@ pub(super) const DAEMON_SOCKET_PATH: &str = "/var/run/defguard.socket"; #[cfg(target_os = "macos")] pub(super) const DAEMON_SOCKET_GROUP: &str = "staff"; +#[cfg(target_os = "linux")] +pub(super) const DAEMON_SOCKET_GROUP: &str = "defguard"; + #[derive(Error, Debug)] pub enum DaemonError { #[error(transparent)] @@ -356,17 +359,14 @@ pub async fn run_server(config: Config) -> anyhow::Result<()> { let uds = UnixListener::bind(DAEMON_SOCKET_PATH)?; // change owner group for socket file - #[cfg(target_os = "macos")] - { - // get the group ID by name - let group = Group::from_name(DAEMON_SOCKET_GROUP)?.ok_or_else(|| { - error!("Group '{}' not found", DAEMON_SOCKET_GROUP); - Error::InternalError(format!("Group '{}' not found", DAEMON_SOCKET_GROUP)) - })?; + // get the group ID by name + let group = Group::from_name(DAEMON_SOCKET_GROUP)?.ok_or_else(|| { + error!("Group '{}' not found", DAEMON_SOCKET_GROUP); + Error::InternalError(format!("Group '{}' not found", DAEMON_SOCKET_GROUP)) + })?; - // change ownership - keep current user, change group - chown(DAEMON_SOCKET_PATH, None, Some(group.gid))?; - } + // change ownership - keep current user, change group + chown(DAEMON_SOCKET_PATH, None, Some(group.gid))?; // Set socket permissions to allow client access // 0o660 allows read/write for owner and group only From 9f624a39a23ecde50bc52421cf105d196c9455f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20W=C3=B3jcik?= Date: Tue, 9 Sep 2025 12:17:46 +0200 Subject: [PATCH 13/13] add more detailed description for linux bundles --- src-tauri/tauri.conf.json | 6 +++--- src-tauri/tauri.linux.conf.json | 5 +++++ 2 files changed, 8 insertions(+), 3 deletions(-) create mode 100644 src-tauri/tauri.linux.conf.json diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 89d9a114..6ab63153 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -35,7 +35,6 @@ ] } }, - "longDescription": "Defguard desktop client.", "macOS": { "entitlements": null, "exceptionDomain": "", @@ -46,7 +45,8 @@ "resources": [ "resources/icons/*" ], - "shortDescription": "", + "shortDescription": "Defguard desktop client", + "longDescription": "Defguard desktop client", "linux": { "deb": { "files": { @@ -107,4 +107,4 @@ } } } -} +} \ No newline at end of file diff --git a/src-tauri/tauri.linux.conf.json b/src-tauri/tauri.linux.conf.json new file mode 100644 index 00000000..1ceacbf7 --- /dev/null +++ b/src-tauri/tauri.linux.conf.json @@ -0,0 +1,5 @@ +{ + "bundle": { + "longDescription": "IMPORTANT: Reboot or Re-login Required\nOn initial install the user is added to the defguard group.\nA reboot or logging out and back in is required for group membership changes to take effect.\nThis is not required on subsequent updates." + } +} \ No newline at end of file