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

Если ssh-agent запускается на удаленном сервере то четыре.
Локальный ssh-agent + ForwardAgent yes
Не согласен. Кидать свой приватный ключ на удаленный сервер — рисково. Пробрасывать с локальной машины — безопасно. Большая разница.
Мне кажется, что мы друг друга не поняли.
Локальный ssh-agent + ForwardAgent yes — я это и указывал

А цепочку можно построить так:
$ ssh-add
$ ssh -A server
connected
  $ ssh-add # будет добавлен ключ из первого шага
  $ ssh -A server2
  connected
    $ ssh-add # будет добавлен ключ из первого шага
    $ ssh -A server3 

Пробрасывать ssh-agent — настолько же не безопасно, насколько и кидать приватный ключ на удаленный сервер. root на сервере может как утянуть файлик с приватным ключом, так и утянуть сокет ssh-agent. И защиты от этого нет.
он будет иметь доступ к ключу ровно на время сеанса, и не более. В случае прокидывания ключа — утекает сам файл (который может быть запаролен, и все же).
В очень большом проценте случаев этого достаточно, чтобы, воспользовавшись агентом, добраться до машины пользователя (где этот же ключ лежит в authorized_keys) и дальше с правами пользователя выполнить что угодно:
— стянуть приватный ключ, если он не запаролен
— прописать свой ключ в authorized_keys и ходить на пользовательскую машину пользоваться уже локальным агентом
— запустить любые туннели или сервисы
Вообще вроде как совсем у малого процента пользователей внешний айпи ведущий на их машину. Еще меньше пользователей которые прописывают свой же ключ в authorized_keys. К примеру на рабочем ноутбуке у меня такого файла нет.
У достаточно большого, не статический, но внешний.
Не могу сейчас найти, но был даже публичный сервис, который предлагал всем желающим ssh-нуться к ним и показывал проблемы и уязвимости вашего клиентсвкого конфига. Они как раз статистику собирали.

А там им воспользоваться зачем? Залогиниться на локальный (для удалённого сервера) узел?
Лично мне хватает пары записей в конфиге:


host server1
  User vasya
  Port 9222

host server2
  User petya
  ProxyCommand ssh server1 -W %h:%p

Открытый ключ прописан на обоих серверах в authorized_keys.
И всё, на server2 заходится в один клик, без всяких манипуляций с агентами и т.д.
Это что, способ 4?

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

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

> Как еще можно улучшить безопасность
Отказаться уже наконец в 2018-м году от доступа по ключам и перейти к доступу по сертификатам. Например github.com/gravitational/teleport (ну или убера есть похожая штука)
А ещё приватные ключи можно хранить например на аппаратных кошельках криптовалют (например ledger nano s это умеет).
Чем данный подход принципиально отличается от традиционного?
У сертификатов тоже вроде приватная часть есть.
Принципиально он отличается тем что
1. на все машины не надо разливать ключи тех кому туда надо ходить
2. у ключей появляется срок действия и понятная логика их обновления
Можно еще добавить о ciphers-ах, MACs, KexAlgorithms и о важности отключения древних.
Опять двадцать пять! Очередная статья об одном и том же.
Расскажите, как вы будете управлять ключами десяти тысяч сотрудников на трёх сотнях тысяч серверов. Доступы у сотрудников добавляются и удаляются сотнями в день, сервера добавляются и исчезают тоже сотнями в день. Подсказка:
Читайте документацию, в ней все написано, как бы это пошло не звучало.
Вот это будет интересный пост. Заранее спасибо.
Тоже интересно. Любое увольнение должно инвалидировать ключ, а как это сделать — непонятно.
в рамках данной статьи удалить его из $HOME/.ssh/authorized_keys
А в энтерпрайзе другие подходы
Это кстати так себе подход. ЛДАП ложится и всё становится плохо.
Использовать Hashicorp Vault в связке со LDAP например, для генерации SSH OTP. В таком случае сертификаты вообще не нужны. Правда на хостах должен стоять ssh-helper, так что решение не для всех подойдет.

Я для этого писал кучу скриптов и хакал ssh_agent :) Но у меня были тепличные условия: 50 сотрудников делились на примерно 5 груп и коннектились на сервера клиентов (~1k машин) на 2-3 аккаунта.

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

PAM?

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

У меня опыт был использования PAM + ldap для управления пользователями
Пф. Тоже мне белые пятна.
Белое пятно — что root на сервере, куда вы пришли с форвардом ключа, может реюзнуть сокет и фактически воспользоваться ключем, пока открыта ваша сессия.
скомпрометированный root на машине без selinux и прочих защит (да и с ними тоже) — это компрометация всей системы, «ЭТО ФИАСКО, БРАТАН» (с)

Дальше о безопасности говорить уже смысла нет
Бла-бла-бла.
Вы не подумали о ситуации, когда вполне себе штатный рут захочет воспользоваться ключем? Или когда машина вовсе чужая и вы не можете быть в курсе, что она похакана?

Форвард ключа штука опасная, а все её советуют включить по дефолту.
Какие варианты?
Я могу предложить только временные ключи на время сессии
Как минимум, не включать форвард на все хосты, а заходить с форвардом только по необходимости.
Взлом одной из машин, через которую вы прошли, означает компрометацию всех серверов в которые вы могли зайти с помощью своего агента. Действительно, если вы пробросили агента, дальше о безопасности говорить нет смысла.
Есть смысл говорить о том, стоит ли вообще пробрасывать агента куда-либо. Я считаю, что не стоит этого делать, от слова совсем.
А еще ключи можно прописывать в файл authorized_keys2, а не только в authorized_keys, ключи будут читаться из обоих файлов.
Если вы накладываете на файл authorized_keys immatable атрибут, что можно сделать только рутом, то не забывайте делать authorized_keys2 и его тоже защищать.
authorized_keys2 ещё в 2001 году был с пометкой deprecated, но проверю на своих системах его поддержку
Debian 9, man sshd
AUTHORIZED_KEYS FILE FORMAT
AuthorizedKeysFile specifies the files containing public keys for public key authentication; if this option is not specified, the default is ~/.ssh/authorized_keys and ~/.ssh/authorized_keys2.


А что мешает сделать первую сесиию на удаленный хост с пробросом удаленного порта 2го хоста на локальный сервер и потом просто зайти на этот(локальный, проброшенный) порт?
Никаких тебе агентов и у рута на удаленной машине нет доступа к агенту.

Технически не мешает и подобное я часто использую (делал внутренний доклад про сценарии использования, однако, на Хабре уже есть статьи на эту тему), но что, если надо зайти на сервер и выполнить


$ git pull

Или scp или rsync да и много чего ещё (на самом деле нет).
Можно использовать парольную аутентификацию или извращаться, а можно воспользоваться агентом.
Часто встречаю ситуацию когда на серверах разработки код стянут по https, ты вызываешь


git pull

А у тебя GIT спрашивает пароль какого-то разраба. Почему нельзя было склонить по SSH? Секурность? Нет — глу… незнание

По поводу компрометации сокета ssh-agent:
Например, под Windows, есть агент, встроенный в KeePass (в виде плагина) и он выдает запрос на каждое использование ключей.


Также есть такие интересные штуки как Krypton, про которые почему-то в статье не упомянули. (Вкратце: ключи генерируются и хранятся на мобильном устройстве в защищенном хранилище и никогда оттуда не извлекаются, это просто невозможно без прав рута и прочих хаков)

На локальной машине можно найти файл $HOME/.ssh/config
А если бы мне давали рубль за каждый случай «я забыл пароль/адрес/параметр» я жил бы недалече от вас.
$HOME/.ssh/config и ключи это удобно но это сильно провоцирует забывчивость.

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

Например:
Host vagrant
    HostName 127.0.0.1
    User vagrant
    IdentityFile ~/.vagrant/machines/default/virtualbox/private_key
    Port 2222
Host * !bitbucket.org !10.2.* !10.1.*
    User ubuntu
    IdentityFile ~/.ssh/id_rsa
Host *
    StrictHostKeyChecking=no
    UserKnownHostsFile=/dev/null
Думал расписать более подробно конфиг, пожалуйста, стоило это сделать. Надо будет дополнить.
В критически важных CI/CD использование комбинации
ssh-keyscan example.com >> ~/.ssh/known_hosts
Во время инициализации совместно с
StrictHostKeyChecking=yes
Позволит надежно защититься от MITM-атак

Это же совсем не так, man ssh-keyscan говорит:


SECURITY
     If an ssh_known_hosts file is constructed using ssh-keyscan without verifying the keys, users will be vulnerable to man in the middle attacks. On the other hand, if the security model allows such a risk, ssh-keyscan can help in the detection of tampered keyfiles or man in the middle attacks which have begun after the ssh_known_hosts file was created.

Т.е. без верификации ключа ты уязвим к MITM.
Или я что-то недопонимаю в вашем высказывании?

Или я что-то недопонимаю в вашем высказывании?

Ключевое слово было инициализации, т.е. когда вы точно уверены, что MITM атаки нет, а если уверенности нет, то можно использовать отдельное хранилище или пример с https, что я приводил выше.
Спасибо за статью. Приватные ключи еще можно держать в менеджерах паролей. Например KeepassXC с версии 2.3.2 прикидывается ssh-agent на всех платформах (правда на Mac-ах требует использования упомянутого выше ssh-askpass
На маке вместо KeepassXC решил использовать MacPass — интерфейс нативный и функционал неплох.
Читаешь такой статью, думаешь как интересно, а потом видишь слово «дешифрация» в тематической статье и охватывает настоящий фейспалм.
На схеме видно, что после обмена публичными ключами два узла могут безопасно общаться между собой через небезопасный Интернет.

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


«При помощи этой самой пары ключей» ТОЛЬКО АУТЕНТИФИКАЦИЯ и производится.
А безопасное общение узлов происходит за счёт симметричного шифрования с использованием сеансового ключа, который в свою очередь генерируется еще до аутентификации при помощи алгоритма Диффи-Хеллмана.
Only those users with full accounts are able to leave comments. Log in, please.