运行 git 具有只读用户的守护程序提供 "fatal: cannot drop privileges"
Running git daemon with read only user gives "fatal: cannot drop privileges"
我不确定这是否是正确的部分 post,如果不是,请告诉我应该在哪里 post 以下问题:
我在局域网上有两台机器:一台有 OS X Yosemite 作为 Git 服务器,另一台笔记本电脑 运行ning Ubuntu 作为 Git 客户端通过 git://
.
访问只读存储库
我正在阅读 Git 这本书。这里 https://git-scm.com/book/it/v2/Git-on-the-Server-Git-Daemon,Scott Chacon 说:
For security reasons, it is strongly encouraged to have this daemon run as a user with read-only permissions to the repositories – you can easily do this by creating a new user git-ro and running the daemon as them. For the sake of simplicity we’ll simply run it as the same git user that Gitosis is running as.
运行 git 守护程序的命令是:
/usr/bin/git daemon --base-path=/opt/git/ /opt/git/
现在,我可以 运行 漂亮地使用 OS X 机器上的当前用户(我当前的用户也是管理员)和 Git 读取的命令没有任何问题只有守护进程启动,但是一旦我尝试 运行 它作为一个非特权用户,它对 repo 具有只读访问权限(在我的例子中,用户 git-ro
,如书中所建议的),git daemon
抱怨不启动:
$ /usr/bin/git daemon \
--user=git-ro --group=git-ro \
--reuseaddr \
--base-path=/opt/git/ \
/opt/git/
fatal: cannot drop privileges
我正在 运行 在 OS X 的 Terminal.app 上执行命令,我还没有设置 git 守护进程在启动时启动,因为我只是想在设置之前先看看它是如何工作的。
cannot drop privileges
是什么意思,我如何解决和 运行 具有对存储库具有只读权限的非特权用户的守护程序?
感谢关注!
编辑:这里http://git.661346.n2.nabble.com/regression-quot-96b9e0e3-config-treat-user-and-xdg-config-permission-problems-as-errors-quot-busted-n-td7582202.html#d1365658927000-296 问题似乎与执行命令的HOME 目录有关,不是吗?如果是这样,我应该如何处理?
编辑 2:这里是带有 sudo 的命令 运行:
$ sudo git daemon --reuseaddr --user=git-ro --group=git-ro --base-path=/opt/git/ /opt/git/
守护进程启动,但是我有它的三个进程 运行ning,其中两个作为 root:
$ ps aux | grep "git-ro"
git-ro 1477 0.0 0.0 2471332 1424 s000 S+ 7:34PM 0:00.01 git-daemon --reuseaddr --user=git-ro --group=git-ro --base-path=/opt/git/ /opt/git/
root 1476 0.0 0.0 2464108 1608 s000 S+ 7:34PM 0:00.01 git daemon daemon --reuseaddr --user=git-ro --group=git-ro --base-path=/opt/git/ /opt/git/
root 1475 0.0 0.1 2452612 2612 s000 S+ 7:34PM 0:00.01 sudo git daemon --reuseaddr --user=git-ro --group=git-ro --base-path=/opt/git/ /opt/git/
为什么守护进程仍然 运行 作为 root 有两个进程?这是预期的行为还是我应该进一步改进?
编辑 3:此外,为什么如果我改为 运行 lsof
并检查端口 9418 上正在侦听的内容,我看到 git-ro
持有的两行具有相同的 pid?这怎么可能? git daemon
进程 运行 作为 root 到哪里去了?
$ sudo lsof -i :9418
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
git-daemo 1477 git-ro 5u IPv4 0xce9b2f57e8d5af93 0t0 TCP *:git (LISTEN)
git-daemo 1477 git-ro 6u IPv6 0xce9b2f57e60cacc3 0t0 TCP *:git (LISTEN)
消息来自 git 的 daemon.c
:
中的函数 drop_privileges
static void drop_privileges(struct credentials *cred)
{
if (cred && (initgroups(cred->pass->pw_name, cred->gid) ||
setgid (cred->gid) || setuid(cred->pass->pw_uid)))
die("cannot drop privileges");
}
请注意,如果 cred
是 NULL
,则此函数相当于一个大空操作。如果 cred
不是 而不是 NULL
程序必须 运行ning 作为超级用户,并且 initgroups、setgid 和 setuid 序列是有意的(正如函数名称所暗示的那样)放弃其超级用户权限并继续 运行ning 而不是作为提供的用户和组。
此函数在同一文件中从 serve
调用,守护程序启动时从 main
调用:
int main(int argc, char **argv)
{
...
return serve(&listen_addr, listen_port, cred);
此处的 cred
参数通过 serve
传递到 drop_privileges
,因此具有直接意义。那么 cred
在哪里设置?让我们多看一点 main
,其中 cred
被初始化,然后被修改:
struct credentials *cred = NULL;
...
if (user_name)
cred = prepare_credentials(user_name, group_name);
所以现在我们需要找到user_name
在哪里设置and/or修改:
const char *pid_file = NULL, *user_name = NULL, *group_name = NULL;
...
if (skip_prefix(arg, "--user=", &v)) {
user_name = v;
continue;
}
此时,即使不查看 skip_prefix
,也应该很明显它来自您提供的 --user=...
参数,如果您不提供,user_name
将保持 NULL
以便 cred
将保持 NULL
以便 drop_privileges
将不执行任何操作并且该命令将 运行 与调用它的人一样(即您自己,而不是提供的用户名)。
简而言之,除非您运行以超级用户身份使用它(例如,使用sudo
),否则不要给它一个 --user=
选项,因为它所做的就是让它在启动时像这样失败。
这个问题和 $HOME
的问题也在 the manual page 中提到(尽管下面的格式来自我的本地 git help daemon
输出而不是 kernel.org link):
--user=<user>, --group=<group>
Change daemon's uid and gid before entering the service loop. When
only --user is given without --group, the primary group ID for the
user is used. The values of the option are given to getpwnam(3) and
getgrnam(3) and numeric IDs are not supported.
Giving these options is an error when used with --inetd; use the
facility of inet daemon to achieve the same before spawning git
daemon if needed.
Like many programs that switch user id, the daemon does not reset
environment variables such as $HOME when it runs git programs, e.g.
upload-pack and receive-pack. When using this option, you may also
want to set and export HOME to point at the home directory of
<user> before starting the daemon, and make sure any Git
configuration files in that directory are readable by <user>.
我不确定这是否是正确的部分 post,如果不是,请告诉我应该在哪里 post 以下问题:
我在局域网上有两台机器:一台有 OS X Yosemite 作为 Git 服务器,另一台笔记本电脑 运行ning Ubuntu 作为 Git 客户端通过 git://
.
我正在阅读 Git 这本书。这里 https://git-scm.com/book/it/v2/Git-on-the-Server-Git-Daemon,Scott Chacon 说:
For security reasons, it is strongly encouraged to have this daemon run as a user with read-only permissions to the repositories – you can easily do this by creating a new user git-ro and running the daemon as them. For the sake of simplicity we’ll simply run it as the same git user that Gitosis is running as.
运行 git 守护程序的命令是:
/usr/bin/git daemon --base-path=/opt/git/ /opt/git/
现在,我可以 运行 漂亮地使用 OS X 机器上的当前用户(我当前的用户也是管理员)和 Git 读取的命令没有任何问题只有守护进程启动,但是一旦我尝试 运行 它作为一个非特权用户,它对 repo 具有只读访问权限(在我的例子中,用户 git-ro
,如书中所建议的),git daemon
抱怨不启动:
$ /usr/bin/git daemon \
--user=git-ro --group=git-ro \
--reuseaddr \
--base-path=/opt/git/ \
/opt/git/
fatal: cannot drop privileges
我正在 运行 在 OS X 的 Terminal.app 上执行命令,我还没有设置 git 守护进程在启动时启动,因为我只是想在设置之前先看看它是如何工作的。
cannot drop privileges
是什么意思,我如何解决和 运行 具有对存储库具有只读权限的非特权用户的守护程序?
感谢关注!
编辑:这里http://git.661346.n2.nabble.com/regression-quot-96b9e0e3-config-treat-user-and-xdg-config-permission-problems-as-errors-quot-busted-n-td7582202.html#d1365658927000-296 问题似乎与执行命令的HOME 目录有关,不是吗?如果是这样,我应该如何处理?
编辑 2:这里是带有 sudo 的命令 运行:
$ sudo git daemon --reuseaddr --user=git-ro --group=git-ro --base-path=/opt/git/ /opt/git/
守护进程启动,但是我有它的三个进程 运行ning,其中两个作为 root:
$ ps aux | grep "git-ro"
git-ro 1477 0.0 0.0 2471332 1424 s000 S+ 7:34PM 0:00.01 git-daemon --reuseaddr --user=git-ro --group=git-ro --base-path=/opt/git/ /opt/git/
root 1476 0.0 0.0 2464108 1608 s000 S+ 7:34PM 0:00.01 git daemon daemon --reuseaddr --user=git-ro --group=git-ro --base-path=/opt/git/ /opt/git/
root 1475 0.0 0.1 2452612 2612 s000 S+ 7:34PM 0:00.01 sudo git daemon --reuseaddr --user=git-ro --group=git-ro --base-path=/opt/git/ /opt/git/
为什么守护进程仍然 运行 作为 root 有两个进程?这是预期的行为还是我应该进一步改进?
编辑 3:此外,为什么如果我改为 运行 lsof
并检查端口 9418 上正在侦听的内容,我看到 git-ro
持有的两行具有相同的 pid?这怎么可能? git daemon
进程 运行 作为 root 到哪里去了?
$ sudo lsof -i :9418
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
git-daemo 1477 git-ro 5u IPv4 0xce9b2f57e8d5af93 0t0 TCP *:git (LISTEN)
git-daemo 1477 git-ro 6u IPv6 0xce9b2f57e60cacc3 0t0 TCP *:git (LISTEN)
消息来自 git 的 daemon.c
:
drop_privileges
static void drop_privileges(struct credentials *cred)
{
if (cred && (initgroups(cred->pass->pw_name, cred->gid) ||
setgid (cred->gid) || setuid(cred->pass->pw_uid)))
die("cannot drop privileges");
}
请注意,如果 cred
是 NULL
,则此函数相当于一个大空操作。如果 cred
不是 而不是 NULL
程序必须 运行ning 作为超级用户,并且 initgroups、setgid 和 setuid 序列是有意的(正如函数名称所暗示的那样)放弃其超级用户权限并继续 运行ning 而不是作为提供的用户和组。
此函数在同一文件中从 serve
调用,守护程序启动时从 main
调用:
int main(int argc, char **argv)
{
...
return serve(&listen_addr, listen_port, cred);
此处的 cred
参数通过 serve
传递到 drop_privileges
,因此具有直接意义。那么 cred
在哪里设置?让我们多看一点 main
,其中 cred
被初始化,然后被修改:
struct credentials *cred = NULL;
...
if (user_name)
cred = prepare_credentials(user_name, group_name);
所以现在我们需要找到user_name
在哪里设置and/or修改:
const char *pid_file = NULL, *user_name = NULL, *group_name = NULL;
...
if (skip_prefix(arg, "--user=", &v)) {
user_name = v;
continue;
}
此时,即使不查看 skip_prefix
,也应该很明显它来自您提供的 --user=...
参数,如果您不提供,user_name
将保持 NULL
以便 cred
将保持 NULL
以便 drop_privileges
将不执行任何操作并且该命令将 运行 与调用它的人一样(即您自己,而不是提供的用户名)。
简而言之,除非您运行以超级用户身份使用它(例如,使用sudo
),否则不要给它一个 --user=
选项,因为它所做的就是让它在启动时像这样失败。
这个问题和 $HOME
的问题也在 the manual page 中提到(尽管下面的格式来自我的本地 git help daemon
输出而不是 kernel.org link):
--user=<user>, --group=<group>
Change daemon's uid and gid before entering the service loop. When
only --user is given without --group, the primary group ID for the
user is used. The values of the option are given to getpwnam(3) and
getgrnam(3) and numeric IDs are not supported.
Giving these options is an error when used with --inetd; use the
facility of inet daemon to achieve the same before spawning git
daemon if needed.
Like many programs that switch user id, the daemon does not reset
environment variables such as $HOME when it runs git programs, e.g.
upload-pack and receive-pack. When using this option, you may also
want to set and export HOME to point at the home directory of
<user> before starting the daemon, and make sure any Git
configuration files in that directory are readable by <user>.