Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

systemctl

systemctl est le programme principal de gestion de systemd.

Nous n'allons globalement nous interesser qu'à la partie gestion de services.
Il ne s'agit pas ici d'apprendre les bases, mais d'aller un peu plus loin.

Hardening

systemd-analyze security

Cette commande permet d'obtenir un score pour chaque service.
L'idéal est de connaitre les besoins du service, et d'interdire tout accès qui ne correspond pas aux besoins.

Il ne s'agit pas de restreindre le fonctionnement normal de l'application, mais bien d'encadrer son exploitation ou un bug.

Configurations

L'intérêt est donc pour chaque service que l'on déploie, d'ajouter un override (par exemple via systemctl edit) qui va ajouter des restrictions.

Exemples:

  • PrivateTmp=yes: Créé un namespace pour que les accès du service dans /tmp/ soient isolés dans un dossier temporaire.
  • NoNewPrivileges=true: Permet d'empêcher le service d'obtenir de nouveaux privilèges.
    Par exemple pour empêcher php-fpm ou un de ses fils de pouvoir passer root.
  • ProtectSystem=strict: Permet de passer tout / en read-only.
    Il convient ensuite d'utiliser ReadWritePaths pour autoriser les écritures dans certains dossiers.
  • InaccessiblePaths: Permet de rendre certains dossiers inaccessibles, y compris en lecture.

Exemples de service

Ces fichiers de configuration ont étés testés sur Debian.
Ils ne sont pas parfaits, et doivent être adaptés à vos usages.

Redis

Cette configuration permet d'obtenir un score de 2.5 sur systemd-analyze security.
Il force l'utilisation des sockets unix (dans /var/run/redis/) pour la connexion, au lieu de sockets tcp.

redis.conf:

[Service]
PrivateTmp=true
NoNewPrivileges=true
PrivateDevices=true
DevicePolicy=closed
ProtectSystem=strict
ProtectHome=true
ProtectControlGroups=true
ProtectKernelModules=true
ProtectKernelTunables=true
ProtectProc=invisible
RestrictNamespaces=true
RestrictRealtime=true
RestrictSUIDSGID=true
MemoryDenyWriteExecute=true
LockPersonality=true
ProtectClock=true
ProtectHostname=true
ProtectKernelLogs=true
PrivateUsers=true
RemoveIPC=true
CapabilityBoundingSet=~CAP_LINUX_IMMUTABLE CAP_IPC_LOCK CAP_SYS_CHROOT CAP_BLOCK_SUSPEND CAP_LEASE
ReadOnlyPaths=/
NoExecPaths=/
ExecPaths=-/usr/bin/redis-server
ExecPaths=-/usr/lib
ExecPaths=-/lib
ReadWritePaths=-/var/run/redis
ReadWritePaths=-/run/redis
ReadWritePaths=-/var/log/redis
ReadWritePaths=-/var/lib/redis
RestrictAddressFamilies=AF_UNIX
UMask=007
LimitNOFILE=65535
SystemCallArchitectures=native
SystemCallFilter=@system-service
SystemCallFilter=~ @privileged @resources

MariaDB

Cette configuration permet d'obtenir un score de 4.5 sur systemd-analyze security.

mariadb.conf:

[Service]
PrivateTmp=true
NoNewPrivileges=true
PrivateDevices=true
DevicePolicy=closed
ProtectSystem=strict
ProtectHome=true
ProtectControlGroups=true
ProtectKernelModules=true
ProtectKernelTunables=true
ProtectProc=invisible
RestrictNamespaces=true
RestrictRealtime=true
RestrictSUIDSGID=true
MemoryDenyWriteExecute=true
LockPersonality=true
ProtectClock=true
ProtectHostname=true
ProtectKernelLogs=true
PrivateUsers=true
RemoveIPC=true
CapabilityBoundingSet=~CAP_LINUX_IMMUTABLE CAP_IPC_LOCK CAP_SYS_CHROOT CAP_BLOCK_SUSPEND CAP_LEASE
ReadOnlyPaths=/
NoExecPaths=/
ExecPaths=-/usr/sbin/mariadbd
ExecPaths=-/usr/lib
ExecPaths=-/lib
ReadWritePaths=-/var/run/mysqld
ReadWritePaths=-/run/mysqld
ReadWritePaths=-/var/lib/mysql/
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
UMask=007
LimitNOFILE=65535
SystemCallArchitectures=native

PHP-FPM

Cette configuration permet d'obtenir un score de 4.6 sur systemd-analyze security.

php-fpm.conf:

[Service]
PrivateTmp=true
NoNewPrivileges=true
PrivateDevices=true
DevicePolicy=closed

# This option will make any JIT techniques to fail.
MemoryDenyWriteExecute=true

LockPersonality=true
UMask=007
LimitNOFILE=65535

RestrictNamespaces=~mnt
RestrictRealtime=true
RestrictSUIDSGID=true
RestrictAddressFamilies=AF_UNIX AF_NETLINK AF_INET AF_INET6

ProtectSystem=strict
ProtectControlGroups=true
ProtectKernelModules=true
ProtectKernelTunables=true
ProtectProc=invisible
ProtectClock=true
ProtectHostname=true
ProtectKernelLogs=true

SystemCallArchitectures=native
SystemCallErrorNumber=EPERM
SystemCallFilter=~@mount
SystemCallFilter=~@clock
SystemCallFilter=~@cpu-emulation
SystemCallFilter=~@module
SystemCallFilter=~@obsolete
SystemCallFilter=~@debug
SystemCallFilter=~@reboot

CapabilityBoundingSet=~CAP_SYS_PTRACE
CapabilityBoundingSet=~CAP_SYS_ADMIN
CapabilityBoundingSet=~CAP_MAC_*
CapabilityBoundingSet=~CAP_LINUX_IMMUTABLE
CapabilityBoundingSet=~CAP_SYS_BOOT
CapabilityBoundingSet=~CAP_SYS_CHROOT
CapabilityBoundingSet=~CAP_BLOCK_SUSPEND
CapabilityBoundingSet=~CAP_NET_ADMIN

ReadOnlyPaths=/

ReadWritePaths=-/var/log/alternatives.log
ReadWritePaths=-/var/lock
ReadWritePaths=-/run/php
ReadWritePaths=-/etc/alternatives
ReadWritePaths=-/var/lib/dpkg/alternatives
ReadWritePaths=-/var/log/php8.4-fpm.log
ReadWritePaths=-/var/www/html

NoExecPaths=/
ExecPaths=-/usr/sbin
ExecPaths=-/bin
ExecPaths=-/usr/bin
ExecPaths=-/usr/lib
ExecPaths=-/lib

InaccessiblePaths=-/boot
InaccessiblePaths=-/lost+found
InaccessiblePaths=-/etc/default
InaccessiblePaths=-/etc/apache2
InaccessiblePaths=-/etc/apt
InaccessiblePaths=-/etc/shadow
InaccessiblePaths=-/etc/sudoers
InaccessiblePaths=-/etc/sysctl.conf
InaccessiblePaths=-/etc/sysctl.d
InaccessiblePaths=-/var/backups
InaccessiblePaths=-/var/mail
InaccessiblePaths=-/var/spool
InaccessiblePaths=-/var/local
InaccessiblePaths=-/var/cache
InaccessiblePaths=-/var/opt

Apache2

Cette configuration permet d'obtenir un score de 4.9 sur systemd-analyze security.

apache2.conf:

[Service]
PrivateTmp=true
NoNewPrivileges=true
PrivateDevices=true
DevicePolicy=closed
ProtectSystem=strict
ProtectControlGroups=true
ProtectKernelModules=true
ProtectKernelTunables=true
ProtectProc=invisible
RestrictNamespaces=true
RestrictRealtime=true
RestrictSUIDSGID=true
MemoryDenyWriteExecute=true
LockPersonality=true
ProtectClock=true
ProtectHostname=true
ProtectKernelLogs=true
ReadOnlyPaths=/
NoExecPaths=/
ExecPaths=-/usr/sbin
ExecPaths=-/bin
ExecPaths=-/usr/bin
ExecPaths=-/usr/local/bin
ExecPaths=-/usr/lib
ExecPaths=-/lib
ExecPaths=-/usr/lib/apache2/modules/
ReadWritePaths=-/var/log/apache2
ReadWritePaths=-/var/cache/apache2
ReadWritePaths=-/var/lib/apache2
ReadWritePaths=-/var/lock
ReadWritePaths=-/run/apache2
RestrictAddressFamilies=AF_UNIX AF_NETLINK AF_INET AF_INET6
UMask=007
LimitNOFILE=65535
SystemCallArchitectures=native
CapabilityBoundingSet=~CAP_SYS_PTRACE

Sources