Valkey без аутентификации, доступный из интернета, - это не утечка данных, а удалённый shell. Набор команд позволяет клиенту изменить, куда сервер пишет файл снимка и как этот файл называется, а этого достаточно, чтобы положить на машину ключ SSH или файл cron от имени пользователя, под которым работает Valkey. Автоматические сканеры находят открытые экземпляры за считанные минуты, и после себя они обычно оставляют майнер криптовалюты. Каждый шаг защиты ниже существует из-за этого одного факта.
Защита в порядке важности: никогда не выставляйте сервер наружу без аутентификации; используйте длинный случайный пароль; дайте каждому приложению собственного пользователя ACL только с теми ключами и командами, которые ему нужны; держите административные и разрушительные команды подальше от учётных данных приложений; и помните, что протокол текстовый и открытый, если не настроен TLS. В этой статье разобран каждый пункт с настоящей конфигурацией и командами.
Почему открытые экземпляры взламывают#
Атака старая и простая, а понимание её устройства объясняет защиту.
- Просканировать интернет в поисках порта
6379(и других распространённых портов), отвечающего на протоколе Redis. - Отправить
INFO. Если ответ пришёл безNOAUTH, экземпляр открыт. - С помощью
CONFIG SET dirиCONFIG SET dbfilenameнаправить вывод снимка в чувствительное место -/root/.ssh/иauthorized_keysили каталог cron. - Записать ключ, значение которого содержит открытый ключ SSH или строку cron, выполнить
SAVE- и файл снимка теперь содержит рабочую нагрузку. - Войти по SSH или дождаться cron и установить майнер.
Варианты загружают вредоносный модуль через MODULE LOAD или злоупотребляют репликацией через REPLICAOF, чтобы подтянуть модуль с сервера злоумышленника. Всем им нужны две вещи: подключение без аутентификации и право выполнять административные команды. Уберите любую - и атака не удастся.
Современный Valkey уже частично закрывает это по умолчанию. enable-protected-configs, enable-debug-command и enable-module-command по умолчанию равны no, что блокирует изменение чувствительных путей вроде dir во время работы и блокирует MODULE LOAD со стороны клиентов. Это реальное улучшение по сравнению с серверами нескольколетней давности, но всё равно не повод оставлять экземпляр открытым: сами данные может читать, менять и удалять любой, кто подключится.
Protected mode и привязка к интерфейсу#
Две настройки решают, кто вообще может подключиться.
bind 127.0.0.1 -::1protected-mode yesport 6379bind перечисляет интерфейсы, на которых слушает Valkey. На машине, где он нужен только локальным процессам, правильный ответ - loopback, и это сразу убирает большую часть риска. Ведущий - в -::1 означает «не отказываться от запуска, если этот адрес недоступен».
protected-mode yes - это страховочная сетка: если пароль не задан и bind не менялся с значения по умолчанию, сервер отказывает в подключениях откуда-либо, кроме loopback, и сообщает клиенту причину. Он не защищает экземпляр, явно привязанный к публичному адресу без пароля, - сервер считает, что это ваш сознательный выбор.
Когда приложение работает на другой машине, что для размещённого у провайдера Valkey - обычный случай, сервер должен слушать доступный адрес, и главной защитой становится пароль. Ограничение адресов-источников, которым разрешено подключаться, на файрволе перед портом добавляет вторую линию там, где этим файрволом управляете вы.
В RE:NODE тариф Valkey создаётся с паролем, сгенерированным для этого сервера, и доступен по собственному хосту и порту тарифа; у тарифов баз данных нет слота прокси перед ними. Экземпляр никогда не продаётся без аутентификации, что устраняет классическую ошибку. За вами остаётся не допускать пароль туда, где ему не место, и всё остальное из этой статьи.
Пароли: requirepass и AUTH#
Простейшая аутентификация - один общий пароль:
requirepass 9fK2pQ7x-a-long-random-string-from-a-generatorТогда клиенты проходят аутентификацию командой AUTH <password> перед любой другой командой или указывают пароль в URL подключения: redis://:password@host:port/0. Внутри requirepass задаёт пароль встроенного пользователя ACL default, поэтому AUTH default <password> тоже работает.
Требования к паролю здесь иные, чем у формы входа. Valkey настолько быстр, что злоумышленник, способный подключиться, может перебирать огромное число паролей в секунду, а блокировки нет. Используйте 32 и больше случайных символов из генератора, а не запоминающуюся фразу. Сгенерировать пароль можно так:
$ openssl rand -base64 32Если пароль пойдёт в URL, избегайте @, /, : и # или кодируйте их через проценты, потому что во многих клиентах они ломают разбор URL, - либо используйте openssl rand -hex 32, который выдаёт только безопасные символы.
Храните пароль там же, где остальные секреты: в переменных окружения или хранилище секретов, никогда не коммитьте его в репозиторий и не вставляйте в чат поддержки или трекер задач. Где им место, описано в статье переменные окружения и секреты, а чек-лист безопасности баз данных применим к Valkey так же, как к любому SQL-серверу.
Смена одного общего пароля означает одновременную замену на сервере и во всех клиентах, что неудобно. Пользователи ACL решают и это.
Откуда пароли утекают на практике
Пароль редко крадут из самого Valkey. Он утекает из окружения:
- Логи. URL подключения, напечатанный при запуске («connecting to redis://:hunter2@...»), попадает в файлы логов, системы сбора логов и на скриншоты. Логируйте хост и порт, но никогда не URL.
- Отчёты об ошибках. Трекеры исключений по умолчанию захватывают переменные окружения и объекты конфигурации. Вычищайте переменную, в которой лежит URL.
- Клиентские сборки. Сборка фронтенда, читающая переменные окружения, может встроить переменную, предназначенную только для сервера. Учётные данные Valkey никогда не должны попадать в браузер.
- Общие экраны и тикеты. Вставленный куда-то файл
.env- это опубликованный пароль. - Бывшие участники команды. Один общий пароль, который знают все, кто когда-либо работал над проектом, - это пароль, который невозможно отозвать у одного человека.
Последний пункт - самый сильный довод в пользу отдельных пользователей ACL для каждого приложения и регулярной смены паролей как рутины, а не экстренной меры. Когда кто-то уходит, меняйте пароль.
Пользователи ACL: по одному на приложение#
Списки управления доступом, унаследованные от архитектуры Redis 6, позволяют создавать именованных пользователей, у каждого из которых свои пароли, набор разрешённых команд и набор разрешённых шаблонов ключей. Смысл - минимальные привилегии: взломанное веб-приложение не должно иметь возможности выполнить FLUSHALL, прочитать ключи другого приложения или перенастроить сервер.
ACL SETUSER shop on >s3cr3t-shop-password ~shop:* &shop:* +@all -@dangerousACL SETUSER reports on >s3cr3t-report-password ~shop:* resetchannels -@all +@read +pingACL SETUSER default offЧитаем первую строку слева направо:
| Правило | Значение |
|---|---|
on | Пользователь включён |
>password | Добавляет пароль (у пользователя их может быть несколько) |
~shop:* | Доступ только к ключам, подходящим под shop:* |
&shop:* | Может использовать каналы pub/sub, подходящие под shop:* |
+@all | Разрешает все категории команд... |
-@dangerous | ...затем убирает категорию опасных |
Правила применяются по порядку, так что +@all -@dangerous - это «всё, кроме опасных команд». Второй пользователь только читает и не имеет никаких каналов. Третья строка отключает пользователя default, а значит, никто не сможет подключиться, не назвав имя пользователя, - делайте это только убедившись, что каждый клиент проходит аутентификацию с именем пользователя.
Клиенты проходят аутентификацию через AUTH shop <password> или с именем пользователя в URL: redis://shop:password@host:port/0. Большинство актуальных клиентских библиотек это поддерживают; очень старые, которые отправляют только AUTH <password>, могут использовать лишь пользователя default.
Полезные команды для проверки:
ACL WHOAMIACL LISTACL GETUSER shopACL CAT dangerousACL DRYRUN shop FLUSHALLACL LOG 10ACL DRYRUN проверяет, разрешена ли пользователю команда, не выполняя её. ACL LOG записывает недавние отказы и неудачные попытки аутентификации, а это и инструмент отладки, и раннее предупреждение о том, что кто-то подбирает пароли.
Пользователи, созданные через ACL SETUSER, живут в памяти. Чтобы пережить перезапуск, их нужно сохранить: либо в файл ACL, заданный через aclfile и записываемый командой ACL SAVE, либо в valkey.conf в виде строк user с сохранением через CONFIG REWRITE. Если забыть этот шаг, тщательно настроенные права исчезнут при следующем перезапуске.
Можете ли вы сами управлять пользователями ACL на размещённом у провайдера экземпляре, зависит от прав выданного вам пользователя. Выполните ACL WHOAMI и ACL LIST; если вторая команда запрещена, ваш пользователь не может администрировать ACL, и границей доступа служит сгенерированный пароль - поэтому обращаться с ним нужно как с паролем root.
Опасные команды#
Категория @dangerous - это набор команд, которые приложению выполнять незачем. Самые важные из них:
| Команда | Риск |
|---|---|
FLUSHALL, FLUSHDB | Мгновенно удаляет всё |
CONFIG | Читает и меняет настройки сервера |
KEYS | Обходит всё пространство ключей одним блокирующим вызовом |
DEBUG | Может обрушить или подвесить сервер |
SHUTDOWN | Останавливает сервер |
MODULE | Загружает нативный код |
REPLICAOF, SLAVEOF | Превращает сервер в реплику сервера злоумышленника |
SAVE | Блокирующий снимок |
MONITOR | Транслирует каждую команду каждого клиента, включая пароли |
Подкоманды CLIENT | Перечисляют и обрывают чужие подключения |
Старый способ отключать команды - rename-command в файле конфигурации, переименовывающий FLUSHALL в пустую строку или случайное имя. Он по-прежнему работает, но действует по принципу «всё или ничего» для всех пользователей и ломает инструменты, ожидающие, что команда существует. ACL - инструмент получше: пользователь приложения просто не может выполнить FLUSHALL, а пользователь-администратор по-прежнему может.
KEYS заслуживает отдельного упоминания, потому что опасна скорее по случайности, чем по злому умыслу. Отладочная строка разработчика с KEYS * на продакшен-экземпляре с миллионами ключей замораживает его на секунды. Используйте SCAN с шаблоном MATCH и уберите KEYS у пользователей приложений.
Шифрование при передаче#
Протокол Redis - открытый текст. Без TLS команда AUTH, пароль в ней и каждое значение, которое вы читаете и пишете, идут по сети в виде, доступном для чтения любому на пути.
Valkey поддерживает TLS, если собран с ним; настраивается он через tls-port, tls-cert-file, tls-key-file и tls-ca-cert-file, а клиенты подключаются по схеме rediss:// (с двумя s). Предлагает ли конкретный размещённый экземпляр TLS на своём порту - это свойство самой услуги, так что проверьте, прежде чем на это рассчитывать: если в тарифе указаны только хост и порт, считайте, что это обычный TCP. Там, где TLS недоступен:
- Держите приложение и Valkey в одной локации, чтобы трафик не ходил по публичному интернету больше необходимого.
- Не храните в Valkey данные, чтение которых при передаче стало бы серьёзным инцидентом: номера карт, персональные записи в открытом виде, долгоживущие секреты.
- Меняйте пароль, если у вас когда-либо появятся подозрения насчёт канала между приложением и сервером.
Никогда не ставьте Valkey за HTTP обратный прокси в надежде, что тот добавит шифрование. Протокол - не HTTP; веб-прокси не умеет его передавать, а TLS-терминатор на уровне TCP перед ним защищает лишь участок до этого терминатора.
Мониторинг, смена паролей и реагирование на инциденты#
Безопасность - это ещё и умение заметить, что что-то не так.
- Следите за `ACL LOG` на предмет повторяющихся неудачных аутентификаций. Всплеск с незнакомого адреса означает, что кто-то подбирает пароль.
- Следите за `INFO clients`:
connected_clientsнамного выше того, что открывает ваше приложение. Неожиданные подключения стоит расследовать. - Следите за `INFO keyspace` и памятью. Пространство ключей, которое внезапно опустело или заполнилось незнакомыми ключами с именами вроде
backup1,backup2и странными значениями, - это почерк атаки, описанной в начале. - Меняйте пароли, пользуясь поддержкой нескольких паролей в ACL: добавьте пользователю новый пароль, разверните его во всех клиентах, затем удалите старый через
<oldpassword. Без простоя и без «дня икс».
Если вы нашли признаки взлома, считайте, что данные были прочитаны и, возможно, изменены. Смените все учётные данные, хранившиеся в Valkey или использовавшиеся вместе с ним, смените пароль Valkey, проверьте машины, которые к нему подключаются, и восстановите данные из заведомо хорошей копии, если значения могли быть подменены. Общий порядок действий - в статье что делать, если ваш сервер взломали.
Чек-лист#
- Аутентификация включена: пароль из 32 и более случайных символов или пользователи ACL.
- Порт доступен только тому, кому нужен: loopback на одной машине, список разрешённых адресов на файрволе там, где вы им управляете.
- У каждого приложения свой пользователь ACL, ограниченный своим префиксом ключей и без
@dangerous, если вы можете создавать пользователей. - Пользователь
defaultотключён или имеет сильный пароль. - Изменения ACL сохранены в файл ACL или в конфигурацию, чтобы пережить перезапуск.
- Пароли живут в переменных окружения или хранилище секретов, а не в коде.
- TLS используется там, где он предлагается; где нет - чувствительные данные в Valkey не попадают.
- За
ACL LOG, числом клиентов и памятью следят. - Есть план смены паролей, не требующий простоя.
FAQ#
Достаточно ли одного requirepass?
Для одного приложения с длинным случайным паролем и портом, открытым не шире, чем необходимо, это разумный базовый уровень. Пользователи ACL добавляют минимальные привилегии и безболезненную смену паролей, и их значение растёт с числом приложений, делящих один экземпляр.
Можно ли спрятать Valkey, сменив порт?
Это уменьшает шум от самых ленивых сканеров и больше ничего. Сканеры проверяют все порты, а протокол легко распознать. Меняйте порт, если хотите, но защищает вас аутентификация.
Почему клиент пишет NOAUTH после того, как я задал имя пользователя?
Клиент отправляет AUTH <password> без имени пользователя, и сервер проверяет пароль у пользователя default. Укажите имя пользователя в URL или в соответствующем параметре клиента и проверьте, что версия библиотеки поддерживает аутентификацию ACL.
Хранятся ли пароли ACL в открытом виде?
Нет. Valkey хранит хэши SHA-256 паролей ACL, и ACL GETUSER показывает хэши, а не пароли. При этом сам пароль идёт по сети открытым текстом, если не используется TLS.
Должны ли кэш и хранилище сессий использовать разных пользователей?
Да, если это разные приложения или у них разный уровень доверия. Отдельные пользователи с отдельными префиксами ключей означают, что ошибка или взлом одного не позволит прочитать или стереть данные другого.




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