Traditional Linux firewalling relies on global rule sets managed by iptables, nftables, or firewalld. While effective, these approaches apply rules system-wide and can become complex in multi-service environments.
A lesser-known but powerful feature of systemd allows administrators to enforce network access control on a per-service basis, without modifying global firewall rules.
This document explains how to implement per-service firewall restrictions using systemd on AlmaLinux, Rocky Linux, and RHEL-based systems.
No impact on existing firewall rules
Service-level network isolation
Reduced blast radius during compromise
Ideal for shared servers and hosting environments
Rarely documented outside internal enterprise setups
AlmaLinux 8 / 9
Rocky Linux 8 / 9
RHEL 8 / 9
systemd v239+
systemd provides built-in network filtering through the following directives:
IPAddressAllow=
IPAddressDeny=
RestrictAddressFamilies=
PrivateNetwork=
These controls apply only to the service, not the entire system.
Example service:
nginx
mysqld
php-fpm
Any custom systemd service
Check the service unit:
systemctl cat nginx
Never edit vendor unit files directly.
systemctl edit nginx
This opens an override configuration.
Allow only specific IPs or networks.
[Service]
IPAddressDeny=any
IPAddressAllow=127.0.0.1
IPAddressAllow=192.168.10.0/24
IPAddressDeny=any blocks all network traffic
IPAddressAllow= explicitly whitelists allowed destinations
Rules apply only to this service
Limit the service to IPv4 only:
[Service]
RestrictAddressFamilies=AF_INET
Supported families include:
AF_INET (IPv4)
AF_INET6 (IPv6)
AF_UNIX
systemctl daemon-reexec
systemctl restart nginx
Verify:
systemctl status nginx
Attempt outbound access from the service context.
Example (PHP-FPM or app-based service):
External API calls fail
Internal subnet access works
Check logs:
journalctl -u nginx
Blocked connections are logged by systemd.
To fully isolate a service:
[Service]
PrivateNetwork=yes
No access to host network
Loopback only
Ideal for untrusted or sandboxed services
Prevent web services from accessing metadata endpoints
Stop compromised apps from scanning the network
Enforce zero-trust principles
Secure multi-tenant hosting environments
Protect backup or billing services
Feature | systemd | iptables/firewalld |
|---|---|---|
Per-service rules | ✅ Yes | ❌ No |
Global impact | ❌ No | ✅ Yes |
Configuration complexity | Low | Medium-High |
Requires extra tooling | ❌ No | ✅ Yes |
Applies only to systemd-managed services
No packet inspection or logging granularity
Not a replacement for perimeter firewalls
Combine with NoNewPrivileges=yes
Enable ProtectSystem=strict
Use ProtectHome=yes
Pair with SELinux for defense-in-depth
systemctl show nginx | grep IPAddress
systemd-analyze security nginx
systemd’s per-service network controls provide a clean, powerful, and underutilized security layer that eliminates the need for complex firewall rules in many scenarios.
This approach is widely used in hardened enterprise environments but remains largely undocumented in public tutorials.