تجمیع لاگ های سیستم های شبکه مبتنی بر یک پروتکل استاندارد که معمولاً همه پشتیبانی می کنند ، در یک سیستم مقیاس پذیر با رابط کاربری وب و امکانات تعریف داشبورد و داده کاوی و ... می تونه یک سناریوی خوب باشه که در این مطلب پیاده سازیش را مرور می کنیم.
تصور من این است که شما یک ادمین لینوکسی هستید و با راه اندازی و مدیریت انواع قضایا روی پلتفرم های لینوکسی آشنایی دارید و الان یک centos7 خام برای اینکار نصب و آپدیت کرده اید و برای سادگی تمرین SELinux آن را هم disable نموده اید که بریم سر اصل مطلب؛
فرض بر این هست که می دانید syslog یک پروتکل از دهه 80 میلادی منطبق بر RFC5424 , RFC3164 است که برای تعیین فرمت ثبت وقایع سیستم (لاگ ها) بکار می رود. پیاده سازی های متعددی نیز دارد که syslog deamon, rsyslog, syslog-ng مشهورترین آن ها هستند و از این میان rsyslog امروزه در میان لینوکس ها شایع تر است.
و می دانید که elasticsearch یک
RESTful distributed NoSQL database, multitenant-capable full-text search engine with an HTTP web interface and schema-free JSON documents
است. (همون تو مایه های دیتابیس ولی از جنس موتور جستجو و ایندکس داده و ...) که برای ذخیره و جستجو و مدل های مختلف داده کاوی بسیار کاراست و اکنون حتی برای بسیاری از سناریوها و پروژه ها بجای RDBMSهای سنتی استفاده می شود.
و وقتی می گوییم ELK Stack منظور مجموعه elasticsearch (موتور جستجو و ایندکس) و logstash (جمع آوری کننده و خواننده دیتا - در اینجا لاگ ها) و kibana (اینترفیس و رابط وب) و Beats (یک agent جمع آوری تخصصی لاگ و دیتا از کلاینت ها) است.
* در این مطلب راجع به beatها صحبت خاصی نمی کنیم.
بصورت پیش فرض rsyslog روی centos شما نصب است و اگر نبود یا هر توزیع لینوکس دیگری بود می توانید نصب کنید و معمولاً مراحل همین شرح ذیل است و تفاوتی ندارد.
این با لاگ نگاری journald از systemd متفاوت است و هر کدام جداگانه کار می کنند اما با هم تعامل دارند.
در حالت عادی که deamon سرویس rsyslog روی لینوکس شما فعال است در var/log/ فایل های لاگ بصورت فرمت Text نگه داری می شوند. در شرایطی که از چند سیستم لاگ جمع آوری کنید با templateی که اینجا استفاده می شود ساختار این پوشه بشکل ذیل می شود.
فایل پیش فرض تنظیمات rsyslog در etc/rsyslog.conf/ است و البته مثل سایر سرویس ها در پوشه rsyslog.d هم فایل کانفیگ بگذارید اعمال می شود.
روی rsyslog server برای فعال کردن listen روی پورت پیش فرض 514 TCP و UDP و تنظیم نحوه گروه بندی فایل ها بشکل بالا باید این خط ها در این فایل افزوده یا غیرکامنت شوند :
$ModLoad imudp $UDPServerRun 514 $ModLoad imtcp $InputTCPServerRun 514 $template RemoteServer, "/var/log/%HOSTNAME%/%SYSLOGFACILITY-TEXT%.log" *.* ?RemoteServer
*منظور از imudp ، input module udp است و برای tcp هم همینطور.
سپس یکبار systemctl restart rsyslog می کنیم.
روی rsyslog client ها برای اینکه لاگ ها را به سرور push کنند در اواخر همین فایل عبارت ذیل را از کامنت در می آوریم (اضافه می کنیم) ، که جای remote-host ، اسم یا IP سرور را می نویسیم :
*.* @@[remote-host]:514
اکنون کلاینت ها لاگ های تنظیم شده را به سرور می فرستند و اگر روی سرور از var/log/ یک ls بگیرید لاگ های کلاینت ها را مشاهده خواهید کرد.
این ساده ترین حالت تنظیم rsyslog برای تجمیع لاگ ها است. در پایان این مطلب منابعی که برای مطالعه بیشتر ذکر شده اند تنظیمات بسیار بیشتر و دقیق تری را نیز توضیح می دهد.
دقت کنید ترافیک rsyslog کاملاً clear text است و اعتبارسنجی نیز ندارد اما براحتی می توان استفاده از TLS را برای آن تنظیم نمود. (راهنماهای آن در لینک های ذیل مطلب هست.)
البته می توان با عبارت ذیل در سرور ، ارسال کننده ها را محدود کرد
$AllowedSender TCP, 127.0.0.1, 192.168.75.0/24, *.domain
برای امتحان می توانید از ابزار logger استفاده نمایید. مثلاً من در کلاینت یک لاگ auth.crit می سازم تا ببینم در سرور نمایش داده می شود؟
#logger -p 'auth.crit' 'sample critical auth'
بحث دیگر این است که اگر rsyslog server از دسترس خارج شود کلاینت ها باید این صف لاگ ها را تا بالا آمدن و برقراری مجدد سرور چگونه نگه دارند و موارد مشابه این که به صف لاگ ها مربوط می شود.
برای اینکار باید queue.type را در تنظیمات کلاینت ها مشخص کرد. جزئیات صف های rsyslog ذیل همین مطلب لینک شده است. بصورت کلی 3 نوع Direct که پیش فرض است و مستقیماً لاگ ها را ارسال می کند ، Disk queues که لاگ های در صف مانده را روی دیسک می نویسد و Memory queues که آن ها را در RAM نگه داری می کند در دسترس هستند. البته برای استفاده از سیستم های با قابلیت صف تخصصی مثل RabbitMQ و kafka و redis هم ماژول هست.
ما اینجا از memory queue استفاده می کنیم. این خطوط باید در فایل تنظیم کلاینت ها اضافه شوند:
$ActionQueueType LinkedList $ActionQueueFileName rsyslog_backup $ActionQueueSaveOnShutdown on $ActiRetryCount -1
برای ActionQueueType چهار نوع “FixedArray”, “LinkedList”, “Direct” , “Disk” در دسترس می باشد که LinkedList به معنای ذخیره در RAM و تخصیص فضای آن بصورت on-fly است. 2 نوع دیسک و دایرکت که مشخص هستند، درخصوص FixedArray نیز باید گفت آن هم با روشی متفاوت در RAM ذخیره می شود.
تا اینجا دیدیم rsyslog چطو لاگ ها را روی یک سرور جمع می کند. طبیعی است که وقتی با میلیون ها لاگ سیستم های یک سازمان طرف هستیم کاوش در فایل های تکست جداگانه خیلی بهینه و کارا نیست.
در بخش ELK ، ابزار Logstash در این سناریو، فرمت syslog را برای ما بصورت JSON در می آورد و به موتور elasticsearch می دهد تا ایندکس کند و kibana داشبورد تحت وب در اختیار ما می گذارد تا داده ها را بصری سازی و داده کاوی کنیم.
قبل از هر چیز بیاد داشته باشید elasticsearch با جاوا نوشته شده و باید روی لینوکس شما نصب باشد.برای اطمینان می توانید از دستور java -version استفاده نمایید.
من از centos7 استفاده می کنم اما روی سایر توزیع ها نیز با ادبیات خودشان همین روال صادق است.
همچنین برای نصب نیاز به IP غیر ایرانی دارید که اگر vpn دارید که هیچ اما اگر ندارید مقاله ذیل برای نصب و تنظیم tor به شما کمک می کند:
حال که قضیه مخفی کردن IP ایرانی را برای نصب اولیه به هر ترتیب حل کرده اید :
#rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch #vi /etc/yum.repos.d/elasticsearch.repo
این محتوی را در elasticsearch.repo درج نمایید:
[elasticsearch-6.x] name=Elasticsearch repository for 6.x packages baseurl=https://artifacts.elastic.co/packages/6.x/yum gpgcheck=1 gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch enabled=1 autorefresh=1 type=rpm-md
الان کافیست yum install elasticsearch بزنید ، سپس systemctl start elasticsearch (و enable) بکنید و برای اطمینان از صحت کار
#lsof -i -P -n | grep LISTEN | grep 9200 #curl -XGET 'http://localhost:9200/_all/_search?q=*&pretty'
را اجرا نمایید.
تا اینجا موتور elasticsearch نصب شده است.
اکنون برای ارسال لاگ ها به آن باید logstash را نصب کنیم.
#yum install logstash #systemctl start logstash #systemctl enable logstash
پس از نصب elasticsearch و logstash اکنون باید kibana را برای رابط کاربری وب نصب کنیم.
#yum install kibana #systemctl start kibana #systemctl enable kibana #lsof -i -P -n | grep LISTEN | grep 5601 #vi /etc/kibana/kibana.yml
و در kibana.yml این را اضافه نمایید.
server.host: "0.0.0.0" server.name: "kibana.example.com" elasticsearch.url: http://localhost:9200
اگر در مرورگر خود http://localhost:5601 باز کنید این صفحه را خواهید دید.
اما اگر از سایر سیستم های شبکه بخواهید http://[ip]:5601 یا http://[ip]:9200 را ببینید conecction refuse خواهید گرفت.
برای حل این مشکل در فایل etc/elasticsearch/elasticsearch.yml/ عبارت network.host: 0.0.0.0 را اضافه/ویرایش/uncomment کنید و یکبار systemctl restart elasticsearch بزنید. در فایل etc/kibana/kibana.yml/ نیز با عبارت ذیل همین کار را می کنیم و آن را systemctl restart kibana می نماییم.
server.host: "0.0.0.0"
حالا باید فوروارد کردن لاگ ها از rsyslog به elasticsearch را در logstash تنظیم کنیم. برای اینکار فایل etc/logstash/conf.d/logstash.conf/ را می سازیم و عبارات ذیل را در آن درج می کنیم. خیلی تنظیم ساده ای است، گفته ایم روی پورت udp10514 چیزی که آمد و از نوع rsyslog است را json کن و به elasticsearch روی همین سیستم (127.0.0.1) بفرست.
input { udp { host => "127.0.0.1" port => 10514 codec => "json" type => "rsyslog" } } filter { } output { if [type] == "rsyslog" { elasticsearch { hosts => [ "127.0.0.1:9200" ] } } }
و در نهایت systemctl restart logstash می کنیم.
حال باید در تنظیمات rsyslog درج کنیم که لاگ ها را براساس شکلی که فرمت json-template تعریف کرده ایم به udp10514 همین سیستم (127.0.0.1) که logstash روی آن بگوش است بفرست.
این فایل را ایجاد کرده و این محتوی را در آن می ریزیم
#vi /etc/rsyslog.d/01-json-template.conf
template(name="json-template" type="list") { constant(value="{") constant(value="\"@timestamp\":\"") property(name="timereported" dateFormat="rfc3339") constant(value="\",\"@version\":\"1") constant(value="\",\"message\":\"") property(name="msg" format="json") constant(value="\",\"sysloghost\":\"") property(name="hostname") constant(value="\",\"severity\":\"") property(name="syslogseverity-text") constant(value="\",\"facility\":\"") property(name="syslogfacility-text") constant(value="\",\"programname\":\"") property(name="programname") constant(value="\",\"procid\":\"") property(name="procid") constant(value="\"}\n") }
انواع این propertyها که در متن بالا استفاده شده را اینجا می توانید ببینید : https://www.rsyslog.com/doc/v8-stable/configuration/properties.html
و etc/rsyslog.d/70-output.conf/ را نیز ایجاد کرده و درون آن می نویسیم :
#vi /etc/rsyslog.d/70-output.conf
*.* @127.0.0.1:10514;json-template
اکنون یک systemctl restart rsyslog می زنیم و برای اطمینان از صحت مراحل طی شده دستور ذیل را صادر می کنیم
curl -XGET 'http://localhost:9200/logstash-*/_search?q=*&pretty'
در kibana هم اگر روی discover بزنید اضافه شدن داده های logstash را خواهید دید.
تا اینجا ما rsyslogها را برای تجمیع لاگ ها روی سرور تنظیم و فعال کرده ایم و ELK Stack را نیز نصب و تنظیم و آماده نموده ایم. اکنون بیایید یک داشبورد وبی ساده برای لاگ ها بسازیم تا ایده کلی را درک کنید و سپس درصورت تمایل به راهنماهای بسیار متعدد روی اینترنت که حتی پیاده سازی SIEM حرفه ای با elasticsearch موجود هستند برای مطالعه بیشتر مراجعه بفرمایید.
این مراحل را طی کنید:
هم اکنون شما با کلیک بر روی discover می توانید لاگ های وارد شده را ببینید.
خاطرتان هست با logger در کلاینت centos3 برای تست rsyslog یک پیام با محتوی sample critical auth ایجاد کردیم؟ قشنگی کار اینجاست که اکنون می توانید این مدل محتوی پیام ها را براحتی سرچ کنید!
برای ساخت داشبورد با چارت و نمودار روی visualize کلیک کنید و create a visualization را بزنید. وقتی یک visualization ساختید با کلیک بر روی dashboard می توانید آن را اضافه کنید. مراحل کلی ساخت داشبورد بصورت ذیل است.
راهنمای مدل های انواع visualization ها در اینترنت هست. من اینجا برای نشان دادن concept مثلاً یک vertical bar ایجاد می کنم.
احتمالا Y-axis خودش روی count هست. یعنی تعداد را روی محور y نمایش بده.
حال برای محور x باید bucket تعریف کنیم. یعنی تعداد چه چیزی را نمایش بده. من بشکل تصویر ذیل یک چارت میله ای ساخته ام که تعداد لاگ های هر سرویس روی هر سیستم را نمایش می دهد و در نهایت آن را save می کنم.
سپس در dashboard می توانیم این visualization یا بقیه را به داشبورد جاری اضافه و save کنیم.
خیلی خیلی ELK قابلیت و خاصیت دارد که انشاالله در نوشته های بعدی باید به آن ها پرداخت، منجمله Beat ها که اتفاقاً به مبحث جمع آوری دیتا از روی کلاینت ها مرتبط هستند.
این مطلب مروری اجمالی روی بحث تجمیع لاگ ها روی یک rsyslog سرور مرکزی و ذخیره و ایندکس آن ها در elasticsearch و نحوه مرور و پیمایش آن ها در kibana بود. لینک های ذیل برای مطالعه بیشتر بسیار مفید هستند.
https://tools.ietf.org/html/rfc3164
https://tools.ietf.org/html/rfc5424
https://debian-handbook.info/browse/squeeze/sect.syslog.html
https://www.rsyslog.com/doc/v8-stable/
https://www.rsyslog.com/doc/v8-stable/tutorials/tls_cert_summary.html
https://www.rsyslog.com/doc/v8-stable/concepts/queues.html
https://www.rsyslog.com/doc/v8-stable/configuration/properties.html
https://www.plesk.com/blog/featured/linux-logs-explained/
https://devconnected.com/the-definitive-guide-to-centralized-logging-with-syslog-on-linux/
https://devconnected.com/monitoring-linux-logs-with-kibana-and-rsyslog/