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, запущенный прямо из терминала.

Дальше два варианта:

Ловушка в том, что этот вопрос легко пропустить или ответить на него машинально. Официальная инструкция упоминает пароль одной строкой, а в сторонних о нём часто ни слова: установка идёт на живом терминале, человек вводит пароль — и следующий шаг, например 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.

Что с этим делать:

Свой файл, users.d/default-user.xml, образ переписывает при каждом старте контейнера, а не только при первом. Поменяли CLICKHOUSE_PASSWORD в compose и пересоздали контейнер — пароль сменился, даже если данные лежат в старом томе. Остальные файлы в users.d/, которые вы смонтировали сами, образ не трогает.

Пароль верный, а 516 всё равно

Порядок действий

  1. Посмотрите имя в ошибке: default: или ваш пользователь. Это сразу говорит, чей пароль или чьи ограничения проверять.
  2. Найдите строку Authentication failed в логе сервера — она назовёт одну из трёх причин.
  3. Invalid credentials — найдите, где задан пароль: users.d/, users.xml или SQL. Войдите с паролем или задайте новый.
  4. There is no user — проверьте имя в DSN и не удалил ли default образ Docker.
  5. Connections from ... are not allowed — расширьте networks пользователя или задайте пароль в Docker-образе.

Как это устроено в Gotcha

Gotcha — self-hosted observability-платформа — хранит события в ClickHouse и на установке без Docker встречалась ровно с этим вопросом пакета:

Поэтому два возможных 516 различаются по имени в сообщении: default: — это шаг создания базы, gotcha: — чаще всего пароль в DSN не совпадает с паролем пользователя. Оба случая с рецептами разобраны в разделе «Типичные ошибки» документации.