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êcherphp-fpmou un de ses fils de pouvoir passerroot. - ProtectSystem=strict: Permet de passer tout
/enread-only.
Il convient ensuite d'utiliserReadWritePathspour 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