MariaDB через VPN: какой user@host видит сервер?
Учётная запись выбирается по пользователю и хосту вместе. Найдите источник, который увидел сервер, прочитайте CURRENT_USER() и затем исправьте ту строку, а не привилегию.
Введите одно и то же имя пользователя двумя разными путями, и MariaDB может аутентифицировать вас как две разные учётные записи. Записи привязаны к пользователю и хосту вместе, поэтому 'reporter'@'localhost' и 'reporter'@'10.90.0.23' — отдельные строки с отдельными паролями и отдельными привилегиями. Через VPN интересен не вопрос, какое имя ввёл пользователь, а какой адрес источника увидел сервер.
Определите источник, который сервер действительно видит
Работайте в обратном направлении от хоста базы данных, а не от ноутбука. Адрес, который клиент считает своим, — лишь один из нескольких вариантов:
| Path | Source MariaDB sees |
|---|---|
| Routed tunnel, no translation | The client's inner VPN address |
| Gateway source translation | The gateway's translated address |
| SSH local forward | The SSH server's address |
| Public exit, no tunnel | Whatever the ISP handed out |
Используйте доказательства на стороне сервера, чтобы решить это. Журнал подключений, список активных сеансов или временная запись в общем журнале показывают адрес, который сервер принял. Публичный IP ноутбука из браузера — другой факт, и часто вводящий в заблуждение.
Сопоставьте учётную запись, которую выбрала MariaDB
Выбор учётной записи следует задокументированному порядку, а не объединению привилегий. Точное совпадение хоста имеет приоритет перед подстановочным знаком, а строки анонимного пользователя участвуют в сопоставлении так, что это удивляет тех, кто считает, что решает одно имя. Сервер выбирает одну строку; он не объединяет привилегии каждой одноимённой строки. Прочитать справочник один раз ценнее, чем полдня перебирать догадки.
Это значит, что добавление привилегии к 'reporter'@'%' может ничего не изменить, если сеанс аутентифицировался как 'reporter'@'10.90.0.23'. Исправление должно попасть в ту строку, которая была выбрана, поэтому идентификация учётной записи предшествует правке привилегий.
Прочитайте учётную запись, которую сеанс действительно использует
SELECT USER(), CURRENT_USER();
SHOW GRANTS;
CURRENT_USER() называет учётную запись, аутентифицировавшую сеанс; USER() сообщает, что запросил клиент, и может отличаться. Выполняйте их как обычные запросы верхнего уровня, а не изнутри хранимой процедуры с контекстом определителя, иначе ответы опишут владельца процедуры, а не ваш сеанс.
Неудачный вход не может выполнить ничего из этого, и это тот случай, когда администратор должен проверить определения учётных записей и доказательства подключения сервера. Планируйте это: у человека, отлаживающего отклонённый вход, обычно нет SQL-сеанса, чтобы задать вопрос.
Отделите доступность от аутентификации
Текст ошибки говорит, на каком уровне вы находитесь. Отказ в соединении или тайм-аут означает, что клиент так и не достиг слушателя, поэтому учётная запись и её пароль пока не под вопросом. Ответ об отказе в доступе означает, что сервер ответил, что доказывает доступность и указывает на учётную запись, совпадение хоста или учётные данные.
Сетевые предпосылки — отдельный список: слушатель, привязанный к нужному адресу, а не только к loopback, разрешённый трафик на настроенный порт и обратный маршрут для ответа. Каждый может отказать независимо, и работающий туннель не подразумевает ни одного из них. Слушатель на loopback принимает локальные соединения и отклоняет все удалённые, что даёт отказ в соединении, похожий на блокировку брандмауэра.
Проверьте адрес привязки, прежде чем открывать заявку сетевой команде. ss -lntp на хосте базы данных показывает, какой адрес и порт действительно слушают, и эта одна строка исключает целую категорию догадок.
Исправляйте точечно, затем проверьте оба направления
Создайте нужную учётную запись, квалифицированную хостом, через утверждённый процесс организации, с учётными данными из поддерживаемого хранилища, а не общими, вставленными в заявку. Выдайте только те операции со схемой, которые нужны задаче. Превращение неудачного удалённого входа в root-запись, политику выдачи всего или общий подстановочный хост заставляет тест пройти и убирает контроль, который вы проверяли. Привилегия, добавленная в спешке, — та, которую потом никто не удаляет.
Повторите проверку с новым сеансом по нужному пути, затем проверьте отрицательные случаи. Путь, который должен быть заблокирован, должен остаться заблокированным, а операция, которая не была выдана, должна остаться запрещённой. Эти две проверки отличают исправленную учётную запись от расширенной.
Наконец, запишите наблюдаемый адрес источника и имя учётной записи вместе. Туннель обеспечивает доступность; MariaDB по-прежнему выбирает и авторизует свою учётную запись, а следующему человеку нужны оба факта, чтобы воспроизвести ваш результат.