我有一个www-data
在运行php
它控制着一个git服务器。www-data
用户创建Unix用户(已将其sudo adduser
(,这些用户应该控制自己的私有git目录,每个用户可以在其中容纳他/她的存储库。
我已经遵循了本指南至少十次,除此之外,我还遵循本指南以创建 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 完成的。.ssh
和authorized_keys
归www-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
。
- 为什么要求我输入 SSH 密码? 他们不应该用 SSH 密钥来处理这个问题吗?
- 如果我使用密码创建一个
bar
,那么我可以使用该 git 存储库,将foo@localhost:/var/www/git/bar
替换为bar@localhost:/var/www/git/bar
- 当我根本不使用
ssh://
时,我仍然可以clone
,但在推送时foo
但bar
时出现相同的错误,前提是我启用了密码。
我做错了什么?
是因为.ssh
和authorized_keys
的权限太开放还是不属于bar
?
即使我(作为sudo(进入bar
homedir并将所有东西归他所有,我仍然会遇到同样的错误。
最后,我为测试用户foo
设置了.ssh/config
,以便:
Host localhost
Hostname 127.0.0.1
IdentityFile ~/.ssh/foo
User foo
这确实是权限。尾随/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
(我添加它是为了将来参考 Debian/Ubuntu 下的 apache 用户如何控制 gitolite www-data
(。
指示
网络服务器 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 拥有并带有掩码700
./ssh
。 -
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
设置要用作 gitolite 管理员的www-data
公共 rsa 密钥:
-
$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 服务器的说明,请参阅:https://github.com/sitaramc/gitolite
从现在开始,您执行的任何 gitolite 命令,都以用户www-data
执行它。任何以root
或sudo
运行命令都会破坏服务器!