您可以在遥控器上编写一个包装脚本,并将 command="/path/to/wrapper" 附加到授权密钥的行中。
command="/usr/local/bin/gitaccess" ssh-rsa ...
在这个包装器中,您将检查 SSH_ORIGINAL_COMMAND。Git 发出以下命令:
git receive-pack '/path/provided' # when pushing
git upload-pack '/path/provided' # when pulling
如果 SSH_ORIGINAL_COMMAND 不为空并且以其中之一开头,则检查路径,必要时创建存储库,在其中安装所需的任何配置,然后执行命令。
如果 SSH_ORIGINAL_COMMAND 为空并且您想为用户提供 shell 访问权限,则调用 shell。
如果 SSH_ORIGINAL_COMMAND 不为空但不以 git 命令开头,如果您想允许用户拥有 shell 访问权限,您只需执行提供的命令即可。
这里有一些 Ruby 代码来演示。请注意,我没有对其进行测试,并且还有改进的空间(例如,我们不应该对 /bin/bash 进行硬编码)。
#!/usr/bin/env ruby
orig_command = ENV['SSH_ORIGINAL_COMMAND']
if orig_command.nil?
# If you want to preserve shell access
exec '/bin/bash' # not tested, I hope it's interactive if executed this way
end
cmd_parts = orig_command.match /([a-z-]+) '([a-z0-9.\/]+)'/
if cmd_parts.nil?
# If you want to preserve shell access
exec '/bin/bash', '-c', orig_command
end
command = cmd_parts[1]
path = '/var/repositories/'+cmd_parts[2] # not secured (could contain '..')
if command == 'git-receive-pack' || command == 'git-upload-pack'
if not File.directory?(path)
`git init --bare #{path}` # not secured, I didn't escape path
# Do any configuration here
end
exec 'git-shell', '-c', "#{command} '#{path}'"
end
# If you want to preserve shell access
exec '/bin/bash', '-c', orig_command
您还可以在 authorized_keys 中将参数传递给此脚本,以识别用户并选择他们是否应该具有 shell 访问权限。我也这样做是为了控制每个存储库的访问。如果您想将此参数带到 git 挂钩,只需创建一个环境变量。