Кого защищаем
«Стандартная» хостинг компания. Наибольшее количество персонала в службе заботы клиентов и поддержке. Честный SSH доступ к серверам есть только у поддержки 3 линии, порядка 12 человек. Завершает набор технический авангард компании — «отдел обслуживания» человек на 8.
Массовый пользователь
Для отдела поддержки и частично отдела обслуживания настроен сервер авторизации SSH. Это сервер который имеет ключ для авторизации почти куда угодно. Всемогущий ключ одна из самых ценных информаций, которую нельзя упустить. Напрямую читать его могут 4 человека в конторе. Резервная копия на бумаге лежит в сейфе. Так же на этот сервер получают временный доступ разработчики которым надо воочию увидеть где и как сломалось.
Сотрудник может через сервер авторизации получить ssh доступ с использованием всемогущего ключа. Технически эти сотрудники могут позвать только одну команду — ssh, ssh в свою очередь использует приватный ключ для подключения к удаленному серверу. Как правило сотрудники используют локальный скрипт для быстрого использования сервера авторизации. Исторически сложилось что он называется go. Вот его содержимое:
Еще один плюс общего сервера авторизации это возможность логировать и считать статистику для всех сотрудников. Мы знаем какой сотрудник сколько времени провел на каком сервере. На случае внештатных ситуаций знаем что сотрудник там вводил и что ему отвечало, так как копируется весь ввод и вывод ssh-сессии.
Полубоги
Второй серьезной уязвимостью являются всемогущие ключи нескольких сотрудников. Такие ключи разрешается прописывать на сервера только с параметром from=””. В authorized_keys это выглядит вот так:
Указанные всемогущие 4 человека осознают свою значимость и шифруют диск ноутбука не забывая о пароле на приватную часть ключа.
Работа вне офиса возможна только с использованием VPN до офиса. Если в офисе нет электричества у нас есть резервный VPN сервер который так же умеет анонсировать нашу офисную сеть.
Всемогущий сервер
Последним серьезным пунктом является большой служебный сервер. Сервер осуществляет мониторинг почти всего и знает обо всех железяках и зачем они нужны, кроме этого на нем запускаются все ansible задачи. На сервере лежит свой приватный ключ под паролем. После входа на сервер магия с ssh-agent в bashrc предлагает ввести пароль от ключа. Дальше можно работать в полную силу. Прямого ssh на этот сервер нет, «два притопа, три прихлопа» и ты на сервере.
Эти правила не отменяют нормальную настройку файрвола на серверах. Но файрвол как правило настраивается чуть шире и пускает ssh из офисной сети, далее через sshd_config прижимаем список ip которые могут стать root:
А если все это не сработает
Последним бастионом проверки на каждом сервере выступает .bashrc файл, при инициализации shell по ssh стартует bash, и он проверяет источник подключения:
Такое количество вариантов ограничения используется чтобы скомпоновать нужный уровень защиты, не заблокировав работу сотрудника. Но при этом сохранить уверенность что сервер прикрыт. По мере роста компании я все меньше уверен в программах запускаемых в офисе. Я доверяю всем сотрудникам, но сплю с трудом.
Планы на доделку
Расширить функционал сервера авторизации, чтобы можно было указывать список или маску серверов для каждого пользователя. Возможно дописать bashrc чтобы он в момент подключения скидывал информацию о пользователе и ip. Далее поднимать флажки если у пользователя новый ip или что-то в этом духе. Не уверен что это работающая схема, но попробовать на досуге можно будет.
P.s: Сообщение от bfuvx как обойти bashrc
ssh -vvv -i everebody root@149.154.64.101
Ловим что-нибудь типа «debug2: shell request accepted on channel 0» и посылаем в этот момент «Ctrl+c»:
Last failed login: Tue Mar 20 02:41:12 EDT 2018 from 58.242.83.24 on ssh:notty
There were 23 failed login attempts since the last successful login.
Last login: Tue Mar 20 02:40:14 2018 from 95.154.75.23
^C-bash-4.2#
Комментарии (63)
citius
19.03.2018 13:29Почему не FreeIPA?
Hile
19.03.2018 14:23вся суть подобных решений, в том, что не надо настраивать конечные хосты (вообще никак). А freeipa требует подготовки хоста ( а если там железка не поддерживает то идея вовсе отпадает ).
Если много разного приходится админить, то только такие велосипеды и спасают.kvaps
19.03.2018 15:16Поддерживаю, FreeIPA + Linux-виртуалка с одим мастер-ключем ко всему.
Через правила sudo можно разрешить запуск определенных команд и только с конкретными аргументами, если есть такая необходимость.
Например: пользователь
vasya
может запускатьsudo ssh
только с аргументомserver1
,server2
иswitchB
Так же настроить
sudoreplay
для логирования, после чего каждая ssh сессия будет сохранена и сможет быть проиграна в интерактивном режиме.
Как бонус отсутствие необходимости устанавливать ipa-client на каждом сервере и общий сервер аутентификации с LDAP и удобной web-мордой — что тоже безусловно большой плюс.
artemirk Автор
19.03.2018 15:36Я думаю ваш вариант тоже хорошее решение. Мы условно еще привязаны к ISPmanager у него есть возможность «пропихнуть» публичный ключ в лицензию и далее владелец сервера одной кнопкой в панели «пускает» саппорт.
Этот вариант уже был и он работал. Далее наша действительность развивалась от него.
Это мои сладкие сны когда у меня будет проект без legacy и я смогу выбрать все технологии и даже ОС на сервере :)
Tatikoma
19.03.2018 13:42ssh hostname "bash --noprofile --norc"
От этого не забыли закрыть? — В статье не вижу.artemirk Автор
19.03.2018 15:32В этом варианте все отрабатывает как надо:
artem:~ artem$ssh root@149.154.64.101
Last failed login: Mon Mar 19 08:31:53 EDT 2018 from 58.242.83.24 on ssh:notty
There were 23 failed login attempts since the last successful login.
Last login: Mon Mar 19 08:31:04 2018 from 188.120.252.193
bashrc Connection DENY
Connection to 149.154.64.101 closed.
artem:~ artem$ssh root@149.154.64.101 «bash --noprofile --norc»
bashrc Connection DENY
myz0ne
20.03.2018 04:34А так?
ssh hostname -T /bin/sh
Почемуbashrc
? Такие вещи лучше делать через pam
Я делал примерно так
https://github.com/dmitriy-myz/pam_alerter
В идеале, ключ вообще не должен храниться на сервере, куда пускают сотрудников.
Можно попробовать использовать ssh-agent на отдельном сервере, который логинится на гейт с пробросом агента. Пользователям задавать переменную SSH_AUTH_SOCK.artemirk Автор
20.03.2018 04:37Мне не удалось проникнуть на сервер с .bashrc, возможно мой эксперимент не достаточно чистый.
Сделал лабораторную VDS. Предлагаю попробовать вместе найти где я не прав. Ключ в конце статьи.
MMik
19.03.2018 14:15как защититься от возможности потери ключа пользователем
Использовать сертификаты и отзывать сертификаты при подозрении на потерю сертификата или при увольнении сотрудника.
FreeIPA ещё выше предлагают.artemirk Автор
19.03.2018 15:24Проблема что не все оборудование бывает «мое». Объяснить клиенту что ему сейчас надо настроить свой ssh сервер, сложнее чем дать ему команду cat >authorized_keys. После чего саппорт может помочь клиенту и вырезать ключ или договориться что ключ останется для будущих обращений.
Подход сертификатов прекрасен если все сервера в личном ведении и ты их сам раскатываешь ансибло-чефом.
vaniacer
19.03.2018 15:02Вот такую штуку сделал, к безопасности отношения не имеет скорей наоборот) Автоматизирует ответ 'yes' при первом подключении к очередному серверу github.com/vaniacer/ssh_yes
И вот такую github.com/vaniacer/sshto создает меню на основе файла ~/.ssh/configMMik
19.03.2018 15:20Автоматизирует ответ 'yes' при первом подключении к очередному серверу
echo "alias ssh='ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no'" >> ~/.bash_profile; source ~/.bash_profile
Опция UserKnownHostsFile=/dev/null — на ваш вкус.ValdikSS
19.03.2018 16:51У openssh есть конфигурационный файл ~/.ssh/config, в который и нужно добавлять опции, а не делать алиасы.
MMik
19.03.2018 21:53Алиас многим привычнее.
Crystal_HMR
20.03.2018 12:40И тем не менее, это не повод упускать прекрасный инструмент конфигурации через конфиг. До банального:
- если использовать кроме ssh еще инструменты типо sshfs и scp — конфигурация через ~/.ssh/config позволяет использовать host во всех этих командах; а в случае alias'ов нужен алиас на каждую.
- Если нужно добавить/поменять какой-то дефолтный параметр — нужно либо разворачивать alias и делать руками, либо писать команду полностью заново. А ssh_config позволяет использовать всё как и раньше, просто передав необходимый ключ.
И многое другое :)
vaniacer
19.03.2018 15:10А тут вообще через web позволяет фигачить баш скрипты в ssh github.com/vaniacer/up
И крону можно задачи назначать.
hishnik
19.03.2018 16:04А не проще было поставить какой нибудь УЦ [PKI-CA] (типа xca даже) на изолированной машине и как все нормальные люди настроить доступ к ssh по сертификатам, разместив ключи на «железных» токенах? Надо — отозвал, надо — выписал новый. Я уж молчу о технологии PMI — это круто конечно, но может оказаться слишком громоздким для вас.
artemirk Автор
19.03.2018 16:08Как я уже писал выше не на всех «машинах» куда я хожу я полноправный владелец. Добавить строку authorized_keys меньшее зло для владельца сервера. Наши клиенты не обрадуются если я буду менять им настройки openssh которые они с заботой сделали.
Все подходы которые решают задачу возможны.YourChief
20.03.2018 01:36Доверие к CA можно указать через authorized_keys в том числе, разница только в одном ключевом слове вначале строки.
Соответственно, любой, кто должен получить доступ куда-либо, должен просто-напросто получить временную подпись на свой ключ со стороны ключа CA. Сам ключ CA при этом может располагаться на каком-либо HSM. Согласитесь, это решение гораздо лучше, чем колхоз со «всемогущим ключом» и сервером-прокси для SSH.
ctacka
19.03.2018 16:35А может поставит что-то типа vault-а и отказаться от единого всемогущего ключа?
linjan
19.03.2018 18:35Мы знаем какой сотрудник сколько времени провел на каком сервере. На случае внештатных ситуаций знаем что сотрудник там вводил и что ему отвечало, так как копируется весь ввод и вывод ssh-сессии.
Подскажите, чем вы это делаете?artemirk Автор
20.03.2018 04:47ssh сессия запускается с |tee -a и далее собирается все для дальнейшего поиска.
diver666
21.03.2018 04:03Не могли бы вы более подробно? или пример привести?
artemirk Автор
21.03.2018 04:07artem:~ artem$ssh -i everebody user@149.154.64.101 |tee -a session_log
Last login: Tue Mar 20 21:01:55 2018 from 188.120.252.193
[user@login ~]$ cat /etc/host
cat: /etc/host: No such file or directory
[user@login ~]$ logout
Connection to 149.154.64.101 closed.
artem:~ artem$cat session_log
Last login: Tue Mar 20 21:01:55 2018 from 188.120.252.193
[user@login ~]$ cat /etc/host
cat: /etc/host: No such file or directory
[user@login ~]$ logout
В файле session_log будут все что происходило по ssh, из минусов это когда mc или другая ncurses программа, в файле будут все перерисовки экрана. Дальше или забираем файл или вместо файла сразу пишем в сокет, все на ваше усмотрение.kt97679
21.03.2018 06:16Как вы защищаетесь от ситуации, когда юзер делает cat /dev/random и переполняет диск?
artemirk Автор
21.03.2018 11:00Ограничением сетевых интерфейсов для начала. Этот дев рандом надо будет по ssh человеку еще вытянуть.
Ну и в целом если мы решили сохранять сессии то согласны потратить на них место на диске. Винты в 8 тб у нас не редкость.
За последний год лог сессий всех сотрудников занимает около 65 гб
diver666
21.03.2018 10:42Хм, я наверно не корректно спросил, вы сами подставляете |tee -a session_log, я почему-то решил что вы логируете сторонних пользователей которые заходят на сервер, те если кто-то войдет ssh -i everebody user@149.154.64.101, лог сессии у вас не сохранится?
artemirk Автор
21.03.2018 10:58На боевые серверы «рядовые» пользователи могут попасть только через сервер авторизации. А на нем ssh подменен на ssh |tee
Обычные ssh сеансы не логируем. Люди которые у нас могут рутом попасть на сервер могут рассказать что делали и они в состояние отключить логирование если им надо :)
acmnu
19.03.2018 19:01Я как-то организовывал доступ к клиентам по ssh для большого количества людей разом. Ситуацию упрощало, что ходить они могли с одного бокса. Т.е. сначал шли на некий ssh_box, а потом оттуда к клиенту.
Идея была в том, чтоб у сотрудника не было возможности прочитать приватный ключ, а значит и законнектится с другого хоста (authorized на целевых хостах строго мониторился). Для этого использовался SshAgent поднятый под левым пользователем (скажем master). Приватные ключи принадлежали этому пользователю, а конечный пользователь, скажем vasya использует socket от ssh agent для коннекта.
Разумеется в такой структуре были разные уровни доступа. Например на root у клиентов могли пойти только три человека (два админа и тех.дир), а на пользователя приложения человек 15. Достигалось это запусков нескольких ssh agent, сокеты, которых был доступны разным unix группам.
Единственное, что для такого варианта пришлось пачить ssh agent. Он по дефолту не позволяет коннектится к себе другому пользователю. Вторая засада была в том, что для того, чтоб явно сказать с каким приватным ключом коннектится к хосту надо сформировать список пар host:public_key и положить его в config. На тот момент это было тайное знание, которое я прояснял у разработчиков.
YourChief
20.03.2018 01:57Последним бастионом проверки на каждом сервере выступает .bashrc файл, при инициализации shell по ssh стартует bash, и он проверяет источник подключения
Этот мусор можно сразу убрать. Чтобы обойти эту «защиту» достаточно передать команду по ssh в неинтерактивном сеансе.artemirk Автор
20.03.2018 04:48Предлагаю попробовать. Я в конце статьи дал ключ от лабораторной VDS. Но во мне так же есть зерно сомнения, но как это сделать я так и не придумал.
saboteur_kiev
20.03.2018 02:37Светить айпишники не боитесь? ботнеты, ddos?
А вдруг обнаружится уязвимость в ssh, а тут как раз и логины есть и айпишники есть и даже адрес главного сервера с главным ключом в публичном интернете?artemirk Автор
20.03.2018 04:50Я очень аккуратен в выборе ip которые свечу. Но в целом все наши сети легко можно выяснить по автономной системе, так как мы является «лиром» и все наши ip по честному наши во whois.
wild_one
20.03.2018 04:50Еще очень советую "ключи на бумаге" хранить с помощью схемы разделения секретов Шамира.
artemirk Автор
20.03.2018 05:15Я оцениваю возможность взлома сейфа ради ssh ключа как событие с крайне малой вероятностью.
bfuvx
20.03.2018 10:46ssh -vvv -i everebody root@149.154.64.101
Ловим что-нибудь типа «debug2: shell request accepted on channel 0» и посылаем в этот момент «Ctrl+c»:
Last failed login: Tue Mar 20 02:41:12 EDT 2018 from 58.242.83.24 on ssh:notty There were 23 failed login attempts since the last successful login. Last login: Tue Mar 20 02:40:14 2018 from 95.154.75.23 ^C-bash-4.2# cat /root/README Привет всемогущий инжинер. Пароль. "Другой жизни не будет"
Можно автоматизировать с помощью expect или правкой ssh клиента. Вручную тоже очень быстро ловится нужный момент.lexore
20.03.2018 11:28К чему такие сложности.
ssh root@149.154.64.101 /bin/sh
bfuvx
20.03.2018 11:51ssh root@149.154.64.101 /bin/sh
выльется в "$SHELL" -c "$command", strace:
strace -e execve -f -p $server_sshd_pid execve("/bin/bash", ["bash", "-c", "/bin/sh"], [/* 8 vars */]) = 0
Возможно не на всех версиях openssh.
datacompboy
20.03.2018 11:53Интересно. А ~/.ssh/rc так обойти можно?
bfuvx
20.03.2018 12:11Да, такой же принцип:
execve("/bin/sh", ["sh", "-c", "/bin/bash -c '/bin/sh .ssh/rc'"]...
Никто не мешает послать sigint в нужный момент. Легко проверить на чем-нибудь типа «sleep 10;echo hello».
artemirk Автор
21.03.2018 04:01Первым решение было просто написать срипт/программу который или пускает bash или выходит. /bin/maybelogin, но потом попробовал bashrc остановились на нем как на более простом. Если у пользователя в passwd прописан /bin/maybelogin и кинуть sigint что будет запуcкать ssh?
bfuvx
21.03.2018 13:01что будет запуcкать ssh?
Ничего, сессия завершится. Но как уже обращали внимание выше, для этого случая есть специально разработанный механизм — pam, его и нужно использовать. Можно как свой модуль написать так и использовать pam_exec для запуска срипта/программы.
lexore
20.03.2018 11:36+1SSH у людей не достаточно безопасен.
Вообще заголовок не раскрыт.
Как я понял из статьи, все риски сводятся к тому, что кто-то может иметь ключ без пароля и потерять его.
Hile
20.03.2018 11:45www.nongnu.org/oath-toolkit
есть в EPEL позволяет юзать Google Authenticator или Yubikey брелки
настройка вот тут github.com/itsumma/isolate#otpHile
20.03.2018 11:52ну и вот удобняшка (консольный генератор QR кодов и secret )
github.com/mcepl/gen-oath-safe
datacompboy
20.03.2018 21:16Чуть не забыл, ещё один момент в защите через башрц:
ssh -L 2222:22.22.22.22:22 -N root@host &
ssh localhost -p 2222
Позволит зайти на удалённый 22.22.22.22 с айпишником "защищённого".
Так как при -N вообще не запускается шелл.
То есть важно проброс портов выключатьkt97679
21.03.2018 01:29Я как раз долбился по списку разрешенных адресов когда ссш сервер был погашен. Справедливости ради надо уточнить, что мы не знаем был ли у машины, которую мы ломали, адрес в разрешенном диапазоне, так что эта атака вполне могла не получится. Но замечание совершенно правильное, порт форвардинг надо отключать.
Hile
github.com/itsumma/isolate
p.s. скоро выкачу новый ssh.py как только у себя протестирую все
p.s.s. сплю хорошо
artemirk Автор
Хороший инструмент. Исторически мы свои примерно в одно время с вами сделали. Пока работает и решает задачи, сам понимаешь не трогаем :)
Hile
У нас давно было, просто в какой то вид оформлено и выложено ток недавно. Основная ветка живет внутри. Баш не страшно юзать в таких местах? шеллшок послужил как раз поводом для написания своего велосипеда )