2009年11月9日 星期一

Yu-Min Space: Linux syslog 程式設計筆記

Yu-Min Space: Linux syslog 程式設計筆記

Linux syslog 程式設計筆記
LINUX下執行的程式除了自己輸出系統日誌到特定檔案外,還可以透過 syslogd來達成這個功能,免除了自行開檔關檔的工作。


程式要使用系統日誌功能,只需要在程式啟動時使用openlog函數來連接syslogd程式,後面隨時用syslog函數傳人系統日誌就行了。

相關的函式有 openlog,syslog,closelog。


#include

void openlog(const char *ident, int option, int facility)

開啟一個到系統日誌記錄程式的連接,開啟後就可使用用syslog或vsyslog函數在系統日誌中添加資訊
ident 是一個標記,ident所表示的字串將固定地加在每行日誌的前面以標識這個日誌,通常就寫成當前程式的名稱以作標記。


option 是下列值取與運算的結果:

LOG_CONS
Write directly to system console if there is an error while sending to system logger.

LOG_NDELAY
Open the connection immediately (normally, the connection is opened when the first message is logged).

LOG_NOWAIT
Don’t wait for child processes that may have been created while logging the message. (The GNU C library does not create a
child process, so this option has no effect on Linux.)

LOG_ODELAY
The converse of LOG_NDELAY; opening of the connection is delayed until syslog() is called. (This is the default, and need
not be specified.)

LOG_PERROR
(Not in SUSv3.) Print to stderr as well.

LOG_PID
Include PID with each message.


facility 指明記錄日誌的程式的類型。facility is the default facility code for this connection. A syslog on this connection that specifies default facility causes this facility to be associated with the message. See syslog for possible values. A value of zero means the default default, which is LOG_USER.



#include

void syslog(int priority, const char *format, ...)

把日誌消息發給系統程式輸出至syslogd記錄
priority 日誌消息的緊急級別

LOG_USER

A miscellaneous user process
LOG_MAIL

Mail
LOG_DAEMON

A miscellaneous system daemon
LOG_AUTH

Security (authorization)
LOG_SYSLOG

Syslog
LOG_LPR

Central printer
LOG_NEWS

Network news (e.g. Usenet)
LOG_UUCP

UUCP
LOG_CRON

Cron and At
LOG_AUTHPRIV

Private security (authorization)
LOG_FTP

Ftp server
LOG_LOCAL0

Locally defined
LOG_LOCAL1

Locally defined
LOG_LOCAL2

Locally defined
LOG_LOCAL3

Locally defined
LOG_LOCAL4

Locally defined
LOG_LOCAL5

Locally defined
LOG_LOCAL6

Locally defined
LOG_LOCAL7

Locally defined


format 日誌消息的格式,之後是格式對應的參數類似printf函數。



#include

void closelog(void)

關閉 開啟的 openlog 連接


#include

void vsyslog(int priority, const char *format, va_list ap);

把日誌消息發給系統程式輸出至syslogd記錄



簡單範例

#include

int main(int argc, char **argv)
{
openlog("test", LOG_CONS | LOG_PID, 0);
syslog(LOG_INFO, "This is a syslog test message generated by program '%s'n", argv[0]);
closelog();

return 0;
}



結果輸出一般是 /var/log/messages 或是 /var/log/syslog

視 /etc/syslog.conf 中的設定,下面的設定是輸出至 /var/log/messages

# 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 *

# 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




補充

Linux有關syslog的函式沒有提供syslog寫到遠端syslogd的功能,如果在程式中想要將syslog寫到遠端的syslog 伺服器,可以使用socket udp(514)的函式,將訊息送出。


參考資料

http://insecure.org/sploits/aix.generic.syslogd.problem.html

http://zhoulifa.bokee.com/6104993.html

http://www.dusek.ch/manual/glibc/libc_18.html


http://www.balabit.com/network-security

2009年11月5日 星期四

FID

FID

对fid的理解:
FID就是FILTERING ID.在SHARE LEARNING环境中,共享地址学习的VLAN用一个FID来标识
support tag_based vlan:
The information inside the VLAN table includes FID, member ports, tag rule, and some other information. Both member port and tag rule help checking the ingress rule. Once the VLAN membership table is configured correctly, when a MAC address is being learned, switch controler looks up in the VLAN membership table for FID of the VLAN to which the received packet belongs. The FID is then entered into the MAC table along with forward port mask, age count, etc. Thus, during lookup, besides matching destination MAC address, the FID field of address table entry of destination MAC address is compared against the FID field of the VLAN membership table entry of the VLAN to which the packet belongs. If both the address and FID fields match, the information in the address table entry is returned. If no entry has a match on both address and FID fields, then it’s a lookup-miss and the packet is flushed.

1、RFC 802.1Q中关于FID的原文
Filtering Database ID (FID)
Addressing information that the device learns about a VLAN is stored in
the filtering database assigned to that VLAN. Several VLANs can be
assigned to the same FID to allow those VLANs to share addressing
information. This enables the devices in the different VLANs to
communicate with each other when the individual ports have been
configured to allow communication to occur. The configuration is
accomplished using the Local Management VLAN Forwarding
Configuration screen. By default a VLAN is assigned to the FID that
matches its VLAN ID.
2、交换机内部存在这样一个数据库filtering database,存放着每个vlan的mac地址信息,fid是这个数

据库的字段之一
3、相同fid的vlan共享着mac地址信息,使得个别的端口可以和其它vlan的端口互相通信(即我们常做的vl
an端口隔离的上行口,可以和其它端口通信)

4、每个vlan都有一个fid属性,缺省情况下,vlan的fid和它的vid相同

5、在2826E等提供fid设置的交换机下,通过fid的灵活设置,真正意义上做到了vlan的端口隔离,有效避
免了在交换机端口的广播

6、Fid在上面的例子中,可以不等于100,经实验等于110或其它值也是可以的

可对比下面的测试:

下面这篇短文是中兴的工程师给我的,重点是介绍ZTE二层交换机中的FID

==========

以太网交换机中FID的概念和作用

本文介绍以太网交换机中的一个新的概念FID,首先我们回顾一下通过vlan进行端口隔离的配置,及存在的一个问题,最后通过FID的设置解决这个问题。

还记得以前介绍的vlan端口隔离配置吗?
创建vlan1, 包含1, 24口
创建vlan2, 包含2, 24口
...
创建vlan23, 包含23,24口
创建vlan100,包含1,2,...,23,24口
这样配置以后,端口1,2,...,23之间是隔离的,不能互相访问,24口上行,可以和1-23通信

但实事证明存在这样一个问题,24口在转发用户下行数据时是广播方式转发到1-23口。抓包可以发现端口1用户的下行数据在2-23口都能抓到包(上行未能抓到),说明隔离的是上行数据,下行却变成了一个HUB。



那么为什么会出现这种情况能?让我们来分析一下。
二层交换机有这样一张转发表:mac -> port,对于每个vlan而言,每个vlan都有一张这个表
当PC1(端口1下的PC)发出上行包后,交换机的vlan1学到如下的一个条目
vlan1 mac -> port
PC1-mac -> 1

当上行口三层设备(R1)回复PC1的数据时,交换机的vlan100学到如下条目
vlan100 mac -> port
R1-mac -> 24

当它在vlan100中要转发给PC1时,vlan100转发表中只有这样的条目
vlan100 mac -> port
R1-mac -> 24

可见并没有满足PC1 mac地址的条目,于是它在vlan100里的端口(1-23口)广播。

当PC1第二个数据包发出后,下行时是否还会在1-23口广播呢?答案是YES,重复上面的过程,始终无法在vlan100中形成PC1的mac条目,所以以后每次通信,下行是都会在每个端口广播。

于是,我们以前用的用户端口隔离的配置,并没有真正意义上起到端口隔离的作用——仅仅上行数据隔离,下行就变成了一个HUB(其实上行也是广播方式,只不过只广播到一个24口)。



那么怎样解决这个问题呢?先介绍一个新的概念——FID,即Filtering Database Identifier,是指相同FID的VLAN可以共享转发表的条目。

FID并不是新鲜事物,在交换机内部其实一直都有fid,大多数厂家并不会提供fid的设置,而是缺省的让fid=vid。

在公司自研的以太网交换机中,提供fid的设置,现在用2826E举例说明,fid的作用。
首先在2826E上配置端口隔离(注意先把缺省vlan1里的端口删掉)
set vlan 1 add port 1,24 untag
set vlan 2 add port 2,24 untag
...
set vlan 23 add port 23,24 untag
set vlan 100 add port 1-24 untag
!
set vlan 1 enable
set vlan 2 enable
...
set vlan 23 enable
set vlan 100 enable
!
set port 1 pvid 1
set port 2 pvid 2
...
set port 23 pvid 23
set port 24 pvid 100
此时show vlan可以看到每个vlan的fid都缺省的等于各自的vid。
这时通过sniffer抓包可以发现,1口的下行包,在2-23口都能被抓到,也就如同之前一样,下行数据在1-23口广播。

我们再增加一条命令set vlan 1-23 fid 100,再抓包,发现1口的下行包,在2-23口都抓不到了,下行数据不再广播到每个端口了,是什么原因呢?这就不得不研究fid的作用了。




前面提到相同fid的vlan可以共享转发表的条目,那么又是如何实现的呢?请看
zte(cfg)#show fdb 可以看到这样一张表
MacAddress Fid PortId Type
----------------- ---- ------ -------
00.08.02.d7.a0.81 4 1 dynamic
...
排除type不管,这张表由mac,fid,port构成

当PC1(端口1下的PC)发出上行包后,交换机学到如下的一个条目(此时vlan1的fid已设为100)
mac, fid -> port
PC1-mac, 100 -> 1

数据在vlan1广播,从24口出去
当上行口三层设备(R1)回复PC1的数据时,根据fid规则,交换机学到如下条目
mac, fid -> port
R1-mac, 100 -> 24

当它在vlan100中要转发给PC1时,fid相同的vlan共享如下条目
mac, fid -> port
PC1-mac, 100 -> 1
R1-mac, 100 -> 24
于是从1口单播出去

PC1第二次发包,查找已经形成的fdb转发表,从24口单播出去,再由1口单播回来。



到了这里,我突然想到,如果端口2的PC2发包,形成如下fdb表
mac, fid -> port
PC1-mac, 100 -> 1
PC2-mac, 100 -> 2
R1-mac, 100 -> 24
那么PC1和PC2还能隔离吗?
PC1的数据从端口1收到后,在vlan1里转发,虽然vlan1共享了fid=100的转发表,但PC2所在的端口2不属于vlan1,所以仍然不会转发到端口2去。



回过头再看,fid缺省时等于vid的情况,经过不断的学习,交换机内部最终形成这样一张fdb表
mac, fid -> port
PC1-mac, 1 -> 1
PC2-mac, 2 -> 2
...
PC23-mac,23 -> 2
R1-mac, 100 -> 24
由于fid不同,每个vlan都只享有与自己fid对应的一个条目,和本文最先说的每个vlan的转发表其实是一会事。不管交换机是否可以设置fid,fdb这张表在交换机内部始终存在着的,而且交换机是依照这张表进行转发的。