Всем привет! В этой статье мы хотим поделиться нашим опытом использования полезной платформы Graylog, которая ежедневно помогает собирать, надежно хранить и анализировать логи с десятков серверов, окутанных заботой нашей поддержки :)

Это первая часть статьи, в которой мы собрали в одном месте информацию, которая поможет установить и настроить Graylog, плюс, расскажем почему мы остановились имено на этой платформе.

Вторая часть, которая появится совсем скоро, будет содержать примеры использования и их реализацию.

Какую задачу мы решали?

Можно долго рассуждать о важности серверных логов и привести много примеров ситуаций, в которых они жизненно необходимы, но так как речь пойдет именно о сторонней системе и ее особенностях, то выделим ряд важных моментов:

  • Удобно, когда все логи хранятся в одном месте.

  • Круто, когда есть отчеты и возможность автоматически их проанализировать.

  • Полезно, когда логи можно посмотреть даже при “упавшем” сервере или после того как злоумышленник “прибрался” за собой.

  • Бесценно, когда о возникшей ошибке в логах будет оповещение.

Сформулировали задачу так: 

“Подобрать бесплатное open source решение для сбора и анализа логов, не перегруженное функционалом, производительное, простое в установке и использовании.”


Почему Graylog?

Это не единственная и, возможно, далеко не самая лучшая платформа, но она широко распространена, прошла проверку временем и все еще поддерживается разработчиками.

Но, начать мы решили с анализа “конкурентов”.

Альтернативы

Splunk

Классный, модный, современный Splunk соответствует подавляющему большинству потребностей и скорее всего, может даже больше.

Но есть три момента, которые не понравились:

  • В нужной конфигурации решение платное.

  • Это закрытое решение.

  • Компания, без объяснений причин покинула рынок РФ.

Но, если вас это не смущает, немного полезной информации по платформе:

С этим “претендентом” не получилось, идем дальше.

Например, тут и тут его часто сравнивают с ELK, который и рассмотрим.

ELK

Стек продуктов Elasticsearch, Logstash, Kibana, образующий аббревиатуру ELK - это очень популярное и еще более настраиваемое решение, по сравнению с предыдущим. Более того, это решение open source.

Что же пошло не так?

  • Некоторые фишки все же платные, например, уведомления и контроль доступа (однако, после некоторых событий часть данного функционала стала бесплатной). 

  • Ресурсоемкость - требуется очень много ресурсов.

  • Систему сложно настроить, “из коробки” она работать не будет.

  • Еще нужно упомянуть Open Distro, которая развивается на базе ELK, но полностью бесплатная, что не отменяет ресурсоемкость и сложность в настройке.

Немного полезной информации:

Остановились на Graylog

Двух претендентов отсеяли, остался виновник торжества - Graylog, выделяющийся по следующим причинам:

  • Это open source решение.

  • Бесплатная версия имеет все необходимое.

  • Функционал небольшой, что удобно, ничего лишнего (для наших задач).

  • “Из коробки” решение уже работает, нужны минимальные настройки.

  • По сравнению с ELK ресурсоемкость значительно ниже.

Далее, мы предлагаем лонгрид по настройке и установке Graylog.


Установка и базовые настройки Graylog

Все адреса, логины, пароли, явки - вымышленные, ничего общего с реальностью не имеют.

Установка - обычный процесс, описанный почти везде. Нам потребуется виртуальный сервер с CentOS и компонентами ElasticSearch, ModgoDB, Graylog4, но тем не менее, засады нас там ждут.

В примере используем CentOS 8.

Prerequisites 

Хорошая привычка - проверить правильность настройки таймзоны и имени.

# timedatectl
# hostnamectl

Если что-то не так - устанавливаем так как нужно, например:

# timedatectl set-timezone Europe/Moscow
# hostnamectl set-hostname graylog.itsft.ru

Обновления обязательны, также установим пакеты для удобства работы, top-ы, etc.

# dnf upgrade --refresh
# dnf install epel-release
# dnf update epel-release
# dnf -y install nc mc vim atop iftop htop mytop iotop pciutils dos2unix tar lbzip2 zip unzip bash-completion python36 tmux screen telnet wget fail2ban cockpit pwgen

Cockpit - веб-интерфейс управления сервером 

(опционально)

# systemctl enable --now cockpit.socket
# systemctl start cockpit
проверяем
# systemctl status cockpit
? cockpit.service - Cockpit Web Service
   Loaded: loaded (/usr/lib/systemd/system/cockpit.service; static; vendor preset: disabled)
   Active: active (running) since Tue 2021-04-27 12:18:42 MSK; 4s ago

Установим SSL-сертификат

смотрим где лежат сертификаты (пока самоподписанные)

# remotectl certificate
certificate: /etc/cockpit/ws-certs.d/0-self-signed.cert

кладём crt и key файлы в /etc/cockpit/ws-certs.d/

кокпит сам найдёт файлы с сертификатами (2 файла - серт + ключ, или в одном)

# systemctl restart cockpit
# remotectl certificate
certificate: /etc/cockpit/ws-certs.d/itsoft.crt

Firewall  

(настройки будут индивидуальными для вашей сети, все команды даны для примера)

Если не используем ipv6 - лучше отключить:

# firewall-cmd --remove-service=dhcpv6-client

Кокпит должен быть доступен только админам, снаружи ему делать нечего. Создадим зону для интранета и добавим нужные адреса подсетей:

# firewall-cmd --permanent --new-zone=itsoft
# firewall-cmd --permanent --zone=itsoft --add-source=100.200.200.0/24

Порты (9000 - временно, для веб-интерфейса graylog, 10514 и 5044 для данных):

# firewall-cmd --permanent --zone=itsoft --add-port=9000/tcp
# firewall-cmd --permanent --zone=itsoft --add-port=10514/tcp
# firewall-cmd --permanent --zone=itsoft --add-port=10514/udp
# firewall-cmd --permanent --zone=itsoft --add-port=5044/tcp

Необходимые сервисы:

# firewall-cmd --permanent --zone=itsoft --add-service=https
# firewall-cmd --permanent --zone=itsoft --add-service=http
# firewall-cmd --permanent --zone=itsoft --add-service=cockpit

После добавления/удаления перезагрузим сервис:

# firewall-cmd --reload

Проконтролируем, что все правила верные:

# firewall-cmd --list-all --zone=public
# firewall-cmd --list-all --zone=itsoft

Проверяем - идём браузером на

https://graylog.itsft.ru:9090

SELinux  

(настраиваем, а не отключаем его!!!)

Устанавливаем пакеты, если ещё не установлены, разрешаем апачу подключения:

# dnf -y install policycoreutils policycoreutils-python-utils policycoreutils-python-utils
# setsebool -P httpd_can_network_connect 1

Проверяем порты 9000, 9200, 27017:

# semanage port -l | egrep '\s(9000|9200|27017)'
http_port_t                    tcp      80, 81, 443, 488, 8008, 8009, 8443, 9000
mongod_port_t                  tcp      27017-27019, 28017-28019
wap_wsp_port_t                 tcp      9200
wap_wsp_port_t                 udp      9200

Небольшая проблема, если попытаемся добавить тип для порта 9200, получим ошибку - порт уже определён:

# semanage port -a -t http_port_t -p tcp 9200
ValueError: Port tcp/9200 already defined

Модифицируем запись - добавится локальная и у неё приоритет будет выше, чем у глобальной, но отображаться будут обе:

# semanage port -m -t http_port_t -p tcp 9200
# semanage port -l | egrep '\s(9000|9200|27017)'
http_port_t          tcp      9200, 80, 81, 443, 488, 8008, 8009, 8443, 9000
mongod_port_t        tcp      27017-27019, 28017-28019
wap_wsp_port_t       tcp      9200
wap_wsp_port_t       udp      9200

Java

# dnf -y install java-1.8.0-openjdk java-1.8.0-openjdk-devel

Тест:

# java -version
openjdk version "1.8.0_292"
OpenJDK Runtime Environment (build 1.8.0_292-b10)
OpenJDK 64-Bit Server VM (build 25.292-b10, mixed mode)

Elastic Search

Импортируем ключ репозитория, добавляем конфигурационный файл репозитория,  устанавливаем (вместо vim можно использовать nano, mcedit или любой другой редактор по вашему выбору):

# rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch
# vim /etc/yum.repos.d/elasticsearch.repo

[elasticsearch-6.x]
name=Elasticsearch repository for 6.x packages
baseurl=https://artifacts.elastic.co/packages/oss-6.x/yum
gpgcheck=1
gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
enabled=1
autorefresh=1
type=rpm-md
# dnf clean all
# dnf makecache


# dnf -y install elasticsearch-oss
. . .
Installed:
  elasticsearch-oss-6.8.15-1.noarch

Чтобы Elasticsearch работал с Graylog, необходимо установим имя кластера “graylog”:

# vim /etc/elasticsearch/elasticsearch.yml

В секции --- Cluster --- меняем параметр:

cluster.name: graylog

В секции --- Various --- добавляем последней строкой:

action.auto_create_index: false

Запускаем:

# systemctl daemon-reload
# systemctl enable --now elasticsearch
Synchronizing state of elasticsearch.service with SysV service script with /usr/lib/systemd/systemd-sysv-install.
Executing: /usr/lib/systemd/systemd-sysv-install enable elasticsearch
Created symlink /etc/systemd/system/multi-user.target.wants/elasticsearch.service > /usr/lib/systemd/system/elasticsearch.service.

Проверяем:

# systemctl status elasticsearch
? elasticsearch.service - Elasticsearch
   Loaded: loaded (/usr/lib/systemd/system/elasticsearch.service; enabled; vendor preset: disabled)
   Active: active (running) since Tue 2021-04-27 12:51:50 MSK; 17s ago

Запускается довольно долго, в зависимости от конфигурации сервера или виртуальной машины. Проверяем:

# ss -ntlp | grep java
LISTEN   0        128         [::ffff:127.0.0.1]:9200                  *:*       users:(("java",pid=61586,fd=166))
LISTEN   0        128                      [::1]:9200               [::]:*       users:(("java",pid=61586,fd=165))
LISTEN   0        128         [::ffff:127.0.0.1]:9300                  *:*       users:(("java",pid=61586,fd=139))
LISTEN   0        128                      [::1]:9300               [::]:*       users:(("java",pid=61586,fd=137))
Файлы Elasticsearch расположены здесь:
Configuration:    /etc/elasticsearch
JVM settings:     /etc/default/elasticsearch
Data files:       /var/lib/elasticsearch/data
Log files:        /var/log/elasticsearch/

Проверяем:

# curl -X GET http://localhost:9200
{
  "name" : "M_ysIuG",
  "cluster_name" : "graylog",
  "cluster_uuid" : "CzqgacNrQ5SfByXz85v0wg",
  ...

# curl -XGET 'http://localhost:9200/_cluster/health?pretty=true'
{
  "cluster_name" : "graylog",
  "status" : "green",
  ...

MongoDB

Добавляем конфигурационный файл репозитория:

# vim /etc/yum.repos.d/mongodb-org-4.4.repo

[mongodb-org-4.4]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/4.4/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-4.4.asc

# dnf -y install mongodb-org
# systemctl enable --now mongod

Проверяем:

# systemctl status mongod.service
? mongod.service - MongoDB Database Server
   Loaded: loaded (/usr/lib/systemd/system/mongod.service; enabled; vendor preset: disabled)
   Active: active (running) since Tue 2021-04-27 12:59:36 MSK; 5s ago
Файлы MongoDB расположены здесь:
Configuration  /etc/mongod.conf
Data files     /var/lib/mongodb/
Log files      /var/log/mongodb/

Graylog

Ссылки на оригинальную документацию:

RPM / YUM / DNF

CentOS installation

# dnf -y install https://packages.graylog2.org/repo/packages/graylog-4.0-repository_latest.rpm

# dnf -y install graylog-server graylog-enterprise-plugins graylog-integrations-plugins graylog-enterprise-integrations-plugins

Graylog не запускается самостоятельно (об этом есть сообщение в процессе установки).

Сначала настраиваем, потом пробуем запускать.

Генерируем хеш пароля:

# pwgen -N 1 -s 96
XzN25fRfHv7NGbVODAGDcRWhzd6QAQQa11RXLIVgSXCgaDZexaxE4VlLA1abmEQjN25BlRVyEp3LNhN6HcJL8GYjV3RQgwkA

# echo -n MyPassword123 | sha256sum
bc7b8851671f2fda237a53f5057a0376037b6d062e65f965c62aa1d047498759  -

# pwgen -N 1 -s 96
g3SpB…...5x7U

# echo -n YourPassword | sha256sum
7b2f50…..b28d0  -

# vim /etc/graylog/server/server.conf

is_master = true
password_secret = XzN25fRfHv7NEQ...8GYjV3RQgwkA
root_username = admin
root_password_sha2 = bc7b88516...1d047498759
root_email = “admin@itsft.ru”
root_timezone = Europe/Moscow

Параметры эластика только для первого запуска, дальше конфигурация будет производиться уже из веб-интерфейса грейлога:

rotation_strategy = count
elasticsearch_max_docs_per_index = 20000000
elasticsearch_max_number_of_indices = 20        
elasticsearch_shards = 1
elasticsearch_replicas = 0

http_bind_address = 0.0.0.0:9000
http_publish_uri = https://graylog.itsft.ru9000/

Также полезно будет настроить Email transport:

transport_email_enabled = true
transport_email_protocol = smtp
transport_email_hostname = mail.itsft.ru
transport_email_port = 25
transport_email_use_auth = true
transport_email_use_tls = false
transport_email_use_ssl = false
transport_email_auth_username = graylog@itsft.ru
transport_email_auth_password = YourMailPassword
transport_email_subject_prefix = [graylog4]
transport_email_from_email = graylog@itsft.ru
transport_email_from_name = Graylog4

Регистрируемся и заходим в панель:

https://www.maxmind.com/en/account/login

Download files  >  В секции GeoLite2 City  >  Get Permalinks (1, 2)

# Database URL

https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-City&license_key=YOUR_LICENSE_KEY&suffix=tar.gz

# SHA256 URL

https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-City&license_key=YOUR_LICENSE_KEY&suffix=tar.gz.sha256
Как выглядит:

В Services  > Manage License Keys (3)

Нажимаем "Generate new license key" создастся новый License Key. На email придёт уведомление о создании ключа.

Лицензия активируется в течение 5 минут.

Подставляем в ссылки, полученные на первом шаге ключ, полученный на втором шаге, загружаем файл с базой и файл контрольной суммы:

# wget --content-disposition 'https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-City&license_key=xxxxxxxxxx&suffix=tar.gz'
# wget --content-disposition 'https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-City&license_key=xxxxxxxxxx&suffix=tar.gz.sha256'

Проверяем целостность архива:

# sha256sum -c GeoLite2-City_20210427.tar.gz.sha256
GeoLite2-City_20210427.tar.gz: OK

Устанавливаем:

# tar zxfv GeoLite2-City_20210427.tar.gz
# mv GeoLite2-City_20210427/GeoLite2-City.mmdb /etc/graylog/server/

Установка GeoLite2 Database выполнена.

Запускаем Graylog:

# systemctl daemon-reload
# systemctl enable --now graylog-server.service

Немного ждём, затем смотрим логи запуска:

# tail /var/log/graylog-server/server.log
...
2021-04-27T15:44:36.005+03:00 INFO  [ServerBootstrap] Graylog server up and running.
Если видим ошибки:
ERROR [AuditLogger] Unable to write audit log entry because there is no valid license.

это нормально.

Возникают из-за того что установлена версия Enterprise, но нет соответствующей лицензии.

Заходим браузером, проверяем что веб-интерфейс доступен, можем залогиниться в веб-интерфейс:

https://graylog.itsft.ru:9000

user: admin

pass: MyPassword123

Нас встречает мини-учебник по настройке:

NGINX

# vim /etc/yum.repos.d/nginx.repo

[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true

[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true

# dnf config-manager --enable nginx-mainline
# dnf -y install nginx
Installed:
  nginx-1:1.20.0-1.el8.ngx.x86_64

Создаём конфиг nginx, размещаем файлы сертификатов в /etc/nginx/ssl (у нас будут в одном файле сертификат + ключ):

# vim /etc/nginx/conf.d/graylog.conf

server
{
  listen 80 default_server;
  server_name graylog.itsft.ru;

  return 301 https://$host$request_uri;
}
server
{
  listen      443 ssl http2;
  server_name graylog.itsft.ru;

  access_log  /var/log/nginx/graylog_access.log;
  error_log   /var/log/nginx/graylog_error.log;

  ssl_certificate     /etc/nginx/ssl/star_itsft.crt;
  ssl_certificate_key /etc/nginx/ssl/star_itsft.crt;
  ssl_session_timeout 1d;
  ssl_session_cache   shared:MozSSL:10m;  # about 40000 sessions
  ssl_session_tickets off;

  # Supports Firefox 27, Android 4.4.2, Chrome 31, Edge, IE 11 on Windows 7,
  # Java 8u31, OpenSSL 1.0.1, Opera 20, and Safari 9 and above
  ssl_protocols TLSv1.2 TLSv1.3;
  ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
  ssl_prefer_server_ciphers off;
 
  # HSTS (ngx_http_headers_module is required) (63072000 seconds)
  add_header Strict-Transport-Security "max-age=63072000" always;
 
  # OCSP stapling
  ssl_stapling on;
  ssl_stapling_verify on;

  location /
  {
    proxy_set_header Host $http_host;
    proxy_set_header X-Forwarded-Host $host;
    proxy_set_header X-Forwarded-Server $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Graylog-Server-URL https://$server_name/;
    proxy_pass       http://127.0.0.1:9000;
  }
}


# systemctl enable nginx
# systemctl start nginx
# systemctl status nginx
? nginx.service - nginx - high performance web server
   Loaded: loaded (/usr/lib/systemd/system/nginx.service; disabled; vendor preset: disabled)
   Active: active (running) since Tue 2021-04-27 17:12:52 MSK; 6s ago
Если получили ошибку:
Oct 11 10:00:00 itsft.ru systemd[1]: Starting nginx - high performance web server...
Oct 11 10:00:00 itsft.ru nginx[315253]: nginx: [emerg] open() "/var/run/nginx.pid" failed (13: Permission denied)
Oct 11 10:00:00 itsft.ru systemd[1]: nginx.service: Failed to parse PID from file /var/run/nginx.pid: Invalid argument
Oct 11 10:00:00 itsft.ru systemd[1]: nginx.service: Failed with result 'protocol'.
Oct 11 10:00:00 itsft.ru systemd[1]: Failed to start nginx - high performance web server.

То это из-за SELinux. Исправляем:

# systemctl stop nginx
# touch /var/run/nginx.pid
# chcon -u system_u -t httpd_var_run_t nginx.pid
# systemctl start nginx

Контролируем:

# ll -Z nginx.pid
-rw-r--r--. 1 root root system_u:object_r:httpd_var_run_t:s0 7 Oct 15 16:08 nginx.pid
# firewall-cmd --permanent --zone=itsoft --remove-port=9000/tcp
# firewall-cmd --reload

Немного реконфигурим Graylog:

# vim /etc/graylog/server/server.conf

http_bind_address = 127.0.0.1:9000
http_publish_uri = https://graylog.itsft.ru/

# systemctl restart graylog-server.service

Теперь Graylog слушает только на локалхосте, если открывали порт 9000, то необходимости в нём больше нет:

# firewall-cmd --permanent --zone=itsoft --remove-port=9000/tcp
# firewall-cmd --reload

Размер БД

Установим размер индекса, так как виртуальный сервер имеет ограниченный объём диска.

System  >  Indices  >  Default index set  >  Edit

В Index Rotation Configuration:

Select rotation strategy - Index Size

Max size per index - 4294965097   (4GiB)

В Index Retention Configuration:

Select retention strategy - Delete Index

Max number of indices - 8

Итого общий размер индексов будет не более 32GiB


Подведем итоги

Если вы дочитали и все еще с нами, то на этом закончим первую часть, где мы разобрали чем нам приглянулся Graylog и как можно его установить / настроить.

Надеемся, что наш опыт будет вам полезен.

Вопросы в комментариях приветствуются :)

Во второй части мы расскажем, как используя Graylog можно собирать системные логи и логи веб-сервера. 


Дата-центр ITSOFT — размещение и аренда серверов и стоек в двух дата-центрах в Москве. За последние годы UPTIME 100%. Размещение GPU-ферм и ASIC-майнеров, аренда GPU-серверов, лицензии связи, SSL-сертификаты, администрирование серверов и поддержка сайтов.