我有一个通过 ssh 运行的 git 服务器,并且每个用户在系统上都有一个 unix 帐户。
假设有两个用户有权访问一个 repo,我如何确定哪个用户执行了哪个提交,因为提交用户名和电子邮件是由 git 客户端提交和控制的。
我担心用户可能会试图冒充另一个用户,即使他们具有相同的授权权限。
答案1
如果您对此感到担心,有几种方法可以解决这个问题。
- 让您的用户签署您的提交,支持 GPG 签名。
- 不要授予用户提交到主存储库的权限,让他们提交到自己的子存储库,然后让受信任的用户将更改带入主存储库。这就是为什么如果您查看某些 git 项目(例如 git 本身)的日志消息,您会看到它们有单独的字段“作者”(创建更改的人)和“提交者”(将更改提交到存储库的人)。
答案2
我认为有两种获取此类信息的好方法。一种是增加 sshd 本身的日志记录,另一种是对磁盘上的 git 存储库进行更深入的监控。由于这两种方法都无法单独提供您想要的信息,因此您可能需要同时执行这两种方法,并使用外部日志分析引擎或根据需要使用人眼和时间戳关联日志数据。
sshd 修改
默认情况下,正如您肯定看到的,您可以使用 ssh 身份验证日志查看用户何时登录以及从何处登录。您想要做的是更改您退出 sshd 时的级别。因此,编辑您的/etc/ssh/sshd_config
并找到如下所示的行
#LogLevel INFO
并将其更改为
LogLevel VERBOSE
然后重新启动 sshd 服务。这会将 sshd 的日志记录级别提高 1 级,从而提供更多信息。查看进行此更改后我的远程访问的日志片段。
Nov 2 08:37:09 node1 sshd[4859]: Connection from 10.10.10.5 port 50445
Nov 2 08:37:10 node1 sshd[4859]: Found matching RSA key: f2:9e:a1:ca:0c:33:02:37:9b:de:e7:63:d5:f4:25:06
Nov 2 08:37:10 node1 sshd[4860]: Postponed publickey for scott from 10.10.10.5 port 50445 ssh2
Nov 2 08:37:10 node1 sshd[4859]: Found matching RSA key: f2:9e:a1:ca:0c:33:02:37:9b:de:e7:63:d5:f4:25:06
Nov 2 08:37:10 node1 sshd[4859]: Accepted publickey for scott from 10.10.10.5 port 50445 ssh2
Nov 2 08:37:10 node1 sshd[4859]: pam_unix(sshd:session): session opened for user scott by (uid=0)
Nov 2 08:37:10 node1 sshd[4859]: User child is on pid 4862
Nov 2 08:40:27 node1 sshd[4862]: Connection closed by 10.10.10.5
Nov 2 08:40:27 node1 sshd[4862]: Transferred: sent 30632, received 7024 bytes
Nov 2 08:40:27 node1 sshd[4862]: Closing connection to 10.10.10.5 port 50445
Nov 2 08:40:27 node1 sshd[4859]: pam_unix(sshd:session): session closed for user scott
这里要注意的重要事项有两点
- 我们看到了用于验证我身份的公钥指纹
- 我们看到我注销的时间戳
使用默认的 LogLevel (INFO),sshd 不会记录上述任何一项。获取密钥的指纹是额外的一步。您必须authorized_keys
使用 ssh-keygen 处理相应的文件。
[root@node1 ssh]# ssh-keygen -l -f /home/scott/.ssh/authorized_keys
4096 f2:9e:a1:ca:0c:33:02:37:9b:de:e7:63:d5:f4:25:06 /home/scott/.ssh/authorized_keys (RSA)
现在您了解了以下信息:
- 登录的用户名
- 用户登录的时间
- 使用哪个公钥进行身份验证
- 用户注销的时间
现在我们有办法在特定时间归因于用户的操作,假设两个用户没有同时登录,我们就可以开始查看对存储库所做的更改。
使用 Auditd 进行目录监控
正如 sysadmin1138 所说,这可能是 auditd 子系统的一个极佳用例。如果您使用的不是基于 RedHat 的发行版,那么可能有一个类似版本,但您必须找到它。auditd 的配置非常复杂,并且具有大量配置选项。要了解一些选项,请查看此问题我们的姐妹信息安全专业人员网站。
至少,我建议在包含相关 git 存储库的磁盘目录上设置所谓的“监视”。它的作用是指示内核模块报告对指向我们列出的文件或目录的文件句柄执行文件访问调用(例如open()
或creat()
)的尝试。
这是一个示例配置,可以执行此操作,并且只能执行此操作。因此,请仔细阅读并理解现有配置,/etc/audit/audit.rules
以便适当地整合更改。
# This file contains the auditctl rules that are loaded
# whenever the audit daemon is started via the initscripts.
# The rules are simply the parameters that would be passed
# to auditctl.
# First rule - delete all
-D
# Increase the buffers to survive stress events.
# Make this bigger for busy systems
-b 1024
-w /path/to/git/repos-p wa
# Disable adding any additional rules - note that adding *new* rules will require a reboot
-e 2
答案3
您唯一可以采取的技术方法是信任 ssh 连接的身份。然后,您可以通过验证每个新推送提交的提交者来强制每个用户仅推送他所做的提交。
为了保证可靠性,您几乎肯定不想让您的用户对存储库所在的框进行不受限制的 shell 访问权限;您需要确保使用类似的东西git-shell
,否则限制很容易被绕过。
不过,用户仍然可以冒充作者。您也可以限制这一点,但这会失去常见的工作流程,例如 cherry-picking 和 rebasing 甚至分支(取决于您的钩子实现),所以您可能不想这样做。
在某些时候,在某种程度上,您需要信任您的开发人员。
答案4
如果所有用户都拥有对存储库具有写权限的 shell 帐户,那么您将无法设置可信的审计日志:他们仍然可以修改存储库而不写入日志,并且可以将任何他们想要的内容写入日志。
为了能够信任审计日志,您需要阻止对存储库的直接文件级写访问,而是使用 gitolite 之类的程序(在其自己的帐户中运行)来调解对存储库的访问。