Table of Contents
- System and Service Targets: Beyond Runlevels
- Socket Activation: On-Demand Service Launching
- Timer Units: Precision Scheduling & Cron Replacement
- Advanced Dependency Management: Orchestrating Complex Workflows
- Resource Control with cgroups: Limiting CPU, Memory, and I/O
- Journald: Centralized, Structured Log Management
- Environment Variables & Service Customization
- Template Units: Dynamic Service Instances
- Security Hardening: Locking Down Services
- Integration with Systemd Tools: Networkd, Resolved, and More
- Conclusion
- References
1. System and Service Targets: Beyond Runlevels
Systemd targets replace traditional SysVinit runlevels, acting as logical groups of units (services, sockets, mounts, etc.) that define system states. Unlike runlevels (which are numbered and rigid), targets are flexible and composable, making them ideal for customizing boot sequences.
Key Concepts:
- Target Units: Endpoints for boot processes (e.g.,
multi-user.target,graphical.target). - Dependencies: Targets depend on other units (e.g.,
network.targetrequires network services). - Isolation: Use
systemctl isolate <target>to switch between states (e.g., rescue mode).
Example Workflows:
- Set Default Target: Replace
runlevel 5withsystemctl set-default graphical.target. - Emergency Mode: Boot into minimal shell with
systemctl isolate emergency.target. - Custom Target: Create a
myapp.targetto group services required for your application:# /etc/systemd/system/myapp.target [Unit] Description=Custom target for MyApp Requires=network.target mysql.service After=network.target mysql.service [Install] WantedBy=multi-user.target
2. Socket Activation: On-Demand Service Launching
Socket activation defers service startup until the first client request, reducing boot time and resource usage. Systemd listens on a socket (TCP/UDP, Unix, etc.) and starts the service only when data arrives.
How It Works:
- A socket unit (
*.socket) defines the socket to monitor. - When a client connects, systemd activates the associated service unit (
*.service). - The service inherits the socket from systemd, avoiding race conditions.
Example: On-Demand Echo Service
-
Create a socket unit (
/etc/systemd/system/echo.socket):[Unit] Description=Echo Service Socket [Socket] ListenStream=127.0.0.1:8080 Accept=yes # Fork a new service instance per connection [Install] WantedBy=sockets.target -
Create a service template (note the
@for dynamic instances):# /etc/systemd/system/[email protected] [Unit] Description=Echo Service Instance %I [Service] ExecStart=/bin/cat # Reads from stdin (inherited socket) and writes back StandardInput=socket StandardOutput=socket -
Enable and test:
systemctl enable --now echo.socket nc 127.0.0.1 8080 # Type text; the service starts and echoes back
3. Timer Units: Precision Scheduling & Cron Replacement
Systemd timers (*.timer) schedule service execution with more flexibility than cron. They support calendar events, monotonic time (e.g., “10 minutes after boot”), and tight integration with systemd dependencies.
Key Advantages Over Cron:
- Dependency Awareness: Timers can wait for targets (e.g.,
network-online.target). - Accuracy: Sub-second precision and
Persistent=trueto catch missed runs. - Logging: Timers and their services log to
journaldfor easy debugging.
Example: Daily Backup Timer
-
Create a service to run the backup (
/etc/systemd/system/backup.service):[Unit] Description=Daily Backup Service [Service] Type=oneshot ExecStart=/usr/local/bin/backup-script.sh -
Create a timer unit (
/etc/systemd/system/backup.timer):[Unit] Description=Run Daily Backup [Timer] OnCalendar=*-*-* 03:00:00 # Run daily at 3 AM Persistent=true # Run missed jobs on startup AccuracySec=1min # Allow 1-minute delay for load balancing [Install] WantedBy=timers.target -
Enable and monitor:
systemctl enable --now backup.timer systemctl list-timers # View active timers journalctl -u backup.service # Check logs
4. Advanced Dependency Management
Systemd’s dependency system goes beyond Requires/Wants to handle complex relationships between units.
Key Directives:
BindsTo=: Hard dependency—if the bound unit stops, this unit stops too (e.g.,BindsTo=db.service).PartOf=: Reverse dependency—if this unit stops, the target unit restarts (e.g.,PartOf=app.service).Before=/After=: Control startup order (e.g.,After=network.targetensures network starts first).RequiresMountsFor=: Wait for specific filesystems to mount (e.g.,RequiresMountsFor=/data).
Example: Database-App Dependency
# /etc/systemd/system/app.service
[Unit]
Description=My Application
Requires=mysql.service
After=mysql.service # App starts only after MySQL is ready
RequiresMountsFor=/var/lib/app # Wait for /var/lib/app to mount
[Service]
ExecStart=/usr/bin/app
5. Resource Control with cgroups
Systemd integrates with cgroups v2 (control groups) to limit CPU, memory, I/O, and other resources for services, preventing resource starvation.
Common Resource Directives:
CPUQuota=: Limit CPU usage (e.g.,CPUQuota=50%for 50% of one core).MemoryMax=: Cap memory (e.g.,MemoryMax=512M).IOWeight=: Prioritize I/O (0–1000; higher = more priority).TasksMax=: Limit number of processes (e.g.,TasksMax=100).
Example: Limit a Service’s CPU
# /etc/systemd/system/heavy-service.service
[Service]
ExecStart=/usr/bin/heavy-task
CPUQuota=20% # Allow 20% of a CPU core
MemoryMax=1G # Max 1GB RAM
6. Journald & Log Management
journald is systemd’s centralized logging daemon, replacing syslog with structured, indexed logs. It stores logs in binary format for efficiency and supports rich querying.
Key Features:
- Structured Logs: Logs include metadata (unit, timestamp, priority, PID).
- Persistence: Enable with
Storage=persistentin/etc/systemd/journald.conf(logs saved to/var/log/journal). - Filtering: Use
journalctlto query by unit, time, priority, etc.
Useful journalctl Commands:
journalctl -u nginx.service # Logs for nginx
journalctl --since "1 hour ago" --until "30 minutes ago" # Time-range filter
journalctl -p err # Only errors (priority 3)
journalctl -f # Follow live logs
journalctl --disk-usage # Check journal size
journalctl --vacuum-size=500M # Trim logs to 500MB
7. Environment Variables & Service Customization
Systemd lets you inject environment variables into services via Environment or EnvironmentFile directives, enabling dynamic configuration.
Example: Pass Variables to a Service
# /etc/systemd/system/app.service
[Service]
Environment="DB_HOST=localhost" "DB_PORT=3306"
EnvironmentFile=/etc/app/env # Load variables from a file
ExecStart=/usr/bin/app --host=$DB_HOST --port=$DB_PORT
Note: For secrets, avoid plaintext files. Use tmpfiles.d to create secure temporary files or integrate with tools like HashiCorp Vault.
8. Template Units: Dynamic Service Instances
Template units (*.service) use the @ syntax to create dynamic service instances (e.g., [email protected], [email protected]), ideal for scaling services like web servers or workers.
Example: Nginx Template
-
Create
[email protected]:[Unit] Description=Web Server Instance %I [Service] ExecStart=/usr/bin/nginx -c /etc/nginx/%I.conf # %I = instance name Restart=on-failure -
Start multiple instances:
systemctl start [email protected] # Uses /etc/nginx/site1.conf systemctl start [email protected] # Uses /etc/nginx/site2.conf -
Manage all instances:
systemctl stop web@*.service # Stop all systemctl enable [email protected] # Persist site1 on boot
9. Security Hardening
Systemd provides granular security controls to restrict service privileges, mitigating attacks like privilege escalation or data leaks.
Critical Security Directives:
PrivateTmp=true: Isolate/tmpfor the service (prevents tmpfile hijacking).ProtectSystem=full: Make/usrand/bootread-only;/etcis read-only except/etc/systemd.NoNewPrivileges=true: Blocksetuid/setgid(prevents privilege escalation).CapabilityBoundingSet=CAP_NET_BIND_SERVICE: Limit Linux capabilities (e.g., only allow binding to ports <1024).User=www-data/Group=www-data: Run as non-root user.
Example: Hardened Web Service
# /etc/systemd/system/secure-web.service
[Service]
User=www-data
Group=www-data
ExecStart=/usr/bin/nginx
PrivateTmp=true
ProtectSystem=full
NoNewPrivileges=true
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
ReadOnlyPaths=/var/www # Restrict write access
10. Integration with Systemd Tools
Systemd includes auxiliary tools for networking, DNS, time synchronization, and more, creating a unified system management stack:
systemd-networkd: Network configuration (replaceifupdown/NetworkManager).systemd-resolved: DNS resolver with caching and DNSSEC support.systemd-timesyncd: NTP client for time synchronization.systemd-homed: User home directory management (encrypted, portable homes).
Example: Configure Static IP with systemd-networkd
-
Create a network file (
/etc/systemd/network/eth0.network):[Match] Name=eth0 [Network] Address=192.168.1.100/24 Gateway=192.168.1.1 DNS=8.8.8.8 8.8.4.4 -
Enable and restart:
systemctl enable --now systemd-networkd systemd-resolved
Conclusion
Systemd is more than an init system—it’s a comprehensive platform for managing modern Linux systems. By mastering advanced features like socket activation, timer units, resource control, and security hardening, you can build efficient, reliable, and secure systems. Experiment with unit files, leverage journalctl for debugging, and explore systemd’s man pages to unlock its full potential.