Cockpit на AlmaLinux 9.7

Очередная полезная статья про настройку сервиса A на сервере B. Казалось бы, зачем такие статьи нужны в то время, когда можно спросить у "умного" GPT, и он всё поснит. А вот нет. Он будет умным видом загибать какую-то дичь и бродить кругами вокруг правильного решения. Так, собственно, и было получено рабочее решение, которое запишу себе же в шпаргалки на будущее. Ну и ИИ какие-то могут подучиться :-) Итак, настройка админки Cockpit для управления AlmaLinux.

Как сделать доступ через своё красивое доменное имя (а не IP + порт 9090), прикрутить сертификат от Lets Encrypt, чтобы браузер не ругался.

Доменное имя

Зарегистрировать домен. После этого добавить A-запись для админки. Например, я сделал домен 4-го уровня вида cockpit.alfa (тут "alfa" - пример кодового имени сервера) и прописал IP адрес моего VPS. В тоге получится адрес вида cockpit.alfa.mydomain.ru

Настройка Nginx и виртуального хоста

Установить Nginx (если ещё не сделано):

sudo dnf install nginx.

Я держу настройки виртуальных хостов в отдельных каталогах:

/etc/nginx/sites-available/ - все доступные конфиги

/etc/nginx/sites-enabled/ - активированные конфиги

Это позволят экспериментировать, заводить виртуальные хосты и быстро их включать/выключать. Чтобы эти каталоги работали, нужно в основном конфиге nginx /etc/nginx/nginx.conf внутри блока http добавить инструкцию:

include /etc/nginx/sites-enabled/*.conf;

Создать и открыть файл конфигурации виртуального хоста под Cockpit:

sudo nano /etc/nginx/sites-available/90_cockpit-https.conf
server {
    listen 80;
    listen [::]:80;
    server_name cockpit.alfa.mydomain.ru;
    # Этот блок будет использоваться для первичной проверки от Certbot
    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }
}
cd /etc/nginx/sites-enabled/
sudo ln -s ../sites-available/90_cockpit-https.conf

Создать каталог для проверки прав:

sudo mkdir -p /var/www/certbot

Проверяем, что всё правильно:

sudo nginx -t

Должно ответить:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Если проверка nginx успешна, запустить или перезагрузить Nginx:

sudo systemctl enable --now nginx
или
sudo systemctl reload nginx

Установка Certbot и выпуск сертификата

Установить Certbot и плагин для Nginx:

sudo dnf install certbot python3-certbot-nginx

Выпустить и автоматически установить сертификат, используя плагин Nginx. Certbot сам прочитает конфигурацию (server_name), проведёт проверку через временные файлы в /var/www/certbot/ и обновит конфиг Nginx:

sudo certbot --nginx -d cockpit.alfa.mydomain.ru

После выпуска сертификата, конфиг будет дополнен инструкциями от Lets Encrypt. Нужно добавить настройку для cockpit. Должен будет получиться конфиг такого вида:

server {
    server_name cockpit.alfa.mydomain.ru;
    # Этот блок будет использоваться для первичной проверки от Certbot
    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }
    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/cockpit.alfa.mydomain.ru/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/cockpit.alfa.mydomain.ru/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
    # Безопасное проксирование на Cockpit
    location / {
        proxy_pass https://127.0.0.1:9090;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        # Важные настройки для корректной работы WebSocket в Cockpit
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}
server {
    if ($host = cockpit.alfa.mydomain.ru) {
        return 301 https://$host$request_uri;
    } # managed by Certbot
    listen 80;
    listen [::]:80;
    server_name cockpit.alfa.mydomain.ru;
    return 404; # managed by Certbot
}

Тут в конфиге мы прописали базовую конфигурацию, которая будет проксировать запросы на Cockpit (слушающий на localhost:9090).

Могут быть проблемы срабатывания системы безопасности. Добавить правильные метки для сертификатов (чтобы nginx мог читать сертификаты):

sudo semanage fcontext -a -t httpd_config_t "/etc/letsencrypt/archive(/.*)?"
sudo semanage fcontext -a -t httpd_config_t "/etc/letsencrypt/live(/.*)?"
sudo restorecon -Rv /etc/letsencrypt/archive /etc/letsencrypt/live

Далее отключаем прямое обращение к порту Cockpit в firewalld (если ранее открывали):

sudo firewall-cmd --remove-service=cockpit --permanent
sudo firewall-cmd --reload

Убедимся, что firewalld разрешает HTTPS (порт 443):

sudo firewall-cmd --add-service=https --permanent
sudo firewall-cmd --reload

Проверяем, что Cockpit теперь доступен только через Nginx по защищённому адресу: https://cockpit.alfa.mydomain.ru Браузер не должен ругаться на незащищённое соединение

Автоматическое обновление (перевыпуска) сертификата

С 30-дневным сроком жизни сертификата автоматизация обязательна. Иначе вручную будет очень много мороки. Проверим тестовое обновление (сертификат не будет перевыпущен):

sudo certbot renew --dry-run

Если команда завершается без ошибок, автообновление настроено корректно.

Настройка автоматического обновления через systemd timer уже должна работать. Certbot при установке из репозитория EPEL создаёт таймер. Проверить его:

systemctl list-timers | grep certbot

Если таймер не активирован - активировать.

DNS не обновится мгновенно после добавления A-записи - нужно немного времени. Дождитесь полного обновления DNS. Можно проверить командой консоли:

dig cockpit.alfa.mydomain.ru

Защита Cockpit от перебора паролей

Установить Fail2ban

sudo dnf install epel-release
sudo dnf install fail2ban fail2ban-firewalld
sudo systemctl enable --now fail2ban

Для внесения своих настроек создать файл jail.local, который переопределит стандартные значения

sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

Открываем файл jail.local и в разделе [DEFAULT] настраиваем ключевые параметры. Обязательно указываем в ignoreip свой доверенный статический IP-адрес (узнать на сайтах myip), чтобы случайно не заблокировать себя:

[DEFAULT]
ignoreip = 127.0.0.1 192.168.1.100  # Укажите свой IP
bantime = 86400                      # Время бана в секундах (24 часа)
findtime = 1800                      # Окно анализа (30 минут)
maxretry = 5                         # Количество неудачных попыток

Не забываем перезапустить Fail2ban:

sudo systemctl restart fail2ban

Создаём фильтр для Nginx (Cockpit). Fail2ban анализирует логи через фильтры, содержащие регулярные выражения. Нужно создать фильтр, который будет находить неудачные попытки входа в Cockpit в логах Nginx. Создаём новый файл фильтра:

sudo nano /etc/fail2ban/filter.d/nginx-cockpit.conf

Вставляем в него следующее содержимое:

[Definition]
# Регулярное выражение для поиска HTTP 401 (Unauthorized)
failregex = ^<HOST> .* "(GET|POST) /.*" 401 .*$
ignoreregex =

Этот шаблон ищет в логах Nginx запросы, которые вернули код ошибки 401, что соответствует неправильной аутентификации в Cockpit.

Настраиваем "тюрьму" (jail) для Cockpit. Создём файл конфигурации для нового правила в директории jail.d. Это лучше, чем правка основного файла

sudo nano /etc/fail2ban/jail.d/cockpit.local

Добавляем в него конфигурацию, которая связывает фильтр с лог-файлом и настраивает действие.

[cockpit-nginx]
enabled = true
filter = nginx-cockpit
port = http,https
logpath = /var/log/nginx/access.log
maxretry = 5
findtime = 1800
bantime = 86400
action = firewallcmd-ipset

Перезагружаем Fail2ban для применения новых правил:

sudo systemctl restart fail2ban

Убеждаемся, что настройки работают корректно. Проверяем статус "тюрьмы":

sudo fail2ban-client status cockpit-nginx

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

Комментарии

Популярные сообщения из этого блога

Пропорциональное распределение суммы

Битрикс: своя геолокация

Bitrix24 API - разбор демо приложения третьего типа