目次
記事ディレクトリ
syslogプロトコル
Syslog (システム ログ) は、IP ネットワークでオペレーティング システムやアプリケーションのログ情報を送信するための標準ネットワーク プロトコルであり、セキュリティ管理システムやログ監査システムなどのシナリオでよく使用されます。
Syslog プロトコルの主要な概念は次のとおりです。
- Facility: ログを生成するプログラム モジュールです。
- 重大度: ログ レベルを識別します。
- アクション: ログが保存されている場所を特定します。
ファシリティ、優先度、アクションの組み合わせにより、「どのログをどこに保存するか」という問題を明確に説明できます。
施設
Linux カーネルに実装されている Syslog 機能 (syslog.h) は次のとおりであり、申請者はこれらのサービス タイプを呼び出してソフトウェア ログ情報を記録します。
重大度
Linux カーネルに実装されている 7 つの Syslog 重大度は次のとおりです。
アクション
1)记录到普通文件或设备文件
*.* /var/log/file.log # 绝对路径
*.* /dev/pts/0 # 设备文件
2)”|”,表示将日志送给其他命令处理
3)”@HOST”,表示将日志发送到特定的主机
*.emerg @192.168.10.1
4)”用户”,表示将日志发送到特定的用户
5)”*”,表示将日志发送所有登录到系统上的用户
例: $msg 変数の内容を抽出し、キーボードのキーワードがリモート送信に使用されているかどうかを判断し、そのようなキーワードが存在しない場合は送信しません。
if $msg contains "keyboard" then
action(type="omfwd" Target="172.18.20.60"\
Port="8594"\
Protocol="udp"\
queue.type="LinkedList"\
queue.spoolDirectory="/var/spool/rsyslog"\
queue.filename="test2"\
queue.size="100000"\
queue.maxdiskspace="2g"\
queue.highwatermark="60000"\
queue.lowwatermark="2000"\
queue.discardmark="80000"\
queue.timeoutenqueue="3000"\
queue.maxfilesize="200m"\
queue.dequeuebatchsize="1000"\
)
rsyslog
rsyslog (rocket-fast system for log) は、CentOS6 以降に導入されたログ サービスであり、Syslog プロトコルのソフトウェア実装です。rsyslog は、さまざまなソースから入力を受け入れ、結果をさまざまな宛先に出力できます。さらに、次のような特徴があります。
- マルチスレッドをサポートします。
- UDP、TCP、TLS、その他のプロトコルをサポートします。
- MySQL、PGSQL、Oracle およびその他のストレージをサポートします。
- カスタム出力形式をサポートします。
- 強力なフィルターを使用すると、ログ情報のあらゆる部分をフィルターできます。
- 1 秒あたり 100 万を超えるメッセージをターゲット ファイルに配信できます。
ソフトウェアアーキテクチャ
Rsyslog アーキテクチャは上の図に示されており、メッセージ フローは次のとおりです: 入力モジュール => 前処理モジュール => メイン キュー => フィルター モジュール => 実行キュー => 出力モジュール。
- 入力モジュール: imklg、imsock、imfile などのニュースのソースです。
- 出力モジュール: メッセージの宛先です。omudp、omtcp、omfile、omprog、ommysql、omruleset が含まれます。
- Filter モジュール: メッセージの分析とフィルタリングを処理します。rsyslog は、mmnormalize を含むメッセージの任意の部分に従ってフィルタリングできます。
- 前処理モジュール: さまざまな Syslog プロトコル実装間の差異を解決します。たとえば、ログ システム クライアントが rsyslog を使用し、サーバーが syslog-ng を使用するとします。特別な処理を行わないと、syslog-ng を認識できません。ただし、rsyslog サーバーは syslog-ng によって送信されたメッセージを認識できるようになります。
- キュー モジュール: メッセージ ストレージを担当します。入力からのフィルタされていないメッセージはメイン キューに配置され、フィルタされたメッセージは別のアクション キューに配置され、アクション キューによって各出力モジュールに送信されます。
rsyslogd サービス
- パッケージ名: rsyslog
- メインプログラムファイル:/usr/sbin/rsyslogd
- 設定ファイル:/etc/rsyslog.conf、/etc/rsyslog.d/*.conf
- ライブラリファイル: /lib64/rsyslog/*.so
Systemd を起動する方法:
/lib/systemd/system/rsyslog.service
CLI の起動方法:
rsyslogd -f /root/rsyslog_worker_dir/rsyslog.conf -i /root/rsyslog_worker_dir/rsyslog.pid
rsyslogd -f /root/rsyslog_worker_dir/rsyslog.conf -i /root/rsyslog_worker_dir/rsyslog.pid -dn >debuglog
# 检测配置文件是否正确
rsyslogd -N1 -f file
rsyslog.conf
rsyslog.conf 設定ファイルは 3 つのセクションで構成されます。
- モジュール: rsyslog の開始時にロードする必要がある追加モジュールとしてのモジュール構成は、複数の機能タイプをサポートする rsyslog の鍵となります。
- グローバル ディレクティブ: グローバル構成、共通の属性を定義します。
- RULES: ログのソース、形式、場所を定義するルール設定。
モジュール
#################
#### MODULES ####
#################
module(load="imuxsock") # provides support for local system logging
#module(load="immark") # provides --MARK-- message capability
# provides UDP syslog reception
module(load="imudp")
input(type="imudp" port="514")
# provides TCP syslog reception
module(load="imtcp")
input(type="imtcp" port="514")
# provides kernel logging support and enable non-kernel klog messages
module(load="imklog" permitnonkernelfacility="on")
グローバルディレクティブ
###########################
#### GLOBAL DIRECTIVES ####
###########################
#
# Use traditional timestamp format.
# To enable high precision timestamps, comment out the following line.
#
$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat
# Filter duplicated messages
$RepeatedMsgReduction on
#
# Set the default permissions for all log files.
#
$FileOwner syslog
$FileGroup adm
$FileCreateMode 0640
$DirCreateMode 0755
$Umask 0022
$PrivDropToUser syslog
$PrivDropToGroup syslog
#
# Where to place spool and state files
#
$WorkDirectory /var/spool/rsyslog
#
# Include all config files in /etc/rsyslog.d/
#
$IncludeConfig /etc/rsyslog.d/*.conf
ルール
#################
#### RULES ####
#################
# 服务名称[.=!]信息等级 信息记录的文件名或设备或主机
# . 表示大于等于 xxx 级别的信息;
# .= 表示等于 xxx 级别的信息;
# .! 表示在 xxx 之外的等级的信息;
mail.info /var/log/maillog_info # mail 服务产生的大于等于 info 级别的日志信息,都记录到后面指定的位置中。
# Log all kernel messages to the console.
# Logging much else clutters up the screen.
#kern.* /dev/console
# Log anything (except mail) of level info or higher.
# Don't log private authentication messages!
*.info;mail.none;authpriv.none;cron.none /var/log/messages
# The authpriv file has restricted access.
authpriv.* /var/log/secure
# Log all the mail messages in one place.
mail.* -/var/log/maillog
# Log cron stuff
cron.* /var/log/cron
# Everybody gets emergency messages
*.emerg :omusrmsg:*
# Save news errors of level crit and higher in a special file.
uucp,news.crit /var/log/spooler
# Save boot messages also to boot.log
local7.* /var/log/boot.log
プロパティの置換
Rsyslog はいくつかの組み込みプロパティを事前定義しており、構成ファイルでログ出力形式を定義するとき、または動的ファイル名を定義するときに使用できます。$で始まる変数はローカルシステムから取得され、$のない変数はメッセージから取得されます。例えば:
- pri (優先度、レベル)
- msg (メッセージ本文)
- 時間(時間)
- ホスト名
- プロセス名
- プロセスID
属性置換の構文形式:
%propname:fromChar:toChar:options:fieldname%
属性置換機能は非常に強力で、開始文字を使用して必要なフィールドを取得したり、正規表現や区切り文字を使用したりすることもできます。例: RFC プロトコルとの互換性を保つために、rsyslog では、ユーザーが入力したメッセージがスペースで始まらない場合、rsyslog は自動的にスペースを追加することを規定しているため、出力時にこのスペースを削除したい場合は、次のようにすることができます。使用:
%msg:2:$% # 选取 msg 变量中,起始位置为 2,终止位置为结尾。
多くの場合、スペースに基づいて文字列を分析する必要があります。F は文字を使用して分割することを意味し、32 はスペースの ASCII コードです。次に例を示します。
%msg:F,32:3% # 按照空格分隔,取第三个子串。
テンプレートのレンダリング
属性置換機能と組み合わせたテンプレートのレンダリングは、ログの出力形式を定義したり、omfile モジュールの動的パスと動的ファイルを定義したりするためによく使用されます。例えば:
$template t_msg, "%msg\n%"
$template f_debug, "/data0/logs/%$year%-%$month%-%$day%/debug.log"
フィルタルール
フィルタリング ルール (ルールセット) を通じて、さまざまなフィルタリング ルールをさまざまな Syslog ソースに適用できます。使用する前に、構成ファイルで事前に定義する必要があります。たとえば、ポートごとに異なるフィルタリング ルールを使用します。
$Ruleset tcp1999
$RulesetCreateMainQueue on
Local3.* @@10.0.0.44:1999
$Ruleset tcp2000
$RulesetCreateMainQueue on
Local4.* @@10.0.0.44:2000
フィルターモジュール
フィルター ルールは、フィルター モジュールが構成ファイルにインポートされた後に適用できます。例えば:
Local3.* -/data0/logs/local3.log;t_msg # 在这个输出中使用 t_msg 的模板。
Local4.* -?f_local3_test;t_msg # 问号表示要使用模板定义的动态路径。
列
Rsyslog には、メイン キューとワーク キューの 2 種類のキューがあります。入力モジュールから受信したメッセージはメイン キューに入り、メイン キュー内のメッセージはフィルター モジュールを通過した後、対応するワーク キューに入ります。
キュー j には 4 つの動作モードがあります。
- ダイレクトモード
- ディスクモード
- 固定配列モード
- リンクリストモード
最初の 2 つはディスク キューであり、信頼性は高くなりますが、パフォーマンスも低下します。後の 2 つはメモリ キューです。FixedArray はキューの長さを事前に割り当てますが、LinkedList は動的に割り当てられます。システム ログ トラフィックが比較的安定している場合は、事前に割り当てられたキューを使用できます。ログがバーストしている場合は、動的キューを使用できます。
また、メモリ キューには、キュー名を指定して DA モードを追加することもできます。DA モードは、主に予期せぬ状況 (プロセスのシャットダウン、サーバーのダウンタイム) によるメモリ キューの損失を防ぐためのものです。
rsyslog のシステム コマンドを表示すると、rsyslog がキューに対して多数の構成可能なパラメータを提供し、必要に応じて最適化できることがわかります。
リモートログファイルサーバーの導入例
- クライアント: 192.168.157.60
- サーバー: 192.168.157.61
クライアント
$ vim /etc/rsyslog.conf
$ModLoad imudp
$UDPServerRun 514
$ModLoad imtcp
$InputTCPServerRun 514
$template myFormat,"%timestamp% %fromhost-ip% %msg%\n"
$ActionFileDefaultTemplate myFormat
# 服务端 IP 地址,一个 @ 表示 TCP 传输,两个 @ 表示 UDP 传输
*.info;mail.none;authpriv.none;cron.none @@192.168.157.61:514
$ systemctl start rsyslog
サーバ
$ vim /etc/rsyslog.conf
$ModLoad imudp
$UDPServerRun 514
$ModLoad imtcp
$InputTCPServerRun 514
*.info;mail.none;authpriv.none;cron.none /data/log/messages
# 允许 157.0 网段内的主机以 TCP 协议来传输
$AllowedSender tcp, 192.168.157.0/24
# 定义模板,接受日志文件路径,这里区分了不同主机的日志
$template Remote,"/data/log/%fromhost-ip%/%fromhost-ip%_%$YEAR%-%$MONTH%-%$DAY%.log"
# 过滤服务器本机的日志。
:fromhost-ip, !isequal, "127.0.0.1" ?Remote
$ systemctl start rsyslog
$ mkdir -pv /data/log
$ touch messages
$ systemctl restart rsyslog
$ tree /data/log/
/data/log/
├── 192.168.157.60
│ └── 192.168.157.60_2019-05-10.log
└── messages
確認する
client $ logger "I'm very happy"
server $ tail -f /data/log/192.168.157.60/192.168.157.60_2019-05-10.log
MySQL へのログの保存のデプロイメント例
サーバ
$ yum install mariadb-server rsyslog-mysql -y
$ systemctl start mariadb.service
$ rpm -ql rsyslog-mysql
/usr/lib64/rsyslog/ommysql.so # 客户端通信模块
/usr/share/doc/rsyslog-8.24.0/mysql-createDB.sql # 创建 rsyslog 日志表结构的 SQL 语句
$ mysql < /usr/share/doc/rsyslog-8.24.0/mysql-createDB.sql
mysql> show databases;
mysql> use Syslog;
mysql> show tables;
+------------------------+
| Tables_in_Syslog |
+------------------------+
| SystemEvents |
| SystemEventsProperties |
+------------------------+
mysql> grant all on Syslog.* to 'rsysloguser'@'127.0.0.1' identified by 'rsyslogpass';
mysql> flush privileges;
サーバー構成ファイルを変更します。
$ vim /etc/rsyslog.conf
......
$ModLoad ommysql # 打开连接 MySQL 的模块
*.* :ommysql:127.0.0.1,Syslog,rsysloguser,rsyslogpass
$ systemctl restart rsyslog.service
確認する
client $ logger 'THIS IS A TEST'
mysql> use Syslog;
mysql> select * from SystemEvents\G;
*************************** 17. row ***************************
ID: 17
CustomerID: NULL
ReceivedAt: 2019-05-10 23:15:07
DeviceReportedTime: 2019-05-10 23:15:06
Facility: 1
Priority: 5
FromHost: send
Message: THIS IS A TEST
NTSeverity: NULL
Importance: NULL
EventSource: NULL
EventUser: NULL
EventCategory: NULL
EventID: NULL
EventBinaryData: NULL
MaxAvailable: NULL
CurrUsage: NULL
MinUsage: NULL
MaxUsage: NULL
InfoUnitID: 1
SysLogTag: root:
EventLogType: NULL
GenericFileName: NULL
SystemID: NULL
リモートサーバーに送信される Apache ログをリッスンする
クライアント
/etc/rsyslog.d/ ディレクトリに新しい apache_log.conf 設定ファイルを作成します。
# 加载 imfile 模块
$ModLoad imfile
$InputFilePollInterval 10
## Apache 访问日志文件路径
$InputFileName /var/log/apache2/access.log
# tag 标签,可以作为过滤或分类用
$InputFileTag apache-access
# 状态文件,只需要指定文件名,程序会在工作目录 $WorkDirectory 下创建指定文件
$InputFileStateFile stat-apache-access
# 日志类型,user 代表应用日志
$InputFileFacility user
# 日志级别
$InputFileSeverity info
# 写入状态文件时间间隔
$InputFilePersistStateInterval 25000
## 以上属性可等效写为:
## input(type="imfile" File="/path" Tag="tag1" StateFile="filename" Severity="info" Facility="user" PersistStateInterval="25000")
## Apache 错误日志文件路径
$InputFileName /var/log/apache2/error.log
$InputFileTag apache-error
$InputFileStateFile stat-apache-error
$InputFileSeverity error
$InputFilePersistStateInterval 25000
## 日志格式模板:msg 代表默认产生的消息
$template apache_temp,"%msg%\n"
## 按照 tag 分类指定 rsyslog 日志服务器地址,
if $syslogtag == 'apache-access' then @your_server:port;apache_temp
if $syslogtag == 'apache-access' then ~
if $syslogtag == 'apache-error' then @your_server:port;apache_temp
if $syslogtag == 'apache-error' then ~
サーバ
# The imjournal module bellow is now used as a message source instead of imuxsock.
$ModLoad imuxsock # provides support for local system logging (e.g. via logger command)
$ModLoad imjournal # provides access to the systemd journal
# 启用 udp 模块,默认端口为 514
module(load="imudp")
input(type="imudp" port="514")
# 启用 tcp 模块
module(load="imtcp")
input(type="imtcp" port="514")
# 将收到的日志模板化,比如在前面添加 IP 进行区分
$template access_log, "%FROMHOST-IP% %msg%\n"
$template error_log, "%msg%\n"
$template eophp_log, "%msg%\n"
# 指定保存到服务器的路径
# access-log
$template access_log_path, "/data/apache/logs/%$NOW%/access-log/web1-access_log"
# error-log
$template error_log_path, "/data/apache/logs/%$NOW%/error-log/web1-error_log"
# eophp log
$template eophp_log_path, "/data/eophp_logs/%$NOW%/%FROMHOST-IP%.log"
# if 进行条件匹配比如多台客户端的 IP 在同一个网络,可以用 startwith 匹配 IP 的前缀
# $syslogtag 为日志的 tag 标签
if $fromhost-ip startswith '119.123.' and $syslogtag == 'apache-access' then ?access_log_path;access_log
& ~
# web1-error-log
if $fromhost-ip startswith '119.123.' and $syslogtag == 'apache-error' then ?error_log_path;error_log
& ~
# eophp
if $fromhost-ip startswith '119.123.' and $syslogtag == 'eplog' then ?eophp_log_path;eophp_log
&~
# omit...