Journald configuration - journald.conf
Introduction
The journald.conf
file is the main configuration file for the system journal journald. It defines all aspects of system journal operation - from how logs are stored, through their rotation, to compression and size limits.
Configuration file location
Journald configuration is located in several possible locations, which are checked in the following order:
/etc/systemd/journald.conf.d/*.conf
- configuration fragments in directory/etc/systemd/journald.conf
- main configuration file/usr/local/lib/systemd/journald.conf.d/*.conf
- local configuration fragments/usr/lib/systemd/journald.conf.d/*.conf
- system configuration fragments/etc/systemd/journald@NAMESPACE.conf
- configuration for specific namespace/etc/systemd/journald@NAMESPACE.conf.d/*.conf
- configuration fragments for namespace/usr/local/lib/systemd/journald@NAMESPACE.conf.d/*.conf
- local fragments for namespace/usr/lib/systemd/journald@NAMESPACE.conf.d/*.conf
- system fragments for namespace
Traditionally, I recommend creating your own configuration files in the /etc/systemd/journald.conf.d/
directory with .conf
extension, instead of directly modifying the main configuration file.
Configuration file format
The journald.conf
file uses the standard configuration file format used by systemd:
All configuration options are in the [Journal]
section.
Available configuration options
Below I present most of the available configuration options in the latest version of journald:
Data storage options
Storage=
Specifies how journal messages are stored:
volatile
- store only in memory (in/run/log/journal/
)persistent
- store on disk (in/var/log/journal/
)auto
- store on disk if/var/log/journal/
directory exists, otherwise in memory (default)none
- no storage, all messages are discarded
Compress=
Specifies whether stored data should be compressed to save space:
yes
- enables compression (default)no
- disables compression
CompressionLevel=
Compression level from 1 (lowest, fastest) to 9 (highest, slowest), or from -1 (default) to 0 (none):
Seal=
Specifies whether journal files should be cryptographically sealed:
yes
- enables sealing (default if cryptographic tools are available)no
- disables sealing
How does it work?
When Seal=yes, systemd uses public key cryptography (FSS - Forward Secure Sealing) to:
- sign logs - each journal entry is authenticated
- protect against changes - if someone modifies the log file, the system will detect tampering
- ensure time integrity - logs are protected against backdating
SplitMode=
Specifies how to split journal files:
uid
- creates separate files for each userlogin
- creates separate files for each login sessionnone
- stores all logs in one file (default)
Journal Ssze limiting options
SystemMaxUse=, SystemKeepFree=
Specify maximum disk space for system (global) journals and amount of free space that should remain available:
SystemMaxFileSize=
Maximum size of a single system journal file:
SystemMaxFiles=
Maximum number of system journal files:
RuntimeMaxUse=, RuntimeKeepFree=
Specify maximum memory space (/run
) for journals and amount of free space that should remain available:
RuntimeMaxFileSize=
Maximum size of a single journal file in memory:
RuntimeMaxFiles=
Maximum number of journal files in memory:
MaxFileSec=
Maximum time messages are stored in a single journal file before rotation begins:
MaxRetentionSec=
Maximum time to keep journal messages (regardless of other limits):
Access control and forwarding policy options
ForwardToSyslog=, ForwardToKMsg=, ForwardToConsole=, ForwardToWall=
Options specifying whether the journal should forward messages to other logging systems:
ForwardToSyslog=yes # Forward to traditional syslog
ForwardToKMsg=no # Forward to kernel kmsg buffer
ForwardToConsole=no # Forward to console
ForwardToWall=yes # Forward to all logged in users (wall)
MaxLevelStore=, MaxLevelSyslog=, MaxLevelKMsg=, MaxLevelConsole=, MaxLevelWall=
Specify maximum priority level of messages stored or forwarded to respective systems:
Available levels (from lowest to highest): debug, info, notice, warning, err, crit, alert, emerg
Formatting and identification options
TTYPath=
Path to terminal where journal messages should be sent:
LineMax=
Maximum length of journal message line:
ReadKMsg=
Specifies whether messages from kernel kmsg buffer should be read and stored:
Audit=
Specifies whether kernel audit system should be used:
Network options
SyncIntervalSec=
Specifies how often journal is synchronized to disk:
RateLimitIntervalSec=, RateLimitBurst=
Options limiting number of messages accepted in specified time:
SystemCallArchitectures=
List of allowed system call architectures:
How does it work?
Parameter specifying which system call architectures are allowed for given process/container. native - means process can only execute system calls compatible with system architecture it runs on (e.g. x86_64, ARM64).
Every kernel-level operation (e.g. opening file, creating process) requires system call. Different processor architectures (x86, ARM, RISC-V) have different numbers and ways of calling syscalls.
Limiting to native
If you set SystemCallArchitectures=native, process can only use syscalls of its architecture. Attempt to execute syscall from different architecture (e.g. i386 emulation on x86_64) will be blocked.
For example:
- In systemd (e.g. for services/containers)
[Service] SystemCallArchitectures=native RestrictAddressFamilies=AF_UNIX AF_INET
- blocks system calls from non-native architecture
-
prevents exploits using emulation
-
In Docker/Sandboxes
docker run --security-opt systemcalls=native ...
Container can only execute syscalls compatible with host (e.g. x86_64).
CapabilityBoundingSet=
Specifies set of capability restrictions for journald process:
CapabilityBoundingSet=CAP_SYS_ADMIN CAP_DAC_OVERRIDE CAP_SYS_PTRACE CAP_SYSLOG CAP_AUDIT_CONTROL CAP_AUDIT_READ
MemoryDenyWriteExecute=
Prevents code execution from memory areas marked for writing:
SystemCallFilter=
Filter for system calls that are allowed or forbidden:
RestrictRealtime=
Prevents process from obtaining real-time priorities:
What does this mean?
Prevents process (e.g. system service) from setting real-time scheduling priority for its threads/tasks.
In Linux processes can use scheduling policies:
SCHED_OTHER (default, shared CPU time),
SCHED_FIFO/SCHED_RR (real-time - process has higher priority than even kernel processes).
Why is it important? Security: Process with SCHED_FIFO priority can block entire system if it enters infinite loop (because it has higher priority).
Attackers can use this for DoS (Denial of Service).
Stability: Prevents accidental RT assignment due to software bug.
Config in unit file
[Service] RestrictRealtime=yes
Effect: Service process cannot use sched_setscheduler() to set SCHED_FIFO/SCHED_RR.
How to check process priorities?
ps -eo pid,comm,cls,pri | grep -E 'FF|RR' # shows RT processes
chrt -p
RestrictNamespaces=
Restricts namespaces that can be created:
What does this mean?
Blocks process from creating new namespaces, which are foundation of containerization (Docker, LXC, podman).
Includes these namespaces:
PID (process isolation), NET (network isolation), UTS (hostname isolation), USER (UID/GID isolation),
etc.
Why is it important?
Creating namespaces can be method of container breakout or privilege escalation. E.g. attacker might try to create new PID/USER namespace to bypass restrictions.
Prevents unauthorized containerization: If service doesn't need to create containers, you can block this capability.
Unit config
[Service] RestrictNamespaces=yes
Effect: Calls like unshare(2) or clone(2) with namespace flags (CLONE_NEWPID, CLONE_NEWNET etc.) will be blocked.
Detailed options You can also block only selected namespaces:
RestrictNamespaces=pid net user # blocks only these three
or allow all:
RestrictNamespaces=no
How to check process namespaces?
ls -l /proc/
LockPersonality=
Prevents changing execution personality:
SplitRoundRobin=
Enables rotation mode for journal splitting:
AutoFlush=
Specifies whether data should be automatically written to disk in case of critical errors:
Configuration verification
After making changes to configuration, you can apply and verify them:
Reload configuration
Check service status
Check current settings
Best Practices
- Conscious limit setting - adjust journal size limits to system characteristics
- Using compression - enable compression even at cost of slight CPU load
- Security - enable
Seal=yes
on production servers - Storage - use
Storage=persistent
for important systems - Bandwidth limits - configure
RateLimitIntervalSec
andRateLimitBurst
for DoS protection - Rotation - set appropriate
MaxRetentionSec
andMaxFileSec
values for automatic old journal management
Notes for Latest Versions
Recent versions of journal (2024-2025) added several security-related features such as system call filtering and capability restrictions. These options help reduce potential attack vector.
[Journal]
MemoryDenyWriteExecute=yes
CapabilityBoundingSet=CAP_SYS_ADMIN CAP_DAC_OVERRIDE CAP_SYS_PTRACE CAP_SYSLOG
SystemCallArchitectures=native
SystemCallFilter=~@mount @privileged @setuid
RestrictRealtime=yes
RestrictNamespaces=yes
LockPersonality=yes
These settings strengthen journald process security by limiting its privileges to necessary minimum.
Summary
Journald configuration offers comprehensive capabilities to adapt system journal behavior to various needs - from small systems with limited resources to large production servers. Latest journald versions put special emphasis on security and performance, providing additional configuration options.
Proper configuration of journald allows for effective management of system journals and their monitoring.