LINUX.ORG.RU
решено ФорумAdmin

Systemd сервис и вход по ssh

 , , ,


0

2

Использую Ubuntu 16.04 Написал собственный скрипт, который выполняет нужные мне команды на группе серверов.

В скрипте есть часть кода:

    for serv in ${SERVERS[@]}
      do
        TEST=$(ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null ${SSH_USER}@${serv}.${HOST} "sudo su - root -c 'cat /root/test.txt'")
        echo $TEST ====
    done

Конечно, ${SSH_USER} , ${serv} и ${HOST} заданы и скрипт отлично работает когда его выполнить так:

$ /bin/bash /path/to/script.sh

Но он должен запускаться каждый раз, когда я включаю ноутбук. Соответственно я решил написать свой systemd сервис для своего пользователя и положил его в .config/systemd/user/. Выглядит он так:

    [Unit]
    Description=service-name
    After=multi-user.target
    
    [Service]
    Type=simple
    EnvironmentFile=%h/.config/systemd/user/default/service-name
    ExecStart=/bin/bash %h/${SCRIPT_DIR}/service-name 
    TimeoutSec=10
    
    [Install]
    WantedBy=default.target

Но сервис не работает, как задумывалось. Когда я его запускаю вот так:
$ systemctl start --user service-name сервис стартует, но скрипт не может выполнить вход на серверы.

В syslog такая картина:

    ssh_askpass: exec(/usr/bin/ssh-askpass): No such file or directory
    Permission denied, please try again.

Я думаю, проблема в том, что вход на серверы настроен через RSA-key, a мой RSA-key защищен при помощи passphrase. И в этом случае мой ssh-agent, по каким-то причинам, не работает. Я пытался экспортировать $SSH_AUTH_SOCK в мой скрипт. Также пытался задать ее вручную. Увы, безуспешно.

Также, я не могу понять какой ssh-agent используется.

    $ echo $SSH_AUTH_SOCK
    /run/user/1000/keyring/ssh

но

    $ps auSfx | grep [a]gent
    user  1399  0.0  0.0 168036   592 ?        Ss   12:34   0:00          \_ gpg-agent --homedir /home/user/.gnupg --use-standard-socket --daemon

и его сокет:

    $lsof -p 1399
    
    COMMAND    PID     USER   FD   TYPE             DEVICE SIZE/OFF    NODE NAME
    gpg-agent 1399 user  cwd    DIR                8,5     4096       2 /
    ....
    gpg-agent 1399 user    3u  unix 0xffff96fcbde83c00      0t0   25282 /home/user/.gnupg/S.gpg-agent type=STREAM

я определял /home/user/.gnupg/S.gpg-agent как переменную SSH_AUTH_SOCK , но в таком случае ключ не определяется вообще.

Вопросы:

  1. Как можно решить эту проблему?;
  2. Возможно есть путь лучше?
  3. Какой все-таки ssh-agent используется?

Спасибо.


Как можно решить эту проблему?

Создать отдельный ключ без парольной защиты.

Какой все-таки ssh-agent используется?

ssh-agent != gpg-agent. Используется у тебя скорее всего SSH-агент из гнома (gnome-keyring).

intelfx ★★★★★ ()
Ответ на: комментарий от intelfx

ssh-agent != gpg-agent. Используется у тебя скорее всего SSH-агент из гнома (gnome-keyring).

Спасибо за пояснение, действительно, gnome-keyring крутится.

Создать отдельный ключ без парольной защиты.

Этот вариант я и рассматриваю, однако, просто думал, что есть способ поизящнее (повелосипеднее) для данного случая =) Тем более, что я думаю, бывают варианты, когда новый ключ создать не вариант.

balzi ()
Ответ на: комментарий от Difrex

Можешь попробовать sshpass - оно пробрасывает пароль

Этот костыль строго хуже костыля с отдельным ключом.

gpg-agent умеет работать в качестве ssh-agent

Я прекрасно знаю. Но в случае ТСа это очевидно не так.

intelfx ★★★★★ ()
Последнее исправление: intelfx (всего исправлений: 2)
Ответ на: комментарий от balzi

Если бы у тебя был дистрибутив поновее (с GNOME >= 3.34, где полностью перешли на systemd для управления стартом сессии) — можно было бы просто вписать зависимость от gnome-keyring и тогда всё бы заработало искаропки (при этом сам ключ будет прозрачно разблокироваться твоим паролем при входе в систему).

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

intelfx ★★★★★ ()
Последнее исправление: intelfx (всего исправлений: 1)

ssh_askpass: exec(/usr/bin/ssh-askpass): No such file or directory

SSH хочет показать окно с предложением ввести пароль. Программа, которая это делает, задается в переменной окружения $SSH_ASKPASS, а при её отсутствии ищется по пути из лога. Видимо, в твоей системе для этого используется какая-то кастомная гномовская тулза, и ssh естественно не может её найти.

Тебе просто надо импортировать эту переменную в systemd до запуска юнита. Плюс, юнит должен запускаться после инициализации графического окружения. Всего этого можно добиться, прописав

systemctl --user import-environment
systemctl --user start service-name

в автозапуске Gnome. Или, как вариант, можно обойтись вообще без systemd и тупо прописать там твой скрипт.

Lrrr ★★ ()
Последнее исправление: Lrrr (всего исправлений: 1)
Ответ на: комментарий от intelfx

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

Да, не скрою, ОСь действительно старая. Уже запланировал переход на последнюю стабильную.

За ответ большое спасибо, проблему осознал.

balzi ()
Ответ на: комментарий от Difrex

Можешь попробовать sshpass - оно пробрасывает пароль

Видел такое, вот только хранить пароль в открытом доступе все равно что убрать его вообще) Более того, как по мне, еще более несекьюрно, ибо это , в теории, может скомпрометировать пароли от других сервисов/сайтов и т.д.

balzi ()
Ответ на: комментарий от anonymous

Немного оффтопа, но может использовать Ansible ? Как раз для этого придуман

Вариант очень хорош, правда) Однако, я задумывал это как более универсально решение. И потом, разве использование Ansible решит проблему с passphrase?

balzi ()
Ответ на: комментарий от Lrrr

SSH хочет показать окно с предложением ввести пароль. Программа, которая это делает, задается в переменной окружения $SSH_ASKPASS, а при её отсутствии ищется по пути из лога. Видимо, в твоей системе для этого используется какая-то кастомная гномовская тулза, и ssh естественно не может её найти.

Тебе просто надо импортировать эту переменную в systemd до запуска юнита.

Да, $SSH_ASKPASS не задана и оно пытается найти стандартную утилиту /usr/bin/ssh-askpass. Попытался поставить ssh-askpass ГНОМовский - заработало, но перед подключением к каждому серверу оно запрашивает пароль

systemctl –user import-environment

А вот когда в консоли просто выполнил это, и запустил ручками сервис (в автостарт его не добавлял, пока он не готов) - все отлично работает. Осталось только разобраться почему)

balzi ()