Страницы

Поиск по вопросам

пятница, 10 января 2020 г.

Как использовать ключи из /etc/ssh_known_hosts в скриптах git

#git #ssh #ansible


Сценарий. Пользователь alice заходит на сервер msk-web-01 (centos7.2, selinux включен)
по своему ssh ключу и хочет в папке /www/mysite.ru/htdocs/ (владелец папки -- пользователь
apache) запустить команду git pull.

Для этого написан небольшой батник:

#!/bin/sh

#see http://ru.stackoverflow.com/questions/548545/ for details
sudo setfacl -m apache:x   $(dirname "$SSH_AUTH_SOCK")
sudo setfacl -m apache:rwx "$SSH_AUTH_SOCK"

cd /www/mysite.ru/htdocs/
pwd
sudo su -s /bin/sh apache -c "/usr/bin/git pull"
....


И он работает... выдавая многочисленные предупреждения:


/www/site1.ru/htdocs
Could not create directory '/usr/share/httpd/.ssh'.
Failed to add the ECDSA host key for IP address '1.2.3.4' to the list of known hosts
(/usr/share/httpd/.ssh/known_ho).
Already up-to-date.
/www/site2.ru/htdocs
Could not create directory '/usr/share/httpd/.ssh'.
Failed to add the ECDSA host key for IP address '1.2.3.4' to the list of known hosts
(/usr/share/httpd/.ssh/known_ho).
Already up-to-date.



Задача -- избавиться от этих лишних записей, добившись чистого вывода при помощи
добавления записей в глобальный known_hosts.

Требуемый эффект можно получить если создать /usr/share/httpd/.ssh/known_hosts со
строкой CheckHostIP no:


/www/site1.ru/htdocs
Already up-to-date.
/www/site2.ru/htdocs
Already up-to-date.
/www/site3.ru/htdocs
Already up-to-date.



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

PS Ключи сохранял одним из двух способов, первый:

ssh-keyscan -t rsa,dsa git.mycomany.ru >> /etc/ssh/ssh_known_hosts


второй:

ssh-keyscan git.mycomany.ru >> /etc/ssh/ssh_known_hosts


Разница не особо велика: в первом случае Failed to add the RSA host, во втором -
Failed to add the ECDSA host key.

И даже так с горя:

ssh-keyscan git.mycomany.ru,1.2.3.4 >> /etc/ssh/ssh_known_hosts

    


Ответы

Ответ 1



как выяснилось в комментариях, /usr/share/httpd — это домашний каталог пользователя apache. именно этому пользователю и должен принадлежать каталог (и всё его содержимое) /usr/share/httpd/.ssh: $ sudo chown -R apache /usr/share/httpd/.ssh также он должен быть доступен только самому пользователю: $ sudo chmod -R go= /usr/share/httpd/.ssh добавить публичные ключи (по умолчанию — типов rsa, ecdsa и ed25519 — см. $ man ssh-keyscan) машины git.mycompany.ru в файл «известных хостов» пользователя apache (/usr/share/httpd/.ssh/known_hosts) можно так: $ ssh-keyscan git.mycompany.ru | sudo tee -a /usr/share/httpd/.ssh/known_hosts если этот файл до этого не существовал, команды из первого пункта надо повторить после этой операции. вместо манипуляций с acl-ами (setfacl ...) лучше добавить строку Defaults env_keep+=SSH_AUTH_SOCK в /etc/sudoers (или даже ещё лучше — в файл с произвольным именем, не содержащем точек и тильд в имени, в каталоге /etc/sudoers.d). подробнее см., например, здесь. редактировать эти файлы лучше через «обёртку» visudo — см., например, здесь. уточнение в связи с требованием не использовать каталог ~/.ssh пользователя apache. чтобы не использовать ~/.ssh/config, но иметь возможность указать особую конфигурацию для конкретного пользователя, можно воспользоваться директивой match user в /etc/ssh/ssh_config, добавив в конец (это важно — см. $ man ssh_config на предмет опции match) этого файла примерно следующее: match user apache # какие-либо персональные настройки для пользователя apache чтобы процесс ssh не использовал ~/.ssh/knonw_hosts, можно (способом, описанным в предыдущем пункте) переопределить для данного пользователя значение конфигурационной переменной userknownhostsfile, указав в ней, например, файл /etc/ssh/ssh_known_hosts (или любой другой доступный пользователю для чтения): userknownhostsfile /etc/ssh/ssh_known_hosts нужные ключи в этот файл, разумеется, уже должны быть добавлены заранее. например, тем способом, что описан во втором пункте первой части ответа. возможно, для пользователей по умолчанию включена необходимость хешировать записи в known_hosts, тогда процесс ssh попытается перезаписать файл с ключами. чтобы он этого не делал, укажите (хотя бы для этого пользователя) не хешировать записи, добавив (как описано в первом пункте) строку: hashknownhosts no

Ответ 2



В итоге, всё оказалось достаточно просто. Сначала ещё раз о постановке задачи. Есть ряд доверенных серверов организации, между которыми сотрудникам нужно перемещаться с сохранением авторизации (ForwardAgent), поэтому нужно уметь заполнять файл /etc/ssh/ssh_known_hosts доверенными данными. Во-первых, гит в своём общении с удалёнными репозиториями по протоколу ssh полагается на системные утилиты, особых настроек ssh-подключения нет -- можно почитать про хаки с созданием файла ssh и экспортированием переменной GIT_SSH. Поэтому изначально в вопросе было больше про ssh, чем про конкретно git. Во-вторых, когда я начал разбираться с ключами (rsa, dsa, esdca) и версиями протоколов -- я решил не только абстрагироваться от гит, но и от ансибл - чтобы не влияло, на всякий случай. После тестов у меня получилось, что ключи были сгенерированы правильно, настройки ssh (как дефолтные центоса, так и мои кастомные) тоже не влияют на работу. Всё, что нужно -- это сдампить отпечатки и записать в общий known_hosts: ssh-keyscan -t rsa,dsa git.mycomany.ru >> /etc/ssh/ssh_known_hosts Включение хеширования не влияет на итог - тоже. А что влияет? Как ни странно -- выяснилось, что влияет ansible. Если файла /etc/ssh/ssh_known_hosts на диске нет -- он создаёт файл с правами rw-r--r-- но стоит лишь ещё раз запустить повторно -- права чудесным образом становятся rw------- Разумеется, что процессы, которые хотят прочитать хранилище и проверить, нет ли там такого отпечатка обламываются и ничего не находят. Стоит лишь восстановить права на файл -- и работа снова восстанавливается. Пример заполнения ключей практически такой же, как и в документации: - name: global pubkes for servers known_hosts: path='/etc/ssh/ssh_known_hosts' name='{{ item }}' key="{{ lookup('file', 'files/pubkeys/{{ item }}.pub') }}" with_items: - git.mycompany.ru Я хотел было создать баг на гитхабе -- но перед заведением поискал, нет ли готового. И нашёл, вот: https://github.com/ansible/ansible-modules-extras/issues/2513

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

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