ลดความยุ่งยากในการใช้คลาวด์ พูดคุยกับเจ้าหน้าที่

รวม Log จากหลายเครื่องไว้ที่เดียวด้วย rsyslog
Home รวม Log จากหลายเครื่องไว้ที่เดียวด้วย rsyslog

รวม Log จากหลายเครื่องไว้ที่เดียวด้วย rsyslog

เมื่อเซิร์ฟเวอร์ถูกบุกรุก สิ่งแรกที่ผู้โจมตีทำคือลบ Log บนเครื่องนั้น การเก็บ Log ไว้แค่บนเครื่องที่สร้างมันจึงไม่ปลอดภัย และยังไล่ปัญหาที่เกิดข้ามหลายเครื่องได้ยากเพราะต้อง SSH เข้าไปไล่ดูทีละเครื่อง

การรวม Log ไว้ที่เดียวแก้ทั้งสองเรื่อง คู่มือนี้ตั้ง rsyslog ซึ่งติดตั้งมาพร้อมกับ Linux เกือบทุกดิสทริบิวชันอยู่แล้ว ให้ทำหน้าที่เป็นเซิร์ฟเวอร์กลาง

สิ่งที่ต้องเตรียม

  • เครื่องหนึ่งเครื่องสำหรับเป็นเซิร์ฟเวอร์ Log พร้อมพื้นที่ดิสก์เพียงพอ
  • เครื่องต้นทางที่ต้องการส่ง Log
  • เครือข่ายภายในระหว่างกัน หรือ VPN หากอยู่คนละที่

ประเมินพื้นที่คร่าว ๆ เซิร์ฟเวอร์เว็บทั่วไปสร้าง Log ระบบราว 50-200 MB ต่อเดือนต่อเครื่อง หากรวม Log ของเว็บเซิร์ฟเวอร์ด้วยจะมากกว่านั้นหลายเท่า

ขั้นตอนที่ 1: ตั้งฝั่งเซิร์ฟเวอร์ให้รับ Log

sudo nano /etc/rsyslog.d/10-server.conf
# รับผ่าน TCP ซึ่งเชื่อถือได้กว่า UDP
module(load="imtcp")
input(type="imtcp" port="514" address="10.0.0.5")

# แยกไฟล์ตามชื่อเครื่องและชื่อโปรแกรม
template(name="RemoteLogs" type="string"
  string="/var/log/remote/%HOSTNAME%/%PROGRAMNAME%.log")

# กฎนี้ใช้กับ Log ที่มาจากเครื่องอื่นเท่านั้น
if $fromhost-ip != '127.0.0.1' then {
    action(type="omfile" dynaFile="RemoteLogs"
           fileCreateMode="0640" dirCreateMode="0750"
           fileOwner="syslog" fileGroup="adm")
    stop
}

บรรทัด stop สำคัญ มันป้องกันไม่ให้ Log จากเครื่องอื่นถูกเขียนปนลงไฟล์ของเครื่องนี้ด้วย

sudo mkdir -p /var/log/remote
sudo chown syslog:adm /var/log/remote
sudo rsyslogd -N1
sudo systemctl restart rsyslog

คำสั่ง rsyslogd -N1 คือตรวจไวยากรณ์โดยไม่เริ่มทำงานจริง ใช้ทุกครั้งก่อนรีสตาร์ต

เปิดพอร์ตเฉพาะจากเครือข่ายภายใน

sudo ufw allow from 10.0.0.0/24 to any port 514 proto tcp
sudo ss -tlnp | grep 514

ขั้นตอนที่ 2: ตั้งฝั่งเครื่องต้นทางให้ส่ง Log

sudo nano /etc/rsyslog.d/90-forward.conf
# คิวบนดิสก์ กัน Log หายเมื่อเซิร์ฟเวอร์กลางล่มชั่วคราว
action(type="omfwd"
       target="10.0.0.5" port="514" protocol="tcp"
       queue.type="LinkedList"
       queue.filename="fwdRule1"
       queue.maxdiskspace="1g"
       queue.saveonshutdown="on"
       action.resumeRetryCount="-1")
sudo rsyslogd -N1
sudo systemctl restart rsyslog

ส่วนของคิวคือสิ่งที่ทำให้ระบบนี้ใช้งานได้จริง หากเซิร์ฟเวอร์กลางดับ เครื่องต้นทางจะเก็บ Log สะสมไว้บนดิสก์ไม่เกิน 1 GB แล้วส่งย้อนหลังให้เมื่อกลับมา

ทดสอบ

logger -t test-message "ทดสอบส่ง log จาก $(hostname)"

แล้วตรวจที่เซิร์ฟเวอร์กลาง

sudo ls -R /var/log/remote/
sudo tail /var/log/remote/web1/test-message.log

ขั้นตอนที่ 3: ส่ง Log ของ Nginx เข้ามาด้วย

Nginx เขียนไฟล์เองโดยไม่ผ่าน syslog ตามค่าเริ่มต้น เปลี่ยนให้ส่งผ่าน syslog ได้

sudo nano /etc/nginx/nginx.conf
error_log syslog:server=unix:/dev/log,tag=nginx_error warn;
access_log syslog:server=unix:/dev/log,tag=nginx_access combined;
sudo nginx -t && sudo systemctl reload nginx

วิธีนี้ทำให้ Log ของเว็บถูกส่งต่อไปเซิร์ฟเวอร์กลางด้วยกฎเดียวกัน โดยไม่ต้องตั้งค่าเพิ่ม

ขั้นตอนที่ 4: ตั้งการหมุนไฟล์ไม่ให้ดิสก์เต็ม

sudo nano /etc/logrotate.d/remote
/var/log/remote/*/*.log {
    daily
    rotate 90
    compress
    delaycompress
    missingok
    notifempty
    create 0640 syslog adm
    sharedscripts
    postrotate
        /usr/lib/rsyslog/rsyslog-rotate
    endscript
}

ทดสอบโดยไม่แตะไฟล์จริง

sudo logrotate -d /etc/logrotate.d/remote

เก็บ 90 วันเป็นจุดเริ่มต้นที่เหมาะสมสำหรับการตรวจสอบย้อนหลัง หากมีข้อกำหนดด้านการปฏิบัติตามกฎเกณฑ์ให้ปรับตามนั้น

ขั้นตอนที่ 5: เข้ารหัสการส่งด้วย TLS

จำเป็นเมื่อ Log วิ่งข้ามเครือข่ายที่ไม่ใช่วงภายในของคุณเอง เพราะ Log มักมีชื่อผู้ใช้ IP และรายละเอียดระบบ

sudo apt install -y rsyslog-gnutls

ฝั่งเซิร์ฟเวอร์

global(
  DefaultNetstreamDriver="gtls"
  DefaultNetstreamDriverCAFile="/etc/ssl/certs/ca.pem"
  DefaultNetstreamDriverCertFile="/etc/ssl/certs/server.pem"
  DefaultNetstreamDriverKeyFile="/etc/ssl/private/server-key.pem"
)
module(load="imtcp" StreamDriver.Name="gtls"
       StreamDriver.Mode="1" StreamDriver.AuthMode="x509/name")
input(type="imtcp" port="6514")

ฝั่งต้นทางเปลี่ยน port เป็น 6514 และเพิ่ม StreamDriver.Mode="1" ในบล็อก action

ขั้นตอนที่ 6: ค้นหา Log ที่รวมไว้

# การล็อกอินที่ล้มเหลวทุกเครื่อง
sudo grep -r 'Failed password' /var/log/remote/ | tail -20

# เรียงว่าเครื่องไหนสร้าง Log เยอะสุด
sudo du -sh /var/log/remote/* | sort -h

# ดูช่วงเวลาที่สนใจ
sudo zgrep -h '25/Sep/2026:14:' /var/log/remote/*/nginx_access.log*

เมื่อปริมาณมากขึ้นจนคำสั่ง grep ไม่ทันใจ ค่อยพิจารณาต่อยอดไปเป็น Loki หรือ OpenSearch โดยใช้ rsyslog เป็นตัวส่งเข้าไปได้เช่นกัน

ปัญหาที่พบบ่อย

ไม่มีไฟล์เกิดขึ้นในโฟลเดอร์ remote

ตรวจสามอย่างตามลำดับ หนึ่งเซิร์ฟเวอร์ฟังพอร์ตอยู่จริงด้วย ss -tlnp | grep 514 สองเครื่องต้นทางเชื่อมต่อได้ด้วย nc -vz 10.0.0.5 514 สามดู Log ของ rsyslog เองด้วย sudo journalctl -u rsyslog -n 50

Log จากเครื่องอื่นปนกับ Log ของเซิร์ฟเวอร์กลาง

ลืมใส่ stop ท้ายบล็อกเงื่อนไข ทำให้กฎเริ่มต้นทำงานต่อและเขียนซ้ำลง /var/log/syslog

ดิสก์เต็มเร็วผิดปกติ

หาไฟล์ที่โตเร็วด้วย sudo du -sh /var/log/remote/* | sort -h | tail สาเหตุที่พบบ่อยคือ Log ระดับ debug ที่เปิดไว้แล้วลืมปิด หรือแอปที่วนเขียนข้อความผิดพลาดซ้ำ ๆ

เวลาบน Log ไม่ตรงกันระหว่างเครื่อง

ตั้ง NTP ให้ตรงกันทุกเครื่องด้วย timedatectl set-ntp true และใช้ Timezone เดียวกันทั้งระบบ Log ที่เวลาไม่ตรงกันทำให้เรียงลำดับเหตุการณ์ข้ามเครื่องไม่ได้เลย

ต้องการวางระบบเก็บ Log ที่รองรับการตรวจสอบย้อนหลัง ติดต่อ THAI DATA CLOUD ได้ที่ https://thaidata.cloud/contact/

ผู้ให้บริการคลาวด์ไทย
เพื่อธุรกิจของคนไทย

"มุ่งมั่น" และ "มั่นคง"
พร้อมรับมือทุกการเติบโต
Trust Cloud
คลาว์ที่ปลอดภัย
คือรากฐานที่มั่นคง
cloud security