Systemd: Difference between revisions

From Lolly's Wiki
Jump to navigationJump to search
No edit summary
No edit summary
Line 1: Line 1:
[[Kategorie:Linux]]
[[Kategorie:Linux]]
=systemd=
Yes, like daemons are usually written this has to be written lowercase.
=What is systemd?=
=What is systemd?=
systemd is a replacement for the old and rusty init system of Linux.
systemd is a replacement for the old and rusty init system of Linux.
Line 6: Line 9:
Maybe it will be as good as SMF (Service Management Facility) of Solaris one day :-).
Maybe it will be as good as SMF (Service Management Facility) of Solaris one day :-).


=systemd=
=Take a look with systemctl=
Yes, like daemons are usually written this has to be written lowercase.
==List units==
 
==Security==
===Use capabilities to drop user privileges (CapabilityBoundingSet)===
<source lang=bash>
# systemctl cat  systemd-networkd.service --no-pager
...
 
[Service]
Type=notify
Restart=on-failure
RestartSec=0
ExecStart=/lib/systemd/systemd-networkd
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_NET_BROADCAST CAP_NET_RAW CAP_SETUID CAP_SETGID CAP_SETPCAP CAP_CHOWN CAP_DAC_OVERRIDE CAP_FOWNER
ProtectSystem=full
ProtectHome=yes
WatchdogSec=1min
 
...
</source>
 
Now the process is started with exactly the capabilities it needs to have. Even if it starts as root all unnessesary capabilities are dropped for starting the process.
 
I dont want to copy the whole man page of [http://manpages.ubuntu.com/manpages/vivid/en/man7/capabilities.7.html capabilities(7)] here but you can take a look to understand what this capabilities are.
 
==Units==
===List units===
As you can see, there are hardware and software related units.
As you can see, there are hardware and software related units.
<source lang=bash>
<source lang=bash>
Line 59: Line 36:
In this example you can see that the anacron.service failed to start.
In this example you can see that the anacron.service failed to start.


===Display unit status===
==Display unit status==
<source lang=bash>
<source lang=bash>
# systemctl status anacron
# systemctl status anacron
Line 78: Line 55:
Ah, deleted the anacron spool directory. ;-)
Ah, deleted the anacron spool directory. ;-)


===Restart units===
==Restart units==
Fix the problem and restart the service.
Fix the problem and restart the service.
<source lang=bash>
<source lang=bash>
Line 100: Line 77:
</source>
</source>


===Display unit declaration===
==Display unit declaration==
<source lang=ini>
<source lang=ini>
# systemctl cat zfs.target
# systemctl cat zfs.target
Line 114: Line 91:
</source>
</source>


===Directories===
====ReadWrite-, ReadOnly- and InaccessibleDirectories====
====Private Tmp-Directories====
Mounts a private incarnation of /tmp and /var/tmp which only lives as long as the unit is up. When the unit comes down the directories are cleared. This is done by a seperate namespace for this unit.
<source lang=ini>
[Unit]
...
PrivateTmp=true|false
...
</source>
If several units should share a private tmp-directory you can use ''JoinsNamespaceOf=<unit1>[,<unit2>,<unit3>]''.
=Service=
=Install=
=Take a look with systemctl=
==Sockets==
==Sockets==
<source lang=bash>
<source lang=bash>
Line 156: Line 116:
</source>
</source>


==Dependencies==
==View dependencies==
What depends on ''zfs.target'':
<source lang=bash>
# systemctl list-dependencies --reverse zfs.target
zfs.target
● ├─basic.target
...
● └─multi-user.target
...
</source>
And what do we need to reach the ''zfs.target''?
<source lang=bash>
# systemctl list-dependencies --recursive zfs.target
zfs.target
● ├─zed.service
● ├─zfs-mount.service
● └─zfs-share.service
</source>
 
 
=Security=
==Use capabilities to drop user privileges (CapabilityBoundingSet)==
<source lang=bash>
# systemctl cat  systemd-networkd.service --no-pager
...
 
[Service]
Type=notify
Restart=on-failure
RestartSec=0
ExecStart=/lib/systemd/systemd-networkd
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_NET_BROADCAST CAP_NET_RAW CAP_SETUID CAP_SETGID CAP_SETPCAP CAP_CHOWN CAP_DAC_OVERRIDE CAP_FOWNER
ProtectSystem=full
ProtectHome=yes
WatchdogSec=1min
 
...
</source>
 
Now the process is started with exactly the capabilities it needs to have. Even if it starts as root all unnessesary capabilities are dropped for starting the process.
 
I dont want to copy the whole man page of [http://manpages.ubuntu.com/manpages/vivid/en/man7/capabilities.7.html capabilities(7)] here but you can take a look to understand what this capabilities are.
 
=Units=
==[Unit]==
===Define dependencies===
===Define dependencies===
For example the ''zfs.target'' is defined like this:
For example the ''zfs.target'' is defined like this:
Line 173: Line 177:
This means to reach the ''zfs.target'' we want that ''zed.service'' is started if enabled and we need ''zfs-mount.service'' and ''zfs-share.service''.
This means to reach the ''zfs.target'' we want that ''zed.service'' is started if enabled and we need ''zfs-mount.service'' and ''zfs-share.service''.


 
===Directories===
===View dependencies===
====ReadWrite-, ReadOnly- and InaccessibleDirectories====
What depends on ''zfs.target'':
====Private Tmp-Directories====
<source lang=bash>
Mounts a private incarnation of /tmp and /var/tmp which only lives as long as the unit is up. When the unit comes down the directories are cleared. This is done by a seperate namespace for this unit.
# systemctl list-dependencies --reverse zfs.target
<source lang=ini>
zfs.target
[Unit]
● ├─basic.target
...
...
● └─multi-user.target
PrivateTmp=true|false
...
...
</source>
</source>
And what do we need to reach the ''zfs.target''?
 
<source lang=bash>
If several units should share a private tmp-directory you can use ''JoinsNamespaceOf=<unit1>[,<unit2>,<unit3>]''.
# systemctl list-dependencies --recursive zfs.target
 
zfs.target
==[Service]==
● ├─zed.service
==[Install]==
● ├─zfs-mount.service
● └─zfs-share.service
</source>


=Tools=
=Tools=

Revision as of 22:41, 2 September 2015

Kategorie:Linux

systemd

Yes, like daemons are usually written this has to be written lowercase.

What is systemd?

systemd is a replacement for the old and rusty init system of Linux. It has many new features and extends the normal init system with the ability to watch processes after the start has done, list sockets owned by processes started with systemd, adds security features like capabilities(7) and a lot more.

Maybe it will be as good as SMF (Service Management Facility) of Solaris one day :-).

Take a look with systemctl

List units

As you can see, there are hardware and software related units.

# systemctl list-units
  UNIT                                                            LOAD   ACTIVE SUB       DESCRIPTION
  proc-sys-fs-binfmt_misc.automount                               loaded active running   Arbitrary Executable File Formats File System Automount Point
  sys-devices-pci0000:00-0000:00:02.0-backlight-acpi_video0.device loaded active plugged   /sys/devices/pci0000:00/0000:00:02.0/backlight/acpi_video0
  sys-devices-pci0000:00-0000:00:02.0-drm-card0-card0\x2dLVDS\x2d1-intel_backlight.device loaded active plugged   /sys/devices/pci0000:00/0000:00:02.0/drm
  sys-devices-pci0000:00-0000:00:19.0-net-eth0.device             loaded active plugged   82579LM Gigabit Network Connection
  sys-devices-pci0000:00-0000:00:1a.0-usb1-1\x2d1-1\x2d1.4-1\x2d1.4:1.0-bluetooth-hci0-rfkill3.device loaded active plugged   /sys/devices/pci0000:00/0000
  sys-devices-pci0000:00-0000:00:1a.0-usb1-1\x2d1-1\x2d1.4-1\x2d1.4:1.0-bluetooth-hci0.device loaded active plugged   /sys/devices/pci0000:00/0000:00:1a.0
  sys-devices-pci0000:00-0000:00:1b.0-sound-card0.device          loaded active plugged   6 Series/C200 Series Chipset Family High Definition Audio Contro
  sys-devices-pci0000:00-0000:00:1c.1-0000:03:00.0-ieee80211-phy0-rfkill2.device loaded active plugged   /sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0
  sys-devices-pci0000:00-0000:00:1c.1-0000:03:00.0-net-wlan0.device loaded active plugged   Centrino Advanced-N 6205 [Taylor Peak] (Centrino Advanced-N 62
  sys-devices-pci0000:00-0000:00:1d.0-usb2-2\x2d1-2\x2d1.4-2\x2d1.4:1.1-tty-ttyACM0.device loaded active plugged   F5521gw
  sys-devices-pci0000:00-0000:00:1d.0-usb2-2\x2d1-2\x2d1.4-2\x2d1.4:1.3-tty-ttyACM1.device loaded active plugged   F5521gw
...
  session-c2.scope                                                loaded active running   Session c2 of user lollypop
  accounts-daemon.service                                         loaded active running   Accounts Service
● anacron.service                                                 loaded failed failed    Run anacron jobs
  apparmor.service                                                loaded active exited    LSB: AppArmor initialization
  apport.service                                                  loaded active exited    LSB: automatic crash report generation
...

In this example you can see that the anacron.service failed to start.

Display unit status

# systemctl status anacron
● anacron.service - Run anacron jobs
   Loaded: loaded (/lib/systemd/system/anacron.service; enabled; vendor preset: enabled)
   Active: failed (Result: exit-code) since Fr 2015-08-28 09:18:13 CEST; 31min ago
  Process: 1591 ExecStart=/usr/sbin/anacron -dsq (code=exited, status=1/FAILURE)
 Main PID: 1591 (code=exited, status=1/FAILURE)

Aug 28 09:18:13 lollybook systemd[1]: Started Run anacron jobs.
Aug 28 09:18:13 lollybook systemd[1]: Starting Run anacron jobs...
Aug 28 09:18:13 lollybook systemd[1]: anacron.service: main process exited, code=exited, status=1/FAILURE
Aug 28 09:18:13 lollybook anacron[1591]: anacron: Can't chdir to /var/spool/anacron: No such file or directory
Aug 28 09:18:13 lollybook systemd[1]: Unit anacron.service entered failed state.
Aug 28 09:18:13 lollybook systemd[1]: anacron.service failed.

Ah, deleted the anacron spool directory. ;-)

Restart units

Fix the problem and restart the service.

root@lollybook:~# mkdir /var/spool/anacron
root@lollybook:~# systemctl restart anacron.service
root@lollybook:~# systemctl status anacron
● anacron.service - Run anacron jobs
   Loaded: loaded (/lib/systemd/system/anacron.service; enabled; vendor preset: enabled)
   Active: active (running) since Fr 2015-08-28 09:53:49 CEST; 4s ago
 Main PID: 5179 (anacron)
   CGroup: /system.slice/anacron.service
           └─5179 /usr/sbin/anacron -dsq

Aug 28 09:53:49 lollybook systemd[1]: Started Run anacron jobs.
Aug 28 09:53:49 lollybook systemd[1]: Starting Run anacron jobs...
Aug 28 09:53:49 lollybook anacron[5179]: Anacron 2.3 started on 2015-08-28
Aug 28 09:53:49 lollybook anacron[5179]: Will run job `cron.daily' in 5 min.
Aug 28 09:53:49 lollybook anacron[5179]: Will run job `cron.weekly' in 10 min.
Aug 28 09:53:49 lollybook anacron[5179]: Will run job `cron.monthly' in 15 min.
Aug 28 09:53:49 lollybook anacron[5179]: Jobs will be executed sequentially

Display unit declaration

# systemctl cat zfs.target
# /lib/systemd/system/zfs.target
[Unit]
Description=ZFS startup target
Requires=zfs-mount.service
Requires=zfs-share.service
Wants=zed.service

[Install]
WantedBy=multi-user.target

Sockets

# systemctl list-sockets --all
LISTEN                          UNIT                            ACTIVATES
/run/acpid.socket               acpid.socket                    acpid.service
/run/systemd/fsckd              systemd-fsckd.socket            systemd-fsckd.service
/run/systemd/initctl/fifo       systemd-initctl.socket          systemd-initctl.service
/run/systemd/journal/dev-log    systemd-journald-dev-log.socket systemd-journald.service
/run/systemd/journal/socket     systemd-journald.socket         systemd-journald.service
/run/systemd/journal/stdout     systemd-journald.socket         systemd-journald.service
/run/systemd/journal/syslog     syslog.socket                   rsyslog.service
/run/systemd/shutdownd          systemd-shutdownd.socket        systemd-shutdownd.service
/run/udev/control               systemd-udevd-control.socket    systemd-udevd.service
/run/uuidd/request              uuidd.socket                    uuidd.service
/var/run/avahi-daemon/socket    avahi-daemon.socket             avahi-daemon.service
/var/run/cups/cups.sock         cups.socket                     cups.service
/var/run/dbus/system_bus_socket dbus.socket                     dbus.service
127.0.0.1:631                   cups.socket                     cups.service
[::1]:631                       cups.socket                     cups.service
audit 1                         systemd-journald-audit.socket   systemd-journald.service
kobject-uevent 1                systemd-udevd-kernel.socket     systemd-udevd.service

17 sockets listed.

View dependencies

What depends on zfs.target:

# systemctl list-dependencies --reverse zfs.target 
zfs.target
● ├─basic.target
...
● └─multi-user.target
...

And what do we need to reach the zfs.target?

# systemctl list-dependencies --recursive zfs.target
zfs.target
● ├─zed.service
● ├─zfs-mount.service
● └─zfs-share.service


Security

Use capabilities to drop user privileges (CapabilityBoundingSet)

# systemctl cat  systemd-networkd.service --no-pager
...

[Service]
Type=notify
Restart=on-failure
RestartSec=0
ExecStart=/lib/systemd/systemd-networkd
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_NET_BROADCAST CAP_NET_RAW CAP_SETUID CAP_SETGID CAP_SETPCAP CAP_CHOWN CAP_DAC_OVERRIDE CAP_FOWNER
ProtectSystem=full
ProtectHome=yes
WatchdogSec=1min

...

Now the process is started with exactly the capabilities it needs to have. Even if it starts as root all unnessesary capabilities are dropped for starting the process.

I dont want to copy the whole man page of capabilities(7) here but you can take a look to understand what this capabilities are.

Units

[Unit]

Define dependencies

For example the zfs.target is defined like this:

# systemctl cat zfs.target
# /lib/systemd/system/zfs.target
[Unit]
Description=ZFS startup target
Requires=zfs-mount.service
Requires=zfs-share.service
Wants=zed.service

[Install]
WantedBy=multi-user.target

This means to reach the zfs.target we want that zed.service is started if enabled and we need zfs-mount.service and zfs-share.service.

Directories

ReadWrite-, ReadOnly- and InaccessibleDirectories

Private Tmp-Directories

Mounts a private incarnation of /tmp and /var/tmp which only lives as long as the unit is up. When the unit comes down the directories are cleared. This is done by a seperate namespace for this unit.

[Unit]
...
PrivateTmp=true|false
...

If several units should share a private tmp-directory you can use JoinsNamespaceOf=<unit1>[,<unit2>,<unit3>].

[Service]

[Install]

Tools

Testing around with capabilities

For example arping:

# getcap /usr/bin/arping
/usr/bin/arping = cap_net_raw+ep

With this capability set we can use this as normal user:

lollypop $ /usr/bin/arping -I wlan0 192.168.178.1
ARPING 192.168.178.1 from 192.168.178.31 wlan0
Unicast reply from 192.168.178.1 [24:65:11:F0:DC:A8]  1.774ms
Unicast reply from 192.168.178.1 [24:65:11:F0:DC:A8]  1.658ms

If we remove this capability it does not work:

# setcap cap_net_raw=-ep /usr/bin/arping
lollypop $ /usr/bin/arping -I wlan0 192.168.178.1
arping: socket: Operation not permitted

Of course it still works as root as root has all capabilities:

root@lollybook:~# /usr/bin/arping -I wlan0 192.168.178.1
ARPING 192.168.178.1 from 192.168.178.31 wlan0
Unicast reply from 192.168.178.1 [24:65:11:F0:DC:A8]  2.052ms
Unicast reply from 192.168.178.1 [24:65:11:F0:DC:A8]  1.852ms
Received 2 response(s)

So we better set this capability again:

# setcap cap_net_raw=+ep /usr/bin/arping