SSH
далек от совершенства, но он был разработан с учетом безопасности, и на
протяжении многих лет было написано огромное количество инструментов для
облегчения его использования. Кроме того, большинство популярного софта
комплектуются SSH.
Он поддерживается практически во всех архитектурах и дистрибутивах, начиная от Raspberry Pi и заканчивая массивными суперкомпьютерными
кластерами.
Сертификаты
Вы наверняка согласитесь с тем, что аутентификация с открытым ключом лучше, чем использование
паролей. Не приходится вводить пароль, никто его не взломает и не подсмотрит через плечо.
Следующий
уровень секьюрности после ключей – SSH-сертификаты, которые поддерживаются с OpenSSH
5.4, выпущенного ещё в 2010 году.
С помощью
SSH-сертификатов вы создаете центр сертификации (CA), а затем используете его
для выдачи и криптографической подписи, которая аутентифицирует пользователей.
Вы можете создать пару ключей, например, с помощью команды ssh-keygen
:
Файл
host_ca
является закрытым ключом центра сертификации хоста и должен храниться в
защищенном месте. Не выдавайте его никому, не копируйте куда-либо и убедитесь,
что как можно меньше людей имеют к нему доступ. В идеале он «живет» на
машине, которая не допускает прямого доступа, и все сертификаты выдаются автоматически.
Рекомендуется использовать два отдельных CA – один для
подписания сертификатов хостов, другой для пользователей. Одни и те же процессы не будут добавлять и хосты, и юзеров. А если закрытый
ключ скомпрометируют, нужно будет лишь пересоздать сертификаты для хостов
или пользователей, а не оба сразу.
Вот так создается
user_ca
:
Файл
user_ca
– закрытый ключ пользователя, который должен быть защищен, как и закрытый
ключ хоста.
Выдача
сертификатов хостам
Создадим новый ключ и подпишем с помощью центра сертификации.
Вот описание
используемых флагов:
- -s host_ca: указывает имя файла закрытого CA-ключа, используемого для подписи.
- -I host.example.com: буквенно-цифровая строка, идентифицирующая сервер. При необходимости значение можно использовать для отзыва сертификата.
- -h: указывает, что сертификат выдается хосту, а не юзеру.
- -n host.example.com: указывает разделенный запятыми список участников, для проверки подлинности которых будет действителен сертификат.
- -V +52w: срок действия сертификата. В данном случае 52 недели (один год). По умолчанию сертификаты действительны вечно. Указание периода истечения срока действия сертификатов хоста настоятельно рекомендуется для ротации и замены сертификатов.
Настройка
SSH для использования сертификатов
Нужно указать серверу, чтобы он использовал новый сертификат. Скопируйте три сгенерированных файла на сервер в каталог /etc/ssh
,
установите разрешения и добавьте в файл /etc/ssh/sshd_config
следующую строку:
Перезагрузите sshd с помощью systemctl restart sshd
. Теперь сервер
настроен на выдачу сертификата. Чтобы локальный ssh-клиент мог автоматически
доверять хосту на основе удостоверения сертификата, нужно добавить открытый ключ
CA в known_hosts
. Вы можете
сделать это, добавив в начало файла host_ca.pub
следующее: @cert-authority
, а затем и в
*.example.com~/.ssh/known_hosts
:
Значение
*.example.com
указывает на то, что этому сертификату следует доверять для
идентификации любого хоста, к которому вы подключаетесь и который имеет домен
*.example.com
. Это разделенный запятыми список имен хостов для сертификата: host1,
host2, host3 или 1.2.3.4, 1.2.3.5 в зависимости от обстоятельств.
Как
только закончите настройку, удалите все старые записи для host.example.com
в ~/.ssh/known_hosts
и запустите подключение. Правильность создания сертификата проверяется так:
На этом
этапе вы можете продолжить выдачу сертификатов всех хостов, используя центр сертификации. Польза от этого следующая: вам больше не нужно полагаться
на небезопасную модель Trust On First Use (TOFU) для новых хостов, и если вы
когда-нибудь повторно развернете сервер и, следовательно, измените ключ хоста, новый хост автоматически представит подписанный сертификат без ужасного предупреждения: WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!
Выдача
сертификатов пользователям (для аутентификации пользователей на хостах)
В этом
примере мы создадим новый ключ пользователя и подпишем с помощью центра сертификации.
user-key-cert.pub
содержит подписанный сертификат пользователя. Для входа в систему понадобится как этот, так и приватный ключ. Вот описание
используемых флагов:
- -s user_ca: указывает приватный ключ CA, используемый для подписи.
- -I tatooine@proglib.io: буквенно-цифровая строка, которая будет видна в логе SSH. Для точной идентификации пользователя рекомендуем использовать адрес электронной почты или логин.
- -n palpatine, tatooine: указывает разделенный запятыми список участников, для проверки подлинности которых будет действителен сертификат. В примере мы предоставляем сертификат доступа как для
palpatine
, так и дляtatooine
. - -V +1d: указывает срок действия сертификата, в данном случае +1d означает 1 день.
Если нужно увидеть параметры подписи сертификата,
используйте ssh-keygen -L
:
Настройка
SSH для проверки подлинности
После
того как сертификат подписан, нужно сообщить серверу, что можно доверять пользователским сертификатам. Копируем user_ca.pub
в директорию /etc/ssh
, поправляем права и добавляем в конфиг /etc/ssh/sshd_config
строку:
Как раньше, перезагружаем sshd с помощью systemctl restart sshd
. Теперь
сервер настроен на пропуск всех, кто представляет сертификат, выданный центром сертификации при подключении. Если сертификат хранится в том же
каталоге, что и ваш приватый ключ (указанный с флагом -i
, например ssh -i
/home/tatooine/user-keypalpatine @proglib.io
),
он будет автоматически использоваться при подключении к серверам.
Проcмотр логов
Если вы
посмотрите в журнал sshd сервера, запустив journalctl -u sshd
, то увидите имя используемого для аутентификации сертификата, а также данные центра сертификации:
Если
пользователь попытается войти в систему под логином, у которого нет доступа, в логе вы увидите такую ошибку:
Если срок
действия сертификата истек, вы увидите следующую ошибку:
В
качестве домашнего задания напишите скрипт, который будет использовать центр сертификации для выдачи сертификатов, действительных в течение следующих
двух часов. Каждое использование этого скрипта должно журналировать того, кто
запросил сертификат и его почту, а потом встраивать этот email в сертификат. Это поможет в
мониторинге.
Взгляните
на man ssh-keygen
для новых идей.
Использование
SSH
Bastion Host
Еще один
способ повысить безопасность SSH – принудительно использовать bastion-хост – ssh-шлюз, служащий единственной точкой входа
в инфраструктуру. Уменьшение вероятности любой потенциальной поверхности атаки
за счет использования файерволов позволяет лучше следить за тем, кто к чему
обращается.
Переход к
использованию такого метода не должен быть трудной задачей, особенно если вы уже
применяете сертификаты. Все настройки совершаются через локальный конфиг:
~/.ssh/config
.
Вот
пример принудительного использования SSH-доступа к любому хосту в домене
example.com, который будет перенаправлен через bastion-хост, в bastion.example.com:
Вместе с bastion для своих подключений вы можете использовать
iptables (или другой *nix-вый файервол на ваш выбор) на серверах за bastion-ом,
для блокировки входящих SSH-соединений. Например, вот так:
Хорошая идея оставить второй SSH-сеанс активным – если что-то пойдет не так,
вы должны иметь возможность исправить ситуацию через установленное соединение.
Двухфакторная
аутентификация
Не так то
и просто преодолеть два различных метода проверки пользователя, особенно когда
не знаешь паролей. Первый уровень – это обычно пароль, а второй – токен из приложения, установленного на телефоне, SMS с уникальным кодом,
отпечаток пальца или голос.
Давайте установим подключаемый модуль аутентификации google-authenticator, который потребует
от пользователей на своем телефоне ввести код из приложения Google Authenticator. Вы можете скачать приложение для iOS и Android.
При использовании мер безопасности всегда
важно учитывать пользовательский скилл. Разумный
вариант – использовать двухфакторную аутентификацию для входа на bastion. После
проверки подлинности юзеры должны иметь возможность ходить на другие хосты,
используя свой сертификат. Такая комбинация должна обеспечивать приемлемый
уровень безопасности и не слишком напрягать пользователей. Однако в конкретных
средах, содержащих критические производственные данные или конфиденциальную
информацию, целесообразно применять дополнительные меры безопасности.
Установка
google-authenticator
В
системах на базе RHEL/CentOS можно установить модуль google-authenticator из
репозитория EPEL:
Для
систем на базе Debian / Ubuntu решение доступно в виде пакета
libpam-google-authenticator:
Модуль
имеет множество опций. В интересах экономии
времени мы используем некоторые значения по умолчанию: запретить использование
одного и того же токена дважды, выдавать временные коды и ограничивать
пользователя максимум тремя входами в систему каждые 30 секунд. Настроим это
все одной командой:
Вы также
можете запустить google-authenticator без флагов и настроить его в интерактивном
режиме.
Выполнение
предоставит QR-код, который пользователь может сканировать с помощью приложения.
Если вам
потребуется изменить какие-либо настройки в будущем, или полностью удалить
функциональность, конфигурация будет сохранена в разделе
~/.google_authenticator
.
Настройка
PAM для двухфакторной аутентификации
Чтобы
заставить систему использовать коды OTP (one-time password), нужно
отредактировать конфиг PAM sshd. Добавьте следующую строку в конец файла /etc/pam.d/sshd
:
nullok
в конце строки означает, что пользователям, у которых еще не настроен
второй фактор, все равно будет разрешено войти в систему, чтобы они могли его
настроить. После того как все настроено, обязательно удалите nullok.
В
завершение, измените методы аутентификации по умолчанию, чтобы SSH не
запрашивал у пользователей пароль, если они не представляют двухфакторный
токен. Эти изменения также вносятся в файл /etc/pam.d/sshd
:
- В RHEL/CentOS закомментируйте auth substack password-auth, добавив # в начало строки:
#auth substack password-auth
. - В Debian/Ubuntu, закомментируйте @include common-auth:
#@include common-auth
. - Сохранитесь.
Настройка
SSH для двухфакторной аутентификации
Для того
чтобы сервер требовал использования такой аутентификации, внесем несколько
изменений в /etc/ssh/sshd_config
:
- изменим
ChallengeResponseAuthentication no
наChallengeResponseAuthentication yes
, чтобы разрешить использование pam. - установим список допустимых методов аутентификации, добавив следующую строку в конец файла (или отредактировав строку, если она уже существует):
AuthenticationMethods publickey,keyboard-interactive
На этом
этапе вы должны перезапустить sshd с помощью systemctl restart sshd
. Убедитесь,
что вы оставили SSH-соединение открытым, чтобы при необходимости исправить ошибки. Перезапуск SSH оставит существующие соединения активными, но если есть проблема с конфигурацией, новые соединения могут быть запрещены.
Тестируем
Подключаемся
к bastion-у и видим приглашение:
Вводим код, представленный приложением Google Authenticator. Если вы проверите журнал
sshd и если все настроено верно, перед вами будет следующее:
Заключение
Приведенные методы дают практические примеры нескольких способов, с помощью которых вы
можете повысить безопасность своей инфраструктуры SSH, предоставляя пользователям
возможность гибко продолжать использовать инструменты, с которыми они знакомы.
Источники
Специально для сайта ITWORLD.UZ. Новость взята с сайта Библиотека программиста