Linux system administrators constantly seek ways to enhance security without compromising functionality. One of the most powerful tools available for securing services on modern Linux systems is systemd, which provides extensive security features to restrict service behavior, limit privileges, and minimize attack surfaces.

This guide will walk you through auditing, configuring, and hardening Linux services using systemd’s security directives. By the end, you’ll know how to:

  • Audit service security exposure with systemd-analyze
  • Apply security overrides without modifying original service files
  • Restrict capabilities, system calls, and filesystem access
  • Run services as non-root users for reduced risk
  • Automate directory management for better isolation

Let’s dive in and lock down your Linux system effectively.

1. Auditing Service Security with systemd-analyze

Before making changes, assess the current security posture of your services using systemd-analyze security. This tool generates a security exposure score (0-10) for each service, where 0 is most secure and 10 is highly exposed.

Step 1: Check All Services

Run:

systemd-analyze security

This lists all services with their security scores and highlights missing protections.

READ 👉  WSL Manager: The Best GUI Tool to Manage WSL Distributions on Windows

Step 2: Focus on a Specific Service

For example, to audit Apache (httpd.service):

systemd-analyze security httpd.service

Review the output to identify which security features are disabled.

2. Applying Security Directives via Override Files

Instead of modifying original service files (which may be overwritten by updates), use drop-in override files to apply security settings.

Step 1: Create an Override File

For httpd.service:

sudo systemctl edit httpd.service

This opens an editor where you can add security directives under [Service].

Step 2: Key Security Directives to Implement

DirectivePurpose
PrivateTmp=yesIsolates /tmp for the service
NoNewPrivileges=truePrevents privilege escalation
ProtectSystem=strictMakes /usr/boot/etc read-only
CapabilityBoundingSet=...Restricts Linux capabilities
RestrictNamespaces=...Limits namespace usage
ProtectKernelTunables=yesBlocks /proc/sys modifications
ProtectKernelModules=yesPrevents loading/unloading kernel modules
PrivateDevices=yesDenies access to physical devices
RestrictSUIDSGID=trueBlocks SUID/SGID file creation
IPAddressAllow=192.168.1.0/24Restricts network access

Example Override File:

[Service]
PrivateTmp=yes
NoNewPrivileges=true
ProtectSystem=strict
CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_DAC_READ_SEARCH
RestrictNamespaces=uts ipc pid user cgroup
ProtectKernelTunables=yes
ProtectKernelModules=yes
PrivateDevices=yes
RestrictSUIDSGID=true
IPAddressAllow=192.168.1.0/24

Step 3: Apply Changes

sudo systemctl daemon-reload
sudo systemctl restart httpd.service

Re-run systemd-analyze security httpd.service to verify the improved score.

3. Restricting Capabilities & System Calls

Linux capabilities split root privileges into granular permissions. Restricting them minimizes risk if a service is compromised.

Step 1: Identify Required Capabilities

Common ones:

  • CAP_NET_BIND_SERVICE (bind to ports <1024)
  • CAP_SETUID/CAP_SETGID (change UID/GID)

Step 2: Limit Capabilities in Override File

[Service]
CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_SETUID CAP_SETGID
AmbientCapabilities=CAP_NET_BIND_SERVICE

Step 3: Filter System Calls

Use SystemCallFilter= to whitelist allowed syscalls:

[Service]
SystemCallFilter=@system-service chroot

Warning: Over-restricting syscalls may break services. Test thoroughly!

4. Restricting Filesystem Access

Prevent unauthorized file access with:

DirectiveEffect
ProtectHome=yesBlocks /home/root/run/user
InaccessiblePaths=/pathDenies access to a specific path
ReadOnlyPaths=/var/readonlyMakes a path read-only
PrivateDevices=yesRestricts device access
UMask=0077Sets strict default file permissions

5. Running Services as Non-Root Users

Avoid running services as root when possible. Instead, specify a dedicated user:

[Service]
User=apache
Group=apache

For even better isolation, use ephemeral users with:

[Service]
DynamicUser=yes

6. Automating Directory Management

Systemd can create and manage directories for logs, cache, and runtime data:

[Service]
CacheDirectory=myservice
StateDirectory=myservice
LogsDirectory=myservice
RuntimeDirectory=myservice

This ensures proper permissions and cleanup.

READ 👉  The Most Versatile Linux Distributions You Can Use for Almost Anything

7. Monitoring & Troubleshooting

After applying security settings:

  • Check logs with: journalctl -u httpd.service
  • Debug missing permissions using strace: strace -f systemctl start httpd.service

If a service fails, gradually relax restrictions until functionality is restored.

Conclusion

By leveraging systemd’s security features, you can significantly reduce the attack surface of Linux services without sacrificing usability. Key takeaways:

Audit services with systemd-analyze security
Use override files for persistent security changes
Restrict capabilities, syscalls, and filesystem access
Run services as non-root users
Automate directory management for better isolation

Implement these steps today to harden your Linux system against exploits and unauthorized access!

Final Tip

For maximum security, test changes in a staging environment before applying them to production systems.

Would you like a follow-up guide on advanced systemd sandboxing techniques? Let me know in the comments! 🚀

Did you enjoy this article? Feel free to share it on social media and subscribe to our newsletter so you never miss a post!

And if you'd like to go a step further in supporting us, you can treat us to a virtual coffee ☕️. Thank you for your support ❤️!
Buy Me a Coffee

Categorized in: