Я уверен, что есть много подобных вопросов, но мой немного более конкретен. У меня есть сервер, используемый для тестирования, и владелец сайта хочет, чтобы он автоматически обновлялся, когда кто-то отправляет данные в репозитории. Я решил использовать Github-хуки для отправки данных на определенный URL-адрес, сигнализируя, что пришло время для обновления. Однако наши репозитории являются частными, и если я запускаю shell_exec() в PHP, он запускается как www-data, который не может иметь ключей ssh. Я не хочу помещать пароли в открытый текст, и я довольно озадачен тем, как я собираюсь разрешить пользователю проходить аутентификацию. Кто-нибудь может дать совет? Я слишком долго вырывал свои волосы из-за чего-то, что, кажется, должно быть довольно простым.
2 ответа
Причина, по которой шаг git pull
завершается неудачей, заключается в том, что в Ubuntu Apache выполняет сценарий от имени пользователя www-data
. Таким образом, git
ищет ключи ssh, связанные с пользовательскими www-data
и, не найдя их, не может выполнить запрос git pull
.
В Ubuntu 16.04 пользователю www-data
назначается домашний каталог /var/www
. Это каталог, в котором git
ищет ключи ssh для согласования передачи. Таким образом, решение состоит в том, чтобы заставить GitHub поверить, что пользовательские www-data
реальны, назначив им действительный набор ключей. Чтобы сломать шаги:
Примечание . Предполагается, что у вас есть доступ к
sudo
.
Создайте каталог
/var/www/.ssh
принадлежащийwww-data:www-data
$ sudo mkdir -p /var/www/.ssh $ sudo chown -R www-data:www-data /var/www/.ssh
Создать SSH ключи в каталоге
$ cd /var/www/.ssh $ sudo ssh-keygen -t rsa -b 2048
Когда
ssh-keygen
запрашивает каталог для ввода ключей, выберите/var/www/id_rsa
Убедитесь в правильности прав доступа и владения ключами.
chown
towww-data:www-data
при необходимости.$ ls -la /var/www/.ssh/ total 24K drwxr-xr-x 2 www-data www-data 4.0K Apr 29 23:58 ./ drwxr-xr-x 5 root root 4.0K Apr 30 00:06 ../ -rw------- 1 www-data www-data 1.7K Apr 29 23:33 id_rsa -rw-r--r-- 1 www-data www-data 394 Apr 29 23:33 id_rsa.pub
Скопируйте ключ
id_rsa.pub
в авторизованные ключи ssh в настройках репозитория GitHub.Важно убедиться, что
git pull
работает, когда пользователь выполняетwww-data
. Использование ssh также требует добавления идентификатора сервера GitHub в файлknown_hosts
. Однако пользовательскиеwww-data
по умолчанию не имеют оболочки входа. Поэтому мы должны использовать простой трюк:$ sudo vi /etc/passwd
Найдите строку для
www-data
и измените/usr/sbin/nologin
на/bin/bash
и сохраните файл. Запись дляwww-data
должна выглядеть примерно так:www-data:x:33:33:www-data:/var/www:/bin/bash
Изменить на пользователя
www-data
$ sudo su # su - www-data
После того, как вы вошли как
www-data
, перейдите в репозиторий git и выполнитеgit pull
вручную.Процесс ssh попросит вас добавить идентификатор сервера GitHub в файл
known_hosts
и использовать пару ключей в/var/www/.ssh
для завершенияgit pull
.Если это удастся, вы должны быть настроены. Попробуйте
push
коммит в GitHub с другого компьютера и убедитесь, что скрипт PHP выполняет запрос наpull
.Сбросьте файл
/etc/passwd
в исходное состояние с помощью оболочки входа пользователяwww-data
как/usr/sbin/nologin
Есть много способов. Вот один из них:
- Этот метод требует только очень простой аутентификации, поэтому создайте UUID для использования в качестве токена аутентификации. Например: https://www.uuidgenerator.net/version4
- Сконфигурируйте веб-крюк репозитория GitHub для запуска веб-крючка, добавив UUID в качестве токена: http://example.com/webhook.php?token=yourUUID
Поместите файл
webhook.php
в корень вашего сайта, который проверяет токен и ничего не делает, кроме как отмечает сайт для обновления:<?php $token = "yourUUID"; if($_GET['token'] != $token) { die("Unauthorized source!"); } else { touch(__DIR__ . '/git_pull_needed'); }
Создать cronjob, который запускается часто (каждую минуту?) и выходит, если файл
git_pull_needed
не существует. Если она существует, то задание может выполнитьgit pull
, после чего удаляетgit_pull_needed
файл. Примечание: пользователь, который запускает этот cronjob, может быть пользователем root или, предпочтительно, пользователем 'deploy', у которого есть ключ SSH с разрешением только для чтения на GitHub и разрешением на запись в webroot.
Основными преимуществами этого развязанного метода являются низкий риск раскрытия webhook.php извне (злоумышленник может вызвать git pull
если он каким-то образом угадывает токен), разъединение между пользователем веб-сервера и удержанием «пользователя» ssh-ключ и встроенное простое ограничение скорости.