استک ELK مجموعهای از ابرازهای متنباز است که برای جمعآوری، تحلیل و نمایش Log برنامهها و سرویسها استفاده میشود. این استک از منابع و فرمتهای ورودی بسیاری پشتیبانی میکند. همچنین با استفاده از logهای دریافتی این برنامه، میتوانید وضعیت سرویسها یا دلیل احتمالی خطاهای ایجادشده را بررسی کنید.
اجزای اصلی این سرویس شامل Elasticsearch، Logstash، Kibana و Beats است. وظیفهی Beats جمعآوری دیتا و log از منابع مختلف و فرستادن آن به Logstashیا Elasticsearch است. Logstash بعد از دریافت اطلاعات Beatها، آنها را دستهبندی و پردازش میکند و به خروجی که معمولن Elasticsearchاست، میفرستد. Elasticsearch اطلاعات دریافتشده را نگهداری میکند یا برای نمایش دادن به شکل گرافیکی به Kibana میفرستد.
پیشنیازها
برای دنبال کردن این آموزش، به یک ابرک با سیستمعامل Ubuntu نیاز دارید که در این آموزش از نسخهی 18.04 آن استفاده شده است؛ همچنین به یک کاربر غیر root با دسترسی sudo نیاز دارید. سختافزاری که برای این آموزش توصیه میکنیم، ابرکی با حداقل GB4 فضای رم و پردازندهی ۲ هستهای است.
برای دسترسی به سرویس Kibana میتوانید به جای آدرس IP ابرک از یک نامدامنه استفاده کنید. برای اینکار لازم است پیش از شروع مراحل، نامدامنهی خود را روی ابرک تنظیم کنید.
سرویسهای Logstash و Elasticsearch برای اجرا شدن به جاوا نیاز دارند. نسخهی سازگار با Elasticsearch، نسخهی ۸ و ۹ است. اما Logstash فقط با نسخهی ۸ سازگار است. به همین دلیل از Java 8 استفاده میکنیم. پیش از شروع آموزش مطمین شوید Java 8 به شکل کامل روی ابرک نصب شده است.
برای دسترسی به Kibana از Nginx به عنوان Reverse Proxy استفاده میشود؛ بنابراین لازم است پیش از شروع نصب ELK، سرویس Nginxروی ابرک نصب و راهاندازی شده باشد.
راهنمای نصب گام به گام ELK
در گام اول، با نصب Elasticsearch آشنا میشوید. Packageهای این برنامه، در Repository رسمی Ubuntu وجود ندارد به همین دلیل لازم است ابتدا Repositoryهای مورد نیاز را اضافه کنیم. برای این کار، با استفاده از دستور زیر کلید عمومی Elasticsearch را اضافه کنید:
wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -
اکنون به کمک دستور زیر میتوانید آدرس Repository موردنیاز را به لیست Repositoryهای apt اضافه کنید:
echo "deb https://artifacts.elastic.co/packages/7.x/apt stable main" | sudo tee -a /etc/apt/sources.list.d/elastic-7.x.list
برای اعمال تغییرات انجامشده، لازم است یکبار دستور Update را اجرا کنید:
sudo apt update
پس از تغییرات بالا، اکنون میتوانید با دستور زیر Elasticsearch را نصب کنید:
sudo apt install elasticsearch
سرویس Elastic تمام ترافیک ورودی روی پورت 9200 را دریافت میکند. پیش از ادامهی روند نصب و استفاده از این سرویس، لازم است بخشی از تنظیمات را تغییر دهید تا دسترسی دیگران به اطلاعات این سرویس را مسدود کنید. برای این کار، لازم است خط مربوط به network.host را از حالت comment خارج کنید و سپس به عنوان مقدار این متغیر، localhost را بنویسید:
sudo nano /etc/elasticsearch/elasticsearch.yml
نکته: پسوند yml نشاندهندهی نوع خاصی از فایل است که به فاصلهی ابتدای هر خط حساس است و فاصلههای ایجادشده با space و tab تفاوت دارند. در ویرایش این فایل، به فاصلهها و تغییر آنها دقت کنید.
پس از اعمال این تغییر و ذخیرهی تظیمات جدید، سرویس Elastic را راهاندازی کنید:
sudo systemctl start elasticsearch
ممکن است راهاندازی سرویس Elasticsearch با مشکل روبهرو شود. یکی از دلایل آن میتواند خطای Timeout در مراحل راهاندازی سرویس باشد. برای افزایش مقدار Timeout میتوانید دستورهای زیر را اجرا کنید:
sudo mkdir /etc/systemd/system/elasticsearch.service.d
echo -e "[Service]\nTimeoutStartSec=240" | sudo tee /etc/systemd/system/elasticsearch.service.d/startup-timeout.conf [Service]
همچنین برای فعالشدن خودکار سرویس پس از هربار راهاندازی مجدد سرور، میتوانید دستور زیر را وارد کنید:
sudo systemctl enable elasticsearch
برای اطمینان از درستی انجام مراحل بالا، با استفاده از دستور زیر یک درخواست HTTP برای پورت 9200 خود بفرستید. با توجه به توضیحات قبل، اگر سرویس Elastic به درستی فعال شده باشد، با ارسال درخواست برای پورت 9200 از این سرویس پاسخ دریافت میکنید:
"curl -X GET "localhost:9200
شیوه نصب و تنظیم Kibana
با توجه به اضافه کردن کلید عمومی و آدرس Elasticsearch به Repositoryهای apt در مرحلهی قبل، اکنون نصب Kibana با استفاده از apt به راحتی امکانپذیر است:
sudo apt install kibana
با استفاده از دستورهای زیر، سرویس Kibana را راهاندازی و در زمان boot فعال کنید:
sudo systemctl enable kibana
sudo systemctl start kibana
با توجه به اینکه سرویس Kibana برای دریافت درخواستهای localhost تنظیمشده، برای دسترسی به پنل Kibana نیاز است از یک Reverse Proxy (در این آموزش Nginx) استفاده کنید. با توجه به ایجاد دسترسی خارجی از طریق Nginx، لازم است با تنظیم username و password، میزان دسترسی به پنل Kibana را محدود کنید. برای این کار، ابتدا به کمک openssl، مقدارهای username و password را تعیین کنید. این مقدارها در فایلی به آدرس etc/nginx/htpasswd.users ذخیره میشوند که تنظیمات nginx مربوط است. پس از اجرای دستور زیر، از شما خواسته میشود تا مقدار گذرواژه را تعیین کنید و مقدار kibanaadmin را به عنوان نام کاربری در نظر میگیرد:
echo "kibanaadmin:`openssl passwd -apr1`" | sudo tee -a /etc/nginx/htpasswd.users
برای استفاده از nginx، یک server block جداگانه برای Kibana ایجاد کنید. در این آموزش، از دامنهی example.com استفاده شده است. اگر پیش از این برای سرور دستکم یک نامدامنه تنظیم کردهاید، میتوانید از نامدامنهی خود در ایجاد server block استفاده کنید. در حالات دیگر، میتوانید برای دسترسی به Kibana از آدرس IP سرور استفاده کنید:
sudo nano /etc/nginx/sites-available/example.com
در فایل تنظیمات ایجادشده، مقدارهای زیر را وارد کنید و به جای example.com مقدار آدرس IP سرور یا نامدامنهی خود را وارد کنید:
} server ;listen 80 ;server_name example.com ;auth_basic "Restricted Access" ;auth_basic_user_file /etc/nginx/htpasswd.users } / location ;proxy_pass http://localhost:5601 ;proxy_http_version 1.1 ;proxy_set_header Upgrade $http_upgrade ;'proxy_set_header Connection 'upgrade ;proxy_set_header Host $host ;proxy_cache_bypass $http_upgrade { {
برای فعالسازی تنظیمات انجامشده روی Nginx، دستور زیر را وارد کنید:
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/example.com
برای بررسی درست بودن فایلهای Nginx از نظر نگارشی دستور زیر را وارد کنید. خروجی دستور، باید مانند شکل زیر باشد:
sudo nginx -t
اکنون میتوانید سرویس Nginx را دوباره فعال کنید:
sudo systemctl restart nginx
اگر روی سرور از فایروال استفاده میکنید، لازم است اجازهی ورود ترافیک مربوط به سرویس Nginx را بدهید. برای انجام این کار در سرویس ufw دستور زیر را وارد کنید:
sudo ufw allow 'Nginx Full'
اگر تمام مراحل را به درستی طی کرده باشید، اکنون میتوانید با وارد کردن آدرس IP سرور یا نامدامنهی خود در مرورگر، پنل Kibana را ببینید:
http://server_ip/status
نصب و تنظیم Logstash
برای نصب Logstash دستور زیر را وارد کنید:
sudo apt install logstash
برای انجام تنظیمات مربوط به Logstash، در مسیر باید /etc/logstash/conf.d سه فایل جداگانه ایجاد کنید سرویس Logstash در استک ELK، اطلاعات ورودی را از منابعی دریافت میکند که در فایل تنظیمات مشخص شده است. سپس با توجه به فایل تنظیمات مربوط به filter، دادهها پردازش میشوند و سپس به خروجی از قبل مشخصشده فرستاده میشوند. فایلهای تنظیماتی که در این مسیر قرار میدهید، درواقع تنظیمات مربوط به ورودی، پردازش و خروجی اطلاعات هستند.
برای ساخت فایل تنظیمات ورودی، دستور زیر را وارد کنید:
sudo nano /etc/logstash/conf.d/02-beats-input.conf
مقدارهای زیر را در این فایل بگذارید، سپس تغییرات را ذخیره کنید و خارج شوید:
input { beats { port => 5044 } }
بعد با استفاده از دستور زیر، فایل تنظیمات filter اطلاعات را ایجاد کنید و تنظیمات زیر را وارد کنید. این تنظیمات، پس از دریافت اطلاعات syslog آنها را دستهبندی میکند و برای نمایش در Kibana قابل استفاده میکند (در این آموزش، از syslog به عنوان مثال استفاده شدهاست. برای دریافت فایل تنظیمات سرویسهای رایج دیگر، میتوانید به مستندات رسمی Elastic مراجعه کنید):
sudo nano /etc/logstash/conf.d/10-syslog-filter.conf
filter { if [fileset][module] == "system" { if [fileset][name] == "auth" { grok { match => { "message" => ["%{SYSLOGTIMESTAMP:[system][auth][timestamp]} %{SYSLOGHOST:[system][auth][hostname]} sshd(?:\[%{POSINT:[system][auth][pid]}\])?: %{DATA:[system][auth][ssh][event]} %{DATA:[system][auth][ssh][method]} for (invalid user )?%{DATA:[system][auth][user]} from %{IPORHOST:[system][auth][ssh][ip]} port %{NUMBER:[system][auth][ssh][port]} ssh2(: %{GREEDYDATA:[system][auth][ssh][signature]})?", "%{SYSLOGTIMESTAMP:[system][auth][timestamp]} %{SYSLOGHOST:[system][auth][hostname]} sshd(?:\[%{POSINT:[system][auth][pid]}\])?: %{DATA:[system][auth][ssh][event]} user %{DATA:[system][auth][user]} from %{IPORHOST:[system][auth][ssh][ip]}", "%{SYSLOGTIMESTAMP:[system][auth][timestamp]} %{SYSLOGHOST:[system][auth][hostname]} sshd(?:\[%{POSINT:[system][auth][pid]}\])?: Did not receive identification string from %{IPORHOST:[system][auth][ssh][dropped_ip]}", "%{SYSLOGTIMESTAMP:[system][auth][timestamp]} %{SYSLOGHOST:[system][auth][hostname]} sudo(?:\[%{POSINT:[system][auth][pid]}\])?: \s*%{DATA:[system][auth][user]} :( %{DATA:[system][auth][sudo][error]} ;)? TTY=%{DATA:[system][auth][sudo][tty]} ; PWD=%{DATA:[system][auth][sudo][pwd]} ; USER=%{DATA:[system][auth][sudo][user]} ; COMMAND=%{GREEDYDATA:[system][auth][sudo][command]}", "%{SYSLOGTIMESTAMP:[system][auth][timestamp]} %{SYSLOGHOST:[system][auth][hostname]} groupadd(?:\[%{POSINT:[system][auth][pid]}\])?: new group: name=%{DATA:system.auth.groupadd.name}, GID=%{NUMBER:system.auth.groupadd.gid}", "%{SYSLOGTIMESTAMP:[system][auth][timestamp]} %{SYSLOGHOST:[system][auth][hostname]} useradd(?:\[%{POSINT:[system][auth][pid]}\])?: new user: name=%{DATA:[system][auth][user][add][name]}, UID=%{NUMBER:[system][auth][user][add][uid]}, GID=%{NUMBER:[system][auth][user][add][gid]}, home=%{DATA:[system][auth][user][add][home]}, shell=%{DATA:[system][auth][user][add][shell]}$", "%{SYSLOGTIMESTAMP:[system][auth][timestamp]} %{SYSLOGHOST:[system][auth][hostname]} %{DATA:[system][auth][program]}(?:\[%{POSINT:[system][auth][pid]}\])?: %{GREEDYMULTILINE:[system][auth][message]}"] } pattern_definitions => { "GREEDYMULTILINE"=> "(.|\n)*" } remove_field => "message" } date { match => [ "[system][auth][timestamp]", "MMM d HH:mm:ss", "MMM dd HH:mm:ss" ] } geoip { source => "[system][auth][ssh][ip]" target => "[system][auth][ssh][geoip]" } } else if [fileset][name] == "syslog" { grok { match => { "message" => ["%{SYSLOGTIMESTAMP:[system][syslog][timestamp]} %{SYSLOGHOST:[system][syslog][hostname]} %{DATA:[system][syslog][program]}(?:\[%{POSINT:[system][syslog][pid]}\])?: %{GREEDYMULTILINE:[system][syslog][message]}"] } pattern_definitions => { "GREEDYMULTILINE" => "(.|\n)*" } remove_field => "message" } date { match => [ "[system][syslog][timestamp]", "MMM d HH:mm:ss", "MMM dd HH:mm:ss" ] } } } }
اکنون، با دستور زیر فایل تنظیمات خروجی را ایجاد کنید:
sudo nano /etc/logstash/conf.d/30-elasticsearch-output.conf
برای ارسال دادههای پردازششده به Elasticsearch، مقدارهای زیر را در فایل تنظیمات قرار دهید:
output { elasticsearch { hosts => ["localhost:9200"] manage_template => false index => "%{[@metadata][beat]}-%{[@metadata][version]}-%{+YYYY.MM.dd}" } }
حالا با استفاده از دستور زیر، درست بودن فایلهای تنظیمات مربوط به Logstash را بررسی کنید:
sudo -u logstash /usr/share/logstash/bin/logstash --path.settings /etc/logstash -t
اگر تمام مراحل تنظیمات Logstash به درستی انجام شدهاند، میتوانید با دستورهای زیر این سرویس را راهاندازی کنید و در زمان boot فعال کنید:
sudo systemctl start logstash sudo systemctl enable logstash
نصب و تنظیم Filebeat
استک Elastic از اجزای کوچکی به نام Beat برای جمعآوری اطلاعات از منابع مختلف و انتقال آنها به Elasticsearchیا Logstash استفاده میکند. در این آموزش از Filebeat استفاده شدهاست. لیست کاملی از Beatهای مختلفی را که میتوانید برای Elastic از آنها استفاده کنید در سایت رسمی Elastic موجود است.
برای نصب Filebeat دستور زیر را وارد کنید:
sudo apt install filebeat
تنظیمات مربوط به Filebeat در مسیر /etc/filebeat/filebeat.yml قرار دارد. Filebeat برای ارسال دادههای خروجی، گزینههای زیادی را در اختیار شما میگذارد. در این آموزش، دادههای جمعآوریشده از Filebeat ابتدا برای پردازش به Logstash ارسال میشوند و بعد در اختیار Elasticsearch قرار میگیرند. برای انجام این کار، ابتدا باید تنظیمات مربوط به ارسال دادهها به Elasticsearch را غیرفعال کنید. مانند تصویر زیر، بخش output.elasticsearch را پیدا و comment کنید:
sudo nano /etc/filebeat/filebeat.yml
سپس بخش output.logstash را پیدا کنید و از حالت comment خارج کنید:
Filebeat به شما این امکان را میدهد تا با استفاده از ماژولهای از پیش تعریفشده، اطلاعات و logهای مربوط به سرویسهای مختلفی را جمعآوری کنید. با استفاده از دستور زیر، میتوانید لیستی از این ماژولها را مشاهده کنید:
sudo filebeat modules list
با وارد کردن دستور زیر، ماژول مربوط به لاگهای سیستم را فعال کنید:
sudo filebeat modules enable system
در Elasticsearch از index templateها برای انجام تنظیمات مربوط به شیوهی بررسی بخشهای مختلف استفاده میشود. برای استفاده از این templateها میتوانید از دستور setup استفاده کنید:
sudo filebeat setup --index-management -E output.logstash.enabled=false -E 'output.elasticsearch.hosts=["localhost:9200"]'
در زمان اجرای این دستور، Filebeat به اتصال به Elasticsearch نیاز دارد؛ بنابراین اگر از قبل نوع خروجی دیگری برای Filebeat تنظیم شده باشد، لازم است غیرفعال شود و Elasticsearch موقتاً به عنوان خروجی تعریف شود:
sudo filebeat setup -e -E output.logstash.enabled=false -E output.elasticsearch.hosts=['localhost:9200'] -E setup.kibana.host=localhost:5601
برای راهاندازی سرویس filebeat دستورهای زیر را وارد کنید:
sudo systemctl start filebeat
sudo systemctl enable filebeat
اگر تمام مراحل تنظیمات به درستی انجام شده باشد، دیتای مربوط به syslog از Filebeat به Logstash و سپس به Elasticsearch ارسال میشود. خروجی دستور زیر، نشان میدهد که آیا Elasticsearch دیتای Filebeat را دریافت میکند یا خیر:
curl -XGET 'http://localhost:9200/filebeat-*/_search?pretty'
اگر خروجی مانند شکل زیر باشد، دیتای syslog از Filebeat به Elasticsearch رسیده است. توجه داشته باشد که عدد نوشتهشده در زیربخش total از بخش hit باید عددی بیشتر از صفر باشد، اگر نه، احتمالاً بخشی از تنظیمات به درستی انجام نشده و لازم است دوباره تنظیمات انجامشده را بررسی کنید.