پرش به مطلب اصلی

معماری rsyslog

هر سرور لینوکس پیام لاگ تولید می‌کند و هر پیام باید جایی برود. rsyslog همان دیمونی است که این پیام‌ها را می‌گیرد، تصمیم می‌گیرد با آن‌ها چه کند و تحویلشان می‌دهد. این راهنما توضیح می‌دهد این خط لوله چگونه ساخته شده و rsyslog در چه کارهایی از گزینه‌های دیگر بهتر عمل می‌کند.

دیمون rsyslog چیست؟​

دیمون rsyslog یک برنامهٔ پس‌زمینه است (نه چیزی که کاربر مستقیم با آن کار می‌کند) که پیام‌های لاگ را از برنامه‌ها و از شبکه می‌گیرد و هر پیام را به مقصد مفیدی می‌رساند. روی سرور لینوکس امروزی، این دیمون معمولاً دو نقش متفاوت را هم‌زمان ایفا می‌کند:

  • جمع‌آوری لاگ محلی: هر چیزی را که سیستم‌عامل و برنامه‌ها می‌نویسند می‌گیرد، بر اساس facility و severity دسته‌بندی می‌کند و در فایل‌هایی مثل /var/log/messages و /var/log/secure می‌نویسد.
  • ارسال لاگ: پیام سرورهای دیگر را می‌گیرد و به یک سرور مرکزی می‌رساند.

به زبان ساده: rsyslog مثل دفتر پستی برای خطوط لاگ است. مرکز تفکیک، همان موتور فیلتر است و مسیرهای تحویل، همان اکشن‌های خروجی.

اطلاعات

واژهٔ syslog هم به پروتکل شبکه اشاره دارد و هم به خانواده‌ای از دیمون‌ها که این پروتکل را می‌فهمند. rsyslog پیاده‌سازی غالب روی لینوکس است و عملاً مرجع این پروتکل به شمار می‌رود.

چرا تقریباً همه‌جا نصب است؟​

پکیج rsyslog در تمام توزیع‌های بزرگ لینوکس وجود دارد و دیمون بسیاری از دستگاه‌های اختصاصی هم همان است. این فراگیری دلیلی فراتر از راحتی دارد: دستگاهی که تا حالا پیکربندی نکرده‌اید هم لاگ‌هایی می‌فرستد که rsyslog از قبل قالبشان را می‌شناسد.

نکته

اگر دیمون قدیمی syslog را روی Solaris یا AIX یا یک دستگاه قدیمی جایگزین می‌کنید، rsyslog سازگاری نسبی با پیکربندی کلاسیک BSD را نگه داشته است. مهاجرت معمولاً یعنی ترجمهٔ دستورهای قدیمی با علامت $، نه بازطراحی خط لوله.

معماری خط لوله​

هر پیام در rsyslog از یک مسیر ثابت و مشخص عبور می‌کند. مرحله‌ها عمداً کلی تعریف شده‌اند؛ به همین دلیل یک دیمون می‌تواند بدون تغییر در نحوهٔ دریافت پیام‌ها، هم‌زمان در فایل محلی بنویسد و به Elasticsearch هم بفرستد.

nginx · sshd · postgresqlبرنامه‌هاnginx · sshd · postgresqlبافر حقلوی و ژورنال systemdسیستم‌عامل و ژورنالبافر حقلوی و ژورنال systemdsyslog روی UDP یا TCPسرورهای راه دورsyslog روی UDP یا TCPimjournal · imtcp · imudp · imuxsockماژول‌های ورودیimjournal · imtcp · imudp · imuxsockیک بافر ورودیصف اصلی پیامیک بافر ورودیشرط‌های RainerScriptرولست و فیلترهاشرط‌های RainerScriptیک بافر برای هر مقصدصف هر خروجییک بافر برای هر مقصدomfile · omfwd · omelasticsearchماژول‌های خروجیomfile · omfwd · omelasticsearch/var/log/*فایل‌های محلی/var/log/*لاگ سرور یا SIEMسرور جمع‌آوریلاگ سرور یا SIEM

ماژول‌های ورودی​

ماژول ورودی (با پیشوند im) افزونه‌ای است که می‌داند پیام را از یک منبع مشخص بخواند. هیچ چیز بدون عبور از یک ماژول ورودی وارد موتور rsyslog نمی‌شود.

ماژول ورودیمنبعی که می‌خواند
imjournalژورنال systemd، تا rsyslog و journalctl رویدادهای یکسانی ببینند
imtcpپیام‌هایی که از طریق TCP از میزبان‌های دیگر می‌رسند
imudpپیام‌هایی که از طریق UDP از میزبان‌های دیگر می‌رسند
imuxsockسوکت یونیکس سنتی /dev/log
imkmsgبافر حلقوی کرنل از طریق /dev/kmsg
imfileفایل‌های لاگ دلخواه، برای دنبال کردن لاگ‌های موجود
imrelpپروتکل RELP که برای هر پیام تأییدیه می‌گیرد
یاداشت

در نسخه‌های فعلی rsyslog، ماژول imtcp ورودی پشتیبان‌شدهٔ TCP برای محیط عملیاتی است. ماژول قدیمی‌تر imptcp هنوز وجود دارد اما دیگر گزینهٔ پیشنهادی نیست.

صف اصلی پیام​

هر پیامی که وارد موتور می‌شود، پیش از هر چیز دیگر در یک صف اصلی پیام قرار می‌گیرد. صف یک فضای انتظار است که تولیدکنندهٔ سریع را از مصرف‌کنندهٔ کند جدا می‌کند و همین ایده پشت بیشتر ویژگی‌های پایداری rsyslog است.

پس از اینکه رولست پیام را پردازش کرد، پیام از صف اصلی خارج و وارد صف پایین‌دستی می‌شود و در همان لحظه از صف اصلی حذف می‌شود. این جابه‌جایی مهم است، چون تضمین می‌کند یک خروجی کند هرگز دریافت پیام را متوقف نمی‌کند.

رولست و فیلترها​

رولست یک بلوک نام‌دار از قواعد است که هم فیلتر می‌کند و هم عمل انجام می‌دهد. داخل هر قاعده، شرط روی فیلدهای ساختاریافتهٔ پیام سنجیده می‌شود، نه روی متن خام؛ پس تطبیق بر اساس severity یا نام برنامه دقیق است و به قالب‌بندی وابسته نیست.

rsyslog فیلدهای ساختاریافته برای زمان، نام میزبان، نام برنامه، شناسهٔ پروسه، شناسهٔ پیام، facility، severity و داده‌های ساختاریافته را نگه می‌دارد. تحلیل مدرن بر پایهٔ RFC 5424 انجام می‌شود که استاندارد کنونی syslog است و قالب قدیمی RFC 3164 هم برای فرستنده‌های قدیمی پذیرفته می‌شود.

اکشن‌ها و صف‌ها​

اکشن (با پیشوند om) کاری با پیام انجام می‌دهد: نوشتن در فایل، ارسال به میزبان دیگر یا تحویل به پایگاه داده. هر اکشن می‌تواند صف مخصوص خودش را داشته باشد و این صف‌ها مستقل از هم تنظیم می‌شوند.

چرا مهم است: همین صفِ جداگانه برای هر خروجی است که به یک نمونهٔ rsyslog اجازه می‌دهد در برابر کندی یک کلاستر Elasticsearch مقاوم بماند و هم‌زمان فایل‌های محلی را با تمام سرعت بنویسد. مقصد کند صف خودش پر می‌شود و در نهایت پیام دور می‌ریزد، در حالی که بقیهٔ مسیرها بی‌وقفه کار می‌کنند.

صف و کنترل جریان​

رفتار صف مهم‌ترین تصمیم طراحی در یک استقرار rsyslog است؛ چون تعیین می‌کند ساعت ۳ بامداد که شبکه قطع شد، صبح چه چیزی از آن شب باقی مانده است.

نوع صفمحل نگهداریپس از ری‌استارتکاربرد معمول
Directبدون ذخیرهنداردنوشتن فایل محلی، جایی که تأخیر مهم‌تر است
LinkedList / FixedArrayحافظهنداردمسیرهای پرترافیک که افتادن پیام در آن‌ها قابل قبول است
Disk-Assistedحافظه با سرریز به دیسکداردارسال به سرور مرکزی، انتخاب رایج در محیط عملیاتی
Diskفقط دیسکداردمسیرهای حسابرسی و بایگانی که هیچ پیامی نباید گم شود

پارامترهای صف با نحو RainerScript داخل همان آبجکتی نوشته می‌شوند که صف را در اختیار دارد؛ پس main_queue()، ruleset() و action() هر کدام تنظیمات queue.* مستقل خود را می‌گیرند.

/etc/rsyslog.conf
main_queue(
queue.type="LinkedList"
queue.size="500000"
queue.filename="mainq"
queue.saveOnShutdown="on"
queue.maxDiskSpace="2g"
)

آستانه‌های بالا و پایین (Watermark)​

کنترل جریان از دو آستانه استفاده می‌کند که به آن‌ها watermark می‌گویند. وقتی صف به آستانهٔ بالا می‌رسد، تولیدکننده کند یا متوقف می‌شود؛ پردازش وقتی ادامه پیدا می‌کند که صف زیر آستانهٔ پایین تخلیه شود.

فاصلهٔ میان این دو آستانه عمدی است. بدون آن، صفی که مدام نزدیک آستانه نوسان کند بارها بین حالت پر و خالی می‌لغزد و پردازش را مکرراً متوقف می‌کند.

هشدار

صفی که پر شود با صدای بلند شکست نمی‌خورد. بسته به پیکربندی، rsyslog پیام‌ها را بی‌سروصدا دور می‌ریزد و در خروجی هم چیزی نشان نمی‌دهد. نرخ پرشدگی صف‌ها را پایش کنید و تحویل را مفروض نگیرید.

اطلاعات

زبان RainerScript​

RainerScript زبان پیکربندی rsyslog است که مشخصاً برای پردازش جریان رویدادها طراحی شده. این زبان جایگزین نحو قدیمی با علامت $ شد، هرچند شکل قدیمی هنوز کار می‌کند و در بسیاری از پیکربندی‌های موجود پیدا می‌شود.

آبجکت‌های اصلی که می‌نویسید global()، module()، input()، action()، template() و ruleset() هستند. کنترل جریان با دستورهای آشنای if و then انجام می‌شود؛ پس نحو برای هر کسی که یک اسکریپت شل نوشته، خوانا می‌ماند.

/etc/rsyslog.conf
global(
workDirectory="/var/spool/rsyslog"
maxMessageSize="64k"
defaultNetstreamDriver="gtls"
)

module(load="imtcp" port="6514")
module(load="imjournal" StateFile="imjournal.state")

template(name="ForwardFormat" type="string"
string="<%pri%>1 %TIMESTAMP:::date-rfc3339% %hostname% %app-name% %procid% %msgid% %structured-data% %msg%\n")

if ($syslogfacility-text == "authpriv") then {
action(type="omfile" file="/var/log/secure" template="RSYSLOG_TraditionalFileFormat")
stop
}
نکته

پارامتر workDirectory مشخص می‌کند صف‌های دیسکی و Disk-Assisted پشتیبان انباشته‌شده‌شان را کجا بنویسند. آن را روی پارتیشنی بگذارید که فضای آزاد واقعی دارد؛ چون صفی که نتواند فایل سرریزش را بنویسد، جایی برای پیام‌های ورودی ندارد.

کاربردهای عملی rsyslog​

rsyslog در چند دلیل مشخص جای خودش را در یک استک مدرن باز کرده است. دانستن اینکه کدام‌یک از این دلایل به شما مربوط می‌شود، تعیین می‌کند اصلاً به آن نیاز دارید یا نه.

تحمل قطعی شبکه​

قوی‌ترین دلیل برای انتخاب rsyslog همین است. syslog روی TCP خالص تأییدیه ندارد؛ پس فرستنده‌ای که بافرش هنگام قطعی شبکه پر شود، پیام‌ها را بی‌سروصدا دور می‌ریزد. صف Disk-Assisted قطعی را روی دیسک جذب می‌کند و بعد از برگشت لینک تخلیه‌اش می‌کند.

سناریوTCP خالص با imtcpRELP با imrelpصف Disk-Assisted
تأیید تحویل بدون از دست رفتن❌✅✅
بافر کردن پیام هنگام قطعی❌تا حدی✅
بقای پیام‌ها پس از ری‌استارت❌❌✅

پروتکل RELP (مخفف Reliable Event Logging Protocol) تأیید به‌ازای‌هرپیام را به syslog اضافه می‌کند. گیرنده هر پیام را تأیید می‌کند و بعد فرستنده آن را دور می‌ریزد؛ همین تحویلِ «به‌درد‌بخور» را به تحویل تأییدشده تبدیل می‌کند.

جمع‌آوری لاگ در یک ناوگان​

مرکزی کردن لاگ دلیلی است که بیشتر سازمان‌ها rsyslog را اجرا می‌کنند. وقتی لاگ فقط روی همان دستگاهی بماند که آن را تولید کرده، دستگاهِ از کار افتاده شاهدِ خودش را هم با خود می‌برد.

از 10.0.1.10 به بعدسرورهای وباز 10.0.1.10 به بعداز 10.0.2.10 به بعدمیزبان‌های پایگاه دادهاز 10.0.2.10 به بعدفایروال و سوئیچتجهیزات شبکهفایروال و سوئیچارسال بافرشده روی TLSریلی rsyslogارسال بافرشده روی TLSصف Disk-Assistedسرور مرکزی لاگصف Disk-Assistedنگهداری بلندمدتآرشیو لاگنگهداری بلندمدتجستجو و هم‌بستگی‌یابیSIEM و هشدارجستجو و هم‌بستگی‌یابی

مسیریابی به مقصدهای متعدد​

فهرست ماژول‌های خروجی برای یک دیمون سیستمی غیرعادی گسترده است. یک نمونه می‌تواند از یک جریان پیام واحد، هم فایل محلی بنویسد، هم به rsyslog دیگری بفرستد و هم رویدادهای ساختاریافته را به یک کلاستر جستجو بفرستد.

ماژول خروجیمقصد
omfileفایل محلی همراه با چرخش
omfwdسرور syslog دیگر روی UDP، TCP یا RELP
omelasticsearchکلاستر Elasticsearch یا OpenSearch
omkafkaیک تاپیک در Apache Kafka
omhiredisیک لیست یا استریم در Redis
ommongodb / ompgsql / ommysqlپایگاه دادهٔ سندی یا رابطه‌ای
omsnmpترپ SNMP برای تجهیزات شبکه

فیلتر کردن پیش از ذخیره‌سازی​

چون رولست روی فیلدهای ساختاریافته تست می‌شود نه روی متن، قواعد مسیریابی حتی وقتی برنامه قالب پیامش را عوض کند درست می‌مانند. جدا کردن رویدادهای احراز هویت در /var/log/secure یک خط شرط است، نه یک عبارت باقاعدهٔ شکننده.

امنیت

پیام‌های لاگ مرتب داده‌ای را در خود دارند که دوست ندارید منتشر شود: نشانی IP مبدأ، نام کاربری، رشتهٔ پرس‌وجو همراه توکن و URL کامل. هر مقصد لاگ را انبار حساس در نظر بگیرید و دسترسی نوشتن روی لاگ سرور را محدود کنید.

محدودیت‌های rsyslog​

ارزیابی صادقانه از هر متن تبلیغاتی مهم‌تر است؛ چون انتخاب rsyslog به بهانهٔ نادرست، سامانه‌ای می‌سازد که نگهداری‌اش سخت است.

  • این یک پلتفرم مشاهده‌پذیری نیست. rsyslog خطوط لاگ را جابه‌جا می‌کند. متریک ذخیره نمی‌کند، تریس درخواست نمی‌گیرد و داشبورد نمی‌سازد؛ پس در کنار ابزارهایی مثل Prometheus می‌نشیند و جای آن‌ها را نمی‌گیرد.
  • پیچیدگی پیکربندی سریع بالا می‌رود. یک خط ارسال ساده است؛ اما به‌محض درگیر شدن صف، زنجیرهٔ اعتماد TLS، محدودیت نرخ و مسیریابی به‌ازای هر برنامه، پیکربندی تبدیل به یک برنامهٔ واقعی می‌شود که به بازبینی نیاز دارد.
  • UDP طبق طراحی ناپایدار است. این پروتکل هیچ تضمینی برای تحویل نمی‌دهد و پورت پیش‌فرض ۵۱۴ روی UDP هر وقت حجم ناگهانی از بافر دریافت بگذرد، پیام دور می‌ریزد.
  • نحو قدیمی همچنان وسوسه‌کننده است. دستورهای قدیمی $ActionQueueType و $AllowedSender کار می‌کنند و همین باعث می‌شود دو سبک پیکربندی در یک فایل قاطی شوند و معلوم نشود کدام واقعاً فعال است.
  • تکرار پیام را پنهان می‌کند. rsyslog می‌تواند پیام‌های یکسان را محدود کند؛ این برای یک سرویس پرسروصدا خوب است، اما یعنی یک حملهٔ واقعی که همان بستهٔ خراب را هزار بار می‌فرستد ممکن است به شکل یک خط دیده شود.
نکته

روی یک ماشین تنها، برای بررسی تعاملی journalctl معمولاً ابزار بهتری است؛ چون از پیش نمایه‌بندی شده و به دیمون جداگانه نیاز ندارد. rsyslog وقتی دست به کار می‌شود که دیگر سؤال دربارهٔ یک میزبان نباشد و دربارهٔ یک ناوگان باشد.

ارتباط rsyslog با ژورنال systemd​

این دو سیستم هم‌پوشانی دارند و درک مرزشان از کار تکراری جلوگیری می‌کند. rsyslog می‌تواند ژورنال را از طریق imjournal بخواند؛ یعنی هر دو نما از یک منبع حقیقت تغذیه می‌شوند.

پرسشابزار مناسب‌تر
در یک ساعت گذشته روی این میزبان چه گذشت؟journalctl
همه‌ی ۲۰۰ میزبان دیشب چه کردند؟rsyslog
چطور رویدادهای ژورنال را به SIEM ببرم؟rsyslog همراه با imjournal
لاگ‌ها را روی لینک ناپایدار چطور بفرستم؟rsyslog با صف Disk-Assisted
یاداشت

چون imjournal ژورنال را از آخرین موقعیت خوانده‌شده بازپخش می‌کند، با ری‌استارت شدن rsyslog هیچ رویدادی گم نمی‌شود؛ به شرطی که فایل state روی ذخیره‌سازی دائمی باشد. حذف آن فایل باعث پخش دوباره از ابتدای ژورنال می‌شود.

خلاصه​

  • دیمون rsyslog همان برنامه‌ای است که پیام‌های لاگ را روی لینوکس می‌گیرد، فیلتر می‌کند، بافر می‌کند و تحویل می‌دهد.
  • مسیر خط لوله ثابت است: ماژول‌های ورودی به صف اصلی می‌دهند، رولست فیلتر می‌کند و صف هر خروجی به ماژول‌های خروجی می‌رسد.
  • صف Disk-Assisted تعیین‌کننده‌ترین ویژگی آن است، چون قطعی شبکه را جذب می‌کند و بعداً تخلیه می‌شود و پیامی از دست نمی‌دهد.
  • در مرکزی کردن لاگ یک ناوگان، مسیریابی چندمقصدی و فیلتر روی فیلد ساختاریافته، rsyslog از گزینه‌های رقیب بهتر عمل می‌کند.
  • پلتفرم مشاهده‌پذیری نیست و به‌محض دخالت TLS، محدودیت نرخ و صف‌های متعدد، پیکربندی آن به بازبینی جدی نیاز دارد.
  • روی یک میزبان تنها، برای بررسی journalctl را ترجیح دهید و کار ناوگان را به rsyslog بسپارید.

برای دستورهایی که این لاگ‌ها را در کار روزمره خوانا می‌کنند، دستورات لاگ‌گیری در لینوکس را ببینید و برای رویکرد مسئله‌محور پیدا کردنشان، راهنمای ذهنی لاگ‌گیری را بخوانید.