背景:在日誌審計項目中收集各個設備的系統信息,利用syslog日誌進行日誌的採集、接收、轉發,因在多網絡段轉發日誌時需要獲取 各個轉發設備主機名/主機IP地址的,所以接入Syslog-ng日誌。
Syslog 詳解
Syslog常被稱爲系統日誌或系統記錄,是一種用來在互聯網協議(TCP/IP)的網上中傳遞記錄檔消息的標準。這個詞彙常用來指涉實際的syslog 協議,或者那些提交syslog消息的應用程序或數據庫。
syslog協議提供傳輸功能,以允許機器通過IP網絡將事件通知消息發送到事件消息collector(也稱爲系統日誌服務器)。因爲每一個進程、應用程序和操作系統是分開開發的,syslog的信息的內容大多都是不同的。因此,不會對消息的格式或內容做出任何假設。這個協議只是簡單的傳遞這些信息。在任何情況下,有一個設備發出消息。那臺機器上的Syslog進程可能將信息發送給collector。不需要任何應答。
Syslog協議和進程的基本原則是它的簡單性。在發送者和接收者之間不需要協調。實際上,syslog信息的發送者可以在接收者沒有配置好或根本不存在的情況下進行發送。相反,很多設備會在沒有任何配置和定義的情況下收到消息。這種簡單性讓syslog更容易接受和部署。
Syslog使用用戶數據報(UDP)作爲底層傳輸層協議。Syslog的UDP端口爲514。如果消息是由syslog進程發出,建議源端口也是514,不是514也是合法的。如果發送者使用比514大的端口號,那麼建議接下來的其他消息也由這個端口發出。
Syslog常被用來日誌等數據的傳輸協議,數據格式遵循規範主要有RFC3164,RFC5424;
RFC5424 相比 RFC3164 主要是數據格式的不同,RFC3164相對來說格式較爲簡單,能適應大部分使用場景,但是已廢棄,RFC5424已作爲Syslog的業界規範。
系統日誌架構
相關定義的說明
- device:生成消息的設備
- relay:接收消息的設備又將消息轉發給了其他設備
- collector:接收消息但不進行轉發的設備,也稱作syslog服務器
- sender:發出消息或轉發消息的設備
- receiver:任何接收消息的設備,包括轉發或收集
+------+ +---------+
|Device|---->----|Collector|
+------+ +---------+
+------+ +-----+ +---------+
|Device|---->----|Relay|---->----|Collector|
+------+ +-----+ +---------+
+------+ +-----+ +-----+ +---------+
|Device|-->--|Relay|-->--..-->--|Relay|-->--|Collector|
+------+ +-----+ +-----+ +---------+
+------+ +-----+ +---------+
|Device|---->----|Relay|---->----|Collector|
| |-\ +-----+ +---------+
+------+ \
\ +-----+ +---------+
\-->--|Relay|---->----|Collector|
+-----+ +---------+
+------+ +---------+
|Device|---->----|Collector|
| |-\ +---------+
+------+ \
\ +-----+ +---------+
\-->--|Relay|---->----|Collector|
+-----+ +---------+
+------+ +-----+ +---------+
|Device|---->----|Relay|---->-------|Collector|
| |-\ +-----+ /--| |
+------+ \ / +---------+
\ +-----+ /
\-->--|Relay|-->--/
+-----+
圖 1. 一些可能的系統日誌架構
Syslog-ng 簡介
syslog-ng就是syslog的升級版,功能也比syslog強大。比如:高性能、支持多平臺、高可靠的傳輸、衆多的用戶羣體、強大的日誌過濾、排序。syslog-ng有兩個版本,一個是收費的,一個是開源的。syslog ng是一個增強的日誌守護進程,支持多種輸入和輸出方法:syslog、非結構化文本、消息隊列、數據庫(類似於SQL和NoSQL)等等。syslog-ng可以通過對日誌信息執行正規表達式過濾,並且支持主機鏈方式等工作,都能更好的協助我們管理主機。syslog-ng官方網站:https://www.syslog-ng.com/
syslog-ng替代syslog是基於以下的設計原則的:
- 通過正規表達式協助,除支持原facitily/level方式,還支持內容過濾等以建立更好的消息過濾機制;
- 支持主機鏈,即使日誌消息經過多重網絡轉發,仍可找到原發出主機的信息和整個消息鏈;
- 支持強大的自定義配置,並且清晰、明瞭。
syslog-ng的主配置文件存放在:/etc/syslog-ng/syslog-ng.conf
配置說明
格式:LOG STATEMENTS『SOURCES - FILTERS -DESTINATIONS』
消息路徑 『消息源 - 過濾器 - 目的站』也就是說,通過定義多個消息源,把匹配上若干個過濾器的消息導向到指定的目的地,從而組成一個消息路徑。
消息源SOURCES
格式:
source <sourcename> {
sourcedriver params;
sourcedriver params;
};
<sourcename>:一個消息源的標識
sourcedriver:消息源驅動器,可以支持若干參數,並使用分號“;”隔離多個消息源驅動器
消息源驅動器有:
消息源驅動器 |
說明 |
file (filename) |
從指定的文件讀取日誌信息 |
unix-dgram (filename) |
打開指定的SOCK_DGRAM模式的unix套接字,接收日誌消息 |
unix-stream (filename) |
打開指定的SOCK_STREAM模式的unix套接字,接收日誌消息 |
udp ( (ip),(port) ) |
在指定的UDP端口接收日誌消息 |
tcp ( (ip),(port) ) |
在指定的TCP端口接收日誌消息 |
sun-streams (filename) |
在solaris系統中,打開一個(多個)指定的STREAM設備,從其中讀取日誌消息 |
internal() |
syslog-ng內部產生的消息 |
pipe(filename),fifo(filename) |
從指定的管道或者FIFO設備,讀取日誌 |
source s_sys {
file ("/proc/kmsg" log_prefix("kernel: "));
internal();
udp(ip(0.0.0.0) port(514));
};
解釋:定義了s_sys消息源 消息驅動器1:從/proc/kmsg 目錄選擇以kernel: 前綴的文件進行讀取 消息驅動器2:syslog-ng內部產生的消息 消息驅動器3:從udp的514端口獲取消息
過濾器:filters
格式爲:filter <filtername> { expression; };
說明:
<filtername>:一個過濾器標識
expression:表達式,支持:邏輯操作符:and(和)、or(或)、not(非);函數:可使用正規表達式描述內容
過濾函數 |
說明 |
facility(,) |
根據facility(設備)選擇日誌消息,使用逗號分割多個facility |
level(,) |
根據level(優先級)選擇日誌消息,使用逗號分割多個level,或使用“..”表示一個範圍 |
program(regexp) |
日誌消息的程序名是否匹配一個正則表達式 |
host(regexp) |
日誌消息的主機名是否和一個正則表達式匹配 |
match(regexp) |
對日誌消息的內容進行正則匹配 |
filter() |
調用另一條過濾規則並判斷它的 |
filter f_filter2 {
level(info..emerg) and not facility(mail,authpriv,cron);
};
這裏的level定義info,相當於syslog的.=info,並不包括更低的等級;
若需要包括更低的等級,請使用“..”表示一個等級範圍;
另外,filter(DEFAULT),用於捕獲所有沒有匹配上的日誌消息。filter(*)是無效的。
目的地:DESTINATIONS
格式爲:
destination <destname> {
destdriver params; destdriver params; ... ;
};
說明:<destname>:一個目的地的標識 destdriver :目的地驅動器
目的地驅動器有:
目的地驅動器 |
說明 |
file (filename) |
把日誌消息寫入指定的文件 |
unix-dgram (filename) |
把日誌消息寫入指定的SOCK_DGRAM模式的unix套接字 |
unix-stream (filename) |
把日誌消息寫入指定的SOCK_STREAM模式的unix套接字 |
udp (ip),(port) |
把日誌消息發送到指定的UDP端口 |
tcp (ip),(port) |
把日誌消息發送到指定的TCP端口 |
usertty(username) |
把日誌消息發送到已經登陸的指定用戶終端窗口 |
pipe(filename),fifo(filename) |
把日誌消息發送到指定的管道或者FIFO設備 |
program(parm) |
啓動指定的程序,並把日誌消息發送到該進程的標準輸入 |
destination d_mesg { file("/var/log/messages"); };
destination d_syslog { udp ("192.168.221.130" port(100)); };
說明:把日誌消息寫入到/var/log/messages 文件中,並把日誌消息通過udp協議 發送到ip 192.168.221.130 端口100機器上
消息路徑LOG STATEMENTS
格式爲:
log {
source S1; source S2; ... filter F1; filter F2; ... destination D1; destination D2; ...
};
把消息源、過濾器、消息目的組合起來就形成一條完整的指令。日誌路徑中的成員是順序執行的。凡是來源於指定的消息源,匹配所有指定的過濾器,並送到指定的地址。
注意:每條日誌消息都會經過所有的消息路徑,並不是匹配後就不再往下執行的。
選項參數 options
格式:options { opt1; opt2; ... };
選項參數 |
說明 |
chain_hostnames(yes|no) |
是否打開主機名鏈功能,打開後可在多網絡段轉發日誌時有效 |
long_hostnames(yes|no) |
是chain_hostnames的別名,已不建議使用 |
keep_hostname(yes|no) |
是否保留日誌消息中保存的主機名稱,否時,總是使用來源主機來作重寫日誌的主機名 |
use_dns(yes|no) |
是否打開DNS查詢功能,應使用防火牆保護使用syslog-ng的節點安全,並確認所有主機都是可以通過dns解釋的,否則請關閉該選項 |
use_fqdn(yes|no) |
是否使用完整的域名 |
check_hostname(yes|no) |
是否檢查主機名有沒有包含不合法的字符 |
bad_hostname(regexp) |
可通過正規表達式指定某主機的信息不被接受 |
dns_cache(yes|no) |
是否打開DNS緩存功能 |
dns_cache_expire(n) |
DNS緩存功能打開時,一個成功緩存的過期時間 |
dns_cache_expire_failed(n) |
DNS緩存功能打開時,一個失敗緩存的過期時間 |
dns_cache_size(n) |
DNS緩存保留的主機名數量 |
create_dirs(yes|no) |
當指定的目標目錄不存在時,是否創建該目錄 |
dir_owner(uid) |
目錄的UID |
dir_group(gid) |
目錄的GID |
dir_perm(perm) |
目錄的權限,使用八進制方式標註,例如0644 |
owner(uid) |
文件的UID |
group(gid) |
文件的GID |
perm(perm) |
文件的權限,同樣,使用八進制方式標註 |
gc_busy_threshold(n) |
當syslog-ng忙時,其進入垃圾信息收集狀態的時間。一旦分派的對象達到這個數字,syslog-ng就啓動垃圾信息收集狀態。默認值是:3000 |
gc_idle_threshold(n) |
當syslog-ng空閒時,其進入垃圾信息收集狀態的時間。一旦被分派的對象到達這個數字,syslog-ng就會啓動垃圾信息收集狀態,默認值是:100 |
log_fifo_size(n) |
輸出隊列的行數 |
log_msg_size(n) |
消息日誌的最大值(bytes) |
stats(n) |
多少時間(秒)寫入兩行STATUS信息供,默認值是:600 |
sync(n) |
緩存多少行的信息再寫入文件中,0爲不緩存,局部參數可以覆蓋該值 |
time_reap(n) |
在沒有消息前,到達多少秒,即關閉該文件的連接 |
time_reopen(n) |
對於死連接,到達多少秒,會重新連接 |
use_time_recvd(yes|no) |
宏產生的時間是使用接受到的時間,還是日誌中記錄的時間;建議使用R_的宏代替接收時間,S_的宏代替日誌記錄的時間,而不要依靠 |
options {
chain_hostnames(yes);
keep_hostname(no);
create_dirs(yes);
use_dns(no);
};
說明:打開主機鏈功能並使用來源主機來作重寫日誌的主機名目標目錄不存在時創建並關閉DNS查詢功能
Syslog-ng配置實例
@version: 3.2
options {
chain_hostnames(yes);
keep_hostname(no);
create_dirs(yes);
use_dns(no);
};
source s_local {
internal();
};
source s_remote {
udp(ip(0.0.0.0) port(519));
};
destination d_mail_sh { udp('192.168.221.102' port('519')); };
destination d_mail_r { tcp('192.168.221.130' port('100')); };
# 配置日誌推到
log{ source(s_local); destination(d_mail_r); };
log{ source(s_remote); destination(d_mail_sh); };
syslog-ng垃圾收集狀態
一定條件下,syslog-ng即會進入垃圾收集狀態,而暫時不再接受日誌信息。這時,會造成非連接的傳輸協議的日誌丟失(例如UDP)。
gc_idle_threshold(n):一旦被分派的對象到達這個數字,並且當syslog-ng空閒時(100微秒內沒有日誌消息到達)。此時,syslog-ng就會啓動垃圾信息收集狀態。已分配的對象可通過-v命令行參數指定其的最小值。而syslog-ng這個值應該比較小,但比已分配的對象要大即可。
gc_busy_threshold(n) :當syslog-ng忙時,一旦分派的對象達到這個數字,syslog-ng就進入垃圾信息收集狀態的時間。該值應該比較高,以保證正常情況下不會打斷日誌消息的收取。
日誌格式-RFC3164
syslog格式:<PRI>HEADER MESSAGE
syslog的消息長度:不超過1024。
RFC3164協議手冊地址:https://tools.ietf.org/html/rfc3164
syslog格式舉例:<15>Jul 10 12:00:00 192.168.1.1 SyslogGen MESSAGE
格式說明:
PRI:即Priority(優先級),有效值範圍爲0 - 191。不能有空格、數字前也不能補0。合法的形式如:<15>。PRI值包含兩部分信息:Facility和Level。其中Facility值用於判斷哪個程序產生了日誌信息。Level值用於判斷嚴重等級。計算方法:PRI = Facility * 8 + Level。只有一種情況,當0跟着<時,表示優先級爲0。其他情況,不能以0開頭
Facility可選值爲
Level可選值爲:
- HEADER:
HEADER包含兩個稱爲TIMESTAMP和HOSTNAME的字段。TIMESTAMP緊跟着PRI中的“>”。TIMESTAMP和HOSTNAME之間用一個空格分隔。HOSTNAME包含主機名。如果沒有主機名,將會包含主機的IP地址。如果設備有多個IP地址,將會使用發送數據的IP地址。兩者可以選一個發送。在這種情況下,device可能被配置成使用一個源IP發送所有的消息,不管消息實際從哪個接口發出。這種方式爲所有的消息的HOSTNAME字段提供了一致性。 TIMESTAMP是本地事件,格式是“Mmm dd hh:mm:ss”:Mmm是月份的英文縮寫,以一個大寫的M開始,兩個小寫的m結束。取值如下:Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec。dd是一個月中的天數。如果小於10,必須表示成空格然後是數字。例如8月的第七天表示成爲“Aug 7”,其中g和7之間有兩個空格。hh:mm:ss是本地時間。小時表示成爲24小時的格式,合法值是00到23。分鐘和秒是00到59。在TIMESTAMP之後需要有一個空格。HOSTNAME字段包含發送者的主機名或IP地址。最好的名稱是主機名。如果使用主機名,HOSTNAME字段必須包含STD 13中描述的主機名。其中不能包含任何空格主機名不能包含在HOSTNAME字段中。如果使用IPv4地址,必須是點分十進制。如果是IPv6格式,使用RFC 2373中的格式。HOSTNAME字段之後也必須有一個空格。
- MESSAGE:
MSG部分是syslog報文的剩餘部分。通常它包含生成這個消息進程的其他信息以及消息的文本內容。這部分沒有結束分隔符。Syslog報文的MSG部分必須包含可見的(可打印)的字符。通常使用和PRI以及HEADER部分一樣的ASCII字符集。在這個字符集中,允許的字符是ABNF VCHAR(%d33-126)以及空格(SP value %d32)。然而,不需要在MSG中使用的代碼集的指示,也不期望這樣做。可以使用其他的字符集,只要MSG中使用的字符是與上述類似的可見的字符和空格。包含不可見字符集的消息不能被展示,也不能被接收者理解,不會給操作員或管理員任何信息。MSG部分有兩個字段,分別是TAG和CONTENT。TAG字段的值是產生消息的程序或進程名稱。CONTENT部分包含消息的詳細信息。通常是開放格式的消息,包含事件的一些詳細信息。TAG是32個字符之內的ABNF數字字母字符集。任何非數字字母的字符會被當作TAG字段的結束標記,並且這個字符會當作CONTENT字段的開始。CONTENT字段的第一個字符表示TAG字段的結束,通常是方括號“[”,冒號“:”或者空格。
日誌格式RFC5424
syslog格式:<PRI>VERSION TIMESTAMP HOSTNAME APP-NAME PROCID MSGID
RFC5424協議手冊地址:https://tools.ietf.org/html/rfc5424
- PRI:參見RFC3164中的PRI。
- VERSION :版本用來表示Syslog協議的版本,RFC5424的版本號爲“1”
- TIMESTAMP :時間戳格式爲:yyyy-mm-ddTHH:MM:SS.xxxxxx+/-HH:MM 有幾個要求:1."T" "Z"必須大寫。2.如果無法獲取時間戳,必須使用"-"代替。3.不能使用閏秒。4."T"是必須的
- HOSTNAME :hostname標識發送syslog消息的源主機。優先選用幾種寫法:1.FQDN:全限定域名:同時帶有主機名和域名的名稱。(通過符號“.”)2.Static IP address:靜態IP地址。3.Hostname:主機名。4.Dynamic IP address:動態Ip地址。4.the NILVALUE:"-"
- APP-NAME:用於識別產生消息的設備或應用,找不到用"-"代替
- PROCID :進程名稱或進程ID,得不到用"-"代替;ProcId常用於分析日誌生成進程的連續性,但不做可靠性保證,比如進程重啓還是可能會分到一樣的進程ID
- MSGID:標識消息類型。例如TCPIN、TCPOUT分別代表TCP數據的流入或流出;如果無法獲取數據類型,用"-"代替。 MSGID可根據數據類型用於數據過濾
RFC 5424 簡單示例
Example 1 - with no STRUCTURED-DATA
<34>1 2003-10-11T22:14:15.003Z mymachine.example.com su - ID47
- BOM'su root' failed for lonvick on /dev/pts/8
In this example, the VERSION is 1 and the Facility has the value of
4. The Severity is 2. The message was created on 11 October 2003 at
10:14:15pm UTC, 3 milliseconds into the next second. The message
originated from a host that identifies itself as
"mymachine.example.com". The APP-NAME is "su" and the PROCID is
unknown. The MSGID is "ID47". The MSG is "'su root' failed for
lonvick...", encoded in UTF-8. The encoding is defined by the BOM.
There is no STRUCTURED-DATA present in the message; this is indicated
by "-" in the STRUCTURED-DATA field.
Example 2 - with no STRUCTURED-DATA
<165>1 2003-08-24T05:14:15.000003-07:00 192.0.2.1
myproc 8710 - - %% It's time to make the do-nuts.
In this example, the VERSION is again 1. The Facility is 20, the
Severity 5. The message was created on 24 August 2003 at 5:14:15am,
with a -7 hour offset from UTC, 3 microseconds into the next second.
The HOSTNAME is "192.0.2.1", so the syslog application did not know
its FQDN and used one of its IPv4 addresses instead. The APP-NAME is
"myproc" and the PROCID is "8710" (for example, this could be the
UNIX PID). There is no STRUCTURED-DATA present in the message; this
is indicated by "-" in the STRUCTURED-DATA field. There is no
specific MSGID and this is indicated by the "-" in the MSGID field.
GerhardsStandards Track[Page 19]
RFC 5424 The Syslog Protocol March 2009
The message is "%% It's time to make the do-nuts.". As the Unicode
BOM is missing, the syslog application does not know the encoding of
the MSG part.
Example 3 - with STRUCTURED-DATA
<165>1 2003-10-11T22:14:15.003Z mymachine.example.com
evntslog - ID47 [exampleSDID@32473 iut="3" eventSource=
"Application" eventID="1011"] BOMAn application
event log entry...
This example is modeled after Example 1. However, this time it
contains STRUCTURED-DATA, a single element with the value
"[exampleSDID@32473 iut="3" eventSource="Application"
eventID="1011"]". The MSG itself is "An application event log
entry..." The BOM at the beginning of MSG indicates UTF-8 encoding.
Example 4 - STRUCTURED-DATA Only
<165>1 2003-10-11T22:14:15.003Z mymachine.example.com
evntslog - ID47 [exampleSDID@32473 iut="3" eventSource=
"Application" eventID="1011"][examplePriority@32473
class="high"]
對於數據的提取 可採用正則表達式 及字符串的分割讀取