Поиск по сайту:

Как повысить безопасность сервисов systemd


В настоящее время все основные дистрибутивы Linux используют Systemd в качестве менеджера системы/сервисов инициализации. Для создания службы systemd достаточно написать модуль «.service» в соответствующем каталоге и управлять им с помощью утилиты systemctl. При запуске службы или процесса в целом мы хотим убедиться, что он работает с минимально возможным набором привилегий, необходимых для выполнения задачи. Systemd предоставляет ряд опций, которые мы можем использовать для точной настройки поведения службы, детального предоставления или отказа в привилегиях и обеспечения определенного уровня изоляции от остальной системы.

В этой статье мы увидим, как повысить безопасность службы systemd и как получить оценку уровня ее уязвимости с помощью утилиты systemd-analyze.

В этом уроке вы узнаете:

  • Как повысить безопасность службы systemd
  • Как получить предполагаемый уровень воздействия сервиса с помощью systemd-analyze

Тестовый пример: написание службы резервного копирования

В предыдущем уроке мы говорили о Restic, эффективной программе резервного копирования с дедупликацией, написанной на Go. Для этой статьи давайте представим, что мы хотим написать «restic»-сервис для планирования резервного копирования через системный таймер. Начнем с написания раздела «Unit»:

[Unit] 
Description=restic backup
Wants=network-online.target
After=network-online.target

Первым делом мы предоставили описание услуги, используя опцию Description. Поскольку мы хотим иметь возможность использовать удаленные репозитории для наших резервных копий, используя параметры Wants и After, мы соответственно объявили (слабую) зависимость службы от network-online.target и установлен, его необходимо запускать только после достижения указанной цели и настройки сетевых интерфейсов.

Теперь давайте заполним раздел «Сервис» устройства. Здесь мы определяем поведение нашего сервиса:

[Service]
Type=oneshot
User=restic
ExecStart=/usr/local/bin/restic_backup.sh

Мы использовали опцию «Тип», чтобы определить наш сервис как «oneshot». Это влияет на то, как systemd обрабатывает службу: она будет считать ее «активной» только после завершения основного процесса.

По очевидным соображениям безопасности мы хотим избежать запуска службы от имени пользователя root, поэтому мы создали непривилегированного пользователя «restic» и с помощью опции User указали, что процесс должен запускаться с его привилегиями. Наконец, с помощью опции ExecStart мы определили команду/исполняемый файл, который должен вызываться при запуске службы; в данном случае это сценарий /usr/local/bin/restic_backup.sh, который содержит основную логику резервного копирования.

В разделе «Сервис» блока мы можем использовать несколько других опций для дальнейшей настройки привилегий нашего сервиса. Давайте посмотрим на некоторые из них.

Запуск процесса с возможностями

Наш сервис будет работать с привилегиями пользователя «restic». Это хорошая мера безопасности, однако мы должны убедиться, что Restic может читать всю файловую систему. Чтобы достичь нашей цели, мы можем гарантировать, что процесс работает с соответствующими возможностями:

AmbientCapabilities=CAP_DAC_READ_SEARCH
CapabilityBoundingSet=CAP_DAC_READ_SEARCH

Параметр AmbientCapabilities принимает в качестве значения список возможностей, разделенных запятыми, которые мы хотим включить в набор внешних возможностей процесса. В данном случае мы просто использовали возможность «CAP_DAC_READ_SEARCH», которая позволяет обходить проверки разрешений на чтение файлов и каталогов. В качестве меры безопасности мы также использовали параметр CapabilityBoundingSet, чтобы ограничить набор возможностей, которые процессу разрешено получить.

Усиление сервиса

Два варианта, связанных с возможностями, которые мы использовали выше, являются лишь небольшим подмножеством тех, которые мы можем использовать для «изолирования» службы. Большинство из них принимают логическое значение. Давайте посмотрим несколько примеров.

ПриватТмп

Опция «PrivateTmp» защищает временные файлы, созданные службой, чтобы другие процессы не могли получить к ним доступ. Когда эта опция активна, systemd создает изолированные каталоги /tmp и /var/tmp и монтирует их в частном пространстве имен.

ProtectKernelModules, ProtectKernelLogs и ProtectKernelTunables

Эти параметры защищают состояние ядра. Активный элемент ProtectKernelModules запрещает службе возможность загружать и выгружать модули ядра, а ProtectKernelLogs запрещает доступ к буферу журнала ядра. Поведение определенных модулей ядра можно изменить, записав соответствующие значения в файлы, представленные в псевдофайловых системах /proc и /sys; опция ProtectKernelTunables, если она активна, запрещает такие действия.

НетНовыеПривилегии

Эту опцию можно использовать, чтобы гарантировать, что служба и ее дочерние процессы не смогут получить новые привилегии путем выполнения других программ с помощью системного вызова execve, который является частью стандартной библиотеки C. Когда эта опция активна, она запрещает выполнение двоичных файлов с установленными битами SETUID или SETGID.

ОграничитьSUIDSGID

Если этот параметр имеет значение true, он не позволяет процессу, вызываемому службой, устанавливать биты SETUID или SETGID в файлах и каталогах.

Ограничить адрессемейства

Эта опция принимает разделенный пробелами список имен семейств адресов, к которым процесс может получить доступ (например: AF_UNIX, AF_INET, AF_INET6); «none» также является допустимым значением: оно запрещает доступ ко всем из них.

Частные устройства

Когда эта опция активна, процессу запрещается доступ к необработанным устройствам, таким как /dev/sda или /dev/mem.

Защитить часы

Если установлено значение true, доступ к системным часам запрещен.

Защитить имя хоста

Эта опция защищает имя хоста системы, гарантируя, что процесс не сможет его изменить.

УдалитьIPC

Когда он активен, он вызывает автоматическое удаление ресурсов IPC (межпроцессного взаимодействия), выделенных службе.

ПриватМаунтс

Когда эта опция активна, процесс выполняется в собственной частной и изолированной файловой системе, недоступной с хоста.

Получение примерного уровня безопасности сервиса

Вот как в итоге выглядит наш сервис:

[Unit] 
Description=restic backup
Wants=network-online.target
After=network-online.target

[Service]
Type=oneshot
User=restic
ExecStart=/usr/local/bin/restic_backup.sh
AmbientCapabilities=CAP_DAC_READ_SEARCH
CapabilityBoundingSet=CAP_DAC_READ_SEARCH
PrivateTmp=yes
ProtectKernelModules=yes
ProtectKernelLogs=yes
ProtectKernelTunables=yes
NoNewPrivileges=yes
RestrictSUIDSGID=yes
RestrictAddressFamilies=yes
PrivateDevices=yes
ProtectClock=yes
ProtectHostname=yes
RemoveIPC=yes
PrivateMounts=yes

Как только мы поместим модуль в один из каталогов, распознаваемых systemd (например, /etc/systemd/system), чтобы получить его предполагаемый уровень безопасности, нам просто нужно запустить «systemd-analyze» с командой «security», передав имя устройства в качестве аргумента. Предположим, мы сохранили модуль как «restic.service», и запустим:

$ systemd-analyze security restic.service

Команда возвращает список доступных опций безопасности с указанием присутствующих и отсутствующих в устройстве, а также общий уровень воздействия: чем он ниже, тем лучше. Каждая неиспользованная опция увеличивает значение риска на сумму, указанную в столбце «ЭКСПОЗИЦИЯ». Вот результат, который мы получаем, выполнив команду для нашего сервисного модуля:

  NAME                                                        DESCRIPTION                                                        EXPOSURE
 RemoveIPC=                                                  Service user cannot leave SysV IPC objects around                          
 RootDirectory=/RootImage=                                   Service runs within the host's root directory                           0.1
 User=/DynamicUser=                                          Service runs under a static non-root user identity                         
 CapabilityBoundingSet=~CAP_SYS_TIME                         Service processes cannot change the system clock                           
 NoNewPrivileges=                                            Service processes cannot acquire new privileges                            
 AmbientCapabilities=                                        Service process receives ambient capabilities                           0.1
 CapabilityBoundingSet=~CAP_(DAC_*|FOWNER|IPC_OWNER)         Service may override UNIX file/IPC permission checks                    0.2
 ProtectControlGroups=                                       Service may modify the control group file system                        0.2
 CapabilityBoundingSet=~CAP_BPF                              Service may load BPF programs                                              
 SystemCallArchitectures=                                    Service may execute system calls with all ABIs                          0.2
 MemoryDenyWriteExecute=                                     Service may create writable executable memory mappings                  0.1
 RestrictNamespaces=~user                                    Service may create user namespaces                                      0.3
 RestrictNamespaces=~pid                                     Service may create process namespaces                                   0.1
 RestrictNamespaces=~net                                     Service may create network namespaces                                   0.1
 RestrictNamespaces=~uts                                     Service may create hostname namespaces                                  0.1
 RestrictNamespaces=~mnt                                     Service may create file system namespaces                               0.1
 RestrictNamespaces=~cgroup                                  Service may create cgroup namespaces                                    0.1
 RestrictNamespaces=~ipc                                     Service may create IPC namespaces                                       0.1
 LockPersonality=                                            Service may change ABI personality                                      0.1
 RestrictRealtime=                                           Service may acquire realtime scheduling                                 0.1
 SupplementaryGroups=                                        Service has no supplementary groups                                        
 CapabilityBoundingSet=~CAP_SYS_RAWIO                        Service has no raw I/O access                                              
 CapabilityBoundingSet=~CAP_SYS_PTRACE                       Service has no ptrace() debugging abilities                                
 CapabilityBoundingSet=~CAP_SYS_(NICE|RESOURCE)              Service has no privileges to change resource use parameters                
 CapabilityBoundingSet=~CAP_NET_ADMIN                        Service has no network configuration privileges                            
 CapabilityBoundingSet=~CAP_NET_(BIND_SERVICE|BROADCAST|RAW) Service has no elevated networking privileges                              
 CapabilityBoundingSet=~CAP_AUDIT_*                          Service has no audit subsystem access                                      
 CapabilityBoundingSet=~CAP_SYS_ADMIN                        Service has no administrator privileges                                    
 PrivateTmp=                                                 Service has no access to other software's temporary files                  
 CapabilityBoundingSet=~CAP_SYSLOG                           Service has no access to kernel logging                                    
 PrivateDevices=                                             Service has no access to hardware devices                                  
 ProtectSystem=                                              Service has full access to the OS file hierarchy                        0.2
 ProtectProc=                                                Service has full access to process tree (/proc hidepid=)                0.2
 ProcSubset=                                                 Service has full access to non-process /proc files (/proc subset=)      0.1
 ProtectHome=                                                Service has full access to home directories                             0.2
 PrivateNetwork=                                             Service has access to the host's network                                0.5
 PrivateUsers=                                               Service has access to other users                                       0.2
 DeviceAllow=                                                Service has a device ACL with some special devices: char-rtc:r          0.1
 KeyringMode=                                                Service doesn't share key material with other services                     
 Delegate=                                                   Service does not maintain its own delegated control group subtree          
 SystemCallFilter=~@clock                                    Service does not filter system calls                                    0.2
 SystemCallFilter=~@cpu-emulation                            Service does not filter system calls                                    0.1
 SystemCallFilter=~@debug                                    Service does not filter system calls                                    0.2
 SystemCallFilter=~@module                                   Service does not filter system calls                                    0.2
 SystemCallFilter=~@mount                                    Service does not filter system calls                                    0.2
 SystemCallFilter=~@obsolete                                 Service does not filter system calls                                    0.1
 SystemCallFilter=~@privileged                               Service does not filter system calls                                    0.2
 SystemCallFilter=~@raw-io                                   Service does not filter system calls                                    0.2
 SystemCallFilter=~@reboot                                   Service does not filter system calls                                    0.2
 SystemCallFilter=~@resources                                Service does not filter system calls                                    0.2
 SystemCallFilter=~@swap                                     Service does not filter system calls                                    0.2
 IPAddressDeny=                                              Service does not define an IP address allow list                        0.2
 NotifyAccess=                                               Service child processes cannot alter service state                         
 ProtectClock=                                               Service cannot write to the hardware clock or system clock                 
 CapabilityBoundingSet=~CAP_SYS_PACCT                        Service cannot use acct()                                                  
 CapabilityBoundingSet=~CAP_KILL                             Service cannot send UNIX signals to arbitrary processes                    
 ProtectKernelLogs=                                          Service cannot read from or write to the kernel log ring buffer            
 CapabilityBoundingSet=~CAP_WAKE_ALARM                       Service cannot program timers that wake up the system                      
 CapabilityBoundingSet=~CAP_LINUX_IMMUTABLE                  Service cannot mark files immutable                                        
 CapabilityBoundingSet=~CAP_IPC_LOCK                         Service cannot lock memory into RAM                                        
 ProtectKernelModules=                                       Service cannot load or read kernel modules                                 
 CapabilityBoundingSet=~CAP_SYS_MODULE                       Service cannot load kernel modules                                         
 CapabilityBoundingSet=~CAP_SYS_TTY_CONFIG                   Service cannot issue vhangup()                                             
 CapabilityBoundingSet=~CAP_SYS_BOOT                         Service cannot issue reboot()                                              
 CapabilityBoundingSet=~CAP_SYS_CHROOT                       Service cannot issue chroot()                                              
 PrivateMounts=                                              Service cannot install system mounts                                       
 CapabilityBoundingSet=~CAP_BLOCK_SUSPEND                    Service cannot establish wake locks                                        
 CapabilityBoundingSet=~CAP_LEASE                            Service cannot create file leases                                          
 CapabilityBoundingSet=~CAP_MKNOD                            Service cannot create device nodes                                         
 ProtectHostname=                                            Service cannot change system host/domainname                               
 CapabilityBoundingSet=~CAP_(CHOWN|FSETID|SETFCAP)           Service cannot change file ownership/access mode/capabilities              
 CapabilityBoundingSet=~CAP_SET(UID|GID|PCAP)                Service cannot change UID/GID identities/capabilities                      
 ProtectKernelTunables=                                      Service cannot alter kernel tunables (/proc/sys, …)                        
 RestrictAddressFamilies=~AF_PACKET                          Service cannot allocate packet sockets                                     
 RestrictAddressFamilies=~AF_NETLINK                         Service cannot allocate netlink sockets                                    
 RestrictAddressFamilies=~AF_UNIX                            Service cannot allocate local sockets                                      
 RestrictAddressFamilies=~…                                  Service cannot allocate exotic sockets                                     
 RestrictAddressFamilies=~AF_(INET|INET6)                    Service cannot allocate Internet sockets                                   
 CapabilityBoundingSet=~CAP_MAC_*                            Service cannot adjust SMACK MAC                                            
 RestrictSUIDSGID=                                           SUID/SGID file creation by service is restricted                           
 UMask=                                                      Files created by service are world-readable by default                  0.1

→ Overall exposure level for restic.service: 4.6 OK 🙂

Наша оценка – «4,6»: неплохо, но мы еще можем ее улучшить!

Выводы

В этом уроке мы узнали, как повысить уровень безопасности службы, используя некоторые параметры Systemd. Мы также узнали, как использовать утилиту systemd-analyze для проверки уровня уязвимости службы. По понятным причинам мы не рассмотрели здесь все доступные варианты усиления защиты; Чтобы получить полный список и узнать больше по этой теме, просмотрите онлайн-документацию или просто проверьте справочную страницу «systemd.exec».

Статьи по данной тематике: