выполнять хуки git в неисполняемой среде / редактировать, как git вызывает хуки

Вопрос: как вы редактируете, как git вызывает ловушку?

TL; DR - безопасность моей хостинг-платформы странная, и мне нужно выяснить, как отредактировать, как git вызывает перехватчик post-receive.

Я пытаюсь настроить автоматическое развертывание через GIT, но в основном люди предлагают это сделать с помощью сценария после получения. Если я вставлю крючки и сделаю

$ sh post-receive

, он работает нормально, но если я

$ ./post-receive

, он будет жаловаться на разрешения, хотя у него

$ chmod 777 post-receive

(что вы можете проверить с помощью $ ls -l).

Вот сообщение, которое я получил от службы поддержки: «Причина в том, что среда SSH смонтирована как неисполняемая среда по соображениям безопасности. Это означает, что вы не можете запускать сценарии только по пути.

Например, running: /www/repos/webprosjekt18.git/hooks/post-receive не будет работать, это выдаст ошибку разрешения.

Запуск: bash /www/repos/webprosjekt18.git/hooks/post-receive будет работать нормально (в зависимости от того, что этот скрипт делает изc, но он, по крайней мере, запустит файл).

Мы думаем, что git по умолчанию запускает хуки, вызывая: /www/repos/webprosjekt18.git/hooks/post-receive, что не сработает. "

удаленный скрипт:

mkdir repos
cd repos
git init --bare
cat > hooks/post-receive <<END
#!/bin/sh
echo "executing post-receive hook"
END
chmod 777 hooks/post-receive
cd hooks
sh post-receive

person Philip Aarseth    schedule 22.03.2018    source источник
comment
Как они это делают? Что произойдет, если вы выполните bash из оболочки, которую вы получите, войдя в систему с помощью ssh. По-прежнему не можете выполнять сценарии? (Это влияет только на сценарии?) Что если вы сделаете PATH=$PATH:., чтобы добавить текущий каталог в PATH?   -  person sneep    schedule 22.03.2018
comment
Что вы имеете в виду, как они это делают? как указано в тексте, сценарий является исполняемым, указав, на каком языке сценария он находится при вызове, но я думаю, что git этого не делает. Если я вставлю крючки и сделаю $ sh post-receive, он будет работать нормально. Также не уверен, где вы предлагаете мне делать материал PATH.   -  person Philip Aarseth    schedule 22.03.2018
comment
Ах, прости. Я думаю, они, должно быть, использовали для этого какие-то странные уловки. Так что мне интересно, могут ли они дать вам какую-то особую оболочку? 1) После входа в систему по ssh попробуйте выполнить, например, /usr/bin/bash (или любая другая оболочка, например /bin/sh, tcsh и т. Д.). Будут ли у итоговой оболочки такие же ограничения? 2) После входа через ssh попробуйте выполнить PATH=$PATH:.. Если вы сделаете это, вы сможете выполнять сценарии по текущему пути, выполняя script.sh, а не ./script.sh. Это работает? 3) Каков результат which bash 4) Выполняется ли _8 _ / _ 9_ при входе в систему?   -  person sneep    schedule 22.03.2018
comment
Кстати, git просто execves скрипты хуков. Я почти уверен, что есть способ обойти безопасность вашей хостинг-платформы. Например, работают ли двоичные исполняемые файлы? Если да, вы могли бы, например, используйте крошечную программу на C, например int main() { system("bash script.sh"); }, в качестве ловушки.   -  person sneep    schedule 22.03.2018


Ответы (2)


Как указано в комментарии sneep, Git, по сути, просто выполняет fork, за которым следует execve пути ловушки, как только он решил запустить некоторую ловушку. (См. Ниже более подробную информацию о «решил запустить некоторую ловушку».) Это означает, что ядро ​​ решает, разрешить ли операцию exec.

Здесь указан конкретный исходный код. Обратите внимание на тестируйте на ENOEXEC, но не на EACCES.

Если вы посмотрите mount документацию по Linux, вы увидите, что параметр noexec запрещает выполнение (выполнение операций) любого файла в этой смонтированной файловой системе. (BSD mount имеет аналогичный вариант, если система хостинга основана на BSD.) В этом случае возвращается ошибка EACCES, а не ENOEXEC. Это означает, что анализ вашей хостинг-системы, что вы буквально не можете этого сделать, верен.


Интересно, что если бы Git запустил ловушку, для которой не задано x бит, в некоторых случаях (не в этих - вы бы захотели испортить «магическое число», чтобы вызвать это, приведенный выше раздел кода мог бы получить ENOEXEC) и второй путь кода, который запускает оболочку на крючке, действительно может работать. Однако код find_hook специально требует access(path, X_OK) успешного выполнения . Для этого необходимо установить x бит и смонтировать файловую систему без noexec < / а>.

Вы можете попробовать создать вариантную версию Git, которая изменяет эти тесты, и попросить вашу хостинговую компанию установить ее как свою версию Git, но если они захотят это сделать, они, вероятно, захотят разместить ваши репозитории в файловой системе, которая позволяет exec.

person torek    schedule 22.03.2018

На самом деле это не ответ, поскольку он во многом основан на предположении @torek о том, что он, вероятно, использует параметр монтирования NOEXEC. Итак, как насчет этого обходного пути: вы можете добавить ловушку, которая представляет собой символическую ссылку на /usr/bin/script (символические ссылки на другие файловые системы выполняются даже с NOEXEC). script выполнит bash, а bash будет думать, что это в терминале. (Если вы просто сделаете символическую ссылку на /bin/bash в каталоге hooks, bash откажется от этого, увидев, что он не может open /dev/tty, но script позаботится об этом за нас.) Если мы поместим некоторый код в ~/.bashrc, чтобы определить, было ли это вызвано как ловушка git , выполняем настоящий скрипт. Таким образом, мы могли бы поместить это прямо в начало /.bashrc:

pppid=$(ps -o ppid= $PPID) # determine grandparent PID
ppproc=$(ps -o comm= $pppid) # determine grandparent process name
if [ "$ppproc" == "git" ]; then # is it 'git'?
    echo running from git @ `date` # call script here
    exit
else
    echo not running from git # you might want to remove this
fi

Пример:

$ touch test15
$ git add test15
$ git commit -m "Test15"
Script started, file is typescript
running from git @ Fri Mar 23 13:19:54 JST 2018
Script done, file is typescript
[master 608083b] Test15
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 test15

(Это создает файл с именем typescript в вашем каталоге Git.)

person sneep    schedule 23.03.2018
comment
Довольно впечатляющий трюк. Мне неясно, может ли кто-нибудь рассмотреть возможность перехода по символическим ссылкам за пределами точки монтирования, что приведет к тому, что выполнение exec будет ошибкой. Кажется, что он не открывает много банок с червями, так что, в конце концов, это может быть нормально, но, используя ваш трюк, он действительно позволяет некоторые вещи, которые кто-то может подумать невозможным (я действительно думал, что это невозможно!). - person torek; 26.03.2018