Защита сервера

В данном гайде я расскажу, как можно максимально защитить свой проект от взлома и DDoS-атак.

Информация

Добро пожаловать на полноценный гайд по защите проекта. Если у вас есть какой-либо ресурс, посвященный майнкрафт тематике, пожалуйста, не надо перезаливать текст этой статьи. Вместо этого, вы можете просто оставить ссылку на данную страницу.

Данный гайд написан на VPS с установленным дистрибутивом Debian 10, взятой мной на один день для написания этой статьи. Если вы увидите здесь IP-адрес этого сервера, пожалуйста, не пытайтесь по нему перейти. Из-за того что после написания гайда я удалил этот сервер, неизвестно кому был передан его IP и что там сейчас находится.

Также, я не несу никакой ответственности за порчу вашего сервера или потерю аптайма при несоблюдении инструкций или неправильной настройке указанных мной утилит. Если у вас нет даже минимальных познаний в администрировании Linux серверов, не советую выполнять какие-либо действия из этой статьи (кроме частей про настройку плагинов и BungeeCord).

Выбор хостинга

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

Избавление от рута

Когда нам выдают сервер после активации, на большинстве хостингов мы получаем данные от пользователя root. Однако, настраивать сервер от этого пользователя неправильно, поэтому нам необходимо создать дополнительного пользователя, зайти в систему от его имени и деактивировать суперпользователя.

Перед выполнением каких-либо действий в системе, нам нужно обновить имеющиеся пакеты.

$ apt update -y && apt upgrade -y

Первым делом, скачиваем пакет sudo, создаем пользователя и добавляем ему sudo права.

$ apt install sudo -y
$ useradd -m ${username}
$ usermod -aG sudo ${username}

Теперь нам необходимо задать пользователю пароль и зайти от его имени.

$ passwd ${username}
$ su ${username}

Как только мы это сделали и убедились что все работает, можно деактивировать root пользователя.

$ sudo nano /etc/passwd

Находим пользователя root, в конце строки меняем /bin/bash на /usr/sbin/nologin и сохраняем файл.

Настройка OpenVPN

В нашем случае, VPN будет использоваться для закрытия от общих глаз SSH порта, а также для нашего удобства. Кроме улучшенной безопасности нашего проекта, мы получим еще и собственный VPN без логирования и сбора личных данных.

Для начала установки, нам нужно скачать специальный скрипт и выдать ему права на запуск.

$ sudo apt install curl -y
$ curl https://raw.githubusercontent.com/Nyr/openvpn-install/master/openvpn-install.sh --output openvpn-install.sh
$ chmod +x openvpn-install.sh

Теперь мы можем запустить скрипт и приступить к установке и настройке нашего VPN.

$ sudo bash openvpn-install.sh

В процессе установки, нам предложат выбрать протокол (просто нажмите ENTER), порт (его рекомендуется сменить), а также DNS-сервера (на выбор из 6 штук). Лично я выбрал AdGuard (под номером 6), потому что я использую этот VPN в качестве основного и мне важна блокировка рекламы. Если вам это не нужно, просто нажмите ENTER.

Теперь нам нужно ввести название клиента, можете ввести сюда произвольное название вашего устройства. После того как вы это сделаете, у вас появится надпись "OpenVPN installation is ready to begin", после чего нажмите ENTER и ожидайте окончания установки.

Профиль был сохранен, однако нам необходимо перенести его в папку нашего пользователя.

$ sudo mv /root/${profile}.ovpn /home/${username}/${profile}.ovpn

Теперь подключаемся к серверу по sFTP и скачиваем этот файл. Не забудьте удалить его с сервера после скачивания, это важно.

Чтобы подключиться к VPN, скачиваем клиент с официального сайта и устанавливаем его. После установки, нажимаем два раза на скачанный с sFTP профиль и соглашаемся с импортом, ставим галочку на "Connect after import", задаем любое название на английском языке и нажимаем "Add".

Теперь у нас есть собственный VPN сервер. Чтобы проверить что мы действительно к нему подключены, заходим на CheckHost и смотрим на верхнюю строку. Если там указан IP-адрес вашего сервера, значит вы сделали все правильно.

Из-за смены IP-адреса, соединение с нашим SSH сервером было разорвано. Чтобы его восстановить, просто входим туда повторно, только уже не под пользователем root, а под созданным нами юзером.

Чтобы подключаться к SSH по локальной сети, нам нужно сначала узнать локальный IP-адрес сервера. Для этого, используйте данную команду:

$ sudo ip address

Здесь нам понадобится этот IP-адрес (у вас он может быть другой), его мы теперь и будем использовать для подключения по SSH.

Теперь пробуем подключиться к серверу по SSH через него.

Если все успешно, меняем также адрес в нашем sFTP клиенте.

После этого, нам нужно разрешить вход в SSH только из сети OpenVPN. Для этого, нам нужно отредактировать конфигурацию демона SSH.

$ sudo nano /etc/ssh/sshd_config

Убираем знак # со строки ListenAddress и меняем 0.0.0.0 на адрес, полученный ранее, после чего сохраняем файл.

После чего, перезагружаем демон SSH следующей командой.

$ sudo service ssh restart

Теперь вы можете подключаться к SSH/sFTP только при включенном OpenVPN и только через локальный IP-адрес, который мы получали ранее. Чтобы это проверить, заходим на CheckHost, в строку вписываем IP нашего сервера, добавляем в конец :22 и нажимаем на кнопку "TCP-порт".

Если все сделано верно, вместо результата и времени пинга, вы увидите надпись "В соединении отказано", "Connection timed out" или любую другую ошибку.

Авторизация по ключам

Мы уже достаточно обезопасили подключение к серверу, однако нам есть куда стремиться. Именно поэтому, необходимо настроить авторизацию по ключам и запретить использование паролей для входа. Если у вас на компьютере нет команд ssh, ssh-keygen и ssh-copy-id, вам нужно будет использовать WSL или установить GitBash.

Для начала, нам необходимо сгенерировать SSH ключи на своем компьютере или в виртуальной машине (не на сервере, это важно).

$ ssh-keygen

Здесь нам нужно нажать ENTER и ввести произвольный дополнительный пароль, чтобы обезопасить сервер, в случае если ключ будет скомпрометирован.

Теперь нам нужно скопировать ключ на сервер, чтобы можно было на него заходить.

$ ssh-copy-id ${username}@{server_ip}

Вводим текущий пароль от сервера и ждем копирования ключа.

Теперь нас просят ввести секретную фразу (пароль) для ключа. Если вам удалось попасть на сервер, значит можно перейти к следующему шагу.

Чтобы разрешить вход на сервер только при помощи ключей, нам нужно снова отредактировать конфиг SSH демона.

$ sudo nano /etc/ssh/sshd_config

Убираем знак # со строки PasswordAuthentication и меняем yes на no и сохраняем файл.

После чего, перезагружаем демон SSH следующей командой.

$ sudo service ssh restart

Подключение к базе данных

Никогда не давайте плагинам доступа к root пользователю от базы данных, поскольку это не только сделает возможным исполнение команд на сервере через SQL-запросы, но и образует огромную уязвимость вашей системы. Для плагинов необходимо создать отдельную базу данных и пользователя для нее.

Для этого, через ssh зайдите в консоль mysql и выберите нужный тип баз данных.

$ mysql
$ [none]> use mysql

Теперь, создайте базу данных, а также пользователя для нее и выставите ему нужные права.

$ mysql> CREATE DATABASE ${database};
$ mysql> CREATE USER '${user}'@'localhost' IDENTIFIED WITH mysql_native_password BY '${password}';
$ mysql> GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, INDEX, DROP, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES ON ${database}.* TO '${user}'@'localhost';

После этого, обновите список таблиц и выйдите из консоли mysql.

$ mysql> FLUSH PRIVILEGES;
$ mysql> exit;

Также, не стоит разрешать внешние подключения и необходимо поставить дополнительную защиту через htpasswd на phpMyAdmin (если он у вас есть).

Выдача прав персоналу

Самой распостраненной ошибкой администраторов является выдача прав на управление сервером другим людям из команды проекта через создание дополнительного пользователя в системе или выдачи доступа к основному.

Если в команде окажется плохой человек, он сможет нанести большой урон проекту. Именно поэтому, рекомендуется использовать панель Pterodactyl, добавлять других администраторов как субпользователей и давать им только определенные права, а также сделать задачу в планировщике на постоянные резервные копии и не давать доступ к управлению ими другим администраторам (чтобы невозможно было их удалить).

Обновление системы

Очень часто, в различных пакетах и дистрибутивах, находят и устраняют уязвимости, позволяющие другим людям получить доступ к вашему серверу. Чтобы автоматически обновлять систему и все пакеты, нам понадобится unattended-upgrades.

Установка производится всего одной командой, дополнительная настройка не требуется.

$ sudo apt install unattended-upgrades -y

Обновление плагинов

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

Настройка BungeeCord

Стандартная настройка BungeeCord (на проектах без online-mode) делает сервер уязвимым. Здесь я покажу, как можно правильно все настроить, чтобы этого избежать.

По умолчанию, у игрока md_5 есть доступ к командам /end (выключение BungeeCord), /ip (показ IP любого игрока) /greload (перезагрузка BungeeCord), а также у всех игроков есть доступ к команде /server (переключение серверов в обход авторизации, если она не на BungeeCord). Нам нужно убрать эти права и снять привилегию администратора с игрока md_5.

Открываем файл config.yml в папке с BungeeCord и редактируем список прав. Стандартный выглядит вот так:

Лично я впринципе уберу группу admin, а также право на /server у всех игроков.

Также, нам необходимо включить передачу IP-адресов на остальные сервера, чтобы они отображались корректно и работали блокировки по IP. Сначала, в конфиге BungeeCord нам нужно изменить параметр ip_forward на true.

А теперь, заходим в конфиг spigot.yml на каждом сервере и меняем bungeecord на true.

Защита BungeeCord

Чтобы защитить ваш проект от недоброжелателей, необходимо установить на сам BungeeCord и все сервера BungeeGuard и закрыть порты через iptables.

Для установки BungeeGuard, кидаем файл в папку с плагинами на BungeeCord и перезагружаем его. Теперь, заходим в папку плагина, открываем файл token.yml и видим перед собой сгенерированный токен. Его необходимо скопировать и хранить в секрете, потому что если кто-то его узнает, он сможет подключиться к серверам в обход BungeeCord.

После этого, ставим этот плагин на каждый сервер, перезагружаем все сервера, заходим в каждую папку с плагином и открываем файл config.yml, после чего добавляем наш токен в раздел allowed-tokens и удаляем все что там было.

Чуть ниже можно настроить сообщения, которые будут выдаваться игрокам при попытке зайти напрямую на сервер (в обход BungeeCord).

Теперь перейдем к настройке файрволла. Для начала, разрешаем все подключения в локальной сети.

$ sudo iptables -A INPUT -s 127.0.0.1 -j ACCEPT
$ sudo iptables -A INPUT -s ${main_server_ip} -j ACCEPT
$ sudo iptables -A INPUT -s ${other_server_ip} -j ACCEPT

После этого, мы можем приступить к закрытию портов. Лично я предпочитаю закрывать целый диапазон, к примеру 25566:25760, чтобы не приходилось каждый раз менять правила. Однако, если вам по какой-то причине нужно закрыть только один или несколько портов, просто укажите его вместо этого диапазона.

$ sudo iptables -A INPUT -p tcp --dport ${port(s)} -j DROP

После этого необходимо сохранить правила файрволла, чтобы они не сбросились после перезагрузки. Для этого, воспользуемся утилитой iptables-persistent и запустим настройку.

$ sudo apt install iptables-persistent -y
$ sudo dpkg-reconfigure iptables-persistent

У нас откроется вот такое окно, где нам два раза необходимо нажать на ENTER.

Защита от DDoS-атак

Как известно, не на всех хостингах есть хорошая защита от DDoS-атак. А в некоторых случаях, если она и есть, то может фильтровать только слабые атаки. Здесь я расскажу, как можно защититься от различных типов DoS/DDoS. Начиная от стандартных TCP-атак, заканчивая специально созданными методами для майнкрафт серверов.

Первым делом, установим BotFilter. Скачиваем stable-версию и заменяем файл BungeeCord на него, после чего перезагружаем сервер, переходим в папку BotFilter, открываем файл config.yml и настраиваем все под себя.

Теперь перейдем к настройке TCPShield. Переходим на сайт, нажимаем "Client Area", выбираем "Register", вводим данные и создаем аккаунт.

Заходим на почту, видим письмо с кнопкой активации и нажимаем на нее.

После этого, переходим в панель управления по данным, которые мы зарегистрировали.

Нажимаем на "Add network" и указываем название нашего проекта.

В левом меню выбираем "Backends", нажимаем на "Add set", после чего вписываем произвольное название сервера (оно будет видно только в панели) и в "Backends" вписываем наш текущий адрес сервера (обязательно с IP и портом, а не с доменом).

Переходим в раздел "Domains" и под "My protected CNAMEs" нажимаем на "Copy".

Теперь заходим в управление DNS (в моем случае это CloudFlare) и создаем новую CNAME-запись с именем play (у меня это play, а у вас может быть join, mc и т.д.) и сохраняем ее. Если есть старая, ее необходимо удалить.

Возвращаемся в нашу панель и раздел "Domains", после чего нажимаем на "Add Domain".

Здесь в поле "Domain" вписываем наш домен, нажимаем на "Re-check domain", в "Backend Set" выбираем наш добавленный ранее сервер, включаем "Badlion Proxy" и нажимаем на "Add".

Теперь наш домен успешно добавился в панель и мы можем заходить на сервер через него.

Поднимаемся чуть выше до раздела "Download plugins". Здесь нажимаем на кнопку в зависимости от используемого ядра. Если у вас BungeeCord - нажимаем на "Download latest Bungee", если Velocity - "Download latest Velocity", а если обычный сервер - "Download latest Spigot".

Отсюда мы скачиваем плагин для нужного нам ядра (если у вас BungeeCord связка - плагин надо ставить только на сам BungeeCord) и перезапускаем его.

Готово, теперь у вас показываются реальные IP игроков (под защитой), закрыт главный порт сервера и вход доступен только указанному вами домену.

Откат действий гриферов

На каждом сервере могут произойти гриферские атаки, от которых необходимо защищаться. Именно для этих целей и был сделан плагин CoreProtect. Он в реальном времени сохраняет все данные о мирах и позволяет отменить действия гриферов в случае необходимости.

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

Установка Pterodactyl

Существует такая панель как Pterodactyl, предоставляющая удобный интерфейс, множество различных функций, а также запускающая все сервера в изолированных Docker контейнерах. При этом, она является полностью бесплатной и имеет открытый исходный код.

Если вы хотите установить данную панель, можете воспользоваться быстрым установщиком, либо сделать все вручную, используя официальную документацию.

Защита от эксплоитов

Для майнкрафт серверов было придумано очень много различных эксплоитов. Начиная от CustomPayload, заканчивая NBT-тегами или шалкерами, ломающими игру остальным игрокам.

Чтобы защититься от этого, установите на все сервера два плагина - ExploitFixer и IllegalStack. Первый необходимо также поставить и на BungeeCord, если вы используете такую связку.

Защита от Proxy и VPN

Чтобы защититься от Proxy и VPN, используйте плагин GateKeeper. Также, если вы используете OpenVPN, откройте конфиг плагина и добавьте IP-адрес сервера в список разрешенных.

Перенос сайта на GitHub Pages

Если вы хотите максимально защитить сайт своего проекта от различных DoS/DDoS-атак, сделайте сайт статичным (как сайт RangeMC) и просто перенесите его на платформу GitHub Pages.

Таким образом, вы получите полностью бесплатный хостинг для сайта с лучшей защитой, которую использует сам GitHub. Также, вы можете привязать собственный домен в настройках репозитория (изначально выдается поддомен на github.io), это тоже абсолютно бесплатно.

Last updated