Bisakah Anda menentukan git-shell di .ssh /otorized_keys untuk membatasi akses hanya perintah git melalui ssh?

37

Saya ingin dapat menggunakan kunci ssh untuk otentikasi, tetapi masih membatasi perintah yang dapat dieksekusi melalui terowongan ssh.

Dengan Subversion, saya telah mencapai ini dengan menggunakan file .ssh / Authorized_key seperti:

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...

Saya sudah mencoba ini dengan "/ usr / bin / git-shell" di perintah, tapi saya baru saja mendapatkan fatal: What do you think I am? A shell?pesan kesalahan lama yang funky .

Matt Connolly
sumber

Jawaban:

30

Berikut ini berfungsi untuk saya.

Di ~/.ssh/authorized_keys:

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

Dalam ~/gitserveskrip:

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

Perhatikan bahwa jika Anda meletakkan gitservesuatu tempat selain direktori home, Anda harus menyesuaikan command="./gitserve"parameter authorized_keys.

Neil Mayhew
sumber
Bingo! Ini berfungsi seperti yang saya harapkan untuk capai! Terima kasih.
Matt Connolly
Dalam posting terkait ini di SO stackoverflow.com/questions/5871652/... mereka menunjuk ke solusi lain di sini: joey.kitenet.net/blog/entry/locking_down_ssh_authorized_keys
Tim
1
@Tim Ini pada dasarnya adalah solusi yang sama, tetapi meremas isi skrip ~ / gitserve saya menjadi kunci yang diotorisasi dengan menggunakan perl. Secara pribadi, saya lebih suka menyimpannya dalam skrip terpisah.
Neil Mayhew
1
Saya mengerti, saya hanya menambahkannya sebagai referensi.
Tim
Shell apa yang Anda gunakan untuk mengatur pengguna dalam konfigurasi ini? /bin/bash?
M-Pixel
33

Saya bisa berhasil menggunakan git-shell secara langsung dalam file AuthorizedKeys tanpa menggunakan skrip tambahan.

Kuncinya adalah menambahkan \" sekitar variabel env.

Diuji dalam 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...
sophana
sumber
+1 itulah jawaban yang benar, lihat svnweb.freebsd.org/base/head/crypto/openssh/…
Tino
2
Secara pribadi, saya akan memberikan jalan penuh untuk git-shell, tapi itu mungkin hanya paranoia.
Ulrich Schwarz
Adakah yang menemukan cara membatasi direktori yang dapat diaksesnya? Saya menemukan bahwa saya dapat melakukan cd ke direktori sebelum mengeksekusi git-shell, tetapi git-shell memungkinkan ".." dan path absolut.
yokto
5

Solusi Grawity dapat dengan mudah dimodifikasi untuk bekerja dengan mengganti saluran

        exec $SSH_ORIGINAL_COMMAND

dengan garis

        git-shell -c "$SSH_ORIGINAL_COMMAND"

Kutipan mengatasi masalah yang dilaporkan di atas, dan mengganti exec dengan git-shell tampaknya sedikit lebih aman.

Dschwen
sumber
4

git-shelldirancang untuk digunakan sebagai shell login, sehingga akan menerima -c "originalcommand"sebagai argumen. Ini tidak terjadi dengan "perintah paksa" di OpenSSH; sebagai gantinya, perintah paksa diteruskan ke shell yang sudah dikonfigurasi.

Yang dapat Anda lakukan adalah menulis skrip yang memeriksa $SSH_ORIGINAL_COMMANDdan menjalankannya. Contoh dalam 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
grawity
sumber
@ Matt: git-shell (1) mengatakan perintahnya adalah git <cmd>, bukan git-<cmd>?
grawity
Hmm ... Saya membuat perubahan itu sesuai dengan apa yang saya lihat ketika saya menjalankannya. Dengan skrip bash dan skrip ruby, saya melihat "git-accept-pack" sebagai perintah. Kutipan dari saya man git-shell(git 1.7.3.4): Saat ini, hanya empat perintah yang diizinkan untuk dipanggil, git-accept-pack git-upload-pack dan git-unggah-arsip dengan argumen tunggal yang diperlukan, atau server cvs (untuk memanggil git -cvsserver).
Matt Connolly
pemformatan tidak berfungsi dalam komentar :(
Matt Connolly
1
Ini tidak berfungsi untuk saya, karena klien git saya (1.7.5.4) mengirimkan nama repo dalam tanda kutip tunggal, mungkin karena mengharapkan seluruh baris perintah ditafsirkan oleh sebuah shell. Eksekutif $ SSH_ORIGINAL_COMMAND kemudian meneruskan tanda kutip tunggal ke git-accept-pack dll. Yang karenanya tidak menemukan repositori.
Neil Mayhew
Terima kasih atas solusinya, grawity, tetapi itu tidak berhasil untuk saya, untuk alasan yang sama yang dilaporkan oleh Neil Mayhew ... versi git 1.7.x saya juga mengirimkan nama repo dalam tanda kutip tunggal, yang akhirnya menyebabkannya $SSH_ORIGINAL_COMMANDmenjadi tidak valid, dan menyebabkan git-shell
memadamkan
1

Untuk kelengkapan, dan karena pertanyaan awal tidak menentukan bahwa akun yang sama harus dapat digunakan untuk hal-hal non-git, jawaban yang jelas adalah untuk digunakan git-shellseperti yang dirancang untuk digunakan: atur sebagai shell login (yaitu dengan usermod, in /etc/passwd) untuk pengguna ssh itu.

Jika Anda memiliki satu akun pengguna yang ingin Anda gunakan dua cara:

  • saat menghubungkan dengan otentikasi kunci, gunakan hanya untuk git
  • saat menghubungkan dengan otentikasi kata sandi, atau menggunakan kunci pribadi yang berbeda, berikan shell lengkap

... maka jawaban lain di utas ini berlaku. Tetapi jika Anda mampu mengalokasikan pengguna terpisah untuk git, maka mengatur shell-nya git-shelladalah cara termudah untuk membatasinya, dan sedikit lebih aman karena tidak memerlukan skrip shell tambahan.

Felix
sumber