我们遇到的情况是,将日志记录目录的写访问权限限制为特定的用户进程子集是有利的。我们已经修改了这些特定的进程(例如,telnet等),以便在发生重要的用户操作时生成日志记录(如远程连接等)。我们不想要的是用户通过复制和编辑现有的日志记录来手动创建这些记录。
syslog
接近但仍允许用户生成虚假记录,SELinux
似乎看似合理,但作为一个无法管理的野兽有着可怕的声誉。
感谢任何见解。
答案 0 :(得分:3)
以root身份运行本地日志记录守护程序。让它在Unix域套接字上监听(通常为/var/run/my-logger.socket
或类似)。
编写一个简单的日志记录库,其中事件消息通过Unix域套接字发送到本地运行的守护程序。对于每个事件,还通过辅助消息发送进程凭据。有关详细信息,请参阅man 7 unix。
当本地日志记录守护程序收到消息时,它会检查辅助消息,如果没有,则丢弃该消息。凭证的uid
和gid
确切地告知谁正在运行已发送日志记录请求的进程;这些都是由内核本身验证的,所以它们不能被欺骗(除非你有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身份运行时,它可以将事件记录到仅限root目录中的文件,和/或将消息转发到远程计算机。
显然,这不是完全轻量级的,但假设每秒事件少于十几个,那么日志记录开销应该完全可以忽略不计。
答案 1 :(得分:1)
通常有两种方法可以做到这一点。一,将这些进程作为root
运行并写保护目录(主要用于历史目的)。那么除了root之外没有人可以在那里写。第二个,更安全的是将它们作为另一个用户(而不是root
)运行,并为该用户提供写入访问日志目录,但没有其他人。
答案 2 :(得分:0)
我们采用的方法是使用setuid二进制文件允许对日志记录目录进行写访问,二进制文件可由所有用户执行,但只允许在/ proc定义的父进程路径时写入日志记录/ $ PPID / exe匹配我们放置在系统上的修改后的二进制路径的子集。