systemd configuration¶
Even if systemd works well with the default configuration, it needs to be configured on some system so that logs don’t fill the disk, …
Logging: syslog and journald¶
On most of my systems I’m using syslog-ng to manage my log files. This
interfaces quite well with journald as the only thing you need to do to make it
work is to use these sources in /etc/syslog-ng/syslog-ng.conf
:
source src {
unix-dgram("/run/systemd/journal/syslog");
internal();
file("/proc/kmsg");
};
Once this is done, you no longer need persistent storage to /var/log/journal.
Instead of deleting this directory or making it a tmpfs, the right way to
disable persistent storage is to set this into /etc/systemd/journald.conf
:
Storage=volatile
ForwardToSyslog=yes
ForwardToKMsg=no
ForwardToConsole=no
More information can be found in the man page: http://www.freedesktop.org/software/systemd/man/journald.conf.html
If you use persistent storage, you may want to rotate logs every 3 months for
example. This option in /etc/systemd/journald.conf
tells journald to do
this:
MaxRetentionSec=3month
Logging: audit logs and journald¶
journald can listen to the audit socket for events. Even if that could be
useful without auditd
service, it can spam the logs when using software
such as Chrome (https://bugs.chromium.org/p/chromium/issues/detail?id=456535
has been opened for more than a year) and it does not honour auditctl
configuration such as:
auditctl -a never,exit -F arch=b64 -S set_robust_list -F path=/usr/lib/chromium/chromium -F key=bug456535
(This line without auditctl
can be put in
/etc/audit/rules.d/chromium.rules
so that augenrules --load
loads this
at every boot).
To disable this journald feature, the easier way consists in masking the audit socket (cf. https://github.com/systemd/systemd/issues/959#issuecomment-174541674):
systemctl mask systemd-journald-audit.socket
Write journal on tty¶
On a workstation, it can be quite convenient to read the journal directly from ttys above 7 (tty1-6 being consoles and tty7 the X Window session, for example).
With syslog-ng, the configuration is quite straightforward:
source src { system(); };
destination d_tty9 { file("/dev/tty9" owner(-1) group(-1) perm(-1)); };
destination d_tty10 { file("/dev/tty10" owner(-1) group(-1) perm(-1)); };
destination d_tty11 { file("/dev/tty11" owner(-1) group(-1) perm(-1)); };
destination console_all { file("/dev/tty12" owner(-1) group(-1) perm(-1)); };
filter f_authpriv { facility(auth, authpriv); };
filter f_daemon { facility(daemon); };
filter f_kernel { facility(kern); };
log { source(src); filter(f_authpriv); destination(d_tty9); };
log { source(src); filter(f_daemon); destination(d_tty10); };
log { source(src); filter(f_kernel); destination(d_tty11); };
log { source(src); destination(console_all); };
It is also possible to send emergency messages to everyone logged in:
source s_src {
system();
internal();
};
destination du_all { usertty("*"); };
filter f_emerg { level(emerg); };
log { source(s_src); filter(f_emerg); destination(du_all); };
With journald, the only “natively” available feature is logging to a tty, with
something like this in /etc/systemd/journald.conf
:
ForwardToConsole=yes
TTYPath=/dev/tty12
MaxLevelConsole=info
The other filters can be implemented with services. Here are some files.
/etc/systemd/system/journal@.service
:
[Unit]
Description=Show journal on %I
After=systemd-journald.service
ConditionPathExists=/dev/%I
[Service]
Type=idle
StandardOutput=tty
TTYPath=/dev/%I
TTYReset=yes
TTYVHangup=yes
[Install]
WantedBy=multi-user.target
/etc/systemd/system/journal@tty9.service
:
.include /etc/systemd/system/journal@.service
[Unit]
Description=Show journal on %I (auth)
[Service]
# Facilities: 4 = LOG_AUTH, 10 = LOG_AUTHPRIV
ExecStart=/usr/bin/journalctl -b -n50 SYSLOG_FACILITY=4 SYSLOG_FACILITY=10
/etc/systemd/system/journal@tty10.service
:
.include /etc/systemd/system/journal@.service
[Unit]
Description=Show journal on %I (daemon)
[Service]
# Facility codes:
# 2 = LOG_MAIL
# 3 = LOG_DAEMON
# 5 = LOG_SYSLOG
# 6 = LOG_LPR
# 7 = LOG_NEWS
# 8 = LOG_UUCP
# 9 = LOG_CRON
# 11 = LOG_FTP
#
# Not selected:
# 0 = LOG_KERN
# 1 = LOG_USER
# 4 = LOG_AUTH
# 10 = LOG_AUTHPRIV
# 16..23 = LOG_LOCAL0..7
#
# Source: /usr/include/sys/syslog.h
# in glibc: https://sourceware.org/git/?p=glibc.git;a=blob;f=misc/sys/syslog.h;hb=HEAD
ExecStart=/usr/bin/journalctl -b -n50 \
SYSLOG_FACILITY=2 SYSLOG_FACILITY=3 SYSLOG_FACILITY=5 SYSLOG_FACILITY=6 \
SYSLOG_FACILITY=7 SYSLOG_FACILITY=8 SYSLOG_FACILITY=9 SYSLOG_FACILITY=11
/etc/systemd/system/journal@tty11.service
:
.include /etc/systemd/system/journal@.service
[Unit]
Description=Show journal on %I (kernel)
[Service]
# --dmesg implies -b and _TRANSPORT=kernel
ExecStart=/usr/bin/journalctl -b -f -n 50 --dmesg
``/etc/systemd/system/journal@tty12.service``::
.include /etc/systemd/system/journal@.service
[Unit]
Description=Show journal on %I (everything)
[Service]
ExecStart=/usr/bin/journalctl -b -f -n 50
With such commands, it is also possible to pipe journalctl
output to
ccze
(if installed) to colorize the logs.
Configure timers (and remove cron)¶
systemd doesn’t rely on a cron daemon to run periodic tasks but uses its own system with calendar time events. ArchLinux provides on its wiki some config files to replace common cron scripts: https://wiki.archlinux.org/index.php/Systemd/cron_functionality
Since April 2014 the timers are included and enabled by default, with timer
files in /usr/lib/systemd/system
and symlinks in
/usr/lib/systemd/system/multi-user.target.wants/
. To disable some timers
which do many disk writes, an overriding unit needs to be created.
/etc/systemd/system/disabled-timer.service
:
[Unit]
Description=Unit to be able to disable timers
[Service]
Type=oneshot
ExecStart=/usr/bin/true
/etc/systemd/system/updatedb.timer
:
[Unit]
Description=Disabled locate database update
[Timer]
#OnCalendar=daily
#Persistent=true
#OnBootSec=10min
#OnUnitActiveSec=1d
OnCalendar=monthly
Unit=disabled-timer.service
Another way may consist in masking the service units, but it did not work well back in spring 2014:
$ systemctl mask updatedb
Created symlink from /etc/systemd/system/updatedb.service to /dev/null.
Automatically create a bridge interface¶
To automatically create a bridge interface which can be used for example to bridge together several virtual machines, here is a systemd-networkd configuration.
/etc/systemd/network/VMBridge.netdev
:
[NetDev]
Name=br0
Kind=bridge
/etc/systemd/network/br0.network
:
[Match]
Name=br0
[Network]
IPForward=yes
[Address]
Address=198.51.100.0/24