Pull to refresh
Comments 63
UFO landed and left these words here
Хороший инструмент. Исторически мы свои примерно в одно время с вами сделали. Пока работает и решает задачи, сам понимаешь не трогаем :)
UFO landed and left these words here
UFO landed and left these words here

Поддерживаю, FreeIPA + Linux-виртуалка с одим мастер-ключем ко всему.
Через правила sudo можно разрешить запуск определенных команд и только с конкретными аргументами, если есть такая необходимость.


Например: пользователь vasya может запускать sudo ssh только с аргументом server1, server2 и switchB


Так же настроить sudoreplay для логирования, после чего каждая ssh сессия будет сохранена и сможет быть проиграна в интерактивном режиме.


Как бонус отсутствие необходимости устанавливать ipa-client на каждом сервере и общий сервер аутентификации с LDAP и удобной web-мордой — что тоже безусловно большой плюс.

Я думаю ваш вариант тоже хорошее решение. Мы условно еще привязаны к ISPmanager у него есть возможность «пропихнуть» публичный ключ в лицензию и далее владелец сервера одной кнопкой в панели «пускает» саппорт.
Этот вариант уже был и он работал. Далее наша действительность развивалась от него.
Это мои сладкие сны когда у меня будет проект без legacy и я смогу выбрать все технологии и даже ОС на сервере :)
ssh hostname "bash --noprofile --norc"
От этого не забыли закрыть? — В статье не вижу.
В этом варианте все отрабатывает как надо:

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

А так? ssh hostname -T /bin/sh
Почему bashrc? Такие вещи лучше делать через pam
Я делал примерно так
https://github.com/dmitriy-myz/pam_alerter


В идеале, ключ вообще не должен храниться на сервере, куда пускают сотрудников.
Можно попробовать использовать ssh-agent на отдельном сервере, который логинится на гейт с пробросом агента. Пользователям задавать переменную SSH_AUTH_SOCK.

Мне не удалось проникнуть на сервер с .bashrc, возможно мой эксперимент не достаточно чистый.
Сделал лабораторную VDS. Предлагаю попробовать вместе найти где я не прав. Ключ в конце статьи.
Сделал лабораторную VDS. Вы можете сами попробовать.
как защититься от возможности потери ключа пользователем
Использовать сертификаты и отзывать сертификаты при подозрении на потерю сертификата или при увольнении сотрудника.
FreeIPA ещё выше предлагают.
Проблема что не все оборудование бывает «мое». Объяснить клиенту что ему сейчас надо настроить свой ssh сервер, сложнее чем дать ему команду cat >authorized_keys. После чего саппорт может помочь клиенту и вырезать ключ или договориться что ключ останется для будущих обращений.

Подход сертификатов прекрасен если все сервера в личном ведении и ты их сам раскатываешь ансибло-чефом.
Вот такую штуку сделал, к безопасности отношения не имеет скорей наоборот) Автоматизирует ответ 'yes' при первом подключении к очередному серверу github.com/vaniacer/ssh_yes

И вот такую github.com/vaniacer/sshto создает меню на основе файла ~/.ssh/config
Автоматизирует ответ 'yes' при первом подключении к очередному серверу
echo "alias ssh='ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no'" >> ~/.bash_profile; source ~/.bash_profile

Опция UserKnownHostsFile=/dev/null — на ваш вкус.
У openssh есть конфигурационный файл ~/.ssh/config, в который и нужно добавлять опции, а не делать алиасы.

И тем не менее, это не повод упускать прекрасный инструмент конфигурации через конфиг. До банального:


  1. если использовать кроме ssh еще инструменты типо sshfs и scp — конфигурация через ~/.ssh/config позволяет использовать host во всех этих командах; а в случае alias'ов нужен алиас на каждую.
  2. Если нужно добавить/поменять какой-то дефолтный параметр — нужно либо разворачивать alias и делать руками, либо писать команду полностью заново. А ssh_config позволяет использовать всё как и раньше, просто передав необходимый ключ.

И многое другое :)

А не проще было поставить какой нибудь УЦ [PKI-CA] (типа xca даже) на изолированной машине и как все нормальные люди настроить доступ к ssh по сертификатам, разместив ключи на «железных» токенах? Надо — отозвал, надо — выписал новый. Я уж молчу о технологии PMI — это круто конечно, но может оказаться слишком громоздким для вас.
Как я уже писал выше не на всех «машинах» куда я хожу я полноправный владелец. Добавить строку authorized_keys меньшее зло для владельца сервера. Наши клиенты не обрадуются если я буду менять им настройки openssh которые они с заботой сделали.

Все подходы которые решают задачу возможны.
Доверие к CA можно указать через authorized_keys в том числе, разница только в одном ключевом слове вначале строки.

Соответственно, любой, кто должен получить доступ куда-либо, должен просто-напросто получить временную подпись на свой ключ со стороны ключа CA. Сам ключ CA при этом может располагаться на каком-либо HSM. Согласитесь, это решение гораздо лучше, чем колхоз со «всемогущим ключом» и сервером-прокси для SSH.

А может поставит что-то типа vault-а и отказаться от единого всемогущего ключа?

а смысл от .bashrc, если можно по scp его поменять?
Или я что-то не понял?
Попробуйте. Лабораторная VDS предоставлена в конце статьи. У меня не получается.
Мы знаем какой сотрудник сколько времени провел на каком сервере. На случае внештатных ситуаций знаем что сотрудник там вводил и что ему отвечало, так как копируется весь ввод и вывод ssh-сессии.


Подскажите, чем вы это делаете?
ssh сессия запускается с |tee -a и далее собирается все для дальнейшего поиска.
Не могли бы вы более подробно? или пример привести?
artem:~ 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 программа, в файле будут все перерисовки экрана. Дальше или забираем файл или вместо файла сразу пишем в сокет, все на ваше усмотрение.
Как вы защищаетесь от ситуации, когда юзер делает cat /dev/random и переполняет диск?
Ограничением сетевых интерфейсов для начала. Этот дев рандом надо будет по ssh человеку еще вытянуть.

Ну и в целом если мы решили сохранять сессии то согласны потратить на них место на диске. Винты в 8 тб у нас не редкость.

За последний год лог сессий всех сотрудников занимает около 65 гб
Хм, я наверно не корректно спросил, вы сами подставляете |tee -a session_log, я почему-то решил что вы логируете сторонних пользователей которые заходят на сервер, те если кто-то войдет ssh -i everebody user@149.154.64.101, лог сессии у вас не сохранится?
На боевые серверы «рядовые» пользователи могут попасть только через сервер авторизации. А на нем ssh подменен на ssh |tee

Обычные ssh сеансы не логируем. Люди которые у нас могут рутом попасть на сервер могут рассказать что делали и они в состояние отключить логирование если им надо :)

Я как-то организовывал доступ к клиентам по ssh для большого количества людей разом. Ситуацию упрощало, что ходить они могли с одного бокса. Т.е. сначал шли на некий ssh_box, а потом оттуда к клиенту.


Идея была в том, чтоб у сотрудника не было возможности прочитать приватный ключ, а значит и законнектится с другого хоста (authorized на целевых хостах строго мониторился). Для этого использовался SshAgent поднятый под левым пользователем (скажем master). Приватные ключи принадлежали этому пользователю, а конечный пользователь, скажем vasya использует socket от ssh agent для коннекта.


Разумеется в такой структуре были разные уровни доступа. Например на root у клиентов могли пойти только три человека (два админа и тех.дир), а на пользователя приложения человек 15. Достигалось это запусков нескольких ssh agent, сокеты, которых был доступны разным unix группам.


Единственное, что для такого варианта пришлось пачить ssh agent. Он по дефолту не позволяет коннектится к себе другому пользователю. Вторая засада была в том, что для того, чтоб явно сказать с каким приватным ключом коннектится к хосту надо сформировать список пар host:public_key и положить его в config. На тот момент это было тайное знание, которое я прояснял у разработчиков.

Последним бастионом проверки на каждом сервере выступает .bashrc файл, при инициализации shell по ssh стартует bash, и он проверяет источник подключения

Этот мусор можно сразу убрать. Чтобы обойти эту «защиту» достаточно передать команду по ssh в неинтерактивном сеансе.
Предлагаю попробовать. Я в конце статьи дал ключ от лабораторной VDS. Но во мне так же есть зерно сомнения, но как это сделать я так и не придумал.
Светить айпишники не боитесь? ботнеты, ddos?

А вдруг обнаружится уязвимость в ssh, а тут как раз и логины есть и айпишники есть и даже адрес главного сервера с главным ключом в публичном интернете?
Я очень аккуратен в выборе ip которые свечу. Но в целом все наши сети легко можно выяснить по автономной системе, так как мы является «лиром» и все наши ip по честному наши во whois.
Я оцениваю возможность взлома сейфа ради ssh ключа как событие с крайне малой вероятностью.

А практическая её реализация с помощью какого софта возможна?

UFO landed and left these words here
UFO landed and left these words here
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# cat /root/README
Привет всемогущий инжинер. Пароль. 

"Другой жизни не будет"

Можно автоматизировать с помощью expect или правкой ssh клиента. Вручную тоже очень быстро ловится нужный момент.

Пример для expect:

spawn ssh -vv -i everebody root@149.154.64.101
expect "debug2: shell request accepted on channel 0" { send "\x03" }
interact
ssh 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.
Да, такой же принцип:
execve("/bin/sh", ["sh", "-c", "/bin/bash -c '/bin/sh .ssh/rc'"]...

Никто не мешает послать sigint в нужный момент. Легко проверить на чем-нибудь типа «sleep 10;echo hello».
Первым решение было просто написать срипт/программу который или пускает bash или выходит. /bin/maybelogin, но потом попробовал bashrc остановились на нем как на более простом. Если у пользователя в passwd прописан /bin/maybelogin и кинуть sigint что будет запуcкать ssh?
что будет запуcкать ssh?

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

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

UFO landed and left these words here
UFO landed and left these words here

Чуть не забыл, ещё один момент в защите через башрц:
ssh -L 2222:22.22.22.22:22 -N root@host &
ssh localhost -p 2222


Позволит зайти на удалённый 22.22.22.22 с айпишником "защищённого".
Так как при -N вообще не запускается шелл.
То есть важно проброс портов выключать

Я как раз долбился по списку разрешенных адресов когда ссш сервер был погашен. Справедливости ради надо уточнить, что мы не знаем был ли у машины, которую мы ломали, адрес в разрешенном диапазоне, так что эта атака вполне могла не получится. Но замечание совершенно правильное, порт форвардинг надо отключать.
Only those users with full accounts are able to leave comments. Log in, please.