Pull to refresh

Эффективная защита Linux: использование Ansible для соблюдения рекомендаций ФСТЭК России

Level of difficultyMedium
Reading time19 min
Views2.1K

Введение

25 декабря 2022 года Федеральная служба по техническому и экспортному контролю Российской Федерации (ФСТЭК России) выпустила руководство под названием «Рекомендации по безопасной настройке операционных систем Linux».

Сейчас эти рекомендации являются обязательными для государственных информационных систем и критической информационной инфраструктуры (КИИ), работающих на Linux.

Цель упомянутого документа — обеспечить надежную защиту информационных систем, работающих на Linux, от киберугроз. В рекомендациях представлены советы, которые помогут минимизировать риски и уязвимости, присущие операционной системе.

Основные моменты следующие:

  • Создание пользователей с ограниченными правами и использование надёжных паролей для защиты от несанкционированного доступа.

  • Настройка брандмауэра и сетевой конфигурации для защиты системы от внешних угроз.

  • Установка защиты на уровне ядра, что позволит предотвратить атаки на ядро операционной системы.

  • Внедрение дополнительных уровней защиты для приложений и процессов.

Настройка систем под рекомендации регулирующего органа может быть непростой задачей, учитывая быстрое развитие технологий и постоянно меняющиеся угрозы.

Вручную ввод конфигураций может быть утомительным и чреват ошибками, особенно если требуется настроить ОС на 50, 100 или даже 1000 серверах и рабочих станциях.

Для решения этой проблемы мы используем Ansible, популярное и удобное решение для управления конфигурациями. С помощью Ansible можно массово развертывать и применять конфигурации, упрощая соблюдение требований ФСТЭК России и обеспечивая надежность и эффективность инфраструктуры.

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

С Ansible можно легко и быстро развернуть приложения на серверах Linux, настроить их под свои нужды и масштабировать инфраструктуру. А ещё Ansible поддерживает разные платформы и сервисы, так что можно автоматизировать задачи как в локальной, так и в облачной среде.

Готовые плейбуки

В этой статье я расскажу о некоторых плеях, разработанных мной. Мои плейбук предназначен для RHEL подобных систем. Для других систем его необходимо адаптировать.

Если будете что-то менять, попробуйте сначала на тестовой машине или в виртуальной среде, особенно если речь идёт о плейбуках с изменением конфигураций ядра. Это просто напоминание, даже если вы и так это знаете.

Создание пользователя

Плей «1 Create user fstec with root-level privileges» предназначен для инициализации работы плейбука и создания пользователя, от имени которого будут выполняться остальные задачи.

Работать от имени root — не всегда безопасно и удобно. Поэтому создадим нового пользователя с правами root. От его имени и будут работать остальные плейбуки.

Перед началом работы не забудьте заменить «your_user» на имя пользователя, которого хотите создать. Можно использовать уже существующего пользователя.

Листинг плея 1
- name: 1 Create user fstec with root-level privileges
  hosts: all
  become: true
  tasks:
    - name: Add user fstec
      user:
        name: your_user
        shell: /bin/bash
        groups: wheel
        append: yes
    - name: Prompt for password for your user
      pause:
        prompt: "Enter password for your user:"
      register: passwd_input
    - name: Set password for your user
      user:
        name: your_user
        password: "{{ passwd_input.user_input | password_hash('sha512') }}"
        update_password: always
    - name: Copy root's SSH key for your user
      authorized_key:
        user: your_user
        key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
    - name: Add fstec to sudoers
      lineinfile:
        dest: /etc/sudoers
        line: " your_user ALL=(ALL:ALL) ALL"
        validate: 'visudo -cf %s'

Описание:

  1. Создание пользователя «your_user» с оболочкой «/bin/bash» и добавление его в группу «wheel».

  2. Запрос пароля для пользователя «your_user».

  3. Установка пароля для пользователя «your_user» с использованием введенного пароля и хэшированием его в формате SHA-512.

  4. Копирование открытого ключа SSH root пользователя для пользователя «your_user».

  5. Добавление пользователя «your_user» к списку пользователей, имеющих права sudo в файле /etc/sudoers.

Далее каждый плейбук будет отвечать за настройку определенного пункта рекомендаций по безопасной настройке ОС Linux ФСТЭК России, что будет отражено в его названии. Например, плейбук с именем «2.1 Configuring authorization in Linux operating systems» выполняет настройки для рекомендации ФСТЭК России по пункту «2.1. Настройка авторизации в операционных системах Linux»

Автоматизация настройки авторизации в операционных системах Linux

Плей «2.1 Configuring authorization in Linux operating systems» автоматизирует пункт «2.1. Настройка авторизации в операционных системах Linux» (утв. ФСТЭК России 25.12.2022).

Листинг плея 2.1
- name: 2.1 Configuring authorization in Linux operating systems
  hosts: all
  become: true
  remote_user: «your_user»
  gather_facts: false
  tasks:
    - name: 2.1.1. Do not allow the use of user accounts with empty passwords.
        Configure accounts so that each user of the system either has a password or
        is blocked by a password. On Linux systems, this feature is provided by the
        /etc/shadow file.
      lineinfile:
        path: /etc/shadow
        regexp: ^([^:]+):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*)
        line: \1:*:\3:\4:\5:\6:\7
        backrefs: yes
      register: shadow_file
    - name: Check the result of changes
      debug:
        var: shadow_file

    - name: 2.1.2. Ensure that superuser login to the system via SSH is disabled by
        setting the PermitRootLogin parameter to no in the /etc/ssh/sshd_config
        file.
      lineinfile:
        dest: /etc/ssh/sshd_config
        regexp: ^PermitRootLogin
        line: PermitRootLogin no
        state: present
        backup: yes
      notify:
        - restart sshd
  handlers:
    - name: restart sshd
      service:
        name: sshd
        state: restarted

Описание:

  • Запрет на использование учетных записей пользователей с пустыми паролями осуществляется путем изменения файла /etc/shadow – пользователи без пароля будут заблокированы. Результат изменений сохраняется в переменной shadowfile.

  • Запрет подключения по SSH под суперпользователем осуществляется добавлением параметра «PermitRootLogin no» в файл /etc/ssh/sshdconfig. После внесения изменений в файл /etc/ssh/sshdconfig, происходит перезапуск службы sshd с помощью обработчика (handler) restart sshd.

Автоматизация ограничений механизмов получения привилегий

Плей «2.2 Limitation of privilege mechanisms» автоматизирует пункт «2.2. Ограничение механизмов получения привилегий» (утв. ФСТЭК России 25.12.2022).

Листинг плея 2.2
- name: 2.2 Limitation of privilege mechanisms
  hosts: all
  become: true
  remote_user: «your_user»
  vars_prompt:
    - name: "allowed_sudo_users"
      prompt: "Specify a list of users who should be allowed to use the sudo command (separated by commas)"
      private: no
  tasks:
    - name: 2.2.1 Add pam_wheel.so to /etc/pam.d/su
      lineinfile:
        path: /etc/pam.d/su
        line: "auth required pam_wheel.so use_uid"
        insertafter: EOF
    - name: 2.2.1 Get list of users to add to wheel group
      pause:
        prompt: "Please provide the list of users to add to the wheel group"
      register: admin_input
    - name: Add users to wheel group
      lineinfile:
        path: /etc/group
        regexp: '^wheel:'
        line: "wheel:x:10:root,{{ admin_input.wheel_group }}"
      when: wheel_group.stdout is defined
    - name: 2.2.2 Limit the list of users who are allowed to use the sudo command and commands allowed to be executed via sudo by revising the /etc/sudoers file
      lineinfile:
        path: /etc/sudoers
        line: "{{ item }} ALL=(ALL:ALL) ALL"
        state: present
        regexp: "^{{ item }}"
      with_items: "{{ allowed_sudo_users.split(',') }}"
      when: allowed_sudo_users is defined
      changed_when: false
    - name: Prohibit the use of sudo for other users
      lineinfile:
        path: /etc/sudoers
        line: "{{ item }}"
        state: absent
      with_lines: "grep -vE '^{{ allowed_sudo_users }}' /etc/passwd | cut -d: -f1 | sed 's/^/%/g' | sed 's/$/ ALL=(ALL:ALL) ALL/'"
      when: allowed_sudo_users is defined

Описание:

  • Перед выполнением плей запрашивает список пользователей, которым разрешено использовать команду sudo.

  • Добавление pam_wheel.so в файл /etc/pam.d/su для ограничения использования команды su только членам группы wheel.

  • Получение списка пользователей для добавления в группу wheel.

  • Добавление указанных пользователей в группу wheel.

  • Ограничение списка пользователей, которым разрешено использовать команду sudo, и команд, разрешенных для выполнения через sudo, путем изменения файла /etc/sudoers.

  • Запрет использования команды sudo для других пользователей.

Автоматизация настройки прав доступа к объектам файловой системы

Плей «2.3 Setting up access rights to file system objects» закрывает настройки пункта «2.3. Настройка прав доступа к объектам файловой системы» (утв. ФСТЭК России 25.12.2022).

Листинг плея 2.3
- name: 2.3. Setting up access rights to file system objects
  hosts: all
  become: yes
  remote_user: fstec
  gather_facts: true
  vars:
    whitelist_apps:
      - /usr/sbin/haproxy

  tasks:

    - name: 2.3.1 Set the rights to /etc/passwd
      ansible.builtin.file:
        path: /etc/passwd
        owner: root
        group: root
        mode: '0644'
      become: yes

    - name: 2.3.1 Set the rights to /etc/group
      ansible.builtin.file:
        path: /etc/group
        owner: root
        group: root
        mode: '0644'
      become: yes

    - name: 2.3.1 Set the rights to /etc/shadow
      ansible.builtin.file:
        path: /etc/shadow
        owner: root
        group: root
        mode: '0600'
      become: yes

    - name: 2.3.2. Set the correct access rights to the files of running processes by executing a command like chmod go-w /path/to/file for all executable files currently running and the corresponding libraries. After that, it is necessary to check that the directory containing this file, as well as all parent directories, are not writable by unprivileged users.
      shell: >
       find /proc -maxdepth 2 -type f -executable -execdir chmod -R
       go-w {} \;
      register: procoutput
      changed_when: false
    
    - name: 2.3.3 Set file access rights for cron files
      find:
        paths: /etc/cron*
        patterns: "*"
        file_type: file
        recurse: yes
      register: cronfiles
    - name: Set correct permissions for cron files
      file:
        path: "{{ item.path }}"
        mode: "0640"
      with_items: "{{ cronfiles.files }}"

    - name: 2.3.4 Find files and links based on $PATH
      shell: echo $PATH
      register: pathvar

    - name: Find regular files
      find:
        paths: '{{ pathvar.stdout.split(":") }}'
        file_type: file
        patterns: '*'
        get_checksum: yes
        hidden: yes
      register: regular_files

    - name: Find symlinks
      find:
        paths: '{{ pathvar.stdout.split(":") }}'
        file_type: link
        patterns: '*'
        get_checksum: yes
        hidden: yes
      register: symlinks

    - name: Output list of regular files to admin
      debug:
        msg: "Found regular applications: {{ regular_files.files | map(attribute='path') | list }}"

    - name: Output list of symlinks to admin
      debug:
        msg: "Found symlinks: {{ symlinks.files | map(attribute='path') | list }}"

    - pause:
        prompt: "Do you want to change the permissions of these files to go-w? (yes/no)"
      register: permissionapprovalfiles
    
    - name: 2.3.4 Change permissions of files if admin approves
      file:
        path: "{{ item.path }}"
        mode: go-w
        state: file
        owner: root
      loop: "{{ regular_files.files }}"
      when: permissionapprovalfiles.user_input == "yes"
      become: true
      
    - pause:
        prompt: "Do you want to change the permissions of these links to go-w? (yes/no)"
      register: permissionapprovallinks

    - name: 2.3.4 Change permissions of links if admin approves
      file:
        path: "{{ item.path }}"
        mode: go-w
        state: link
        owner: root
      loop: "{{ symlinks.files }}"
      when: permissionapprovallinks.user_input == "yes"
      become: true

    - name: 2.3.5. Set the correct access rights to the startup scripts
      file:
        path: "{{ item }}"
        owner: root
        group: root
        mode: '0755'
      with_fileglob:
        - /etc/rc*.d/*
    
    - name: Set access rights to .service files
      find:
        paths: /
        patterns: "*.service"
      register: service_files_result
    
    - name: Set access rights for .service files
      file:
        path: "{{ item.path }}"
        owner: root
        group: root
        mode: '0755'
      loop: "{{ service_files_result.files }}"

    - name: 2.3.6 Set access rights to /etc/crontab /etc/cron.d /etc/cron.hourly /etc/cron.daily /etc/cron.weekly /etc/cron.monthly
      find:
        paths: /etc/cron*
        file_type: any
      register: found_files
    - name: Print found files
      debug:
        var: found_files
   
    - name: Set access rights to found cron files
      file:
        path: "{{ item.path }}"
        mode: 'go-w'
      loop: "{{ cron_files.files }}"

    - name: 2.3.7 Setting access rights to user files of cron tasks
      shell: chmod go-w "{{ item }}"
      with_fileglob:
        - /var/spool/cron/crontabs/*
      register: cron_files_result
    - name: Check the result of changes
      debug:
        var: cron_files_result

    - name: 2.3.8 Setting access rights to executable files and operating system libraries
      shell: echo $PATH
      register: path_result
      changed_when: false
    - name: Set access rights to executable files in paths
      command: find "{{ item }}" -type f -exec chmod go-w {} +
      with_items: "{{ path_result.stdout_lines[0].split(':') }}"
      changed_when: false
    - name: Set access rights to libraries in paths
      command: find "{{ item }}" -type f -exec chmod go-w {} +
      with_items:
        - /lib
        - /lib64
        - /bin
        - /usr/bin
      changed_when: false
    - name: Set access rights to kernel modules
      command: find /lib/modules/{{ ansible_kernel }} -type f -exec chmod go-w {} +
      changed_when: false

    - name: 2.3.9 Find files with setuid permissions
      command: find / -perm -4000 -type f
      register: found_files_4000
      ignore_errors: yes

    - name: 2.3.9 Find files with setgid permissions
      command: find / -perm -2000 -type f
      register: found_files_2000
      ignore_errors: yes

    - name: Display found files with setuid permissions
      debug:
        msg: "{{ found_files_4000.stdout_lines }}"

    - name: Display found files with setgid permissions
      debug:
        msg: "{{ found_files_2000.stdout_lines }}"

    - name: 2.3.9 Remove write permissions from group and others for files with setuid permissions
      file:
        path: "{{ item }}"
        mode: '4755'
      loop: "{{ found_files_4000.stdout_lines | default([]) }}"

    - name: 2.3.9 Remove write permissions from group and others for files with setgid permissions
      file:
        path: "{{ item }}"
        mode: '2755'
      loop: "{{ found_files_2000.stdout_lines | default([]) }}"

    - name: 2.3.10 Get home directories
      shell: ls -d /home/*/
      register: home_directories_output
      ignore_errors: true

    - name: 2.3.10 Convert home directories output to list
      set_fact:
        home_directories: "{{ home_directories_output.stdout_lines }}"
      when: home_directories_output is defined

    - name: 2.3.10 Find dot files in home directories
      find:
        paths: "{{ item }}"
        patterns: ".*"
        file_type: file
      register: dot_files
      with_items: "{{ home_directories }}"
      loop_control:
        loop_var: item

    - name: 2.3.10 Set the correct access rights to the contents of users' home directories
      file:
        path: "{{ item.path }}"
        mode: go-rwx
      with_items: "{{ dot_files.files }}"
      when: dot_files.files | default([])
      become: true

    - name: 2.3.11. Set correct access rights to users' home directories
      find:
        paths: /home
        patterns: "*"
        depth: 1
        file_type: directory
      register: home_directories_result

    - name: Set correct access rights to users' home directories
      file:
        path: "{{ item.path }}"
        state: directory
        mode: "0700"
      loop: "{{ home_directories_result.files }}"

Описание:

  • Переменная whitelist_apps содержит список приложений, для которых права доступа не требуется изменять.

  • Плеи 2.3.1 устанавливают права доступа к системным файлам /etc/passwd, /etc/group и /etc/shadow.

  • Плеи 2.3.2 проверяют и устанавливают права доступа к файлам, используемым запущенными процессами.

  • Плей 2.3.3 устанавливает права доступа для файлов cron.

  • Плеи 2.3.4 находят обычные файлы и символьные ссылки в /usr/bin, выводят их и запрашивают разрешение на изменение владельца. Затем устанавливают права доступа для найденных файлов и ссылок.

  • Плей 2.3.5 запускает команду оболочки для установки прав доступа к скриптам автозагрузки. Он также находит и устанавливает права доступа к «.service» файлам.

  • Плей 2.3.6 проводит установку прав доступа к файлам, находящимся в указанных директориях, выводит найденные файлы и проверяет результат изменений.

  • Плей 2.3.7 устанавливает права доступа к файлам пользовательских задач cron и проверяет результат изменений.

  • Плей 2.3.8 выполняет установку прав доступа к исполняемым файлам, библиотекам операционной системы и модулям ядра.

  • Плеи 2.3.9 находят SUID/SGID приложения, устанавливают права доступа к ним и удаляют SUID/SGID биты из ненужных приложений.

  • Плеи 2.3.10 находят домашние каталоги пользователей, затем точечные файлы в этих каталогах и устанавливают правильные права доступа к содержимому домашних каталогов.

  • 2.3.11 устанавливает правильные права доступа к домашним каталогам пользователей.

Настройка прав доступа к объектам файловой системы

Плей «2.4 Configuring Linux Kernel protection mechanisms» закрывает настройки пункта «2.4. Настройка механизмов защиты ядра Linux» (утв. ФСТЭК России 25.12.2022).

Листинг плея 2.4
- name: 2.4 Configuring Linux Kernel protection mechanisms
  hosts: all
  become: true
  remote_user: fstec 
  tasks:
    - name: 2.4.1 Restrict access to kernel logs
      sysctl:
        name: kernel.dmesg_restrict
        value: 1
        state: present
        sysctl_set: yes
    
    - name: Check for CAP_SYSLOG capability
      command: "sysctl -p"
      changed_when: false
      register: sysctl_result
    
    - name: Print sysctl result
      debug:
        var: sysctl_result
          
    - name: 2.4.2 Check and update kernel.kptr_restrict value and interface address
      shell: cat /proc/sys/kernel/kptr_restrict
      register: kptr_restrict_value
      
    - name: Check if kptr_restrict value is 2
      debug:
        msg: "The kernel.kptr_restrict value is already set to 2"
      when: kptr_restrict_value.stdout == "2\n"
      
    - name: Set kernel.kptr_restrict value to 2
      sysctl:
        name: kernel.kptr_restrict
        value: 2
        state: present
      register: kernel_kptr_restrict
      when: kptr_restrict_value.stdout != "2\n"
      
    - name: Get network interfaces information
      shell: ip addr show
      register: network_interface_info
      
    - name: Check if any interface has address 0.0.0.0
      debug:
        msg: "Interface has address 0.0.0.0"
      when: "'0.0.0.0' in network_interface_info.stdout"
      
    - name: Set interface address to 0.0.0.0
      shell: ip addr add 0.0.0.0 dev {{ item }}
      with_items: "{{ ansible_interfaces }}"
      register: interface_address_change
      when: "'0.0.0.0' not in network_interface_info.stdout"
      
    - name: Check if interface address was changed
      debug:
        msg: "Interface address changed"
      when: interface_address_change.changed or interface_address_change.results | selectattr('changed', 'defined') | list | length > 0
      
    - name: Persist interface address changes
      shell: ip addr save
      when: interface_address_change.changed or interface_address_change.results | selectattr('changed', 'defined') | list | length > 0
      
    - name: Check if kernel.kptr_restrict value is set to 2
      debug:
        msg: "The kernel.kptr_restrict value is set to 2"
      when: kernel_kptr_restrict.changed or interface_address_change.changed or interface_address_change.results | selectattr('changed', 'defined') | list | length > 0

    - name: 2.4.3. Checking the value of the initonalloc kernel boot option
      become: true
      shell: cat /proc/cmdline
      register: cmdlineoutput
    - name: Checking the value of the initonalloc kernel boot option
      become: true
      debug:
        msg: The initonalloc option is already set to 1!
      when: "'initonalloc=1' in cmdlineoutput.stdout"
    - name: Setting the value of the initonalloc kernel boot option
      become: true
      lineinfile:
        dest: /etc/default/grub
        regexp: ^GRUB_CMDLINE_LINUX=
        line: GRUB_CMDLINE_LINUX="initonalloc=1"

    - name: 2.4.4 Checking the value of the slab_nomerge option
      blockinfile:
        path: /etc/default/grub
        block: |
          # Added by Ansible to enable slab_nomerge
          GRUB_CMDLINE_LINUX="slab_nomerge"
        insertafter: EOF
      changed_when: false

    - name: 2.4.5. Initialize the IOMMU mechanism
      blockinfile:
        path: /etc/default/grub
        block: |
          # Added by Ansible: Initialize the IOMMU mechanism
          GRUB_CMDLINE_LINUX="iommu=force iommu.strict=1 iommu.passthrough=0"
        insertafter: EOF
      changed_when: false
    - name: 2.4.6. Randomize the location of the kernel stack
      blockinfile:
        path: /etc/default/grub
        block: |
          # Added by Ansible: Randomize the location of the kernel stack
          GRUB_CMDLINE_LINUX="randomizekstackoffset=1"
        insertafter: EOF
      changed_when: false    
    - name: 2.4.7 Enable protection against CPU hardware vulnerabilities
      blockinfile:
        path: /etc/default/grub
        block: |
          # Added by Ansible: Enable protection against CPU hardware vulnerabilities
          GRUB_CMDLINE_LINUX="mitigations=auto,nosmt"
        insertafter: EOF
      changed_when: false
    - name: Update Grub
      command: sudo grub2-mkconfig -o /boot/grub2/grub.cfg  

    - name: 2.4.8. Enable protection of the eBPF JIT subsystem of the Linux kernel
      sysctl:
        name: net.core.bpf_jit_harden
        value: "2"
        state: present

Описание:

2.4.1 Restrict access to kernel logs:

  • Устанавливает параметр kernel.dmesg_restrict в значение 1, ограничивая доступ к журналу ядра.

Check for CAPSYSLOG capability:

  • Выполняет команду sysctl -p для проверки наличия возможности CAPSYSLOG.

  • Результаты сохраняются в переменную sysctl_result.

2.4.2 Check and update kernel.kptrrestrict value and interface address:

  • Выводит текущее значение kernel.kptrrestrict из /proc/sys/kernel/kptrrestrict.

  • Проверяет, установлено ли значение 2. Если нет, устанавливает его.

  • Получает информацию об интерфейсах с помощью ip addr show, проверяет адрес каждого интерфейса, и при необходимости устанавливает адрес 0.0.0.0.

2.4.3 Checking the value of the initonalloc kernel boot option:

  • Читает содержимое файла /proc/cmdline для проверки наличия опции ядра initonalloc=1.

  • Если опция уже установлена, выводит сообщение об этом. В противном случае добавляет опцию в файл /etc/default/grub.

2.4.4 Checking the value of the slabnomerge option:

  • Добавляет опцию slab_nomerge в файл настроек загрузчика GRUB (/etc/default/grub).

  • Плейбук реализует набор действий по настройке безопасности ядра Linux, устанавливая необходимые параметры и опции для улучшения общей защиты системы.

2.4.5. Инициализация механизма IOMMU

  • В блоке blockinfile добавляется информация в файл настроек grub (/etc/default/grub) для инициализации механизма IOMMU.

  • Устанавливаются параметры GRUBCMDLINELINUX="iommu=force iommu.strict=1 iommu.passthrough=0", что позволяет активировать и жестко настроить механизм IOMMU.

2.4.6. Рандомизация расположения ядра стека

  • В блоке blockinfile добавляется информация в файл настроек grub (/etc/default/grub) для рандомизации расположения ядра стека.

  • Устанавливается параметр GRUBCMDLINELINUX="randomizekstackoffset=1", что поможет увеличить безопасность системы за счет рандомизации расположения стека ядра.     

2.4.7. Включение защиты от уязвимостей оборудования процессора

  • В блоке blockinfile добавляется информация в файл настроек grub (/etc/default/grub) для включения защиты от уязвимостей оборудования процессора.

  • Устанавливаются параметры GRUBCMDLINELINUX="mitigations=auto,nosmt", что активирует автоматическое управление мерами безопасности и отключение поддержки SMT (Simultaneous Multithreading).     

2.4.8. Включение защиты подсистемы eBPF JIT в ядре Linux

  • Модулем sysctl устанавливается параметр net.core.bpfjitharden на значение "2", что позволяет активировать защиту подсистемы eBPF JIT в ядре Linux.

Реализация мер по уменьшению периметра атаки ядра Linux

Плей «2.5 Reducing the attack perimeter of the Linux kernel». Он закрывает настройки из пункта «2.5. Уменьшение периметра атаки ядра Linux» (утв. ФСТЭК России 25.12.2022).

Листинг плея 2.5
- name: 2.5 Reducing the attack perimeter of the Linux kernel
  hosts: all
  become: true
  remote_user: fstec
  tasks:
    - name: 2.5.1 Disabling the outdated vsyscall interface
      blockinfile:
        path: /etc/default/grub
        marker: "# {mark} ANSIBLE MANAGED BLOCK - vsyscall settings"
        block: |
          GRUB_CMDLINE_LINUX_DEFAULT="quiet splash vsyscall=none"
             
    - name: 2.5.2. Restrict access to performance events
      sysctl:
        name: kernel.perf_event_paranoid
        value: "3"
        state: present

    - name: 2.5.3. Disable mounting of the debugfs virtual file system
      blockinfile:
        path: /etc/default/grub
        marker: "# {mark} ANSIBLE MANAGED BLOCK - debugfs settings"
        block: |
          GRUB_CMDLINE_LINUX_DEFAULT="quiet splash debugfs=no-mount"
      
    - name: 2.5.4. Disable the kexec_load system call
      sysctl:
        name: kernel.kexec_load_disabled
        value: "1"
        state: present

    - name: 2.5.5. Restrict the use of user namespaces
      sysctl:
        name: user.max_user_namespaces
        value: "0"
        state: present

    - name: 2.5.6. Prohibit the bpf system call for unprivileged users
      sysctl:
        name: kernel.unprivileged_bpf_disabled
        value: "1"
        state: present

    - name: 2.5.7. Prohibit the userfaultfd system call for unprivileged users
      sysctl:
        name: vm.unprivileged_userfaultfd
        value: "0"
        state: present

    - name: 2.5.8. Prohibition of automatic loading of kernel modules for terminal line discipline
      sysctl:
        name: dev.tty.ldisc_autoload
        value: "0"
        state: present

    - name: 2.5.9. Disable Transactional Synchronization Extensions (TSX) technology
      blockinfile:
        path: /etc/default/grub
        marker: "# {mark} ANSIBLE MANAGED BLOCK - TSX settings"
        block: |
          GRUB_CMDLINE_LINUX_DEFAULT="quiet splash tsx=off"


    - name: 2.5.10 Configuring the vm.mmap_min_addr kernel parameter
      sysctl:
        name: vm.mmap_min_addr
        value: "4096"
        state: present

    - name: 2.5.11. Implement address space randomization
      sysctl:
        name: kernel.randomize_va_space
        value: "2"
        state: present
  
    - name: Applying sysctl change
      command: sysctl -p

Описание:

  • 2.5.1 Отключение устаревшего интерфейса vsyscall: в блоке blockinfile добавляется информация в файл настроек grub (/etc/default/grub) для отключения устаревшего интерфейса vsyscall. Устанавливается параметр GRUB_CMDLINE_LINUX_DEFAULT="quiet splash vsyscall=none". 

  • 2.5.2 Ограничение доступа к событиям производительности: с помощью модуля sysctl настраивается параметр kernel.perf_event_paranoid на значение "3", что ограничивает доступ к событиям производительности.  

  • 2.5.3 Отключение монтирования виртуальной файловой системы debugfs: в блоке blockinfile добавляется информация в файл настроек grub (/etc/default/grub) для отключения монтирования виртуальной файловой системы debugfs. Устанавливается параметр GRUB_CMDLINE_LINUX_DEFAULT="quiet splash debugfs=no-mount".

  • 2.5.4 Отключение системного вызова kexec_load: с помощью модуля sysctl настраивается параметр kernel.kexec_load_disabled на значение "1", что отключает использование системного вызова kexec_load. 

  • 2.5.5 Ограничение использования пространств имен пользователей: с помощью модуля sysctl настраивается параметр user.max_user_namespaces на значение "0", что ограничивает использование пространств имен пользователей.

  • 2.5.6 Запрет системного вызова bpf для непривилегированных пользователей: с помощью модуля sysctl настраивается параметр kernel.unprivileged_bpf_disabled на значение "1", что запрещает использование системного вызова bpf для непривилегированных пользователей.

  • 2.5.7 Запрет системного вызова userfaultfd для непривилегированных пользователей: с помощью модуля sysctl настраивается параметр vm.unprivileged_userfaultfd на значение "0", что запрещает использование системного вызова userfaultfd для непривилегированных пользователей. 

  • 2.5.8 Запрет автоматической загрузки модулей ядра для терминальной линейной дисциплины: с помощью модуля sysctl настраивается параметр dev.tty.ldisc_autoload на значение "0", что запрещает автоматическую загрузку модулей ядра для терминальной линейной дисциплины.

  • 2.5.9 Отключение технологии Transactional Synchronization Extensions (TSX): в блоке blockinfile добавляется информация в файл настроек grub (/etc/default/grub) для отключения технологии Transactional Synchronization Extensions (TSX). Устанавливается параметр GRUB_CMDLINE_LINUX_DEFAULT="quiet splash tsx=off".

  • 2.5.10 Настройка параметра ядра vm.mmap_min_addr: с помощью модуля sysctl настраивается параметр vm.mmap_min_addr на значение "4096".

  • 2.5.11 Реализация случайной адресации пространства адресов: с помощью модуля sysctl настраивается параметр kernel.randomize_va_space на значение "2", что реализует случайную адресацию пространства адресов.  

  • Применение изменений sysctl: командой выполняется перезагрузка параметров sysctl для применения всех изменений.

Реализация автоматизации настройки средств защиты пользовательского пространства со стороны ядра Linux

Плей «2.6 Configuring user space protection tools from the Linux kernel» закрывает настройки по пункту «2.6. Настройка средств защиты пользовательского пространства со стороны ядра Linux» (утв. ФСТЭК России 25.12.2022).

Листинг плея 2.6
- name: 2.6 Configuring user space protection tools from the Linux kernel
  hosts: all
  become: true
  remote_user: fstec
  tasks:
    - name: 2.6.1. Prohibit connection to other processes using ptrace
      sysctl:
        name: kernel.yama.ptrace_scope
        value: "3"
        state: present

    - name: 2.6.2. Limit unsafe options for passing through symbolic links
      sysctl:
        name: fs.protected_symlinks
        value: "1"
        state: present


    - name: 2.6.3. Limit unsafe options for working with hard links
      sysctl:
        name: fs.protected_hardlinks
        value: "1"
        state: present

    - name: 2.6.4. Enable protection against unintentional writing to a FIFO object
      sysctl:
        name: fs.protected_fifos
        value: "2"
        state: present

    - name: 2.6.5. Enable protection against unintentional writing to a file
      become: yes
      sysctl:
        name: fs.protected_regular
        value: 2
      register: sysctl_result
    - name: Check the result of changing the sysctl option
      debug:
        var: sysctl_result

    - name: 2.6.6. Prohibit the creation of core dump
      sysctl:
        name: fs.suid_dumpable
        value: 0
      register: sysctl_result
    - name: Check the result of changing the sysctl option
      debug:
        var: sysctl_result
    
    - name: Applying sysctl change
      command: sysctl -p

- name: Update Grub
  hosts: all
  become: true
  remote_user: fstec
  tasks:
    - name: Update Grub configuration
      command: sudo grub2-mkconfig -o /boot/grub2/grub.cfg

 Описание:

  • 2.6.1 Запрещение подключения к другим процессам с использованием ptrace: с помощью модуля sysctl настраивается параметр kernel.yama.ptracescope на значение "3", что запрещает подключение к другим процессам с использованием ptrace.

  • 2.6.2 Ограничение небезопасных опций для передачи символических ссылок: с помощью модуля sysctl настраивается параметр fs.protectedsymlinks на значение "1", что ограничивает небезопасные опции для передачи символических ссылок.

  • 2.6.3 Ограничение небезопасных опций для работы с жесткими ссылками: с помощью модуля sysctl настраивается параметр fs.protectedhardlinks на значение "1", что ограничивает небезопасные опции для работы с жесткими ссылками.

  • 2.6.4 Включение защиты от ненамеренной записи в объект FIFO: с помощью модуля sysctl настраивается параметр fs.protectedfifos на значение "2", что включает защиту от ненамеренной записи в объект FIFO.

  • 2.6.5 Включение защиты от ненамеренной записи в файл: с помощью модуля sysctl настраивается параметр fs.protectedregular на значение "2" с правами суперпользователя. Результат изменения параметра регистрируется и выводится для проверки.

  • 2.6.6 Запрет создания дампа ядра: с помощью модуля sysctl настраивается параметр fs.suiddumpable на значение "0". Результат изменения параметра регистрируется и выводится для проверки.

  • 2.6.7 Применение изменений sysctl: командой выполняется перезагрузка параметров sysctl для применения всех изменений.

  • Обновление Grub: после настройки инструментов защиты пространства пользователя, плейбук также выполняет обновление Grub для применения изменений в конфигурационных файлах.

Заключение

Выполнение рекомендаций ФСТЭК России по безопасной настройке операционных систем Linux не только важно для обеспечения информационной безопасности, но и является обязательным для объектов, относящихся к критической информационной инфраструктуре (КИИ) и государственным информационным системам.

Использование Ansible для автоматизации процессов значительно упрощает соблюдение этих требований и снижает риск ошибок.

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

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

Автор: Вероника Воронцова, инженер направления автоматизации ИБ УЦСБ

Tags:
Hubs:
+7
Comments5

Articles

Information

Website
www.ussc.ru
Registered
Founded
Employees
501–1,000 employees
Location
Россия