MAATRIX / Блог / Как оформить доступ сотрудников к продакшену

Как оформить доступ сотрудников к продакшену

MAATRIX

Команда выросла с трёх человек до пятнадцати, а доступ к продакшену всё ещё выдаётся так же, как в первый месяц — общий root-пароль в чате или один SSH-ключ, который скопировали всем при найме. Работает, пока не увольняется человек, у которого этот ключ был, или пока кто-то не удаляет продакшн-таблицу, потому что зашёл туда «просто посмотреть логи» с правами администратора. Ниже — рабочая методика доступа для штатных сотрудников: как разграничить права по ролям, какими техническими средствами это делается и как закрыть доступ в день увольнения, а не через полгода.

Принцип наименьших привилегий на практике

Принцип наименьших привилегий (principle of least privilege) звучит просто: у каждого сотрудника должен быть доступ ровно к тому, что нужно для его задач, и ни битом больше. На практике его почти всегда нарушают в одну сторону — выдают доступ «с запасом», потому что так проще закрыть вопрос сейчас. Через год у половины команды есть root на продакшн-сервер, хотя реально им пользуются два человека.

Правильная последовательность обратная: сначала описываете роль и задачи, потом — минимальный набор прав под эти задачи, и только потом заводите аккаунт с этим набором. Если через месяц прав не хватает — их добавляют точечно, а не выдают «на всякий случай» заранее. Это дороже в моменте выдачи доступа, но многократно дешевле, когда нужно разобраться, кто мог удалить файл или почему в базе изменились данные.

Ключевой вывод: доступ привязывается не к человеку и не к должности вообще, а к конкретной роли и системе. Разработчик Иван с фронтенда и разработчица Мария с биллинга могут иметь разный набор прав, даже если оба называются «разработчик», — потому что им нужны разные части инфраструктуры.

Ролевая матрица: кому что нужно на самом деле

Прежде чем что-то настраивать технически, полезно свести роли и права в таблицу — она же потом становится основой для аудита.

РольПродакшн-серверыПродакшн-БДStagingЛоги приложенияОсобенности
Разработчикнетнетда, полныйда, чтениедоступ к БД — через staging-копию или анонимизированный дамп
DevOps/SREда, полныйда, полныйдадавсе действия логируются и хранятся отдельно от исполнителя
Тимлид/техлидда, ограниченный (свой сервис)да, чтениедадаможет эскалировать до DevOps-доступа временно, с фиксацией причины
Финансы/аналитиканетнет (только read-only представления)нетнетдоступ к данным, не к инфраструктуре
Саппортнетнет (панель поддержки)нетда, чтение по своему продуктудоступ через внутренний тул, не напрямую

Для разработчиков ключевое ограничение — никакого прямого доступа к продакшн-базе данных. Это не недоверие к людям, а снижение количества точек, откуда может произойти случайная порча данных: чем меньше человек умеет выполнять DELETE FROM на боевой таблице, тем меньше шанс, что кто-то сделает это по ошибке в пятницу вечером. Если разработчику нужны реальные данные для отладки — заводится анонимизированный дамп на staging или доступ через read-реплику с отдельным ограниченным пользователем БД.

DevOps/SRE — противоположный случай: этим людям физически нужен широкий доступ к инфраструктуре, включая продакшн, потому что это их работа. Компенсация за широкие права — обязательное и неотключаемое логирование каждого действия. Широкий доступ без логирования — то же самое, что общий root-пароль, просто на одного человека вместо всех.

Финансовый и аналитический персонал — отдельная категория, которую часто решают неправильно: заводят человеку доступ к серверу «чтобы он сам выгрузил данные», хотя ему нужны не серверы, а конкретные цифры. Правильное решение — подготовленные read-only представления данных (материализованные вьюхи, отдельная аналитическая БД, дашборд), а не доступ к инфраструктуре вообще.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Именные аккаунты и группы Linux вместо общего логина

Первое правило, без которого вся остальная схема не работает: у каждого сотрудника — свой именной аккаунт. Не admin, не deploy, не общий root на всех — а ivan.petrov, maria.sidorova, каждый со своим паролем/ключом. Без этого невозможен аудит: в логах будет просто «admin что-то сделал», а кто именно — придётся вспоминать по памяти или спрашивать в чате.

Создание пользователя и распределение по ролевым группам:

# создаём группы под роли
groupadd devs
groupadd devops
groupadd finance-readonly

# заводим именной аккаунт разработчика
useradd -m -s /bin/bash -G devs ivan.petrov
passwd -l ivan.petrov          # блокируем вход по паролю
mkdir -p /home/ivan.petrov/.ssh
cp /tmp/ivan_id_ed25519.pub /home/ivan.petrov/.ssh/authorized_keys
chown -R ivan.petrov:ivan.petrov /home/ivan.petrov/.ssh
chmod 700 /home/ivan.petrov/.ssh
chmod 600 /home/ivan.petrov/.ssh/authorized_keys

Дальше — ограниченный sudo вместо полного root. В /etc/sudoers.d/ заводится отдельный файл на каждую роль (не правьте общий /etc/sudoers напрямую — используйте visudo -f):

# /etc/sudoers.d/devs-app-restart
%devs ALL=(root) NOPASSWD: /usr/bin/systemctl restart myapp
%devs ALL=(root) NOPASSWD: /usr/bin/systemctl status myapp
%devs ALL=(root) NOPASSWD: /usr/bin/journalctl -u myapp --since "1 hour ago"

Это даёт разработчику возможность перезапустить свой сервис и посмотреть логи, но не даёт прав на что-либо ещё — ни на файлы других сервисов, ни на сетевые настройки, ни тем более на базу данных. Для DevOps/SRE группа шире, но всё равно перечисляется явно, а не через ALL=(ALL) ALL:

# /etc/sudoers.d/devops-full
%devops ALL=(ALL) ALL
Defaults:%devops log_output
Defaults:%devops logfile=/var/log/sudo-devops.log

Директива log_output (модуль sudoers_io в современном sudo) пишет не только факт запуска команды, но и весь вывод сессии — это и есть базовое логирование действий DevOps, о котором говорилось выше. Логи стоит сразу форвардить на отдельный сервер логирования, чтобы человек с root-доступом физически не мог их подчистить на том же сервере, где работал.

Bastion-хост: одна точка входа вместо прямого SSH на продакшн

Второй технический слой — центральная точка входа. Вместо того чтобы у каждого продакшн-сервера был открыт 22-й порт наружу, все SSH-подключения идут через один bastion-хост (он же jump-host), а с него — дальше во внутреннюю сеть. Это даёт три вещи сразу: единую точку логирования всех подключений, возможность мгновенно отозвать доступ одному человеку без пересборки всей инфраструктуры, и меньшую площадь атаки — внутренние серверы просто не видны из интернета.

На bastion-хосте у каждого сотрудника — свой аккаунт и свой ключ, как описано выше. На стороне клиента доступ настраивается через ~/.ssh/config, чтобы не превращать каждое подключение в две команды:

Host bastion
    HostName bastion.example.com
    User ivan.petrov
    IdentityFile ~/.ssh/id_ed25519_work
    IdentitiesOnly yes

Host prod-app-01
    HostName 10.20.0.11
    User ivan.petrov
    ProxyJump bastion
    IdentityFile ~/.ssh/id_ed25519_work

Дальше — ssh prod-app-01, и SSH сам прогоняет соединение через bastion прозрачно. На самом bastion-хосте полезно явно ограничить, кто вообще может через него проходить дальше, и включить подробное логирование:

# /etc/ssh/sshd_config на bastion
AllowUsers ivan.petrov maria.sidorova devops-*
LogLevel VERBOSE
PermitTunnel no
X11Forwarding no
AllowTcpForwarding local

LogLevel VERBOSE добавляет в логи отпечаток ключа, которым подключился пользователь, — это позволяет ответить на вопрос «кто заходил вчера в 23:40», не полагаясь на честность записи в общей таблице доступов. Если нужна ещё и запись самих сессий (что именно вводил человек в терминале), на bastion можно поставить auditd с правилами на execve, либо использовать готовые инструменты session recording (Teleport, Boundary) — они не бесплатны по объёму внедрения, но снимают вопрос «а что именно он там делал» без ручного разбора логов.

Ключевая практическая ошибка — заводить один общий ключ для bastion «чтобы не возиться с каждым сотрудником». Это возвращает к тому же общему логину, только узким местом становится не продакшн-сервер, а bastion. Личный ключ на человека — обязательное условие, без него аудит теряет смысл: логи покажут вход, но не покажут, кто именно.

Read-only доступ для финансов и аналитики без доступа к инфраструктуре

Финансовому и аналитическому персоналу почти никогда не нужен сервер — им нужны цифры: выручка, конверсии, использование ресурсов по клиентам. Выдавать таким сотрудникам SSH-доступ или логин в панель управления сервером — это доступ, который не решает их задачу, но добавляет ещё одну точку, которую нужно защищать и отзывать.

Правильная схема — отдельная read-only роль в базе данных, у которой физически нет прав на запись и нет доступа к таблицам, не относящимся к её задаче:

-- отдельная роль только на чтение
CREATE ROLE analytics_ro WITH LOGIN PASSWORD 'сгенерированный-пароль';
GRANT CONNECT ON DATABASE prod TO analytics_ro;
GRANT USAGE ON SCHEMA analytics_views TO analytics_ro;
GRANT SELECT ON ALL TABLES IN SCHEMA analytics_views TO analytics_ro;

-- явно закрываем всё остальное
REVOKE ALL ON SCHEMA public FROM analytics_ro;

Схема analytics_views — это отдельный набор представлений (view), подготовленных под задачи аналитики, а не прямой доступ к боевым таблицам приложения. Такой слой решает две проблемы разом: аналитик не может случайно нагрузить продакшн тяжёлым запросом без LIMIT, и структура боевых таблиц может меняться без необходимости предупреждать всех, кто строит отчёты — представления остаются стабильными.

Ещё лучше — если аналитика вообще не подключается к базе напрямую, а смотрит данные через BI-инструмент (Metabase, Redash, Superset), подключённый к read-реплике. В этом случае сотруднику выдаётся логин в само приложение, а не сетевой доступ к серверу базы данных вообще — область, которую можно скомпрометировать, ещё меньше.

Оффбординг: чек-лист отзыва доступа в день увольнения

Самая частая практическая проблема — не в том, что доступ выдают неправильно, а в том, что его забывают отозвать. Сотрудник уволился в понедельник, а его SSH-ключ на bastion-хосте, VPN-конфиг и логин в панели хостинга остаются рабочими ещё полгода, просто потому что об этом никто не вспомнил. Это не гипотетический риск — это типовая находка на любом аудите доступов в компании, которая растёт быстрее, чем успевает наводить порядок в процессах.

Решение — не «постараться не забыть», а чек-лист, который проходят в день увольнения или смены роли, без исключений:

  • SSH-ключи: удалить публичный ключ из authorized_keys на bastion-хосте и на всех серверах, куда он мог быть скопирован напрямую в обход bastion.
  • Linux-аккаунт: заблокировать или удалить учётку (usermod -L ivan.petrov для немедленной блокировки, userdel -r ivan.petrov при полном увольнении), убить активные сессии (pkill -u ivan.petrov).
  • VPN: удалить peer из WireGuard (wg set wg0 peer <публичный-ключ> remove) или отозвать сертификат в OpenVPN (easyrsa revoke ivan.petrov и пересборка CRL).
  • Панели управления: снять доступ в панели хостинга/облака (учётка в панели провайдера, панель мониторинга, панель CI/CD).
  • Облачные сервисы: отозвать доступ в IAM (например aws iam delete-login-profile, отвязка политик, удаление access key), выйти из организации на GitHub/GitLab, деактивировать в Google Workspace/Slack.
  • Базы данных: REVOKE ALL PRIVILEGES ... FROM ivan_petrov; DROP ROLE ivan_petrov; — если роль привязана к личным правам, а не к общей сервисной учётке.
  • Общие секреты: если человек имел доступ к общему хранилищу паролей (Vault, 1Password, Bitwarden) — не только убрать его оттуда, но и оценить, какие пароли стоит сменить, если они не были персональными для каждого.

На практике проще всего держать этот список не в голове, а в виде реального чек-листа (таск в трекере, шаблон в вики), который открывается при увольнении и закрывается только после того, как каждый пункт отмечен. Это тот случай, где формальность буквально экономит деньги — забытый доступ бывшего сотрудника не создаёт проблем в 99% случаев, но именно в оставшемся 1% это дорого обходится.

Учёт доступов без сложных систем — для маленькой команды

Bastion-хост, роли в Linux и read-only представления в БД — это правильная цель, но если в команде пять человек, разворачивать Teleport или писать Terraform под IAM-роли часто избыточно на старте. Минимально работающий вариант, который лучше, чем вообще никакого учёта — простая таблица, которую ведёт один ответственный человек:

СотрудникРольСистемы с доступомДата выдачиДата отзыва
Иван ПетровРазработчикstaging SSH, GitHub repo2026-01-15
Мария СидороваDevOpsbastion, prod SSH, AWS IAM2025-11-02
Олег СмирновАналитикMetabase read-only2026-03-10

Такая таблица не заменяет техническую реализацию наименьших привилегий, но решает главную проблему на старте — у компании появляется единый список того, кто и к чему имеет доступ, который можно открыть и свериться с реальностью раз в квартал. Если инфраструктура арендована на внешнем сервере (VPS или выделенный сервер), тот же принцип работает и там: bastion можно поднять на отдельной небольшой машине, не смешивая точку входа с боевыми серверами приложения.

Похожая логика разбирается в статье про то, как раздать доступ команде без выдачи root — там больше деталей именно про sudo и группы для небольшой команды. Если нужен инструмент для быстрой раздачи VPN-доступа с индивидуальными ключами и мгновенным отзывом, без ручной возни с WireGuard-конфигами, стоит посмотреть на Outline Manager. А чтобы закрыть вопрос «кто и когда подключался» на уровне VPN отдельно от SSH-логов, пригодится схема из статьи про аудит доступов VPN.

Стоит отдельно отметить: вся эта методика написана про штатных сотрудников — тех, кто работает в компании постоянно и по мере роста команды получает новые роли. Со временными подрядчиками и фрилансерами логика доступа немного другая — там обычно короче срок жизни доступа и жёстче ограничение по объёму задачи с самого начала, а не расширение прав со временем; если нанимаете внешнего исполнителя под разовую задачу, будет полезна статья о том, как составить ТЗ на настройку сервера для фрилансера — там разбирается похожий вопрос, но с обратной стороны, до того как доступ вообще выдан.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

С чего начать, если сейчас у всех root и общий пароль?

Не пытайтесь переделать всё за один день. Сначала заведите именные аккаунты всем, кто сейчас пользуется общим доступом, параллельно со старым доступом. Убедитесь, что все перешли на личные ключи и всё работает. Только после этого отключайте общий пароль/ключ — иначе рискуете разом обрубить доступ всей команде посреди рабочего дня.

Нужен ли bastion-хост, если сервер всего один?

Если инфраструктура — это один сервер, отдельный bastion избыточен: важнее сами именные аккаунты, ограниченный sudo и логирование. Bastion становится оправданным, когда серверов несколько и нужна единая точка входа и аудита.

Как быть, если DevOps-инженер должен видеть вообще всё?

Широкий доступ — нормальная часть роли DevOps/SRE, проблема не в объёме прав, а в отсутствии логирования этого доступа. Компенсируйте широту прав обязательной записью сессий (sudo с log_output, аудит на bastion) и хранением логов отдельно от машины, на которой работал сотрудник.

Что делать с доступом, который выдали «временно» полгода назад и забыли?

Это типовая находка при первом аудите. Решение системное — не разовая чистка, а плановая ревизия доступов (раз в квартал сверка таблицы или ролей с реальным составом команды), а не полагаться на то, что кто-то вспомнит вручную.

Можно ли обойтись без sudoers-файлов, просто добавив нужных людей в группу sudo целиком?

Технически можно, но это снова полный root по факту — группа sudo/wheel без ограничений даёт те же права, что и общий root-пароль, только через личный логин. Смысл ограниченных sudoers.d-файлов именно в том, чтобы разрешить конкретные команды, а не всё подряд.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →