ผู้ดูแลระบบ *nix ส่วนใหญ่คงคุ้นเคยกับ syslog มาเป็นอย่างดี เพราะ syslog ถือได้ว่าเป็น log daemon ที่ใช้กันมาอย่างยาวนานและกลายเป็นมาตรฐานของการเก็บข้อมูลล็อกของระบบปฏิบัติการ *nix ในหลายๆ ตัว แต่อย่างไรก็ตาม syslog ก็มีข้อเสียบางอย่าง ที่ log daemon ตัวอื่น เช่น syslog-ng, msyslog สามารถแก้ไขข้อบกพร่องดังกล่าวได้ เอกสารฉบับนี้จะแนะนำ syslog-ng ซึ่งเป็น log daemon ตัวใหม่ที่กำลังเป็นที่นิยมกันมากขึ้น และจะกล่าวถึงการสร้าง configuration แบบละเอียดเพื่อให้สามารถนำ syslog-ng ไปใช้งานได้จริง
แนะนำ Syslog-ng (Syslog new generation)
syslog-ng สามารถแก้ไขข้อบกพร่องส่วนใหญ่ของ syslog ได้ โดย
- syslog-ng สามารถทำงานได้ทั้งบน TCP และ UDP
- syslog-ng สามารถทำการกรอง (filter) ข้อมูลได้ด้วย regular expression
- syslog-ng สามารถทำงานในรูปแบบที่อ้างอิง priority/facility ได้ ดังนั้น มันจึงสามารถทำงานแทนที่ syslog ได้
- syslog-ng สนับสนุน log forwarding ซึ่งทำให้สามารถทราบได้ว่า ต้นทางของล็อกถูกส่งมาจากเครื่องใด และผ่านเครื่องใดมาบ้าง
นอกจากนี้ syslog-ng ยังมีรูปแบบของไฟล์ configuration ที่ง่าย แต่มีความยืดหยุ่นสูง สามารถนำไปประยุกต์ใช้ให้ตรงความต้องการได้โดยง่าย
การติดตั้ง Syslog-ng
syslog-ng ได้ถูกติดตั้งไว้แล้วใน Debian แต่ในระบบปฏิบัติการอื่นนั้น ผู้ดูแลระบบจะต้องติดตั้งเองโดยการคอมไพล์จาก source ทั้งนี้จะต้องติดตั้ง libol ก่อนจึงจะสามารถติดตั้ง syslog-ng ได้
ผู้ดูแลระบบสามารถดาวน์โหลด libol และ syslog-ng ได้จาก http://www.balabit.com/downloads/ หลังจากนั้นให้ขยายไฟล์ออกมา และทำการติดตั้งดังคำสั่งด้านล่างนี้
# cd libol-x.x
# ./configure; make; make install
# cd syslog-ng-x.x
# ./configure --sysconfdir=/etc; make; make install
คำสั่งด้านบนจะทำการติดตั้ง syslog-ng ไปไว้ที่ตำแหน่งโดยดีฟอลต์ (default location) คือ /usr/local หากต้องการติดตั้ง syslog-ng ไปยัง path อื่นให้ใช้คำสั่ง ./configure --prefix=/your/dir/
หลังจากการติดตั้งแล้ว ผู้ดูแลระบบจำเป็นต้องดำเนินการบางอย่างเพื่อให้ syslog-ng ทำงานได้ตามปกติ ดังนี้
- สร้างไดเรกทอรี /etc/syslog-ng
- สร้างไฟล์ configuration ของ syslog-ng (หรือคัดลอกมาจากไดเรกทอรี contrib/ และ doc/) ไว้ที่ /etc/syslog-ng/syslog-ng.conf
- สร้าง startup script ของ syslog-ng ไว้ที่ /etc/init.d/syslog-ng รวมทั้งสร้าง symbolic link จาก run level ต่างๆ เช่น /etc/rc2.d, /etc/rc3.d, /etc/rc5.d) ผู้ดูแลระบบสามารถคัดลอกตัวอย่าง startup script ของระบบปฏิบัติการที่ต้องการได้จากไดเรกทอรี contrib/
การใช้งาน syslog-ng
ผู้ดูแลระบบควรรัน syslog-ng ภายหลังการสร้างไฟล์ configuration เสร็จสิ้นแล้วเท่านั้น โดย syslog-ng มีออปชันในการรันค่อนข้างง่าย ดังตารางที่ 1
ตารางที่ 1 syslog-ng command line options
Flag |
Description |
-d |
แสดงข้อความดีบัก |
-v |
แสดงข้อความดีบักมากกว่าเดิม (verbose) |
-f filename |
ใช้ filename เป็นไฟล์ configuration (default = /etc/syslog-ng/syslog-ng.conf) |
-V |
แสดงหมายเลขเวอร์ชัน |
-p pidfilename |
ตั้งชื่อไฟล์ proce-ID (default = /var/run/syslog-ng.pid) |
Configuring Syslog-ng
Configuration ของ syslog-ng มีความยุ่งยากมากกว่าของ syslog แต่ก็ให้ประโยชน์ในแง่ของความยืดหยุ่นที่ได้และความสามารถที่มีมากกว่า หลังจากที่ทำความเข้าใจ configuration แล้ว ผู้ดูแลระบบสามารถสร้างไฟล์ configuration ง่ายๆ ขึ้นมาได้ด้วยตัวเอง และสามารถปรับปรุงให้เหมาะสมกับระบบของตนต่อไป
โดยปกติแล้ว syslog-ng จะอ่านข้อมูล configuration จากไฟล์ /etc/syslog-ng/syslog-ng.conf
ตัวอย่างที่ 1 แสดง configuration อย่างง่ายของ syslog-ng
options {
use_fqdn(no);
sync(0);
};
source s_sys { unix-stream("/dev/log"); internal(); };
source s_net { udp(); };
destination d_security { file("/var/log/security"); };
destination d_meages { file("/var/log/meages"); };
destination d_console { usertty("root"); };
filter f_authpriv { facility(auth, authpriv); };
filter f_meages { level(info .. emerg) and not facility(auth, authpriv); };
filter f_emergency { level(emerg); };
log { source(s_sys); filter(f_authpriv); destination(d_security); };
log { source(s_sys); filter(f_meages); destination(d_meages); };
log { source(s_sys); filter(f_emergency); destination(d_console); };
|
จากตัวอย่างจะเห็นได้ว่า ส่วนประกอบหลักของ configuration ประกอบไปด้วย 5 statement หลักคือ options{}, source{}, destination{}, filter{}, log{} ซึ่งแต่ละ statement จะคั่นด้วยเครื่องหมาย semicolon(;)
จะเห็นได้ว่ารูปแบบ configuration ของ syslog-ng.conf จะคล้ายคลึงกับรูปแบบของภาษาซี (C) ซึ่งทุกๆ statement จะต้องลงท้ายด้วยเครื่องหมาย semicolon ส่วน whitespace หรือช่องว่างนั้นไม่มีผลใดๆ ใน configuration จะใช้งานเพียงเพื่อให้สามารถอ่านได้ง่ายเท่านั้น
Global options
เป็นออปชันที่ถูกประกาศใช้งานภายใน options {} statement ซึ่งบางออปชันนั้นนอกจากสามารถใช้งานได้ใน option {} เองแล้วยังสามารถใช้งานใน statement อื่น เช่น source {}, destination {}, filter {}, log {} ได้อีกด้วย
ตารางที่ 2 options{}
Option |
Description |
chain_hostnames( yes | no ) |
หลังจากแสดง hostname ของเครื่องที่ส่งล็อกมายังเครื่องนี้ผ่านทาง tcp/udp แล้ว ให้แสดง hostname ของทุกเครื่องที่ข้อมูลล็อกถูก handle (โดย syslog-ng) มาตลอดทาง ซึ่งเหตุการณ์นี้จะเกิดขึ้นเมื่อล็อกถูกส่งต่อจาก syslog-ng server ไปยัง syslog-ng server อื่นๆ เป็นทอดๆ (default = yes) |
keep_hostname( yes | no ) |
ให้เชื่อใจ (trust) ค่า hostname ที่อยู่ใน tcp/udp message (default = no) |
use_fqdn( yes | no ) |
บันทึก full name ของเครื่องที่ส่ง tcp/udp message (default = no) |
use_dns( yes | no ) |
ให้ resolve ค่า IP address ในข้อมูลล็อก เป็น hostname (default = yes) |
use_time_recvd( yes | no ) |
ตั้งค่า message timestamp เป็นเวลาที่ล็อกเดินทางมาถึง ซึ่งโดยปกติแล้วจะใช้เวลาที่ระบุในล็อก (default = no) |
time_reopen( NUMBER ) |
เมื่อมีแพ็กเกต tcp ที่สูญหายระหว่างทางหรือเหตุที่ทำให้ไม่สามารถสื่อสารได้ตามปกติ syslog-ng จะพยายามสร้างการสื่อสารใหม่ขึ้นมา โดยจะรอเวลาตามที่ระบุ (NUMBER) หน่วยเป็นวินาที (default = 60) |
time_reap( NUMBER ) |
เมื่อ syslog-ng เปิดไฟล์ที่เป็น inactive file (ไม่มีการเขียนข้อมูลลงไฟล์) syslog-ng จะพยายามปิดไฟล์ดังกล่าว โดยจะรอเวลาตามที่ระบุ (NUMBER) หน่วยเป็นวินาที (default = 60) |
log_fifo_size( NUMBER )a |
ขนาดของ message ที่จะถูกนำไปเข้าคิวในหน่วยความจำก่อนที่จะถูกประมวลผล
ถ้าคิวเต็มและ syslog-ng ไม่สามารถทำงานได้ตามปกติ (busy) ข้อความล็อกที่ส่งเข้ามาจะถูกละทิ้ง แต่หากระบุขนาด FIFO จำนวนมากเกินไปก็จะทำให้สิ้นเปลืองหน่วยความจำ (default = 100)
|
sync( NUMBER )a |
จำนวนบรรทัดของ message ที่จะเขียนลงไฟล์ก่อนที่ไฟล์จะถูก synchronize (default = 0) |
owner( string )a |
ตั้งค่าชื่อ user สำหรับไฟล์ล็อกที่ syslog-ng สร้างขึ้นมาใหม่ (default = root) |
group( string )a |
ตั้งค่าชื่อ group สำหรับไฟล์ล็อกที่ syslog-ng สร้างขึ้นมาใหม่ (default = root) |
perm( NUMBER )a |
ตั้งค่า file permission สำหรับไฟล์ล็อก (default = 0600) |
create_dirs( NUMBER )a |
เป็นตัวบอกว่าจะให้ syslog-ng สร้างไดเรกทอรีใหม่ได้หรือไม่ ในกรณีที่ path ที่ระบุไม่มีอยู่จริงในระบบ (default = no) |
dir_owner( string )a |
ตั้งค่าชื่อ user สำหรับไดเรกทอรีที่ syslog-ng สร้างขึ้นมาใหม่ (default = root) |
dir_group( string )a |
ตั้งค่าชื่อ group สำหรับไดเรกทอรีที่ syslog-ng สร้างขึ้นมาใหม่ (default = root) |
dir_perm( NUMBER )a |
ตั้งค่า directory permission เมื่อ syslog-ng สร้างไดเรกทอรีใหม่ (default = 700) |
a : ออปชันที่สามารถนำไปใช้กับ file() ใน destination{} ได้
สำหรับออปชันที่เกี่ยวข้องกับ hostname ได้แก่ chain_hostnames(), keep_hostname(), use_fqdn() และ use_dns() นั้น สนใจเฉพาะค่า hostname ของเครื่องที่ส่งล็อกมาเท่านั้น ไม่เกี่ยวข้องกับ hostname ที่ระบุใน message body แต่อย่างใด
use_dns()
เช่น หากใน syslog-ng.conf มี statement ดังต่อไปนี้
options { use_dns(yes); };
และเครื่อง joe-chong ซึ่งมีไอพีเป็น 10.0.0.7 ส่งล็อกดังต่อไปนี้มาที่ log server
Oct 13 19:56:56 s_sys@10.0.0.7 sshd[1222]: Accepted publickey for ROOT from 10.0.0.222 port 1355 ssh2
เครื่อง log server จะทำการบันทึกล็อกดังนี้
Oct 13 19:56:56 s_sys@joe-chong sshd[1222]: Accepted publickey for ROOT from 10.0.0.222 port 1355 ssh2
จากตัวอย่างจะเห็นว่าไอพี 10.0.0.7 นั้นถูก resolve ให้เป็น joe-chong แต่ข้อมูลไอพีอื่นที่อยู่ใน message body คือ 10.0.0.222 นั้น ไม่ได้ถูก resolve ไปด้วย ดังนั้นจึงสรุปได้ว่าออปชัน use_dns(yes) นั้นจะทำการ resolve เฉพาะ hostname ที่อยู่ในส่วนต้นบรรทัดของ message เท่านั้น
นอกจากนี้ออปชันบางตัวที่เกี่ยวข้องกับไฟล์และไดเรกทอรี ยังสามารถใช้งานได้ทั้งใน global options() และ destination() ซึ่งก็คือ modifier ของออปชัน file() เช่น owner(), group() เป็นต้น ทั้งนี้หากมีการระบุค่าออปชันบางตัวที่ซ้ำกันใน options() section และ section อื่นๆ ค่าที่ระบุใน section อื่นๆ จะถูกนำไปใช้แทนที่ค่าใน options() section
keep_hostname() เป็นออปชันที่ใช้งานค่อนข้างมาก ซึ่งจะตั้งค่าดีฟอลต์เป็น no ซึ่งหมายถึง syslog-ng จะไม่ใช้ค่า hostname ที่ส่งมา มันจะทำการ resolve หา hostname จาก source IP address ของแพ็กเกตที่ส่งล็อกเข้ามา เพื่อป้องกันการปลอม hostname จากเครื่องที่ส่งล็อกเข้ามา ซึ่งจะแตกต่างจาก syslog ซึ่งใช้ค่า hostname ตามที่ได้รับมาจาก log message
chain_hostnames() โดยดีฟอลต์มีค่าเป็น yes ซึ่งหมายถึง syslog-ng จะแสดงรายชื่อ host ทุก host ที่ message ถูกส่งต่อมา (relayed by syslog-ng) โดย host ดังกล่าวต้องเป็น host ที่ติดตั้ง syslog-ng และทำหน้าที่ redirect ข้อมูลล็อกมายัง log server (ไม่ใช่ host ที่เป็น network host ตามปกติ เช่น router, firewall)
ตัวอย่างที่ 2 แสดงผลของการใช้งาน keep_hostname() และ chain_hostnames() ซึ่งทั้งสองค่าถูกตั้งค่าดีฟอลต์ให้เป็น yes โดยในตัวอย่างข้อมูลล็อกจะถูกสร้างขึ้นโดยเครื่องปัจจุบัน (locally) จากนั้นจะถูกส่งต่อไปยัง host1 ซึ่งมี hostname จริงๆ เป็น "linux" ซึ่งจะส่งข้อมูลล็อกต่อไปยัง host2 โดย host2 จะทำหน้าที่ตรวจสอบ hostname ผ่านทาง DNS จากนั้นล็อกจึงจะถูกส่งต่อไปยัง host3 ต่อไป
ตัวอย่างที่ 2 แสดงตัวอย่างล็อกที่ถูกส่งต่อผ่านโฮสต์
Original log entry on host1:
Oct 9 23:57:16 s_loc@linux syslog-ng[1656]: syslog-ng version 1.4.13 starting
Entry as sent to and recorded by host2:
Oct 9 23:57:16 s_loc@linux/host1 syslog-ng[1656]: syslog-ng version 1.4.13 starting
Same log entry as relayed from host2 to host3:
Oct 9 23:57:16 s_loc@linux/host1/host2 syslog-ng[1656]: syslog-ng version 1.4.13 starting
|
สิ่งที่น่าสนใจจากตัวอย่างที่ 2 คือ
- เมื่อ host2 บันทึกข้อมูลล็อก ตัว syslog-ng ได้ตรวจสอบข้อมูลจาก DNS แล้วพบว่า จริงๆ แล้ว host1 นั้นมี DNS name เป็น linux แต่ syslog-ng เองก็ยังไม่มั่นใจ จึงเพิ่ม hostname "linux" ต่อท้าย hostname "host1" (host1 อาจจะเป็นชื่อที่ปลอมมา)
- timestamp ที่ระบุในล็อกทั้งสามชุดมีเวลาที่ตรงกัน ซึ่งหมายถึง เวลาที่เห็นนั้นถูกสร้างขึ้นจากเครื่องที่ให้กำเนิดล็อกแล้วจึงส่งล็อกต่อไปเรื่อยๆ ผ่านโฮสต์ต่างๆ ซึ่งโฮสต์เหล่านั้นไม่ได้ตั้งค่า use_time_recd() ให้เป็น yes โฮสต์ต่างๆ จึงไม่ได้แก้ไขข้อมูล timestamp จึงมีผลให้เวลาทั้งสามจุดตรงกันหมด
- จากข้อมูลล็อกที่ host1 จะพบคำว่า s_loc อยู่ ซึ่งค่าดังกล่าวเป็นค่า source{} ของ syslog-ng ที่อยู่บน host1
ตัวอย่างที่ 3 แสดง configuration ของ syslog-ng บนเครื่อง host1
options{};
source s_loc {unix-stream("/dev/log"); internal(); };
destination d_host2 { udp("host2" port(514)); };
destination d_local { file("/var/log/messages"); };
log { source(s_loc); source(s_net); destination(d_host2); destination(d_local); };
|
Sources
จากตัวอย่างที่ 3 มีการประกาศค่า source{} หนึ่งครั้ง โดยข้อมูลภายใน source{} ซึ่งก็คือ source driver ทำหน้าที่ระบุถึงแหล่งที่มาของข้อมูลล็อก ทั้งนี้ใน syslog-ng.conf หนึ่งๆ สามารถประกาศ source{} ได้ไม่จำกัดครั้ง ซึ่งภายใน source{} แต่ละตัวนั้นสามารถบรรจุ driver ได้ไม่จำกัดเช่นกัน
รูปแบบการประกาศ source{}
source sourcelabel1 { drivers([options]); drivers([options]); etc. };
โดย sourcelabel หมายถึง string ที่ใช้เพื่ออ้างอิงกลุ่มของ source driver เพื่อให้สามารถนำไปใช้งานต่อได้อย่างสะดวก เช่น
source s_loc { unix-stream("/dev/log"); internal(); };
จากบรรทัดด้านบน s_loc เป็นชื่อที่ถูกใช้เพื่ออ้างอิงถึงข้อมูลล็อกที่ถูกดึงมาจาก /dev/log และข้อมูลล็อกจาก syslog-ng เอง
syslog-ng มีความหยืดหยุ่นอย่างมากในการใช้งาน source driver ซึ่งสามารถรับข้อมูลล็อกได้จาก Unix socket เช่น /dev/log หรือล็อกจาก syslog-ng เอง รวมทั้งล็อกที่ส่งมาจากเครื่องอื่นผ่านทาง TCP, UDP protocol และยังสามารถรับล็อกจากไฟล์พิเศษเช่น ไฟล์ใน /proc ได้อีกด้วย ตารางที่ 3
ตารางที่ 3 Source drivers
Source |
Description |
internal() |
ล็อกที่รับมาจาก syslog-ng daemon เอง |
file("filename" [options]) |
ล็อกที่อ่านมาจากไฟล์ที่ระบุไว้ เช่น /proc/kmsg |
pipe("filename") |
ล็อกที่รับมาจาก name pipe |
unix-stream("filename" [options]) |
ล็อกที่รับมาจาก Unix socket ที่อยู่ในโหมด connection-oriented stream เช่น /dev/log (maximum concurrent connections default = 100) |
unix-dgram("filename" [options]) |
ล็อกที่รับมาจาก Unix socket ที่อยู่ในโหมด connectionless datagram เช่น ล็อกของ klogd จาก /dev/log |
tcp([ip(address)] [port(#)] [max-connections(#)] ) |
ล็อกที่รับมาจากเครื่องอื่นที่ส่งข้อมูลผ่านทาง TCP ตามหมายเลขพอร์ตที่ระบุ (default = 514) โดยรับข้อมูลจาก local network interface (default = all) และสามารถระบุจำนวน concurrent connections ได้ (default = 10) |
udp([ip(address)] [port(#)]) |
ล็อกที่รับมาจากเครื่องอื่นที่ส่งข้อมูลผ่านทาง UDP ตามหมายเลขพอร์ตที่ระบุ (default = 514) โดยรับข้อมูลจาก local network interface (default = all) |
nternal()
syslog-ng เองจะส่งข้อมูลล็อก เช่น startup message, errors หรือล็อกอื่นๆ ไปยัง internal() ดังนั้นหากต้องการรับล็อกของตัวโปรแกรม syslog-ng จะต้องระบุ internal() ไว้ใน source{} ด้วย
file()
file() ใช้เพื่อระบุชื่อไฟล์ที่ต้องการให้ syslog-ng ไปดึงข้อมูลล็อกมา เช่น ไฟล์ /proc/kmsg ซึ่งเป็นไฟล์ข้อมูลล็อกของเคอร์เนลหากต้องการให้ syslog-ng ดึงข้อมูลล็อกจาก text file ปกติ เช่น ล็อกของ httpd นั้น จะต้องสร้างสคริปต์ขึ้นมาเพิ่มเติมเพื่อทำหน้าที่ pipe ผลลัพธ์ของคำสั่ง tail -f [filename] ไปยัง logger (ดูรายละเอียดเพิ่มเติมเกี่ยวกับการใช้งาน logger ได้จากคำสั่ง # man logger)
unix-stream(), unix-dgram()
เป็น source driver ที่สำคัญ โดยจะรับข้อมูลจากการเชื่อมต่อแบบ connection-oriented และ connectionless Unix socket สำหรับลีนุกซ์ที่ใช้เคอร์เนลเวอร์ชัน 2.4.1 หรือสูงกว่านั้น จะใช้งาน Unix datagram socket ดังนั้นหากต้องการเก็บข็อมูลล็อกของ /dev/log จะต้องใช้ unix-dgram("/dev/log") เท่านั้น จึงจะสามารถได้รับล็อกตามปกติ เช่น
source s_loc { unix-dgram("/dev/log"); internal(); };
หากใช้ลีนุกซ์ที่มีเวอร์ชันของเคอร์เนลเป็น 2.4.0 หรือต่ำกว่า จะต้องใช้ unix-stream() ในการเก็บข้อมูลล็อกจาก /dev/log
tcp(), udp()
ทั้ง tcp() และ udp() จะรับข้อมูลล็อกจาก remote host ผ่านทาง TCP protocol (connection-oriented) และ UDP protocol (connectionless) โดยทั้งคู่สามารถตั้งให้รอรับข้อมูลล็อกผ่านทาง IP address และ port ที่ระบุได้ โดยดีฟอลต์แล้ว syslog-ng จะรอรับการเชื่อมต่อที่ 0.0.0.0:514 ซึ่งหมายถึง "รอรับการเชื่อมต่อที่ทุก network interface, port 514"
การระบุ IP address มีประโยชน์สำหรับโฮสต์ที่มี network interface มากกว่าหนึ่ง และต้องการเปิดพอร์ตรอรับล็อกจากบาง interface เท่านั้น ดังตัวอย่างที่ 4
ตัวอย่างที่ 4 ตัวอย่างการระบุ ip, port ใน source{}
source s_tcpmessages { tcp( ip(192.168.1.19) port(10514) ); };
source s_udpmessages { ucp(); };
|
จากตัวอย่างที่ 4 ซึ่งกำหนดให้ s_tcpmessages รับข้อมูลล็อกทุกอันที่ส่งมายัง network interface ที่มีไอพีเป็น 192.178.190.190 TCP port 10514 ส่วน s_udpmessages นั้นรอรับข้อมูลล็อกทุกอันผ่านทาง UDP port 514 ในทุกๆ local network interface
ip(), port(), max_connections()
นอกเหนือจาก ip() และ port() แล้ว ยังมี max_connections() ซึ่งใช้ร่วมกับ tcp() เพื่อจำกัดจำนวนการเชื่อมต่อพร้อมกันสูงสุด ซึ่งการใช้งานออปชันนี้ต้องใช้ค่าที่เหมาะสมกับระบบ เพราะหากกำหนดค่าที่มากไปอาจจะมีผลให้ล็อกบางส่วนถูกทิ้ง (drop) ไปเมื่อเซิร์ฟเวอร์ทำงานเกินพิกัด หากกำหนดน้อยเกินไปและมีการเชื่อมต่อเพื่อส่งล็อกถึงขีดที่กำหนดไว้ จะมีผลให้ข้อมูลล็อกถูก drop ไป จนกระทั่งจะมีช่องว่างเพียงพอที่จะสร้างการเชื่อมต่อ
ตัวอย่างที่ 5 ตัวอย่างการใช้งาน max-connections()
source s_tcpmessages { tcp( ip(192.168.1.19) port(10514) max-connections(100)); };
|
ค่าดีฟอลต์ของ max-connections() สำหรับ unix-stream() มีค่าเป็น 100 และสำหรับ tcp() มีค่าเป็น 10
Destinations
syslog-ng สามารถเก็บข้อมูลล็อกในรูปแบบเดียวกันกับที่ syslog เก็บได้ ไม่ว่าจะเป็น ASCII file, name pipe, remote host (ผ่านทาง UDP) และแสดงผลออกทาง TTY นอกจากนี้ syslog-ng ยังสามารถส่งข้อมูลล็อกไปยัง Unix socket, remote host (ผ่าน TCP) และส่งต่อไปยัง standard input ของโปรแกรมอื่น
ตารางที่ 5 Destination drivers
Driver |
Description |
file("filename [$MACROS]") |
เก็บข้อมูลล็อกลง Ascii file ตามปกติ หาก syslog-ng ไม่พบไฟล์ตามที่ระบุ มันจะสร้างให้โดยอัตโนมัติ
ส่วน MACRO นั้น ใช้เพื่อกำหนดชื่อไฟล์แบบ dynamic เช่น ตั้งชื่อไฟล์ตาม facility ของข้อมูลล็อก
(โปรดอ่านรายละเอียดเพิ่มเติม ที่เอกสารเผยแพร่เรื่อง "ทำความรู้จักกับ syslogd" )
|
tcp("address" [port(#);]) |
ส่งข้อมูลล็อกไปยัง IP address หรือ hostname ที่ระบุผ่านทาง TCP port ที่ระบุ (default port = 514) |
udp("address" [port(#);]) |
ส่งข้อมูลล็อกไปยัง IP address หรือ hostname ที่ระบุผ่านทาง UDP port ที่ระบุ (default port = 514) |
pipe("pipename") |
ส่งข้อมูลล็อกไปยัง name pipe เช่น /dev/xconsole |
unix-stream("filename" [options]) |
ส่งข้อมูลล็อกไปยัง Unix socket แบบ connection-oriented เช่น /dev/log |
unix-dgram("filename" [options]) |
ส่งข้อมูลล็อกไปยัง Unix socket แบบ connectionless เช่น /dev/log |
usertty(username) |
ส่งข้อมูลล็อกไปยัง console ของ user ที่ระบุ |
program("/path/to/program") |
ส่งข้อมูลล็อกเพื่อนำไปเป็น standard input ของโปรแกรมที่ระบุ |
syslog-ng สามารถเก็บข้อมูลลงไฟล์ได้และมีความสามารถมากกว่า syslog ตรงที่มีการใช้งานมาโคร มาโครช่วยให้สามารถตั้งชื่อไฟล์ที่ใช้เก็บข้อมูลล็อกได้อย่างน่าดี เช่น ตั้งชื่อไฟล์ตามปีเดือนวัน หรือตั้งชื่อไฟล์ตาม facility, priority
ตัวอย่างที่ 6 ตัวอย่างการใช้งานมาโคร
destination d_dailylog { file("/var/log/messages.$WEEKDAY"); };
|
จากตัวอย่าง configuration ด้านบน เมื่อ syslog-ng ต้องการเขียนข้อมูลล็อกลงไฟล์ มันจะสร้างไฟล์ชื่อ /var/log/messages.Tues, /var/log/messages.Wed ซึ่งขึ้นกับวันที่เก็บข้อมูลล็อกดังกล่าว
ตารางที่ 6 Macros supported in file() destinations
Macro |
Expands to |
Program |
ชื่อของโปรแกรมที่ส่งล็อกเข้ามา |
HOST |
ชื่อโฮสต์ที่เป็นจุดกำเนิดล็อก |
FACILITY |
facility ของล็อกที่ถูกส่งเข้ามา |
PRIORITY or LEVEL |
priority ของล็อกที่ถูกส่งเข้ามา |
YEAR |
ปีปัจจุบันa |
MONTH |
เดือนปัจจุบันa |
DAY |
วันที่ปัจจุบันa |
WEEKDAY |
วันปัจจุบันa เช่น Monday |
HOUR |
ชั่วโมงปัจจุบันa |
MIN |
นาทีปัจจุบันa |
SEC |
วินาทีปัจจุบันa |
a : หากออปชัน use_time_recvd() ถูกตั้งค่า yes แล้ว ข้อมูลเวลาจะอ้างอิงจาก local system ขณะที่ล็อกเดินทางมาถึง แต่หาก use_time_recvd() มีค่าเป็น no ก็จะอ้างอิงเวลาจากเวลาที่ปรากฎในข้อมูลล็อก
syslog-ng จะสร้างไฟล์ขึ้นมาใหม่ หากไฟล์ที่ระบุใน file() ไม่มีอยู่จริง นอกจากนี้ syslog-ng ยังสามารถกำหนดออปชันบางตัวในระดับทั่วไป (general rule) คือให้มีผลกับ configuration ทั้งไฟล์ได้ ขณะเดียวกันก็สามารถกำหนดออปชันในระดับ per-log-file ได้ ซึ่งการกำหนดออปชันชนิดหลังนี้จะเป็นการ overridden ออปชันในระดับ general rule
ตัวอย่างที่ 7 การควบคุม file()
destination d_mylog { file("/var/log/ngfiles/mylog" create_dirs(yes)
dir_owner(root) dir_group(root) dir_perm(700)); };
|
จากตัวอย่างที่ 7 เป็นการระบุออปชัน dir_owner(), dir_group(), dir_perm() ใน destination{} ซึ่งค่าที่ระบุนี้จะมีผลแทนที่ค่าที่ระบุใน options{} โดยอัตโนมัติ นอกจากนี้ยังสามารถระบุออปชัน owner(), group(), perm() ได้เช่นเดียวกันกับออปชันด้านบน
โดยปกติ syslog-ng จะสร้างไฟล์ล็อกที่ไม่มีอยู่ในระบบโดยอัตโนมัติ เว้นเสียแต่ว่าไฟล์ที่ระบุดังกล่าวจะอยู่ใน path ที่ไม่มีอยู่จริงและออปชัน create_dirs() ถูกตั้งค่าเป็น no
sync() ถูกใช้เพื่อจำกัดความถี่ในการ synchronize ไฟล์ล็อก หากมีค่าสูงๆ จะทำให้ข้อมูลล็อกถูกนำไปเก็บไว้ที่แคช (cache) เป็นจำนวนมากก่อนที่จะถูก synchronize หรือบันทึกลงไฟล์ล็อกต่อไป หาก sync() มีค่าต่ำ ก็เป็นการลดความเสี่ยงในการสูญเสียข้อมูล เพราะข้อมูลที่ถูกประมวลผลแล้วจะถูกบันทึกลงไฟล์ล็อกทันที
โดยดีฟอลต์แล้ว ค่าล็อกถูกตั้งค่าเป็นศูนย์ ซึ่งหมายถึงให้บันทึกข้อมูลล็อกทุกอันในทันที โดยปกติค่า sync() ต่ำๆ จะเหมาะสำหรับระบบที่ข้อมูลล็อกไม่เยอะมาก ส่วนระบบที่มีข้อมูลล็อกจำนวนมากควรใช้ค่า sync() สูง ซึ่งค่าระหว่าง 100 ถึง 1000 นั้นถือว่ามีค่าสูงพอสมควร ซึ่งผู้ดูแลระบบจะต้องทดสอบเพื่อหาค่าที่เหมาะสมกับระบบของตนต่อไป
อย่างไรก็ตามหากระบบที่ติดตั้ง syslog-ng ได้ติดตั้งโปรแกรมจำพวก log monitoring tool เช่น Swatch แล้วไม่ควรตั้งค่า sync() ไว้สูงมากนัก เพราะอาจจะทำให้ไม่สามารถแจ้งเตือนผู้ดูแลระบบได้ในกรณีที่ไฟล์ล็อกโดนลบ
Filters
filter หรือการกรองข้อมูลเป็นส่วนที่มีความสำคัญส่วนหนึ่ง นอกเหนือจากการกรองข้อมูลโดยใช้ facility, priority แล้ว syslog-ng ยังสามารถตรวจสอบชื่อโปรแกรมที่ส่งข้อมูลล็อกมา ชื่อเครื่องที่ทำหน้าที่ส่งต่อล็อกมา และยังสามารถกรองข้อมูลล็อกตาม regular expression ที่ตั้งไว้อีกด้วย
filter{} statement ประกอบไปด้วย label (ชื่อเรียกของ filter{} ชุดนั้นๆ) และคำสั่งในการกรองข้อมูลอย่างน้อย 1 คำสั่ง โดยสามารถใช้ and, or, not ในการเชื่อมคำสั่งในการกรองข้อมูลได้
ตารางที่ 7 filter{} funtions
Function (criteria) |
Description |
facility( facility-name ) |
facility ที่ต้องการ |
priority( priority-name )
priority( priority-name1, priority-name2, etc, )
priority( priority-name1 .. priority-name2 ) |
ระดับของ priority ที่ต้องการ
- สามารถใช้เครื่องหมาย comma (,) คั่น หากต้องการมากกว่าหนึ่งระดับได้
- สามารถใช้เครื่องหมาย .. แทน priority ที่ต้องการระหว่าง priority ที่กำหนดได้ เช่น info .. warn |
level( priority-name ) |
เช่นเดียวกันกับ priority |
program( program-name ) |
ชื่อโปรแกรมที่สร้างล็อกขึ้นมา |
host( hostname ) |
ชื่อ host ที่ล็อกนี้ถูกสร้าง |
match( regular-expression ) |
regular expression ที่จะถูกนำไปเปรียบกับกับส่วน body ของล็อก |
filter( filter-name ) |
ชื่อ filter อื่นที่ต้องการนำมากรองอีกครั้ง |
จากตัวอย่างที่ 8 แสดง syslog-ng.conf ในระบบปฏิบัติการลินุกซ์เดเบียน 2.2 (Debian 2.2)
ตัวอย่างที่ 8 ตัวอย่างการใช้งาน filter{}
filter f_mail { facility(mail); };
filter f_debug { not facility(auth, authpriv, news, mail); };
filter f_messages { level(info .. warn) and not facility(auth, authpriv, cron, daemon, mail, news); };
filter f_cother { level(debug, info, notice, warn) or facility(daemon, mail); };
|
บรรทัดแรกในตัวอย่างที่ 8 filter f_mail กรองได้ข้อมูลล็อกทุกอันที่อยู่ใน facility mail
บรรทัดที่สอง filter f_debug กรองได้ข้อมูลล็อกทุกอันยกเว้น facility auth, authpriv, news, และ mail
บรรทัดที่สาม filter f_messages กรองได้ข้อมูลล็อกทุกอันที่มี priority ตั้งแต่ info จนถึง warn ยกเว้นข้อมูลล็อกที่มี facility เป็น auth, authpriv, cron, daemon, mail, news
บรรทัดสุดท้าย filter f_cother กรองข้อมูลล็อกที่มี priority เป็น debug, info, notice และ warn หรือ ข้อมูลล็อกที่มี facility เป็น daemin และ mail
Log statements
หลังจากที่ทำความเข้าใจส่วนประกอบต่างๆ คือ sources, filters และ destinations แล้ว ก็จะนำส่วนประกอบทั้งหมดมารวมไว้ใน log{}
ตัวอย่างที่ 9 ตัวอย่าง syslog-ng.conf
source s_loc { unix-stream("/dev/log"); internal(); };
source s_tcpmessages { tcp( ip(192.168.1.19); port(10514);); };
destination d_dailylog { file("/var/log/messages.$WEEKDAY"); };
destination d_untlog { file("/var/log/untlog" owner(unt)) perm(0600)); };
filter f_mail { facility(mail); };
filter f_messages { level(info .. warn) and not facility(auth, authpriv, cron, daemon, mail, news); };
log { source(s_tcpmessages); destination(d_untlog); };
log { source(s_loc); filter(f_mail); destination(d_untlog); };
log { source(s_loc); filter(f_messages); destination(d_dailylog); };
|
จาก log statement บรรทัดแรกนั้น จะทำให้ข้อมูลล็อกทุกอันที่มาจากเครื่อง 192.168.1.19 จะถูกบันทึกลงในไฟล์ /var/log/untlog
บรรทัดที่สองจะทำให้ข้อมูลล็อกของเมล์ (facility mail) ของ localhost ถูกบันทึกลงในไฟล์ /var/log/untlog
บรรทัดที่สามจะทำให้ข้อมูลล็อกของ localhost ที่ผ่านการกรองของ filter f_messages ถูกบันทึกลงในไฟล์ /var/log/messages.$WEEKDAY เช่น /var/log/Mon, /var/log/Sun
จากตัวอย่างที่ 9 อาจจะเกิดข้อสังสัยว่า ล็อกบางส่วนที่ไม่ได้ถูกจัดเก็บโดย log{} statement ทั้งสามตัวนั้นจะถูกจัดเก็บไว้ที่ใด syslog-ng มีค่า filter(DEFAULT) ซึ่งสามารถใช้ระบุในตอนท้ายเพื่อสั่งให้ syslog-ng บันทึกข้อมูลล็อกที่ไม่ได้ถูกจัดเก็บโดย log{} ก่อนหน้านี้ได้ ดังตัวอย่างที่ 10
ตัวอย่างที่ 10 ตัวอย่าง syslog-ng.conf
log { source(s_tcpmessages); destination(d_untlog); };
log { source(s_loc); filter(f_mail); destination(d_untlog); };
log { source(s_loc); filter(f_messages); destination(d_dailylog); };
log { source(s_loc); filter(DEFAULT); destination(d_dailylog); };
|
Advanced Configurations
ตัวอย่างที่ 11 แสดงการใช้ syslog-ng เพื่อคอยเฝ้าดูข้อมูลล็อกที่ต้องการ (log monitoring)
ตัวอย่างที่ 11
source s_local { unix_stream("/dev/log"); internal(); };
filter f_denials { match("[Dd]enied|[Ff]ail"); };
destination d_mail { program("/usr/local/sbin/mail.sh"); };
log { source(s_local); filter(f_denials); destination(d_mail); };
|
ตัวอย่างที่ 12 เป็นตัวอย่าง script ที่ใช้สำหรับส่งอี-เมล์
ตัวอย่างที่ 12
#!/usr/bash
while read line;
do
echo $line |mail -s "Weirdness on that Linux box" your_email@yourcompany.com
done
|
จุดที่น่าสนใจในตัวอย่างที่ 11 คือ match("[Dd]enied|[Ff]ail") ซึ่งหมายถึง ข้อมูลล็อกใดก็ตามที่มีคำว่า denied, Denied, Fail หรือ fail ปรากฏอยู่ ก็จะถูกส่งในรูปแบบอี-เมล์ไปยัง your_email@yourcompany.com โดย shell script ที่ชื่อ /usr/local/sbin/mail.sh
ข้อควรระวังในการใช้งานดังตัวอย่างที่ 11 คือ การใช้ program() นั้นเป็นการเรียกใช้งานโปรแกรมที่ระบุ โดยโปรแกรมนั้นจะยังคงรันอยู่จนกว่า syslog-ng จะหยุดการทำงานหรือเริ่มการทำงานใหม่ ดังนั้นผู้ดูแลระบบควรไตร่ตรองก่อนการใช้งานออปชันดังกล่าว เช่น หากรัน bash process ก็จะทำให้เกิดการสิ้นเปลืองงานทรัพยากร นอกจากนี้หากรันโปรแกรมในฐานะ root ก็จะเป็นการเพิ่มความเสี่ยงให้กับระบบอีกด้วย นอกจากนี้การใช้ระบบเตือนภัยผ่านทางอี-เมล์ดังตัวอย่างที่ 11 ยังก่อให้เกิดความเสี่ยงที่ทำให้ระบบถูกโจมตีแบบ Denial of Service ได้ เช่น ทำให้ mailbox ของผู้ดูแลระบบเต็ม