我不知道这是否正确的部分张贴,如果不是,请告诉我,我应该在哪里张贴以下问题:
我在一个局域网上,有两台机器:一台带有only,它充当Git服务器,另一台运行Ubuntu的笔记本电脑,它充当通过git://访问只读存储库的Git客户机。
我正在读吉特书。在这里,https://git-scm.com/book/it/v2/Git-on-the-Server-Git-Daemon斯科特·查肯说:
出于安全考虑,强烈鼓励将此守护进程作为具有只读存储库权限的用户运行--您可以通过创建一个新用户git-ro并以它们的身份运行守护进程来轻松地做到这一点。为了简单起见,我们将简单地以Gitosis运行的相同git用户的身份运行它。
运行git守护进程的命令是:
/usr/bin/git daemon --base-path=/opt/git/ /opt/git/现在,我可以在OS机器上运行命令,不会出现任何问题(我的当前用户也是管理员),Git只读守护进程就会启动,但只要我尝试以非特权用户的身份运行它(在我的例子中是用户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的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问题似乎与执行命令的主目录有关,不是吗?如果是的话,我应该如何处理我的情况?
编辑2:下面是使用sudo运行的命令:
$ sudo git daemon --reuseaddr --user=git-ro --group=git-ro --base-path=/opt/git/ /opt/git/守护进程启动,但是我有三个进程在运行,其中两个进程是根进程:
$ 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/为什么守护进程仍然以根进程的形式运行,有两个进程?这是预期的行为,还是我应该进一步改进?
编辑3:此外,如果我运行lsof并检查在端口9418上侦听的是什么,为什么我会看到git-ro持有的两行具有相同pid的行?那件事怎么可能?git daemon进程作为根进程运行在哪里?
$ 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)发布于 2015-08-16 13:39:15
消息来自git's drop_privileges中的函数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");
}请注意,如果cred是NULL,则此函数相当于一个大的无操作。如果cred不是NULL,则程序必须以超级用户的身份运行,而initgroup、setgid和setuid序列的作用是(如函数名所示)放弃其超级用户权限,继续作为提供的用户和组运行。
这个函数是从同一个文件中的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的位置:
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的问题也在手册页中提到(尽管下面的格式来自本地git help daemon输出,而不是kernel.org链接):
--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>.https://stackoverflow.com/questions/32034920
复制相似问题