Discord-бот, который может выполнять команды на вашем игровом сервере, - это удалённая консоль, паролем к которой служит «нужная роль в Discord». Это может быть вполне хорошей архитектурой - команда и так живёт в Discord, а кикнуть грифера с телефона действительно полезно, - но только если бот выполняет короткий белый список команд, а не всё, что ему напишут, проверяет роли при каждой команде, имеет минимальные права в Discord, с которыми он может работать, логирует каждое использование и держит свой токен и пароль RCON вне досягаемости. Для одностороннего трафика вроде статуса и оповещений вебхук проще и безопаснее любого бота.
В этой статье - интеграции, которые обычно используют игровые серверы, риски, характерные именно для админ-ботов, как правильно настроить права с обеих сторон, и небольшой безопасный админ-бот, который можно запустить самостоятельно. Односторонние сообщения о статусе разобраны в статье вебхуки Discord для статуса сервера, а хостинг любого бота - в статье хостинг Discord-бота 24/7.
Вебхук, интеграция или собственный бот#
Выбирайте наименее мощный инструмент, который справляется с задачей.
| Задача | Инструмент | Может ли он изменить сервер? |
|---|---|---|
| Статус, оповещения, объявления о входе | Вебхук | Нет |
| Мост чата между игрой и Discord | Интеграция на стороне игры | Только в пределах чата |
| Консоль в канале Discord | Интеграция на стороне игры | Да, всё |
| Заявки в белый список, кики, несколько команд | Админ-бот с белым списком команд | Только то, что вы разрешили |
| Модерация самого Discord | Discord AutoMod, бот-модератор | Нет, только Discord |
Вебхук умеет только публиковать. У него нет учётных данных от вашего игрового сервера, поэтому худшее, что может сделать утёкший URL вебхука, - заспамить один канал. Это делает его правильным выбором для всего одностороннего: эмбедов со статусом, оповещений о крашах, уведомлений о перезапуске, объявлений о банах.
Бот - это постоянно работающая программа, подключённая к Discord с токеном, и она может делать всё, что позволяют её код и её права. Как только она получает возможность говорить с консолью игрового сервера, её безопасность становится так же важна, как безопасность вашего пароля RCON.
Интеграции, которые обычно используют игровые серверы#
У большинства популярных игр есть проверенная интеграция, и использовать её обычно лучше, чем писать свою.
- Minecraft - DiscordSRV. Плагин на сервере, который соединяет игровой чат с каналом Discord, связывает аккаунты Discord и Minecraft, синхронизирует роли и может зеркалировать консоль в канал, где сообщения выполняются как команды. Над последней функцией стоит хорошо подумать. Настройка описана в статье DiscordSRV для Minecraft.
- FiveM - txAdmin. В txAdmin есть Discord-бот, который может публиковать постоянный эмбед со статусом сервера и обрабатывать заявки в белый список: игроки запрашивают доступ из Discord, а команда одобряет их в txAdmin. О самом txAdmin - в статье сервер FiveM и txAdmin, а о доступе по ролям - в статье права Discord и белый список в FiveM.
- Игры на Source и CS2. Плагины SourceMod и CounterStrikeSharp обычно публикуют жалобы, баны и чат в Discord через вебхуки; сами действия администраторов остаются в игре.
- Rust, DayZ, Arma и другие игры с RCON. Админ-инструменты и RCON-сервисы подключаются к серверу по RCON и часто имеют свои функции для Discord: килфиды, уведомления о банах, списки игроков. Они хранят ваш пароль RCON, поэтому заслуживают такой же проверки, как бот, написанный вами.
- Универсальные боты статуса. Боты, которые опрашивают публичный порт статуса сервера и показывают, кто онлайн. Им не нужно ничего секретного, потому что эта информация публична. Что именно они читают, объяснено в статье query-порты и A2S.
Почему консольный бот - это RCON с другим замком#
Представьте, что нужно атакующему, чтобы выполнять команды на вашем сервере каждым из путей.
Консоль панели закрыта вашим аккаунтом и его двухфакторной аутентификацией. RCON - одним паролем. Консольный бот - ролью в Discord, а значит, каждым аккаунтом Discord с этой ролью, безопасностью каждого из этих аккаунтов и каждым, кто может назначать роли в вашем Discord. Взломанный аккаунт Discord члена команды, модератор, выдавший себе роль, которой у него быть не должно, или бот с правом «Administrator», которого перехватил кто-то другой, - всё это ведёт к консоли вашего сервера.
Конкретные риски:
- Повышение ролей внутри Discord. Любой с правом «Manage Roles» может выдать себе любую роль ниже собственной высшей роли. Если роль для консоли стоит низко в списке, добраться до неё может больше людей, чем вы думаете.
- Зеркалированные каналы консоли. Канал, где каждое сообщение выполняется как консольная команда и который может читать и писать какая-то роль, - самая опасная из возможных конфигураций. К тому же он показывает вывод консоли, который в Minecraft содержит IP-адреса игроков при каждом входе.
- Кража токена бота. Токен в публичном репозитории, вставленный куда-то конфиг или взломанный хостинг дают вору бота со всеми его правами в вашем Discord и всем, что он может сделать с вашим сервером. Discord сбрасывает токены, которые обнаруживает в публичных репозиториях GitHub, - это говорит о том, как часто такое случается.
- Непроверенный ввод. Бот, который передаёт в консоль любой текст, введённый пользователем, позволяет склеивать команды и выполнять произвольные, даже если вы собирались разрешить только
kick.
Правильные права с обеих сторон#
Со стороны Discord:
- Дайте боту собственную роль только с теми правами, которые он использует. Боту статуса или админ-боту обычно нужно видеть несколько каналов, отправлять сообщения и встраивать ссылки. Не давайте Administrator, Manage Server, Manage Roles и Manage Webhooks, если только они не нужны конкретной функции.
- Поставьте роль команды, которая управляет ботом, высоко в списке ролей и ограничьте круг тех, у кого есть Manage Roles, чтобы её нельзя было выдать себе самому.
- Используйте переопределения прав каналов, чтобы админ-команды бота работали только в канале команды.
- Требуйте двухфакторную аутентификацию для модерации в настройках безопасности сервера Discord - тогда Discord требует 2FA у аккаунтов, использующих права модерации.
- Используйте slash-команды с правами по умолчанию, чтобы команда была скрыта от людей без нужного права в Discord, если вы намеренно не измените это.
Со стороны игры:
- Дайте боту собственный пароль RCON, если игра это позволяет, или хотя бы пароль, отличный от того, которым пользуется команда, и меняйте его, когда бот переходит в другие руки.
- Используйте в боте белый список команд, а не чёрный.
list,kick,whitelist add- нормально. Всё, что принимает в консоль произвольный текст (обычное исключение -say), требует проверки ввода. - В играх с системой прав запускайте бота под ограниченной учётной записью. Плагины Minecraft вроде DiscordSRV умеют ограничивать консольные команды из Discord белым списком в своём конфиге; пользуйтесь этим, а не открытым доступом к консоли.
- Логируйте каждую команду, которую выполняет бот, вместе с пользователем Discord, который её запросил, в канал, который команда может читать, но не редактировать.
Подробнее о стороне RCON, в том числе о том, в каких играх его вообще можно ограничить, - в статье безопасный RCON.
Небольшой админ-бот, которому можно доверять#
Если вам нужно несколько админ-команд из Discord, а в вашей игре стандартный RCON в стиле Source (Minecraft, Rust в legacy-режиме, игры на Source и многие другие), бота такого размера достаточно, и его легко проверить. Он использует discord.py 2.x и пакет rcon из PyPI.
import osimport discordfrom discord import app_commandsfrom rcon.source import rconGUILD = discord.Object(id=int(os.environ["GUILD_ID"]))LOG_CHANNEL = int(os.environ["LOG_CHANNEL_ID"])STAFF_ROLE = "Server Staff"ALLOWED = {"list", "kick", "whitelist"}client = discord.Client(intents=discord.Intents.default())tree = app_commands.CommandTree(client)async def run(*args: str) -> str: return await rcon(*args, host=os.environ["RCON_HOST"], port=int(os.environ["RCON_PORT"]), passwd=os.environ["RCON_PASSWORD"])@tree.command(name="server", description="Run an allowed server command", guild=GUILD)@app_commands.default_permissions(kick_members=True)@app_commands.checks.has_role(STAFF_ROLE)async def server(interaction: discord.Interaction, command: str): parts = command.split() if not parts or parts[0] not in ALLOWED: await interaction.response.send_message("Not allowed.", ephemeral=True) return await interaction.response.defer(ephemeral=True) result = await run(*parts) await interaction.followup.send(f"```\n{result[:1800]}\n```", ephemeral=True) log = client.get_channel(LOG_CHANNEL) if log: await log.send(f"{interaction.user} ran `{command}`")@tree.errorasync def on_error(interaction: discord.Interaction, error): if isinstance(error, app_commands.MissingRole): await interaction.response.send_message("Staff only.", ephemeral=True)@client.eventasync def on_ready(): await tree.sync(guild=GUILD)client.run(os.environ["DISCORD_TOKEN"])Что делает его достаточно безопасным:
- Только slash-команды. Он никогда не читает обычные сообщения, поэтому ему не нужен привилегированный intent на содержимое сообщений, и никто не может вызвать его, просто написав что-то в канале.
- Две проверки.
default_permissionsскрывает команду от участников без права Kick Members, аhas_roleотказывает всем без роли команды, даже если администратор сервера изменит видимость команды. - Белый список по первому слову. Выполняться могут только
list,kickиwhitelist. Добавляйте команды по одной и осознанно. - Аргументы передаются отдельно. Команда разбивается на слова и отправляется отдельными аргументами, а не вставляется в консоль одной строкой.
- Каждое использование логируется в канал вместе с тем, кто выполнил команду.
- Никаких секретов в коде. Токен, пароль RCON и ID берутся из переменных окружения.
Когда станет понятно, какими командами команда реально пользуется, расширяйте бота отдельными командами - /kick player reason с типизированными параметрами, - а не растущим белым списком для свободного текста.
Как отправлять логи в Discord и не допускать утечек#
Логи в Discord удобны, но это и проблема приватности: каналы Discord легко читать и легко скриншотить.
- Отправляйте события, а не сырую консоль. «Anna забанила Steve: иксрей» - полезно. Сырое зеркало консоли включает IP-адреса, ошибки плагинов и всё остальное, что выводит сервер.
- Держите логи команды в каналах команды и проверяйте права. Канал логов, случайно видимый
@everyone, - частая причина того, что адреса игроков оказываются в открытом доступе. - Соблюдайте ограничения частоты. Discord ограничивает, как быстро бот или вебхук может публиковать сообщения; собирайте строки логов в одно сообщение раз в несколько секунд, а не по сообщению на строку. Обработка 429 описана в статье о вебхуках.
- Не используйте Discord как архив логов. Настоящие логи остаются на сервере со сроком хранения - об этом статья логи, которые стоит хранить, а почему это важно, объяснено в статье приватность и данные игроков на игровом сервере.
Хостинг бота и его токен#
Боту нужно работать постоянно, а значит, он не должен жить на чьём-то игровом компьютере. Хватит небольшого тарифа для хостинга приложений: бот вроде описанного выше использует заметно меньше памяти, чем есть в самом маленьком тарифе. На RE:NODE линейки Python и Node.js начинаются с 1 ГБ, переменные окружения для токена и паролей задаются на вкладке Startup, а Git deploy может при запуске подтягивать код бота из приватного репозитория GitHub. Пошаговая инструкция - в статье хостинг бота на discord.py, а тарифы - на странице хостинга приложений.
Обращайтесь с токеном как с паролем:
- Никогда не коммитьте его. Держите его в переменной окружения и добавьте локальный файл
.envв.gitignore. Этот подход описан в статье переменные окружения и секреты. - Немедленно сбрасывайте его при утечке в портале разработчиков Discord. Старый токен сразу перестаёт работать.
- Ограничьте круг тех, кто видит хостинг бота. Любой с доступом к файлам или настройкам сервера бота может прочитать его токен. Субпользователям панели можно дать доступ к консоли без доступа к настройкам и файлам.
- Знайте, кому принадлежит приложение. Бот, принадлежащий личному аккаунту Discord одного члена команды, уйдёт вместе с ним. Команды разработчиков в Discord позволяют нескольким людям управлять приложением без общего аккаунта.
Если что-то пошло не так#
Если бот начал делать то, о чём никто не просил, или вы подозреваете, что его токен или пароль RCON утекли:
- Сбросьте токен бота в портале разработчиков.
- Смените пароль RCON на игровом сервере и обновите переменную окружения бота.
- Проверьте журнал аудита Discord на изменения ролей и прав, а канал логов бота - на незнакомые команды.
- Проверьте игровой сервер на записи администраторов, баны, изменения белого списка или файлы, которые вы не создавали. Полный порядок действий - в статье что делать, если ваш сервер взломали.
FAQ#
Безопасно ли пользоваться консольным каналом DiscordSRV?
Он безопасен ровно настолько, насколько надёжны права канала и аккаунты, которые могут в нём писать. Ограничьте его несколькими доверенными членами команды, требуйте двухфакторную аутентификацию для модераторов в Discord и используйте его конфигурацию, чтобы ограничить команды, которые можно выполнять из Discord. Большинству сообществ команде удобнее работать через консоль панели.
Использовать в боте RCON или игровой плагин?
Плагин может интегрироваться глубже и часто имеет более тонкие права; RCON работает с любой игрой, которая его поддерживает, и держит бота отдельно от сервера. Для небольшого админ-бота RCON с белым списком команд проще проверить.
Можно ли запустить бота на том же тарифе, что и игровой сервер?
Запускайте его отдельно. Бот на собственном небольшом тарифе для приложений продолжает работать, когда игровой сервер перезапускается или падает, - как раз тогда, когда статус и оповещения нужнее всего, - и держит токен бота подальше от людей с доступом к файлам игрового сервера.
Нужен ли мне intent на содержимое сообщений?
Не для slash-команд. Это привилегированный intent, который нужен для чтения текста обычных сообщений. Боту, который использует только slash-команды, он не нужен, и без него бот безопаснее.
Какие права нужны боту статуса?
Просмотр канала, отправка сообщений и встраивание ссылок, а также чтение истории сообщений, если он редактирует собственное сообщение. Ему не нужно ничего, что касается ролей, участников или настроек сервера.




Комментарии
Полностью анонимно: без аккаунта, без почты, без cookie. Мы храним имя, которое вы ввели, текст и время - больше ничего. Количество ссылок ограничено, разметка не отображается.