2

我不确定这是否是在哪里发布的正确部分,如果不是,请告诉我应该在哪里发布以下问题:

我在一个有两台机器的局域网上:一台装有 OS X Yosemite,充当 Git 服务器,另一台运行 Ubuntu 的笔记本电脑充当 Git 客户端,通过git://.

我正在阅读 Git 书籍。在这里https://git-scm.com/book/it/v2/Git-on-the-Server-Git-Daemon,Scott Chacon 说:

出于安全原因,强烈建议让这个守护进程以对存储库具有只读权限的用户身份运行——您可以通过创建新用户 git-ro 并以他们的身份运行守护进程来轻松做到这一点。为了简单起见,我们将简单地以与 Gitosis 相同的 git 用户身份运行它。

运行 git 守护进程的命令是:

/usr/bin/git daemon --base-path=/opt/git/ /opt/git/

现在,我可以在 OS X 机器上的当前用户(我当前的用户也是管理员)上完美地运行命令而不会出现任何问题,并且 Git 只读守护程序启动,但是一旦我尝试以非特权用户身份运行它它具有对 repo 的只读访问权限(在我的情况下 user 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/

守护程序启动,但是我运行了三个进程,其中两个以 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)
4

1 回答 1

2

该消息来自drop_privilegesgit's 中的函数daemon.c

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");
}

请注意,如果credNULL,这个函数相当于一个很大的空操作。如果cred不是 NULL则程序必须以超级用户身份运行,并且 initgroups、setgid 和 setuid 序列旨在(正如函数名称所暗示的那样)放弃其超级用户权限并继续以提供的用户身份运行 - 并且 -团体。

此函数serve在同一个文件中调用,该文件main在守护程序启动时调用:

int main(int argc, char **argv)
{
...
        return serve(&listen_addr, listen_port, cred);

这里的cred论点被传递servedrop_privileges,因此是直接感兴趣的。那么在哪里cred设置呢?让我们再看一下main,在哪里cred初始化,然后再修改:

        struct credentials *cred = NULL;
...
        if (user_name)
                cred = prepare_credentials(user_name, group_name);

所以现在我们需要找到user_name设置和/或修改的位置:

        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它就不会执行任何操作,并且命令将以任何人的身份运行调用它(即,您自己,而不是提供的用户名)。credNULLdrop_privileges

简而言之,除非您以超级用户身份运行它(例如,使用sudo),否则不要给它一个--user=选项,因为这样做只会让它在启动时像这样失败。

手册页$HOME中也提到了这个和问题(尽管下面的格式来自我的本地输出而不是 kernel.org 链接):git help daemon

   --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>.
于 2015-08-16T13:39:15.397 回答