Skip to content
VDS · Бази даних

Користувачі та права в базі даних

Як створити окремого користувача для кожного застосунку в MySQL і PostgreSQL, надати мінімальні права та переконатися, що зайвого не дозволено.

Оновлено 23 серпня 2026 р.

Застосунок, що працює від root або postgres, віддає зловмиснику всі бази даних на машині вже за першої вразливості. Окремий користувач із правами лише на власну схему обмежує збитки одним проєктом.

MySQL і MariaDB

Користувач тут — це пара «ім'я та хост», і саме це найчастіше плутає:

CREATE USER 'shop'@'localhost' IDENTIFIED BY 'long-random-password';
GRANT SELECT, INSERT, UPDATE, DELETE ON shop.* TO 'shop'@'localhost';
FLUSH PRIVILEGES;

'shop'@'localhost' і 'shop'@'%' — це два різні користувачі з різними паролями. Не створюйте записи з хостом %, якщо в цьому немає потреби: він дозволяє вхід з будь-якої адреси.

Права на структуру потрібні лише під час міграцій:

GRANT CREATE, ALTER, DROP, INDEX, REFERENCES ON shop.* TO 'shop_migrate'@'localhost';

Розділяти роль застосунку та роль для міграцій — добра практика: звичайний запит тоді фізично не зможе видалити таблицю.

Перевірка:

SELECT user, host FROM mysql.user;
SHOW GRANTS FOR 'shop'@'localhost';

Зміна пароля та видалення:

ALTER USER 'shop'@'localhost' IDENTIFIED BY 'new-password';
DROP USER 'shop'@'localhost';

PostgreSQL

Роль та її права на базу даних і схему:

CREATE ROLE shop WITH LOGIN PASSWORD 'long-random-password';
CREATE DATABASE shop OWNER shop;
REVOKE ALL ON DATABASE shop FROM PUBLIC;

Для ролі лише з читанням (звіти, аналітика, панель моніторингу):

CREATE ROLE reader WITH LOGIN PASSWORD '...';
GRANT CONNECT ON DATABASE shop TO reader;
GRANT USAGE ON SCHEMA public TO reader;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO reader;
ALTER DEFAULT PRIVILEGES IN SCHEMA public
  GRANT SELECT ON TABLES TO reader;

Останній рядок обов'язковий: без нього роль не бачитиме таблиць, створених після надання прав, і за місяць звіти зламаються на нових даних.

Перевірка:

\du
\l
\dp

Що потрібно закрити

  • Жодна роль застосунку не є суперкористувачем.
  • Кожен проєкт має власну базу даних і власного користувача.
  • Паролі довгі та випадкові, і різні для різних проєктів.
  • Зовнішній вхід дозволений лише для тих адрес, яким він потрібен — віддалений доступ.
  • У MySQL немає анонімних користувачів і тестової бази даних: це робить mariadb-secure-installation.

Типові помилки

СимптомПричина
Access denied з правильним паролемСпрацювало інше правило хоста, наприклад ''@'localhost'
Права надано, але SELECT не працюєУ PostgreSQL бракує USAGE ON SCHEMA
Роль не бачить нової таблиціНе налаштовано DEFAULT PRIVILEGES
Застосунок видалив усе під час невдалої міграціїРоль застосунку мала права DROP
Пароль видно в історії командЗадавайте паролі з файлу, очищуйте ~/.mysql_history

Зберігайте паролі до баз даних у файлі середовища сервісу з правами 600, а не в коді. У разі компрометації ви змінюєте один рядок і перезапускаєте сервіс, а не перебудовуєте весь проєкт.