Systemd Journal 简介

背景:暴走的Syslog

Syslog已经有近40年的历史(developed in the 1980s by Eric Allman as part of the Sendmail project),在漫长的演变过程中syslog几乎没有任何可圈可点的改进
在日常使用过程中Syslog暴露的主要问题包括:

  1. 使用本地时戳,local设置不对将导致不同服务器上的日志时间不一样。
  2. 不对写入进程进行验证,任何一个进程不需要任何权限都可以伪造成为另外一个进程产生日志。
  3. 缺少权限控制,任何进程都可以读写其他进程的日志。
  4. 残废的Rotate,定时滚动,而非根据日志大小进行滚动,被DDOS后会导致磁盘写满,系统报废。

第四点深受其害,内部报告的惨案就有四次:

https://tower.im/s/18UtK

https://tower.im/s/91Umk

https://tower.im/s/24UtL

https://tower.im/s/d1UtM

如何处理Syslog

建议一: 写一个rsyslog的空包,替换掉Dibain的rsyslog,世界会清净很多。

建议二: 使用crond,5min执行logrotate -f

Systemd Journal特性

(Lennart Poettering自称)

  • 简单性:依赖小,结构简单。
  • 零维护:可以在极端环境中使用,包括磁盘损害。并且不会引发磁盘问题。
  • 健壮性:纯文件系统实现,可以在没有systemd-journal服务时离线访问。
  • 移植性:由于是二进制格式,需要在不同的CPU类型上(ARM,MIPS)生成可以正确解析的日志。
  • 性能:实现 O(log n)效率的日志查询算法,syslog是O(n)。
  • 安全性:Journal 文件应该是可以验证的,让无法检测的修改不再可能。
  • 整合性/最小资源占用/通用的事件存储/统一化/高级别工具的基础/扩展性/通用性/集群和网络

值得关注的特性

健壮性:内存存储/日志滚动

1 可以在磁盘损坏的情况下工作,日志默认存储在内存文件系统/run/systemd/journal/中

ls /run/systemd/journal/

2 日志滚动不会引发严重磁盘问题

通过监测磁盘内容大小进行回滚。

Debian上的问题,debian默认没有开启日志持久化,重启后日志会丢失。

➜ cat /etc/systemd/journald.conf

[Journal]
Storage=auto

性能:通过二进制格式。可以方便的实现索引和引用。

通过偏移来定位日志位置,避免了文本类型日志遍历的低性能

通过引用相同日志来压缩体积,尽管 Journal 相比经典的 Syslog 明显记录了更多的元数据信息,但是磁盘占用却无明显变化。

权限控制:实现日志按用户访问

从非特权登录用户发来的消息将按照每用户分割为独立的 Journal 文件。使用 POSIX ACL 来实现读取权限控制,保证用户可以访问他自己的 Journal 文件。系统服务生成的 Journal 条目默认情况下无法被一般用户访问,除非他们属于一个特殊的 Unix 用户组。

** 客户端认证**

Systemd在生成日志时,会在日志中添加元数据信息,由Systemd-Journald生成的的元信息将以“_”开头,例如:

SYSLOG_IDENTIFIER=systemd-logind
MESSAGE_ID=fcbefc5da23d428093f97c82a9290f7b
SEAT_ID=seat0
SEAT_ID
_COMM=systemd-logind
_EXE=/lib/systemd/systemd-logind
_CMDLINE=/lib/systemd/systemd-logind
_CAP_EFFECTIVE=24420002f

以”_”开头的信息是无法由客户端进行修改的。普通权限的应用再也无法伪造身份。

没什么用的特性

  • 简单性:依赖小,结构简单。
  • 移植性:由于是二进制格式,需要在不同的CPU类型上(ARM,MIPS)生成可以正确解析的日志。(PS:完全在扯淡)

然而Systemd-Journal强烈依赖Systemd,基本告别了上面两个特性。

  • 安全性:Forward Secure Sealing (FSS)

Systemd-Journal中的所有条目都是加密哈希过的,且在文件中包含先前条目的哈希值。这样的结果是一个条目链,每一个条目都可以认证之前的全部。如果最顶端的哈希通常都保存在一个只读的位置,整个链条都可以通过它认证。检测攻击者的修改将变得十分容易。

然而被入侵的系统可以重新生成整个日志,导致这个检测毫无意义。
唯一保证日志安全性的方法是使用一个物理上的只追加的设备来保存日志(比如网卡)。并且一旦系统被入侵,后续追加的日志都是无法保证可靠性的。

Systemd Journal常用命令

# tail /var/log/syslog
journalctl -r

# tail -f /var/log/syslog
journalctl -f

# cat /var/log/syslog | grep "systemd" #Systemd Journal由明显的性能优势
journalctl /usr/lib/systemd/systemd

# dmesg
journalctl -k

# 启动日志
journalctl -b

# 强制写入日志到磁盘
journalctl --sync

#查看特定目录下的日志 journalctl -D /media/Arch/var/log/journal -xe #日志筛选 journalctl -u nginx journalctl -o json-pretty journalctl --since="2012-10-30 18:17:16" journalctl --since "20 min ago"

开发中使用Systemd Journal

由多种方法可以将程序日志记录到Systemd Journal,常见的包括:

  1. Systemd Journal自动记录自己启动程序的输出
  2. 通过Syslog转接
  3. 通过编程语言API

主要区别在与Systemd Journal记录的元信息不同

C/C++ 绑定

#include <systemd/sd-journal.h>
#include <unistd.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
        sd_journal_send("MESSAGE=Hello World!",
                        "MESSAGE_ID=52fb62f99e2c49d89cfbf9d6de5e3555",
                        "PRIORITY=5",
                        "HOME=%s", getenv("HOME"),
                        "TERM=%s", getenv("TERM"),
                        "PAGE_SIZE=%li", sysconf(_SC_PAGESIZE),
                        "N_CPUS=%li", sysconf(_SC_NPROCESSORS_ONLN),
                        NULL);
        return 0;
}

Python绑定

from systemd import journal
journal.send('Hello world')
journal.send('Hello, again, world', FIELD2='Greetings!', FIELD3='Guten tag')

Lua绑定

https://github.com/philips/luvit-systemd-journal

local fmt = require('string').format
local Journal = require('systemd-journal')

j = Journal:new()

j:print(1, "Hello World From Print")
j:send({PRIORITY=1, MESSAGE="Hello World From Send", VERSION=process.version})

Qt 对 Systemd Journal的支持

https://www.ics.com/blog/whats-new-qt-560-logging-syslog-and-journald

从5.6开始官方加入对journald的支持,只需要在configure的时候打开-journald 或者 -syslog参数即可:

Logging backends:
    journald ............... yes
    syslog   ............... yes

Deepin中对Systemd Journal使用

Goang后端统一使用go-lib, go-lib通过Syslog转发到Systemd Journal。

桌面应用(qt)暂时使用cutelog,考虑是否支持Systemd Journal中。

发表评论

电子邮件地址不会被公开。 必填项已用*标注