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

понедельник, 24 января 2011 г.

SSH-туннель (часть 3)

Аутентификация по ключу

  В принципе, всего вышеизложенного вполне достаточно, чтобы спокойно лазить по всему Интернету под носом у ничего не подозревающих админов. Но, как обычно (дьявол — в деталях :) ) есть несколько нюансов. Во-первых, пароль пользователя может быть скомпрометирован. Ни для кого не секрет, что винда — это рассадник разнообразных вирусов, среди которых попадаются и кейлоггеры. Это значит, что любая последовательность символов, введённая с клавиатуры (в том числе и пароль от шелл-аккаунта), может стать известной любому сопливому не особо опытному школьнику начинающему взломщику, который по чистой случайности натравил на ваш ноутбук какой-то эксплойт. То есть теперь он сможет по локоть засунуть свои грязные ручонки в ваш законный шелл, а то и вообще лишить вас его. По-моему, это неправильно.
Во-вторых, пароль может быть недостаточно устойчивым к подбору, а сервер может не догадаться пнуть подборщика после трёх неудачных попыток авторизации подряд (ну фиг с ним, ну пнёт, но никто же не запрещает делать это медленно и осторожно). Заметьте, я даже не говорю, что кто-то может охотиться за вашими данными, которые вы решили сохранить подальше от любопытных в домашнем каталоге своего шелла. Я к тому, что шелл сам по себе достаточно ценен, чтобы его стоило угнать. Иначе вы бы и не занимались всей этой бодягой с PuTTY, так ведь? :) Ну вот, а в-третьих, пароль слишком легко забыть, записать на бумажке и посеять, напечатать вместо имени пользователя, когда кто-то стоит над душой, ну и т.д. В конце концов, ваш сервер может вообще запрещать аутентификацию паролем — но это, наверное, самый правильный случай, и его можно не упоминать. :)

Генерация ключей

  Так вот, чтобы ещё надёжнее защититься от гнусных поползновений всяких недоумков на ваш законный (надеюсь :) ) аккаунт, можно — и, безусловно, нужно — сделать следующее. Первым делом запустить PuTTY Key Generator:
После этого следует ткнуть на кнопку «Generate», чтобы запустить естественную функцию, для которой и предназначена эта утилита: собственно, сгенерировать пару ключей. На иллюстрации показана настройка для генерации RSA-ключа, но я рекомендовал бы выбрать DSA с длиной ключа 2048 бит.
  После того, как ключ сгенерирован, можно задать комментарий (чтобы проще было идентифицировать эту бредовую последовательность символов) и пароль.
Пароль я рекомендовал бы использовать достаточно длинный. Он нужен для того, чтобы невозможно было использовать ваш закрытый ключ всем, кому не лень. Если даже кто-то в этом случае подсмотрит ваш пароль, то эти сведения будут бесполезны без файла ключа. А если кто-то сопрёт ключ, то без пароля всё равно ничего не сможет с ним сделать. Так что настоятельно рекомендую.
  После этого можно сохранить ключи, ткнув на соответствующие кнопки. «Save public key» сохраняет открытый ключ, а «Save private key», соответственно, закрытый. Сохраним их, например, в каталоге «C:\secret folder\» под именами public-rsa и secret-rsa.ppk соответственно (ну или -dsa, если вы на предыдущем шаге решились использовать более стойкие ключи). То есть (я надеюсь) всем понятно, что имя каталога для сохранения ключей не может быть настолько дурацким?
  Теперь вспомним картинку про способ аутентификации в PuTTY:
В прошлый раз мы оставили поле для файла ключа пустым, поскольку этого самого ключа у нас ещё не было. Ну вот теперь наконец-то можно позволить себе указать файл свежесозданного закрытого ключа. Естественно, после этого настройки нужно сохранить. :)
  Но этого мало! =) Сейчас мы научимся менять по своему усмотрению ключи для аутентификации на нашем сервере. B-) Ну просто если этого сейчас не сделать, никто наш ключ просто не узнает, и получается, что мы зря сгоношили пару ключей. Ну так вот. Ключ в настройках мы указали, имя пользователя подставляется автоматически, крыжик про «keyboard-interactive» у нас стоит — можно подключаться. :) Хотя нет, нельзя. :/ Если в настройках SSH у нас стоит флаг «Don't start a shell or command at all», то у нас не будет возможности похимичить в командной строке, а мы в данном конкретном случае добиваемся именно этого. Так что снимаем этот крыжик — и вперёд!
  Должно получиться примерно следующее:
Using username "user".
Server refused our key
user@somehost.testing.com's password:
Linux shell 2.6.32-5-openvz-amd64 #1 SMP Thu Nov 25 18:44:54 UTC 2010 x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Mon Jan 17 10:56:32 2011 from gate.corporate.com
user@shell:~$

  Что же произошло? PuTTY взял имя пользователя, указанное нами в настройках. Потом он сказал, что сервер не принял наш ключ (ага, ещё бы он его принял! он его ещё не знает!), после чего стребовал с нас пароль и впустил по паролю.
  Ну и хорошо, что впустил. :) Теперь надо перейти в каталог .ssh (для не-линуксоидов: точка перед именем каталога важна, она означает, что этот каталог является скрытым):
user@shell:~$ cd .ssh
user@shell:~/.ssh$

  Теперь нужно в любом текстовом редакторе (M$ Word, если что — это не текстовый редактор, так что если ничего другого нет, сойдёт и обычный Notepad) открыть файлик, в который мы сохранили наш открытый ключ. Для чего? Сейчас поясню. Поскольку мы ещё не знаем, что такое sftp, :) нам придётся передать открытый ключ на сервер каким-то другим способом. Например, так, как я сейчас опишу. Сначала нужно просто выделить весь текст нашего открытого ключа и скопировать его в clipboard (то бишь в буфер обмена). Далее нужно вернуться в PuTTY и выполнить такую команду:
user@shell:~/.ssh$ cat <<EOF >test.pub
После этого под ней мы увидим приглашение вида
>
Это значит, что оболочка ждёт от нас каких-то данных. Хорошо, дадим ей эти самые данные. То есть вставим текст из буфера через Ctrl-V, или через Shift-Ins, или любым другим удобным способом. Должно получиться что-то типа такого:
user@shell:~/.ssh$ cat <<EOF >test.pub
> ---- BEGIN SSH2 PUBLIC KEY ----
> Comment: "External key"
> AAAAB3NzaC1yc2EAAAABJQAAAIBYFdtyk8CUeVU6El1vvlSUehDyv4qknTx3ZtSY
> XaM+IBWTHGC8QK07d4Viph52JvdII53AI2rhgD72m4Bd9naK8yYkzMMA8BrpzLeq
> ZBG1RlV+cAIZxzEvfbstgXA6W+1ImGYy0Y35ilza2rGJzvR-inWCeKMJ0BfVuU+G
> xObObQ==
> ---- END SSH2 PUBLIC KEY ----
>
В последней строчке руками набираем EOF и нажимаем <Enter>. Всё, оболочка должна выдать своё обычное приглашение. Наберём ls и проверим, присутствует ли на диске файл test.pub, который мы только что создали:
user@shell:~/.ssh$ ls
authorized_keys id_dsa.pub id_rsa.pub test.pub id_dsa
id_rsa known_hosts
user@shell:~/.ssh$
Хорошо, файл есть. Теперь посмотрим, похоже ли его содержимое на то, что мы в него запихивали:
user@shell:~/.ssh$ cat test.pub
---- BEGIN SSH2 PUBLIC KEY ----
Comment: "External key"
AAAAB3NzaC1yc2EAAAABJQAAAIBYFdtyk8CUeVU6El1vvlSUehDyv4qknTx3ZtSY
XaM+IBWTHGC8QK07d4Viph52JvdII53AI2rhgD72m4Bd9naK8yYkzMMA8BrpzLeq
ZBG1RlV+cAIZxzEvfbstgXA6W+1ImGYy0Y35ilza2rGJzvR-inWCeKMJ0BfVuU+G
xObObQ==
---- END SSH2 PUBLIC KEY ----
user@shell:~/.ssh$
Ну да, похоже на правду. И вот теперь можно добавлять этот ключ к списку авторизованных ключей. Несколько разных проверок были отнюдь не лишними, если учесть, что этот ключ может оказаться нашей единственной возможностью войти на сервер.
user@shell:~/.ssh$ ssh-keygen -i -f test.pub >>authorized_keys
user@shell:~/.ssh$
И ещё раз проверяем, что у нас в authorized_keys. Если там уже что-то и было, то наш ключ должен оказаться последним в этом файле:
user@shell:~/.ssh$ cat authorized_keys
ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIBYFdtyk8CUeVU6El1vwlSUehDyv4qknTx3ZtSY
XaM+IBWTHGC8QK07d4Viph52JvdII53AI2rhpD72m4Bd8naK8yYkzMMA8BrpzLeqZBG1RlV+
cAIZxzEvfbstqXA6W+1ImGYy0Y35ilza2rGJzvR-inWCeKMJ0BfVuU+GxObObQ==
user@shell:~/.ssh$
Ну тоже вроде бы совпадает. :) (Небольшое отступление: особенно дотошный и въедливый читатель мог заметить, что кое-какие символы всё-таки не совпали. Так вот. Это было сделано преднамеренно, а в боевой ситуации, естественно, ключи должны совпадать полностью! Если это не так, значит у вас глючит или сеть, или зрительный анализатор, и неизвестно ещё, что хуже.) Если вы создавали DSA-ключ, то сигнатура вместо ssh-rsa будет ssh-dss; если длина была больше 1024 бит, то, соответственно, и буковок будет значительно больше. Вот теперь можно нажать Ctrl-D (это «короткая форма» команды logout — отсоединения от сервера).
  После этого, не изменяя никаких настроек в PuTTY, открываем соединение ещё раз. Если ключ был импортирован правильно, мы должны увидеть примерно следующее:
Using username "user".
Authenticating with public key "External key"
Passphrase for key "External key":
Linux shell 2.6.32-5-openvz-amd64 #1 SMP Thu Nov 25 18:44:54 UTC 2010 x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Mon Jan 17 11:02:23 2011 from gate.corporate.com
user@shell:~$
Это значит, что PuTTY использовал ключ, названный нами в своё время «External key», и сервер этот ключ принял. Если вы решили проигнорировать защиту ключа паролем после генерации пары ключей, то строку про «Passphrase for key…» вы не увидите.
  Вот, пожалуй, и всё, что я хотел рассказать про ключи. :)
  Upd: 15/07/2011. Впрочем, есть ещё кое-что, достойное упоминания. Это утилита Pageant (PuTTY authentication agent), входящая в поставку PuTTY. Она позволяет импортировать ключи и запускать настроенные сессии без ввода пароля для ключа. После запуска появляется иконка в трее. Контекстное меню содержит, кроме пунктов просмотра и добавления ключей, ещё и список сохранённых сессий. При выборе сессии запускается PuTTY и без лишних вопросов логинится на сервер, поскольку пароли ему теперь сообщает агент. Поэтому в начале работы достаточно запустить Pageant (импортировать ключи, если это первый запуск) и по мере необходимости коннектиться к серверам через него.

Дополнительные замечания по безопасности

  Повторюсь, но в данном случае это не будет лишним. Даже если вы используете 2048-битный DSA ключ, закройте его паролем. Поскольку, к сожалению, никто не застрахован от кражи данных (вместе с компьютером или простым копированием). А ваш ключ от шелла — это в некотором смысле даже нечто большее, чем ключ от квартиры, потому что злоумышленник может не просто тихо подселиться к вам, но и выпнуть вас с сервера. Кроме того, от вашего имени можно провести серию взломов, что не самым лучшим образом скажется на ваших отношениях с органами охраны правопорядка. При этом доказывать, что вы не верблюд, будет весьма сложно.
  В свете сделанных замечаний наиболее оптимальным представляется хранение незапароленных ключей или паролей к ключам в любом криптоконтейнере. Им может быть как файл, зашифрованный средствами PGP/GPG, так и настоящий контейнер, созданный каким-нибудь коммерческим продуктом. А если пытаться быть параноиком по полной программе, то можно вспомнить и про стеганографию, но это явно избыточное средство для решения данной задачи. :) В Линуксе с шифрованием всё значительно проще. Выбор весьма широк: от пользовательских утилит для шифрования отдельных файлов до встроенных в ядро средств поддержки шифрованных блочных устройств. С точки зрения удобства каждый раз перед запуском PuTTY расшифровывать один файл — вероятно, не самый оптимальный вариант. Именно поэтому имеет смысл запаролить ключ, который теперь можно хранить в своём домашнем каталоге. А вот сложный пароль к этому ключу можно записать в текстовый файл и зашифровать. С большой вероятностью со второго-третьего раза пароль запомнится, и необходимость в расшифровке файла отпадёт сама собой. Ну и, кстати, не стоит забывать и про специализированный софт, предназначенный для хранения паролей. Из кросс-платформенных, пожалуй, навскидку вспомню keepassx и password-gorilla. Это определённо удобнее голого gpg. ;) Да, и ещё. Пароль желательно хранить подальше от ключа. Например, на флэшке в ксивнике.
В предыдущих постах можно найти первую и вторую части.

Комментариев нет:

Отправить комментарий