Как установить GitLab CE на AlmaLinux 10

Un espacio de oficina futurista con desarrolladores colaborando sobre GitLab CE.

Полное руководство по установке, публикации через NAT и комплексной защите от злоумышленников.

Содержание
  1. Что нового в AlmaLinux 10: ключевые отличия от версии 9
  2. Сводная таблица изменений
  3. Важные изменения для администратора
  4. Требования к системе
  5. Аппаратные требования
  6. Сетевые требования
  7. Подготовка AlmaLinux 10
  8. Первичное обновление и репозитории
  9. Обновление системы
  10. Подключение репозиториев
  11. Установка всех необходимых пакетов
  12. Включение сервисов
  13. Настройка SELinux
  14. Имя хоста, время и системный пользователь
  15. Автоматические обновления безопасности
  16. Установка GitLab CE
  17. Добавление официального репозитория
  18. Установка GitLab CE
  19. Базовая конфигурация /etc/gitlab/gitlab.rb
  20. Настройка NAT и публикация в интернете
  21. Схема перенаправления портов
  22. Настройка Port Forwarding на маршрутизаторе
  23. Пример конфигурации MikroTik (RouterOS)
  24. Статический IP на сервере
  25. SSL/TLS: Let’s Encrypt и усиленная конфигурация
  26. Проверка и обновление сертификата
  27. Постквантовая криптография AlmaLinux 10
  28. Безопасность GitLab: конфигурация приложения
  29. Отключение публичной регистрации
  30. Rate Limiting (защита от брутфорса на уровне приложения)
  31. Таблица настроек Admin Area
  32. Ограничение Admin Area по IP (Nginx)
  33. SELinux, Firewalld, Auditd
  34. Настройка Firewalld
  35. Auditd — правила аудита для GitLab
  36. AIDE — контроль целостности файловой системы
  37. Инициализация базы данных
  38. Автоматическая ежедневная проверка
  39. Fail2Ban — защита от брутфорса
  40. Запуск сервиса
  41. Конфигурация для GitLab и SSH
  42. Защита SSH (OpenSSH 9.9)
  43. Конфигурация /etc/ssh/sshd_config
  44. Генерация SSH-ключа ed25519
  45. WAF: ModSecurity + Nginx
  46. Установка
  47. Конфигурация ModSecurity
  48. Двухфакторная аутентификация и политики доступа
  49. Принудительная 2FA
  50. Политика паролей через gitlab.rb
  51. Управление токенами доступа
  52. Мониторинг и оповещения
  53. Ключевые лог-файлы GitLab
  54. Настройка SMTP-уведомлений
  55. Скрипт ежедневного аудита безопасности
  56. Резервное копирование
  57. Создание резервной копии
  58. Автоматические бэкапы
  59. Чек-лист безопасности
  60. Сеть и NAT
  61. Операционная система
  62. GitLab (приложение)
  63. Резервное копирование и мониторинг

Что нового в AlmaLinux 10: ключевые отличия от версии 9

AlmaLinux 10 «Purple Lion» вышел 27 мая 2025 года. Перед установкой важно понять изменения, которые непосредственно влияют на установку и эксплуатацию GitLab.

Сводная таблица изменений

КомпонентAlmaLinux 9AlmaLinux 10
КомпонентAlmaLinux 9AlmaLinux 10
Ядро Linux5.14.x6.12 (LTS)
OpenSSH8.79.9 (пост-квантовая криптография)
OpenSSL3.0.x3.5.x (FIPS, PKCS#11)
Python3.9 / 3.113.12
Node.js18 / 2022 (LTS)
Git2.39.x2.47
Nginx1.22.x1.26
SELinux userspace3.53.8 (CIL output, Wayland)
Архитектура x86x86-64-v2 (по умолчанию)x86-64-v3 (по умолч.) + v2 (доп.)
PostgreSQL (GitLab)14 (bundled)16 (bundled)
Срок поддержкидо 31 мая 2032до 31 мая 2035

Архитектура x86-64-v3

AlmaLinux 10 по умолчанию требует процессор с поддержкой инструкций AVX/AVX2/BMI (Intel Haswell 2013+ / AMD Excavator 2015+). На более старом железе используйте специальную сборку x86-64-v2. Проверьте: grep -m1 flags /proc/cpuinfo | grep -c avx2

Важные изменения для администратора

  • OpenSSH 9.9 по умолчанию включает алгоритмы постквантовой защиты (ML-KEM, sntrup761x25519). Старые клиенты SSH могут потребовать обновления.
  • Crypto-policies теперь работают с постквантовыми алгоритмами — политика DEFAULT включает их поддержку.
  • SELinux userspace 3.8: новый режим вывода CIL для audit2allow — команды для разрешения исключений изменились.
  • Пакет dnf-automatic заменён на dnf5-automatic в ряде конфигураций — проверьте наличие в репозитории.
  • EPEL 10 собирается для x86-64-v3 по умолчанию. Для v2-сборки нужна отдельная настройка репозитория.

Требования к системе

Аппаратные требования

КомпонентМинимумРекомендуется
CPU4 ядра (x86-64-v3)8+ ядер
RAM4 ГБ8–16 ГБ
Диск40 ГБ SSD200+ ГБ SSD (NVMe)
Своп2 ГБ4 ГБ
СетьСтатический IP + доменСтатический IP + домен + резерв

Совет по CPU

Проверьте совместимость с x86-64-v3 до установки ОС: grep -m1 flags /proc/cpuinfo | grep -E ‘avx2|bmi2|fma’. Если вывод пуст — используйте AlmaLinux 10 x86-64-v2 ISO.

Сетевые требования

  • Статический внешний IP-адрес или настроенный DDNS
  • Зарегистрированный домен с A-записью: gitlab.mycompany.com → внешний IP
  • Доступ к настройкам NAT/Port Forwarding на маршрутизаторе
  • Открытые порты 80 и 443 на маршрутизаторе (не заняты другими сервисами)
  • Исходящий доступ к packages.gitlab.com и storage.googleapis.com

Подготовка AlmaLinux 10

Первичное обновление и репозитории

Обновление системы

# Полное обновление сразу после установки ОС
sudo dnf clean all
sudo dnf update -y && sudo dnf upgrade -y

Подключение репозиториев

# EPEL — расширенный репозиторий (Fail2Ban, дополнительные утилиты)
# В AlmaLinux 10 EPEL собирается для x86-64-v3
sudo dnf install -y epel-release

# CRB (CodeReady Builder) — сборочные зависимости
sudo dnf config-manager --set-enabled crb

# Проверить подключённые репозитории
sudo dnf repolist
# Ожидаемый вывод: appstream, baseos, crb, epel

Установка всех необходимых пакетов

Устанавливаем все зависимости одной командой, чтобы не возвращаться к этому шагу позднее:

sudo dnf install -y \
  # ── Базовые утилиты ──────────────────────────────────────────
  curl wget nano net-tools bind-utils git \
  # ── OpenSSH ──────────────────────────────────────────────────
  openssh-server openssh-clients \
  # ── Firewall и SELinux ───────────────────────────────────────
  firewalld policycoreutils policycoreutils-python-utils \
  setools-console setroubleshoot-server \
  # ── Сертификаты и TLS ────────────────────────────────────────
  openssl ca-certificates \
  # ── Perl (зависимость GitLab omnibus) ────────────────────────
  perl perl-Digest-SHA \
  # ── Почта и планировщик ──────────────────────────────────────
  postfix mailx cronie logrotate \
  # ── Аудит и обнаружение вторжений ───────────────────────────
  audit audispd-plugins aide \
  # ── Защита от брутфорса ──────────────────────────────────────
  fail2ban fail2ban-firewalld \
  # ── Синхронизация времени ────────────────────────────────────
  chrony \
  # ── Автообновления безопасности ──────────────────────────────
  dnf-automatic

Включение сервисов

sudo systemctl enable --now sshd
sudo systemctl enable --now firewalld
sudo systemctl enable --now chronyd
sudo systemctl enable --now crond
sudo systemctl enable --now auditd
sudo systemctl enable --now postfix

# Проверка статуса всех сервисов
for svc in sshd firewalld chronyd crond auditd postfix; do
  printf '%-12s: %s\n' $svc $(systemctl is-active $svc)
done

Настройка SELinux

В AlmaLinux 10 SELinux userspace обновлён до версии 3.8. Команда audit2allow теперь поддерживает вывод в формате CIL. Режим Enforcing обязателен.

# Проверить текущий режим
getenforce
# Ожидаемый вывод: Enforcing

# Если Permissive или Disabled — включить:
sudo sed -i 's/SELINUX=.*/SELINUX=enforcing/' /etc/selinux/config
sudo setenforce 1

# Проверить итоговый статус
sestatus

# После установки GitLab — восстановить контексты файлов
# (выполнить после раздела 4):
sudo restorecon -Rv /var/opt/gitlab
sudo restorecon -Rv /etc/gitlab
sudo restorecon -Rv /var/log/gitlab

# Если появятся AVC-отказы — диагностика (синтаксис AL10):
sudo ausearch -m avc -ts recent | audit2allow -M gitlab_custom --cil
sudo semodule -i gitlab_custom.pp

Имя хоста, время и системный пользователь

# Задать FQDN
sudo hostnamectl set-hostname gitlab.mycompany.com

# Часовой пояс
sudo timedatectl set-timezone Europe/Moscow

# Проверить синхронизацию NTP (критично для SSL и логов!)
chronyc tracking
timedatectl status

# Создать администратора (не работать под root!)
sudo useradd -m -s /bin/bash gitadmin
sudo passwd gitadmin
sudo usermod -aG wheel gitadmin

# Проверить права sudo
su - gitadmin -c 'sudo whoami'   # должно вывести: root

Автоматические обновления безопасности

sudo nano /etc/dnf/automatic.conf

# Убедиться что установлены следующие значения:
# upgrade_type = security
# apply_updates = yes
# emit_via = motd

# Включить таймер
sudo systemctl enable --now dnf-automatic-install.timer
sudo systemctl status dnf-automatic-install.timer

Установка GitLab CE

Добавление официального репозитория

GitLab официально поддерживает AlmaLinux 10. Репозиторий подключается одной командой:

# Официальный скрипт репозитория GitLab Inc.
curl -fsSL https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.rpm.sh \
  | sudo bash

# Проверить, что репозиторий добавлен
sudo dnf repolist | grep gitlab
# Ожидаемый вывод: gitlab_gitlab-ce

# Посмотреть доступные версии
sudo dnf list available gitlab-ce

Особенность AlmaLinux 10

Скрипт репозитория GitLab автоматически определяет AlmaLinux 10 и использует el10-совместимые пакеты. Начиная с GitLab CE 17.x, поддержка RHEL 10 / AlmaLinux 10 является официальной.

Установка GitLab CE

# Установка с автоматическим Let's Encrypt (домен должен уже резолвиться!)
sudo EXTERNAL_URL='https://gitlab.mycompany.com' dnf install -y gitlab-ce

# Опционально: задать root-пароль прямо при установке
sudo GITLAB_ROOT_EMAIL='admin@mycompany.com' \
     GITLAB_ROOT_PASSWORD='StrongPass123!' \
     EXTERNAL_URL='https://gitlab.mycompany.com' \
     dnf install -y gitlab-ce

# Установка занимает 5–15 минут. После завершения — проверить:
sudo gitlab-ctl status

Пароль root-пользователя GitLab

Временный пароль сохранён в /etc/gitlab/initial_root_password. Файл удаляется через 24 часа. Немедленно войдите в веб-интерфейс и смените пароль: Profile → Password.

Базовая конфигурация /etc/gitlab/gitlab.rb

sudo nano /etc/gitlab/gitlab.rb

# ── Основные параметры ───────────────────────────────────────────
external_url 'https://gitlab.mycompany.com'

# ── Let's Encrypt ────────────────────────────────────────────────
letsencrypt['enable'] = true
letsencrypt['contact_emails'] = ['admin@mycompany.com']
letsencrypt['auto_renew'] = true
letsencrypt['auto_renew_hour'] = 3
letsencrypt['auto_renew_minute'] = 30

# ── TLS — только современные протоколы ───────────────────────────
nginx['redirect_http_to_https'] = true
nginx['ssl_protocols'] = 'TLSv1.2 TLSv1.3'
nginx['ssl_ciphers'] = 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384'
nginx['ssl_prefer_server_ciphers'] = 'on'

# ── Заголовки безопасности HTTP ──────────────────────────────────
nginx['custom_gitlab_server_config'] = "
  add_header Strict-Transport-Security 'max-age=63072000; includeSubDomains; preload' always;
  add_header X-Frame-Options SAMEORIGIN always;
  add_header X-Content-Type-Options nosniff always;
  add_header Referrer-Policy strict-origin-when-cross-origin always;
  add_header X-XSS-Protection '1; mode=block' always;
"

# ── GitLab SSH (нестандартный порт) ──────────────────────────────
gitlab_rails['gitlab_shell_ssh_port'] = 2222

# Применить конфигурацию
sudo gitlab-ctl reconfigure

Настройка NAT и публикация в интернете

Схема перенаправления портов

Входящие соединения из интернета маршрутизируются маршрутизатором на внутренний IP сервера GitLab:

ПортНазначениеСтатус
HTTPS (443)Клиенты — веб-интерфейс, API, git cloneОбязателен
HTTP (80)Только для редиректа на HTTPS и Let’s EncryptОбязателен
TCP (2222)Git по SSH — git push/pullРекомендуется

Настройка Port Forwarding на маршрутизаторе

Создайте следующие правила перенаправления (замените 192.168.1.100 на реальный LAN-IP сервера):

Внешний портНазначение (LAN)Комментарий
443 TCP192.168.1.100:443GitLab HTTPS
80 TCP192.168.1.100:80GitLab HTTP → редирект
2222 TCP192.168.1.100:2222GitLab SSH для git

Пример конфигурации MikroTik (RouterOS)

/ip firewall nat
add chain=dstnat action=dst-nat dst-port=443 protocol=tcp \
    to-addresses=192.168.1.100 to-ports=443 comment="GitLab HTTPS"

add chain=dstnat action=dst-nat dst-port=80 protocol=tcp \
    to-addresses=192.168.1.100 to-ports=80  comment="GitLab HTTP"

add chain=dstnat action=dst-nat dst-port=2222 protocol=tcp \
    to-addresses=192.168.1.100 to-ports=2222 comment="GitLab SSH"

Статический IP на сервере

# Посмотреть имя интерфейса
ip addr show

# Настроить статический IP через nmcli (замените ens3 на ваш интерфейс)
sudo nmcli con modify ens3 ipv4.addresses 192.168.1.100/24
sudo nmcli con modify ens3 ipv4.gateway 192.168.1.1
sudo nmcli con modify ens3 ipv4.dns '8.8.8.8 1.1.1.1'
sudo nmcli con modify ens3 ipv4.method manual
sudo nmcli con up ens3

# Проверка связи
ip addr show ens3
ping -c 4 8.8.8.8

SSL/TLS: Let’s Encrypt и усиленная конфигурация

Проверка и обновление сертификата

# Принудительный запрос/обновление сертификата
sudo gitlab-ctl renew-le-certs

# Проверить срок действия
sudo openssl s_client -connect gitlab.mycompany.com:443 \
  -servername gitlab.mycompany.com </dev/null 2>/dev/null \
  | openssl x509 -noout -dates

# Проверить качество TLS (из другой машины)
# Или используйте https://www.ssllabs.com/ssltest/
curl -vI https://gitlab.mycompany.com 2>&1 | grep -E 'SSL|TLS|cipher'

Постквантовая криптография AlmaLinux 10

AlmaLinux 10 поставляет OpenSSL 3.5.x и OpenSSH 9.9, поддерживающие постквантовые алгоритмы. Это не требует дополнительной настройки — защита работает автоматически для OpenSSH-соединений.

# Проверить поддержку постквантовых алгоритмов в OpenSSH 9.9
ssh -Q kex | grep -i ml
# Ожидаемый вывод: mlkem768x25519-sha256 (или аналог)

# Проверить версию OpenSSL
openssl version
# Ожидаемый вывод: OpenSSL 3.5.x ...

Безопасность GitLab: конфигурация приложения

Отключение публичной регистрации

# Через веб-интерфейс (рекомендуется):
# Admin Area → Settings → General → Sign-up restrictions
# → Снять галочку «Sign-up enabled» → Save changes

# Через gitlab.rb:
# gitlab_rails['gitlab_signup_enabled'] = false
# sudo gitlab-ctl reconfigure

Rate Limiting (защита от брутфорса на уровне приложения)

# /etc/gitlab/gitlab.rb
gitlab_rails['rack_attack_git_basic_auth'] = {
  'enabled'     => true,
  'ip_whitelist' => [],
  'maxretry'    => 10,
  'findtime'    => 60,
  'bantime'     => 3600
}

sudo gitlab-ctl reconfigure

Таблица настроек Admin Area

РазделПараметрЗначение
General → Sign-inTwo-factor authenticationEnforced for all
General → Sign-inPassword minimum length12+ символов
General → Sign-inSession expire (remember me)7 дней
General → VisibilityDefault project visibilityPrivate
General → VisibilityDefault snippet visibilityPrivate
Network → IP restrictionAdmin area IP restrictionIP офиса/VPN
Network → OutboundAllow local requests from web hooksОтключено
Network → Rate limitsUnauthenticated API rate limitВключено

Ограничение Admin Area по IP (Nginx)

# /etc/gitlab/gitlab.rb
# Заменить 203.0.113.10 на IP вашего офиса или VPN
nginx['custom_gitlab_server_config'] = "
  location /admin {
    allow 203.0.113.10;
    allow 10.0.0.0/8;
    deny  all;
  }
"
sudo gitlab-ctl reconfigure

SELinux, Firewalld, Auditd

Настройка Firewalld

# Установить зону по умолчанию — блокировать всё входящее
sudo firewall-cmd --set-default-zone=drop

# Разрешить только нужные сервисы
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-port=2222/tcp    # SSH (нестандартный)

# Применить
sudo firewall-cmd --reload

# Проверить активные правила
sudo firewall-cmd --list-all

Auditd — правила аудита для GitLab

В AlmaLinux 10 пакеты audit и audispd-plugins уже установлены в разделе 3. Настраиваем правила:

sudo tee /etc/audit/rules.d/gitlab.rules << 'EOF'
# Изменения конфигурации GitLab
-w /etc/gitlab/           -p wa -k gitlab-config
# Изменения данных GitLab
-w /var/opt/gitlab/       -p wa -k gitlab-data
# SSL-сертификаты
-w /etc/letsencrypt/      -p wa -k ssl-certs
# Повышение привилегий
-w /usr/bin/sudo          -p x  -k privilege-escalation
-w /bin/su                -p x  -k privilege-escalation
# Изменения пользователей
-w /etc/passwd            -p wa -k user-changes
-w /etc/shadow            -p wa -k user-changes
# Изменения SSH-конфигурации
-w /etc/ssh/sshd_config   -p wa -k ssh-config
EOF

# Загрузить правила
sudo augenrules --load

# Проверить событие
sudo ausearch -k gitlab-config | tail -5

AIDE — контроль целостности файловой системы

AIDE создаёт эталонную базу контрольных сумм всех критических файлов. При следующей проверке любое несанкционированное изменение будет обнаружено.

Инициализация базы данных

# Инициализировать базу ПОСЛЕ полной установки GitLab
# Процесс занимает 5–15 минут
sudo aide --init

# Переименовать базу в рабочую
sudo mv /var/lib/aide/aide.db.new.gz /var/lib/aide/aide.db.gz

# Запустить первую проверку (должно быть 0 изменений)
sudo aide --check

Автоматическая ежедневная проверка

sudo tee /etc/cron.d/aide-check << 'EOF'
0 5 * * * root /usr/sbin/aide --check 2>&1 \
  | mail -s '[AIDE] Отчёт целостности $(hostname)' admin@mycompany.com
EOF

# После плановых обновлений системы — обновить базу:
sudo aide --update
sudo mv /var/lib/aide/aide.db.new.gz /var/lib/aide/aide.db.gz

Зачем нужен AIDE

Если злоумышленник проник на сервер и изменил бинарные файлы или конфигурации — AIDE обнаружит это при следующей проверке. Храните базу данных AIDE на отдельном (read-only) носителе.

Fail2Ban — защита от брутфорса

Запуск сервиса

Пакеты fail2ban и fail2ban-firewalld уже установлены в разделе 3:

sudo systemctl enable --now fail2ban
sudo fail2ban-client ping   # ответ: pong

Конфигурация для GitLab и SSH

# Фильтр для логов GitLab
sudo tee /etc/fail2ban/filter.d/gitlab.conf << 'EOF'
[Definition]
failregex = Failed Login.*"ip":"<HOST>"
            Invalid Login.*"ip":"<HOST>"
ignoreregex =
EOF

# Jail-конфигурация
sudo tee /etc/fail2ban/jail.d/gitlab.conf << 'EOF'
[gitlab]
enabled   = true
port      = http,https
filter    = gitlab
logpath   = /var/log/gitlab/gitlab-rails/production.log
maxretry  = 5
findtime  = 300
bantime   = 86400
action    = firewallcmd-ipset

[sshd-custom]
enabled   = true
port      = 2222
filter    = sshd
logpath   = /var/log/secure
maxretry  = 3
findtime  = 60
bantime   = 604800
EOF

sudo systemctl restart fail2ban
sudo fail2ban-client status

Защита SSH (OpenSSH 9.9)

AlmaLinux 10 поставляет OpenSSH 9.9 с поддержкой постквантовых алгоритмов обмена ключами. Настройка максимально ужесточена.

Конфигурация /etc/ssh/sshd_config

sudo nano /etc/ssh/sshd_config

# ── Порт и адрес ────────────────────────────────────────────────
Port 2222
AddressFamily inet

# ── Аутентификация ──────────────────────────────────────────────
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
PermitEmptyPasswords no

# ── Безопасность сессии ─────────────────────────────────────────
MaxAuthTries 3
MaxSessions 5
LoginGraceTime 30
ClientAliveInterval 300
ClientAliveCountMax 2

# ── Постквантовые алгоритмы (OpenSSH 9.9 / AL10) ───────────────
# ML-KEM включён по умолчанию, явно зафиксируем приоритет:
KexAlgorithms mlkem768x25519-sha256,curve25519-sha256@libssh.org
HostKeyAlgorithms ssh-ed25519,rsa-sha2-512,rsa-sha2-256

# ── Разрешённые пользователи ────────────────────────────────────
AllowUsers gitadmin

# ── Отключить ненужное ──────────────────────────────────────────
X11Forwarding no
AllowAgentForwarding no
AllowTcpForwarding no
PrintMotd no

sudo systemctl restart sshd

Генерация SSH-ключа ed25519

# На рабочей машине администратора:
ssh-keygen -t ed25519 -C 'admin@mycompany.com' -f ~/.ssh/gitlab_admin

# Скопировать публичный ключ на сервер
ssh-copy-id -i ~/.ssh/gitlab_admin.pub -p 2222 gitadmin@192.168.1.100

# Проверить вход по ключу (в новом терминале!)
ssh -i ~/.ssh/gitlab_admin -p 2222 gitadmin@gitlab.mycompany.com

Важно

Проверьте вход по ключу в отдельном терминале ДО закрытия текущего. Только убедившись в успешном входе — отключайте PasswordAuthentication.

WAF: ModSecurity + Nginx

ModSecurity защищает от атак OWASP Top 10: SQL-инъекций, XSS, path traversal и других. В AlmaLinux 10 устанавливается из основного репозитория.

Примечание об архитектуре

Встроенный Nginx GitLab omnibus не поддерживает сторонние модули. ModSecurity подключается через системный Nginx, работающий как обратный прокси перед GitLab. Альтернатива — использовать Cloudflare WAF.

Установка

# Системный Nginx и ModSecurity
sudo dnf install -y nginx mod_security mod_security_crs

# Актуальные правила OWASP CRS (опционально, свежее версии из пакета)
sudo git clone --depth 1 https://github.com/coreruleset/coreruleset.git \
  /etc/nginx/modsecurity/coreruleset
sudo cp /etc/nginx/modsecurity/coreruleset/crs-setup.conf.example \
        /etc/nginx/modsecurity/coreruleset/crs-setup.conf

Конфигурация ModSecurity

sudo tee /etc/nginx/modsecurity/modsecurity.conf << 'EOF'
SecRuleEngine On
SecRequestBodyAccess On
SecResponseBodyAccess Off
SecRequestBodyLimit 13107200
SecPcreMatchLimit 1000
SecPcreMatchLimitRecursion 1000
SecAuditEngine RelevantOnly
SecAuditLog /var/log/nginx/modsecurity_audit.log
Include /etc/nginx/modsecurity/coreruleset/crs-setup.conf
Include /etc/nginx/modsecurity/coreruleset/rules/*.conf
EOF

sudo systemctl enable --now nginx

Двухфакторная аутентификация и политики доступа

Принудительная 2FA

  • Admin Area → Settings → General → Sign-in restrictions
  • Two-factor authentication → Enforce two-factor authentication → Enabled
  • Grace period: 0 (немедленно, без отсрочки)
  • Поддерживаемые приложения: Google Authenticator, Authy, любой TOTP-клиент

Политика паролей через gitlab.rb

# /etc/gitlab/gitlab.rb
gitlab_rails['password_minimum_length']    = 12
gitlab_rails['password_require_uppercase'] = true
gitlab_rails['password_require_lowercase'] = true
gitlab_rails['password_require_numeric']   = true
gitlab_rails['password_require_symbol']    = true

gitlab_rails['max_login_attempts']          = 5
gitlab_rails['login_attempts_reset_duration'] = 10

sudo gitlab-ctl reconfigure

Управление токенами доступа

  • Admin Area → Settings → General → Account and limit settings
  • Personal Access Token expiry: максимум 90 дней
  • Запрет токенов без срока действия — включить
  • Регулярный аудит: Admin Area → Overview → Users → Personal Access Tokens

Мониторинг и оповещения

Ключевые лог-файлы GitLab

Файл логаСодержимое
/var/log/gitlab/gitlab-rails/production.logВходы, ошибки приложения, аутентификация
/var/log/gitlab/nginx/gitlab_access.logHTTP-запросы: IP, метод, код ответа
/var/log/gitlab/nginx/gitlab_error.logОшибки Nginx
/var/log/gitlab/gitlab-rails/api_json.logЗапросы к REST API
/var/log/gitlab/gitlab-rails/audit_json.logАудит: действия администраторов
/var/log/gitlab/gitlab-rails/auth_json.logСобытия аутентификации
/var/log/secureSSH-входы, sudo
/var/log/audit/audit.logВсе auditd-события
/var/log/nginx/modsecurity_audit.logСрабатывания WAF

Настройка SMTP-уведомлений

# /etc/gitlab/gitlab.rb
gitlab_rails['smtp_enable']               = true
gitlab_rails['smtp_address']              = 'smtp.mycompany.com'
gitlab_rails['smtp_port']                 = 587
gitlab_rails['smtp_user_name']            = 'gitlab@mycompany.com'
gitlab_rails['smtp_password']             = 'SecurePassword!'
gitlab_rails['smtp_domain']               = 'mycompany.com'
gitlab_rails['smtp_authentication']       = 'login'
gitlab_rails['smtp_enable_starttls_auto'] = true
gitlab_rails['gitlab_email_from']         = 'gitlab@mycompany.com'

sudo gitlab-ctl reconfigure

# Тест отправки письма
sudo gitlab-rails runner \
  'Notify.test_email("admin@mycompany.com","Test","OK").deliver_now'

Скрипт ежедневного аудита безопасности

sudo tee /opt/gitlab-security-check.sh << 'SCRIPT'
#!/bin/bash
LOG="/var/log/gitlab-security-$(date +%Y%m%d).log"
echo "=== GitLab Security Report $(date) ===" > $LOG

echo '--- Failed Logins (24h) ---' >> $LOG
grep -i 'failed login' /var/log/gitlab/gitlab-rails/production.log \
  | grep "$(date +%Y-%m-%d)" | wc -l >> $LOG

echo '--- Fail2Ban Banned IPs ---' >> $LOG
fail2ban-client status gitlab 2>/dev/null >> $LOG

echo '--- SSL Certificate Expiry ---' >> $LOG
openssl s_client -connect localhost:443 -servername localhost \
  </dev/null 2>/dev/null | openssl x509 -noout -dates >> $LOG

echo '--- Recent AVC Denials ---' >> $LOG
ausearch -m avc -ts today 2>/dev/null | tail -5 >> $LOG
SCRIPT

sudo chmod +x /opt/gitlab-security-check.sh
echo '0 7 * * * root /opt/gitlab-security-check.sh' \
  | sudo tee /etc/cron.d/gitlab-security

Резервное копирование

Создание резервной копии

# Создать резервную копию всех данных GitLab
sudo gitlab-backup create

# Копия сохраняется в /var/opt/gitlab/backups/
# Формат: TIMESTAMP_YYYY_MM_DD_VERSION_gitlab_backup.tar

# ВАЖНО: конфигурация и секреты бэкапятся отдельно!
sudo tar -czf /tmp/gitlab-config-$(date +%Y%m%d).tar.gz \
  /etc/gitlab/gitlab.rb \
  /etc/gitlab/gitlab-secrets.json

# gitlab-secrets.json критически важен —
# без него восстановление из резервной копии невозможно!

Автоматические бэкапы

# /etc/gitlab/gitlab.rb
gitlab_rails['backup_keep_time'] = 604800   # 7 дней
gitlab_rails['backup_path']      = '/var/opt/gitlab/backups'

# Cron: бэкап каждую ночь в 02:00
sudo tee /etc/cron.d/gitlab-backup << 'EOF'
0 2 * * * root /opt/gitlab/bin/gitlab-backup create CRON=1
30 2 * * * root tar -czf /backup/gitlab-config-$(date +\%Y\%m\%d).tar.gz \
  /etc/gitlab/gitlab.rb /etc/gitlab/gitlab-secrets.json
EOF

💾  Хранение резервных копий

Никогда не храните бэкапы только на том же сервере. Используйте отдельный NAS, S3-совместимое хранилище или резервный сервер. При атаке шифровальщиком бэкапы на том же диске будут уничтожены.

Чек-лист безопасности

Используйте этот список для проверки полноты развёртывания перед вводом в эксплуатацию.

Сеть и NAT

Пункт проверкиСтатус
NAT настроен: порты 80, 443, 2222 перенаправлены на сервер GitLab 
Сервер имеет статический LAN-IP 
DNS A-запись gitlab.mycompany.com указывает на внешний IP 
Firewalld активен, зона по умолчанию — drop 
Открыты только необходимые порты 
Fail2Ban запущен и настроен для GitLab и SSH 

Операционная система

Пункт проверкиСтатус
AlmaLinux 10: проверена совместимость CPU с x86-64-v3 
Система полностью обновлена (dnf update && dnf upgrade) 
SELinux в режиме Enforcing — getenforce возвращает Enforcing 
restorecon выполнен для каталогов GitLab после установки 
Автоматические обновления безопасности включены (dnf-automatic) 
Auditd настроен и ведёт журнал событий 
AIDE инициализирован, настроена ежедневная проверка 
SSH: PermitRootLogin no, PasswordAuthentication no 
SSH: вход только по ключам ed25519, порт 2222 
SSH: настроены постквантовые алгоритмы KexAlgorithms (ML-KEM) 
NTP синхронизирован: chronyc tracking показывает System time offset < 1s 

GitLab (приложение)

Пункт проверкиСтатус
HTTPS настроен, Let’s Encrypt сертификат активен и действителен 
HTTP автоматически перенаправляет на HTTPS 
Только TLS 1.2 и 1.3 — старые версии отключены 
Заголовки безопасности HTTP активны (HSTS, X-Frame-Options и др.) 
Публичная регистрация отключена 
Двухфакторная аутентификация обязательна для всех пользователей 
Rate Limiting (Rack Attack) настроен 
Проекты по умолчанию — Private 
Admin Area ограничена по IP (офис/VPN) 
Personal Access Tokens: максимальный срок 90 дней 
Email-уведомления настроены и протестированы 
Первый пароль root сменён, initial_root_password удалён 

Резервное копирование и мониторинг

Пункт проверкиСтатус
Автоматические ежедневные бэкапы настроены 
gitlab-secrets.json включён в бэкап и хранится отдельно 
Бэкапы хранятся на отдельном сервере/хранилище 
Восстановление из бэкапа протестировано 
Скрипт ежедневного аудита настроен и протестирован 
WAF ModSecurity активен и фиксирует события в лог 

Заключение

Безопасность — непрерывный процесс. Регулярно: обновляйте GitLab (gitlab-ctl upgrade) и AlmaLinux; просматривайте логи безопасности; проверяйте список пользователей; тестируйте восстановление из бэкапа; отслеживайте CVE на https://about.gitlab.com/releases/

Оцените статью
IT-Sierra