Взлом сайта на WordPress: что делать и как найти веб-шелл

Сайт на WordPress взломали: что делать и как найти веб-шелл

Марина
Марина
📅 23 октября 2026
Сайт на WordPress взломали: что делать и как найти веб-шелл

В сентябре 2026 года мы разбирали аккаунт виртуального хостинга, где под одним пользователем лежали 15 установок WordPress. Один сайт вычистили 2–3 сентября, а 4 сентября в нём снова появились три чужих администратора и mu-plugin, который пересоздавал себя примерно через минуту после удаления. Вероятная причина нашлась на соседнем сайте: там остался веб-шелл, а пользователь у всех сайтов аккаунта был общий. Вторую чистку провели по всем сайтам сразу, и на контрольных проверках взлом не вернулся.

Повод вспомнить этот случай — PHP2Shell. 21 октября 2026 года PHP выпустил версии 8.5.12, 8.4.27, 8.3.36 и 8.2.35, которые закрывают две критические уязвимости с выполнением кода без авторизации (php.net). Подтверждённых массовых взломов на 21.10.2026 нет, но попытки атак фиксировали watchTowr и Cloudflare. Huntress советует сохранить логи и искать в каталогах сайта веб-шеллы, новые файлы, задания cron и учётные записи (Huntress). Подробности — в нашей новости о PHP2Shell.

Ниже — порядок действий, когда случился взлом сайта на WordPress. Если под подозрением весь сервер, начните с гайда «Взломали сервер: что делать в первые 24 часа» — там изоляция VPS и смена SSH-ключей. Команды WP-CLI сверены с документацией и исходным кодом WP-CLI на 22.10.2026, shell-команды — для Ubuntu 22.04/24.04 и Debian 12.

Признаки взлома сайта, которые не спишешь на сбой

Документация WordPress называет явными признаками компрометации такие события (WordPress.org):

  • сайт попал в чёрные списки поисковиков или помечен как распространяющий вредоносное ПО;
  • хостер отключил сайт;
  • антивирусы посетителей ругаются на сайт, а с самого сайта атакуют другие ресурсы;
  • в админке происходит то, чего никто не делал, например появляются новые пользователи;
  • следы взлома видны прямо в браузере.

В сентябрьском случае это выглядело так: администратор admin9734, файл admin.php на 33 КБ в корне, index.php, подменённый дорвеем с контентом с чужого домена, сотни одинаковых .htaccess по папкам. Аккаунт на четыре дня ушёл в ответ 403: хостер закрыл его из-за майнера, работавшего от имени пользователя сайтов.

Поисковики сообщают о заражении в кабинетах: в Google Search Console — отчёт «Проблемы безопасности» (справка Google), в Яндекс Вебмастере — раздел «Безопасность и нарушения» (справка Яндекса).

Ошибки 500 сами по себе взлом не доказывают. Для PHP2Shell Wiz называет сигналы атаки — multipart-запросы, за которыми идут ошибки memory limit или повторяющиеся HTTP 500, аномально большие cookie PHPSESSID, необъяснимые перезапуски воркеров PHP — и тут же оговаривает, что они не доказывают ни атаку, ни её отсутствие (php2shell.com).

Первый час: закрыть сайт и снять копию «как есть»

Первое действие по документации WordPress — записать, что вы увидели, во сколько и в каком часовом поясе, что меняли в последние дни: ставили плагин, правили тему. Из этих записей собирается отчёт об инциденте, и специалисту они сэкономят часы.

Второе — закрыть сайт. Штатный режим обслуживания WordPress для этого слабый. Команда wp maintenance-mode activate пишет в .maintenance фиксированную метку времени (WP_Upgrader::maintenance_mode), а WordPress считает режим законченным, когда метке больше 10 минут (wp_is_maintenance_mode). Главное — режим останавливает загрузку WordPress, а веб-шелл — отдельный PHP-файл, и по прямому адресу он продолжит работать.

Надёжнее закрыть весь сайт паролем на уровне веб-сервера. Для Apache — .htaccess в корне сайта (документация Apache):

sudo apt install apache2-utils           # утилита htpasswd
htpasswd -c /home/user/.htpasswd-site admin

# в начало /var/www/example.com/public_html/.htaccess
AuthType Basic
AuthName "Closed"
AuthUserFile /home/user/.htpasswd-site
Require valid-user

Для nginx — файл паролей и две директивы в блоке server сайта (документация nginx):

sudo htpasswd -c /etc/nginx/.htpasswd-site admin

# в блок server сайта
auth_basic "Closed";
auth_basic_user_file /etc/nginx/.htpasswd-site;

sudo nginx -t && sudo systemctl reload nginx

Проверка — запросы без пароля к главной, wp-login.php и любому адресу в uploads получают 401: curl -sI https://example.com/wp-login.php | head -1. В конфиге nginx не должно быть auth_basic off в отдельных location. На виртуальном хостинге .htaccess действует не везде: в сентябрьском случае статику отдавал nginx, и правила на неё не распространялись. Нет 401 — просите поддержку закрыть сайт.

Третье — копия «как есть». Документация WordPress советует снять её перед чисткой, даже заражённую: если чистка что-то сломает, будет с чем сравнить. Копию держат вне веб-корня и никогда не восстанавливают на боевой сайт:

mkdir -p ~/incident && chmod 700 ~/incident
cd /var/www/example.com/public_html      # каталог, где лежит wp-config.php
grep -E "DB_(NAME|USER|HOST)" wp-config.php
mysqldump --single-transaction -u DB_USER -p DB_NAME > ~/incident/db-asis.sql
tar -czf ~/incident/files-asis.tgz .
sudo cp -a /var/log/nginx ~/incident/       # если сайт на nginx
sudo cp -a /var/log/apache2 ~/incident/     # если на Apache
sha256sum ~/incident/*.sql ~/incident/*.tgz > ~/incident/sha256.txt

Дамп снимают через mysqldump или панель хостинга, а не wp db export: WP-CLI перед этой командой исполняет код wp-config.php, а в заражённом сайте там может стоять вставка бэкдора.

На виртуальном хостинге логи скачивают из панели сразу: в сентябрьском случае хостер хранил их около 10 дней. После копии смените пароли от панели хостинга, FTP/SFTP и SSH — через них атакующий может вернуться, пока вы ищете бэкдоры.

Где прячутся веб-шеллы и бэкдоры WordPress

Где прячутся веб-шеллы и бэкдоры WordPress: uploads, mu-plugins, ядро и база данных

Веб-шелл (web shell) — PHP-файл, через который атакующий выполняет команды на сервере из браузера. Бэкдор (backdoor) шире: любой способ вернуться — файл, скрытый администратор, опция в базе, задание cron, ключ удалённого управления (подробнее — что такое бэкдор). Искать нужно всё сразу: в сентябре бэкдор закрепился в drop-in’ах, скрытых файлах uploads и upgrade, вставке в wp-config.php, опциях базы, файлах темы, PHP-переводах и cron.

Порядок поиска задаёт то, что запускает код сайта. Почти все команды WP-CLI загружают WordPress, а с ним mu-plugins и drop-in’ы. Флаг --skip-plugins отключает обычные плагины, но mu-plugins, по документации, загружаются всё равно (WP-CLI Handbook). Сначала идут find, grep и wp core verify-checksums, который работает до загрузки WordPress; команды с загрузкой — только после проверки mu-plugins, drop-in’ов и wp-config.php.

PHP-файлы там, где их быть не должно

В wp-content/uploads лежат картинки и документы, PHP там не нужен. Любой .php, .phtml, .phar в этой папке — повод для разбора:

cd /var/www/example.com/public_html
find wp-content/uploads -type f -iname '*.ph*'
find wp-content/uploads wp-content/upgrade -maxdepth 2 -type f -name '.*'
find . -name '.htaccess' | wc -l
find . \( -name '.user.ini' -o -name 'php.ini' \) -ls

На обычном сайте .htaccess — единицы, на двух сайтах из сентябрьского случая их было 355 и 635. Через .user.ini и php.ini в каталогах сайта атакующие переопределяют настройки PHP: у нас нашёлся php.ini с disable_functions = NONE.

С переводами осторожнее. С версии 6.5 WordPress хранит переводы и в PHP-файлах *.l10n.php (Make WordPress Core), так что PHP в wp-content/languages — норма. В сентябре вредоносный код сидел как раз в таких файлах: их проще удалить и скачать языковые пакеты заново, чем проверять построчно.

mu-plugins и drop-in’ы

Плагины из wp-content/mu-plugins включаются автоматически, отключить их из админки нельзя, в списке плагинов они вынесены во вкладку «Must-Use» (документация WordPress). Drop-in’ы db.php, object-cache.php, advanced-cache.php в wp-content грузятся раньше обычных плагинов. Происхождение каждого подтверждают: обычно их ставит плагин кэша или хостинг для своего подключения к базе:

ls -la wp-content/mu-plugins/
ls -la wp-content/db.php wp-content/object-cache.php wp-content/advanced-cache.php 2>/dev/null

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

Команда wp core verify-checksums сравнивает файлы сайта с контрольными суммами WordPress.org, не загружая WordPress, а флаг --include-root предупреждает о посторонних файлах в корне (документация WP-CLI):

wp core verify-checksums --include-root
# Warning: File doesn't verify against checksum: wp-admin/users.php
# Error: WordPress installation doesn't verify against checksums.

В сентябре так нашёлся изменённый wp-admin/users.php. Плагины проверяет wp plugin verify-checksums --all, но только по суммам WordPress.org: платные плагины и плагины не из каталога он пропускает с предупреждением «Could not retrieve the checksums… skipping» (документация WP-CLI). Эта команда загружает WordPress, поэтому её запускают с --skip-plugins --skip-themes и только после проверки mu-plugins и drop-in’ов. Для тем сверки нет: тему сравнивают с оригинальным архивом разработчика.

Поиск по eval и base64_decode: что значат совпадения

Веб-шеллы прячут код за eval, base64_decode, gzinflate, str_rot13. Поиск по этим функциям даёт список кандидатов, а не список вирусов:

grep -rlE --include='*.php' \
  'eval[[:space:]]*\(|base64_decode[[:space:]]*\(|gzinflate[[:space:]]*\(|str_rot13[[:space:]]*\(|assert[[:space:]]*\(\$_' \
  wp-content/ > ~/incident/grep-hits.txt
wc -l ~/incident/grep-hits.txt

find . -name '*.php' -newermt '2026-10-01' -printf '%TY-%Tm-%Td %TH:%TM %p\n' | sort

Ложных срабатываний будет много. В зеркале ядра WordPress на GitHub поиск находит base64_decode в 16 файлах, среди них библиотеки PHPMailer, SimplePie и ID3, а eval( — в class-pclzip.php и class-json.php (поиск на 22.10.2026). Подозрительны файл из одной строки с длинной кашей символов, обфускация рядом с $_POST или $_COOKIE, системное на вид имя, которого нет в составе плагина. В сентябре поиск спама по слову «казино» выдал 62 «заражённых» поста — все ложные: выражение цепляло «азино» внутри слова «магазинов».

Дату изменения файла подделывают командой touch, поэтому свежий mtime — подсказка, а не доказательство. Полезнее то, что выбивается из картины: у нас 77 файлов ядра имели мартовскую дату, отличную от остальных файлов ядра.

Отдельно смотрят файлы, которые атакующие правят чаще всего: .htaccess, index.php, wp-config.php, а в теме — header.php, footer.php, functions.php (WordPress.org). В стандартном wp-config.php после строки с wp-settings.php кода нет, и всё, что там стоит, разбирают: в сентябре там был блок, восстанавливавший бэкдор после удаления.

Сканеры на хостинге и онлайн-проверки разобраны в гайде «Как проверить сайт на вирусы», поиск следов на уровне сервера — в статье «Как проверить VPS на взлом».

Лишние администраторы, опции и cron в базе данных

Команда wp db query, судя по исходникам WP-CLI, исполняет wp-config.php, но WordPress не загружает, так что mu-plugins и плагины при ней не выполняются. Запускают её, когда wp-config.php уже проверен; до этого те же запросы выполняют через mysql или phpMyAdmin. Префикс таблиц смотрят командой grep table_prefix wp-config.php; в примерах он стандартный, wp_:

# последние зарегистрированные пользователи
wp db query "SELECT ID,user_login,user_email,user_registered FROM wp_users ORDER BY user_registered DESC LIMIT 15"

# у кого роль администратора или отдельное право manage_options
wp db query "SELECT user_id,meta_value FROM wp_usermeta WHERE meta_key='wp_capabilities' AND (meta_value LIKE '%administrator%' OR meta_value LIKE '%manage_options%')"

# адрес сайта, почта администратора, открытая регистрация
wp db query "SELECT option_name,option_value FROM wp_options WHERE option_name IN ('siteurl','home','admin_email','users_can_register','default_role')"

# опции с кодом и опции со случайными именами
wp db query "SELECT option_name,LENGTH(option_value) FROM wp_options WHERE option_value LIKE '%base64_decode%' OR option_value LIKE '%eval(%' OR option_name REGEXP '^_[0-9a-f]{16,20}\$'"

Искать стоит по правам, а не по логинам. В кампании через UpdraftCentral бэкдор-аккаунт числился редактором с отдельным правом manage_options (Patchstack), и в фильтре по администраторам его не видно. Опции со случайными именами из 16–20 шестнадцатеричных символов — шаблон из сентябрьского случая: в них бэкдор хранил удалённых администраторов и восстанавливал их.

Cron WordPress и пароли приложений проверяют после очистки файлов, потому что эти команды загружают WordPress: wp cron event list --skip-plugins --skip-themes и wp user application-password list admin. Незнакомые хуки, вроде xmsg_ping из сентябрьского случая, — механизм возврата; пароли приложений, которые никто не создавал, удаляют.

Отдельный инцидент октября: ключи UpdraftCentral

Параллельно с PHP2Shell идёт отдельная кампания; опубликованные источники её связь с PHP2Shell не устанавливают. 19 октября 2026 года Patchstack сообщил: злоумышленник с действующими ключами UpdraftCentral ставит бэкдор-плагины на подключённые сайты, окно атаки — около 18 часов 18–19 октября. Это не ошибка в коде плагина: команды подписаны настоящими ключами. Имён бэкдор-плагинов 99, среди них «Site Health Cache», «Content Helper», «Seo Manager».

TeamUpdraft сообщила о доступе к своему сайту 17–18 октября; по её оценке, затронута база клиентов с email, хешами паролей и ключами UpdraftCentral, UpdraftVault, UpdraftClone. Файлы плагина и self-hosted UpdraftCentral, по заявлению компании, не пострадали. Исправление — UpdraftPlus 1.26.13 / 2.26.13: на 22.10.2026 компания пишет, что они отключают подключения UpdraftCentral, созданные до 13:07 BST 18 октября (TeamUpdraft). В том же посте в блоке «What you need to do» указано «1.26.12 или новее», но, по данным Nethemba, 1.26.12 из-за ошибки ключи не удалял (Nethemba) — ставьте 1.26.13.

Что делать по Patchstack:

  1. Проверить ключ: wp option get updraft_central_localkeys — по Patchstack, любой вывод означает, что ключ есть; ошибка об отсутствии опции — ключа нет. Команда загружает WordPress; до чистки ту же проверку делают SQL-запросом к wp_options. Удалить: «Настройки → UpdraftPlus Backups → Advanced Tools → UpdraftCentral» или wp option delete updraft_central_localkeys. Отключить сайт в дашборде недостаточно.
  2. Искать признаки: незнакомые плагины, в том числе во вкладке Must-Use; описание «Small maintenance toolkit: keeps option storage tidy»; скрытый редактор с manage_options, логином из двух слов и двух цифр (data-ops43, media-staff96), email на @example.org и именем «Site Tools»; опция, имя которой заканчивается на _sync_token; в логе UpdraftCentral — probe.central.updraftplus.com и plugin.upload_plugin.
  3. Нашли бэкдор — сначала удалить ключ, затем деактивировать плагин и вынести его папку из веб-корня. Удалять через админку нельзя: процедура удаления стирает следы. «Чинить» тоже нельзя: в образцах есть ошибка, из-за которой код падает до проверки токена, и её исправление включает бэкдор. Потом удалить опцию …_sync_token и аккаунт.
  4. Если аккаунт или следы в логах нашлись — восстановление из бэкапа до 17 октября, смена паролей, завершение сессий, 2FA. Обновление плагина бэкдоры не удаляет.

Восстановить из бэкапа или чистить

Восстановление сайта из бэкапа до первого следа взлома или чистка с переустановкой ядра и плагинов

Бэкап быстрее, но только если он старше первого следа взлома, и даже такую копию проверяют: ранние следы могли не сохраниться. Дату первого следа дают логи и даты создания чужих аккаунтов и файлов. В сентябрьском случае бэкдор появился 4 сентября, сразу после первой чистки, и копии позже этой даты были заражены.

Ситуация Что выбрать Чем платите
Есть бэкап до первого следа, контент меняется редко Восстановление Правками и комментариями после даты бэкапа
Магазин с заказами после даты бэкапа Файлы — из бэкапа или заново, база — чистка Временем на разбор таблиц
Чистого бэкапа нет Чистка с переустановкой ядра, плагинов и темы Временем и риском пропустить точку возврата
Взлом вернулся после чистки Чистка всех сайтов аккаунта разом и смена всех паролей Простоем всех сайтов на время работ

Восстановление не закрывает дыру, через которую вошли: без обновления PHP и плагинов и без смены паролей остаётся риск заразиться тем же способом.

При чистке ядро ставят той же версии, что стояла, иначе сайт может не подняться. Каталоги wp-admin и wp-includes удаляют и заливают заново, а не перезаписывают: установщики перезаписывают существующие файлы, а взлом добавляет новые (WordPress.org). У wp core download флаг --force перезаписывает файлы, --skip-content не трогает темы и плагины (документация WP-CLI):

wp core version                          # запомнить версию, например 7.1.3
rm -rf wp-admin wp-includes
wp core download --version=7.1.3 --locale=ru_RU --skip-content --force   # локаль — как у сайта
wp core verify-checksums --include-root

Плагины из каталога WordPress.org удаляют целиком и ставят заново, платные — из кабинета разработчика, тему — из оригинального архива, неиспользуемые удаляют совсем. В uploads остаются только медиафайлы. Все точки возврата убирают за один заход, до первого запуска того, что загружает WordPress, — иначе бэкдор восстановит себя из оставшейся копии. Если сайтов на аккаунте несколько и пользователь общий, чистят все одновременно.

Пароли, соли и сессии: что менять и когда

Документация WordPress требует менять все точки доступа — FTP/SFTP, админку, панель хостинга, MySQL — для всех пользователей, а пароли сайта менять дважды: при обнаружении взлома и после чистки (WordPress.org).

wp config shuffle-salts
# Success: Shuffled the salt keys.

Команда обновляет ключи и соли в wp-config.php (документация WP-CLI), и все залогиненные выходят из системы — включая атакующего с украденной cookie. Пароль базы меняют в панели и сразу прописывают в wp-config.php: веб-шелл читает этот файл первым. В сентябре на сервере нашёлся след чужого запуска mysqldump, и утечку базы мы исключить не смогли.

Ключи, хранившиеся на сайте, тоже считаются скомпрометированными: SMTP, платёжные шлюзы, CDN, API сервисов. Для PHP2Shell это верно даже без следов выполнения кода: утечка памяти процесса может раскрыть пароли, токены и ключи из других запросов (FAQ на php2shell.com). Администраторам включают двухфакторную аутентификацию.

Обновить PHP, ядро и плагины — и закрыть uploads

От PHP2Shell обновление WordPress и плагинов не спасает: дыра в самом PHP. Нужны 8.5.12, 8.4.27, 8.3.36, 8.2.35 или пропатченная сборка дистрибутива; ветки 8.1 и старше обновлений от PHP не получают (php.net). Дистрибутивы оставляют старый номер версии: на Ubuntu 24.04 исправленный PHP показывает 8.3.6, поэтому сверяют версию пакета, а не вывод php -v. Пошагово — в гайде «Как обновить PHP на хостинге».

На виртуальном хостинге PHP обновляет хостер. Beget, например, 21 октября ограничил upload_progress на виртуальном хостинге и предупредил, что VPS обновляет владелец. Если хостер молчит, а сайт работает на PHP 8.1 или старше, сравните тарифы в разделе хостинг с актуальным PHP; если нужен отдельный пользователь на каждый проект — каталог VPS.

Актуальный WordPress на 22.10.2026 — 7.1.3 (по API обновлений WordPress.org), рекомендуемый PHP — 8.3 и новее (требования WordPress). Ещё две настройки из нашего чек-листа после сентябрьского случая: define( 'DISALLOW_FILE_EDIT', true ); в wp-config.php отключает редактор файлов в админке (документация WordPress), а правило для Apache запрещает PHP в uploads:

# wp-content/uploads/.htaccess
<FilesMatch "\.(php|php\d|phtml|phar)$">
  Require all denied
</FilesMatch>

Проверка: положить в uploads файл t.php с <?php echo 1;, открыть по адресу — ответ должен быть 403 — и сразу удалить. Увидели «1» — правило не действует, нужен запрет в конфиге nginx или через поддержку.

Вернуть сайт в поиск

Перепроверку запрашивают, только когда сайт чист полностью. Google просит устранить проблему на всех страницах и описать, что сделано; проверка занимает от нескольких дней до нескольких недель (справка Google). В Яндекс Вебмастере срок — до 30 дней, а при статусе «Ограничение не снято» повторно отправить сайт можно только через 30 дней (справка Яндекса). Ранний запрос с недочищенным сайтом в Яндексе может отодвинуть следующую попытку на месяц.

Когда звать специалистов

Начинать стоит с поддержки хостинга: на виртуальном хостинге взлом мог затронуть не только ваш сайт, и хостер подтвердит, атака это или сбой (WordPress.org). Специалисты по реагированию на инциденты нужны, если:

  • взлом вернулся после чистки — значит, точка возврата или вход остались;
  • сайт принимает платежи или хранит персональные данные: если выявлен неправомерный доступ к ним, оператор обязан уведомить Роскомнадзор в течение 24 часов, а о результатах расследования — в течение 72 часов (ч. 3.1 ст. 21 152-ФЗ), порядок — в нашем гайде про взлом VPS;
  • нет SSH, WP-CLI и чистого бэкапа, а сайт приносит деньги;
  • сайт на PHP 8.1 или старше и быстро обновить его нельзя: CISA в такой ситуации советует выводить приложение из интернета (CISA).

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

Чек-лист после взлома сайта на WordPress

Этап Что сделать Чем проверить
Записать Что увидели, время с часовым поясом, последние изменения Файл заметок рядом с копией
Закрыть Пароль на весь сайт на уровне веб-сервера curl -sI без пароля — 401
Копия «как есть» Дамп через mysqldump, файлы, логи вне веб-корня, хеши ~/incident/sha256.txt
Доступы хостинга Пароли панели, FTP/SFTP, SSH Старый пароль не подходит
Файлы PHP в uploads, скрытые файлы, .htaccess, .user.ini, mu-plugins, drop-in’ы find из раздела про веб-шеллы
Ядро и плагины Сверка контрольных сумм wp core verify-checksums --include-root, wp plugin verify-checksums --all
Код Поиск eval/base64_decode, разбор совпадений вручную grep-hits.txt разобран построчно
База Пользователи, права manage_options, siteurl/home, опции с кодом wp db query из раздела про базу
UpdraftCentral Удалить ключи, обновить до 1.26.13 / 2.26.13 wp option get updraft_central_localkeys — опции нет
Бэкап или чистка Бэкап до первого следа или чистка всех точек за один заход Повторный поиск через сутки — пусто
Пароли и соли Все пользователи WordPress, база, ключи API, соли, 2FA wp config shuffle-salts — Success
PHP и обновления PHP 8.2.35 / 8.3.36 / 8.4.27 / 8.5.12 или пропатченный пакет, WordPress, плагины Версия пакета в панели или dpkg -l 'php*'
Защита DISALLOW_FILE_EDIT, запрет PHP в uploads Тестовый t.php в uploads — 403
Поиск Перепроверка в Search Console и Вебмастере Статус «Ограничение снято»

Что в сухом остатке

Взломанный WordPress закрывают паролем веб-сервера, снимают копию «как есть», ищут бэкдоры до загрузки WordPress и убирают все точки возврата за один заход. Пароли и соли меняют после чистки, PHP обновляют до релизов 21 октября. Сайты с общим пользователем чистят все сразу — в сентябре исход решило именно это. Если у сайта нет своего пользователя и актуального PHP, хостинг стоит сменить — тарифы в разделе хостинг для WordPress.

Поделиться:
👁 16 просмотров
Марина
Редактор · FREEHOSTING
Главный редактор FREEHOSTING. С 2020 года тестирует VDS, VPS и хостинг-провайдеров — арендует серверы, нагружает их реальными проектами и пишет честные обзоры по итогам. Помогает читателям выбирать хостинг под свои задачи: от Telegram-бота до production-сайта.