Я часто упоминаю в статьях ssh ключи. В определенный момент ко мне пришло осознание того, что про них-то написать я и забыл. Статья примитивная, но «чтобы было». Опытные пользователи в статье заметят много странностей, они смогут сказать много «а вот тут можно и так». man ssh-keygen я и сам могу почитать. И вы можете. Я не собираюсь его в сотый раз здесь переписывать.
SSH ключи позволяют авторизовываться нам на сервере без ввода пароля пользователя. Для чего оно? Кто-то говорит, что так безопаснее (отчасти они правы, в конце статьи покажу почему). Для меня же это удобный способ авторизовываться на тех пачках серверов, куда у меня есть доступ.
Логика действия простая — на сервере хранится открытая часть ключа, у вас — закрытая. При попытке авторизации происходит обмен частями ключа, если они «подойдут друг к другу» — сервер вас пустит. Мы сидели и считали — ssh ключик могут поломать года за 3 большим кластером (впрочем, могут и с первой попытки). Но вы же настроили fail2ban, верно? В любом случае, шанс — меньше.
Теперь по поводу пароля на ключ. Для кросс-авторизации между серверами (для работы rsync, например) использовать пароль — глупо. Поэтому я создаю отдельные ключи для каждого сервера (без пароля), кладу их подальше и кроном каждый час дергаю откуда-нибудь актуальный список.
Для себя же я использую запароленный ключ. Один черт, убунта или дебиан после первого ввода сохраняют ключ расшифрованным в памяти до логаута (а когда мы отходим от ноута — мы нажимаем ctrl-alt-l, right?). Остальным, вероятно, придется вводить пароль при каждом коннекте или настроить ssh-agent ручками.
Ну да ладно. Всё равно ssh ключи — они из разряда «must have».
Сначала создадим ключ у себя на локальной машине (тем пользователем, которым мы обычно сидим в системе. Хотя, можно и рутом создать, но и ходить по ssh нужно будет тоже рутом):
inky@laptop:~$ ssh-keygen -t dsa -b 1024
# создаем ключ зашифрованный алгоритмом dsa, 1024 бита
дальше нам задают вопросы:
Enter file in which to save the key (/home/inky/.ssh/id_dsa): жмем enter
Enter passphrase (empty for no passphrase): вводим пароль от ключа
Enter same passphrase again: и ещё раз пароль от ключа
Дальше нам напишут:
Your identification has been saved in /home/inky/.ssh/id_dsa.
Your public key has been saved in /home/inky/.ssh/id_dsa.pub.
Файлик /home/inky/.ssh/id_dsa нужно беречь как зеницу ока и не допускать его попадания в чужие руки.
/home/inky/.ssh/id_dsa.pub — открытая часть ключа, её содержимое кидаем на сервер.
Как закидывать Pub часть. Простейший способ, который есть не везде:
inky@laptop:~$ ssh-copy-id root@server -p22
У нас спросят пароль.
После этого мы сможем подключаться к серверу по ключу. И спрашивать у нас будут пароль ключа (если будут). Всё это актуально, если вы не отключили авторизацию по ключам на сервере.
Если у вас нет утилиты ssh-copy-id, то вам нужно закинуть содержимое файла id_dsa.pub в ~/.ssh/authorized_keys одной строкой. Например:
inky@laptop:~$ cat ~/.ssh/id_dsa.pub | ssh user@server "touch ~/.ssh/authorized_keys && tee ~/.ssh/authorized_keys" && ssh user@server "cat ~/.ssh/authorized_keys"
Возьмите в привычку всегда делать вот такое:
inky@laptop:~$ chmod -R 600 ~/.ssh/
user@server:~$ chmod -R 600 ~/.ssh/
Ну и да. Если вы сохранили ключ в недефолтное место, то используйте параметр -i (и для ssh-copy-id, и для ssh):
inky@laptop:~$ ssh-copy-id -i /somedir/id_dsa.pub user@server
inky@laptop:~$ ssh -i /somedir/id_dsa.pub user@server
А теперь почему безопаснее. Вы представляете насколько сложнее нагенерировать столько 1024 битных ключей, чтобы один из них подошел? нет? http://ru.wikipedia.org/wiki/DSA почитайте) А там ещё и псевдослучайные цифры.
И запароленный файлик менее уязвим, чем куча паролей, которые нам приходится где-либо хранить.
Пожалуй только упускаете момент, если работать не из под root, пароль всё равно нужен. Чтобы «не забывать» 38-ми символьный пароль от пачки серверов купил себе yubikey, благодаря ему жизнь становится проще.
Ну рутом можно сделать su в любого пользователя.
PermittRootLogin without-password никто не отменял)
Логика действия простая – на сервере хранится открытая часть ключа, у вас – закрытая. При попытке авторизации происходит обмен частями ключа, если они «подойдут друг к другу» – сервер вас пустит.
То есть клиент посылает закрытую часть ключа на сервер? Вот уж действительно: «Для каждой вещи есть 2 объяснения — одно простое, другое правильное».
Если создавать отдельные ключи для каждого сервера, но все ключи хранятся в одном месте, это не увеличит защиту.
inky@laptop:~$ ssh-copy-id root@server -p22
нахера? оно и так по дефолту на 22 идет.
Если у вас нет утилиты ssh-copy-id
lolwut? http://packages.ubuntu.com/oneiric/amd64/openssh-client/filelist
она в ЛЮБОМ дистре идет из коробки, вместе с ссх.
если нет ssh-keygen, то и нету ssh-copy-id
но я такого еще не разу не видел :)
> она в ЛЮБОМ дистре идет из коробки, вместе с ссх.
в «дистре» под названием FreeBSD:
[root@xxx ~]# which ssh-keygen
/usr/bin/ssh-keygen
[root@xxx ~]# which ssh-copy-id
[root@xxx ~]# ssh-copy-id root@somewhere
bash: ssh-copy-id: command not found
ssh-copy-id это шелл-скрипт.
cat `which ssh-copy-id`
#!/bin/sh
# Shell script to install your identity.pub on a remote machine
# Takes the remote machine name as an argument.
# Obviously, the remote machine must accept password authentication,
# or one of the other keys in your ssh-agent, for this to work.
ID_FILE=»${HOME}/.ssh/identity.pub»
if [ «-i» = «$1» ]; then
shift
# check if we have 2 parameters left, if so the first is the new ID file
if [ -n «$2» ]; then
if expr «$1» : «.*\.pub» > /dev/null ; then
ID_FILE=»$1″
else
ID_FILE=»$1.pub»
fi
shift # and this should leave $1 as the target name
fi
else
if [ x$SSH_AUTH_SOCK != x ] ; then
GET_ID=»$GET_ID ssh-add -L»
fi
fi
if [ -z «`eval $GET_ID`» ] && [ -r «${ID_FILE}» ] ; then
GET_ID=»cat ${ID_FILE}»
fi
if [ -z «`eval $GET_ID`» ]; then
echo «$0: ERROR: No identities found» >&2
exit 1
fi
if [ «$#» -lt 1 ] || [ «$1» = «-h» ] || [ «$1» = «—help» ]; then
echo «Usage: $0 [-i [identity_file]] [user@]machine» >&2
exit 1
fi
{ eval «$GET_ID» ; } | ssh $1 «umask 077; test -d .ssh || mkdir .ssh ; cat >> .ssh/authorized_keys» || exit 1
cat <<EOF
Now try logging into the machine, with "ssh '$1'", and check in:
.ssh/authorized_keys
to make sure we haven't added extra keys that you weren't expecting.
EOF
и что?
А можно сделать так, чтобы все пользователи могли авторизоваться только по ключам, а какой-то один — и по паролю тоже?
/usr/sbin/usermod $username —lock можно сделать, если в него su делать не нужно.
Нет. Надо наоборот — одному пользователю разрешить авторизацию по паролю, а не запретить. Запрет авторизации по паролю стоит в конфиге SSH, можно ли этот запрет сделать не для всех?
Match user
PasswordAuthentication yes
Если у кого при этом всплывет трабл «agent admitted failure to sign using the key» — Нужно просто выполнить команду ssh-add
@
Возьмите в привычку всегда делать вот такое:
inky@laptop:~$ chmod -R 600 ~/.ssh/
user@server:~$ chmod -R 600 ~/.ssh/
@
Если же сделать так, то нету прав на execute, и получаю.
[sun@st ~]$ chmod -R 600 ~/.ssh/
chmod: cannot access ‘/home/sun/.ssh/known_hots’: Permission denied
chmod: cannot access ‘/home/sun/.ssh/id_rsa’: Permission denied
…..
[sun@st ~]$ ssh debsrv
ssh: Could not resolve hostname debsrv