Илья Кондратьев

Системный администратор Linux / Junior DevOps

Фокус на администрировании Linux серверов, автоматизации, мониторинге и безопасности. Опыт в развертывании изолированных СУБД, веб окружении, контейнеризации и автоматическом CI/CD деплое.

Общий стек
Linux Bash Git Network Security SQL Docker CI/CD

Мои проекты

Предлагаю ознакомиться с моими проектами. Представлены краткие описания и некоторые технические моменты, которые мне захотелось подсветить. По многим проектам можно перейти на репозиторий GitLab.

1. Автоматизация администрирования (Bash-скрипты и Systemd)

О проекте & Задача

Разработка комплексной системы автоматизации для снижения рутинной нагрузки на системного администратора. Включает в себя создание отказоустойчивых скриптов для регулярного резервного копирования баз данных и интерактивного мониторинга/анализа логов веб-сервера.

Инженерные решения
  • Автоматизация бэкапов БД: Потоковое создание дампов баз данных MySQL/MariaDB непосредственно из работающих Docker-контейнеров с использованием mariadb-dump и динамическим сжатием через gzip.
  • Интерактивный анализатор логов Nginx: Написание консольной утилиты для парсинга access.log. Скрипт поддерживает аргументы командной строки и выполняет агрегацию метрик: расчет топ-10 IP-адресов, топ-10 запрашиваемых URL, выборку ошибок с кодами 5xx, а также расчет почасового распределения нагрузки. Реализована функция «горячего» скачивания свежих логов из контейнера Nginx (–refresh).
  • Переход на Systemd Timers: Отказ от устаревшего cron в пользу связки systemd.service + systemd.timer. Это обеспечило гибкое управление расписанием, изоляцию процессов, автоматический перезапуск при сбоях и централизованное логирование в systemd-journald (без риска переполнения диска лог-файлами).
Стек технологий
Bash (Shell) Systemd Timers Docker Regex Journalctl Nginx logs
Репозиторий ➔

📁 Структура репозитория автоматизации

backup-wp-db/
├── backup-wp-db.sh          # Исполняемый скрипт бэкапа с логикой ротации
├── backup-wp-db.conf        # Конфигурационный файл (параметры подключения и secrets)
├── wp-backup.service        # Юнит-файл однократного запуска службы SystemD
├── wp-backup.timer          # Юнит-файл таймера автоматического расписания SystemD
├── deploy_backup-wp-db.sh   # Автоматизированный скрипт безопасного деплоя проекта на хост
├── README-backup.md         # Инструкция по развертыванию и сценарий восстановления данных
└── VERSION-TODO-backup.md   # Лог версионирования и дорожная карта развития

🔒 Безопасность и разграничение прав (Security & Deploy)

  • Принцип наименьших привилегий: Процесс деплоя полностью автоматизирован через deploy_backup-wp-db.sh. Все файлы передаются во владение root:root.
  • Защита Secrets: На конфигурационный файл с паролями принудительно выставляются права 600 (-rw-------), а на саму рабочую директорию — 700 (drwx------). Любые сторонние пользователи хоста полностью изолированы от чтения учетных данных БД.

⚙️ Bash Best Practices (Отказоустойчивость кода)

  • Предсказуемость исполнения: Скрипты работают в строгом режиме set -euo pipefail (немедленная остановка при любой ошибке в пайплайнах или вызове необъявленной переменной).
  • Чистка мусора через сигналы: Внедрен перехват системных сигналов с помощью trap на сигнал EXIT. В случае аварийного прерывания бэкапа (например, не хватило места), скрипт автоматически удаляет поврежденный “огрызок” архива, предотвращая порчу мониторинга.
  • Качество кода:
    • Реализована строгая проверка зависимостей (проверка наличия утилит docker, gzip в системе перед стартом).
    • Проверка входных параметров и валидация состояния целевых Docker-контейнеров (проверка статуса running).
    • Повторяющиеся операции (например, кастомное логирование с разделением потоков stdout/stderr) вынесены в функции.
    • Код полностью соответствует стандартам линтера ShellCheck.
    • Используются каноничные коды завершения команд (Exit Codes).

🛠️ Сценарий восстановления данных (Disaster Recovery)

Разработана и задокументирована процедура быстрого восстановления базы данных «из коробки» (восстановление структуры и записей одной командой путем подачи распакованного через zcat потока в stdin контейнера):

sudo zcat /var/backups/backup-wp-db/backup_file.sql.gz | docker exec -i "$CONTAINER_NAME" mysql -u root -p database_name

2. Изолированный сервер баз данных MySQL

О проекте & Задача

Организация безопасного контура хранения данных СУБД с многоуровневой сетевой изоляцией для защиты от внешних атак и несанкционированного доступа.

Инженерные решения
  • Сетевая безопасность: Стандартный порт СУБД (3306) полностью закрыт для внешних запросов на уровне межсетевого экрана и конфигурации Docker.
  • Ограничение прав на уровне СУБД: Доступ к базам данных разрешен строго изнутри выделенной изолированной IP-подсети Docker (172.18.0.%).
  • Безопасное администрирование: Удаленное взаимодействие с СУБД, управление базами данных и подключение через GUI-клиенты реализованы исключительно через шифрованный SSH-туннель.
  • Документирование: Разработана техническая документация по добавлению новых клиентов баз данных.
Стек технологий
MySQL Docker Network SSH Tunneling Linux Security
Репозиторий ➔

🔒 Изоляция на уровне запуска контейнера

Главная уязвимость многих инсталляций — проброс порта базы данных на внешний интерфейс хоста (0.0.0.0:3306). В данном проекте порт жестко привязан к локальной петле 127.0.0.1, что делает СУБД невидимой для внешних сканеров сети порт-в-порт.

docker run -d \
  --name mysql-server \
  --network mysql_net \
  -v mysql_data:/var/lib/mysql \
  -v /opt/mysql/config:/etc/mysql/conf.d \
  -e MYSQL_ROOT_PASSWORD=SuperSecretRootPass \
  -p 127.0.0.1:3306:3306 \
  --restart unless-stopped \
  mysql:8.0

🌐 Подробности сетевого взаимодействия и механика Docker NAT

Архитектура изоляции построена на комбинации локального форвардинга портов SSH и механизмов маршрутизации виртуальной сети Docker (Bridge Network):

  • Локальная привязка порта (Loopback): В конфигурации порт СУБД проброшен строго на внутренний loopback-интерфейс хоста: 127.0.0.1:3306:3306. Это делает порт физически недоступным со стороны внешней сети (Internet), даже если на внешнем интерфейсе нет файрвола.
  • Прохождение трафика через туннель: Когда клиент инициирует сессию Standard TCP/IP over SSH, его трафик шифруется и доставляется службе sshd на сервере. Локальный клиент СУБД отправляет запросы в этот туннель, и они «приземляются» на стороне сервера как запросы, исходящие от локального адреса 127.0.0.1 на порт 3306.
  • Трансляция адресов (Docker NAT & Masquerading): Запрос принимает виртуальный сетевой интерфейс Docker. Поскольку пакеты, идущие с хоста внутрь изолированной bridge-сети контейнеров, должны быть корректно маршрутизированы обратно, подсистема сетевого моста Docker применяет Source NAT (SNAT / Маскарадинг).
  • Финальная доставка: В результате подмены адреса источника пакеты входят в сетевой стек контейнера MySQL не с внешнего IP-адреса и не с адреса 127.0.0.1, а с IP-адреса шлюза Docker-сети (по умолчанию 172.18.0.1). СУБД видит подключение из подсети 172.18.0.%, что полностью удовлетворяет строгим политикам безопасности пользователей ('user'@'172.18.0.%') и блокирует любые сторонние попытки аутентификации.

📋 Техническая документация: Регламент предоставления доступа для нового клиента

##### 1. Действия со стороны клиента
1. Клиент генерирует пару SSH-ключей на своей рабочей машине командой:
   ssh-keygen -t ed25519 -C "your_email@example.com"
2. Передает созданный публичный ключ (.pub) администратору сервера.
3. Настраивает подключение в GUI-клиенте СУБД (DBeaver, MySQL Workbench или аналог) по методу Standard TCP/IP over SSH:
   - Вкладка SSH (Параметры туннеля):
        SSH Hostname: SERVER_PUBLIC_IP (публичный IP-адрес сервера)
        SSH Username: sqluser (выделенный служебный пользователь)
        SSH Key File: Путь к локальному приватному ключу клиента
   - Вкладка Main (Параметры MySQL):
        MySQL Hostname: 127.0.0.1 (относительно сервера)
        MySQL Port: 3306
        Username: appuser
        Password: client_password

##### 2. Действия со стороны администратора (заведение клиента и БД)
1. Администратор добавляет публичный ключ клиента в файл авторизации служебного пользователя:
   nano ~/.ssh/authorized_keys
2. Подключается к работающему Docker-контейнеру СУБД с правами суперпользователя:
   docker exec -it mysql-server mysql -uroot -p
3. Создает изолированную базу данных с поддержкой современных кодировок:
   CREATE DATABASE newbase_name CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
4. Создание пользователя и делегирование прав с ограничением авторизации виртуальной Docker-подсетью:
   CREATE USER 'appuser'@'172.18.0.%' IDENTIFIED BY 'client_password';
   GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER, DROP, INDEX ON newbase_name.* TO 'appuser'@'172.18.0.%';
   FLUSH PRIVILEGES;
5. Завершает сессию администрирования:
   exit

##### 3. Режимы работы с базой данных
После настройки туннеля клиент может:
- Подключиться к уже выделенной и созданной для него базе данных.
- Самостоятельно развернуть структуру таблиц внутри выделенного пространства.
- Запросить создание дополнительных изолированных баз у администратора согласно регламенту.

3. Защищенный контур серверной инфраструктуры (Baseline)

О проекте & Задача

Создание безопасного эталонного Linux-сервера для развертывания production-приложений с защитой от несанкционированного доступа.

Инженерные решения
  • Настройка Firewall (UFW) с политикой ограничения входящего трафика по умолчанию — исключения порты SSH (22), HTTP (80), HTTPS (443).
  • Интеграция Fail2ban для динамической блокировки хостов при попытках брутфорса по SSH.
  • Организация удаленного доступа через WireGuard VPN и авторизация строго по SSH ключам.
Стек технологий
Ubuntu Server UFW Fail2ban WireGuard VPN SSH Security

🛡️ Отключение прямого доступа для root

В рамках политики безопасности выполнено отключение доступа к учетной записи root. Почему это важно?

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

Постоянная работа под root нарушает главные правила безопасности:

  • Риск критических ошибок: Под обычным пользователем команда rm -rf / выдаст ошибку Permission denied. Под root система сотрет себя без лишних вопросов.
  • Компрометация системы: Если вы запустите под root программу или скрипт, содержащий уязвимость, злоумышленник мгновенно получит полный контроль над всем сервером.
  • Принцип минимальных привилегий (Principle of Least Privilege — PoLP): Фундаментальное правило безопасности — использовать в каждый момент времени только те права, которые минимально необходимы для выполнения текущей задачи.
  • Отсутствие контроля (Логирование): Если все администраторы заходят на сервер напрямую под root, в логах невозможно разобрать, кто именно совершил действие или ошибку. При использовании sudo система фиксирует реальное имя пользователя.

4. Production-like веб-инфраструктура WordPress

О проекте & Задача

Развёртывание отказоустойчивого контейнеризированного веб-сервиса с автоматическим деплоем и изолированными слоями.

Инженерные решения
  • Выполнена контейнеризация компонентов веб-приложения (Nginx, PHP-FPM, MariaDB).
  • Настроено управление через Docker Compose, изолирован каждый слой инфраструктуры на уровне контейнеров и внутренних сетей Docker.
  • Сконфигурирован Nginx в роли Reverse Proxy, настроена маршрутизация и upstream-сервисы.
  • Настроен автоматический выпуск SSL-сертификатов Let’s Encrypt и постоянный редирект с HTTP на HTTPS.
  • Развернут локальный GitLab Runner и построен автоматизированный pipeline для валидации манифестов Docker Compose и линтинга конфигураций Nginx, что позволило полностью исключить downtime (простой) веб-сервиса при обновлениях.
Стек технологий
Docker Docker Compose Nginx PHP-FPM MariaDB GitLab CI/CD Let’s Encrypt
Репозиторий ➔

🏗️ Архитектурная схема веб-инфраструктуры

Архитектурная схема веб-инфраструктуры WordPress

🔑 Ключевые архитектурные акценты

  • Многоуровневая изоляция (Security Best Practice): Внешний мир имеет доступ исключительно к контейнеру Nginx по HTTP-порту. Контейнеры приложения (WordPress) и базы данных (MariaDB) находятся в приватной виртуальной сети Docker. Прямой доступ к СУБД извне полностью заблокирован, что исключает возможность брутфорса или сканирования портов базы данных.
  • Разделение обязанностей (Separation of Concerns): Nginx освобождает PHP-FPM от рутины, самостоятельно обрабатывая и отдавая статические файлы (.css, .png, .js) с максимальным временем кэширования в браузере (директива expires max). Тяжелый бэкенд обрабатывает только динамический PHP-код, что снижает нагрузку на сервер.
  • Безопасный CI/CD Pipeline (Automation & Zero-Downtime подход): Развертывание защищено предварительной валидацией: сначала проверяется синтаксис манифестов (docker-compose config), затем линтится конфигурация Nginx. И только при успешных тестах локальный GitLab Runner производит деплой, минимизируя риски «уронить» рабочий сайт из-за синтаксической ошибки.
  • Stateful Persistence (Надежность данных): Разделение stateless-логики контейнеров и stateful-данных через именованные Docker Volumes гарантирует, что обновление, перезапуск или уничтожение контейнеров не приведет к потере пользовательского контента и базы данных.