Você pode especificar o git-shell em .ssh / allowed_keys para restringir o acesso apenas aos comandos git via ssh?


37

Eu gostaria de poder usar uma chave ssh para autenticação, mas ainda assim restringir os comandos que podem ser executados no túnel ssh.

Com o Subversion, consegui isso usando um arquivo .ssh / allowed_keys como:

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

Eu tentei isso com "/ usr / bin / git-shell" no comando, mas recebo apenas a antiga fatal: What do you think I am? A shell?mensagem de erro antiga .

Respostas:


30

O seguinte funciona para mim.

Em ~/.ssh/authorized_keys:

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

No ~/gitservescript:

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

Note que se você colocar gitservealgum lugar diferente do diretório home, você terá que ajustar o command="./gitserve"parâmetro authorized_keys.


Bingo! Isso funciona exatamente como o que eu esperava alcançar! Obrigado.
Matt Connolly

Neste post relacionado no SO stackoverflow.com/questions/5871652/... eles apontam para uma outra solução aqui: joey.kitenet.net/blog/entry/locking_down_ssh_authorized_keys
Tim

11
@ Tim Esta é essencialmente a mesma solução, mas comprime o conteúdo do meu script ~ / gitserve em chaves autorizadas usando perl. Pessoalmente, prefiro mantê-lo em um script separado.
Neil Mayhew

11
Entendo, apenas o adicionei como referência.
Tim

Em qual shell você definiu o usuário nesta configuração? /bin/bash?
M-Pixel

33

Eu poderia usar o git-shell com sucesso diretamente no arquivo allowedKeys sem usar um script adicional.

A chave é adicionar em \"torno da variável env.

Testado em 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 é a resposta correta, consulte svnweb.freebsd.org/base/head/crypto/openssh/…
Tino

2
Pessoalmente, eu daria o caminho completo git-shell, mas isso pode ser apenas paranóia.
Ulrich Schwarz

Alguém encontrou uma maneira de restringir o diretório ao qual ele tem acesso? Eu descobri que posso cd em um diretório antes de executar o git-shell, mas o git-shell permite ".." e caminhos absolutos.
yokto

5

A solução da Grawity pode ser facilmente modificada para funcionar, substituindo a linha

        exec $SSH_ORIGINAL_COMMAND

com a linha

        git-shell -c "$SSH_ORIGINAL_COMMAND"

As aspas resolvem os problemas relatados acima e a substituição de exec por git-shell parece um pouco mais segura.


4

git-shellfoi projetado para ser usado como um shell de logon, para receber -c "originalcommand"como argumentos. Isso não acontece com "comandos forçados" no OpenSSH; em vez disso, o comando forçado é passado para o shell configurado.

O que você pode fazer é escrever um script que o verifique $SSH_ORIGINAL_COMMANDe execute. Exemplo no 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) diz que os comandos git <cmd>não são git-<cmd>?
grawity

Hmm ... fiz essa alteração de acordo com o que vi quando a executei. Com o script bash e o ruby, vi "git-receive-pack" como o comando. Citação de my man git-shell(git 1.7.3.4): Atualmente, apenas quatro comandos podem ser chamados, git-receive-pack git-upload-pack e git-upload-archive com um único argumento necessário ou servidor cvs (para chamar o git -cvsserver).
Matt Connolly

formatação não funciona nos comentários :(
Matt Connolly

11
Isso não funciona para mim, porque meu cliente git (1.7.5.4) envia o nome do repo entre aspas simples, presumivelmente porque espera ter toda a linha de comando interpretada por um shell. O exec $ SSH_ORIGINAL_COMMAND passa as aspas simples para o git-receive-pack etc. que, portanto, não encontram o repositório.
Neil Mayhew

Obrigado pela solução, grawity, mas não funciona para mim, pelo mesmo motivo relatado por Neil Mayhew ... minha versão 1.7.x do git também envia o nome do repo entre aspas simples, fazendo $SSH_ORIGINAL_COMMANDcom que seja inválido, e causando git-shellbum out :-(
pvandenberk


1

Para garantir a integridade, e como a pergunta original não especificou que a mesma conta deveria ser usada para coisas que não são do git, a resposta óbvia é usar git-shellcomo foi projetada para ser usada: defina-a como o shell de login (ou seja usermod, com , in /etc/passwd) para esse usuário ssh.

Se você possui uma única conta de usuário que deseja usar de duas maneiras:

  • ao conectar com autenticação de chave, use apenas para git
  • ao conectar-se com autenticação por senha ou usar uma chave privada diferente, forneça um shell completo

... então as outras respostas neste tópico se aplicam. Mas se você puder alocar um usuário separado para o git, definir seu shell como git-shella maneira mais simples de restringi-lo e é um pouco mais seguro, pois não requer scripts de shell adicionais.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.