---
description: 'Описаны сотни стандартных практик о том, как защитить системы и сети, и для пользователя FreeBSD понимание того, как защититься от атак и злоумышленников, является обязательным'
next: books/handbook/jails
params:
  path: /books/handbook/security/
part: 'Часть III. Администрирование системы'
prev: books/handbook/boot
showBookMenu: 'true'
tags: ["security", "TCP Wrappers", "Kerberos", "OpenSSL", "OpenSSH", "ACL", "NFSv4 ACLs", "advisories", "sudo", "doas", "capsicum", "monitoring"]
title: 'Глава 16. Безопасность'
weight: 20
---

[[security]]
= Безопасность
:doctype: book
:toc: macro
:toclevels: 1
:icons: font
:sectnums:
:sectnumlevels: 6
:sectnumoffset: 16
:partnums:
:source-highlighter: rouge
:experimental:
:images-path: books/handbook/security/

ifdef::env-beastie[]
ifdef::backend-html5[]
:imagesdir: ../../../../images/{images-path}
endif::[]
ifndef::book[]
include::shared/authors.adoc[]
include::shared/mirrors.adoc[]
include::shared/releases.adoc[]
include::shared/attributes/attributes-{{% lang %}}.adoc[]
include::shared/{{% lang %}}/teams.adoc[]
include::shared/{{% lang %}}/mailing-lists.adoc[]
include::shared/{{% lang %}}/urls.adoc[]
toc::[]
endif::[]
ifdef::backend-pdf,backend-epub3[]
include::../../../../../shared/asciidoctor.adoc[]
endif::[]
endif::[]

ifndef::env-beastie[]
toc::[]
include::../../../../../shared/asciidoctor.adoc[]
endif::[]

[[security-synopsis]]
== Обзор

Сотни стандартных практик написаны о том, как защитить системы и сети, и, как пользователю FreeBSD, понимание того, как защититься от атак и злоумышленников, является обязательным.

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

Эта глава охватывает:

* Основные концепции безопасности системы FreeBSD.
* Доступные в FreeBSD механизмы шифрования.
* Как настроить TCP Wrappers для использования с man:inetd[8].
* Как настроить Kerberos на FreeBSD.
* Как настроить и использовать OpenSSH на FreeBSD.
* Как использовать OpenSSL в FreeBSD.
* Как использовать ACL файловых систем.
* Как использовать pkg для аудита сторонних программных пакетов, установленных из Коллекции портов.
* Как использовать рекомендации по безопасности FreeBSD.
* Что такое учёт процессов и как его включить в FreeBSD.
* Как управлять ресурсами пользователей с помощью классов входа или базы данных ограничений ресурсов.
* Что такое Capsicum и базовый пример.

Некоторые темы из-за их сложности рассматриваются в отдельных главах, таких как crossref:firewalls[firewalls,Межсетевые экраны], crossref:mac[mac,Принудительное управление доступом], и статьях, например extref:{vpn-ipsec}[VPN через IPsec].

[[security-intro]]
== Введение

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

Триада КЦД (конфиденциальность, целостность, доступность) — это фундаментальная концепция безопасности в компьютерных системах, так как клиенты и пользователи ожидают, что их данные будут защищены. Например, клиент ожидает, что информация о его кредитной карте хранится безопасно (конфиденциальность), что его заказы не будут изменены без его ведома (целостность) и что он в любое время сможет получить доступ к информации о своих заказах (доступность).

Для обеспечения КЦД специалисты по безопасности применяют стратегию "глубокой эшелонированной защиты". Идея глубокой эшелонированной защиты заключается в добавлении нескольких уровней безопасности, чтобы предотвратить отказ одного уровня и полный крах всей системы безопасности. Например, системный администратор не может просто включить межсетевой экран и считать сеть или систему безопасными. Необходимо также проводить аудит учётных записей, проверять целостность бинарных файлов и убеждаться, что вредоносные инструменты не установлены. Для реализации эффективной стратегии безопасности необходимо понимать угрозы и способы защиты от них.

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

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

Применяя меры безопасности к системам, рекомендуется начать с защиты базовых учётных записей и конфигурации системы, а затем обеспечить безопасность сетевого уровня, чтобы он соответствовал политике системы и процедурам безопасности организации. Многие организации уже имеют политику безопасности, которая охватывает конфигурацию технологических устройств. Эта политика должна включать настройки безопасности рабочих станций, настольных компьютеров, мобильных устройств, телефонов, производственных серверов и серверов разработки. Во многих случаях уже существуют стандартные операционные процедуры (СОП). Если возникают сомнения, обратитесь к команде безопасности.

[[sec-accounts]]
== Защита учётных записей

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

[[security-accounts]]
=== Предотвращение входов в систему

При обеспечении безопасности системы хорошей отправной точкой является аудит учётных записей. Отключите все учётные записи, которым не требуется доступ для входа.

[TIP]
====
Убедитесь, что у пользователя `root` установлен надёжный пароль и что этот пароль не используется совместно.
====

Для запрета входа в учётные записи существуют два метода.

Первый способ — заблокировать учётную запись, в этом примере показано, как заблокировать учётную запись `imani`:

[source, shell]
....
# pw lock imani
....

Второй способ — запретить вход в систему, изменив оболочку на [.filename]#/usr/sbin/nologin#. Оболочка man:nologin[8] предотвращает назначение оболочки пользователю при попытке входа в систему.

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

[source, shell]
....
# chsh -s /usr/sbin/nologin imani
....

[[security-passwords]]
=== Хеши паролей

Пароли — это неизбежное зло в мире технологий. Когда их использование необходимо, они должны быть сложными, а для хранения зашифрованной версии в базе данных паролей следует использовать надёжный механизм хеширования. FreeBSD поддерживает несколько алгоритмов, включая SHA256, SHA512 и Blowfish, в своей библиотеке `crypt()`. Подробности можно найти в man:crypt[3].

По умолчанию используется SHA512, и его не следует заменять на менее безопасный алгоритм хеширования, но можно перейти на более безопасный алгоритм Blowfish.

[NOTE]
====
Blowfish не является частью AES и не соответствует Федеральным стандартам обработки информации (FIPS). Его использование может быть запрещено в некоторых средах.
====

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

Если используется DES, начальный символ отсутствует. Для MD5 символ — `$`. Для SHA256 и SHA512 символ — `$6$`. Для Blowfish символ — `$2a$`. В этом примере пароль для `imani` хеширован с использованием алгоритма SHA512 по умолчанию, так как хеш начинается с `$6$`. Обратите внимание, что в базе данных паролей хранится зашифрованный хеш, а не сам пароль:

[source, shell]
....
# grep imani /etc/master.passwd
....

Вывод должен быть похож на следующий:

[.programlisting]
....
imani:$6$pzIjSvCAn.PBYQBA$PXpSeWPx3g5kscj3IMiM7tUEUSPmGexxta.8Lt9TGSi2lNQqYGKszsBPuGME0:1001:1001::0:0:imani:/usr/home/imani:/bin/sh
....

Механизм хеширования задается в классе входа пользователя.

Следующая команда позволяет проверить, какой механизм хеширования используется в данный момент:

[source, shell]
....
% grep passwd_format /etc/login.conf
....

Вывод должен быть похож на следующий:

[.programlisting]
....
:passwd_format=sha512:\
....

Например, чтобы изменить алгоритм на Blowfish, измените эту строку следующим образом:

[.programlisting]
....
:passwd_format=blf:\
....

Затем необходимо выполнить man:cap_mkdb[1] для обновления базы данных login.conf:

[source, shell]
....
# cap_mkdb /etc/login.conf
....

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

[[security-pwpolicy]]
=== Политика применения паролей

Обеспечение строгой политики паролей для локальных учётных записей является основополагающим аспектом безопасности системы. В FreeBSD длина пароля, его стойкость и сложность могут быть реализованы с использованием встроенных подключаемых модулей аутентификации (Pluggable Authentication Modules - PAM).

Этот раздел демонстрирует, как настроить минимальную и максимальную длину пароля, а также принудительное использование смешанных символов с помощью модуля man:pam_passwdqc[8]. Данный модуль применяется при изменении пользователем своего пароля.

Для настройки этого модуля станьте суперпользователем и раскомментируйте строку с `pam_passwdqc.so` в [.filename]#/etc/pam.d/passwd#.

Затем отредактируйте эту строку в соответствии с политикой паролей:

[.programlisting]
....
password        requisite       pam_passwdqc.so         min=disabled,disabled,disabled,12,10 similar=deny retry=3 enforce=users
....

Описание параметров можно найти в man:pam_passwdqc[8].

После сохранения этого файла пользователь, изменяющий свой пароль, увидит сообщение, похожее на следующее:

[source, shell]
....
% passwd
....

Вывод должен быть похож на следующий:

[.programlisting]
....
Changing local password for user
Old Password:

You can now choose the new password.
A valid password should be a mix of upper and lower case letters,
digits and other characters.  You can use a 12 character long
password with characters from at least 3 of these 4 classes, or
a 10 character long password containing characters from all the
classes.  Characters that form a common pattern are discarded by
the check.
Alternatively, if no one else can see your terminal now, you can
pick this as your password: "trait-useful&knob".
Enter new password:
....

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

Если политика вашей организации требует, чтобы пароли имели срок действия, FreeBSD поддерживает параметр `passwordtime` в классе пользователя в [.filename]#/etc/login.conf#

Класс входа `default` содержит пример:

[.programlisting]
....
#       :passwordtime=90d:\
....

Итак, чтобы установить срок действия в 90 дней для этого класса входа, удалите символ комментария (#), сохраните изменения и выполните следующую команду:

[source, shell]
....
# cap_mkdb /etc/login.conf
....

Чтобы установить срок действия для отдельных пользователей, передайте дату истечения срока или количество дней до истечения и имя пользователя в `pw`:

[source, shell]
....
# pw usermod -p 30-apr-2025 -n user
....

Как показано здесь, срок действия устанавливается в виде дня, месяца и года. Для получения дополнительной информации см. man:pw[8].

[[security-sudo]]
=== Совместное администрирование с помощью sudo

Системные администраторы часто сталкиваются с необходимостью предоставления пользователям расширенных прав для выполнения привилегированных задач. Идея о том, что члены команды получают доступ к системе FreeBSD для выполнения своих конкретных задач, создает уникальные проблемы для каждого администратора. Этим сотрудникам требуется лишь ограниченный набор прав, выходящий за рамки обычного уровня пользователя; однако они почти всегда заявляют руководству, что не могут выполнять свои задачи без прав суперпользователя. К счастью, нет необходимости предоставлять такие права конечным пользователям, так как существуют инструменты для управления этим требованием.

[TIP]
====
Даже администраторы должны ограничивать свои привилегии, когда в них нет необходимости.
====

До этого момента в главе о безопасности рассматривались вопросы предоставления доступа авторизованным пользователям и попытки предотвратить несанкционированный доступ. Однако возникает другая проблема, когда авторизованные пользователи получают доступ к системным ресурсам. Во многих случаях некоторым пользователям может потребоваться доступ к скриптам запуска приложений, или команде администраторов необходимо обслуживать систему.. Традиционно для управления таким доступом использовались стандартные пользователи и группы, права доступа к файлам и даже команда man:su[1]. Однако по мере того, как приложениям требовалось больше прав, а большему числу пользователей нужно было использовать системные ресурсы, потребовалось лучшее решение. В настоящее время наиболее часто используемым приложением для этих целей является Sudo.

Sudo позволяет администраторам настраивать более строгий доступ к системным командам и обеспечивать дополнительные функции ведения журналов. Этот инструмент доступен в коллекции портов как package:security/sudo[] или с помощью утилиты man:pkg[8].

Выполните следующую команду для установки:

[source, shell]
....
# pkg install sudo
....

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

Файл конфигурации состоит из нескольких небольших разделов, которые позволяют проводить детальную настройку. В следующем примере администратору веб-приложения, user1, требуется запускать, останавливать и перезапускать веб-приложение с именем _webservice_. Чтобы предоставить этому пользователю права на выполнение данных задач, добавьте следующую строку в конец файла [.filename]#/usr/local/etc/sudoers#:

[.programlisting]
....
user1   ALL=(ALL)       /usr/sbin/service webservice *
....

Пользователь может теперь запустить _webservice_ с помощью следующей команды:

[source, shell]
....
% sudo /usr/sbin/service webservice start
....

Хотя данная конфигурация предоставляет одному пользователю доступ к службе `webservice`, в большинстве организаций управление этой службой доверено целой команде веб-разработчиков. Одной строкой можно также предоставить доступ всей группе. Следующие шаги позволят создать группу `web`, добавить в неё пользователя и разрешить всем членам группы управлять службой:

[source, shell]
....
# pw groupadd -g 6001 -n webteam
....

Используя ту же команду man:pw[8], пользователь добавляется в группу webteam:

[source, shell]
....
# pw groupmod -m user1 -n webteam
....

Наконец, эта строка в [.filename]#/usr/local/etc/sudoers# разрешает любому члену группы webteam управлять _webservice_:

[.programlisting]
....
%webteam   ALL=(ALL)       /usr/sbin/service webservice *
....

В отличие от man:su[1], man:sudo[8] требует только пароль конечного пользователя. Это позволяет избежать совместного использования паролей, что является небезопасной практикой.

Пользователи, которым разрешено запускать приложения с помощью man:sudo[8], вводят только свои собственные пароли. Это более безопасно и обеспечивает лучший контроль, чем man:su[1], где вводится пароль `root` и пользователь получает все права `root`.

[TIP]
====
Большинство организаций переходят или уже перешли на модель двухфакторной аутентификации. В таких случаях у пользователя может не быть пароля для ввода.

man:sudo[8] можно настроить для поддержки двухфакторной модели аутентификации с использованием переменной `NOPASSWD`. Добавление её в приведённую выше конфигурацию позволит всем членам группы _webteam_ управлять службой без требования пароля:

[.programlisting]
....
%webteam   ALL=(ALL)       NOPASSWD: /usr/sbin/service webservice *
....
====

[[security-doas]]
=== Совместное администрирование с Doas

man:doas[1] - это утилита командной строки, портированная из OpenBSD. Она служит альтернативой широко используемой команде man:sudo[8] в Unix-подобных системах.

С помощью `doas` пользователи могут выполнять команды с повышенными привилегиями, обычно от имени пользователя `root`, сохраняя при этом простой и безопасный подход. В отличие от man:sudo[8], `doas` делает акцент на простоте и минимализме, предлагая лаконичное делегирование полномочий без избыточного количества настройки.

Выполните следующую команду для установки:

[source, shell]
....
# pkg install doas
....

После установки необходимо настроить [.filename]#/usr/local/etc/doas.conf#, чтобы предоставить пользователям доступ к определённым командам или ролям.

Самый простой вариант может выглядеть следующим образом, который предоставляет пользователю `local_user` права `root` без запроса пароля при выполнении команды doas.

[.programlisting]
....
permit nopass local_user as root
....

После установки и настройки утилиты `doas` команда теперь может быть выполнена с повышенными привилегиями, например:

[source, shell]
....
$ doas vi /etc/rc.conf
....

Для дополнительных примеров конфигурации обратитесь к man:doas.conf[5].

[[security-ids]]
== Система обнаружения вторжений (IDS)

Проверка системных файлов и двоичных файлов важна, поскольку предоставляет администраторам системы и командам безопасности информацию об изменениях в системе. Программное приложение, которое отслеживает изменения в системе, называется системой обнаружения вторжений (Intrusion Detection System — IDS).

FreeBSD предоставляет встроенную поддержку базовой системы IDS под названием man:mtree[8]. Хотя ежедневные письма с информацией о безопасности уведомят администратора об изменениях, эти данные хранятся локально, и существует вероятность, что злоумышленник может изменить их, чтобы скрыть свои изменения в системе. Поэтому рекомендуется создать отдельный набор бинарных сигнатур и хранить их в предназначенном только для чтения каталоге, принадлежащем root, или, предпочтительно, на съёмном USB-диске или удалённом сервере.

Также рекомендуется запускать `freebsd-update IDS` после каждого обновления.

[[security-ids-generate-spec-file]]
=== Генерация файла спецификации

Встроенная утилита man:mtree[8] может использоваться для создания спецификации содержимого каталога. Спецификация генерируется с использованием начального значения (seed) — числовой константы, которая также необходима для проверки неизменности спецификации. Это позволяет определить, был ли изменён файл или бинарный файл. Поскольку злоумышленник не знает начальное значение, подделать или проверить контрольные суммы файлов будет крайне сложно или невозможно.

[TIP]
====
Рекомендуется создавать спецификации для каталогов, содержащих исполняемые файлы и конфигурационные файлы, а также для любых каталогов с чувствительными данными. Обычно спецификации создаются для [.filename]#/bin#, [.filename]#/sbin#, [.filename]#/usr/bin#, [.filename]#/usr/sbin#, [.filename]#/usr/local/bin#, [.filename]#/etc# и [.filename]#/usr/local/etc#.
====

Следующий пример создает набор хешей `sha512` — по одному для каждого системного бинарного файла в [.filename]#/bin# — и сохраняет эти значения в скрытый файл в домашнем каталоге пользователя [.filename]#/home/user/.bin_chksum_mtree#:

[source, shell]
....
# mtree -s 123456789 -c -K cksum,sha512 -p /bin > /home/user/.bin_chksum_mtree
....

Вывод должен быть похож на следующий:

[.programlisting]
....
mtree: /bin checksum: 3427012225
....

[WARNING]
====
Значение `123456789` представляет собой зерно (seed) и должно быть выбрано случайным образом. Этот параметр необходимо запомнить, *но не раскрывать*.

Важно скрывать начальное значение и контрольную сумму от злоумышленников.
====

[[security-ids-spec-file-structure]]
=== Структура файла спецификации

Формат `mtree` — это текстовый формат, описывающий набор объектов файловой системы. Такие файлы обычно используются для создания или проверки иерархий каталогов.

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

Созданный выше файл спецификации будет использоваться для объяснения формата и содержания:

[.programlisting]
....
#          user: root <.>
#       machine: machinename <.>
#          tree: /bin <.>
#          date: Thu Aug  24 21:58:37 2023 <.>

# .
/set type=file uid=0 gid=0 mode=0555 nlink=1 flags=uarch <.>
.               type=dir mode=0755 nlink=2 time=1681388848.239523000 <.>
    \133        nlink=2 size=12520 time=1685991378.688509000 \
                cksum=520880818 \
                sha512=5c1374ce0e2ba1b3bc5a41b23f4bbdc1ec89ae82fa01237f376a5eeef41822e68f1d8f75ec46b7bceb65396c122a9d837d692740fdebdcc376a05275adbd3471
    cat         size=14600 time=1685991378.694601000 cksum=3672531848 \ <.>
                sha512=b30b96d155fdc4795432b523989a6581d71cdf69ba5f0ccb45d9b9e354b55a665899b16aee21982fffe20c4680d11da4e3ed9611232a775c69f926e5385d53a2
    chflags     size=8920 time=1685991378.700385000 cksum=1629328991 \
                sha512=289a088cbbcbeb436dd9c1f74521a89b66643976abda696b99b9cc1fbfe8b76107c5b54d4a6a9b65332386ada73fc1bbb10e43c4e3065fa2161e7be269eaf86a
    chio        size=20720 time=1685991378.706095000 cksum=1948751604 \
                sha512=46f58277ff16c3495ea51e74129c73617f31351e250315c2b878a88708c2b8a7bb060e2dc8ff92f606450dbc7dd2816da4853e465ec61ee411723e8bf52709ee
    chmod       size=9616 time=1685991378.712546000 cksum=4244658911 \
                sha512=1769313ce08cba84ecdc2b9c07ef86d2b70a4206420dd71343867be7ab59659956f6f5a458c64e2531a1c736277a8e419c633a31a8d3c7ccc43e99dd4d71d630
....

<.> Пользователь, создавший спецификацию.
<.> Имя хоста машины.
<.> Путь к каталогу.
<.> Дата и время создания спецификации.
<.> `/set` специальные команды, определяют некоторые настройки, полученные из проанализированных файлов.
<.> Ссылается на разобранный каталог и указывает такие параметры, как его тип, режим доступа, количество жёстких ссылок и время изменения в формате UNIX.
<.> Ссылается на файл и показывает его размер, время и список хешей для проверки целостности.

[[security-ids-verify-specification-file]]
=== Проверка файла спецификации

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

Эта команда требует начальное значение, которое использовалось для создания исходной спецификации:

[source, shell]
....
# mtree -s 123456789 -p /bin < /home/user/.bin_chksum_mtree >> /home/user/.bin_chksum_output
....

Это должно дать такую же контрольную сумму для [.filename]#/bin#, какая была получена при создании спецификации. Если в каталоге не было изменений бинарных файлов, выходной файл [.filename]#/home/user/.bin_chksum_output# будет пустым.

Для имитации изменения измените дату файла [.filename]#/bin/cat# с помощью man:touch[1] и снова выполните команду проверки:

[source, shell]
....
# touch /bin/cat
....

Выполните команду проверки ещё раз:

[source, shell]
....
# mtree -s 123456789 -p /bin < /home/user/.bin_chksum_mtree >> /home/user/.bin_chksum_output
....

И затем проверьте содержимое выходного файла:

[source, shell]
....
# cat /root/.bin_chksum_output
....

Вывод должен быть похож на следующий:

[.programlisting]
....
cat:    modification time (Fri Aug 25 13:30:17 2023, Fri Aug 25 13:34:20 2023)
....

[WARNING]
====
Это просто пример того, что будет отображено при выполнении команды, чтобы показать изменения, которые произойдут в метаданных.
====

[[security-secure-levels]]
== Уровни безопасности

securelevel — это механизм безопасности, реализованный в ядре. Когда securelevel имеет положительное значение, ядро ограничивает выполнение определённых задач; даже суперпользователь (root) не может их выполнять.

Механизм securelevel ограничивает возможность:

* Снять определённые флаги файлов, такие как `schg` (флаг системной неизменяемости).
* Записать в память ядра через [.filename]#/dev/mem# и [.filename]#/dev/kmem#.
* Загрузить модули ядра.
* Изменить правила межсетевого экрана.

[[security-secure-levels-definitions]]
=== Определения уровней безопасности

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

Определения безопасности следующие:

-1::
*Постоянный небезопасный режим* — всегда запускать систему в небезопасном режиме.
Это значение по умолчанию при начальной настройке.

0::
*Небезопасный режим* - флаги `immutable` и `append-only` могут быть отключены.
Доступ на чтение и запись всех устройств разрешён в соответствии с их правами доступа.

1::
*Безопасный режим* - флаги «только для чтения» (system immutable) и «только для дополнения» (system append-only) не могут быть отключены;
диски с смонтированными файловыми системами, [.filename]#/dev/mem# и [.filename]#/dev/kmem# не могут быть открыты для записи;
[.filename]#/dev/io# (если он есть на вашей платформе) не может быть открыт вообще; загрузка и выгрузка модулей ядра (см. man:kld[4]) запрещены.
Нельзя перейти в отладчик ядра с помощью sysctl debug.kdb.enter.
Нельзя вызвать панику или прерывание через sysctl debug.kdb.panic, debug.kdb.panic_str и другие.

2::
*Высокозащищённый режим* — аналогичен защищённому режиму, но дополнительно запрещает открывать диски на запись (за исключением man:mount[2]), независимо от того, смонтированы они или нет.
Этот уровень предотвращает изменение файловых систем путём их размонтирования, но также запрещает запуск man:newfs[8] в многопользовательском режиме.

3::
*Режим сетевой безопасности* - аналогично режиму высокой безопасности, плюс правила фильтрации IP-пакетов (см. man:ipfw[8], man:ipfirewall[4] и man:pfctl[8]) не могут быть изменены, а конфигурация man:dummynet[4] или man:pf[4] не может быть скорректирована.

[TIP]
====
Вкратце, ключевое различие между `Режимом постоянной незащищённости` и `Незащищённым режимом` в уровнях безопасности FreeBSD заключается в степени предоставляемой защиты. `Режим постоянной незащищённости` полностью снимает все ограничения безопасности, тогда как `Незащищённый режим` ослабляет некоторые ограничения, но сохраняет определённый уровень контроля и защиты.
====

[[security-modify-secure-levels]]
=== Изменение уровней безопасности

Для изменения securelevel системы необходимо активировать `kern_securelevel_enable`, выполнив следующую команду:

[source, shell]
....
# sysrc kern_securelevel_enable="YES"
....

И установите значение `kern_securelevel` на желаемый уровень безопасности:

[source, shell]
....
# sysrc kern_securelevel=2
....

Для проверки уровня безопасности (securelevel) в работающей системе выполните следующую команду:

[source, shell]
....
# sysctl -n kern.securelevel
....

Вывод содержит текущее значение уровня securelevel. Если оно больше 0, значит, включена по крайней мере часть защит securelevel.

[[security-file-flags]]
== Флаговые атрибуты файлов

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

Флаги файлов могут использоваться для достижения различных целей, таких как предотвращение удаления файла, разрешение только дополнения файла, синхронизация обновлений файлов и многое другое. Некоторые часто используемые флаги файлов в FreeBSD включают флаг "immutable", который запрещает изменение или удаление файла, и флаг "append-only", который разрешает только добавление данных в конец файла, но не их изменение или удаление.

Эти флаги можно управлять с помощью команды man:chflags[1] в FreeBSD, что предоставляет администраторам и пользователям больший контроль над поведением и характеристиками их файлов и каталогов. Важно отметить, что флаги файлов обычно управляются root или пользователями с соответствующими привилегиями, так как они могут влиять на доступ и манипуляции с файлами. Некоторые флаги доступны для использования владельцем файла, как описано в man:chflags[1].

[[security-work-file-flag]]
=== Работа с флагами файлов

В этом примере файл с именем [.filename]#~/important.txt# в домашнем каталоге пользователя необходимо защитить от удаления.

Выполните следующую команду, чтобы установить флаг файла `schg`:

[source, shell]
....
# chflags schg ~/important.txt
....

Когда любой пользователь, включая пользователя `root`, пытается удалить файл, система отобразит сообщение:

[.programlisting]
....
rm: important.txt: Operation not permitted
....

Чтобы удалить файл, необходимо сначала удалить его флаги, выполнив следующую команду:

[source, shell]
....
# chflags noschg ~/important.txt
....

Список поддерживаемых флагов файлов и их функциональность можно найти в man:chflags[1].

[[openssh]]
== OpenSSH

OpenSSH — это набор сетевых инструментов для подключения, которые используются для обеспечения безопасного доступа к удаленным машинам. Кроме того, TCP/IP-соединения могут быть туннелированы или перенаправлены через SSH-соединения с обеспечением безопасности. OpenSSH шифрует весь трафик, чтобы исключить прослушивание, перехват соединений и другие атаки на сетевом уровне.

OpenSSH разрабатывается проектом OpenBSD и устанавливается по умолчанию в FreeBSD.

Когда данные передаются по сети в незашифрованном виде, снифферы где-либо между клиентом и сервером могут украсть информацию о пользователе/пароле или данные, передаваемые во время сеанса. OpenSSH предлагает различные методы аутентификации и шифрования, чтобы предотвратить это.

Дополнительная информация о OpenSSH доступна на link:https://www.openssh.com/[веб-сайте].

В этом разделе представлен обзор встроенных клиентских утилит для безопасного доступа к другим системам и безопасной передачи файлов с системы FreeBSD. Затем описывается, как настроить SSH-сервер на системе FreeBSD.

[TIP]
====
Как уже упоминалось, в этой главе будет рассмотрена базовая версия OpenSSH. Также доступна версия OpenSSH в пакете package:security/openssh-portable[], которая предоставляет дополнительные параметры конфигурации и регулярно обновляется с новыми функциями.
====

=== Использование клиентских утилит SSH

Для входа на SSH-сервер используйте man:ssh[1], указав имя пользователя, существующее на этом сервере, и IP-адрес или имя хоста сервера. Если подключение к указанному серверу выполняется впервые, пользователю будет предложено сначала подтвердить его отпечаток:

[source, shell]
....
# ssh user@example.com
....

Вывод должен быть похож на следующий:

[.programlisting]
....
The authenticity of host 'example.com (10.0.0.1)' can't be established.
ECDSA key fingerprint is 25:cc:73:b5:b3:96:75:3d:56:19:49:d2:5c:1f:91:3b.
Are you sure you want to continue connecting (yes/no)? yes
Permanently added 'example.com' (ECDSA) to the list of known hosts.
Password for user@example.com: user_password
....

SSH использует систему отпечатков ключей для проверки подлинности сервера при подключении клиента. Когда пользователь принимает отпечаток ключа, введя `yes` при первом подключении, копия ключа сохраняется в файле [.filename]#~/.ssh/known_hosts# в домашнем каталоге пользователя. Последующие попытки входа проверяются по сохранённому ключу, и man:ssh[1] выведет предупреждение, если ключ сервера не совпадает с сохранённым. В таком случае пользователю следует сначала проверить, почему изменился ключ, прежде чем продолжать подключение.

[NOTE]
====
Как выполнить эту проверку, выходит за рамки данной главы.
====

Используйте man:scp[1] для безопасного копирования файла на удалённую машину или с неё.

Этот пример копирует файл `COPYRIGHT` на удалённой системе в файл с тем же именем в текущем каталоге локальной системы:

[source, shell]
....
# scp user@example.com:/COPYRIGHT COPYRIGHT
....

Вывод должен быть похож на следующий:

[.programlisting]
....
Password for user@example.com: *******
COPYRIGHT            100% |*****************************|  4735
....

Поскольку отпечаток этого узла уже был проверен, ключ сервера автоматически проверяется перед запросом пароля пользователя.

Аргументы, передаваемые в man:scp[1], аналогичны аргументам man:cp[1]. Первым аргументом указывается файл или файлы для копирования, а вторым — место назначения. Поскольку файл передаётся по сети, один или несколько аргументов с файлами имеют вид `user@host:<путь_к_удалённому_файлу>`. Обратите внимание, что при рекурсивном копировании каталогов man:scp[1] использует `-r`, тогда как man:cp[1] использует `-R`.

Чтобы открыть интерактивную сессию для копирования файлов, используйте man:sftp[1].

Обратитесь к man:sftp[1] для получения списка доступных команд во время сеанса man:sftp[1].

[[security-ssh-keygen]]
=== Аутентификация на основе ключей

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

man:ssh-keygen[1] можно использовать для генерации ключей аутентификации. Чтобы создать пару из открытого и закрытого ключей, укажите тип ключа и следуйте инструкциям. Рекомендуется защитить ключи запоминающейся, но трудной для угадывания парольной фразой.

[source, shell]
....
% ssh-keygen -t rsa -b 4096
....

Вывод должен быть похож на следующий:

[.programlisting]
....
Generating public/private rsa key pair.
Enter file in which to save the key (/home/user/.ssh/id_rsa):
Created directory '/home/user/.ssh/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/user/.ssh/id_rsa.
Your public key has been saved in /home/user/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:54Xm9Uvtv6H4NOo6yjP/YCfODryvUU7yWHzMqeXwhq8 user@host.example.com
The key's randomart image is:
+---[RSA 2048]----+
|                 |
|                 |
|                 |
|        . o..    |
|       .S*+*o    |
|      . O=Oo . . |
|       = Oo= oo..|
|      .oB.* +.oo.|
|       =OE**.o..=|
+----[SHA256]-----+
....

Закрытый ключ хранится в [.filename]#~/.ssh/id_rsa#, а открытый ключ — в [.filename]#~/.ssh/id_rsa.pub#. _Открытый_ ключ должен быть скопирован в файл [.filename]#~/.ssh/authorized_keys# на удалённой машине, чтобы аутентификация по ключу работала.

[WARNING]
====
Использование парольной фразы для ключей OpenSSH является важной практикой безопасности, обеспечивающей дополнительный уровень защиты от несанкционированного доступа и повышающей общую кибербезопасность.

В случае утери или кражи это добавляет дополнительный уровень защиты.
====

[[security-ssh-tunneling]]
=== Туннелирование SSH

OpenSSH обладает возможностью создания туннеля для инкапсуляции другого протокола в зашифрованном сеансе.

Следующая команда указывает man:ssh[1] создать туннель:

[source, shell]
....
% ssh -D 8080 user@example.com
....

Этот пример использует следующие параметры:

-D::
Указывает локальное "динамическое" перенаправление портов на уровне приложений.

user@foo.example.com::
Имя пользователя для входа на указанный удаленный SSH-сервер.

Туннель SSH работает путем создания сокета для прослушивания на `localhost` на указанном `localport`.

Этот метод можно использовать для защиты любого количества незащищённых TCP-протоколов, таких как SMTP, POP3 и FTP.

=== Включение сервера SSH

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

[TIP]
====
Как уже было сказано, в этой главе рассматривается базовая версия OpenSSH. *Не* путайте её с package:security/openssh-portable[], версией OpenSSH, которая поставляется с коллекцией портов FreeBSD.
====

Чтобы включить сервер SSH для автоматического запуска после перезагрузки, выполните следующую команду:

[source, shell]
....
# sysrc sshd_enable="YES"
....

Затем выполните следующую команду, чтобы включить службу:

[source, shell]
....
# service sshd start
....

При первом запуске `sshd` в системе FreeBSD автоматически создаются ключи хоста системы, и их отпечаток выводится на консоль. Предоставьте пользователям этот отпечаток, чтобы они могли проверить его при первом подключении к серверу.

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

На этом этапе `sshd` должен быть доступен всем пользователям системы, имеющим имя пользователя и пароль.

[[config-publickey-auth]]
=== Настройка метода аутентификации по открытому ключу

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

Первым шагом будет настройка man:sshd[8] для использования требуемого метода аутентификации.

Отредактируйте файл [.filename]#/etc/ssh/sshd_config# и раскомментируйте следующую настройку:

[.programlisting]
....
PubkeyAuthentication yes
....

После завершения настройки пользователям необходимо отправить системному администратору свой *открытый ключ*, и эти ключи будут добавлены в [.filename]#.ssh/authorized_keys#. Процесс генерации ключей описан в crossref:security[security-ssh-keygen,Аутентификация на основе ключей].

Затем перезапустите сервер, выполнив следующую команду:

[source, shell]
....
# service sshd reload
....

Настоятельно рекомендуется выполнить указанные улучшения безопасности, приведённые в crossref:security[security-sshd-security-options, Параметры безопасности SSH-сервера].

[[security-sshd-security-options]]
=== Параметры безопасности сервера SSH

В то время как `sshd` является наиболее широко используемым средством удалённого администрирования в FreeBSD, атаки методом грубой силы и сканирование уязвимостей распространены для любой системы, доступной из публичных сетей.

В этом разделе описаны дополнительные параметры, которые помогают предотвратить успех подобных атак. Все настройки выполняются в файле [.filename]#/etc/ssh/sshd_config#

[TIP]
====
Не путайте [.filename]#/etc/ssh/sshd_config# с [.filename]#/etc/ssh/ssh_config# (обратите внимание на дополнительную букву `d` в первом имени файла). Первый файл настраивает сервер, а второй — клиент. Список доступных настроек клиента приведён в man:ssh_config[5].
====

По умолчанию аутентификация может выполняться как по открытому ключу, так и по паролю. Чтобы разрешить *только* аутентификацию по открытому ключу, *что настоятельно рекомендуется*, измените переменную:

[.programlisting]
....
PasswordAuthentication no
....

Хорошей практикой является ограничение пользователей, которые могут подключаться к SSH-серверу, а также мест, откуда они могут это делать, с помощью ключевого слова `AllowUsers` в конфигурационном файле сервера OpenSSH. Например, чтобы разрешить вход только пользователю `user` с адреса `192.168.1.32`, добавьте следующую строку в файл [.filename]#/etc/ssh/sshd_config#:

[.programlisting]
....
AllowUsers user@192.168.1.32
....

Чтобы разрешить пользователю `user` входить из любого места, укажите этого пользователя без указания IP-адреса:

[.programlisting]
....
AllowUsers user
....

Несколько пользователей следует перечислять в одной строке, например:

[.programlisting]
....
AllowUsers root@192.168.1.32 user
....

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

[source, shell]
....
# sshd -t
....

Если файл конфигурации верен, вывод не будет отображен. В случае, если файл конфигурации содержит ошибки, будет показано примерно следующее:

[.programlisting]
....
/etc/ssh/sshd_config: line 3: Bad configuration option: sdadasdasdasads
/etc/ssh/sshd_config: terminating, 1 bad configuration options
....

После внесения изменений и проверки корректности файла конфигурации, дайте команду `sshd` перезагрузить файл конфигурации, выполнив:

[source, shell]
....
# service sshd reload
....

[[openssl]]
== OpenSSL

OpenSSL — это набор криптографических инструментов, реализующий сетевые протоколы Secure Sockets Layer (SSL) и Transport Layer Security (TLS), а также множество криптографических функций.

Программа `openssl` — это инструмент командной строки для использования различных криптографических функций криптобиблиотеки OpenSSL из оболочки. Она может быть использована для

* Создания и управления закрытыми ключами, открытыми ключами и параметрами
* Криптографических операций с открытым ключом
* Создания сертификатов X.509, запросов на подпись сертификатов (CSR) и списков отозванных сертификатов (CRL)
* Вычисления дайджестов сообщений
* Шифрования и дешифрования с использованием шифров
* Тестирования SSL/TLS клиента и сервера
* Обработки почты с подписью или шифрованием S/MIME
* Запросов, генерации и проверки временных меток
* Бенчмаркинга криптографических процедур

Для получения дополнительной информации о OpenSSL ознакомьтесь с бесплатной книгой https://www.feistyduck.com/books/openssl-cookbook/[OpenSSL Cookbook].

[[generating-certificates]]
=== Генерация сертификатов

OpenSSL поддерживает создание сертификатов как для проверки link:https://en.wikipedia.org/wiki/Certificate_authority[ЦС], так и для собственного использования.

Выполните команду man:openssl[1] для генерации действительного сертификата для link:https://en.wikipedia.org/wiki/Certificate_authority[центра сертификации (CA)] с указанными аргументами. Эта команда создаст два файла в текущем каталоге. Запрос на сертификат, [.filename]#req.pem#, можно отправить в link:https://en.wikipedia.org/wiki/Certificate_authority[центр сертификации (CA)], который проверит введённые данные, подпишет запрос и вернёт подписанный сертификат. Второй файл, [.filename]#cert.key#, является закрытым ключом для сертификата и должен храниться в безопасном месте. Если он попадёт в чужие руки, его можно использовать для выдачи себя за пользователя или сервер.

Выполните следующую команду для создания сертификата:

[source, shell]
....
# openssl req -new -nodes -out req.pem -keyout cert.key -sha3-512 -newkey rsa:4096
....

Вывод должен быть похож на следующий:

[.programlisting]
....
Generating a RSA private key
..................................................................................................................................+++++
......................................+++++
writing new private key to 'cert.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:ES
State or Province Name (full name) [Some-State]:Valencian Community
Locality Name (eg, city) []:Valencia
Organization Name (eg, company) [Internet Widgits Pty Ltd]:My Company
Organizational Unit Name (eg, section) []:Systems Administrator
Common Name (e.g. server FQDN or YOUR name) []:localhost.example.org
Email Address []:user@FreeBSD.org

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:123456789
An optional company name []:Another name
....

В качестве альтернативы, если подпись от link:https://ru.wikipedia.org/wiki/Центр_сертификации[центра сертификации] не требуется, можно создать самоподписанный сертификат. Это приведёт к созданию двух новых файлов в текущем каталоге: файла закрытого ключа [.filename]#cert.key# и самого сертификата [.filename]#cert.crt#. Эти файлы следует поместить в каталог, желательно в [.filename]#/etc/ssl/#, с доступом только для пользователя `root`. Для этих файлов подходят права доступа `0700`, которые можно установить с помощью команды `chmod`.

Выполните следующую команду для создания сертификата:

[source, shell]
....
# openssl req -new -x509 -days 365 -sha3-512 -keyout /etc/ssl/private/cert.key -out /etc/ssl/certs/cert.crt
....

Вывод должен быть похож на следующий:

[.programlisting]
....
Generating a RSA private key
........................................+++++
...........+++++
writing new private key to '/etc/ssl/private/cert.key'
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:ES
State or Province Name (full name) [Some-State]:Valencian Community
Locality Name (eg, city) []:Valencia
Organization Name (eg, company) [Internet Widgits Pty Ltd]:My Company
Organizational Unit Name (eg, section) []:Systems Administrator
Common Name (e.g. server FQDN or YOUR name) []:localhost.example.org
Email Address []:user@FreeBSD.org
....

[[fips-provider]]
=== Настройка поставщика FIPS

С внедрением OpenSSL 3 в базовую систему (на FreeBSD 14 и новее) в систему была добавлена новая концепция модулей-провайдеров. Помимо модуля по умолчанию, встроенного в библиотеку, модуль _legacy_ реализует теперь необязательные устаревшие криптографические алгоритмы, а модуль _fips_ ограничивает реализацию OpenSSL криптографическими алгоритмами, присутствующими в наборе стандартов link:https://en.wikipedia.org/wiki/Federal_Information_Processing_Standards[FIPS]. Эта часть OpenSSL получает link:https://www.openssl.org/docs/fips.html[особое внимание], включая link:https://www.openssl.org/news/fips-cve.html[список соответствующих проблем безопасности], и регулярно проходит link:https://github.com/openssl/openssl/blob/master/README-FIPS.md[процесс валидации FIPS 140]. Также доступен link:https://www.openssl.org/source/[список версий, прошедших валидацию FIPS]. Это позволяет пользователям обеспечивать соответствие FIPS при использовании OpenSSL.

Важно отметить, что модуль man:fips_module[7] защищен дополнительной мерой безопасности, предотвращающей его использование без прохождения проверки целостности. Эта проверка может быть настроена системным администратором, что позволяет каждому пользователю OpenSSL 3 загружать этот модуль. Если настройка выполнена некорректно, ожидается, что модуль FIPS завершит работу следующим образом:

[source, shell]
....
# echo test | openssl aes-128-cbc -a -provider fips -pbkdf2
....

Вывод должен быть похож на следующий:

[.programlisting]
....
aes-128-cbc: unable to load provider fips
Hint: use -provider-path option or OPENSSL_MODULES environment variable.
00206124D94D0000:error:1C8000D5:Provider routines:SELF_TEST_post:missing config data:crypto/openssl/providers/fips/self_test.c:275:
00206124D94D0000:error:1C8000E0:Provider routines:ossl_set_error_state:fips module entering error state:crypto/openssl/providers/fips/self_test.c:373:
00206124D94D0000:error:1C8000D8:Provider routines:OSSL_provider_init_int:self test post failure:crypto/openssl/providers/fips/fipsprov.c:707:
00206124D94D0000:error:078C0105:common libcrypto routines:provider_init:init fail:crypto/openssl/crypto/provider_core.c:932:name=fips
....

Проверка может быть настроена путем создания файла [.filename]#/etc/ssl/fipsmodule.cnf#, который затем будет указан в основном конфигурационном файле OpenSSL [.filename]#/etc/ssl/openssl.cnf#. OpenSSL предоставляет утилиту man:openssl-fipsinstall[1] для помощи в этом процессе, которую можно использовать следующим образом:

[source, shell]
....
# openssl fipsinstall -module /usr/lib/ossl-modules/fips.so -out /etc/ssl/fipsmodule.cnf
....

Вывод должен быть похож на следующий:

[.programlisting]
....
INSTALL PASSED
....

Файл [.filename]#/etc/ssl/openssl.cnf# затем следует изменить, чтобы:

* Включить файл [.filename]#/etc/ssl/fipsmodule.cnf#, созданный выше,
* Предоставить доступ к модулю FIPS для возможного использования,
* И явно активировать модуль по умолчанию.

[.programlisting]
....
[...]
# For FIPS
# Optionally include a file that is generated by the OpenSSL fipsinstall
# application. This file contains configuration data required by the OpenSSL
# fips provider. It contains a named section e.g. [fips_sect] which is
# referenced from the [provider_sect] below.
# Refer to the OpenSSL security policy for more information.
.include /etc/ssl/fipsmodule.cnf

[...]

# List of providers to load
[provider_sect]
default = default_sect
# The fips section name should match the section name inside the
# included fipsmodule.cnf.
fips = fips_sect

# If no providers are activated explicitly, the default one is activated implicitly.
# See man 7 OSSL_PROVIDER-default for more details.
#
# If you add a section explicitly activating any other provider(s), you most
# probably need to explicitly activate the default provider, otherwise it
# becomes unavailable in openssl.  As a consequence applications depending on
# OpenSSL may not work correctly which could lead to significant system
# problems including inability to remotely access the system.
[default_sect]
activate = 1
....

После этого можно убедиться, что модуль FIPS действительно доступен и работает:

[source, shell]
....
# echo test | openssl aes-128-cbc -a -provider fips -pbkdf2
....

Вывод должен быть похож на следующий:

[.programlisting]
....
enter AES-128-CBC encryption password:
Verifying - enter AES-128-CBC encryption password:
U2FsdGVkX18idooW6e3LqWeeiKP76kufcOUClh57j8U=
....

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

[[kerberos5]]
== Kerberos

Kerberos — это сетевой протокол аутентификации, изначально созданный Массачусетским технологическим институтом (MIT) для безопасной аутентификации в потенциально враждебной сети. Протокол Kerberos использует надёжное шифрование, позволяя как клиенту, так и серверу подтверждать свою подлинность без передачи незашифрованных секретов по сети. Kerberos можно охарактеризовать как систему проверки подлинности через посредника (прокси) и как систему аутентификации с доверенным третьим лицом. После аутентификации пользователя в Kerberos его передаваемые данные могут шифроваться для обеспечения конфиденциальности и целостности информации.

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

Текущая версия протокола — версия 5, описанная в RFC 4120. Существует несколько свободных реализаций этого протокола, охватывающих широкий спектр операционных систем. MIT продолжает развивать свой пакет Kerberos. Он широко используется в США как криптографический продукт и исторически подпадал под экспортные ограничения США. В FreeBSD MITKerberos доступен в виде пакета package:security/krb5[] или порта. Реализация Heimdal Kerberos была разработана за пределами США специально, чтобы избежать экспортных ограничений. Дистрибутив Heimdal Kerberos включён в базовую установку FreeBSD, а другая версия с более гибкими настройками доступна в коллекции портов как package:security/heimdal[].

В Kerberos пользователи и службы идентифицируются как «принципалы», которые входят в административную группу, называемую «реалмом». Типичный принципал пользователя имеет вид `_пользователь_@_РЕАЛМ_` (реалмы традиционно пишутся в верхнем регистре).

Эта часть руководства содержит инструкции по настройке Kerberos с использованием дистрибутива Heimdal, включённого в FreeBSD.

Для демонстрации установки Kerberos пространства имён будут следующими:

* Доменная зона DNS будет `example.org`.
* Realm Kerberos будет `EXAMPLE.ORG`.

[NOTE]
====
Используйте настоящие доменные имена при настройке Kerberos, даже если он будет работать внутри сети. Это позволяет избежать проблем с DNS и обеспечивает взаимодействие с другими доменами Kerberos.
====

=== Настройка Heimdal KDC

Центр распределения ключей (Key Distribution Center — KDC) — это централизованная служба аутентификации, предоставляемая Kerberos, «доверенная третья сторона» системы. Это компьютер, который выдает билеты Kerberos, используемые клиентами для аутентификации на серверах. Поскольку KDC считается доверенным для всех остальных компьютеров в области Kerberos, к нему предъявляются повышенные требования безопасности. Прямой доступ к KDC должен быть ограничен.

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

Для начала установите пакет package:security/heimdal[] следующим образом:

[source, shell]
....
# pkg install heimdal
....

Далее обновите [.filename]#/etc/rc.conf# с помощью `sysrc` следующим образом:

[source, shell]
....
# sysrc kdc_enable=yes
# sysrc kadmind_enable=yes
....

Далее отредактируйте файл [.filename]#/etc/krb5.conf# следующим образом:

[.programlisting]
....
[libdefaults]
    default_realm = EXAMPLE.ORG
[realms]
    EXAMPLE.ORG = {
	kdc = kerberos.example.org
	admin_server = kerberos.example.org
    }
[domain_realm]
    .example.org = EXAMPLE.ORG
....

В этом примере KDC будет использовать полное доменное имя `kerberos.example.org`. Имя хоста KDC должно разрешаться в DNS.

Kerberos также может использовать DNS для поиска KDC вместо раздела `[realms]` в [.filename]#/etc/krb5.conf#. Для крупных организаций, имеющих собственные DNS-серверы, приведённый выше пример можно сократить до:

[.programlisting]
....
[libdefaults]
      default_realm = EXAMPLE.ORG
[domain_realm]
    .example.org = EXAMPLE.ORG
....

Со следующими строками, включёнными в файл зоны `example.org`:

[.programlisting]
....
_kerberos._udp      IN  SRV     01 00 88 kerberos.example.org.
_kerberos._tcp      IN  SRV     01 00 88 kerberos.example.org.
_kpasswd._udp       IN  SRV     01 00 464 kerberos.example.org.
_kerberos-adm._tcp  IN  SRV     01 00 749 kerberos.example.org.
_kerberos           IN  TXT     EXAMPLE.ORG
....

[NOTE]
====
Чтобы клиенты могли найти службы Kerberos, они _должны_ иметь либо полностью настроенный файл [.filename]#/etc/krb5.conf#, либо минимально настроенный [.filename]#/etc/krb5.conf# _и_ правильно настроенный DNS-сервер.
====

Далее создайте базу данных Kerberos, которая содержит ключи всех принципалов (пользователей и хостов), зашифрованные мастер-паролем. Нет необходимости запоминать этот пароль, так как он будет храниться в [.filename]#/var/heimdal/m-key#; разумно использовать для этого случайный пароль длиной 45 символов. Чтобы создать мастер-ключ, выполните `kstash` и введите пароль:

[source, shell]
....
# kstash
....

Вывод должен быть похож на следующий:

[.programlisting]
....
Master key: xxxxxxxxxxxxxxxxxxxxxxx
Verifying password - Master key: xxxxxxxxxxxxxxxxxxxxxxx
....

После создания мастер-ключа следует инициализировать базу данных. Утилита администрирования Kerberos man:kadmin[8] может быть использована на KDC в режиме, который работает напрямую с базой данных, без использования сетевого сервиса man:kadmind[8], как `kadmin -l`. Это решает проблему курицы и яйца, когда попытка подключения к базе данных происходит до её создания. В командной строке `kadmin` используйте `init` для создания начальной базы данных realm:

[source, shell]
....
# kadmin -l
kadmin> init EXAMPLE.ORG
Realm max ticket life [unlimited]:
....

Наконец, оставаясь в `kadmin`, создайте первый принципал с помощью команды `add`. Пока придерживайтесь стандартных настроек для принципала, так как их можно изменить позже с помощью команды `modify`. Введите `?` в командной строке, чтобы увидеть доступные опции.

[source, shell]
....
kadmin> add tillman
....

Вывод должен быть похож на следующий:

[.programlisting]
....
Max ticket life [unlimited]:
Max renewable life [unlimited]:
Principal expiration time [never]:
Password expiration time [never]:
Attributes []:
Password: xxxxxxxx
Verifying password - Password: xxxxxxxx
....

Далее запустите службы KDC, выполнив:

[source, shell]
....
# service kdc start
# service kadmind start
....

Хотя на этом этапе не будет запущено никаких сервисов с поддержкой Kerberos, можно убедиться, что KDC функционирует, получив билет для только что созданного принципала:

[source, shell]
....
% kinit tillman
....

Вывод должен быть похож на следующий:

[.programlisting]
....
tillman@EXAMPLE.ORG's Password:
....

Подтвердите успешное получение билета с помощью `klist`:

[source, shell]
....
% klist
....

Вывод должен быть похож на следующий:

[.programlisting]
....
Credentials cache: FILE:/tmp/krb5cc_1001
	Principal: tillman@EXAMPLE.ORG

  Issued                Expires               Principal
Aug 27 15:37:58 2013  Aug 28 01:37:58 2013  krbtgt/EXAMPLE.ORG@EXAMPLE.ORG
....

Временный билет можно уничтожить после завершения теста:

[source, shell]
....
% kdestroy
....

=== Настройка сервера для использования Kerberos

Первым шагом в настройке сервера для использования аутентификации Kerberos является проверка правильности конфигурации в файле [.filename]#/etc/krb5.conf#. Версию с KDC можно использовать как есть или пересоздать на новой системе.

Затем создайте файл [.filename]#/etc/krb5.keytab# на сервере. Это основная часть процесса "керберизации" службы — она соответствует созданию общего секрета между службой и KDC. Секрет представляет собой криптографический ключ, хранящийся в "keytab". Keytab содержит хост-ключ сервера, который позволяет ему и KDC проверять подлинность друг друга. Этот файл должен быть передан на сервер безопасным способом, так как если ключ станет общедоступным, безопасность сервера может быть нарушена. Обычно [.filename]#keytab# генерируется на доверенной машине администратора с помощью `kadmin`, а затем безопасно передаётся на сервер, например, с помощью man:scp[1]; его также можно создать непосредственно на сервере, если это соответствует выбранной политике безопасности. Очень важно, чтобы keytab был передан на сервер безопасным способом: если ключ станет известен третьей стороне, эта сторона сможет выдавать себя за любого пользователя на сервере! Использование `kadmin` непосредственно на сервере удобно, так как запись для хостового принципала в базе данных KDC также создается с помощью `kadmin`.

Конечно, `kadmin` — это керберизованный сервис; для аутентификации в сетевой службе необходим билет Kerberos, но чтобы убедиться, что пользователь, запускающий `kadmin`, действительно присутствует (и его сеанс не был захвачен), `kadmin` запросит пароль для получения нового билета. Учётная запись, аутентифицирующаяся в службе kadmin, должна иметь разрешение на использование интерфейса `kadmin`, как указано в [.filename]#/var/heimdal/kadmind.acl#. Подробнее о создании списков контроля доступа см. в разделе «Удалённое администрирование» в `info heimdal`. Вместо включения удалённого доступа к `kadmin` администратор может безопасно подключиться к KDC через локальную консоль или man:ssh[1] и выполнять администрирование локально с помощью `kadmin -l`.

После установки [.filename]#/etc/krb5.conf# используйте `add --random-key` в `kadmin`. Это добавит главный серверный принципал в базу данных, но не извлечет копию ключа главного принципала в keytab. Чтобы сгенерировать keytab, используйте `ext` для извлечения ключа главного серверного принципала в его собственный keytab:

[source, shell]
....
# kadmin
....

Вывод должен быть похож на следующий:

[.programlisting]
....
kadmin> add --random-key host/myserver.example.org
Max ticket life [unlimited]:
Max renewable life [unlimited]:
Principal expiration time [never]:
Password expiration time [never]:
Attributes []:
kadmin> ext_keytab host/myserver.example.org
kadmin> exit
....

Обратите внимание, что `ext_keytab` по умолчанию сохраняет извлечённый ключ в [.filename]#/etc/krb5.keytab#. Это удобно при выполнении на сервере, который керберизируется, но следует использовать аргумент `--keytab _путь/к/файлу_`, когда извлечение keytab происходит на другом устройстве:

[source, shell]
....
# kadmin
....

Вывод должен быть похож на следующий:

[.programlisting]
....
kadmin> ext_keytab --keytab=/tmp/example.keytab host/myserver.example.org
kadmin> exit
....

Затем файл keytab можно безопасно скопировать на сервер с помощью man:scp[1] или съемного носителя. Убедитесь, что указано нестандартное имя keytab, чтобы избежать добавления ненужных ключей в системный keytab.

На этом этапе сервер может читать зашифрованные сообщения от KDC, используя свой общий ключ, хранящийся в [.filename]#krb5.keytab#. Теперь он готов к включению служб, использующих Kerberos. Одна из самых распространённых таких служб — man:sshd[8], которая поддерживает Kerberos через GSS-API. В файле [.filename]#/etc/ssh/sshd_config# добавьте строку:

[.programlisting]
....
GSSAPIAuthentication yes
....

После внесения этого изменения необходимо перезапустить `man:sshd[8]`, чтобы новая конфигурация вступила в силу: `service sshd restart`.

=== Настройка клиента для использования Kerberos

Как и для сервера, клиенту требуется настройка в [.filename]#/etc/krb5.conf#. Скопируйте файл (безопасным способом) или введите его заново при необходимости.

Проверьте клиент, используя `kinit`, `klist` и `kdestroy` на клиенте, чтобы получить, отобразить, а затем удалить билет для существующего принципала. Приложения Kerberos также должны иметь возможность подключаться к серверам с поддержкой Kerberos. Если это не работает, но получение билета проходит успешно, проблема, скорее всего, на стороне сервера, а не клиента или KDC. В случае с kerberized man:ssh[1], GSS-API по умолчанию отключен, поэтому проверьте с помощью `ssh -o GSSAPIAuthentication=yes _имя_хоста_`.

При тестировании приложения с поддержкой Kerberos попробуйте использовать анализатор трафика, например `tcpdump`, чтобы убедиться, что конфиденциальная информация не передаётся в открытом виде.

Доступны различные клиентские приложения Kerberos. С появлением моста, позволяющего приложениям, использующим SASL для аутентификации, также применять механизмы GSS-API, широкий спектр клиентских приложений — от клиентов Jabber до клиентов IMAP — может использовать Kerberos для аутентификации.

Пользователи в пределах realm обычно имеют свой Kerberos-принципал, сопоставленный с локальной учётной записью. Иногда необходимо предоставить доступ к локальной учётной записи пользователю, у которого нет соответствующего Kerberos-принципала. Например, `tillman@EXAMPLE.ORG` может потребоваться доступ к локальной учётной записи `webdevelopers`. Другие принципалы также могут нуждаться в доступе к этой локальной учётной записи.

Файлы [.filename]#.k5login# и [.filename]#.k5users#, размещённые в домашнем каталоге пользователя, могут быть использованы для решения этой проблемы. Например, если следующий [.filename]#.k5login# поместить в домашний каталог пользователя `webdevelopers`, оба указанных принципала получат доступ к этой учётной записи без необходимости использования общего пароля:

[.programlisting]
....
tillman@example.org
jdoe@example.org
....

Обратитесь к man:ksu[1] для получения дополнительной информации о [.filename]#.k5users#.

=== Различия MIT

Основное различие между реализациями MIT и Heimdal заключается в том, что `kadmin` имеет разные, но эквивалентные наборы команд и использует разные протоколы. Если KDC — MIT, то версия `kadmin` от Heimdal не может использоваться для удалённого администрирования KDC, и наоборот.

Клиентские приложения также могут использовать немного другие параметры командной строки для выполнения тех же задач. Рекомендуется следовать инструкциям на сайте http://web.mit.edu/Kerberos/www/[http://web.mit.edu/Kerberos/www/]. Обратите внимание на пути: порт MIT по умолчанию устанавливается в [.filename]#/usr/local/#, а системные приложения FreeBSD будут запускаться вместо версий MIT, если `PATH` указывает на системные каталоги в первую очередь.

При использовании MIT Kerberos в качестве KDC на FreeBSD выполните следующие команды, чтобы добавить необходимые конфигурации в [.filename]#/etc/rc.conf#:

[source, shell]
....
# sysrc kdc_program="/usr/local/sbin/krb5kdc"
# sysrc kadmind_program="/usr/local/sbin/kadmind"
# sysrc kdc_flags=""
# sysrc kdc_enable="YES"
# sysrc kadmind_enable="YES"
....

=== Советы, хитрости и устранение неполадок Kerberos

При настройке и устранении неполадок Kerberos учитывайте следующие моменты:

* При использовании Heimdal или MITKerberos из портов убедитесь, что в `PATH` версии клиентских приложений из портов указаны перед системными версиями.
* Если временные настройки всех компьютеров в домене не синхронизированы, аутентификация может завершиться неудачей. crossref:network-servers[network-ntp,“Синхронизация часов с помощью NTP”] описывает, как синхронизировать часы с использованием NTP.
* Если имя хоста изменено, необходимо изменить принципал `host/` и обновить keytab. Это также относится к особым записям keytab, таким как принципал `HTTP/`, используемый для пакета Apache package:www/mod_auth_kerb[].
* Все узлы в области должны разрешаться как в прямом, так и в обратном направлении через DNS или, как минимум, присутствовать в [.filename]#/etc/hosts#. CNAME-записи будут работать, но A- и PTR-записи должны быть корректными и присутствовать. Сообщение об ошибке для неразрешимых узлов неочевидно: `Kerberos5 refuses authentication because Read req failed: Key table entry not found`.
* Некоторые операционные системы, выступающие в роли клиентов KDC, не устанавливают для `ksu` права setuid `root`. Это означает, что `ksu` не работает. Это проблема прав доступа, а не ошибка KDC.
* С использованием MITKerberos, чтобы разрешить принципалу иметь билет сроком действия больше стандартных десяти часов, используйте `modify_principal` в командной строке man:kadmin[8], чтобы изменить `maxlife` как для нужного принципала, так и для принципала `krbtgt`. После этого принципал может использовать `kinit -l` для запроса билета с увеличенным сроком действия.
* При запуске сниффера пакетов на KDC для устранения неполадок во время выполнения `kinit` с рабочей станции, билет на получение билетов (TGT) отправляется немедленно, даже до ввода пароля. Это происходит потому, что сервер Kerberos свободно передаёт TGT на любой неавторизованный запрос. Однако каждый TGT зашифрован с использованием ключа, производного от пароля пользователя. Когда пользователь вводит свой пароль, он не отправляется на KDC, а вместо этого используется для расшифровки TGT, который `kinit` уже получил. Если процесс расшифровки приводит к действительному билету с корректной временной меткой, пользователь получает действительные учётные данные Kerberos. Эти учётные данные включают в себя сеансовый ключ для установления безопасного соединения с сервером Kerberos в будущем, а также сам TGT, зашифрованный собственным ключом сервера Kerberos. Этот второй уровень шифрования позволяет серверу Kerberos проверять подлинность каждого TGT.
* Принципалы хостов могут иметь более длительное время жизни билета. Если принципал пользователя имеет время жизни в неделю, а у хоста, к которому происходит подключение, время жизни составляет девять часов, кэш пользователя будет содержать просроченный принципал хоста, и кэш билетов не будет работать должным образом.
* При настройке файла [.filename]#krb5.dict# для запрета использования определённых слабых паролей, как описано в man:kadmind[8], помните, что он применяется только к принципалам, для которых назначена политика паролей. Формат файла [.filename]#krb5.dict# предполагает одну строку на каждую запись. Может быть полезно создать символическую ссылку на [.filename]#/usr/share/dict/words#.

=== Смягчение ограничений Kerberos

Поскольку Kerberos — это подход «всё или ничего», каждая служба, включённая в сети, должна быть либо изменена для работы с Kerberos, либо защищена от сетевых атак другим способом. Это необходимо для предотвращения кражи и повторного использования учётных данных пользователей. Например, если Kerberos включён для всех удалённых оболочек, но не поддерживающий Kerberos POP3-сервер передаёт пароли в открытом виде.

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

Скомпрометированный мастер-ключ не так страшен, как может показаться. Мастер-ключ используется только для шифрования базы данных Kerberos и в качестве затравки для генератора случайных чисел. Пока доступ к KDC защищен, злоумышленник не сможет сделать многое с мастер-ключом.

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

Kerberos позволяет пользователям, хостам и службам аутентифицироваться между собой. Однако у него нет механизма для аутентификации KDC перед пользователями, хостами или службами. Это означает, что троянская версия `kinit` может записывать все имена пользователей и пароли. Инструменты проверки целостности файловой системы, такие как package:security/tripwire[], могут помочь смягчить эту проблему.

=== Ресурсы и дополнительная информация

* http://www.faqs.org/faqs/Kerberos-faq/general/preamble.html[Часто задаваемые вопросы Kerberos]
* http://web.mit.edu/Kerberos/www/dialogue.html[Проектирование системы аутентификации: диалог в четырёх сценах]
* https://www.ietf.org/rfc/rfc4120.txt[RFC 4120, The Kerberos Network Authentication Service (V5)]
* http://web.mit.edu/Kerberos/www/[Домашняя страница MIT Kerberos]
* https://github.com/heimdal/heimdal/wiki[Wiki страница проекта Heimdal Kerberos]

[[tcpwrappers]]
== TCP Wrappers

TCP Wrappers — это система контроля сетевого доступа на основе хоста. Перехватывая входящие сетевые запросы до их поступления к реальному сетевому сервису, TCP Wrappers определяет, разрешен или запрещен доступ для исходного IP-адреса, на основе предопределённых правил в конфигурационных файлах.

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

[[tcpwrappers-initial-configuration]]
=== Начальная настройка

TCP Wrappers включены по умолчанию в man:inetd[8]. Первым шагом будет включение man:inetd[8] выполнением следующих команд:

[source, shell]
....
# sysrc inetd_enable="YES"
# service inetd start
....

Затем правильно настройте [.filename]#/etc/hosts.allow#.

[WARNING]
====
В отличие от других реализаций TCP Wrappers, использование [.filename]#hosts.deny# в FreeBSD считается устаревшим. Все параметры конфигурации должны размещаться в [.filename]#/etc/hosts.allow#.
====

В простейшей конфигурации политики подключения к демонам устанавливаются на разрешение или блокировку в зависимости от параметров в [.filename]#/etc/hosts.allow#. Конфигурация по умолчанию в FreeBSD разрешает все подключения к демонам, запущенным через inetd.

Базовая конфигурация обычно имеет вид `daemon : address : action`, где `daemon` — это демон, запущенный inetd, `address` — допустимое имя хоста, IP-адрес или адрес IPv6, заключённый в квадратные скобки ([ ]), а `action` — либо `allow`, либо `deny`. TCP Wrappers использует семантику первого совпадения, то есть файл конфигурации сканируется с начала до первого совпадающего правила. При обнаружении совпадения правило применяется, и процесс поиска прекращается.

Например, чтобы разрешить соединения POP3 через демон package:mail/qpopper[], в файл [.filename]#/etc/hosts.allow# следует добавить следующие строки:

[.programlisting]
....
# This line is required for POP3 connections:
qpopper : ALL : allow
....

Всякий раз, когда редактируется этот файл, перезапустите inetd:

[source, shell]
....
# service inetd restart
....

[[tcpwrappers-advanced-config]]
=== Расширенная настройка

TCP Wrappers предоставляет расширенные возможности для более тонкого управления обработкой соединений. В некоторых случаях может быть уместно отправить сообщение определённым хостам или демонам при подключении. В других ситуациях может потребоваться сделать запись в журнал или отправить письмо администратору. Также бывают случаи, когда сервис должен быть доступен только для локальных соединений. Всё это возможно благодаря использованию параметров конфигурации, известных как шаблоны (wildcards), символы подстановки и выполнение внешних команд. Для получения дополнительной информации о шаблонах и связанной с ними функциональности обратитесь к man:hosts_access[5].

[[fs-acl]]
== Списки контроля доступа

Списки контроля доступа (Access Control Lists — ACL) расширяют традиционные права доступа UNIX(R), позволяя детально управлять доступом пользователей и групп к отдельным файлам или каталогам. Каждая запись ACL определяет пользователя или группу и связанные с ними права, такие как чтение, запись и выполнение. FreeBSD предоставляет команды, такие как man:getfacl[1] и man:setfacl[1], для управления ACL.

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

[NOTE]
====
FreeBSD поддерживает реализацию NFSv4 ACL как в UFS, так и в OpenZFS. Обратите внимание, что некоторые аргументы команды man:setfacl[1] работают только с POSIX ACL, а другие — с NFSv4 ACL.
====

[[acl-enabling-support-ufs]]
=== Включение поддержки ACL в UFS

ACL включаются с помощью административного флага при монтировании `acls`, который может быть добавлен в [.filename]#/etc/fstab#.

Следовательно, необходимо получить доступ к [.filename]#/etc/fstab# и в разделе опций добавить флаг `acls` следующим образом:

[.programlisting]
....
# Device        Mountpoint        FStype    Options     Dump      Pass#
/dev/ada0s1a    /                 ufs       rw,acls     1         1
....

[[security-acl-info]]
=== Получение информации об ACL

Можно проверить ACL файла или каталога с помощью man:getfacl[1].

Например, чтобы просмотреть настройки ACL для файла [.filename]#~/test#, выполните следующую команду:

[source, shell]
....
% getfacl test
....

Вывод должен быть похож на следующий в случае использования NFSv4 ACL:

[.programlisting]
....
# file: test
# owner: freebsduser
# group: freebsduser
            owner@:rw-p--aARWcCos:-------:allow
            group@:r-----a-R-c--s:-------:allow
         everyone@:r-----a-R-c--s:-------:allow
....

И вывод должен быть похож на следующий в случае использования POSIX.1e ACL:

[.programlisting]
....
# file: test
# owner: freebsduser
# group: freebsduser
user::rw-
group::r--
other::r--
....

[[security-working-acls]]
=== Работа с ACL

`man:setfacl[1]` можно использовать для добавления, изменения или удаления ACL из файла или каталога.

Как упоминалось выше, некоторые аргументы man:setfacl[1] не работают с ACL NFSv4, и наоборот. В этом разделе описывается, как выполнять команды для POSIX ACL и для ACL NFSv4, а также приводятся примеры для обоих типов.

Например, чтобы установить обязательные элементы ACL по умолчанию POSIX.1e:

[source, shell]
....
% setfacl -d -m u::rwx,g::rx,o::rx,mask::rwx directory
....

Этот другой пример устанавливает права на чтение, запись и выполнение для записи POSIX.1e ACL владельца файла, а также права на чтение и запись для группы mail в файле:

[source, shell]
....
% setfacl -m u::rwx,g:mail:rw file
....

Чтобы сделать то же самое, что и в предыдущем примере, но с использованием ACL NFSv4:

[source, shell]
....
% setfacl -m owner@:rwxp::allow,g:mail:rwp::allow file
....

Чтобы удалить все записи ACL, кроме трёх обязательных, из файла в POSIX.1e ACL:

[source, shell]
....
% setfacl -bn file
....

Чтобы удалить все записи ACL в NFSv4 ACL:

[source, shell]
....
% setfacl -b file
....

Обратитесь к man:getfacl[1] и man:setfacl[1] для получения дополнительной информации о доступных опциях этих команд.

[[capsicum]]
== Capsicum

Capsicum — это легковесная платформа возможностей ОС и песочницы, реализующая гибридную модель системы возможностей. Возможности (capabilities) являются не подделываемыми токенами авторизации, которые могут быть делегированы и должны быть предъявлены для выполнения действия. Capsicum преобразует файловые дескрипторы в возможности.

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

[[security-accounting]]
== Учёт процессов

Учёт процессов — это метод безопасности, при помощи которого администратор может отслеживать использование системных ресурсов и их распределение между пользователями, обеспечивать мониторинг системы и минимально фиксировать выполняемые пользователями команды.

Учёт процессов имеет как положительные, так и отрицательные стороны. Один из плюсов заключается в том, что вторжение может быть локализовано до точки входа. Минус — это объём журналов, генерируемых учётом процессов, и дисковое пространство, которое они могут занять. В этом разделе рассматриваются основы учёта процессов для администратора.

[NOTE]
====
Если требуется более детальный учёт, обратитесь к разделу crossref:audit[audit,Аудит событий безопасности].
====

=== Включение и использование учёта процессов

Прежде чем использовать учёт процессов, его необходимо включить с помощью следующих команд:

[source, shell]
....
# sysrc accounting_enable=yes
# service accounting start
....

Информация учёта хранится в файлах, расположенных в [.filename]#/var/account#, который автоматически создаётся при необходимости при первом запуске службы учёта. Эти файлы содержат конфиденциальную информацию, включая все команды, выполненные всеми пользователями. Право записи в файлы ограничено для `root`, а право чтения — для `root` и членов группы `wheel`. Чтобы также запретить членам `wheel` читать эти файлы, измените режим доступа к каталогу [.filename]#/var/account#, разрешив доступ только для `root`.

После включения учёт начнёт собирать информацию, такую как статистика использования CPU и выполненные команды. Все журналы учёта хранятся в нечитаемом формате, который можно просмотреть с помощью man:sa[8]. Если команда запущена без параметров, man:sa[8] выводит информацию о количестве вызовов для каждого пользователя, общем затраченном времени в минутах, общем времени CPU и пользователя в минутах, а также среднем количестве операций ввода-вывода. Полный список доступных параметров, управляющих выводом, смотрите в man:sa[8].

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

Например, эта команда выводит все случаи использования `ls` пользователем `trhodes` на терминале `ttyp1`:

[source, shell]
....
# lastcomm ls trhodes ttyp1
....

Существует множество других полезных опций, которые описаны в man:lastcomm[1], man:acct[5] и man:sa[8].

[[security-resourcelimits]]
== Ограничения ресурсов

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

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

Традиционный метод определения классов входа в систему предполагает редактирование файла [.filename]#/etc/login.conf#. Хотя этот метод по-прежнему поддерживается, любые изменения требуют многоэтапного процесса: правки этого файла, пересборки базы данных ресурсов, внесения необходимых изменений в [.filename]#/etc/master.passwd# и пересборки базы данных паролей. Это может быть затратным по времени в зависимости от количества настраиваемых пользователей.

man:rctl[8] может использоваться для более детального управления ограничениями ресурсов. Эта команда поддерживает не только пользовательские ограничения, так как также может применяться для установки ограничений ресурсов на процессы и jail.

Этот раздел демонстрирует оба метода управления ресурсами, начиная с традиционного метода.

[[security-resource-limits-types]]
=== Типы ресурсов

FreeBSD устанавливает ограничения для различных типов ресурсов, включая:

.Типы ресурсов
[options="header", cols="1,1"]
|===
| Тип | Описание

| Время процессора
| Ограничивает количество процессорного времени, которое может использовать процесс

| Память
| Управляет количеством физической памяти, которое может использовать процесс

| Открытые файлы
| Ограничивает количество файлов, которые процесс может открыть одновременно

| Процессы
| Управляет количеством процессов, которые пользователь или процесс может создать

| Размер файла
| Ограничивает максимальный размер файлов, которые процесс может создать

| Дампы памяти
| Управляет возможностью процессов создавать файлы дампа памяти

| Сетевые ресурсы
| Ограничивает количество сетевых ресурсов (например, сокетов), которые может использовать процесс

|===

Для полного списка типов см. man:login.conf[5] и man:rctl[8].

[[users-limiting]]
=== Настройка классов входа

В традиционном методе классы входа и ограничения ресурсов, применяемые к классу входа, определяются в файле [.filename]#/etc/login.conf#. Каждой учётной записи пользователя может быть назначен класс входа, где `default` является классом входа по умолчанию. Каждый класс входа имеет набор связанных с ним возможностей входа. Возможность входа — это пара `_имя_=_значение_`, где _имя_ — это общеизвестный идентификатор, а _значение_ — произвольная строка, которая обрабатывается соответствующим образом в зависимости от _имени_.

Первым шагом для настройки ограничения ресурсов будет открытие файла [.filename]#/etc/login.conf# с помощью следующей команды:

[source, shell]
....
# ee /etc/login.conf
....

Затем найдите раздел для изменяемого класса пользователей. В этом примере предположим, что класс пользователей называется `limited`; создайте его, если он не существует.

[.programlisting]
....
limited:\ <.>
        :maxproc=50:\ <.>
        :tc=default: <.>
....

<.> Имя класса пользователя.
<.> Устанавливает максимальное количество процессов (maxproc) равным 50 для пользователей в классе `limited`.
<.> Указывает, что этот класс пользователя наследует настройки по умолчанию из класса "default".

После изменения файла [.filename]#/etc/login.conf# выполните команду man:cap_mkdb[1] для создания базы данных, которую FreeBSD использует для применения этих настроек:

[source, shell]
....
# cap_mkdb /etc/login.conf
....

man:chpass[1] может быть использован для изменения класса пользователя на желаемый, выполнив следующую команду:

[source, shell]
....
# chpass username
....

Это откроет текстовый редактор, где нужно добавить новый класс `limited` следующим образом:

[.programlisting]
....
#Changing user information for username.
Login: username
Password: $6$2H.419USdGaiJeqK$6kgcTnDadasdasd3YnlNZsOni5AMymibkAfRCPirc7ZFjjv
DVsKyXx26daabdfqSdasdsmL/ZMUpdHiO0
Uid [#]: 1001
Gid [# or name]: 1001
Change [month day year]:
Expire [month day year]:
Class: limited
Home directory: /home/username
Shell: /bin/sh
Full Name: User &
Office Location:
Office Phone:
Home Phone:
Other information:
....

Теперь пользователь, назначенный классу `limited`, будет иметь ограничение на максимальное количество процессов в 50. Помните, что это лишь один пример настройки ограничения ресурсов с помощью файла [.filename]#/etc/login.conf#.

Имейте в виду, что после внесения изменений в файл [.filename]#/etc/login.conf# пользователю необходимо выйти из системы и снова войти, чтобы изменения вступили в силу. Кроме того, всегда соблюдайте осторожность при редактировании системных конфигурационных файлов, особенно при использовании привилегированного доступа.

[[security-rctl]]
=== Включение и настройка ограничений ресурсов

Система man:rctl[8] предоставляет более детализированный способ установки и управления ограничениями ресурсов для отдельных процессов и пользователей. Она позволяет динамически назначать ограничения ресурсов конкретным процессам или пользователям, независимо от их класса.

Первым шагом для использования man:rctl[8] будет его включение путем добавления следующей строки в [.filename]#/boot/loader.conf# и перезагрузки системы:

[.programlisting]
....
kern.racct.enable=1
....

Затем включите и запустите службу man:rctl[8], выполнив следующие команды:

[source, shell]
....
# sysrc rctl_enable="YES"
# service rctl start
....

Затем man:rctl[8] может быть использован для установки правил в системе.

Синтаксис правил (man:rctl.conf[5]) определяется с использованием субъекта, идентификатора субъекта, ресурса и действия, как показано в следующем примере правила:

[.programlisting]
....
subject:subject-id:resource:action=amount/per
....

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

[source, shell]
....
# rctl -a user:username:maxproc:deny=10/user
....

Для проверки установленных ограничений ресурсов можно выполнить команду man:rctl[8]:

[source, shell]
....
# rctl
....

Вывод должен быть похож на следующий:

[.programlisting]
....
user:username:maxproc:deny=10
....

Правила сохранятся после перезагрузки, если они добавлены в [.filename]#/etc/rctl.conf#. Формат записи — это правило без указания команды в начале. Например, предыдущее правило можно добавить так:

[.programlisting]
....
user:username:maxproc:deny=10
....

[[security-pkg]]
== Мониторинг проблем безопасности приложений сторонних разработчиков

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

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

pkg опрашивает базу данных на наличие уязвимостей безопасности. База данных обновляется и поддерживается командой FreeBSD Security Team и разработчиками портов.

Установка предоставляет файлы конфигурации man:periodic[8] для поддержания базы данных pkg audit и предлагает программный метод её обновления.

После установки, а также для проверки сторонних утилит из Коллекции портов в любое время, администратор может обновить базу данных и просмотреть известные уязвимости установленных пакетов, выполнив:

[source, shell]
....
% pkg audit -F
....

Вывод должен быть похож на следующий:

[.programlisting]
....
vulnxml file up-to-date
chromium-116.0.5845.96_1 is vulnerable:
  chromium -- multiple vulnerabilities
  CVE: CVE-2023-4431
  CVE: CVE-2023-4427
  CVE: CVE-2023-4428
  CVE: CVE-2023-4429
  CVE: CVE-2023-4430
  WWW: https://vuxml.FreeBSD.org/freebsd/5fa332b9-4269-11ee-8290-a8a1599412c6.html

samba413-4.13.17_5 is vulnerable:
  samba -- multiple vulnerabilities
  CVE: CVE-2023-3347
  CVE: CVE-2023-34966
  CVE: CVE-2023-34968
  CVE: CVE-2022-2127
  CVE: CVE-2023-34967
  WWW: https://vuxml.FreeBSD.org/freebsd/441e1e1a-27a5-11ee-a156-080027f5fec9.html

2 problem(s) in 2 installed package(s) found.
....

Направив веб-браузер по указанному URL, администратор может получить дополнительную информацию об уязвимости.

Это будет включать затронутые версии, указанные по версии порта FreeBSD, а также другие веб-сайты, которые могут содержать рекомендации по безопасности.

[[security-advisories]]
== Рекомендации по безопасности FreeBSD

Как и многие разработчики качественных операционных систем, проект FreeBSD имеет команду безопасности, которая отвечает за определение даты окончания срока службы (EoL) для каждого выпуска FreeBSD и предоставляет обновления безопасности для поддерживаемых выпусков, которые ещё не достигли своего EoL. Дополнительная информация о команде безопасности FreeBSD и поддерживаемых выпусках доступна на странице link:https://www.FreeBSD.org/security[безопасности FreeBSD].

Одна из задач команды безопасности — реагировать на сообщения об уязвимостях в операционной системе FreeBSD. После подтверждения уязвимости команда безопасности проверяет шаги, необходимые для её устранения, и обновляет исходный код с исправлением. Затем она публикует подробности в виде «Рекомендации по безопасности» (Security Advisory). Рекомендации по безопасности публикуются на сайте link:https://www.FreeBSD.org/security/advisories/[FreeBSD] и рассылаются в списки рассылки {freebsd-security-notifications}, {freebsd-security} и {freebsd-announce}.

=== Формат рекомендации по безопасности

Вот пример рекомендации по безопасности FreeBSD:

[.programlisting]
....
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

=============================================================================
FreeBSD-SA-23:07.bhyve                                      Security Advisory
                                                          The FreeBSD Project

Topic:          bhyve privileged guest escape via fwctl

Category:       core
Module:         bhyve
Announced:      2023-08-01
Credits:        Omri Ben Bassat and Vladimir Eli Tokarev from Microsoft
Affects:        FreeBSD 13.1 and 13.2
Corrected:      2023-08-01 19:48:53 UTC (stable/13, 13.2-STABLE)
                2023-08-01 19:50:47 UTC (releng/13.2, 13.2-RELEASE-p2)
                2023-08-01 19:48:26 UTC (releng/13.1, 13.1-RELEASE-p9)
CVE Name:       CVE-2023-3494

For general information regarding FreeBSD Security Advisories,
including descriptions of the fields above, security branches, and the
following sections, please visit <URL:https://security.FreeBSD.org/>.

I.   Background

bhyve(8)'s fwctl interface provides a mechanism through which guest
firmware can query the hypervisor for information about the virtual
machine.  The fwctl interface is available to guests when bhyve is run
with the "-l bootrom" option, used for example when booting guests in
UEFI mode.

bhyve is currently only supported on the amd64 platform.

II.  Problem Description

The fwctl driver implements a state machine which is executed when the
guest accesses certain x86 I/O ports.  The interface lets the guest copy
a string into a buffer resident in the bhyve process' memory.  A bug in
the state machine implementation can result in a buffer overflowing when
copying this string.

III. Impact

A malicious, privileged software running in a guest VM can exploit the
buffer overflow to achieve code execution on the host in the bhyve
userspace process, which typically runs as root.  Note that bhyve runs
in a Capsicum sandbox, so malicious code is constrained by the
capabilities available to the bhyve process.

IV.  Workaround

No workaround is available.  bhyve guests that are executed without the
"-l bootrom" option are unaffected.

V.   Solution

Upgrade your vulnerable system to a supported FreeBSD stable or
release / security branch (releng) dated after the correction date.

Perform one of the following:

1) To update your vulnerable system via a binary patch:

Systems running a RELEASE version of FreeBSD on the amd64, i386, or
(on FreeBSD 13 and later) arm64 platforms can be updated via the
freebsd-update(8) utility:

# freebsd-update fetch
# freebsd-update install

Restart all affected virtual machines.

2) To update your vulnerable system via a source code patch:

The following patches have been verified to apply to the applicable
FreeBSD release branches.

a) Download the relevant patch from the location below, and verify the
detached PGP signature using your PGP utility.

[FreeBSD 13.2]
# fetch https://security.FreeBSD.org/patches/SA-23:07/bhyve.13.2.patch
# fetch https://security.FreeBSD.org/patches/SA-23:07/bhyve.13.2.patch.asc
# gpg --verify bhyve.13.2.patch.asc

[FreeBSD 13.1]
# fetch https://security.FreeBSD.org/patches/SA-23:07/bhyve.13.1.patch
# fetch https://security.FreeBSD.org/patches/SA-23:07/bhyve.13.1.patch.asc
# gpg --verify bhyve.13.1.patch.asc

b) Apply the patch.  Execute the following commands as root:

# cd /usr/src
# patch < /path/to/patch

c) Recompile the operating system using buildworld and installworld as
described in <URL:https://www.FreeBSD.org/handbook/makeworld.html>.

Restart all affected virtual machines.

VI.  Correction details

This issue is corrected by the corresponding Git commit hash or Subversion
revision number in the following stable and release branches:

Branch/path                             Hash                     Revision
- -------------------------------------------------------------------------
stable/13/                              9fe302d78109    stable/13-n255918
releng/13.2/                            2bae613e0da3  releng/13.2-n254625
releng/13.1/                            87702e38a4b4  releng/13.1-n250190
- -------------------------------------------------------------------------

Run the following command to see which files were modified by a
particular commit:

# git show --stat <commit hash>

Or visit the following URL, replacing NNNNNN with the hash:

<URL:https://cgit.freebsd.org/src/commit/?id=NNNNNN>

To determine the commit count in a working tree (for comparison against
nNNNNNN in the table above), run:

# git rev-list --count --first-parent HEAD

VII. References

<URL:https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-3494>

The latest revision of this advisory is available at
<URL:https://security.FreeBSD.org/advisories/FreeBSD-SA-23:07.bhyve.asc>
-----BEGIN PGP SIGNATURE-----

iQIzBAEBCgAdFiEEthUnfoEIffdcgYM7bljekB8AGu8FAmTJdsIACgkQbljekB8A
Gu8Q1Q/7BFw5Aa0cFxBzbdz+O5NAImj58MvKS6xw61bXcYr12jchyT6ENC7yiR+K
qCqbe5TssRbtZ1gg/94gSGEXccz5OcJGxW+qozhcdPUh2L2nzBPkMCrclrYJfTtM
cnmQKjg/wFZLUVr71GEM95ZFaktlZdXyXx9Z8eBzow5rXexpl1TTHQQ2kZZ41K4K
KFhup91dzGCIj02cqbl+1h5BrXJe3s/oNJt5JKIh/GBh5THQu9n6AywQYl18HtjV
fMb1qRTAS9WbiEP5QV2eEuOG86ucuhytqnEN5MnXJ2rLSjfb9izs9HzLo3ggy7yb
hN3tlbfIPjMEwYexieuoyP3rzKkLeYfLXqJU4zKCRnIbBIkMRy4mcFkfcYmI+MhF
NPh2R9kccemppKXeDhKJurH0vsetr8ti+AwOZ3pgO21+9w+mjE+EfaedIi+JWhip
hwqeFv03bAQHJdacNYGV47NsJ91CY4ZgWC3ZOzBZ2Y5SDtKFjyc0bf83WTfU9A/0
drC0z3xaJribah9e6k5d7lmZ7L6aHCbQ70+aayuAEZQLr/N1doB0smNi0IHdrtY0
JdIqmVX+d1ihVhJ05prC460AS/Kolqiaysun1igxR+ZnctE9Xdo1BlLEbYu2KjT4
LpWvSuhRMSQaYkJU72SodQc0FM5mqqNN42Vx+X4EutOfvQuRGlI=
=MlAY
-----END PGP SIGNATURE-----
....

Каждый бюллетень безопасности использует следующий формат:

* Каждое уведомление о безопасности подписано PGP-ключом офицера безопасности. Открытый ключ офицера безопасности можно проверить в crossref:pgpkeys[pgpkeys,OpenPGP Keys].
* Название рекомендации по безопасности всегда начинается с `FreeBSD-SA-` (для FreeBSD Security Advisory), за которым следует год в двузначном формате (`23:`), затем номер рекомендации за этот год (`07.`), а затем название затронутого приложения или подсистемы (`bhyve`).
* Поле `Topic` содержит краткое описание уязвимости.
* `Category` относится к затронутой части системы, которая может быть одной из следующих: `core`, `contrib` или `ports`. Категория `core` означает, что уязвимость затрагивает основной компонент операционной системы FreeBSD. Категория `contrib` означает, что уязвимость затрагивает программное обеспечение, включённое в состав FreeBSD, например BIND. Категория `ports` указывает, что уязвимость затрагивает программное обеспечение, доступное через Коллекцию портов.
* Поле `Module` указывает на расположение компонента. В данном примере затронут модуль `bhyve`; следовательно, эта уязвимость затрагивает приложение, установленное вместе с операционной системой.
* Поле `Announced` указывает дату публикации уведомления о безопасности. Это означает, что команда безопасности подтвердила наличие проблемы и что исправление было добавлено в репозиторий исходного кода FreeBSD.
* Поле `Credits` указывает на человека или организацию, которые обнаружили уязвимость и сообщили о ней.
* Поле `Affects` указывает, какие выпуски FreeBSD подвержены данной уязвимости.
* Поле `Corrected` указывает дату, время, смещение времени и версии, в которых была исправлена ошибка. Раздел в скобках показывает каждую ветку, в которую было внесено исправление, и номер версии соответствующего выпуска из этой ветки. Идентификатор выпуска включает номер версии и, если необходимо, уровень патча. Уровень патча обозначается буквой `p` с последующим числом, указывающим порядковый номер патча, что позволяет пользователям отслеживать, какие патчи уже были применены к системе.
* Поле `CVE Name` содержит номер рекомендации, если он существует, в публичной базе данных уязвимостей безопасности http://cve.mitre.org[cve.mitre.org].
* Поле `Background` содержит описание затронутого модуля.
* Поле `Описание проблемы` поясняет уязвимость. Оно может содержать информацию о проблемном коде и о том, как утилита может быть использована злоумышленниками.
* Поле `Impact` описывает, какой тип воздействия проблема может оказать на систему.
* Поле `Workaround` указывает, доступно ли временное решение для системных администраторов, которые не могут немедленно установить исправление.
* Поле `Solution` содержит инструкции по исправлению уязвимости на затронутой системе. Это пошаговый проверенный метод, позволяющий обновить систему и обеспечить её безопасную работу.
* Поле `Correction Details` отображает каждую затронутую ветку Subversion или Git с номером ревизии, содержащей исправленный код.
* Поле `References` содержит источники дополнительной информации об уязвимости.
