【问题标题】:git insufficient permission for adding an object to local git server repositorygit 权限不足,无法将对象添加到本地 git 服务器存储库
【发布时间】:2016-05-15 23:33:47
【问题描述】:

我有一个 www-dataphp 一起运行,它控制着一个 git 服务器。 www-data 用户创建 Unix 用户(给它sudo adduser),这些用户应该控制他们自己的私有 git 目录,每个用户都可以在其中存放他/她的存储库。

我已经关注this guide至少十次了,除此之外,我也是following this guide为了创建git服务器。

  • Apache 添加了一个unix 用户bar,在/var/www/git/bar 中有一个家,并且该用户没有密码(--disable-password

  • 用户bar 是组gitusers 的一部分,该组允许+rwx 访问组成员,并且他的shell 设置为/usr/bin/git-shell

  • 这样做是为了让www-data 可以访问他的主目录并使用存储库和 ssh 密钥填充它。

  • 骨架主目录也填充了git-shell-commands,用户www-data创建了一个/var/www/git/bar/.ssh/authorized_keys,它在其中附加了我的测试用户 foo 公钥。

www-data 添加一个新用户,然后添加一个新存储库时:

sudo adduser --disabled password\
             --home /var/www/git/bar\
             --conf /var/www/conf/adduser.conf\
             --ingroup gitusers\
             bar

上面的^^是通过php完成的。 .sshauthorized_keyswww-data 所有。

然后www-data继续创建一个新目录并初始化它:

  • mkdir /var/www/git/bar/test.git
  • cd /var/www/git/bar/test
  • git --bare init

我的测试用户foo 可以从 ssh 读取它(它只是克隆一个空的存储库)。 一旦我尝试推送初始提交:

git clone ssh://foo@localhost:/var/www/git/bar/test.git
cd test
touch readme
vim readme
git add .
git commit -m "init"
git push origin master
foo@127.0.0.1's password:
Counting objects: 6, done.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (6/6), 411 bytes | 0 bytes/s, done.
Total 6 (delta 0), reused 0 (delta 0)
remote: error: insufficient permission for adding an object to repository database ./objects
remote: fatal: failed to write object
error: unpack failed: unpack-objects abnormal exit
To ssh://foo@localhost:/var/www/git/bar/random.git
 ! [remote rejected] master -> master (unpacker error)
error: failed to push some refs to 'ssh://foo@localhost:/var/www/git/bar/random.git'

我被要求输入foo 用户的密码(即拥有公钥的用户)。

这不是拥有主目录的 Unix 用户,而是拥有禁用密码的用户 bar

  1. 为什么要求我输入 ssh 密码?他们不应该使用 ssh 密钥来解决这个问题吗?
  2. 如果我创建一个bar with 密码,那么我可以使用该git 存储库,将foo@localhost:/var/www/git/bar 替换为bar@localhost:/var/www/git/bar
  3. 当我完全不使用ssh:// 时,我仍然可以使用clone,但在推送为foo 时会出现相同的错误,但如果我启用了密码,则不是bar

我做错了什么?

是不是.sshauthorized_keys的权限太开放或者不属于bar

即使我(以 sudo 身份)进入 bar homedir 并让所有东西都归他所有,我仍然遇到同样的错误。

最后,我为测试用户foo 设置了我的.ssh/config,以便:

Host localhost
     Hostname 127.0.0.1
     IdentityFile ~/.ssh/foo
     User foo

【问题讨论】:

  • 虽然这不是您问题的答案,但我认为您以错误的方式攻击它。看看 gitolite,如果它(也不是 gitlab)不符合你的需求,看看他们如何实现让用户拥有私有存储库。为所有用户设置一个 git 用户是一种更简单的解决方案。许多 unix 用户很难以好的方式取得成功。

标签: php git apache shell ssh


【解决方案1】:

事实证明确实是权限。 跟踪/var/log/auth.log 提供了见解:

Authentication refused: bad ownership or modes for directory /var/www/git/bar

用谷歌搜索我发现问题在于该组可以访问整个主目录。

所以回到第一方,允许www-data 成为具有+rwx 的组的一部分是不可能的,因为它会破坏 ssh。

编辑:

iveqy 的评论非常明智,使用 unix 用户进行此类操作是一种过度杀伤,并且会打开潜在的安全漏洞,因为它需要您将用户 www-data 升级为超级用户。

我最终通过以下方式使用gitolite-admin(我添加它以供将来参考www-data Debian/Ubuntu 下的 apache 用户如何控制 gitolite)。

说明

网络服务器 apache2 在系统上以www-data 运行。 所有 php 脚本都以www-data 执行。 这就要求我们让这个用户能够自动管理我们的 git 服务器。

gitolite 要工作,需要管理员提供 ssh 密钥。 这反过来又要求用户 www-data (apache2) 有一对 ssh 密钥。 密钥对必须受到保护否则 ssh 将无法工作:

  • 创建一个新用户git,主目录位于:/var/www/git
  • sudo adduser git --home /var/www/git
  • cd 进入/var/dir/git 并删除所有骨架文件(.bashrc、.profile、.bash_logout)
  • 本地登录为用户 git:su - git 并使用您之前创建的密码
  • 确保 git 用户主目录的权限设置为 755 (g+rx)
  • 创建.ssh 目录:mkdir .ssh,然后将其设为私有:chmod 700 -R .ssh

现在以www-data 创建您的 ssh 密钥(从git 用户退出):

  • 进入/var/www/ 并创建一个由www-data 拥有的./ssh,并带有700 掩码。
  • sudo -u www-data ssh-keygen -t rsa

如果一切顺利,请将您的 /var/www/.ssh/id_rsa.pub 复制到 /var/www/git/.ssh/

  • 将密钥所有权授予用户git: sudo chown git.git .ssh/id_rsa.pub
  • git重新登录:su - git
  • 将 pub 密钥设为私有:chmod 600 .ssh/id_rsa.pub

安装时间gitolite

  • git clone git://github.com/sitaramc/gitolite
  • mkdir -p $HOME/bin
  • gitolite/install -to $HOME/bin

设置www-data公共rsa密钥作为gitolite的管理员:

  • $HOME/bin/gitolite setup -pk .ssh/id_rsa.pub

你应该得到:

Initialised empty Git repository in /var/www/git/repositories/gitolite-admin.git/ Initialised empty Git repository in /var/www/git/repositories/testing.git/ WARNING: /var/www/git/.ssh/authorized_keys missing; creating a new one (this is normal on a brand new install)

用户git 现已设置完毕。 注销:exit

从现在开始不要触摸目录 /var/www/git

我们将在本地克隆它,并从那里控制它。 将其克隆为用户www-data

  • 首先创建www-data拥有的本地副本:sudo mkdir gitolite-admin && chown -R www-data.www-data gitolite-admin/
  • 然后以用户www-data 执行命令:sudo -u www-data git clone git@localhost:gitolite-admin gitolite-admin/

这会克隆/var/www/gitolite-admin 中的gitolite-admin,您可以从中控制gitolite 服务器。

有关如何控制 gitolite-server 的说明,请参阅:https://github.com/sitaramc/gitolite

从现在开始,您执行的任何 gitolite 命令都以用户 www-data 的身份执行。 以rootsudo 运行的任何命令都会破坏服务器!

PS:如果这破坏了您的 apache 配置,我不承担任何责任。我希望它可以帮助任何出于同样原因来到这里的人:创建一个 git 服务器。我愿意接受建议和更好的想法或改进。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-15
    • 1970-01-01
    • 2021-04-23
    • 1970-01-01
    • 2012-07-08
    • 1970-01-01
    • 2015-12-16
    • 1970-01-01
    相关资源
    最近更新 更多