OpenSSH и доступ по ключам

Часто в Unix администрировании приходится использовать работу с ssh коннектами. Особенно, если это касается скриптов для полуавтоматизации, то это может сильно раздражать — ведь для того, чтобы скопировать что-то через scp или rsync, ваши скриптам придется прерываться и запрашивать у вас пароль. Какая тут автоматизация? 🙂 Что делать? Прочитать эту статейку… 🙂

Итак, если кратко, то надо сгенерировать закрытый и открытый ключи на стороне, где будем запускать скрипты (назовем такую машину «клиент»), положить открытый ключ туда, куда будем коннектится (назовем его условно «сервер») и настроим, чтобы сессия для такого-то аккаунта Unix запускалась не от Unix пароля, а от ключа (с паролем, но ниже будет показано, как настроить, чтобы вводить его однократно за весь день, например)

  1. На стороне клиента генерируем ключ типа DSA:
    mkdir -p ~/.ssh
    chmod 700 ~/.ssh
    cd ~/.ssh
    ssh-keygen -t dsa
    Enter passphrase (empty for no passphrase): …
    Enter same passphrase again: …
    chmod go-rwx ~/.ssh/*

    Я рекодмендую обязательно указать пароль. Рекомендуется указывать пароль, который не используется для аккаунта Unix. Если вы не укажите пароль (сделаете пустым), то любой, кому попадет ваш закрытый ключ-файл, сможет зайти на удаленный сервер под вашим аккаунтом без всяких проблем. Конечно, чтобы файл попал к кому либо, надо, чтобы были нарушены права доступа в Unix. Но файл может «утечь» случайно с утилитами синхронизации, бекапа или т.п.. Далее, я расскажу, как настроить, чтобы вы сами в дальнейшем не вводили часто пароль для закрытого ключа.

  2. Копируем ключ на сервер:
    scp -p id_dsa.pub remoteuser@remotehost:
    Password: ********
  3. На уделенном сервере делаем:
    ssh -l remoteuser remotehost
    Password: ********
    mkdir -p ~/.ssh # Создать директорию, если ее нет
    chmod 700 ~/.ssh
    cat id_dsa.pub >> ~/.ssh/authorized_keys  # Добавление к файлу, если он уже есть
    chmod 600 ~/.ssh/authorized_keys
    mv id_dsa.pub ~/.ssh # Не обязательно, но можно сохранить открытый ключ на всякий случай
    logout

    Теперь, у вас есть закрытый и открытый ключ на вашей клиентской машине, защищенный (или нет) паролем, и открытый ключ на стороне сервера. Серверу достаточно вашего открытого ключа, чтобы вас идентифицировать (условно говоря, сервер каждый раз будет генерировать некий уникальный текст и давать его вашей клиентской машине при открытии сессии, а ваша машина должна будет его подписать с помощью закрытого ключа, передать обратно цифровую подпись серверу, а тот сверит ее для выданного вам же текста. Поскольку подписать может только тот, кто имеет закрытый ключ + пароль к нему, а проверить подпись может тот, что имеет ваш открытый ключ, то идентификация в этом случае гарантирует серверу, что вы — эти именно вы, и Unix пароль в таком случае вообще не нужен и нигде в сессии не передается).

  4. Следующий шаг — настройка ssh-agent. Он может нам понадобится, если мы не хотим постоянно вводить пароль для закрытого ключа. Если же вы на шаге 1 указали пустой пароль, то можете пропустить 4 -6 пункты — вам не потребуется демон ssh-agent для кеширования пароля — его попросту нет — он не будет запрашиваться утилитами, использующими протокол ssh, и все эти утилиты могут работать из скриптов прямо на этом этапе.
    Демон ssh-agent висит в памяти и за операциями подписи и криптования к нему обращаются программы ssh & scp (и другие). Этот демон хранит в своей памяти ваш пароль для закрытого ключа определенное время, заданное вами. Это очень удобно, если вы повседневно используете openssh, например, даже для git pull & git push.

    crontab -e

    Вставляем в редакторе в crontab файл:

    @reboot ssh-agent -s | grep -v echo > $HOME/.ssh-agent

    Эти команды говорят крону, что во время ребута системы запустить ssh-agent, а его вывод — переменные среды окружения с настройками записать в файл $HOME/.ssh-agent. Этот файл необходим нам для того, чтобы программы ssh, scp знали, куда коннектится (в них сохраняются пути до Unix сокетов коммуникации с ssh-agent).
    Чтобы нам не ждать перезагрузки, запускаем демон сразу же:

    nohup ssh-agent -s > ~/.ssh-agent
  5. Теперь, в ваши скрипты, которые используют ssh & scp, надо добавить такую строку:
    . ~/.ssh-agent

    Также, рекомендую добавить следующие строки в ~/.bashrc (для bash shell-а):

    . $HOME/.ssh-agent
    alias keyon="ssh-add -t 10h"
    alias keyoff='ssh-add -D'
    alias keylist='ssh-add -l'

    Тем самым, при заходе на клиентскую машину ssh сессией, у вас загрузятся настройки для работы с ssh-agent, а также определятся алиасы команд для повседневной работы. Например, выполнив в bash команду «keyon», от вас ssh-add команда потребует ввести пароль для ключа. После ввода он будет еще работать 10 часов. В это время вы можете запускать команды ssh, scp и любые другие, что используют ssh для коннекта на сервер (rsync, git), и все эти команды будут работать без запроса пароля.

  6. Второй вариант настройки ssh-agent (если его выбираете, можете пропустить пункты 4 и 5):
    В файле ~/.bash_profile прописываем:

    SSHAGENT=/usr/bin/ssh-agent
    SSHAGENTARGS="-s"
    if [ -z "$SSH_AUTH_SOCK" -a -x "$SSHAGENT" ]; then
    eval `$SSHAGENT $SSHAGENTARGS`
    trap "kill $SSH_AGENT_PID" 0
    ssh-add
    fi

    Этими командами вы говорим при логине, если если нет таких-то переменных, запустить ssh-agent, выполнить команды вывода ssh-agent в текущем шеле (eval), а по завершении shell-а пристрелить процесс ssh-agent-а (trap). Здесь также при логине у вас единожды запросится пароль для ключа. Затем он будет в памяти ssh-agent

Подробнее и всесторонне об ssh-agent можете прочитать в статье Mark A. Hershberger

Также рекомендуется к чтению:

  1. 20 советов по безопасному использованию сервера OpenSSH
  2. OpenSSH Public Key Authentication