SSD Nodes Learn 🎉 VPS від $5.50/міс
Посібники Matt ConnorВід Matt Connor · Оновлено 2026-08-13

Що робити, якщо ваш VPS зламали

Не очищайте зламаний VPS: ізолюйте його у firewall провайдера, створіть snapshot диска як доказ, замініть усі ключі та розгорніть сервер із чистого образу.

Не очищайте зламаний VPS

Якщо ваш VPS зламано, найважливіше рішення потрібно прийняти до виконання будь-якої команди. Не намагайтеся очистити сервер. Ізолюйте його на стороні провайдера, створіть snapshot диска як доказ, замініть усі облікові дані, які зберігалися на цьому сервері, а потім розгорніть систему заново на чистому сервері з надійних джерел.

Неможливо довести, що rootkit видалено, оскільки інструменти, які могли б це підтвердити, контролює зловмисник.

Це основний аргумент. Нижче наведено механізм. Зловмисник, який отримав root, може замінити ps так, щоб один ідентифікатор процесу ніколи не відображався в його виведенні. Один рядок у /etc/ld.so.preload завантажує код зловмисника в кожну програму на сервері, пов’язану динамічно, тому ls, ss і find однаково приховують правду. Завантажуваний kernel module може приховувати файли на рівні системного виклику, тому навіть щойно завантажений бінарний файл бачить чистий диск. Ви видаляєте майнер, графік використання CPU знижується, і сервер перестає подавати ознаки активності. Відсутність активності також може бути ознакою справного backdoor.

Перевстановлення коштує менше, ніж здається. Типовий VPS — це кілька пакетів, один каталог конфігурації та один набір даних, тому перевстановлення є кінцевим завданням із чітким завершенням. Пошук усіх змін, внесених зловмисником, не має визначеного кінця й ніколи не дає доказів.

Підтвердьте, що справді сталося порушення безпеки

Багато серверів, про злам яких повідомляють, насправді не скомпрометовані. Тисячі невдалих входів через SSH на день — це фоновий шум інтернету, оскільки кожну публічну IPv4-адресу постійно сканують. Вивід lastb, заповнений спробами root і admin, означає, що сканери виявили ваш порт. Це не означає, що хтось отримав доступ.

Ці ознаки справді щось означають:

  • Успішний вхід, якому ви не можете знайти пояснення, наприклад Accepted password for root from 203.0.113.7.
  • Ключ у authorized_keys, якого ви не додавали.
  • Повідомлення від вашого хостинг-провайдера про зловживання через трафік, що виходить із вашого сервера.
  • Процес зі 100% використанням CPU, назва якого скопійована з назви потоку ядра. Майнерів, розміщених через відкриті сокети Redis і Docker, часто виявляють під такими назвами, як kdevtmpfsi і kinsing.
  • Вихідні з’єднання з адресами, які не використовує жоден із ваших сервісів.

Маскування під потік ядра можна швидко перевірити. Справжні потоки ядра відображаються у квадратних дужках і не мають виконуваного файла, тому для них sudo ls -l /proc/<pid>/exe завершується помилкою No such file or directory. Якщо процес із назвою [kworker/0:2] має посилання exe, яке вказує на об’єкт у /tmp, це звичайна програма користувача, що використовує назву потоку ядра.

Виконуйте ці перевірки з урахуванням того, що система може вводити вас в оману. Їх достатньо, щоб визначити, що щось не так. Але їх недостатньо, щоб визначити, що все гаразд.

Ізолюйте мережу на стороні провайдера, а не з самого сервера

Ізоляція має бути першим кроком, оскільки всі наступні дії марні, доки хтось інший ще має доступ до shell. Читання журналів, ротація ключів і відновлення даних не мають сенсу, якщо зловмисник усе ще спостерігає за системою.

Виконайте це в панелі керування провайдера, у мережевому firewall, який працює за межами операційної системи. Заблокуйте вхідний і вихідний трафік, а web console залиште способом доступу до сервера. Правила, застосовані на цьому рівні, зберігають чинність незалежно від того, що відбувається на диску.

Є дві причини не робити цього з самого сервера. Firewall, налаштований усередині скомпрометованого kernel, застосовується цим kernel, а root може очистити nftables так само легко, як і ви можете його налаштувати. Крім того, sudo ip link set enp1s0 down через SSH спочатку розриває ваш власний сеанс і блокує доступ до сервера, який ви саме перевіряли.

Заблокуйте як вихідний, так і вхідний трафік. Reverse shell встановлює вихідне з’єднання із сервера до зловмисника, тому блокування лише вхідного трафіку залишає вже встановлене з’єднання повністю працездатним. Якщо провайдер підтримує лише правила для вхідного трафіку, залишаються два варіанти: від’єднати мережевий інтерфейс або вимкнути instance.

Поки що не перезавантажуйте сервер. Спочатку перевірте, чи існує /var/log/journal. Якщо цього каталогу немає, journald записує дані до /run/log/journal, який зберігається в пам’яті, тому перезавантаження видалить записи про вторгнення. Під час перезавантаження також зникають запущені процеси, а їхні командні рядки часто є найчіткішим доказом, який ви матимете.

Створіть snapshot диска, перш ніж щось змінювати

У цьому випадку snapshot і backup виконують різні завдання. Snapshot, який ви створите зараз, є копією скомпрометованого диска. Це ваш доказ і єдиний спосіб повернутися до попереднього стану, якщо ви випадково щось перезапишете. Старі backup — це шлях до відновлення. Якщо в панелі вашого провайдера ці два терміни використовуються без чіткого розмежування, спочатку прочитайте чим snapshot VPS відрізняється від справжнього backup, оскільки правила зберігання та поведінка під час відновлення відрізняються.

Створіть snapshot у панелі провайдера, перш ніж знову входити в систему. Snapshot запущеної системи є crash-consistent: він фіксує стан диска в конкретний момент, так само як у разі вимкнення живлення. Для збору доказів цього достатньо. Назвіть його так, щоб ніхто випадково не відновив цей snapshot. Просте ім’я на кшталт COMPROMISED-do-not-restore-2026-08-12 — саме те, що потрібно. Зберігайте його, доки не завершите розслідування та не буде закрито будь-який abuse ticket у вашого хостинг-провайдера.

Як отримати доступ, якщо SSH більше не працює

Є два варіанти, і обидва доступні в панелі провайдера. Вебконсоль (VNC або serial) під’єднується до машини так, ніби ви підключили клавіатуру безпосередньо. Вона працює, коли sshd не запущений, firewall налаштовано неправильно або зловмисник змінив порт SSH. Вебконсоль автентифікує користувача за локальним паролем, тому на сервері, де дозволено вхід лише за ключем, спочатку може знадобитися скинути пароль root.

Rescue mode — кращий варіант. Він запускає невелику live-систему, до якої під’єднано ваш диск, але його система не запущена. Тому команди виконуються в надійному середовищі: скомпрометовані kernel і binaries не працюють. Підключіть диск у режимі лише для читання.

lsblk -f
sudo mkdir -p /mnt/victim
sudo mount -o ro /dev/vda1 /mnt/victim

Якщо lsblk показує томи LVM (logical volume manager), а не звичайний розділ, спочатку активуйте їх за допомогою sudo vgchange -ay, а потім змонтуйте пристрій, який з’явиться в /dev/mapper/.

Не виконуйте chroot для змонтованого диска, щоб переглянути його вміст. chroot запускає binaries зловмисника з вашими правами, що зводить нанівець саму мету запуску rescue mode.

Зберіть дані, яким іще можна довіряти

Виконайте ці команди з rescue mode, підключивши диск лише для читання до /mnt/victim. Почніть із входів у систему, оскільки вони допомагають визначити час вторгнення. Після цього всі інші дії буде легше прив’язати до часового проміжку.

sudo grep -aE 'Accepted (password|publickey)' /mnt/victim/var/log/auth.log
sudo last -f /mnt/victim/var/log/wtmp
sudo lastb -f /mnt/victim/var/log/btmp
sudo journalctl -D /mnt/victim/var/log/journal -u ssh --since "2026-07-01"

Відсутність /var/log/auth.log сама по собі не є підозрілою. Деякі сучасні образи Ubuntu постачаються без rsyslog, тому sshd записує журнали лише до journal. Саме це читає рядок journalctl -D. Варто звернути увагу на розрив у безперервних журналах або на файл журналу, усічений до нульового розміру. Знищення журналів трапляється часто й зазвичай виконується недбало.

Далі перевірте облікові записи та ключі.

sudo find /mnt/victim/root /mnt/victim/home -name 'authorized_keys*' -exec ls -l {} +
sudo awk -F: '$3 == 0 {print $1}' /mnt/victim/etc/passwd
sudo lsattr /mnt/victim/root/.ssh/authorized_keys

Рядок awk виводить усі облікові записи з ідентифікатором користувача 0. Будь-яке значення, відмінне від root, у цьому виводі означає наявність другого root-облікового запису. Шаблон find навмисно також відповідає authorized_keys2, оскільки OpenSSH типово читає обидва імені файлів, а друге легко не помітити. Якщо lsattr виводить i у списку атрибутів, файл є незмінним: зловмисник встановлює цей прапорець, щоб ваша спроба видалити його ключ завершилася з Operation not permitted, а втомлений адміністратор вирішив, що зміни застосовано.

Механізми закріплення зазвичай приховані в невеликій кількості місць, тому перевірте їх усі.

sudo ls -lt /mnt/victim/etc/systemd/system
sudo ls -l /mnt/victim/etc/cron.d /mnt/victim/var/spool/cron/crontabs
sudo cat /mnt/victim/etc/ld.so.preload
sudo grep -rnE 'curl|wget|base64|/dev/tcp' /mnt/victim/etc/update-motd.d /mnt/victim/etc/rc.local /mnt/victim/root/.bashrc /mnt/victim/root/.profile

/etc/ld.so.preload не існує у звичайній системі Ubuntu або Debian, тому No such file or directory є штатним результатом, а будь-який вміст потребує вашої уваги. Файл входу, який передає вивід base64 -d до shell, має ту саму ознаку: легітимній конфігурації не потрібно приховувати власний текст.

Побудуйте часову шкалу за часом зміни, а не за часом модифікації.

sudo find /mnt/victim -xdev -newerct '2026-08-01' -type f -printf '%TF %TT %p\n' | sort

touch дає змогу зловмиснику встановити час модифікації будь-яким значенням, тому mtime легко підробити. Час зміни (ctime) оновлюється за будь-якої зміни inode, а touch не може перемістити його назад. Тому -newerct дає достовірніший список того, що було нещодавно записано. Це все одно не є доказом, оскільки root може змінити системний годинник або безпосередньо записати дані на block device.

Перевірка цілісності пакетів потребує однієї команди та одного застереження. У запущеній системі sudo dpkg --verify виводить рядок для кожного файлу пакета, контрольна сума якого більше не збігається, із 5 у стовпці контрольної суми. sudo debsums -ac виконує те саме завдання, включно з файлами конфігурації, якщо встановлено пакет debsums. Інтерпретуйте результат лише в одному напрямку. Змінений /usr/sbin/sshd є реальним доказом. Чистий звіт нічого не доводить, оскільки той самий root-обліковий запис, який замінив бінарний файл, може переписати списки контрольних сум у /var/lib/dpkg/info/. Сканери rootkit, як-от rkhunter і chkrootkit, працюють за тим самим правилом: знайдений об’єкт є інформацією, а чистий результат не означає відсутності компрометації.

Скопіюйте зібрані дані з машини, перш ніж виконувати будь-які руйнівні дії.

sudo tar --ignore-failed-read -C /mnt/victim -czf /root/evidence-2026-08-12.tgz \
  var/log etc root/.ssh root/.bash_history home
sha256sum /root/evidence-2026-08-12.tgz

Запишіть цей хеш десь поза сервером. Якщо справа дійде до страхового позову або заяви в поліцію, можливість довести, що архів не змінювався після збору, відрізняє доказ від простої папки з файлами. Випадкове видалення даних під час розслідування є звичайною ситуацією. Саме snapshot і цей архів дають змогу пережити таку помилку. Виправити наслідки невдалого rm згодом набагато складніше, ніж зазвичай очікують, як пояснено в матеріалі відновлення файлів, видалених за допомогою rm -rf.

Знайдіть шлях проникнення

Якщо під час відновлення не закрити шлях проникнення, сервер знову буде зламано, часто протягом кількох днів, оскільки сканування, під час якого його виявили вперше, не припиняється. На більшість компрометацій окремих серверів припадають чотири шляхи.

Автентифікація SSH за паролем. Рядок Accepted password for root з адресою, якої ви не впізнаєте, сам по собі є доказом. Перевірте PasswordAuthentication у /etc/ssh/sshd_config і в кожному файлі в /etc/ssh/sshd_config.d/. sshd використовує перше отримане значення ключового слова, а рядок Include розташований на початку основного файлу в Ubuntu. Тому конфігураційний файл, доданий до каталогу, непомітно має пріоритет над параметром, який ви змінили нижче.

Сервіс, опублікований без автентифікації. Redis на 6379, Docker API на 2375, база даних, прив’язана до 0.0.0.0 замість 127.0.0.1. Docker часто стає несподіваною причиною. Публікація порту контейнера додає правила DNAT (трансляції мережевих адрес призначення), які обробляються перед ланцюжками ufw. Тому ufw status може показувати, що порт заблокований, тоді як контейнер за ним відповідає всьому інтернету. З’ясуйте це до відновлення: у матеріалі чому опубліковані порти Docker обходять ufw описано порядок обробки правил і спосіб виправлення.

Невиправлений вебзастосунок. Перегляньте журнал доступу вебсервера за час поблизу найранішої підозрілої позначки часу. Знайдіть POST-запит до шляху завантаження файлів або адміністративного шляху. Потім пошукайте у вебкорені файли з відповідним часом зміни. Типовий результат — сторонній PHP-файл у каталозі завантажень.

Витік облікових даних. Ключ, зафіксований у репозиторії, токен, вставлений у чат, або файл .env, який неправильно налаштований вебсервер роздає як статичний файл. Автоматизація спрощує випадкове розкриття таких даних. Саме тому слід не зберігати секрети в AI-агентах і їхніх конфігураційних файлах.

Якщо після всього цього ви не можете назвати шлях проникнення, припускайте витік облікових даних і вважайте загальнодоступним кожен секрет, який зберігався на машині.

Ротація всіх облікових даних, до яких машина могла отримати доступ

Виконуйте ротацію після відключення мережі, ніколи не робіть цього раніше. Якщо виконати ротацію, поки зловмисник ще має з’єднання, ви просто передасте йому нові секрети.

  • Усі приватні SSH-ключі, збережені на сервері, а також усі облікові записи в інших системах, які довіряли відповідному відкритому ключу.
  • Будь-який ключ, переданий на машину через ssh -A. Переспрямування агента залишає сокет у /tmp, а root на цій машині може використовувати його для автентифікації від вашого імені всюди, де приймається ваш ключ, доки ваша сесія залишається відкритою.
  • API-токени у файлах .env, у рядках Environment= systemd, у конфігурації CI та в облікових даних провайдера.
  • Паролі баз даних і облікові записи застосунків, які їх використовують.
  • Приватні ключі TLS (безпеки транспортного рівня), які зберігалися на сервері. Випустіть сертифікат повторно та відкличте старий.
  • Пароль облікового запису хостингу з увімкненою двофакторною автентифікацією. Через цю панель можна перебудувати, створити snapshot і відкрити консоль кожного вашого сервера, тому саме вона є фактичною межею периметра.
  • Будь-який пароль, введений у shell-сесію на цьому хості під час компрометації, оскільки root може записувати термінальну сесію в реальному часі.

Якщо пароль на цій машині використовується десь іще, змініть його також там. Повторне використання паролів перетворює один скомпрометований VPS на скомпрометований обліковий запис електронної пошти.

Контрольний список відновлення

  1. Створіть новий сервер із чистого образу дистрибутива. Не використовуйте snapshot скомпрометованого сервера або повне відновлення кореневої файлової системи.
  2. Встановіть пакети з репозиторіїв дистрибутива. Ніколи не копіюйте бінарний файл зі старого диска.
  3. Відновлюйте лише дані з резервної копії, створеної до найраніших доказів у вашій часовій шкалі. Дампи баз даних, завантажені файли, стан застосунків. Не переносіть /etc, /usr і старі unit-файли.
  4. Введіть оновлені секрети вручну. Не копіюйте старий .env.
  5. Перевірте відновлений вебконтент на наявність файлів, доданих під час періоду вторгнення, перш ніж знову зробити його доступним.
  6. Посильте захист до відкриття доступу: SSH лише за ключами, робочий обліковий запис не root, вхідний firewall із політикою default-deny і жоден сервіс не має бути опублікований ширше, ніж це потрібно. Виконайте перші десять хвилин на новому VPS, потім належно захистіть SSH, а далі додайте fail2ban на Ubuntu 24.04, щоб зменшити шум у журналах входу. Надайте кожному сервісу власний обліковий запис із мінімальними привілеями, щоб наступне проникнення не давало доступу до root.
  7. Вимкніть старий сервер і зберігайте його snapshot, доки розслідування та всі звернення щодо зловживань не буде завершено.
  8. Виправте систему резервного копіювання. Якщо на кроці 3 довелося діяти навмання, справжня проблема полягає в тому, що історія резервних копій була недостатньо довгою, щоб дістатися до моменту до вторгнення. Версійовані резервні копії на зовнішньому сервері з тривалим зберіганням дадуть змогу наступного разу отримати чисту точку відновлення: резервні копії restic на VPS забезпечать і те, і інше.

Якщо ви не можете визначити дату вторгнення, ви не можете вибрати безпечну резервну копію. У такому разі відновлюйте лише ті дані, які можна перевірити візуально: SQL-дамп, який можна прочитати, або каталог зображень, вміст якого можна перелічити. Вважайте все виконуване підозрілим і встановлюйте його повторно з репозиторіїв.

Що означає повідомлення про зловживання від вашого хостинг-провайдера

Більшість користувачів дізнаються про злам сервера від свого провайдера, а не завдяки власному моніторингу. Провайдери бачать вихідний трафік: SSH-підбір паролів проти інших мереж, спам через порт 25 або участь у reflection-атаці. У тікеті зазвичай зазначено часові мітки, порти та приклад потоків трафіку, а також крайній термін, указаний у годинах.

Відповідайте на такий тікет, навіть якщо можете лише повідомити, що сервер ізольовано та його перебудовують. Провайдери налаштовують null route або призупиняють роботу сервера, якщо на тікет не відповідають. Унаслідок цього інцидент перетворюється на простій сервісу. Потім попросіть надати необроблені рядки журналу, на яких ґрунтується повідомлення. Ці часові мітки записано за межами вашої машини, тому це єдина частина часової шкали, яку зловмисник не міг змінити. Вони часто точніше визначають час проникнення, ніж будь-які дані на диску.

Зламаний сервер клієнта — звичайний робочий випадок для хостинг-провайдера, і належне опрацювання такого інциденту не вважається порушенням з вашого боку. Ширше питання чи безпечний VPS-хостинг переважно зводиться до того, що налаштовує клієнт. Саме це тепер доведеться налаштувати заново з нуля.

Коли потрібно звернутися до фахівця

  • На сервері зберігалися персональні дані інших людей. Відповідно до GDPR (General Data Protection Regulation), про порушення захисту персональних даних потрібно без невиправданої затримки повідомити наглядовий орган, а якщо це можливо — протягом 72 годин із моменту, коли про нього стало відомо. Визначення того, чи почався цей відлік, належить до юридичної роботи, а не до роботи системного адміністратора.
  • Оброблялися дані платіжних карток. Платіжні системи вимагають залучення схваленого фахівця з комп’ютерної криміналістики, а самостійні дії можуть пошкодити докази у справі.
  • Надійшла вимога про викуп або ваші дані було зашифровано.
  • Машина могла підключатися до інших машин: внутрішньої мережі, гіпервізора, CI runner із production credentials. Один скомпрометований хост у групі слід вважати інцидентом для всієї групи, доки не доведено протилежне.
  • Докази мають бути придатними для використання страховою компанією або правоохоронними органами. Зупиніться на етапі створення snapshot, створіть повний образ диска та зафіксуйте, хто і коли працював із ним.

Для одного VPS, на якому працюють лише ваші сервіси й немає даних інших осіб, наведений вище порядок дій охоплює всю роботу. Ізолюйте сервер у провайдера. Створіть snapshot для збереження доказів. Зберіть дані, які ще можна вважати достовірними. Замініть усі облікові дані та ключі. Виконайте чисте розгортання.

FAQ

Чи можна очистити зламаний VPS замість перевстановлення?

Не з достатньою впевненістю, оскільки в такому разі ви просите скомпрометовану систему перевірити саму себе. Підмінений ps приховує процес, рядок у /etc/ld.so.preload впроваджує код у кожен динамічно скомпонований інструмент, який ви запускаєте, а kernel module може одночасно приховати файли від усіх програм. Виявлення окремих об’єктів можливе, тому знайдений результат має значення. Але неможливо довести відсутність інших змін, тому чистий результат перевірки цього не підтверджує. Очищення можна вважати прийнятним лише тоді, коли на сервері немає нічого важливого для вас і ви погоджуєтеся з ризиком повторної компрометації.

Чи потрібно вимкнути скомпрометований сервер або залишити його запущеним?

Спочатку заблокуйте його мережевий доступ на стороні провайдера, а потім залиште сервер увімкненим достатньо довго, щоб створити snapshot і перевірити запущені процеси. Вимкнення знищує список процесів і повністю видаляє журнал, якщо /var/log/journal не існує, оскільки journald у такому разі записує дані в пам’ять через /run. Усе одно вимкніть сервер, якщо він активно атакує інші мережі, а ви не можете заблокувати вихідний трафік. Припинення шкоди важливіше за збереження доказів.

Як визначити, коли зловмисник отримав доступ?

Знайдіть найраніший рядок Accepted password або Accepted publickey, який ви не можете пояснити, у /var/log/auth.log або в журналі. Зіставте його зі списком часу зміни, find / -xdev -newerct 'YYYY-MM-DD' -type f, оскільки ctime важче підробити, ніж mtime. Потім порівняйте обидва значення з часовими мітками у повідомленні про зловживання від провайдера. Їх було зафіксовано поза машиною, тому їх не можна було змінити на сервері. Виберіть backup, створений раніше за найранішу з цих трьох дат. Якщо часові мітки не узгоджуються, вважайте, що компрометація сталася раніше за всю історію backup, і відновлюйте лише дані, які можна перевірити.

Чи безпечно відновлювати backup після компрометації?

Зазвичай дані безпечні після перевірки. Системні файли — ні. Backup, створений після проникнення, містить backdoor, тому відновлення всієї root filesystem також відновить доступ зловмисника. Перевірте і сам backup repository: якщо облікові дані для доступу до нього зберігалися на скомпрометованому сервері, історію backup могли видалити або змінити. Саме тому потрібні append-only або pull-based backup targets. Відновіть дані застосунків, а потім повторно встановіть програмне забезпечення з репозиторіїв дистрибутива.

Чи потрібно повідомляти когось про компрометацію мого VPS?

Завжди відповідайте на повідомлення про зловживання від вашого хостинг-провайдера. Подальші дії залежать від того, чиї дані зберігалися на машині. Персональні дані інших людей можуть створювати юридичний обов’язок повідомити про інцидент, наприклад обов’язок GDPR повідомити наглядовий орган протягом 72 годин. Якщо на сервері зберігалися облікові дані користувачів, повідомте цих користувачів, щоб вони змінили паролі в інших системах. Якщо ключі на сервері надавали доступ до сторонніх систем, наприклад code host або cloud account, повідомте відповідних провайдерів, щоб вони перевірили можливе зловживання. Суто особистий сервер, на якому немає даних інших людей, не створює жодних додаткових обов’язків, крім відповіді на повідомлення про зловживання.

#security#incident-response#compromise#backups#forensics