[ English | English (United Kingdom) | Deutsch | русский ]

Настройки безопасности

Данный раздел содержит информацию о настройке определенных параметров безопасности вашего облака OpenStack-Ansible.

Для понимания принципов безопасности обратитесь к Security.

[ English | English (United Kingdom) | Deutsch | русский ]

Защита сервисов при помощи SSL сертификатов

Инструкция по безопасности OpenStack рекомендует использовать защищенное соединение между различными сервисами в окружении OpenStack. Проект OpenStack-Ansible в данный момент предоставляет возможность настройки SSL сертификатов для безопасного взаимодействия между сервисами:

Все публичные точки доступа находятся за HAProxy, в результате чего единственным управлением сертификатами для внешне видимых https-сервисов являются те, что для HAProxy. Некоторые внутренние сервисы, такие как RabbitMQ, также требуют надлежащей конфигурации SSL.

Во время развертывания с OpenStack-Ansible вы можете либо использовать самоподписанные сертификаты, которые будут сгенерированы во время процесса развертывания, либо предоставить SSL сертификаты, ключи и промежуточные сертификаты для вашего доверенного центра сертификации. Высокозащищенные окружения используют доверенные сертификаты, предоставленные пользователями, для максимально возможного количества сервисов.

Примечание

Выполните все настройки SSL сертификатов в файле /etc/openstack_deploy/user_variables.yml. Не редактируйте роли или плейбуки самостоятельно для этого.

OpenStack-Ansible использует роль ansible ansible_role_pki в качестве общего инструмента для управления и установки самоподписанных и предоставленных пользователями сертификатов.

Примечание

Примеры конфигураций OpenStack-Ansible разработаны как минимальные примеры и в тестовых или разрабатываемых сценариях использования установят external_lb_vip_address на IP-адрес внешней точки доступа HAProxy. Для рабочего развертывания рекомендуется установить external_lb_vip_address на полное доменное имя, которое разрешается через DNS в IP внешней точки доступа.

Самоподписанные сертификаты

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

Самоподписанные сертификаты могут играть важную роль в обеспечении безопасности внутренних служб в рамках развертывания OpenStack-Ansible, поскольку они могут быть выпущены только частным CA, связанным с развертыванием. Использование взаимного TLS между внутренними службами, такими как RabbitMQ и MariaDB, с самоподписанными сертификатами и надежной настройкой CA может гарантировать, что только правильно аутентифицированные клиенты смогут подключаться к этим внутренним службам.

Создание и восстановление самоподписанных центров сертификации

Самоподписанный центр сертификации создается на хосте развертывания во время первого запуска сценария.

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

# openstack-ansible -e "openstack_pki_regen_ca=ExampleCorpIntermediate" certificate-authority.yml

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

Генерация и регенерация самоподписанных сертификатов

Самоподписанные сертификаты генерируются для каждого сервиса во время первого запуска плейбука.

Чтобы повторно создать новый самоподписанный сертификат для службы, необходимо установить переменную <servicename>_pki_regen_cert в значение true одним из следующих способов:

  • Для принудительного обновления самоподписанного сертификата, вы можете передать переменную openstack-ansible в командной строке:

    # openstack-ansible -e "haproxy_pki_regen_cert=true" haproxy-install.yml
    
  • Чтобы заставить самоподписанный сертификат регенерироваться при каждом запуске playbook, установите соответствующий параметр регенерации в true. Например, если вы уже запустили playbook haproxy, но хотите регенерировать самоподписанный сертификат, установите переменную haproxy_pki_regen_cert в true в файле /etc/openstack_deploy/user_variables.yml:

    haproxy_pki_regen_cert: true
    

Генерация и повторная генерация самоподписанных сертификатов пользователей

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

Для генерации пользовательских сертификатов определите переменную с префиксом user_pki_certificates_ в файле /etc/openstack_deploy/user_variables.yml.

Пример

user_pki_certificates_example:
   - name: "example"
     provider: ownca
     cn: "example.com"
     san: "DNS:example.com,IP:x.x.x.x"
     signed_by: "{{ openstack_pki_service_intermediate_cert_name }}"
     key_usage:
       - digitalSignature
       - keyAgreement
     extended_key_usage:
       - serverAuth

Сгенерируйте сертификат с помощью следующей команды:

# openstack-ansible certificate-generate.yml

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

  • Для принудительного обновления самоподписанного сертификата, вы можете передать переменную openstack-ansible в командной строке:

    # openstack-ansible -e "user_pki_regen_cert=true" certificate-generate.yml
    
  • Чтобы принудительно регенерировать самоподписанный сертификат при каждом запуске сценария, установите для переменной user_pki_regen_cert значение true в файле /etc/openstack_deploy/user_variables.yml:

    user_pki_regen_cert: true
    

Сертификаты, предоставленные пользователем

Для большего доверия в высоконадежных окружениях, вы можете предоставить собственный SSL сертификат, ключи и промежуточные сертификаты. Получение сертификатов из доверенного центра сертификации находится за пределами данного документа, но раздел Управление Сертификатами Linux Documentation Project объясняет как создать свой собственный центр сертификации и подписывать сертификаты.

Используйте следующий подход для установки собственных SSL сертификатов в OpenStack-Ansible:

  1. Скопируйте ваш SSL сертификат, ключ и промежуточные сертификаты на хост развертывания.

  2. Укажите путь к вашему SSL сертификату, ключу и промежуточным сертификатам в файле /etc/openstack_deploy/user_variables.yml.

  3. Запустите плейбуки для этого сервиса.

Пример HAProxy

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

haproxy_user_ssl_cert: /etc/openstack_deploy/ssl/example.com.crt
haproxy_user_ssl_key: /etc/openstack_deploy/ssl/example.com.key
haproxy_user_ssl_ca_cert: /etc/openstack_deploy/ssl/ExampleCA.crt

Пример RabbitMQ

Для установки определенных пользователем сертификатов на RabbitMQ, скопируйте сертификаты на хост развертывания, отредактируйте файл /etc/openstack_deploy/user_variables.yml и задайте следующие переменные:

rabbitmq_user_ssl_cert:    /etc/openstack_deploy/ssl/example.com.crt
rabbitmq_user_ssl_key:     /etc/openstack_deploy/ssl/example.com.key
rabbitmq_user_ssl_ca_cert: /etc/openstack_deploy/ssl/ExampleCA.crt

Потом запустите плейбук для применения сертификатов:

# openstack-ansible rabbitmq-install.yml

Плейбук установит предоставленный вами SSL сертификат, ключ и промежуточные сертификаты на каждый контейнер RabbitMQ.

Процесс идентичен для остальных сервисов. Замените префикс rabbitmq в переменной на horizon, haproxy или keystone, а после запустите плейбук для данного сервиса для разливки предоставленного сертификата на данные сервисы.

Сертификаты Certbot

Роль HAProxy ansible поддерживает использование certbot для автоматического развертывания доверенных сертификатов SSL для публичной точки доступа. Каждый сервер HAProxy будет индивидуально запрашивать сертификат SSL с помощью certbot.

По умолчанию Certbot использует Let’s Encrypt в качестве центра сертификации. Другие центры сертификации можно использовать, установив переменную haproxy_ssl_letsencrypt_certbot_server в файле /etc/openstack_deploy/user_variables.yml:

haproxy_ssl_letsencrypt_certbot_server: "https://acme-staging-v02.api.letsencrypt.org/directory"

Запрос типа http-01 используется certbot для развертывания сертификатов, поэтому необходимо, чтобы публичная точка доступа была доступна напрямую центру сертификации.

Развертывание сертификатов с использованием Let’s Encrypt было проверено для Openstack-Ansible с использованием Ubuntu 22.04 (Jammy Jellyfish). Другие дистрибутивы должны работать, но не тестировались.

Чтобы развернуть сертификаты с помощью certbot, добавьте следующее в /etc/openstack_deploy/user_variables.yml, чтобы включить функцию certbot в роли HAProxy ansible, а также создать новую внутреннюю службу с именем certbot для обслуживания запросов http-01.

haproxy_ssl: true
haproxy_ssl_letsencrypt_enable: True
haproxy_ssl_letsencrypt_email: "email.address@example.com"

TLS для внутреннего VIP HAProxy

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

По умолчанию OpenStack-Ansible не защищает соединения с внутренним VIP. Чтобы включить это, необходимо задать следующие переменные в файле /etc/openstack_deploy/user_variables.yml:

openstack_service_adminuri_proto: https
openstack_service_internaluri_proto: https

haproxy_ssl_all_vips: true

Запустите все сценарии для настройки служб HAProxy и OpenStack.

При включении HAProxy будет использовать один и тот же сертификат TLS на всех интерфейсах (внутренних и внешних). В настоящее время в OpenStack-Ansible невозможно использовать различные самоподписанные или предоставленные пользователем сертификаты TLS на различных интерфейсах HAProxy.

Единственный способ использовать разные сертификаты TLS на внутреннем и внешнем VIP — это использовать certbot.

Включение TLS на внутреннем VIP для существующих развертываний приведет к некоторому простою, это связано с тем, что HAProxy прослушивает только один известный порт для каждой службы OpenStack, а службы OpenStack настроены на использование http или https. Это означает, что после обновления HAProxy для приема только HTTPS-соединений службы OpenStack перестанут работать, пока они не будут обновлены для использования HTTPS.

Чтобы избежать простоя, рекомендуется включить openstack_service_accept_both_protocols, пока все службы не будут настроены правильно. Это позволяет фронтендам HAProxy прослушивать как HTTP, так и HTTPS.

TLS для бекэндов HAProxy

Связь между HAProxy и бекэндами сервисов может быть зашифрована. В настоящее время по умолчанию она отключена. Ее можно включить для всех сервисов, установив следующую переменную:

openstack_service_backend_ssl: True

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

keystone_backend_ssl: True
neutron_backend_ssl: True

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

TLS для живых миграций

Живая миграция виртуальных машин с использованием SSH устарела, и OpenStack Nova Docs рекомендует использовать более безопасный собственный метод TLS, поддерживаемый QEMU. Метод живой миграции по умолчанию, используемый OpenStack-Ansible, был обновлен для использования миграций TLS.

Для использования нативного протокола TLS в QEMU требуется, чтобы все вычислительные хосты принимали TCP-подключения на порту 16514 и в диапазоне портов 49152–49261.

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

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

Чтобы принудительно использовать SSH вместо TLS для живых миграций, необходимо установить переменную nova_libvirtd_listen_tls в 0 в файле /etc/openstack_deploy/user_variables.yml:

nova_libvirtd_listen_tls: 0

TLS для VNC

При использовании VNC для доступа к консоли необходимо защитить 3 соединения: клиент к HAProxy, HAProxy к noVNC Proxy и noVNC Proxy к вычислительным узлам. В OpenStack Nova Docs for remote console access безопасность консоли рассматривается гораздо более подробно.

В OpenStack-Ansible TLS для HAProxy настроен в HAProxy, TLS от HAProxy до noVNC в настоящее время не включен, а TLS от nVNC до вычислительных узлов включен по умолчанию.

Изменения не будут применяться к существующим запущенным гостевым ОС на вычислительном узле, поэтому эту настройку следует выполнить до запуска любых инстансов. Для существующих развертываний рекомендуется перенести инстансы с вычислительного узла перед включением.

Чтобы помочь с переходом от незашифрованного VNC к VeNCrypt, изначально схема аутентификации прокси noVNC допускает как зашифрованные, так и незашифрованные сеансы с использованием переменной nova_vencrypt_auth_scheme. Это будет ограничено VeNCrypt только в будущих версиях OpenStack-Ansible.

nova_vencrypt_auth_scheme: "vencrypt,none"

Чтобы не шифровать данные из прокси-сервера noVNC на вычислительные узлы, необходимо установить переменную nova_qemu_vnc_tls в 0 в файле /etc/openstack_deploy/user_variables.yml:

nova_qemu_vnc_tls: 0

[ English | English (United Kingdom) | Deutsch | русский ]

Заголовки безопасности

Заголовки безопасности — это HTTP-заголовки, которые можно использовать для повышения безопасности веб-приложения путем ограничения того, что современные браузеры могут запускать.

В OpenStack-Ansible заголовки безопасности реализованы в HAProxy, поскольку все публичные точки доступа находятся за ним.

Следующие заголовки включены по умолчанию на всех интерфейсах HAProxy, которые реализуют TLS, но только для службы Horizon. Заголовки безопасности могут быть реализованы на других службах HAProxy, но только службы, используемые браузерами, будут использовать заголовки.

HTTP Strict Transport Security

` Гид по безопасности OpenStack TLS`_ советует всем окружениям в промышленном использовании использовать HTTP Strict Transport Security (HSTS).

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

Чтобы изменить максимальный возраст по умолчанию на 1 день, переопределите переменную haproxy_security_headers_max_age в файле /etc/openstack_deploy/user_variables.yml:

haproxy_security_headers_max_age: 86400

Если вы хотите, чтобы ваш домен был включен в список предварительной загрузки HSTS, встроенный в браузеры, перед отправкой запроса на добавление в список предварительной загрузки HSTS вы должны добавить токен preload в заголовок ответа. Токен preload указывает тем, кто поддерживает список предварительной загрузки HSTS, что вы согласны включить туда свой сайт.

- "http-response set-header Strict-Transport-Security \"max-age={{ haproxy_security_headers_max_age }}; includeSubDomains; preload;\""

X-Content-Type-Options

Заголовок X-Content-Type-Options предотвращает перехват типа MIME.

Эту функциональность можно изменить, переопределив список заголовков в переменной haproxy_security_headers в файле /etc/openstack_deploy/user_variables.yml.

Referrer политика

Заголовок Referrer-Policy контролирует, сколько информации о реферере отправляется с запросами. По умолчанию он равен same-origin, что не отправляет путь источника для запросов кросс-источника.

Эту функциональность можно изменить, переопределив список заголовков в переменной haproxy_security_headers в файле /etc/openstack_deploy/user_variables.yml.

Политика предоставления разрешений

Заголовок Permissions-Policy позволяет выборочно включать, отключать или изменять использование функций браузера и API, ранее известный как Feature Policy.

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

Эту функциональность можно изменить, переопределив список заголовков в переменной haproxy_security_headers в файле /etc/openstack_deploy/user_variables.yml.

Content Security Policy (CSP)

Заголовок Content-Security-Policy позволяет контролировать, какие ресурсы браузеру разрешено загружать для определенной страницы, что помогает снизить риски, связанные с межсайтовым скриптингом (XSS) и атаками с внедрением данных.

По умолчанию политика безопасности контента (CSP) включает минимальный набор ресурсов, позволяющий Horizon работать, включая доступ к консоли Nova. Если вам требуется доступ к другим ресурсам, их можно задать, переопределив переменную haproxy_security_headers_csp в файле /etc/openstack_deploy/user_variables.yml.

Report Only

Реализация CSP может привести к повреждению контента, если браузеру будет заблокирован доступ к определенным ресурсам, поэтому при тестировании CSP рекомендуется использовать заголовок Content-Security-Policy-Report-Only вместо Content-Security-Policy. Это сообщает о нарушениях CSP в консоль браузера, но не обеспечивает соблюдение политики.

Чтобы настроить политику CSP на создание отчетов только путем переопределения переменной haproxy_security_headers_csp_report_only на True в файле /etc/openstack_deploy/user_variables.yml:

haproxy_security_headers_csp_report_only: True

Сообщение о нарушениях

Рекомендуется отслеживать попытки нарушения CSP в рабочей среде. Это достигается путем установки токенов report-uri и report-to.

Федеративный вход

При использовании федеративного входа вам потребуется переопределить политику безопасности контента по умолчанию, чтобы разрешить доступ к вашему серверу авторизации, переопределив переменную haproxy_horizon_csp в файле /etc/openstack_deploy/user_variables.yml:

haproxy_horizon_csp: >
  http-response set-header Content-Security-Policy "
  default-src 'self';
  frame-ancestors 'self';
  form-action 'self' {{ external_lb_vip_address }}:5000 <YOUR-AUTHORISATION-SERVER-ORIGIN>;
  upgrade-insecure-requests;
  style-src 'self' 'unsafe-inline';
  script-src 'self' 'unsafe-inline' 'unsafe-eval';
  child-src 'self' {{ external_lb_vip_address }}:{{ nova_spice_html5proxy_base_port }} {{ external_lb_vip_address }}:{{ nova_novncproxy_port }} {{ external_lb_vip_address }}:{{ nova_serialconsoleproxy_port }};
  frame-src 'self' {{ external_lb_vip_address }}:{{ nova_spice_html5proxy_base_port }} {{ external_lb_vip_address }}:{{ nova_novncproxy_port }} {{ external_lb_vip_address }}:{{ nova_serialconsoleproxy_port }};
  "

Также можно установить специальные заголовки безопасности для Skyline.

haproxy_skyline_csp: ...

[ English | English (United Kingdom) | Deutsch | русский ]

security.txt

security.txt — это предложенный стандарт IETF, позволяющий независимым исследователям безопасности легко сообщать об уязвимостях. Стандарт определяет, что текстовый файл с именем security.txt должен находиться по адресу «/.well-known/security.txt». Для совместимости с устаревшими версиями файл также может находиться по адресу «/security.txt».

В OpenStack-Ansible security.txt реализован в HAProxy, поскольку все публичные точки доступа находятся за ним. По умолчанию он направляет любые пути запросов, которые заканчиваются на /security.txt, в текстовый файл с использованием правила ACL в HAProxy.

Включение security.txt

Используйте следующий процесс для добавления файла security.txt в ваше развертывание с помощью OpenStack-Ansible:

  1. Запишите содержимое файла security.txt в соответствии со стандартом.

  2. Определите содержимое security.txt в переменной haproxy_security_txt_content в файле /etc/openstack_deploy/user_variables.yml:

haproxy_security_txt_content: |
    # This is my example security.txt file
    # Please see https://securitytxt.org/ for details of the specification of this file
  1. Обновите HAProxy

# openstack-ansible haproxy-install.yml

Расширенный security.txt ACL

В некоторых случаях вам может потребоваться изменить ACL HAProxy, используемый для перенаправления запросов в файл security.txt, например, добавить дополнительные домены.

Список контроля доступа HAProxy обновляется путем переопределения переменной haproxy_map_entries внутри haproxy_security_txt_service.

[ English | English (United Kingdom) | Deutsch | русский ]

Применение ansible-hardening

Роль ansible-hardening применима к физическим хостам любого типа внутри развертывания OpenStack-Ansible - как инфраструктурного, так и вычислительного. По умолчанию роль включена. Вы можете выключить ее установив значение переменной apply_security_hardening в файле user_variables.yml в false:

apply_security_hardening: false

Вы можете применить настройки усиления безопасности к существующему окружению или провести аудит окружения при помощи предоставляемого OpenStack-Ansible-ом плейбука:

# Apply security hardening configurations
  openstack-ansible security-hardening.yml

# Perform a quick audit by using Ansible's check mode
  openstack-ansible --check security-hardening.yml

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

[ English | English (United Kingdom) | Deutsch | русский ]

Запуск от имени пользователя без прав root

Операторам не нужно использовать учетные записи пользователя root на хостах развертывания или целевых хостах. Этот подход работает из коробки, используя Ansible privilege escalation.

Хосты развертывания

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

  1. Склонируйте репозиторий OpenStack-Ansible в домашний каталог пользователя. Это значит, что вместо /opt/openstack-ansible репозиторий будет в ~/openstack-ansible.

  2. Используйте произвольный путь для каталога /etc/openstack_deploy. Вы можете разместить каталог конфигурации OpenStack-Ansible внутри домашнего каталога пользователя. Для этого вам нужно будет определить следующую переменную среды:

    export OSA_CONFIG_DIR="${HOME}/openstack_deploy"
    
  3. Если вы хотите сохранить базовое ведение журнала ansible, вам нужно либо создать каталог /openstack/log/ansible-logging/ и разрешить пользователю писать в него, либо определить следующую переменную среды:

    export ANSIBLE_LOG_PATH="${HOME}/ansible-logging/ansible.log"
    

    Примечание

    Вы также можете добавить переменную среды в файл user.rc внутри папки openstack_deploy (${OSA_CONFIG_DIR}/user.rc). Файл user.rc создается каждый раз при запуске бинарного файла openstack-ansible.

  4. Первоначальную загрузку OpenStack-Ansible с использованием скрипта ./scripts/bootstrap-ansible.sh по-прежнему следует выполнять либо от имени пользователя root, либо повысить привилегии с помощью sudo или su.

Хосты назначения

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

Примечание

Вы можете добавить переменные среды из этого раздела в файл user.rc внутри папки openstack_deploy (${OSA_CONFIG_DIR}/user.rc). Файл user.rc создается каждый раз при запуске бинарного файла openstack-ansible.

Есть еще несколько дополнительных вещей, которые вам, возможно, стоит учесть:

  1. Предоставляйте флаг --become каждый раз, когда вы запускаете playbook или ad-hoc команду. В качестве альтернативы вы можете определить следующую переменную окружения:

    export ANSIBLE_BECOME="True"
    
  2. Переопределите временный путь Ansible, если используются контейнеры LXC. Соединение Ansible от физического хоста к контейнеру LXC передает переменные среды с хоста. Это означает, что Ansible пытается использовать ту же временную папку в контейнере LXC, что и на хосте, относительно каталога пользователя без прав root ${HOME}. Он не будет существовать внутри контейнера, и вместо него должен быть использован другой путь.

    Вы можете сделать это различными способами:

    1. Задайте ansible_remote_tmp: /tmp в user_variables.yml

    2. Определите следующую переменную окружения:

    export ANSIBLE_LOCAL_TEMP="/tmp"
    
  3. Определите пользователя, который будет использоваться для подключений от хоста развертывания к целевым хостам ansible. Если пользователь один и тот же для всех хостов в вашем развертывании, вы можете сделать это одним из следующих способов:

    1. Определите ansible_user: <USER> в user_variables.yml

    2. Определите следующую переменную окружения:

    export ANSIBLE_REMOTE_USER="<USER>"
    

    Если пользователь отличается от хоста к хосту, вы можете использовать group_vars или host_vars. Более подробную информацию о том, как это использовать, можно найти в Руководстве по переопределениям