Чи можете ви вказати git-shell у .ssh / санкціонованих_кеях, щоб обмежити доступ лише до команд git через ssh?


37

Я хотів би мати можливість використовувати ключ ssh для автентифікації, але все ж обмежувати команди, які можна виконати над тунелем ssh.

За допомогою Subversion я досяг цього, використовуючи файл .ssh / санкціонований_кейс на зразок:

command="/usr/local/bin/svnserve -t --tunnel-user matt -r /path/to/repository",no-port-forwarding,no-agent-forwarding,no-X11-forwarding,no-pty ssh-rsa AAAAB3NzaC1yc2EAAAABIetc...

Я спробував це з командою "/ usr / bin / git-shell", але я просто отримую старе fatal: What do you think I am? A shell?повідомлення про помилку.

Відповіді:


30

Наступні роботи для мене.

В ~/.ssh/authorized_keys:

command="./gitserve",no-port-forwarding,no-agent-forwarding,no-X11-forwarding,no-pty ssh-dss AAAAB…

У ~/gitserveсценарії:

#!/bin/sh
exec git-shell -c "$SSH_ORIGINAL_COMMAND"

Зауважте, що якщо ви розмістите gitserveдесь інше, ніж домашній каталог, вам доведеться налаштувати command="./gitserve"параметр в authorized_keys.


Бінго! Це працює так само, як я сподівався досягти! Спасибі.
Метт Конноллі

У цій пов’язаній публікації про SO stackoverflow.com/questions/5871652/… вони вказують на інше рішення тут: joey.kitenet.net/blog/entry/locking_down_ssh_authorized_keys
Тім,

1
@Tim Це по суті те саме рішення, але видавлює вміст мого сценарію ~ / gitserve в авторизовані ключі, використовуючи perl. Особисто я вважаю за краще зберігати його в окремому сценарії.
Ніл Мейхев

1
Я розумію, я просто додав це як посилання.
Тім

Яку оболонку у вас встановлено користувачем у цій конфігурації? /bin/bash?
M-Pixel

33

Я міг успішно використовувати git-shell безпосередньо у файлі санкціонованих ключів без використання додаткового сценарію.

Ключ полягає в тому, щоб додати \"навколо змінної env.

Тестовано на rhel6 openssh-server-5.3p1-70.el6.x86_64:

no-port-forwarding,no-agent-forwarding,command="git-shell -c \"$SSH_ORIGINAL_COMMAND\"" ssh-dss AAAA...

+1 - це правильна відповідь, див. Svnweb.freebsd.org/base/head/crypto/openssh/…
Tino

2
Особисто я хотів би дати повний шлях до цього git-shell, але це може бути просто параною.
Ульріх Шварц

Хтось знайшов спосіб обмеження каталогу, до якого він має доступ? Я виявив, що я можу записатись до каталогу перед виконанням git-shell, але git-shell дозволяє ".." та абсолютні шляхи.
Йокто

5

Рішення Grawity можна легко змінити для роботи, замінивши лінію

        exec $SSH_ORIGINAL_COMMAND

з лінією

        git-shell -c "$SSH_ORIGINAL_COMMAND"

Котирування вирішують проблеми, про які повідомлялося вище, а заміна exec на git-shell здається трохи безпечнішою.


4

git-shellпризначений для використання в якості оболонки для входу, щоб він отримав -c "originalcommand"як аргументи. Цього не відбувається з «примусовими командами» у OpenSSH; натомість примусова команда передається налаштованій оболонці.

Що ви можете зробити - це написати сценарій, який перевіряє $SSH_ORIGINAL_COMMANDта виконує його. Приклад в bash :

#!/bin/bash

SSH_ORIGINAL_COMMAND=${SSH_ORIGINAL_COMMAND/#git /git-}

case $SSH_ORIGINAL_COMMAND in
    "git-receive-pack"*|"git-upload-pack"*|"git-upload-archive"*)
        eval exec $SSH_ORIGINAL_COMMAND
        ;;
    *)
        echo "Go away." >&2
        exit 1
        ;;
esac

@Matt: git-shell (1) каже, що команди є git <cmd>, чи не так git-<cmd>?
grawity

Гм ... Я змінив цю зміну відповідно до того, що бачив, коли я її провів. Як і bash-скрипт, так і ruby-скрипт, я бачив "git-rece-pack" як команду. Цитата з мого man git-shell(git 1.7.3.4): На даний момент дозволяється викликати лише чотири команди, git-accept-pack git-upload-pack та git-upload-archive з одним необхідним аргументом або сервер cvs (для виклику git -cvsserver).
Метт Конноллі

форматування не працює в коментарях :(
Метт Конноллі

1
Це не працює для мене, тому що мій клієнт git (1.7.5.4) надсилає ім'я репо в одних лапках, імовірно, тому, що він очікує, що весь командний рядок буде інтерпретований оболонкою. Потім exec $ SSH_ORIGINAL_COMMAND передає єдині лапки в git-accept-pack і т.д., які не знаходять сховища.
Ніл Мейх'ю

Дякую за рішенням, grawity, але це не працює для мене, з тієї ж причини , що було повідомлено Ніл Мейхью ... моя 1.7.x версія мерзотника також відправляє ім'я репо в одинарних лапках, в кінцевому рахунку , в результаті чого $SSH_ORIGINAL_COMMANDбуде недійсний і спричиняє git-shell
випирання

1

Я не міг отримати рішення grawity для роботи з тієї ж причини, про яку повідомляв Ніл Мейхью (тобто єдині цитати, надіслані клієнтом git, що викликають недійсність $SSH_ORIGINAL_COMMAND- я використовую git v1.7.x)

Однак таке рішення, реалізоване @moocode, просто працює:

https://moocode.com/posts/6-code-your-own-multi-user-private-git-server-in-5-minutes

Ruby FTW! :-)


1

Для повноти, і оскільки в початковому запитанні не було вказано, що той самий обліковий запис повинен бути використаний для не-git речей, очевидною відповіддю є використання, git-shellяк було призначено для використання: встановити його як оболонку входу (тобто з usermod, в /etc/passwd) для цього користувача ssh.

Якщо у вас є один обліковий запис користувача, який потрібно використовувати двома способами:

  • під час з'єднання з аутентифікацією ключа використовуйте лише для git
  • під час підключення за допомогою автентифікації пароля або використання іншого приватного ключа надайте повну оболонку

... тоді застосовуються інші відповіді в цій темі. Але якщо ви можете дозволити собі виділити окремого користувача для git, то встановлення його оболонки git-shell- це найпростіший спосіб її обмеження, і трохи безпечніший, оскільки не потребує додаткових скриптів оболонки.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.