syslog สุดโหด เหมือนโกรธใครมา?

เพื่อให้รองรับกระแสโลก IT ที่ต้องคำนึงความปลอดภัย รวมถึงความมั่นใจในการส่งข้อมูลผ่าน syslog protocol

author image
drs

Technology evangelistic advocacy

Posted on 2023-01-06 08:14:30 +0700

จากภาพความทรงจำเดิมที่เคยได้ยินได้ฟังกันมา syslog รองรับ connection ที่ UDP/514 … ทุกวันนี้ภาพจำนั้นเปลี่ยนแปลงไปอย่างมาก เพื่อให้รองรับกระแสโลก IT ที่ต้องคำนึงความปลอดภัย รวมถึงความมั่นใจในการส่งข้อมูลผ่าน syslog protocol … จาก syslog server เดิม vs ความต้องการในปัจจุบัน

  1. คนส่งก็ส่งข้อความไป .. คนรับจะรับได้หรือไม่ ก็พอรับได้ vs ไม่ได้ log หายไม่ได้ สำคัญมาก ข้อความต้องอยู่ครบ
  2. ส่ง ๆ ไปใครจะมาดักอ่านกลางทางก็ไม่เป็นไรมั้ง vs ข้อมูลนี้ให้คนอื่นเห็นไม่ได้ ต้องรักษาความลับได้จนถึงปลายทาง
  3. ใครส่งข้อความมาให้(ก็ได้) พร้อมรับเข้ามาประมวล vs syslog จะรับข้อความจาก client ที่รู้จักเท่านั้น

เป้าหมายของ Syslog สุดโหด

นิยามที่ syslog server ที่ผมเรียกว่า syslog สุดโหดนั้น ผมอยากสื่อความหมายในมุมของการเชื่อมต่อจาก client ที่ต้องมีข้อกำหนดในการเชื่อมต่อ ไม่รองรับการเชื่อมต่อจาก client ที่ไม่สามารถพิสูจน์ตัวตนได้ และยังต้องการเข้ารหัสลับตั้งแต่ต้นทางถึงปลายทาง ดังนั้นในการกำหนดค่า configuration ของ syslog server จะต้องรองรับความสามารถดังนี้

  1. log หายไม่ได้ สำคัญมาก ข้อความต้องอยู่ครบ
  2. ข้อมูลนี้ให้คนอื่นเห็นไม่ได้ ต้องรักษาความลับได้จนถึงปลายทาง
  3. syslog จะรับข้อความจาก client ที่รู้จักเท่านั้น

จากเป้าหมาย 3 ข้อ ถ้าหยิบมาตีความให้เป็นข้อกำหนดทาง technical เพื่อตอบโจทย์ให้ครบทุกข้อ Syslog จะต้องรองรับ Protocol TCP, Transport Layer Security (TLS) ที่กำหนดให้ร้องขอจาก Client เพื่อตรวจสอบ Certificate จาก Client ได้ ที่เรียกว่า Mutual Authentication หรือจะเรียกรวม ๆ ว่า mTLS - Mutual Transport Layer Security

#0 เตรียมสร้าง Key Pair

ในการเตรียมทดสอบ mTLS ต้องจัดเตรียมสร้าง Key Pair ไว้ 3 ชุด และ ให้เป็นไปตามข้อกำหนดของ rsyslog และ client ที่จะนำมาทดสอบ (ในกรณีนี้เลือก Docker เป็น client ในการทดสอบ) กรณีศึกษาที่จะทดสอบ เลือกเป็น Self Signed มาใช้ในการทดสอบ

  1. สร้าง Key Pair เพื่อทำหน้าที่เป็น Certificated Authority
  2. สร้าง Key Pair สำหรับ rsyslog server ที่ signed โดย ​CA ในข้อที่ 1 และมีข้อมูลในส่วนของ SAN - Subject Alternative Name อยู่ด้วย
  3. สร้าง Key Pair สำหรับ client (ในกรณีนี้จะใส่ให้กับ Docker Daemon) ที่ signed โดย ​CA ในข้อที่ 1 และมีข้อมูลในส่วนของ SAN - Subject Alternative Name อยู่ด้วย

syslog mtls

ที่ syslog server จัดวางไฟล์ ca.crt,server1.key และ server1.crt ไว้ที่ /etc/pki/rsyslog

ที่ client จัดวาง ca.crt, client1.key และ client1.crt ไว้ที่ /etc/docker/

#1 กำหนดค่าให้ rsyslog

/etc/rsyslog.conf เป็นไฟล์หลักที่จะกำหนดการทำงานของ rsyslog เพื่อให้เป็นไปอย่างที่เราต้องการ

syslog > ~ sudo apt install -y rsyslog-gnutls
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following packages were automatically installed and are no longer required:
  libflashrom1 libftdi1-2
Use 'sudo apt autoremove' to remove them.
Suggested packages:
  gnutls-bin
[... truncated output ...]

syslog > ~ sudo vi /etc/rsyslog.conf

#-  เพิ่มข้อมูลส่วนนี้ใน configuration

module(load="imtcp"
    StreamDriver.Name="gtls"
    StreamDriver.Mode="1" # run driver in TLS-only mode
    StreamDriver.Authmode="x509/name"
    PermittedPeer="docker.d8k.io"
)
input(type="imtcp" port="514")
global(
    DefaultNetstreamDriver="gtls"
    DefaultNetstreamDriverCAFile="/etc/pki/rsyslog/ca.crt"
    DefaultNetstreamDriverCertFile="/etc/pki/rsyslog/server1.crt"
    DefaultNetstreamDriverKeyFile="/etc/pki/rsyslog/server1.key"
)

syslog ~  >  cat <<-EOF | sudo tee /etc/rsyslog.d/01-container-log.conf 
\$template containerLogs,"/var/log/docker/%hostname%_%syslogtag:R,ERE,1,ZERO:.*cname/([^\[]+)--end%.log"

if \$syslogtag contains 'cname'  then -?containerLogs

& stop
EOF

syslog > ~ sudo systemctl restart rsyslog

syslog > ~ ss -tlanp | grep 514
LISTEN 0      25            0.0.0.0:514          0.0.0.0:*
LISTEN 0      25               [::]:514             [::]:*

#2 เลือก Docker มาเป็นตัวอย่างของ Client

ในการกำหนด log driver จากเดิมที่ค่าปกติเป็น json-file ให้เปลี่ยนเป็น syslog และรองรับ mTLS จะกำหนดที่ /etc/docker/daemon.json

docker > ~ cat /etc/docker/daemon.json
{
   "log-driver": "syslog",
      "log-opts": {
           "syslog-address": "tcp+tls://syslog.d8k.io:514",
           "tag": "cname/\{\{.Name\}\}",
           "syslog-tls-ca-cert": "/etc/docker/ca.crt",
           "syslog-tls-cert": "/etc/docker/client1.crt",
           "syslog-tls-key": "/etc/docker/client1.key"
      }
}
# เพิ่มเติมข้อมูลส่วน log driver ในไฟล์

docker > ~ sudo systemctl restart docker

#3 ทดสอบการทำงาน และผลการทดสอบ

ในการทดสอบ จะสร้าง container ชื่อว่า mynginx จาก image ที่ชื่อว่า NGINX และทดลอง request ไปที่ container ตัวนี้ ซึ่งผลที่คาดว่าจะได้รับคือ มี access log เกิดขึ้นที่ syslog server ที่ /var/log/docker/<Docker host>-mynginx.log

[at Docker Host]
docker > ~ docker container run -d --name mynginx --rm nginx
68d9f69002be79e0125a6ad3b3d4cf1b94ff7aa787a2973412e834a7c1bb1542


[at Syslog Server]
syslog > ~ sudo ls -la /var/log/docker
total 16
drwxr-xr-x 2 syslog syslog 4096 Jan  6 14:44 .
drwxrwxr-x 9 root   syslog 4096 Jan  6 14:44 ..
-rw-r----- 1 syslog adm    4873 Jan  6 14:49 128.199.210.227_mynginx.log

syslog > ~ sudo tail -n 3 /var/log/docker/128.199.210.227_mynginx.log
Jan  6 14:49:57 128.199.210.227 cname/mynginx[3660]: 2023/01/06 14:49:57 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
Jan  6 14:49:57 128.199.210.227 cname/mynginx[3660]: 2023/01/06 14:49:57 [notice] 1#1: start worker processes
Jan  6 14:49:57 128.199.210.227 cname/mynginx[3660]: 2023/01/06 14:49:57 [notice] 1#1: start worker process 29

ข้อผิดพลาดที่อาจจะเกิดขึ้น

  • ถ้า Client ไม่รองรับ mTLS จะเกิดข้อความที่ฝั่ง syslog server ว่าเกิดข้อผิดพลาดขณะเชื่อต่อ
[at client (docker.d8k.io)]
docker > ~ logger --tcp --server syslog.d8k.io --port 514 "Hello Syslog Server"

[at syslog server]
syslog > ~ sudo tail -f /var/log/syslog
[... truncated output ...]
Jan  6 14:54:29 syslog rsyslogd: gnutls returned error on handshake: An unexpected TLS packet was received.  [v8.2112.0 try https://www.rsyslog.com/e/2083 ]
Jan  6 14:54:29 syslog rsyslogd: tcpsrv listener (inputname: 'imtcp') failed to process incoming connection with error -2083 [v8.2112.0 try https://www.rsyslog.com/e/2083 ]

  • ถ้า Client Certificate ไม่มี SAN - Subject Alternative Name ฝั่ง syslog server ก็ไม่สามารถพิสูจน์ตัวตนของฝั่ง client ได้ก็จะไม่อนุญาตให้เชื่อมต่อ
syslog > ~ sudo tail -f /var/log/syslog
[... truncated output ...]
Jan  6 15:09:45 syslog rsyslogd: error: peer name not authorized -  not permitted to talk to it. Names: CN: docker;  [v8.2112.0 try https://www.rsyslog.com/e/2088 ]
Jan  6 15:09:45 syslog rsyslogd: netstream session 0x7f67e000d640 from 128.199.210.227 will be closed due to error [v8.2112.0 try https://www.rsyslog.com/e/2089 ]
  • ถ้า Client ที่ไม่ได้รับอนุญาตมาขอเชื่อมต่อ ฝั่ง syslog server ก็สามารถพิสูจน์ตัวตนของฝั่ง client ได้ก็จริง แต่ว่าไม่ได้อยู่ในรายชื่อที่อนุญาตให้เชื่อมต่อ ก็จะไม่อนุญาตให้เชื่อมต่อ
syslog > ~ sudo tail -f /var/log/syslog
[... truncated output ...]
Jan  6 15:14:59 syslog rsyslogd: error: peer name not authorized -  not permitted to talk to it. Names: DNSname: docker.d8k.io; CN: docker;  [v8.2112.0 try https://www.rsyslog.com/e/2088 ]
Jan  6 15:14:59 syslog rsyslogd: netstream session 0x7f2f9401bef0 from 128.199.210.227 will be closed due to error [v8.2112.0 try https://www.rsyslog.com/e/2089 ]

ข้อมูลมูลเพิ่มที่เกี่ยวข้องกับ Syslog

Made by มูลค่าความสุข

Share on

Tags

Human knowledge belongs to the world

a line from the movie "Antitrust"