feat: add auto-enrollment, cert validation, and crash loop fixes
- Auto-enrollment on startup when certs are missing/invalid and enrollment.manager_url configured - Certificate validation (existence, parse, expiry, key match, CA trust) - --enroll exits after completion (no port conflict with systemd service) - --renew-certs flag for manual cert renewal - SO_REUSEADDR on TcpListener::bind (prevents Address already in use) - Polling token persistence for enrollment resume after restart - Exit code strategy (0=clean, 1=error, 2=enrollment in progress) - HTTP 409 (host already exists) handling during enrollment - Move 'Listening on' log after actual bind - Increase RestartSec to 10s and add StartLimitBurst=5 - Postinst checks for certs and enrollment URL, prints guidance - EnrollmentConfig.manager_url changed to Option<String> - cert_renewal_threshold_days and polling_token config fields - Updated SPEC.md and DEPLOYMENT_GUIDE.md with new workflow - RCA document for crash loop root cause analysis - Version bumped to 1.2.0
This commit is contained in:
@ -1,11 +0,0 @@
|
||||
linux-patch-api (1.0.0-1) stable; urgency=medium
|
||||
|
||||
* Initial production release
|
||||
* Secure mTLS-authenticated REST API for remote package management
|
||||
* 15 API endpoints for package install/remove, patch application, system management
|
||||
* Asynchronous job processing with WebSocket status streaming
|
||||
* IP whitelist enforcement and comprehensive audit logging
|
||||
* Systemd integration with security hardening
|
||||
* Supports Debian 11/12, Ubuntu 20.04/22.04/24.04
|
||||
|
||||
-- Echo <echo@moon-dragon.us> Thu, 09 Apr 2026 18:57:12 -0500
|
||||
@ -1,4 +0,0 @@
|
||||
debian/tmp/usr/bin/linux-patch-api
|
||||
debian/tmp/lib/systemd/system/linux-patch-api.service
|
||||
debian/tmp/etc/linux_patch_api/config.yaml
|
||||
debian/tmp/etc/linux_patch_api/whitelist.yaml
|
||||
@ -1,30 +0,0 @@
|
||||
# Automatically added by dh_installsystemd/13.31
|
||||
if [ "$1" = "configure" ] || [ "$1" = "abort-upgrade" ] || [ "$1" = "abort-deconfigure" ] || [ "$1" = "abort-remove" ] ; then
|
||||
# The following line should be removed in trixie or trixie+1
|
||||
deb-systemd-helper unmask 'linux-patch-api.service' >/dev/null || true
|
||||
|
||||
# was-enabled defaults to true, so new installations run enable.
|
||||
if deb-systemd-helper --quiet was-enabled 'linux-patch-api.service'; then
|
||||
# Enables the unit on first installation, creates new
|
||||
# symlinks on upgrades if the unit file has changed.
|
||||
deb-systemd-helper enable 'linux-patch-api.service' >/dev/null || true
|
||||
else
|
||||
# Update the statefile to add new symlinks (if any), which need to be
|
||||
# cleaned up on purge. Also remove old symlinks.
|
||||
deb-systemd-helper update-state 'linux-patch-api.service' >/dev/null || true
|
||||
fi
|
||||
fi
|
||||
# End automatically added section
|
||||
# Automatically added by dh_installsystemd/13.31
|
||||
if [ "$1" = "configure" ] || [ "$1" = "abort-upgrade" ] || [ "$1" = "abort-deconfigure" ] || [ "$1" = "abort-remove" ] ; then
|
||||
if [ -d /run/systemd/system ]; then
|
||||
systemctl --system daemon-reload >/dev/null || true
|
||||
if [ -n "$2" ]; then
|
||||
_dh_action=restart
|
||||
else
|
||||
_dh_action=start
|
||||
fi
|
||||
deb-systemd-invoke $_dh_action 'linux-patch-api.service' >/dev/null || true
|
||||
fi
|
||||
fi
|
||||
# End automatically added section
|
||||
@ -1,5 +0,0 @@
|
||||
# Automatically added by dh_installsystemd/13.31
|
||||
if [ -z "$DPKG_ROOT" ] && [ "$1" = remove ] && [ -d /run/systemd/system ] ; then
|
||||
deb-systemd-invoke stop 'linux-patch-api.service' >/dev/null || true
|
||||
fi
|
||||
# End automatically added section
|
||||
200
debian/changelog
vendored
200
debian/changelog
vendored
@ -1,190 +1,22 @@
|
||||
linux-patch-api (1.2.0) unstable; urgency=medium
|
||||
|
||||
* Add auto-enrollment on startup when certs are missing/invalid
|
||||
* Add cert validation (existence, parse, expiry, key match, CA trust)
|
||||
* Add --renew-certs CLI flag for manual cert renewal
|
||||
* Fix --enroll to exit after completion (no port conflict)
|
||||
* Add SO_REUSEADDR to prevent Address already in use errors
|
||||
* Add polling token persistence for enrollment resume after restart
|
||||
* Add exit code strategy (0=clean, 1=error, 2=enrollment in progress)
|
||||
* Increase RestartSec to 10s and add StartLimitBurst=5
|
||||
* Add cert and enrollment URL check in postinst
|
||||
* Fix misleading "Listening on" log before actual bind
|
||||
|
||||
-- Echo <echo@moon-dragon.us> Thu, 29 May 2026 10:20:00 -0500
|
||||
|
||||
linux-patch-api (1.1.17) unstable; urgency=medium
|
||||
|
||||
* Add mandatory package cache refresh before patch_apply
|
||||
* Add health check cache refresh when stale (>4h)
|
||||
* Add cache status fields to health response
|
||||
* Add 404/fetch error retry with cache refresh
|
||||
* Add degraded health status on cache failure
|
||||
* New src/packages/cache.rs module
|
||||
|
||||
-- Echo <echo@moon-dragon.us> Tue, 27 May 2026 15:30:00 -0500
|
||||
|
||||
linux-patch-api (1.1.16) unstable; urgency=medium
|
||||
|
||||
* Add Pacman package manager backend for Arch Linux
|
||||
* Fix: Pacman backend not yet implemented error on Arch systems
|
||||
* Support pacman -Q for package listing, pacman -Qi for package details
|
||||
* Support pacman -Qu for patch/update detection
|
||||
* Fix Arch CI: add stale package cleanup and version verification
|
||||
|
||||
-- Echo <echo@moon-dragon.us> Tue, 20 May 2026 17:11:00 -0500
|
||||
|
||||
linux-patch-api (1.1.15) unstable; urgency=medium
|
||||
|
||||
* Add DNF package manager backend for Fedora/RHEL/CentOS 8+
|
||||
* Add YUM package manager backend for RHEL/CentOS 7
|
||||
* Fix: DNF backend not yet implemented error on Fedora systems
|
||||
* Support rpm -qa for package listing, rpm -qi for package details
|
||||
* Support dnf check-update (exit code 100) for patch detection
|
||||
* Support yum check-update (exit code 100) for patch detection
|
||||
|
||||
-- Echo <echo@moon-dragon.us> Tue, 20 May 2026 15:41:00 -0500
|
||||
|
||||
linux-patch-api (1.1.14) unstable; urgency=medium
|
||||
|
||||
* Fix RPM packaging: pre-build binary before tarball (like Alpine/Arch pattern)
|
||||
* Fix rpmbuild can't find cargo in PATH - binary now included in source tarball
|
||||
* Fix config file ownership: add %defattr(-,root,root,-) in %files section
|
||||
* Fix Requires: libsystemd -> systemd-libs for Fedora compatibility
|
||||
* Remove Requires: systemd (not needed, may not exist in containers)
|
||||
* Add stale RPM cleanup and version verification to build-rpm.sh
|
||||
* Support SKIP_CARGO_BUILD=1 like Alpine/Arch builds
|
||||
|
||||
-- Echo <echo@moon-dragon.us> Tue, 20 May 2026 14:44:00 -0500
|
||||
|
||||
linux-patch-api (1.1.13) unstable; urgency=medium
|
||||
|
||||
* Fix APK backend detection for Alpine (/sbin/apk not /usr/bin/apk)
|
||||
|
||||
-- Echo <echo@moon-dragon.us> Tue, 20 May 2026 13:55:00 -0500
|
||||
|
||||
linux-patch-api (1.1.12) unstable; urgency=medium
|
||||
|
||||
* Add APK (Alpine Linux) package manager backend
|
||||
* Add machine-id generation to Alpine pre-install script
|
||||
* Fix OpenRC init script ownership (root:root)
|
||||
|
||||
-- Echo <echo@moon-dragon.us> Tue, 20 May 2026 12:25:00 -0500
|
||||
|
||||
linux-patch-api (1.1.10-1) unstable; urgency=low
|
||||
|
||||
* Fix Alpine install scripts: use separate files with valid abuild suffixes
|
||||
* Root cause: .apk-install is not a valid abuild suffix (abuild silently fails)
|
||||
* Correct format: pkgname.pre-install, .post-install, .pre-deinstall, .post-deinstall
|
||||
* Verified on actual Alpine runner: install script suffixes now pass abuild validation
|
||||
|
||||
-- Echo <echo@moon-dragon.us> Wed, 20 May 2026 07:43:00 -0500
|
||||
|
||||
linux-patch-api (1.1.9-1) unstable; urgency=low
|
||||
|
||||
* Fix non-Ubuntu packages: align Arch, RPM, Alpine with Debian baseline
|
||||
* Remove system user creation (service runs as root)
|
||||
* Fix ownership to root:root across all platforms
|
||||
* Fix Alpine: co-locate install script with APKBUILD
|
||||
* Fix Arch: correct $startdir path in PKGBUILD
|
||||
* Fix RPM: add runtime deps, comment BuildRequires for CI
|
||||
* Add comprehensive installation docs for all platforms
|
||||
|
||||
-- Echo <echo@moon-dragon.us> Tue, 19 May 2026 21:54:00 -0500
|
||||
|
||||
linux-patch-api (1.1.8-1) unstable; urgency=low
|
||||
|
||||
* Fix FQDN resolution: prioritize hostname -f over /etc/hostname for full domain
|
||||
* Fix display_name blank: add hostname field to enrollment request
|
||||
* Fix Arch package: add install scripts, user creation, directory creation
|
||||
* Fix Alpine package: add install scripts, user creation, missing config.yaml
|
||||
* Fix RPM package: dynamic version, config handling, tarball exclusions
|
||||
|
||||
-- Echo <echo@moon-dragon.us> Mon, 18 May 2026 19:34:00 -0500
|
||||
|
||||
linux-patch-api (1.1.7-1) unstable; urgency=low
|
||||
|
||||
* Fix CI pipeline: add cargo clean and remove old .deb artifacts before packaging
|
||||
* Bump version to 1.1.7 to ensure clean build with correct binary
|
||||
|
||||
-- Echo <echo@moon-dragon.us> Mon, 18 May 2026 12:20:00 -0500
|
||||
|
||||
linux-patch-api (1.1.6-1) unstable; urgency=low
|
||||
|
||||
* Fix rustls CryptoProvider initialization panic on server startup
|
||||
* Add explicit CryptoProvider::install_default() for aws-lc-rs
|
||||
|
||||
-- Echo <echo@moon-dragon.us> Mon, 18 May 2026 08:45:00 -0500
|
||||
|
||||
linux-patch-api (1.1.5-1) unstable; urgency=low
|
||||
|
||||
* Fix enrollment IP detection: filter Docker bridge subnets (172.16.0.0/12)
|
||||
* Fix enrollment IP detection: filter link-local addresses (169.254.0.0/16)
|
||||
* Add report_interface and report_ip config options for explicit IP override
|
||||
* Add route-based IP selection using kernel routing table
|
||||
* Fix package versioning to derive from Cargo.toml
|
||||
|
||||
-- Echo <echo@moon-dragon.us> Sun, 18 May 2026 02:00:00 -0500
|
||||
|
||||
linux-patch-api (0.3.12-1) unstable; urgency=low
|
||||
|
||||
* Fix socket activation detection to use resolved service name
|
||||
* Queries like "sshd" now correctly resolve to "ssh.socket" for socket activation
|
||||
|
||||
-- Echo <echo@moon-dragon.us> Tue, 06 May 2026 20:42:00 -0500
|
||||
|
||||
linux-patch-api (0.3.10-1) unstable; urgency=low
|
||||
|
||||
* Fix socket activation detection for service status healthy logic
|
||||
* When service is inactive but enabled, check if .socket unit is active
|
||||
|
||||
-- Echo <echo@moon-dragon.us> Mon, 05 May 2026 13:10:00 -0500
|
||||
|
||||
linux-patch-api (0.3.9-1) unstable; urgency=low
|
||||
|
||||
* Fix socket activation detection for service status healthy logic
|
||||
* When service is inactive but enabled, check if .socket unit is active
|
||||
* Mark service healthy if socket is listening (e.g., ssh.socket for ssh.service)
|
||||
|
||||
-- Echo <echo@moon-dragon.us> Mon, 05 May 2026 11:25:00 -0500
|
||||
|
||||
linux-patch-api (0.3.8-1) unstable; urgency=low
|
||||
|
||||
* Add GET /api/v1/system/services/{name} endpoint for service health checks
|
||||
* Add ServiceStatus struct with systemd and OpenRC support
|
||||
* Add get_service_status() to PackageManagerBackend trait
|
||||
* Implement systemd service status via systemctl
|
||||
* Implement OpenRC service status via rc-service
|
||||
* Add E2E test for service status endpoint
|
||||
|
||||
-- Echo <echo@moon-dragon.us> Mon, 04 May 2026 23:44:00 -0500
|
||||
|
||||
linux-patch-api (0.3.5-1) unstable; urgency=low
|
||||
|
||||
* Remove CapabilityBoundingSet and AmbientCapabilities - apt needs full root capabilities
|
||||
* Remove ProtectSystem=strict, NoNewPrivileges, RestrictSUIDSGID - block core functionality
|
||||
* Remove ReadWritePaths - unnecessary without ProtectSystem=strict
|
||||
* Fix E2E test: properly FAIL on status=failed package operations
|
||||
* Fix E2E test: require status=completed for install/update/remove lifecycle
|
||||
* Update service file Type=notify -> Type=simple
|
||||
* Add DEBIAN_FRONTEND=noninteractive environment variable
|
||||
|
||||
-- Echo <echo@moon-dragon.us> Sat, 03 May 2026 03:15:00 -0500
|
||||
|
||||
linux-patch-api (0.3.4-1) unstable; urgency=low
|
||||
|
||||
* Fix CI workflow: prevent recursive tag triggers (v* -> v*.*.*)
|
||||
* Fix CI workflow: upload u2204 deb to same release (no -u2204 suffix)
|
||||
* Remove sudo from apt commands (service runs as root)
|
||||
* Remove NoNewPrivileges and RestrictSUIDSGID from service file
|
||||
* Update service file Type=notify -> Type=simple
|
||||
* Add DEBIAN_FRONTEND=noninteractive environment variable
|
||||
|
||||
-- Echo <echo@moon-dragon.us> Fri, 02 May 2026 22:00:00 -0500
|
||||
|
||||
linux-patch-api (0.3.3-1) unstable; urgency=low
|
||||
|
||||
* Fix dpkg packaging: remove linux-patch-api user creation
|
||||
* Change ownership to root:root in preinst/postinst scripts
|
||||
* Bump version to 0.3.3
|
||||
|
||||
-- Echo <echo@moon-dragon.us> Fri, 02 May 2026 21:45:00 -0500
|
||||
|
||||
linux-patch-api (0.3.2-1) unstable; urgency=low
|
||||
|
||||
* Remove sudo from apt commands in source code
|
||||
* Remove NoNewPrivileges=true from service file
|
||||
* Remove RestrictSUIDSGID=true from service file
|
||||
* Add DEBIAN_FRONTEND=noninteractive to service file
|
||||
* Fix TLS 1.3 enforcement in mtls.rs
|
||||
* Add client_disconnect_timeout to main.rs
|
||||
* Optimize RwLock usage in jobs/manager.rs
|
||||
* Bump version to 0.3.2
|
||||
|
||||
-- Echo <echo@moon-dragon.us> Fri, 02 May 2026 21:30:00 -0500
|
||||
|
||||
-- Echo <echo@moon-dragon.us> Thu, 22 May 2026 12:00:00 -0500
|
||||
|
||||
1
debian/debhelper-build-stamp
vendored
1
debian/debhelper-build-stamp
vendored
@ -1 +0,0 @@
|
||||
linux-patch-api
|
||||
2
debian/files
vendored
2
debian/files
vendored
@ -1,2 +0,0 @@
|
||||
linux-patch-api_1.0.0-1_amd64.buildinfo admin optional
|
||||
linux-patch-api_1.0.0-1_amd64.deb admin optional
|
||||
1
debian/linux-patch-api.debhelper.log
vendored
1
debian/linux-patch-api.debhelper.log
vendored
@ -1 +0,0 @@
|
||||
dh_auto_install
|
||||
12
debian/linux-patch-api.postrm.debhelper
vendored
12
debian/linux-patch-api.postrm.debhelper
vendored
@ -1,12 +0,0 @@
|
||||
# Automatically added by dh_installsystemd/13.31
|
||||
if [ "$1" = remove ] && [ -d /run/systemd/system ] ; then
|
||||
systemctl --system daemon-reload >/dev/null || true
|
||||
fi
|
||||
# End automatically added section
|
||||
# Automatically added by dh_installsystemd/13.31
|
||||
if [ "$1" = "purge" ]; then
|
||||
if [ -x "/usr/bin/deb-systemd-helper" ]; then
|
||||
deb-systemd-helper purge 'linux-patch-api.service' >/dev/null || true
|
||||
fi
|
||||
fi
|
||||
# End automatically added section
|
||||
3
debian/linux-patch-api.substvars
vendored
3
debian/linux-patch-api.substvars
vendored
@ -1,3 +0,0 @@
|
||||
shlibs:Depends=libc6 (>= 2.39), libgcc-s1 (>= 4.2)
|
||||
misc:Depends=
|
||||
misc:Pre-Depends=
|
||||
4
debian/linux-patch-api/DEBIAN/conffiles
vendored
4
debian/linux-patch-api/DEBIAN/conffiles
vendored
@ -1,4 +0,0 @@
|
||||
/etc/linux_patch_api/config.yaml
|
||||
/etc/linux_patch_api/whitelist.yaml
|
||||
/etc/linux_patch_api/config.yaml
|
||||
/etc/linux_patch_api/whitelist.yaml
|
||||
23
debian/linux-patch-api/DEBIAN/control
vendored
23
debian/linux-patch-api/DEBIAN/control
vendored
@ -1,23 +0,0 @@
|
||||
Package: linux-patch-api
|
||||
Version: 1.0.0-1
|
||||
Architecture: amd64
|
||||
Maintainer: Echo <echo@moon-dragon.us>
|
||||
Installed-Size: 8897
|
||||
Depends: systemd, libsystemd0, libc6 (>= 2.39), libgcc-s1 (>= 4.2)
|
||||
Section: admin
|
||||
Priority: optional
|
||||
Homepage: https://gitea.moon-dragon.us/echo/linux_patch_api
|
||||
Description: Secure remote package management API for Linux systems
|
||||
Linux Patch API provides a secure, mTLS-authenticated REST API for
|
||||
remote package management operations including:
|
||||
- Package installation and removal
|
||||
- Security patch application
|
||||
- System health monitoring
|
||||
- Job queue management with WebSocket status streaming
|
||||
.
|
||||
Features:
|
||||
- Mutual TLS (mTLS) authentication
|
||||
- IP whitelist enforcement
|
||||
- Asynchronous job processing
|
||||
- Comprehensive audit logging
|
||||
- Systemd integration with security hardening
|
||||
5
debian/linux-patch-api/DEBIAN/md5sums
vendored
5
debian/linux-patch-api/DEBIAN/md5sums
vendored
@ -1,5 +0,0 @@
|
||||
23b89eecc51f46c6813658dd615d13a9 lib/systemd/system/linux-patch-api.service
|
||||
d64a80e2a796561c39c6941c6b9e268c usr/bin/linux-patch-api
|
||||
154c7ae7e01ae22cdc8ceea1fd0956e2 usr/share/doc/linux-patch-api/changelog.Debian.gz
|
||||
978478c6c7f1e9dcb38eb1f2454535c0 usr/share/doc/linux-patch-api/changelog.gz
|
||||
c2fab316c94aa61adb70d79365cfe08f usr/share/doc/linux-patch-api/copyright
|
||||
49
debian/linux-patch-api/DEBIAN/postinst
vendored
49
debian/linux-patch-api/DEBIAN/postinst
vendored
@ -1,49 +0,0 @@
|
||||
#!/bin/bash
|
||||
# postinst script for linux-patch-api
|
||||
# Created by package build system
|
||||
|
||||
set -e
|
||||
|
||||
# Configure with debhelper
|
||||
if [ "$1" = "configure" ]; then
|
||||
echo "Configuring linux-patch-api..."
|
||||
|
||||
# Copy example configs if they don't exist
|
||||
if [ ! -f "/etc/linux_patch_api/config.yaml" ]; 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 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 root:root /etc/linux_patch_api/whitelist.yaml
|
||||
fi
|
||||
|
||||
# Reload systemd daemon to pick up new service file
|
||||
systemctl daemon-reload
|
||||
|
||||
# Enable the service (but don't start automatically - admin should configure first)
|
||||
systemctl enable linux-patch-api.service
|
||||
|
||||
echo ""
|
||||
echo "linux-patch-api installed successfully!"
|
||||
echo ""
|
||||
echo "Next steps:"
|
||||
echo " 1. Configure /etc/linux_patch_api/config.yaml with your settings"
|
||||
echo " 2. Place TLS certificates in /etc/linux_patch_api/certs/"
|
||||
echo " 3. Configure IP whitelist in /etc/linux_patch_api/whitelist.yaml"
|
||||
echo " 4. Start the service: systemctl start linux-patch-api"
|
||||
echo " 5. Check status: systemctl status linux-patch-api"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# Handle upgrade
|
||||
if [ "$1" = "abort-upgrade" ] || [ "$1" = "abort-remove" ] || [ "$1" = "abort-deconfigure" ]; then
|
||||
echo "Installation aborted - service remains in previous state"
|
||||
fi
|
||||
|
||||
exit 0
|
||||
52
debian/linux-patch-api/DEBIAN/postrm
vendored
52
debian/linux-patch-api/DEBIAN/postrm
vendored
@ -1,52 +0,0 @@
|
||||
#!/bin/bash
|
||||
# postrm script for linux-patch-api
|
||||
# Created by package build system
|
||||
|
||||
set -e
|
||||
|
||||
# Handle purge - remove all configuration and data
|
||||
if [ "$1" = "purge" ]; then
|
||||
echo "Purging linux-patch-api configuration and data..."
|
||||
|
||||
# Stop service if still running
|
||||
if systemctl is-active --quiet linux-patch-api.service 2>/dev/null; then
|
||||
systemctl stop linux-patch-api.service
|
||||
fi
|
||||
|
||||
# Disable service
|
||||
if systemctl is-enabled --quiet linux-patch-api.service 2>/dev/null; then
|
||||
systemctl disable linux-patch-api.service
|
||||
fi
|
||||
|
||||
# Reload systemd to remove service file
|
||||
systemctl daemon-reload
|
||||
|
||||
# Remove configuration directory (preserved by conffiles during normal remove)
|
||||
if [ -d "/etc/linux_patch_api" ]; then
|
||||
echo "Removing /etc/linux_patch_api..."
|
||||
rm -rf /etc/linux_patch_api
|
||||
fi
|
||||
|
||||
# Remove data directory
|
||||
if [ -d "/var/lib/linux_patch_api" ]; then
|
||||
echo "Removing /var/lib/linux_patch_api..."
|
||||
rm -rf /var/lib/linux_patch_api
|
||||
fi
|
||||
|
||||
# Remove log directory
|
||||
if [ -d "/var/log/linux_patch_api" ]; then
|
||||
echo "Removing /var/log/linux_patch_api..."
|
||||
rm -rf /var/log/linux_patch_api
|
||||
fi
|
||||
|
||||
echo "linux-patch-api purged successfully"
|
||||
fi
|
||||
|
||||
# Handle upgrade/remove - just ensure service is disabled
|
||||
if [ "$1" = "remove" ] || [ "$1" = "upgrade" ]; then
|
||||
# Service should already be stopped by prerm
|
||||
# Just reload systemd to remove the service file
|
||||
systemctl daemon-reload 2>/dev/null || true
|
||||
fi
|
||||
|
||||
exit 0
|
||||
29
debian/linux-patch-api/DEBIAN/preinst
vendored
29
debian/linux-patch-api/DEBIAN/preinst
vendored
@ -1,29 +0,0 @@
|
||||
#!/bin/bash
|
||||
# preinst script for linux-patch-api
|
||||
# Created by package build system
|
||||
|
||||
set -e
|
||||
|
||||
# Check if this is an upgrade
|
||||
if [ -d "/etc/linux_patch_api" ]; then
|
||||
echo "Detected existing installation - performing upgrade"
|
||||
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 (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
|
||||
chmod 750 /etc/linux_patch_api/certs
|
||||
chmod 755 /var/lib/linux_patch_api
|
||||
chmod 755 /var/log/linux_patch_api
|
||||
|
||||
echo "Pre-installation checks completed successfully"
|
||||
|
||||
exit 0
|
||||
33
debian/linux-patch-api/DEBIAN/prerm
vendored
33
debian/linux-patch-api/DEBIAN/prerm
vendored
@ -1,33 +0,0 @@
|
||||
#!/bin/bash
|
||||
# prerm script for linux-patch-api
|
||||
# Created by package build system
|
||||
|
||||
set -e
|
||||
|
||||
# Stop the service before removal/upgrade
|
||||
if [ "$1" = "remove" ] || [ "$1" = "upgrade" ]; then
|
||||
echo "Stopping linux-patch-api service..."
|
||||
|
||||
if systemctl is-active --quiet linux-patch-api.service; then
|
||||
systemctl stop linux-patch-api.service
|
||||
echo "Service stopped successfully"
|
||||
else
|
||||
echo "Service was not running"
|
||||
fi
|
||||
|
||||
# Disable the service
|
||||
if systemctl is-enabled --quiet linux-patch-api.service 2>/dev/null; then
|
||||
systemctl disable linux-patch-api.service
|
||||
echo "Service disabled"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Handle failed upgrade
|
||||
if [ "$1" = "failed-upgrade" ]; then
|
||||
echo "Upgrade failed - attempting to restore previous state"
|
||||
# Previous version should handle restoration
|
||||
fi
|
||||
|
||||
echo "Pre-removal script completed"
|
||||
|
||||
exit 0
|
||||
@ -1,46 +0,0 @@
|
||||
# Linux Patch API Configuration
|
||||
# Example configuration file - copy to /etc/linux_patch_api/config.yaml
|
||||
|
||||
# Server Configuration
|
||||
server:
|
||||
port: 12443
|
||||
bind: "0.0.0.0"
|
||||
timeout_seconds: 30
|
||||
|
||||
# TLS/mTLS Configuration
|
||||
tls:
|
||||
enabled: true
|
||||
port: 12443
|
||||
ca_cert: "/etc/linux_patch_api/certs/ca.pem"
|
||||
server_cert: "/etc/linux_patch_api/certs/server.pem"
|
||||
server_key: "/etc/linux_patch_api/certs/server.key"
|
||||
min_tls_version: "1.3"
|
||||
|
||||
# Job Configuration
|
||||
jobs:
|
||||
max_concurrent: 5
|
||||
timeout_minutes: 30
|
||||
storage_path: "/var/lib/linux_patch_api/jobs"
|
||||
|
||||
# Logging Configuration
|
||||
logging:
|
||||
level: "info"
|
||||
journal_enabled: true
|
||||
syslog_enabled: false
|
||||
# syslog_server: "udp://localhost:514"
|
||||
file_path: "/var/log/linux_patch_api/audit.log"
|
||||
retention_days: 30
|
||||
|
||||
# IP Whitelist Configuration
|
||||
whitelist:
|
||||
path: "/etc/linux_patch_api/whitelist.yaml"
|
||||
# Entries can be:
|
||||
# - Individual IPs: "192.168.1.100"
|
||||
# - CIDR subnets: "192.168.1.0/24"
|
||||
# - Hostnames: "admin-server.internal"
|
||||
|
||||
# Package Manager Backend
|
||||
package_manager:
|
||||
# Primary backend (auto-detected if not specified)
|
||||
# Options: apt, dnf, yum, apk, pacman
|
||||
backend: "auto"
|
||||
@ -1,14 +0,0 @@
|
||||
# Linux Patch API - IP Whitelist Configuration
|
||||
# Copy to /etc/linux_patch_api/whitelist.yaml
|
||||
# Block all by default - only listed IPs can access the API
|
||||
|
||||
# Supported entry types:
|
||||
# - Individual IPs: "192.168.1.100"
|
||||
# - CIDR subnets: "192.168.1.0/24"
|
||||
# - Hostnames: "admin-server.internal" (resolved at startup)
|
||||
|
||||
# Example entries:
|
||||
entries:
|
||||
- "192.168.1.0/24" # Management network
|
||||
- "10.0.0.50" # Specific admin workstation
|
||||
# - "admin-server.internal" # Hostname example (uncomment to use)
|
||||
@ -1,62 +0,0 @@
|
||||
[Unit]
|
||||
Description=Linux Patch API - Secure Remote Package Management
|
||||
Documentation=man:linux-patch-api(8)
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
NotifyAccess=all
|
||||
ExecStart=/usr/bin/linux-patch-api --config /etc/linux_patch_api/config.yaml
|
||||
Restart=on-failure
|
||||
RestartSec=5s
|
||||
TimeoutStopSec=30s
|
||||
|
||||
# Process management
|
||||
RuntimeDirectory=linux-patch-api
|
||||
RuntimeDirectoryMode=0755
|
||||
|
||||
# Security hardening
|
||||
# NOTE: Package management requires extensive system access. The following
|
||||
# restrictions have been removed because they block core functionality:
|
||||
# - ProtectSystem=strict: Blocks writes to /usr, /etc, /lib where packages install
|
||||
# - NoNewPrivileges: Blocks sudo/setuid which apt needs for _apt sandbox
|
||||
# - RestrictSUIDSGID: Blocks setuid/setgid which apt needs for _apt sandbox
|
||||
# - CapabilityBoundingSet: Drops capabilities that apt needs (SETUID, SETGID, CHOWN, etc.)
|
||||
# - AmbientCapabilities: Same issue as CapabilityBoundingSet
|
||||
# Network security is provided by mTLS + IP whitelist. The service runs as root
|
||||
# and MUST be able to install/remove/update packages system-wide.
|
||||
ProtectHome=true
|
||||
PrivateTmp=true
|
||||
ProtectHostname=true
|
||||
ProtectClock=true
|
||||
ProtectKernelTunables=true
|
||||
ProtectKernelModules=true
|
||||
ProtectKernelLogs=true
|
||||
RestrictNamespaces=true
|
||||
LockPersonality=true
|
||||
MemoryDenyWriteExecute=false
|
||||
RestrictRealtime=true
|
||||
|
||||
# System call filtering (whitelist approach)
|
||||
SystemCallFilter=@system-service
|
||||
SystemCallErrorNumber=EPERM
|
||||
|
||||
# Environment
|
||||
Environment="RUST_BACKTRACE=1"
|
||||
Environment="DEBIAN_FRONTEND=noninteractive"
|
||||
Environment="RUST_LOG=info"
|
||||
|
||||
# Logging
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
SyslogIdentifier=linux-patch-api
|
||||
SyslogFacility=daemon
|
||||
SyslogLevel=info
|
||||
|
||||
# Resource limits
|
||||
LimitNOFILE=65536
|
||||
LimitNPROC=4096
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
BIN
debian/linux-patch-api/usr/bin/linux-patch-api
vendored
BIN
debian/linux-patch-api/usr/bin/linux-patch-api
vendored
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,31 +0,0 @@
|
||||
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||
Upstream-Name: linux-patch-api
|
||||
Upstream-Contact: Echo <echo@moon-dragon.us>
|
||||
Source: https://gitea.moon-dragon.us/echo/linux_patch_api
|
||||
|
||||
Files: *
|
||||
Copyright: 2024-2026 Echo <echo@moon-dragon.us>
|
||||
License: MIT
|
||||
|
||||
License: MIT
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
.
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
Files: debian/*
|
||||
Copyright: 2024-2026 Echo <echo@moon-dragon.us>
|
||||
License: MIT
|
||||
58
debian/postinst
vendored
58
debian/postinst
vendored
@ -29,16 +29,60 @@ if [ "$1" = "configure" ]; then
|
||||
# Enable the service (but don't start automatically - admin should configure first)
|
||||
systemctl enable linux-patch-api.service
|
||||
|
||||
# Check for TLS certificates and enrollment URL
|
||||
CERT_DIR="/etc/linux_patch_api/certs"
|
||||
CA_CERT="$CERT_DIR/ca.pem"
|
||||
SERVER_CERT="$CERT_DIR/server.pem"
|
||||
SERVER_KEY="$CERT_DIR/server.key.pem"
|
||||
CONFIG_FILE="/etc/linux_patch_api/config.yaml"
|
||||
|
||||
CERTS_MISSING=false
|
||||
if [ ! -f "$CA_CERT" ] || [ ! -f "$SERVER_CERT" ] || [ ! -f "$SERVER_KEY" ]; then
|
||||
CERTS_MISSING=true
|
||||
fi
|
||||
|
||||
if [ "$CERTS_MISSING" = true ]; then
|
||||
echo ""
|
||||
echo "⚠ TLS certificates are missing. The service will not start without them."
|
||||
echo ""
|
||||
|
||||
# Check if enrollment.manager_url is configured
|
||||
if [ -f "$CONFIG_FILE" ]; then
|
||||
# Check for manager_url in config (handles both old String format and new Option format)
|
||||
MANAGER_URL=$(grep -E '^\s*manager_url:' "$CONFIG_FILE" 2>/dev/null | sed 's/^\s*manager_url:\s*//' | tr -d '"' | tr -d "'" | xargs)
|
||||
if [ -n "$MANAGER_URL" ] && [ "$MANAGER_URL" != "" ]; then
|
||||
echo "✓ Auto-enrollment is configured (manager_url: $MANAGER_URL)"
|
||||
echo " Auto-enrollment will run on first service start."
|
||||
echo " The service will automatically request and provision certificates."
|
||||
else
|
||||
echo "⚠ No enrollment.manager_url found in config.yaml."
|
||||
echo ""
|
||||
echo "To enable automatic certificate enrollment, add the manager URL:"
|
||||
echo " 1. Edit /etc/linux_patch_api/config.yaml"
|
||||
echo " 2. Add enrollment.manager_url: https://<your-manager-url>"
|
||||
echo " 3. Start the service: systemctl start linux-patch-api"
|
||||
echo ""
|
||||
echo "Or enroll manually:"
|
||||
echo " linux-patch-api --enroll https://<your-manager-url>"
|
||||
echo ""
|
||||
echo "Or place certificates manually:"
|
||||
echo " - CA certificate: $CA_CERT"
|
||||
echo " - Server certificate: $SERVER_CERT"
|
||||
echo " - Server key: $SERVER_KEY"
|
||||
fi
|
||||
else
|
||||
echo "⚠ Config file not found at $CONFIG_FILE"
|
||||
echo " Please configure the service before starting."
|
||||
fi
|
||||
else
|
||||
echo ""
|
||||
echo "✓ TLS certificates found. The service is ready to start."
|
||||
echo " Start the service: systemctl start linux-patch-api"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "linux-patch-api installed successfully!"
|
||||
echo ""
|
||||
echo "Next steps:"
|
||||
echo " 1. Configure /etc/linux_patch_api/config.yaml with your settings"
|
||||
echo " 2. Place TLS certificates in /etc/linux_patch_api/certs/"
|
||||
echo " 3. Configure IP whitelist in /etc/linux_patch_api/whitelist.yaml"
|
||||
echo " 4. Start the service: systemctl start linux-patch-api"
|
||||
echo " 5. Check status: systemctl status linux-patch-api"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# Handle upgrade
|
||||
|
||||
46
debian/tmp/etc/linux_patch_api/config.yaml
vendored
46
debian/tmp/etc/linux_patch_api/config.yaml
vendored
@ -1,46 +0,0 @@
|
||||
# Linux Patch API Configuration
|
||||
# Example configuration file - copy to /etc/linux_patch_api/config.yaml
|
||||
|
||||
# Server Configuration
|
||||
server:
|
||||
port: 12443
|
||||
bind: "0.0.0.0"
|
||||
timeout_seconds: 30
|
||||
|
||||
# TLS/mTLS Configuration
|
||||
tls:
|
||||
enabled: true
|
||||
port: 12443
|
||||
ca_cert: "/etc/linux_patch_api/certs/ca.pem"
|
||||
server_cert: "/etc/linux_patch_api/certs/server.pem"
|
||||
server_key: "/etc/linux_patch_api/certs/server.key"
|
||||
min_tls_version: "1.3"
|
||||
|
||||
# Job Configuration
|
||||
jobs:
|
||||
max_concurrent: 5
|
||||
timeout_minutes: 30
|
||||
storage_path: "/var/lib/linux_patch_api/jobs"
|
||||
|
||||
# Logging Configuration
|
||||
logging:
|
||||
level: "info"
|
||||
journal_enabled: true
|
||||
syslog_enabled: false
|
||||
# syslog_server: "udp://localhost:514"
|
||||
file_path: "/var/log/linux_patch_api/audit.log"
|
||||
retention_days: 30
|
||||
|
||||
# IP Whitelist Configuration
|
||||
whitelist:
|
||||
path: "/etc/linux_patch_api/whitelist.yaml"
|
||||
# Entries can be:
|
||||
# - Individual IPs: "192.168.1.100"
|
||||
# - CIDR subnets: "192.168.1.0/24"
|
||||
# - Hostnames: "admin-server.internal"
|
||||
|
||||
# Package Manager Backend
|
||||
package_manager:
|
||||
# Primary backend (auto-detected if not specified)
|
||||
# Options: apt, dnf, yum, apk, pacman
|
||||
backend: "auto"
|
||||
14
debian/tmp/etc/linux_patch_api/whitelist.yaml
vendored
14
debian/tmp/etc/linux_patch_api/whitelist.yaml
vendored
@ -1,14 +0,0 @@
|
||||
# Linux Patch API - IP Whitelist Configuration
|
||||
# Copy to /etc/linux_patch_api/whitelist.yaml
|
||||
# Block all by default - only listed IPs can access the API
|
||||
|
||||
# Supported entry types:
|
||||
# - Individual IPs: "192.168.1.100"
|
||||
# - CIDR subnets: "192.168.1.0/24"
|
||||
# - Hostnames: "admin-server.internal" (resolved at startup)
|
||||
|
||||
# Example entries:
|
||||
entries:
|
||||
- "192.168.1.0/24" # Management network
|
||||
- "10.0.0.50" # Specific admin workstation
|
||||
# - "admin-server.internal" # Hostname example (uncomment to use)
|
||||
@ -1,57 +0,0 @@
|
||||
[Unit]
|
||||
Description=Linux Patch API - Secure Remote Package Management
|
||||
Documentation=man:linux-patch-api(8)
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=notify
|
||||
ExecStart=/usr/bin/linux-patch-api --config /etc/linux_patch_api/config.yaml
|
||||
Restart=on-failure
|
||||
RestartSec=5s
|
||||
TimeoutStopSec=30s
|
||||
|
||||
# Process management
|
||||
RuntimeDirectory=linux-patch-api
|
||||
RuntimeDirectoryMode=0755
|
||||
|
||||
# Security hardening
|
||||
NoNewPrivileges=true
|
||||
ProtectSystem=strict
|
||||
ProtectHome=true
|
||||
ReadWritePaths=/var/lib/linux_patch_api /var/log/linux_patch_api
|
||||
PrivateTmp=true
|
||||
PrivateDevices=true
|
||||
ProtectHostname=true
|
||||
ProtectClock=true
|
||||
ProtectKernelTunables=true
|
||||
ProtectKernelModules=true
|
||||
ProtectKernelLogs=true
|
||||
RestrictNamespaces=true
|
||||
LockPersonality=true
|
||||
MemoryDenyWriteExecute=false
|
||||
RestrictRealtime=true
|
||||
RestrictSUIDSGID=true
|
||||
RemoveIPC=true
|
||||
|
||||
# System call filtering (whitelist approach)
|
||||
SystemCallFilter=@system-service
|
||||
SystemCallErrorNumber=EPERM
|
||||
|
||||
# Environment
|
||||
Environment="RUST_BACKTRACE=1"
|
||||
Environment="RUST_LOG=info"
|
||||
|
||||
# Logging
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
SyslogIdentifier=linux-patch-api
|
||||
SyslogFacility=daemon
|
||||
SyslogLevel=info
|
||||
|
||||
# Resource limits
|
||||
LimitNOFILE=65536
|
||||
LimitNPROC=4096
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
BIN
debian/tmp/usr/bin/linux-patch-api
vendored
BIN
debian/tmp/usr/bin/linux-patch-api
vendored
Binary file not shown.
Reference in New Issue
Block a user