🛡️ Аудит безопасности — global-prod-main

Веб/ERP-сервер · OpenVPN · Portainer
Дата аудита: 2026-06-05
Хост: vm-evrotrans-yandex-global-1749891880453
ОС: Ubuntu 20.04 (cloud-init 24.4.1)
Платформа: Yandex Cloud (зона ru-central1)
Источник: ручной аудит из-под root (3.txt)
См. также: архитектура сервера · общая карта

1. Сводка (Executive Summary)

4
🔴 Высокая критичность
5
🟠 Средняя критичность
🟢 Настроено хорошо
КритичностьКол-воТемы
🔴 Высокая4NOPASSWD-sudo у orphan-аккаунта y4tsun0v, приватный SSH-ключ в дереве приложения, ключи OpenVPN CA на диске, открытый FTP (vsftpd)
🟠 Средняя5Переиспользование одного личного SSH-ключа, Zabbix/Acronis на всех интерфейсах, пароли без срока действия, незавершённый аудит SUID, массовый перебор SSH
🟢 Хорошо настроеноSSH: запрет root-логина, только ключи, AllowUsers, нестандартный порт; root-пароль заблокирован; нет пустых паролей; нет лишних UID 0
Главный вывод: базовая защита SSH настроена грамотно (вход только по ключу, root запрещён, нестандартный порт, белый список пользователей). Основные риски — не во входной двери, а внутри: orphan-аккаунт с беспарольным sudo, реальные приватные ключи, лежащие в каталоге приложения, и устаревший FTP-сервис.
Содержание
  1. Учётные записи пользователей
  2. SSH — конфигурация и доступ
  3. Приватные ключи и секреты на диске
  4. Запущенные сервисы
  5. Сетевые порты
  6. Активность входов
  7. Задачи по расписанию (cron)
  8. Незавершённые проверки
  9. Перечень обслуживаемых доменов
  10. План действий
  11. Что настроено хорошо

2. Учётные записи пользователей

2.1 Интерактивные пользователи (могут логиниться)

ПользовательUIDОболочкаПарольSSH-входsudoНазначение
root0/bin/bash🔒 заблокирован (L)❌ запрещён— (это root)Системный
y4tsun0v1000/bin/bash✅ задан (P)❌ нет в AllowUsers🔴 NOPASSWD:ALLПохоже на изначального владельца VM / orphan
r3ddan91001/bin/bash✅ задан (P)✅ разрешён✅ группа sudo (с паролем)Администратор (danil)
evrotrans1002/bin/bash✅ задан (P)✅ разрешён❌ нетСервисный/прикладной аккаунт
🔍 Доказательство — awk -F: '($3==0)' /etc/passwd
# awk -F: '($3==0){print $1}' /etc/passwd
root
# единственная учётка с UID 0 — скрытых суперпользователей нет
🔍 Доказательство — awk -F: '($2=="")' /etc/shadow
# sudo awk -F: '($2==""){print $1}' /etc/shadow
# вывод пуст — учётных записей с пустым паролем нет

2.2 Привилегии (sudo) — детально

Конфигурация даёт root тремя путями:

root            ALL=(ALL:ALL) ALL          # /etc/sudoers
%admin          ALL=(ALL) ALL              # группа admin — ПУСТАЯ
%sudo           ALL=(ALL:ALL) ALL          # группа sudo — только r3ddan9
y4tsun0v        ALL=(ALL) NOPASSWD:ALL     # /etc/sudoers.d/90-cloud-init-users
🔍 Доказательство — getent group sudo
# getent group sudo
sudo:x:27:r3ddan9
# в группе sudo (требует пароль) — только r3ddan9

# getent group admin
admin:x:
# группа admin пуста — членов нет
🔴 y4tsun0v имеет полный root БЕЗ пароля через cloud-init drop-in. При этом аккаунт не может зайти по SSH (нет в AllowUsers) — но любой, кто получит локальную сессию под этим пользователем (например, через su/cron/эксплойт сервиса), сразу станет root без запроса пароля.
🔍 Доказательство — cat /etc/sudoers.d/90-cloud-init-users
# sudo cat /etc/sudoers.d/90-cloud-init-users
y4tsun0v ALL=(ALL) NOPASSWD:ALL
# orphan-аккаунт получает полный root без запроса пароля

2.3 Политика паролей

PASS_MAX_DAYS   99999   # пароли НИКОГДА не истекают  ⚠️
PASS_MIN_DAYS   0
PASS_WARN_AGE   7
🟠 Пароли бессрочные. Для входа по SSH это не критично (парольная аутентификация отключена), но влияет на локальный вход / su / консоль.
🔍 Доказательство — grep '^PASS_' /etc/login.defs
# grep '^PASS_' /etc/login.defs
PASS_MAX_DAYS   99999
PASS_MIN_DAYS   0
PASS_WARN_AGE   7
# PASS_MAX_DAYS 99999 — пароли практически никогда не истекают

3. SSH — конфигурация и доступ

3.1 Настройки демона (sshd -T)

ПараметрЗначениеОценка
permitrootloginno
passwordauthenticationno✅ только ключи
pubkeyauthenticationyes
permitemptypasswordsno
allowusersr3ddan9 evrotrans✅ белый список
Порт (из ss)48008 (нестандартный)✅ снижает шум

Итог: конфигурация SSH соответствует лучшим практикам.

🔍 Доказательство — sshd -T + ss -tlpn
# sudo sshd -T | grep -Ei '^(permitrootlogin|passwordauthentication|pubkeyauthentication|permitemptypasswords|allowusers)'
permitrootlogin no
passwordauthentication no
pubkeyauthentication yes
permitemptypasswords no
allowusers r3ddan9 evrotrans

# ss -tlpn | grep sshd
LISTEN 0 128 0.0.0.0:48008 0.0.0.0:* users:(("sshd"...))
# только ключи, root запрещён, белый список, нестандартный порт 48008

3.2 Авторизованные ключи (authorized_keys)

ФайлКлючиКомментарий
/root/.ssh/authorized_keysdanil@IdeaPad-3-14ALC6⚠️ С форсированной командой-заглушкой (command="echo 'Please login as ...'") — реальный вход под root заблокирован. ✅ Хорошая практика.
/home/r3ddan9/.ssh/authorized_keysdanil@IdeaPad-3-14ALC6 (admin) + root@7cb276780667 (github actions)Личный ключ админа + CI-раннер
/home/y4tsun0v/.ssh/authorized_keysdanil@IdeaPad-3-14ALC6 («Added by Google»)Тот же личный ключ
/home/evrotrans/.ssh/authorized_keysdanil@IdeaPad-3-14ALC6 + root@7cb276780667Личный ключ + CI-раннер
🟠 Наблюдение: один и тот же личный ключ danil@IdeaPad-3-14ALC6 прописан во всех четырёх аккаунтах. Это означает, что один человек (danil) = root(заглушка)/r3ddan9/y4tsun0v/evrotrans. Компрометация одного приватного ключа на ноутбуке IdeaPad-3-14ALC6 даёт доступ ко всем учёткам сразу. Ключ root@7cb276780667 — это деплой-ключ GitHub Actions (CI/CD).
🔍 Доказательство — обход authorized_keys всех аккаунтов
# for u in root r3ddan9 y4tsun0v evrotrans; do echo "== $u =="; sudo cat /home/$u/.ssh/authorized_keys 2>/dev/null; done
== root ==
command="echo 'Please login as ...'" ssh-... danil@IdeaPad-3-14ALC6
== r3ddan9 ==
ssh-... danil@IdeaPad-3-14ALC6
ssh-... root@7cb276780667
== y4tsun0v ==
ssh-... danil@IdeaPad-3-14ALC6
== evrotrans ==
ssh-... danil@IdeaPad-3-14ALC6
ssh-... root@7cb276780667
# один личный ключ danil@IdeaPad-3-14ALC6 во всех 4 аккаунтах; у root — обезврежен командой-заглушкой; root@7cb276780667 = деплой-ключ GitHub Actions

4. Приватные ключи и секреты на диске

Подавляющее большинство найденного find-ом — это штатные файлы Let's Encrypt и тестовые фикстуры библиотек (ложные срабатывания). Ниже разделено на реальные риски и шум.

4.1 🔴 Реальные приватные ключи (требуют внимания)

ПутьЧто этоРиск
/home/evrotrans/stable/crontab/keys/id_rsaПриватный SSH-ключ внутри дерева приложения🔴 Используется, видимо, cron-задачами для деплоя/доступа. Лежит в каталоге приложения — рискует попасть в бэкап/архив/git/публикацию.
/home/evrotrans/stable/openvpn/config/web-ssl/ca.keyПриватный ключ центра сертификации OpenVPN🔴 Самый чувствительный файл VPN — позволяет выпускать любые клиентские сертификаты.
/home/evrotrans/stable/openvpn/config/web-ssl/server.keyПриватный ключ сервера OpenVPN🔴 Компрометация = MITM/имперсонация VPN-сервера.
/home/evrotrans/stable/portainer/data/portainer.keyКлюч TLS Portainer (управление Docker)🟠 Доступ к Portainer = контроль над контейнерами.
🔍 Доказательство — find … -name id_rsa -o -name '*.key'
# sudo find /home/evrotrans/stable -name id_rsa -o -name '*.key' 2>/dev/null
/home/evrotrans/stable/crontab/keys/id_rsa
/home/evrotrans/stable/openvpn/config/web-ssl/ca.key
/home/evrotrans/stable/openvpn/config/web-ssl/server.key
/home/evrotrans/stable/portainer/data/portainer.key
# реальные приватные ключи (SSH-деплой, CA и сервер OpenVPN, TLS Portainer) лежат в дереве приложения

4.2 🟢 Штатные сертификаты Let's Encrypt (certbot)

/home/evrotrans/stable/certbot/config/{live,archive,keys,csr}/... — сотни privkey*.pem, fullchain*.pem, cert*.pem, *_key-certbot.pem, *_csr-certbot.pem. Это нормальные TLS-сертификаты обслуживаемых доменов. Действие не требуется, но это раскрывает полный список доменов (см. §10).

5. Запущенные сервисы

systemctl — 37 активных юнитов. Значимые:

СервисНазначениеПримечание
ssh.serviceOpenSSHпорт 48008
docker.service / containerd.serviceDockerweb (80/443), OpenVPN (1194) — через docker-proxy
vsftpd.serviceFTP-сервер🔴 порт 48080, см. §6
zabbix-agent2.serviceМониторинг Zabbixпорт 10050 на всех интерфейсах
aakore / acronis_mms / acronis_schedule / active-protection / acp-update-controllerAcronis Cyber Protect (бэкап + антивирус)набор localhost-портов + grpm-sync на всех интерфейсах
google-guest-agent.serviceYandex Cloud гостевой агентуправляет SSH-ключами через метаданные проекта (см. «Added by Google»)
unattended-upgrades.serviceАвтообновления безопасности✅ хорошо
vsftpd, atd, cron, unscd, rsyslogбазовые демоны
⚠️ Важно про google-guest-agent: агент Yandex Cloud может автоматически добавлять SSH-ключи и пользователей из метаданных проекта/инстанса. Появление ключа «Added by Google» у y4tsun0v — его работа. Контроль над метаданными проекта в облаке = контроль над доступом к VM. Проверьте enable-oslogin / список ключей в метаданных в облачной консоли.

6. Сетевые порты (ss -tulpn)

6.1 Доступны извне (0.0.0.0 / * / [::])

ПортПротоколПроцессОценка
48008tcpsshd✅ SSH (ключи)
80tcpdocker-proxy🟢 HTTP (веб)
443tcpdocker-proxy🟢 HTTPS (веб)
1194tcp+udpdocker-proxy🟢 OpenVPN
48080tcpvsftpd🔴 FTP — открыт в интернет, протокол незашифрованный
10050tcp (*)zabbix_agent2🟠 Должен быть доступен только серверу Zabbix
40963tcp (*)grpm-sync-unit (Acronis)🟠 Слушает на всех интерфейсах
🔍 Доказательство — ss -tulpn
# ss -tulpn
tcp LISTEN 0.0.0.0:48008  users:(("sshd"...))
tcp LISTEN 0.0.0.0:80     users:(("docker-proxy"...))
tcp LISTEN 0.0.0.0:443    users:(("docker-proxy"...))
tcp LISTEN 0.0.0.0:1194   users:(("docker-proxy"...))
tcp LISTEN 0.0.0.0:48080  users:(("vsftpd"...))
tcp LISTEN *:10050        users:(("zabbix_agent2"...))
tcp LISTEN *:40963        users:(("grpm-sync-unit"...))
# на всех интерфейсах: SSH, web (docker-proxy), OpenVPN, FTP, Zabbix, Acronis grpm-sync

6.2 Только localhost (127.0.0.1 / ::1) — ✅ безопасно

53 (systemd-resolved), 24100-24102/43234/9850 (Acronis mms), 9772 (adp-agent), 41421 (task-manager), 9775 (acp-update), 39611 (aakore), 6109 (active-protection).

🔴 FTP (vsftpd, 48080): передаёт логины/пароли и данные открытым текстом. Если он не нужен — отключить. Если нужен — заменить на SFTP/FTPS и ограничить firewall'ом.

🟠 Zabbix (10050) и Acronis grpm-sync (40963) слушают * — закрыть firewall'ом/security-group, оставив доступ только с IP сервера мониторинга/Acronis.
🔍 Доказательство — ss -tlpn | grep 48080
# ss -tlpn | grep 48080
LISTEN 0 32 0.0.0.0:48080 0.0.0.0:* users:(("vsftpd"...))
# FTP открыт на 0.0.0.0 (в интернет), протокол незашифрованный

7. Активность входов

7.1 Текущие/недавние сессии (who, last)

7.2 Неудачные входы (lastb) — массовый перебор

🟠 Сотни неудачных SSH-попыток (со 2 июня 2026) с ботнет-адресов: 77.83.39.0/24, 130.12.181.0/24, 45.144.212.54 — перебор имён (huawei, student2, wildfly, ftpu, admin, user...).

Это фоновый интернет-шум. Поскольку парольная аутентификация отключена и есть AllowUsers, эти попытки обречены на провал. Тем не менее рекомендуется fail2ban/sshguard для снижения нагрузки и объёма логов.
🔍 Доказательство — lastb | head
# sudo lastb | head
huawei   ssh:notty   77.83.39.x      ...
admin    ssh:notty   130.12.181.x    ...
user     ssh:notty   45.144.212.54   ...
# массовый перебор имён с ботнет-подсетей; обречён — парольный вход отключён

8. Задачи по расписанию (cron)

⚠️ При этом в /home/evrotrans/stable/crontab/keys/id_rsa лежит ключ — значит, расписание, вероятно, реализовано внутри Docker-контейнера или через systemd timer, а не через системный cron. Стоит проверить отдельно (systemctl list-timers, cron внутри контейнеров).
🔍 Доказательство — cat /etc/crontab + crontab -l
# cat /etc/crontab
# только штатные системные задачи (apt, logrotate, man-db, popularity-contest)

# for u in root r3ddan9 evrotrans; do crontab -l -u $u; done
no crontab for root
no crontab for r3ddan9
no crontab for evrotrans
# системный cron чист, персональных нет — но есть .../crontab/keys/id_rsa: расписание внутри Docker-контейнера

9. Незавершённые проверки (требуют повторного прогона)

ПроверкаЧто случилосьКоманда для повтора
SUID/SGID-бинарникиВывод find / -perm -4000 оказался пустым (4 пустые строки). Это аномалия — обычно есть sudo, su, passwd, mount и др. Вероятно команда не отработала.sudo find / -xdev \( -perm -4000 -o -perm -2000 \) -type f -exec ls -la {} \; 2>/dev/null
Облачные credentials.aws/.azure/.config/gcloud не найдены — это норма (их нет).
Секреты в env/etc/environment, /etc/profile.d/ — чисто. Но секреты приложения почти наверняка в .env/docker-compose контейнеров.sudo find /home/evrotrans/stable -maxdepth 3 -name '.env' -o -name 'docker-compose*.yml' 2>/dev/null
Содержимое контейнеровDocker запущен (web, OpenVPN, Portainer), но контейнеры не аудировались.sudo docker ps, sudo docker inspect, проверка .env в каждом проекте
🔍 Доказательство — find / -perm -4000 -type f
# sudo find / -perm -4000 -type f 2>/dev/null




# 4 пустые строки вместо ожидаемых sudo/su/passwd/mount — аномалия, проверку повторить

10. Перечень обслуживаемых доменов (из certbot)

Из путей certbot/config/archive/ видно, что сервер (или его reverse-proxy) обслуживает домены *.evrotrans.net:

evrotrans.net, www, api, api3, sales, doz, pma, pma1, ptr, erp, erp2, erp3,
old, mde, test, p, v3, vpn, wld, partnerstickets, sakai3, monofront3,
плюс wildcard wildcard.evrotrans.net
🔍 Доказательство — ls certbot/config/archive/
# ls /home/evrotrans/stable/certbot/config/archive/
evrotrans.net  www  api  api3  sales  erp  erp2  erp3
pma  pma1  ptr  mde  doz  test  p  vpn  partnerstickets
... wildcard.evrotrans.net
# каталоги certbot раскрывают полный список обслуживаемых поддоменов (карта поверхности атаки)

Это карта поверхности атаки веб-уровня (поддомены ERP, API, phpMyAdmin pma, VPN, test).

⚠️ Поддомены pma/pma1 (phpMyAdmin) и test — частые цели атак; убедитесь, что они закрыты доступом по IP/авторизацией.

11. План действий (приоритизированный)

🔴 Высокий приоритет (сделать в первую очередь)

  1. Разобраться с y4tsun0v: если аккаунт не используется — удалить (userdel) или как минимум убрать NOPASSWD:ALL из /etc/sudoers.d/90-cloud-init-users. Это orphan от первичной настройки VM.
  2. Убрать приватный ключ из дерева приложения: перенести /home/evrotrans/stable/crontab/keys/id_rsa за пределы публикуемого/бэкапируемого каталога, выставить chmod 600, убедиться, что он не попадает в git/архивы. Рассмотреть ротацию ключа.
  3. Защитить ключи OpenVPN: ca.key/server.key — проверить права (600, владелец root/контейнер), убедиться, что каталог не доступен по web. ca.key в идеале хранить offline.
  4. Закрыть/заменить FTP (vsftpd, 48080): отключить, если не используется (systemctl disable --now vsftpd); иначе перейти на SFTP/FTPS + firewall.

🟠 Средний приоритет

  1. Firewall на сервисные порты: ограничить 10050 (Zabbix) и 40963 (Acronis) доступом только с доверенных IP. Использовать облачные security-groups + локальный ufw/nftables.
  2. Установить fail2ban для гашения SSH-перебора и роста логов.
  3. Проверить метаданные Yandex Cloud (SSH-ключи проекта/инстанса, OS Login) — это альтернативный канал доступа в обход authorized_keys.
  4. Политика паролей: задать PASS_MAX_DAYS (напр. 365) для интерактивных аккаунтов.
  5. Разделить переиспользуемый ключ: по возможности завести отдельные ключи на каждого администратора/каждую роль вместо одного danil@IdeaPad.

🟢 Дополнительно

  1. Повторить аудит SUID/SGID (см. §9) — текущий результат недостоверен.
  2. Проаудировать Docker-контейнеры: docker ps, секреты в .env/compose, привилегированные контейнеры, проброс сокета Docker.
  3. Проверить systemd timers и cron внутри контейнеров (системный cron пуст, но расписание где-то есть).
  4. Закрыть/ограничить доступ к pma* (phpMyAdmin) и test поддоменам.

12. Что настроено хорошо (сохранить)