Тут будет собираться полезные документы/видео по работе.
Архив:
Документы:
### 1. Введение
- Разбирается процесс раскатки на примере кода практикантки Кристины.
- Сам код рабочий, но есть моменты, которые можно улучшить.
- Способов доставки кода на сервер много, показан один — используемый в компании (Docker + Helm + GitLab CI + ArgoCD + Vault).
### 2. Dockerfile
- В целом нормальный, рабочий.
- **Замечание:** публичные образы (`FROM`) могут быть недоступны в окружениях с закрытым доступом к Docker Hub. В текущем проекте это не критично, но для внешних поставок лучше заменить на внутренние базовые образы.
- Добавлен `annotation liquid` — описывает имя и путь до Dockerfile для внутренней логики сборок.
### 3. Helm-чарт: общая структура
- Чарт избыточен: два лишних файла (не используются) можно удалить.
### 4. Deployment
- **`chart name` vs `release name`:**
- Использование `{{ .Chart.Name }}` в именах сущностей приводит к конфликтам при нескольких установках на одном контуре.
- **Рекомендация:** заменить на `{{ .Release.Name }}`, чтобы имена подов/сервисов были уникальны для каждого релиза.
- **Аннотации для Vault:**
- В примере каждый секрет стягивается в отдельный файл отдельным блоком.
- **Лучшая практика:** использовать цикл `range` по списку секретов из `values.yaml`, который за один проход подкладывает все секреты как JSON-файлы. Это компактнее и читаемее.
- **Пути к секретам:** нужно выносить в `values.yaml`, чтобы их можно было менять без правок Deployment.
- **Переменные окружения:** возник вопрос, как секреты попадают в код. В проекте Кристины использован нестандартный подход (не `APPHOME`), из-за нехватки времени. Обычно секреты кладутся в файлы, и приложение читает их через библиотеку, а локально для тестов разработчики просто подкладывают JSON-файл в папку.
- **Sidecar (VPN-клиент):** тоже заменять `chart name` на `release name`.
- **YAML-отступы:** Helm очень чувствителен к пробелам, особенно в многострочных конструкциях.
### 5. Ingress
- Принимает 80-й порт, пути описаны регуляркой.
- **Заменить** `chart name` на `release name` в хостах и TLS-секции, чтобы сертификат подтягивался корректно.
### 6. Service
- В Deployment контейнер жёстко слушает порт 5000, в Service наружу отдаётся 80.
- При этом номера портов зачем-то вынесены в `values.yaml`, хотя они никогда не меняются.
- **Предложение:** либо оставить захардкоженными и не выносить в values, либо вынести осмысленно, используя `service.port` и `service.targetPort`.
### 7. Версионирование чарта
- При каждом коммите должна генерироваться новая версия чарта (`version` в `Chart.yaml`), иначе не произойдёт обновления на стенде. Для этого используются mock-переменные.
### 8. Values.yaml
- **Хост:** заменить на моки.
- **Registry credentials:** добавлен отдельный секрет, чтобы не тянуть общий.
- **Account name для Vault:** без замечаний.
- **Mock image:** использовать переменную `mockImage`, чтобы CD автоматически подставлял собранный образ; не нужно переопределять вручную.
- **Resources:** вопросов к выставленным значениям нет, но вообще они определяются «на глаз».
- **Внешний Redis:** строка подключения лежит открыто в values, лучше убрать в Vault/секреты.
- **VPN:** большинству команд не нужно.
### 9. GitLab CI/CD (пайплайн)
- **Два основных артефакта:** Docker-образ и Helm-чарт. Дополнительно могут собираться NuGet-пакеты (через Nexus) или EXE-файлы (на S3).
- **Стадии:**
- `prebuild` – определение версии, генерация метаинформации.
- `annotation leak` – подстановка mock-переменных, определение Dockerfile.
- `build` – сборка образа по Dockerfile.
- `test` – запуск тестов.
- `chart-museum/deploy` – подстановка mock’ов в чарт и загрузка чарта в реестр (ChartMuseum).
- **Реестр образов (Harbour):** веб-интерфейс, хранит Docker-образы. Есть система автоматической очистки старых образов, чтобы не переполнять диск.
- **Реестр пакетов (Nexus):** хранит NuGet-пакеты и другие артефакты, доступ через API.
### 10. ArgoCD (развёртывание)
- Используется для автоматической выкатки.
- **Ключевые настройки:**
- Автоматическая политика обновления (auto-sync).
- Self-heal (автоматический перезапуск упавших подов).
- Выбор реестра (предварительно добавленного).
- Версия образа: можно указать `x.x.x` (всегда последняя), `1.1.x` (последняя в ветке 1.1) и т.д.
- Namespace – для одиночных проектов, либо несколько namespace для распределённых.
- Host можно указать в values или передать через параметры.
### 11. Vault (подтягивание секретов)
- **Создание секрета:**
- Тип: KVv2.
- Путь указывается полностью (включая все папки), если папки нет – создастся.
- Данные лучше писать в JSON, особенно если есть числовые или булевы значения (булевы могут неверно интерпретироваться в строковом представлении).
- **Как секреты попадают в под:**
- **Init-container с Vault Agent:** запускается до основного контейнера и стягивает секреты согласно аннотациям и циклу `range`.
- В примере из лекции используется конструкция `range` по ключам из `values.yaml`: для каждого ключа забирается всё содержимое секрета и записывается в файл `имя_ключа.json`.
- **Настройка Vault Agent:**
- При первой инициализации агент выдаёт «печати» (seals/ключи расщепления) – их нужно сохранить локально, они нужны для ручной разблокировки Vault при сбоях.
- Создаётся роль и политика доступа: разрешено только чтение (`read`) нужных секретов, доступ ограничен списком namespace (можно через запятую или звёздочку `*` для всех).
- Политика привязывается к сервисному аккаунту Kubernetes.
- **Отладка:** если init-контейнер завис, нужно смотреть логи sidecar’а. Частая ошибка – `Secret does not exist` (неправильный путь или название секрета).
### 12. Мониторинг и ресурсы
- **Инструмент:** Grafana. В базовой конфигурации есть графики потребления CPU/GPU/ОЗУ по подам.
- **Requests и Limits:**
- **Requests** – сколько ресурсов должно быть свободно в кластере, чтобы под запустился.
- **Limits** – верхняя граница, больше которой Kubernetes не даст потреблять.
- Если приложение потребляет меньше requests, это допустимо. Писать нулевые requests сейчас запрещено корпоративными политиками (нельзя отправить без указания).
- **Как определить ресурсы:**
- Часто ставятся «на глаз» (0.2 CPU, 300 МБ ОЗУ), с запасом.
- Для тяжёлых приложений (нейросети) можно сначала задать завышенные лимиты, запустить, снять реальные метрики в Grafana, а затем скорректировать под рабочую нагрузку (в т.ч. пиковую с несколькими пользователями).
- Технически можно убрать блок `limits` вообще, тогда под будет «жадно» потреблять сколько сможет в пределах узла, но это не рекомендуется.
### 13. ClickHouse (ответ на вопрос)
- **Колоночная база данных,** изначально спроектированная для записи и аналитики больших объёмов событий.
- **Ключевое преимущество:** данные хранятся по колонкам, а не по строкам. При выборке за временной период читаются только нужные колонки, что резко ускоряет запросы.
- Идеально подходит для логов, метрик, событийных данных с временной меткой. Пример: запись событий с дорожных камер за год – ClickHouse выдавал выборки практически мгновенно.
- В PostgreSQL тоже можно сделать индекс по времени, но ClickHouse даёт выигрыш именно на аналитике больших массивов однотипных записей. настройка приложения для деплоя.md Скачать# Регламент по валидации и хранению паролей пользователей
## 1. Цель и основание
**Цель:** Установить единые и обязательные правила создания, проверки и безопасного хранения паролей пользователей для предотвращения использования слабых учётных данных и компрометации систем.
**Область применения:** Настоящий регламент распространяется на все сервисы, производящие регистрацию и хранение данных пользователей, включая как публичные, так и внутренние системы компании.
## 2. На что распространяется политика
Требования применяются ко всем системам и сервисам, включая:
- сервисы, доступные из интернета (публичные интерфейсы, админки, панели, VPN/VDI, bastion, GitLab, Harbor, Monitoring, API с аутентификацией);
- внутренние сервисы и CI/CD;
- учетные записи пользователей и сервисные аккаунты.
**Обязательное требование к интерфейсам:** Фронтенд всех сервисов, подпадающих под действие настоящего регламента, должен реализовывать функцию генерации надежного пароля для новых пользователей в каждой форме создания/регистрации пользователей.
**Разделение секретов по типам (из входящих требований ИБ):**
В системе используются разные типы секретов с разными требованиями:
1. **Пароли пользователей (Human)** — SSO, локальные учётки, админ-панели, пользовательские интерфейсы. *Требования описаны в данном регламенте.*
2. **Секреты сервисов (Machine)** — пароли БД, service accounts, basic auth, webhook secrets. *Требования к ним описаны в отдельных документах.*
3. **Токены и ключи** — API-ключи, JWT-секреты, приватные ключи. *Требования к ним описаны в отдельных документах.*
**Ключевое правило:** `UUIDv7` допустим только для Machine-секретов. Использование `UUIDv7` в качестве пароля для человека **запрещено**, так как это неудобно и почти гарантированно приводит к утечкам.
## 3. Требования к паролям пользователей (валидация)
Любой пароль, устанавливаемый пользователем, должен проходить проверку на соответствие следующим правилам.
### 3.1. Базовые требования
* **Минимальная длина:** 12 символов.
* **Для администраторов:** 14 символов.
* **Максимальная длина:** 128 символов.
* Пароль не может быть пустым или состоять только из пробелов.
### 3.2. Запрещённые пароли
Пароль должен быть отклонен, если он:
1. Присутствует в актуальном списке запрещенных (слабых) паролей (denylist), включая, но не ограничиваясь: `password`, `123456`, `qwerty`, `admin123` и др.
2. Содержит, без учета регистра:
* Логин пользователя (при длине логина от 3 символов).
* Локальную часть адреса электронной почты пользователя (часть до символа `@`, при длине от 3 символов).
* Наименование сервиса или домена (при длине от 3 символов).
* Служебные слова, такие как: `admin`, `prod`, `dev`, `test`, `msdis`.
3. Содержит простые шаблоны:
* Повторяющийся символ (4 и более раз подряд).
* Последовательные буквы алфавита (например, `abc`, `cde`) или цифры (например, `123`, `987`).
* Распространенные клавиатурные комбинации (например, `qwerty`, `asdfgh`).
### 3.3. Требование к криптостойкости
Пароль считается валидным, только если итоговая оценка сложности ≥ 3.
**Критерии оценки:**
1. **Длина:**
- ≥ 12 символов → +1
- ≥ 16 символов → +1
- ≥ 20 символов → +1
2. **Разнообразие символов:**
- lowercase (строчные буквы)
- uppercase (заглавные буквы)
- digits (цифры)
- special chars (специальные символы)
**Начисление баллов:**
- 2 типа символов → +1
- 3 типа символов → +2
- 4 типа символов → +3
3. **Уникальность символов:**
- ≥ 60% уникальных символов → +1
- ≥ 80% уникальных символов → +2
**Максимальный score: 5**
### 3.4. Логирование валидации
При отклонении пароля логируется только причина отказа (текстовое описание).
Уровень логирования: **Warning**.
**Опционально:** идентификатор пользователя (необязателен).
**Запрещено:**
- Логирование пароля в любом виде
- Логирование персональных данных
## 4. Требования к хранению паролей
### 4.1. Алгоритм и формат хранения
Для постоянного хранения паролей пользователей должен использоваться **исключительно** алгоритм хэширования **Argon2id**. Результат хэширования должен сохраняться в стандартизированном формате **PHC (Password Hashing Competition)** *(string)*.
**Пример корректного формата хранения:**
`$argon2id$v=19$m=65536,t=3,p=4$$`
### 4.2. Параметры алгоритма
Рекомендуемые параметры для Argon2id:
Минимальные:
| Параметр | Значение |
|----------|----------|
| Version | 19 |
| Memory | 32768 KiB (32 MiB) |
| Iterations | 3 |
| Parallelism | 1 |
| Salt size | 16 bytes (128 bit) |
| Hash size | 32 bytes (256 bit) |
Рекомендуемые:
| Параметр | Значение |
|----------|----------|
| Version | 19 |
| Memory | 19456 KiB (19 MiB) |
| Iterations | 2 |
| Parallelism | 1 |
| Salt size | 16 bytes (128 bit) |
| Hash size | 32 bytes (256 bit) |
Максимальные:
| Параметр | Значение |
|----------|----------|
| Version | 19 |
| Memory | 65536 KiB (64 MiB) |
| Iterations | 3 |
| Parallelism | 4 |
| Salt size | 16 bytes (128 bit) |
| Hash size | 32 bytes (256 bit) |
[Шпаргалка по OWASP](https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html)
**Требования к salt:**
- Генерируется криптографически стойко
- Уникальна для каждого пароля
- Хранится внутри PHC-строки
- Минимальная допустимая длина при проверке: **≥ 8 bytes**
### 4.3. Запрещенные методы хранения
Для хранения паролей пользователей запрещены следующие форматы:
1. **SHA-256** (полностью запрещён для хранения паролей)
2. **Base64-хэши без PHC-формата**
3. **Любые форматы, отличные от PHC-строки Argon2id**
4. **Строки без префикса `$argon2id$` в начале**
### 4.4. Формат хэша для проверки
Для проверки пароля принимается исключительно PHC-строка Argon2id, содержащая:
- Префикс `$argon2id$`
- Версию `v=19`
- Параметры `m` (memory), `t` (iterations), `p` (parallelism)
- Валидные Base64-кодированные `salt` и `hash`
### 4.5. Проверка корректности хэша
Перед верификацией необходимо проверить корректность PHC-строки:
1. Наличие обязательных компонентов (`$argon2id$`, `v=19`, `m`, `t`, `p`)
2. Корректность Base64-кодирования `salt` и `hash`
3. Соответствие длины `salt` (≥ 8 байт) и `hash` (32 байта)
### 4.6. Процедура верификации
Верификация пароля выполняется в следующем порядке:
1. **Извлечение параметров** — получение `salt`, `memory`, `iterations`, `parallelism` из PHC-строки
2. **Вычисление хэша** — пересчёт хэша от предоставленного пароля с **теми же параметрами**:
- Та же соль (`salt`)
- Та же память (`memory`)
- То же количество итераций (`iterations`)
- Та же степень параллелизма (`parallelism`)
3. **Сравнение хэшей** — постоянное по времени (constant-time) сравнение полученного хэша с хранимым
**Обработка ошибок:**
- Любая ошибка (некорректный формат, неверный пароль) → возврат `false`
- Исключения не пробрасываются
- Пустые/null значения → `false`Регламент по валидации и хранению паролей пользователей.md Скачать# Регламент по генерация паролей и доступ к сервисам и виртуальным машинам
## 1. Цель и основание
**Цель:**
Настоящий регламент устанавливает требования к генерации, валидации, ротации и использованию паролей и учетных данных для доступа к сервисам, доступным из внешнего интернета, а также к виртуальным машинам, с целью реализации требований информационной безопасности и снижения рисков компрометации доступов.
**Основание:**
Регламент разработан на основании:
- требований заказчика в области информационной безопасности к паролям, секретам и инфраструктурному доступу;
- требований к управлению секретами и учетными записями сервисов и инфраструктуры;
- эксплуатационных практик команд разработки и эксплуатации.
## 2. Область применения
Действие настоящего регламента распространяется на:
- сервисы и приложения, доступные из внешнего интернета и не требующие подключения к VPN;
- виртуальные машины во всех окружениях (production, stage, test и др.);
- учетные записи сервисов и инфраструктурные учетные записи;
- пароли, SSH-ключи и иные учетные данные, используемые для доступа к указанным ресурсам.
## 3. Термины и определения
- **Внешний сервис** — сервис, доступный из сети Интернет без использования VPN.
- **Критичный сервис** — сервис, компрометация которого может привести к нарушению безопасности, доступности или целостности данных.
- **Учетные данные** — пароли, SSH-ключи и иные средства аутентификации.
- **Виртуальная машина (ВМ)** — вычислительный ресурс, предоставляемый инфраструктурой виртуализации.
## 4. Требования к генерации и валидации паролей
4.1. Пароли для доступа к сервисам, доступным из внешнего интернета, **должны соответствовать гайдлайнам генерации и валидации паролей**, установленным в регламенте по валидации и хранению паролей пользователей.
4.2. Использование вручную созданных, простых или предсказуемых паролей для внешних сервисов **запрещается**.
4.3. Пароли, используемые для доступа к виртуальным машинам, при их наличии **должны проходить валидацию** по тем же требованиям, что и пароли сервисов.
## 5. Требования к ротации паролей
5.1. Для критичных сервисов **рекомендуется** осуществлять регулярную ротацию паролей.
5.2. Рекомендуемый период ротации паролей для критичных сервисов составляет **от 1 до 4 месяцев**, если иные сроки не установлены требованиями информационной безопасности.
5.3. Ротация паролей должна выполняться с учетом корректной поддержки смены учетных данных со стороны сервисов.
## 6. Требования к доступу к виртуальным машинам
6.1. Доступ по SSH к виртуальным машинам **не должен осуществляться под учетной записью root**.
6.2. Для административного доступа к виртуальным машинам должны использоваться индивидуальные учетные записи с минимально необходимыми привилегиями.
6.3. При возможности **весь доступ к виртуальным машинам рекомендуется осуществлять с использованием SSH-ключей**, а не паролей.
6.4. Использование парольной аутентификации для доступа к виртуальным машинам допускается только в случаях, когда применение SSH-ключей технически невозможно.
## 7. Общие требования безопасности
7.1. Учетные данные не должны передаваться или храниться в незащищенном виде (репозитории, чаты, документация и т.п.).
7.2. Доступы к сервисам и виртуальным машинам должны предоставляться по принципу минимально необходимых привилегий.
7.3. Факты предоставления и использования доступов должны подлежать аудиту в соответствии с требованиями информационной безопасности.
## 8. Ответственность и контроль
8.1. Ответственность за соблюдение настоящего регламента несут команды разработки и эксплуатации.
8.2. Контроль соблюдения требований настоящего регламента осуществляется командой информационной безопасности.
8.3. Нарушение требований регламента рассматривается как нарушение требований информационной безопасности.
Регламент по генерация паролей и доступ к сервисам и виртуальным машинам.md Скачать# Регламент по хранению данных в HashiCorp Vault
## 1. Цель и основание
**Цель:**
Настоящий регламент устанавливает единые правила хранения, структурирования, именования и использования конфиденциальных данных (секретов) в HashiCorp Vault с целью повышения уровня информационной безопасности, управляемости и прозрачности работы с секретами.
**Основание:**
Регламент разработан на основании внутренних требований информационной безопасности к управлению секретами, а также практик эксплуатации HashiCorp Vault, используемых в инфраструктуре компании, и требований к хранению и использованию секретов.
## 2. Область применения
Действие настоящего регламента распространяется на:
- все команды разработки и эксплуатации;
- все сервисы и приложения, использующие HashiCorp Vault;
- все окружения (production, stage, test и иные);
- все типы секретов, включая, но не ограничиваясь: пароли баз данных, API-ключи, токены, сервисные учетные данные, ключи интеграций.
## 3. Термины и определения
- **Vault** — централизованное хранилище секретов HashiCorp Vault.
- **Секрет** — конфиденциальные данные, используемые сервисами или инфраструктурой (пароли, ключи, токены и т.д.).
- **Окружение** — логически изолированная среда эксплуатации сервиса (prod, stage, test и т.п.).
## 4. Общие требования к хранению данных в Vault
4.1. Секреты запрещается хранить:
- в репозиториях исходного кода;
- в CI/CD переменных без защиты;
- в документации, Confluence, чатах и иных незащищенных хранилищах.
4.2. Секреты, используемые в различных окружениях, **должны быть уникальными** и не пересекаться между собой.
## 5. Требования к структуре хранения секретов
5.1. Все секреты в Vault **должны храниться в виде структуры «ключ–значение»**.
5.2. Не рекомендуется хранение нескольких значений в одном поле в виде сериализованного JSON, сохраненного строкой, за исключением случаев, когда это технически обосновано и согласовано.
5.3. При возможности секреты **должны группироваться по иерархическим папкам (path)** для предотвращения нагромождения данных и повышения читаемости структуры Vault.
Пример логической структуры:
```
mcdis////
```
## 6. Требования к именованию секретов
6.1. Наименования секретов должны быть **исчерпывающими, однозначными и следовать единому стандарту именования**.
6.2. Рекомендуемый формат имени секрета:
```
product-env-function-wbsecret
```
где:
- `product` — продукт или жомен;
- `env` — окружение (prod, stage, test);
- `function` — назначение секрета (db-password, api-token и т.п.).
## 7. Повторно используемые данные
7.1. При наличии повторяющихся значений в разных секретах такие данные рекомендуется выносить в отдельный секрет и использовать повторно через ссылки или шаблоны.
7.2. Дублирование идентичных секретных данных без необходимости не допускается.
## 8. Интеграция Vault с Kubernetes / Helm
8.1. Для использования секретов в Kubernetes рекомендуется применять механизм **Vault Agent Injection**.
8.2. Для корректного парсинга структуры «ключ–значение» в Helm-шаблонах рекомендуется использовать следующий подход:
```yaml
vault.hashicorp.com/agent-inject-secret-{{ $key }}: "{{ $value }}"
vault.hashicorp.com/agent-inject-template-{{ $key }}: |
{{`{{- with secret "`}}{{ $value }}{{`" -}}`}}
{{`{{ .Data.data | toJSON }}`}}
{{`{{- end }}`}}
vault.hashicorp.com/agent-inject-file-{{ $key }}: "{{ $key }}.json"
```
8.3. Результатом инжекта должен являться файл с корректным JSON-представлением данных секрета.
## 9. Ответственность и контроль
9.1. Ответственность за корректное хранение и использование секретов в Vault несут команды разработки и эксплуатации.
9.2. Контроль соблюдения настоящего регламента осуществляется командой информационной безопасности.
9.3. Нарушение требований регламента рассматривается как нарушение требований информационной безопасности.
Регламент по хранению данных в HashiCorp Vault.md Скачать