Syslog

無法過濾 syslog-ng 中格式錯誤的消息

  • March 27, 2017

我正在就 syslog-NG 的問題與您聯繫。我們的一些設備(主要是 HP 交換機和 SAN)正在發送似乎不遵守 syslog RFC 5424 的 syslog 消息。

舉幾個例子:

如果我嗅探伺服器的網路介面,我們可以看到這些“錯誤”消息(如您​​所見,在 PRI 之後,我們可以看到 PROGRAM,然後是時區和用逗號分隔的欄位。簡而言之,混合欄位,缺少欄位等不是標準的系統日誌消息):

<190>raslogd: 2017/03/08-16:03:20, [SEC-1203], 53642, WWN 10:00:50:eb:1a:6c:21:38 | FID 128, INFO, cswc-mo8x-SAN01, Login information: Login successful via TELNET/SSH/RSH. IP Addr: 1.2.3.4

因此,我目前無法過濾這些消息。我嘗試定義一個正常過濾器並嘗試列印 MSGHDR、MSG、PRI 等欄位,但什麼也看不到。

過濾此消息的唯一方法是僅定義外部介面和一個文件作為輸出,而無需任何模板。

例如,如果我做這樣的過濾器:

destination d_INCOMING_ALL   { file("/app/syslog-ng/logs/incoming_all.log"); };

log {
 source(s_EXTERNAL);
 destination(d_INCOMING_ALL);
};

我可以在日誌文件中看到消息,但以某種方式格式化(我想 syslog-NG 重新格式化它們):

[root@xxxxxxxxxxxx logs]# grep -i cswc incoming_all.log
Mar  9 09:44:20 cswc-mo8x-hpsan01 raslogd: 2017/03/09-08:34:50, [SEC-1203], 53647, WWN 10:00:50:eb:1a:6c:21:38 | FID 128, INFO, cswc-mo8x-SAN01, Login information: Login successful via TELNET/SSH/RSH. IP Addr: 1.2.3.4
[root@xm1p1034vmo logs]#

問題是我無法在那裡過濾這些消息(我們從超過 1000 個設備接收日誌),我需要過濾來自這些設備的消息!我能做到的唯一方法是使用主機名(cswc- )或程序名(raslogd

所以我嘗試通過向該文件添加模板來顯示欄位,例如:

destination d_test { 
   file ("/app/syslog-ng/logs/test_olivier.log" 
   template("pri=${priority} date=${ISODATE} host=${HOST} program=${PROGRAM} message=${MSG}\n") 
   ); 
};

但沒有任何效果,沒有顯示任何內容。我嘗試了所有欄位,MSG、MESSAGE、MSGHDR 等。無法管理顯示任何內容。唯一有效的是沒有過濾器或模板的解析。

自然,如果我嘗試了所有類型的過濾器,如下面的這些,它就不起作用(因為欄位是混合的):

filter f_is_SAN     {
   host("cswc.*" flags(ignore-case));
};

相同的:

filter f_is_SAN     {
   match(".*cswc.*" flags(ignore-case));
};

關於如何為來自這些設備(主機名或程序名)的這些消息創建過濾器的任何提示?

感謝和問候,

嗯,我找到了一個似乎有效的解決方案

我正在重用“本地副本”目標作為源

例如:

我有一個正常的日誌過濾器,保留所有內容的副本:

destination d_INCOMING_ALL       { file("/app/syslog-ng/logs/incoming_all.log"); };
log {
 source(s_EXTERNAL);
 destination(d_INCOMING_ALL); 
};

該消息保存在正在重新格式化的“本地副本”中。然後我可以從源中的這個文件重新讀取並將過濾器應用到它。它很髒,但它有效:

source s_NON_RFC_COMPLIANT {   # new source
   file("/app/syslog-ng/logs/incoming_all.log" follow-freq(10));
};

....

destination d_INCOMING_ALL {
   file("/app/syslog-ng/logs/incoming_all.log");    # old destination where we keep a local copy of EVERYTHING
};

....

log {      # local copy of everything
 source(s_EXTERNAL);
 destination(d_INCOMING_ALL);
};

....

other filters here

....

filter f_is_Network     {
 host("cswc.*" flags(ignore-case))       # we want to filter on hosts called cswc-something or program raslogd
 or program("raslogd" flags(ignore-case));
};

log {    # new source for HP stuff here
 source(s_NON_RFC_COMPLIANT);
 filter(f_is_Network);              # add the filters you need
 destination(<your_final_destination_here>);
 flags(final);
};

實際上,syslog-ng 並沒有重新格式化它們,而是添加了一個適當的 syslog 標頭:

3 月 9 日 09:44:20 cswc-mo8x-hpsan01 raslogd:2017/03/09-08:34:50,

$$ SEC-1203 $$, 53647, WWN 10:00:50:eb:1a:6c:21:38 | FID 128,INFO,cswc-mo8x-SAN01,登錄資訊:TELNET/SSH/RSH登錄成功。IP 地址:1.2.3.4

以下是 syslog 添加的:

3 月 9 日 09:44:20 cswc-mo8x-hpsan01

其餘的是原始消息:

raslogd: 2017/03/09-08:34:50,

$$ SEC-1203 $$, 53647, WWN 10:00:50:eb:1a:6c:21:38 | FID 128,INFO,cswc-mo8x-SAN01,登錄資訊:TELNET/SSH/RSH登錄成功。IP 地址:1.2.3.4

因此 syslog-ng 同意您的觀點,即這些消息不符合 RFC。

在設置過濾器方面,這意味著您沒有太多可玩的了。

我個人更習慣於 rsyslog(您可以在其中使用正則表達式檢查消息,例如尋找raslogd- 儘管這不一定有效)。

但是,標題 syslog-ng 能夠添加給您一些事情要做:

  • 似乎 syslog-ng 能夠報告一個主機名,我傾向於假設它是從源 IP 解析的。因此,您至少可以使用主機網路遮罩過濾源 IP :

filter hp_hosts { (host(192.168.0.25)) };

  • 您目前的主機過濾器失敗,因為消息中沒有 HOST 欄位 -host過濾器狀態的文件:

也就是說,syslog-ng OSE 會將過濾器表達式與 ${HOST} 宏的內容進行比較。

  • 但是,您確實在消息中有一個主機名(至少在您的範例中),因此您可以考慮使用消息過濾器。

話雖這麼說 - 對我來說,如果有可能獲得所有這些設備的源 IP 列表(我只能為了你的緣故希望這是可能的),那麼我會使用網路遮罩過濾器 - 它似乎很可能是比其他選項更有效。

引用自:https://serverfault.com/questions/837585