Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 157376af7e | |||
| 77e8ac2e65 | |||
| 9e42f32270 |
BIN
.a0proj/audit.db
BIN
.a0proj/audit.db
Binary file not shown.
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -1859,7 +1859,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "linux-patch-api"
|
||||
version = "0.3.1"
|
||||
version = "0.3.2"
|
||||
dependencies = [
|
||||
"actix",
|
||||
"actix-rt",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "linux-patch-api"
|
||||
version = "0.3.1"
|
||||
version = "0.3.2"
|
||||
edition = "2021"
|
||||
authors = ["Echo <echo@moon-dragon.us>"]
|
||||
description = "Secure remote package management API for Linux systems"
|
||||
|
||||
@ -17,7 +17,6 @@ RuntimeDirectory=linux-patch-api
|
||||
RuntimeDirectoryMode=0755
|
||||
|
||||
# Security hardening
|
||||
NoNewPrivileges=true
|
||||
# Allow reboot capability for scheduled reboots
|
||||
CapabilityBoundingSet=CAP_SYS_BOOT
|
||||
AmbientCapabilities=CAP_SYS_BOOT
|
||||
@ -37,7 +36,7 @@ RestrictNamespaces=true
|
||||
LockPersonality=true
|
||||
MemoryDenyWriteExecute=false
|
||||
RestrictRealtime=true
|
||||
RestrictSUIDSGID=true
|
||||
# RestrictSUIDSGID removed - package management requires setuid/setgid for apt/dpkg
|
||||
RemoveIPC=true
|
||||
|
||||
# System call filtering (whitelist approach)
|
||||
|
||||
17
debian/changelog
vendored
17
debian/changelog
vendored
@ -1,3 +1,20 @@
|
||||
linux-patch-api (0.3.3-1) unstable; urgency=low
|
||||
|
||||
* Fix dpkg packaging: Remove linux-patch-api user creation, fix directory ownership
|
||||
* Fix package install: Remove sudo from apt commands (service runs as root)
|
||||
* Remove NoNewPrivileges and RestrictSUIDSGID from systemd service
|
||||
|
||||
-- Echo <echo@moon-dragon.us> Sat, 03 May 2026 02:30:00 -0500
|
||||
linux-patch-api (0.3.2-1) unstable; urgency=low
|
||||
|
||||
* Fix package install: Remove sudo from apt commands (service runs as root)
|
||||
* Fix reboot endpoint: Implement actual system reboot via shutdown/systemctl
|
||||
* Fix patches handler: Call reboot_system() instead of just logging
|
||||
* Remove NoNewPrivileges and RestrictSUIDSGID from systemd service
|
||||
* Add CAP_SYS_BOOT capability to systemd service for LXC reboot support
|
||||
* Fix dpkg packaging: Remove linux-patch-api user creation, fix directory ownership
|
||||
|
||||
-- Echo <echo@moon-dragon.us> Sat, 02 May 2026 21:25:00 -0500
|
||||
linux-patch-api (0.3.1-1) unstable; urgency=low
|
||||
|
||||
* Fix reboot endpoint: Implement actual system reboot via shutdown/systemctl
|
||||
|
||||
4
debian/linux-patch-api/DEBIAN/postinst
vendored
4
debian/linux-patch-api/DEBIAN/postinst
vendored
@ -13,14 +13,14 @@ if [ "$1" = "configure" ]; then
|
||||
echo "Creating default config.yaml..."
|
||||
cp /etc/linux_patch_api/config.yaml.example /etc/linux_patch_api/config.yaml
|
||||
chmod 640 /etc/linux_patch_api/config.yaml
|
||||
chown linux-patch-api:linux-patch-api /etc/linux_patch_api/config.yaml
|
||||
chown root:root /etc/linux_patch_api/config.yaml
|
||||
fi
|
||||
|
||||
if [ ! -f "/etc/linux_patch_api/whitelist.yaml" ]; then
|
||||
echo "Creating default whitelist.yaml..."
|
||||
cp /etc/linux_patch_api/whitelist.yaml.example /etc/linux_patch_api/whitelist.yaml
|
||||
chmod 640 /etc/linux_patch_api/whitelist.yaml
|
||||
chown linux-patch-api:linux-patch-api /etc/linux_patch_api/whitelist.yaml
|
||||
chown root:root /etc/linux_patch_api/whitelist.yaml
|
||||
fi
|
||||
|
||||
# Reload systemd daemon to pick up new service file
|
||||
|
||||
12
debian/linux-patch-api/DEBIAN/postrm
vendored
12
debian/linux-patch-api/DEBIAN/postrm
vendored
@ -39,18 +39,6 @@ if [ "$1" = "purge" ]; then
|
||||
rm -rf /var/log/linux_patch_api
|
||||
fi
|
||||
|
||||
# Remove system user
|
||||
if getent passwd linux-patch-api > /dev/null 2>&1; then
|
||||
echo "Removing user linux-patch-api..."
|
||||
userdel linux-patch-api 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# Remove system group
|
||||
if getent group linux-patch-api > /dev/null 2>&1; then
|
||||
echo "Removing group linux-patch-api..."
|
||||
groupdel linux-patch-api 2>/dev/null || true
|
||||
fi
|
||||
|
||||
echo "linux-patch-api purged successfully"
|
||||
fi
|
||||
|
||||
|
||||
23
debian/linux-patch-api/DEBIAN/preinst
vendored
23
debian/linux-patch-api/DEBIAN/preinst
vendored
@ -9,31 +9,14 @@ if [ -d "/etc/linux_patch_api" ]; then
|
||||
echo "Detected existing installation - performing upgrade"
|
||||
fi
|
||||
|
||||
# Create system user if it doesn't exist
|
||||
if ! getent group linux-patch-api > /dev/null 2>&1; then
|
||||
echo "Creating group linux-patch-api..."
|
||||
groupadd --system linux-patch-api
|
||||
fi
|
||||
|
||||
if ! getent passwd linux-patch-api > /dev/null 2>&1; then
|
||||
echo "Creating user linux-patch-api..."
|
||||
useradd --system \
|
||||
--gid linux-patch-api \
|
||||
--home-dir /var/lib/linux_patch_api \
|
||||
--no-create-home \
|
||||
--shell /usr/sbin/nologin \
|
||||
--comment "Linux Patch API Service" \
|
||||
linux-patch-api
|
||||
fi
|
||||
|
||||
# Create required directories
|
||||
mkdir -p /etc/linux_patch_api/certs
|
||||
mkdir -p /var/lib/linux_patch_api
|
||||
mkdir -p /var/log/linux_patch_api
|
||||
|
||||
# Set proper ownership
|
||||
chown -R linux-patch-api:linux-patch-api /var/lib/linux_patch_api
|
||||
chown -R linux-patch-api:linux-patch-api /var/log/linux_patch_api
|
||||
# Set proper ownership (service runs as root)
|
||||
chown -R root:root /var/lib/linux_patch_api
|
||||
chown -R root:root /var/log/linux_patch_api
|
||||
|
||||
# Set secure permissions
|
||||
chmod 750 /etc/linux_patch_api
|
||||
|
||||
4
debian/postinst
vendored
4
debian/postinst
vendored
@ -13,14 +13,14 @@ if [ "$1" = "configure" ]; then
|
||||
echo "Creating default config.yaml..."
|
||||
cp /etc/linux_patch_api/config.yaml.example /etc/linux_patch_api/config.yaml
|
||||
chmod 640 /etc/linux_patch_api/config.yaml
|
||||
chown linux-patch-api:linux-patch-api /etc/linux_patch_api/config.yaml
|
||||
chown root:root /etc/linux_patch_api/config.yaml
|
||||
fi
|
||||
|
||||
if [ ! -f "/etc/linux_patch_api/whitelist.yaml" ]; then
|
||||
echo "Creating default whitelist.yaml..."
|
||||
cp /etc/linux_patch_api/whitelist.yaml.example /etc/linux_patch_api/whitelist.yaml
|
||||
chmod 640 /etc/linux_patch_api/whitelist.yaml
|
||||
chown linux-patch-api:linux-patch-api /etc/linux_patch_api/whitelist.yaml
|
||||
chown root:root /etc/linux_patch_api/whitelist.yaml
|
||||
fi
|
||||
|
||||
# Reload systemd daemon to pick up new service file
|
||||
|
||||
12
debian/postrm
vendored
12
debian/postrm
vendored
@ -39,18 +39,6 @@ if [ "$1" = "purge" ]; then
|
||||
rm -rf /var/log/linux_patch_api
|
||||
fi
|
||||
|
||||
# Remove system user
|
||||
if getent passwd linux-patch-api > /dev/null 2>&1; then
|
||||
echo "Removing user linux-patch-api..."
|
||||
userdel linux-patch-api 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# Remove system group
|
||||
if getent group linux-patch-api > /dev/null 2>&1; then
|
||||
echo "Removing group linux-patch-api..."
|
||||
groupdel linux-patch-api 2>/dev/null || true
|
||||
fi
|
||||
|
||||
echo "linux-patch-api purged successfully"
|
||||
fi
|
||||
|
||||
|
||||
23
debian/preinst
vendored
23
debian/preinst
vendored
@ -9,31 +9,14 @@ if [ -d "/etc/linux_patch_api" ]; then
|
||||
echo "Detected existing installation - performing upgrade"
|
||||
fi
|
||||
|
||||
# Create system user if it doesn't exist
|
||||
if ! getent group linux-patch-api > /dev/null 2>&1; then
|
||||
echo "Creating group linux-patch-api..."
|
||||
groupadd --system linux-patch-api
|
||||
fi
|
||||
|
||||
if ! getent passwd linux-patch-api > /dev/null 2>&1; then
|
||||
echo "Creating user linux-patch-api..."
|
||||
useradd --system \
|
||||
--gid linux-patch-api \
|
||||
--home-dir /var/lib/linux_patch_api \
|
||||
--no-create-home \
|
||||
--shell /usr/sbin/nologin \
|
||||
--comment "Linux Patch API Service" \
|
||||
linux-patch-api
|
||||
fi
|
||||
|
||||
# Create required directories
|
||||
mkdir -p /etc/linux_patch_api/certs
|
||||
mkdir -p /var/lib/linux_patch_api
|
||||
mkdir -p /var/log/linux_patch_api
|
||||
|
||||
# Set proper ownership
|
||||
chown -R linux-patch-api:linux-patch-api /var/lib/linux_patch_api
|
||||
chown -R linux-patch-api:linux-patch-api /var/log/linux_patch_api
|
||||
# Set proper ownership (service runs as root)
|
||||
chown -R root:root /var/lib/linux_patch_api
|
||||
chown -R root:root /var/log/linux_patch_api
|
||||
|
||||
# Set secure permissions
|
||||
chmod 750 /etc/linux_patch_api
|
||||
|
||||
@ -98,18 +98,9 @@ impl AptBackend {
|
||||
|
||||
/// Run apt command and capture output
|
||||
fn run_apt(&self, args: &[&str]) -> Result<String> {
|
||||
// Use sudo for operations that modify packages (install, upgrade, remove, purge)
|
||||
let needs_sudo = args.first().is_some_and(|&cmd| {
|
||||
matches!(
|
||||
cmd,
|
||||
"install" | "upgrade" | "remove" | "purge" | "dist-upgrade" | "autoremove"
|
||||
)
|
||||
});
|
||||
let (program, cmd_args): (&str, Vec<&str>) = if needs_sudo {
|
||||
("sudo", ["apt"].iter().chain(args.iter()).copied().collect())
|
||||
} else {
|
||||
("apt", args.to_vec())
|
||||
};
|
||||
// Service runs as root - no sudo needed for apt commands
|
||||
let program = "apt";
|
||||
let cmd_args: Vec<&str> = args.to_vec();
|
||||
|
||||
let output = Command::new(program)
|
||||
.args(&cmd_args)
|
||||
|
||||
@ -47,3 +47,27 @@
|
||||
**Correction:** Add `sudo apt-get -f install -y` before `sudo apt-get install` in CI workflow to fix broken deps automatically.
|
||||
**Rule:** Always add `apt-get -f install -y` before `apt-get install` in CI workflows. Runners may have broken apt state from partial upgrades.
|
||||
**Status:** Active
|
||||
|
||||
## 2026-05-03 - NoNewPrivileges=true blocks sudo in systemd services
|
||||
**Mistake:** Service used NoNewPrivileges=true which prevented sudo from working (PERM_SUDOERS: setresuid Operation not permitted).
|
||||
**Correction:** Removed NoNewPrivileges=true from systemd service. The service runs as root and uses sudo for apt commands, which requires privilege escalation capabilities.
|
||||
**Rule:** For package management services that use sudo, do not use NoNewPrivileges=true. mTLS + IP whitelist provides network security.
|
||||
**Status:** Active
|
||||
|
||||
## 2026-05-03 - RestrictSUIDSGID=true blocks sudo in systemd services
|
||||
**Mistake:** Service used RestrictSUIDSGID=true which prevented sudo from using setuid/setgid operations.
|
||||
**Correction:** Removed RestrictSUIDSGID=true from systemd service. Package management requires setuid/setgid for apt/dpkg.
|
||||
**Rule:** For package management services, do not use RestrictSUIDSGID=true. It blocks sudo and apt from working.
|
||||
**Status:** Active
|
||||
|
||||
## 2026-05-03 - dpkg preinst creates linux-patch-api user causing permission issues
|
||||
**Mistake:** dpkg preinst script creates a linux-patch-api system user and changes directory ownership, causing the service to crash with 'Permission denied' on log file creation.
|
||||
**Correction:** Fix dpkg preinst to not create the linux-patch-api user or change directory ownership. Service runs as root and directories should be owned by root.
|
||||
**Rule:** For services that run as root, do not create a dedicated system user in the dpkg preinst script. Keep all directory ownership as root:root.
|
||||
**Status:** Active
|
||||
|
||||
## 2026-05-03 - Service runs as root, no sudo needed for apt commands
|
||||
**Mistake:** Service used sudo to run apt commands even though it runs as root. This caused failures when systemd security restrictions blocked sudo.
|
||||
**Correction:** Removed sudo from apt command execution in the source code. Service runs as root and can execute apt directly.
|
||||
**Rule:** If a service runs as root, it does not need sudo to execute commands. Remove sudo from command execution.
|
||||
**Status:** Active
|
||||
|
||||
Reference in New Issue
Block a user