1

我们遇到了这样一种情况,将日志目录的写访问权限限制为用户进程的特定子集是有利的。这些特定进程(例如,telnet 等)已被我们修改,以便在发生重大用户操作(如远程连接等)时生成日志记录。我们不希望用户通过复制和编辑现有日志记录来手动创建这些记录。

syslog接近但仍然允许用户生成虚假记录,SELinux似乎合理但作为难以管理的野兽而臭名昭著。

任何见解都值得赞赏。

4

3 回答 3

3

以 root 身份运行本地日志记录守护程序。让它监听一个 Unix 域套接字(通常/var/run/my-logger.socket或类似的)。

编写一个简单的日志库,其中事件消息通过 Unix 域套接字发送到本地运行的守护进程。对于每个事件,还通过辅助消息发送流程凭据。有关详细信息,请参阅man 7 unix

当本地日志守护进程收到一条消息时,它会检查辅助消息,如果没有,则丢弃该消息。凭据的uidgid准确地告诉谁在运行发送日志请求的进程;这些是由内核本身验证的,所以它们不能被欺骗(除非你有 root 权限)。

聪明的地方来了:守护进程还检查PID凭据中的 ,并根据其值,/proc/PID/exe. 它是发送消息的进程正在执行的实际进程二进制文件的符号链接,这是用户无法伪造的。为了能够伪造消息,他们必须用自己的二进制文件覆盖实际的二进制文件,这需要 root 权限。

(有一个可能的竞争条件:用户可以制作一个执行相同操作的特殊程序,并立即exec()生成他们知道允许的二进制文件。为了避免这种竞争,您可能需要让守护程序在检查凭据后做出响应,并且日志客户端发送另一条消息(带有凭据),因此守护进程可以验证凭据仍然相同,并且/proc/PID/exe符号链接没有更改。我个人会使用它来检查消息的真实性(通过记录器要求确认事件,使用随机 cookie,并让请求者用校验和和 cookie 来响应事件校验和是否正确。包括随机 cookie 应该使之前不可能在套接字队列中填充确认exec()。)

使用 ,pid您还可以进行进一步检查。例如,您可以通过跟踪父进程来跟踪进程父级以查看人类用户如何连接,直到您通过 ssh 或控制台检测到登录。这有点乏味,因为您需要解析/proc/PID/stat/proc/PID/status文件,并且不可移植。OSX 和 BSD 有一个 sysctl 调用,可用于查找父进程 ID,因此您可以parent_process_of(pid_t pid)通过编写特定于平台的函数使其可移植。

这种方法将确保您的日志守护进程确切知道 1) 日志请求来自哪个可执行文件,以及 2) 哪个用户(以及如何连接,如果您进行进程跟踪)运行了该命令。

由于本地日志守护程序以 root 身份运行,它可以将事件记录到仅根目录中的文件,和/或将消息转发到远程机器。

显然,这并不完全是轻量级的,但假设您每秒处理的事件少于十二个,那么日志记录开销应该完全可以忽略不计。

于 2012-10-09T00:54:13.307 回答
1

通常有两种方法可以做到这一点。一,运行这些进程root并写保护目录(主要出于历史目的提及)。然后除了root之外没有人可以在那里写。第二个也是更安全的方法是将它们作为另一个用户(不是root)运行并授予该用户(但没有其他人)对日志目录的写入权限。

于 2012-10-08T20:18:17.580 回答
0

我们采用的方法是使用 setuid 二进制文件来允许对日志目录进行写访问,该二进制文件可由所有用户执行,但仅当父进程路径由 /proc/$PPID 定义时才允许写入日志记录/exe 匹配我们放置在系统上的修改后的二进制路径的子集。

于 2012-10-09T10:28:56.443 回答