Полное руководство по установке, публикации через NAT и комплексной защите от злоумышленников.
- Что нового в AlmaLinux 10: ключевые отличия от версии 9
- Сводная таблица изменений
- Важные изменения для администратора
- Требования к системе
- Аппаратные требования
- Сетевые требования
- Подготовка AlmaLinux 10
- Первичное обновление и репозитории
- Обновление системы
- Подключение репозиториев
- Установка всех необходимых пакетов
- Включение сервисов
- Настройка SELinux
- Имя хоста, время и системный пользователь
- Автоматические обновления безопасности
- Установка GitLab CE
- Добавление официального репозитория
- Установка GitLab CE
- Базовая конфигурация /etc/gitlab/gitlab.rb
- Настройка NAT и публикация в интернете
- Схема перенаправления портов
- Настройка Port Forwarding на маршрутизаторе
- Пример конфигурации MikroTik (RouterOS)
- Статический IP на сервере
- SSL/TLS: Let’s Encrypt и усиленная конфигурация
- Проверка и обновление сертификата
- Постквантовая криптография AlmaLinux 10
- Безопасность GitLab: конфигурация приложения
- Отключение публичной регистрации
- Rate Limiting (защита от брутфорса на уровне приложения)
- Таблица настроек Admin Area
- Ограничение Admin Area по IP (Nginx)
- SELinux, Firewalld, Auditd
- Настройка Firewalld
- Auditd — правила аудита для GitLab
- AIDE — контроль целостности файловой системы
- Инициализация базы данных
- Автоматическая ежедневная проверка
- Fail2Ban — защита от брутфорса
- Запуск сервиса
- Конфигурация для GitLab и SSH
- Защита SSH (OpenSSH 9.9)
- Конфигурация /etc/ssh/sshd_config
- Генерация SSH-ключа ed25519
- WAF: ModSecurity + Nginx
- Установка
- Конфигурация ModSecurity
- Двухфакторная аутентификация и политики доступа
- Принудительная 2FA
- Политика паролей через gitlab.rb
- Управление токенами доступа
- Мониторинг и оповещения
- Ключевые лог-файлы GitLab
- Настройка SMTP-уведомлений
- Скрипт ежедневного аудита безопасности
- Резервное копирование
- Создание резервной копии
- Автоматические бэкапы
- Чек-лист безопасности
- Сеть и NAT
- Операционная система
- GitLab (приложение)
- Резервное копирование и мониторинг
Что нового в AlmaLinux 10: ключевые отличия от версии 9
AlmaLinux 10 «Purple Lion» вышел 27 мая 2025 года. Перед установкой важно понять изменения, которые непосредственно влияют на установку и эксплуатацию GitLab.
Сводная таблица изменений
| Компонент | AlmaLinux 9 | AlmaLinux 10 |
| Компонент | AlmaLinux 9 | AlmaLinux 10 |
| Ядро Linux | 5.14.x | 6.12 (LTS) |
| OpenSSH | 8.7 | 9.9 (пост-квантовая криптография) |
| OpenSSL | 3.0.x | 3.5.x (FIPS, PKCS#11) |
| Python | 3.9 / 3.11 | 3.12 |
| Node.js | 18 / 20 | 22 (LTS) |
| Git | 2.39.x | 2.47 |
| Nginx | 1.22.x | 1.26 |
| SELinux userspace | 3.5 | 3.8 (CIL output, Wayland) |
| Архитектура x86 | x86-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-сборки нужна отдельная настройка репозитория.
Требования к системе
Аппаратные требования
| Компонент | Минимум | Рекомендуется |
| CPU | 4 ядра (x86-64-v3) | 8+ ядер |
| RAM | 4 ГБ | 8–16 ГБ |
| Диск | 40 ГБ SSD | 200+ ГБ 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 TCP | 192.168.1.100:443 | GitLab HTTPS |
| 80 TCP | 192.168.1.100:80 | GitLab HTTP → редирект |
| 2222 TCP | 192.168.1.100:2222 | GitLab 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-in | Two-factor authentication | Enforced for all |
| General → Sign-in | Password minimum length | 12+ символов |
| General → Sign-in | Session expire (remember me) | 7 дней |
| General → Visibility | Default project visibility | Private |
| General → Visibility | Default snippet visibility | Private |
| Network → IP restriction | Admin area IP restriction | IP офиса/VPN |
| Network → Outbound | Allow local requests from web hooks | Отключено |
| Network → Rate limits | Unauthenticated 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.log | HTTP-запросы: 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/secure | SSH-входы, 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/








