ClickHouse Code: 516 Authentication failed: откуда у default пароль и когда дело вовсе не в пароле
ClickHouse только что установлен, первая же команда — и вместо ответа:
Code: 516. DB::Exception: default: Authentication failed: password is incorrect, or there is no user with such name.
Пароль вы не задавали, пользователь default точно существует. Чаще всего
пароль всё-таки есть — его попросил задать сам пакет при установке. Но бывает,
что пароль ни при чём: ClickHouse отвечает этой же строкой, когда пользователю
запрещено подключаться с вашего адреса. Ниже — как за минуту узнать, какой из
случаев ваш.
Одна ошибка на три разные причины
Клиенту ClickHouse всегда отвечает одним и тем же текстом, что бы ни пошло не так. В исходниках это сделано намеренно: сервер не должен подсказывать постороннему, существует ли такой пользователь. Под 516 скрываются три отказа:
- пользователь есть, но пароль не подошёл или не был передан;
- такого пользователя нет;
- пользователь есть, пароль может быть верным, но подключаться с вашего адреса ему запрещено.
Настоящая причина пишется в лог сервера. Это первое, куда стоит смотреть:
sudo grep -E 'user: .*: Authentication failed' /var/log/clickhouse-server/clickhouse-server.log | tail -5
В Docker файл лежит внутри контейнера, и команду запускают через
docker exec <контейнер>. В строке видны адрес клиента, имя пользователя,
которое пришло на сервер, и внутренняя ошибка:
| В логе | Что это значит |
|---|---|
Invalid credentials | пользователь найден, пароль не совпал |
There is no user `имя` in ... | такого пользователя нет |
Connections from <адрес> are not allowed | адреса нет в networks пользователя |
Имя пользователя в логе полезно само по себе: если вы подключаетесь через DSN или драйвер, оно покажет, что до сервера дошло на самом деле.
Для пользователя default сервер дописывает к ошибке подсказку: пароль обычно
лежит в /etc/clickhouse-server/users.d/default-password.xml, и удаление
этого файла его сбрасывает. Это верно для первого случая, но не для двух
других.
Откуда у default пароль, который вы не задавали
Пакет clickhouse-server после установки запускает clickhouse install, и
эта программа сама спрашивает:
Set up the password for the default user:
Вопрос появляется, только если вывод идёт в терминал и переменная
DEBIAN_FRONTEND не равна noninteractive. Пароль читается прямо из
терминала, поэтому на Debian и Ubuntu вопрос задаётся и при apt install, и
при dpkg -i. Скрипт после установки у rpm-пакета тот же, но dnf пишет
вывод скриптов пакета в свой журнал, а не в терминал, так что при dnf install на AlmaLinux, Rocky и RHEL вопроса нет и пароль остаётся пустым
(проверено на dnf 4). Спросить может только rpm -i, запущенный прямо из
терминала.
Дальше два варианта:
- нажали Enter — пароль пустой, программа так и пишет:
Password for the default user is an empty string; - ввели что угодно — его SHA-256 записывается в
/etc/clickhouse-server/users.d/default-password.xml.
Ловушка в том, что этот вопрос легко пропустить или ответить на него
машинально. Официальная инструкция упоминает пароль одной строкой, а в
сторонних о нём часто ни слова: установка идёт на живом терминале, человек
вводит пароль — и следующий шаг, например clickhouse-client --query "CREATE DATABASE ..." без пароля, падает с 516. Так было и в нашей
инструкции до версии 1.7.1, об этом ниже. В
исходниках ClickHouse рядом с текстом подсказки так и написано: это типичная
история — поставить, ввести пароль и тут же его забыть.
Второй источник — прошлая установка. Если на хосте уже был ClickHouse и файл
с паролем остался, повторная установка видит, что пароль задан, и вопрос не
задаёт: Password for the default user is already specified.
Проверить, где задан пароль:
sudo ls /etc/clickhouse-server/users.d/
sudo grep -rlE '<password[a-z0-9_]*>[^<]' /etc/clickhouse-server/users.d/
В стандартном users.xml пароль у default пустой, если файл не правили
руками. Файлы из users.d/ накладываются поверх users.xml в алфавитном порядке
имён, поэтому default-password.xml перекрывает пустой пароль из
users.xml: внутри стоит <password remove='1' /> и <password_sha256_hex>.
Как войти или сбросить пароль
Пароль известен. Передайте его клиенту. С ключом --password без
значения клиент спросит пароль сам, и он не останется в истории shell:
clickhouse-client --password
Пароль неизвестен. Из SHA-256 он не восстанавливается. Есть два пути.
Удалить файл — пароль у default снова станет пустым:
sudo rm -f /etc/clickhouse-server/users.d/default-password.xml
sudo systemctl restart clickhouse-server
Это безопасно, только пока сервер слушает localhost. В config.xml по
умолчанию так и есть, но проверять нужно не только его: тот же
clickhouse install сразу после пароля спрашивает Allow server to accept connections from the network и при ответе y пишет <listen_host>::</listen_host>
в config.d/listen.xml. Проверка:
sudo grep -r '<listen_host>' /etc/clickhouse-server/config.d/
Если сервер открыт в сеть, то после удаления файла default без пароля
доступен отовсюду: в стандартном users.xml у него networks разрешает любой
адрес. В этом случае задайте новый пароль вместо удаления:
PASSWORD=$(openssl rand -hex 16)
echo "$PASSWORD" # запишите: из хеша его потом не достать
HASH=$(printf '%s' "$PASSWORD" | sha256sum | awk '{print $1}')
sudo tee /etc/clickhouse-server/users.d/default-password.xml >/dev/null <<EOF
<clickhouse>
<users>
<default>
<password remove='1' />
<password_sha256_hex>$HASH</password_sha256_hex>
</default>
</users>
</clickhouse>
EOF
sudo systemctl restart clickhouse-server
Обратите внимание на printf '%s'. Частая причина 516 сразу после смены
пароля — хеш, посчитанный через echo "$PASSWORD" | sha256sum: echo
добавляет перевод строки, и в конфиг попадает хеш другого пароля.
Документация ClickHouse поэтому использует echo -n.
Пароль не должен появляться вовсе — в скриптах, Ansible и CI ставьте пакеты неинтерактивно и задавайте пароль явно файлом, как выше:
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y clickhouse-server clickhouse-client
На RHEL-семействе dnf install вопроса не задаёт и так.
Если пользователь создан SQL-командой CREATE USER, он хранится не в XML, а
в /var/lib/clickhouse/access/, и пароль ему меняют командой ALTER USER.
Docker: default закрыт от сети, хотя пароля нет
В официальном образе clickhouse/clickhouse-server 516 приходит по другой
причине. Если не задана ни одна из переменных CLICKHOUSE_USER,
CLICKHOUSE_PASSWORD и CLICKHOUSE_DEFAULT_ACCESS_MANAGEMENT, а
смонтированные конфиги не меняют default, скрипт запуска образа разрешает пользователю default подключаться только с 127.0.0.1 и
::1. Внутри контейнера clickhouse-client работает, а приложение из соседнего
контейнера получает 516 — хотя пароля нет ни у кого. В логе сервера при этом
стоит Connections from <адрес контейнера> are not allowed, а не Invalid credentials.
Что с этим делать:
- задать
CLICKHOUSE_PASSWORD— образ пересоздастdefaultс этим паролем и доступом с любого адреса; - задать
CLICKHOUSE_USERиCLICKHOUSE_PASSWORD— образ создаст вашего пользователя, аdefaultудалит совсем. Подключение подdefaultпосле этого тоже даёт 516, в логе —There is no user; CLICKHOUSE_SKIP_USER_SETUP=1возвращает открытыйdefaultбез пароля, документация образа прямо называет это небезопасным.
Свой файл, users.d/default-user.xml, образ переписывает при каждом старте
контейнера, а не только при первом. Поменяли CLICKHOUSE_PASSWORD в compose и пересоздали
контейнер — пароль сменился, даже если данные лежат в старом томе. Остальные
файлы в users.d/, которые вы смонтировали сами, образ не трогает.
Пароль верный, а 516 всё равно
- Спецсимволы в DSN. В строке вида
clickhouse://user:password@host:9000/dbпароль кодируется как часть URL:@→%40,+→%2B,%→%25, а также/,?и#. Неэкранированные@,/,?и#обычно ломают разбор ещё на клиенте, и до сервера дело не доходит. Опаснее%xxи+: они молча меняют пароль (clickhouse-clientпревращает+в пробел), и сервер отвечает 516. - HTTP-интерфейс без учётных данных. На порту 8123 запрос без имени
выполняется от
defaultс пустым паролем. Имя и пароль передаются через basic auth, параметры?user=...&password=...или заголовкиX-ClickHouse-UserиX-ClickHouse-Key. Из браузера дляdefaultпридёт тот же текст, но с кодом 194REQUIRED_PASSWORD. networksу своего пользователя. Пользователь ограничен адресом127.0.0.1, а приложение подключается через сеть контейнеров или по внешнему IP. Ответ — тот же 516, в логе —Connections from ... are not allowed.
Порядок действий
- Посмотрите имя в ошибке:
default:или ваш пользователь. Это сразу говорит, чей пароль или чьи ограничения проверять. - Найдите строку
Authentication failedв логе сервера — она назовёт одну из трёх причин. Invalid credentials— найдите, где задан пароль:users.d/,users.xmlили SQL. Войдите с паролем или задайте новый.There is no user— проверьте имя в DSN и не удалил лиdefaultобраз Docker.Connections from ... are not allowed— расширьтеnetworksпользователя или задайте пароль в Docker-образе.
Как это устроено в Gotcha
Gotcha — self-hosted observability-платформа — хранит события в ClickHouse и на установке без Docker встречалась ровно с этим вопросом пакета:
- скрипт-инсталлер на Debian и Ubuntu ставит пакеты с
DEBIAN_FRONTEND=noninteractive, а на RHEL-семействе черезdnf, где у скрипта пакета и так нет терминала, поэтому вопроса о пароле не бывает. Страница ручной установки до версии 1.7.1 этого не делала, и введённый на вопрос пароль ронял следующий шаг — создание базы — с ошибкой 516. Теперь страница ставит пакеты так же, а тест в репозитории продукта роняет сборку, если хоть одна строкаapt-get installв документации установки без Docker написана без этой переменной; - приложение не ходит в ClickHouse под
default. Инсталлер заводит пользователяgotchaвusers.d/10-gotcha.xml: SHA-256 сгенерированного пароля и доступ только с127.0.0.1и::1. Сам пароль попадает вGOTCHA_CH_DSNв/etc/gotcha/gotcha.env; - если у
defaultпароль уже есть, потому что ClickHouse стоял на хосте раньше, скрипт останавливается и предлагает создать базу вручную, а не пытается подобрать пароль.
Поэтому два возможных 516 различаются по имени в сообщении: default: — это
шаг создания базы, gotcha: — чаще всего пароль в DSN не совпадает с
паролем пользователя. Оба случая с рецептами разобраны в разделе
«Типичные ошибки»
документации.