Базы данных: MariaDB/MySQL и PostgreSQL
Установка и защита MariaDB и PostgreSQL, удалённый доступ через SSH-туннель и резервные копии.
На этой странице
В этом руководстве описано, как установить на сервер MariaDB (совместима с MySQL) или PostgreSQL, создать базу данных с отдельным пользователем, подключиться к ней со своего компьютера через SSH-туннель и настроить резервное копирование. Команды выполняются от root в SSH-сеансе (Подключение к серверу по SSH (Windows, macOS, Linux)). IP-адрес сервера указан в панели app.blackbox.md: «Инфраструктура» → «Мои серверы» (app.blackbox.md/my-servers).
Доступно: владельцу VPS-сервера с Ubuntu, Debian, AlmaLinux или CentOS Stream. Если на сервере есть панель управления (Тарифы «VPS hosting» с панелью управления), базы данных обычно создают в ней.
MariaDB или PostgreSQL
Устанавливайте ту СУБД, которая нужна вашему приложению.
| MariaDB | PostgreSQL | |
|---|---|---|
| Обычно используется для | WordPress, Joomla, Drupal, большинства PHP-приложений | многих приложений на Django, Ruby on Rails, Node.js и тех, которым нужен именно PostgreSQL |
| Пакет в Ubuntu и Debian | mariadb-server |
postgresql |
| Пакет в AlmaLinux и CentOS Stream | mariadb-server |
postgresql-server |
| Порт | 3306 | 5432 |
Для большинства приложений MariaDB заменяет MySQL без каких-либо изменений. Если приложению нужен именно MySQL, установите mysql-server в Ubuntu, AlmaLinux или CentOS Stream (в стандартных репозиториях Debian его нет). Тогда команды называются mysql и mysql_secure_installation, а имя службы и пути к файлам настроек отличаются от приведённых в этом руководстве. Не ставьте MySQL и MariaDB на один сервер.
MariaDB: установка и защита
Ubuntu и Debian
apt update
apt install -y mariadb-serverСлужба запускается автоматически и слушает только 127.0.0.1.
AlmaLinux и CentOS Stream
dnf install -y mariadb-server
systemctl enable --now mariadbЗдесь MariaDB по умолчанию слушает все сетевые интерфейсы. Привяжите её к 127.0.0.1 с помощью файла 99-local.cnf, описанного ниже.
Файл с вашими настройками
Свои настройки храните в отдельном файле 99-local.cnf (создайте его в nano или vi): в Ubuntu и Debian — в каталоге /etc/mysql/mariadb.conf.d/, в AlmaLinux и CentOS Stream — в /etc/my.cnf.d/. В AlmaLinux и CentOS Stream начните его так (в Ubuntu и Debian bind-address = 127.0.0.1 уже задан):
[mysqld]
bind-address = 127.0.0.1После каждого изменения перезапускайте службу и проверяйте, что в выводе есть 127.0.0.1:3306, а не 0.0.0.0:3306 или *:3306:
systemctl restart mariadb
ss -tlnp | grep 3306mariadb-secure-installation
mariadb-secure-installation| Вопрос | Ответ |
|---|---|
Enter current password for root (enter for none) |
Enter |
Switch to unix_socket authentication [Y/n] |
n |
Change the root password? [Y/n] |
n, если скрипт вывел «You already have your root account protected, so you can safely answer 'n'.»; иначе Y и надёжный пароль |
Remove anonymous users?, Disallow root login remotely?, Remove test database and access to it?, Reload privilege tables now? |
Y на все |
Пользователь root в MariaDB использует аутентификацию через сокет (unix_socket): войти под ним может только системный root командой mariadb, без пароля. В Ubuntu 20.04 (MariaDB 10.3) команды называются mysql_secure_installation и mysql, а на вопрос «Set root password?» ответьте n.
База данных и её пользователь
Каждому приложению — своя база и пользователь с правами только на неё. Сгенерируйте надёжный пароль и откройте консоль MariaDB:
openssl rand -base64 24
mariadbВыполните команды, подставив ИМЯ_БАЗЫ, ИМЯ_ПОЛЬЗОВАТЕЛЯ и ПАРОЛЬ:
CREATE DATABASE ИМЯ_БАЗЫ CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'ИМЯ_ПОЛЬЗОВАТЕЛЯ'@'localhost' IDENTIFIED BY 'ПАРОЛЬ';
GRANT ALL PRIVILEGES ON ИМЯ_БАЗЫ.* TO 'ИМЯ_ПОЛЬЗОВАТЕЛЯ'@'localhost';
EXIT;ИМЯ_БАЗЫ.* ограничивает права этой базой, а 'localhost' разрешает подключение только с самого сервера и через SSH-туннель. Не используйте ON *.* и '%'. Проверьте подключение под новым пользователем:
mariadb -u ИМЯ_ПОЛЬЗОВАТЕЛЯ -p ИМЯ_БАЗЫВ настройках приложения укажите хост localhost, порт 3306, имя базы, пользователя и пароль.
PostgreSQL: установка и пользователи
Ubuntu и Debian
apt update
apt install -y postgresqlСлужба запускается автоматически и слушает только localhost.
AlmaLinux и CentOS Stream
dnf install -y postgresql-server
postgresql-setup --initdb
systemctl enable --now postgresqlОткройте /var/lib/pgsql/data/pg_hba.conf. Если в строках host для 127.0.0.1/32 и ::1/128 указан метод ident, замените его на md5 (он принимает и пароли, сохранённые в формате SCRAM). Иначе приложения будут получать ошибку Ident authentication failed. Примените изменения:
systemctl reload postgresqlПользователь и база данных
sudo -u postgres createuser --pwprompt ИМЯ_ПОЛЬЗОВАТЕЛЯ
sudo -u postgres createdb --owner=ИМЯ_ПОЛЬЗОВАТЕЛЯ ИМЯ_БАЗЫНа запросы «Enter password for new role:» и «Enter it again:» введите пароль. Пользователь не будет суперпользователем: полные права у него только в базе, которой он владеет. Предупреждение could not change directory to "/root": Permission denied безвредно; его не будет, если выполнять команды из /tmp. Проверьте подключение (выход — \q):
psql -h 127.0.0.1 -U ИМЯ_ПОЛЬЗОВАТЕЛЯ ИМЯ_БАЗЫУдалённый доступ через SSH-туннель (рекомендуется)
Чтобы работать с базой из DBeaver, HeidiSQL, MySQL Workbench, pgAdmin или другого клиента на компьютере, не открывайте порт базы данных. SSH-туннель идёт через уже открытый порт 22 и шифрует трафик, а база остаётся привязанной к 127.0.0.1.
На компьютере, в терминале (macOS, Linux) или PowerShell (Windows), запустите туннель. Для MariaDB:
ssh -N -L 3306:127.0.0.1:3306 root@IP_СЕРВЕРАДля PostgreSQL:
ssh -N -L 5432:127.0.0.1:5432 root@IP_СЕРВЕРАНе закрывайте окно: туннель работает, пока выполняется команда. Закрыть его можно сочетанием Ctrl + C.
В клиенте подключайтесь к хосту
127.0.0.1, порт3306или5432, с пользователем и паролем базы данных.
Туннель использует ту же аутентификацию, что и обычное SSH-подключение: на сервере «Только ключ», если ключ лежит не в стандартном месте, укажите его через -i. Если этот порт на компьютере уже занят локальной базой, возьмите другой локальный порт, например -L 13306:127.0.0.1:3306, и подключайтесь к 127.0.0.1:13306. Пишите 127.0.0.1, а не localhost: клиент mariadb/mysql воспринимает localhost как локальный сокет и идёт в обход туннеля. Во многих графических клиентах SSH-туннель встроен в настройки подключения: SSH-хост IP_СЕРВЕРА, порт 22, пользователь root и ключ или пароль, а хост базы — 127.0.0.1.
Открытие порта базы данных (не рекомендуется)
Доступную из интернета базу данных постоянно сканируют и пытаются подобрать к ней пароли. Если внешнему сервису всё же нужно подключаться напрямую, порт должен быть открыт на обоих уровнях:
Сетевая фильтрация, которой управляет BLACKBOX, по умолчанию пропускает только SSH (22), HTTP (80), HTTPS (443) и ping, так что порты 3306 и 5432 закрыты. Настроек файрвола в панели нет: напишите в поддержку, указав IP-адрес сервера и порт (Как связаться с поддержкой BLACKBOX).
Файрвол в системе должен быть включён (см. примечание ниже) и пропускать порт только с вашего IP-адреса — его покажет Инструмент «Ваш публичный IP-адрес». Для PostgreSQL замените 3306 на 5432. С
ufw(Ubuntu, Debian):ufw allow from ВАШ_IP to any port 3306 proto tcpС
firewalld(AlmaLinux, CentOS Stream):firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="ВАШ_IP/32" port port="3306" protocol="tcp" accept' firewall-cmd --reloadMariaDB: в
99-local.cnf, в секции[mysqld], укажитеbind-address = 0.0.0.0, перезапустите службу и создайте пользователя'ИМЯ_ПОЛЬЗОВАТЕЛЯ'@'ВАШ_IP'теми же командамиCREATE USERиGRANT.PostgreSQL: в
pg_hba.conf(Ubuntu и Debian:/etc/postgresql/ВЕРСИЯ/main/pg_hba.conf; AlmaLinux и CentOS Stream:/var/lib/pgsql/data/pg_hba.conf) добавьте строкуhost ИМЯ_БАЗЫ ИМЯ_ПОЛЬЗОВАТЕЛЯ ВАШ_IP/32 МЕТОД, где метод тот же, что в строках для127.0.0.1/32(scram-sha-256илиmd5), затем выполните:sudo -u postgres psql -c "ALTER SYSTEM SET listen_addresses = '*'" systemctl restart postgresql
Если ваш IP-адрес сменится, правило придётся обновить. Без настроенного в базе TLS данные передаются в открытом виде — ещё один довод в пользу туннеля.
Внимание На новом сервере
ufwиfirewalldне включены. Прежде чем включать их, разрешите SSH и держите открытым второй SSH-сеанс: веб-консоли и VNC для клиентов нет. Порядок действий: Файрвол: сетевая фильтрация и ufw/firewalld на сервере. Если вы потеряли доступ, напишите в поддержку.
База данных на другом сервере BLACKBOX
Серверы BLACKBOX не связаны между собой частной сетью: приложение обращается к базе на другом сервере по его публичному IP-адресу, как любой компьютер из интернета. Не рассчитывайте, что порт базы данных доступен с другого сервера. Рекомендуемый вариант — постоянный SSH-туннель, который запускается на сервере приложения как служба systemd: база остаётся привязанной к 127.0.0.1, а трафик идёт в зашифрованном виде через порт 22.
Постоянный SSH-туннель (рекомендуется)
Команды приведены для MariaDB; для PostgreSQL везде замените 3306 на 5432.
На сервере приложения создайте SSH-ключ только для туннеля, без парольной фразы, чтобы его могла использовать служба:
ssh-keygen -t ed25519 -f /root/.ssh/db_tunnel_ed25519 -N "" -C db-tunnel cat /root/.ssh/db_tunnel_ed25519.pubНа сервере базы данных создайте отдельного пользователя без командной оболочки и откройте его файл
authorized_keys:useradd -m -s /usr/sbin/nologin dbtunnel mkdir -p /home/dbtunnel/.ssh nano /home/dbtunnel/.ssh/authorized_keysЗапишите одну строку: ограничения, пробел и ключ, показанный на шаге 1.
restrict,port-forwarding,permitopen="127.0.0.1:3306" ssh-ed25519 AAAA... db-tunnelЗадайте права:
chown -R dbtunnel:dbtunnel /home/dbtunnel/.ssh chmod 700 /home/dbtunnel/.ssh chmod 600 /home/dbtunnel/.ssh/authorized_keysВ AlmaLinux и CentOS Stream восстановите также метки SELinux:
restorecon -R /home/dbtunnel/.sshС такими ограничениями ключ открывает только туннель к порту базы: командной оболочки и доступа к другим портам у него нет. Не добавляйте его через «Добавить SSH-ключ» в панели: панель добавляет ключ пользователю
rootбез ограничений.На сервере приложения один раз запустите туннель вручную. При первом подключении подтвердите ключ сервера базы, ответив
yes. Пока туннель открыт, команда ничего не выводит; остановите её сочетанием Ctrl + C:ssh -N -i /root/.ssh/db_tunnel_ed25519 -L 3306:127.0.0.1:3306 dbtunnel@IP_СЕРВЕРА_БДСоздайте службу:
nano /etc/systemd/system/db-tunnel.service[Unit] Description=SSH tunnel to the database Wants=network-online.target After=network-online.target [Service] ExecStart=/usr/bin/ssh -N -i /root/.ssh/db_tunnel_ed25519 -o BatchMode=yes -o ExitOnForwardFailure=yes -o ServerAliveInterval=30 -o ServerAliveCountMax=3 -L 3306:127.0.0.1:3306 dbtunnel@IP_СЕРВЕРА_БД Restart=always RestartSec=10 [Install] WantedBy=multi-user.targetВключите службу и проверьте, что туннель слушает
127.0.0.1:3306:systemctl daemon-reload systemctl enable --now db-tunnel systemctl status db-tunnel ss -tlnp | grep 3306В настройках приложения укажите хост
127.0.0.1(неlocalhost), порт3306, имя базы, пользователя и пароль. На сервере базы достаточно пользователя, созданного для'localhost'.
ExitOnForwardFailure закрывает подключение, если туннель не удалось открыть, а ServerAliveInterval замечает оборвавшееся соединение; в обоих случаях systemd перезапускает службу через 10 секунд. BatchMode=yes не даёт службе ждать подтверждения или пароля. Если порт 3306 на сервере приложения занят локальной базой, возьмите другой локальный порт, например -L 13306:127.0.0.1:3306, и укажите его в настройках приложения. Если служба не запускается, посмотрите журнал:
journalctl -u db-tunnel -n 50Порт, открытый только для сервера приложения
Если туннель вам не подходит, попросите поддержку открыть порт 3306 или 5432 на сервере базы и выполните шаги из раздела «Открытие порта базы данных (не рекомендуется)», указав вместо ВАШ_IP IP-адрес сервера приложения: в правиле ufw или firewalld, в пользователе MariaDB ('ИМЯ_ПОЛЬЗОВАТЕЛЯ'@'IP_СЕРВЕРА_ПРИЛОЖЕНИЯ') и в строке pg_hba.conf. Без TLS данные между серверами передаются в открытом виде. Прежде чем включать файрвол, держите открытым второй SSH-сеанс: веб-консоли нет (см. примечание выше).
Резервные копии
Не копируйте файлы работающей базы: такая копия может оказаться несогласованной. Делайте выгрузку (дамп) через mysqldump или pg_dump со сжатием gzip.
Создайте скрипт
/usr/local/bin/backup-db.shи оставьте в нём только строку для вашей СУБД:#!/bin/bash set -euo pipefail cd /tmp DIR=/var/backups/db DATE=$(date +%F) mkdir -p "$DIR" chmod 700 "$DIR" # MariaDB / MySQL mysqldump --single-transaction --routines ИМЯ_БАЗЫ | gzip > "$DIR/mariadb-ИМЯ_БАЗЫ-$DATE.sql.gz" # PostgreSQL sudo -u postgres pg_dump ИМЯ_БАЗЫ | gzip > "$DIR/pg-ИМЯ_БАЗЫ-$DATE.sql.gz" # удалить выгрузки старше 7 дней find "$DIR" -name '*.sql.gz' -mtime +7 -deleteСделайте его исполняемым, запустите один раз и проверьте файлы:
chmod 700 /usr/local/bin/backup-db.sh /usr/local/bin/backup-db.sh ls -lh /var/backups/dbОткройте список заданий cron командой ниже и добавьте строку, которая запускает скрипт каждую ночь в 02:30 по времени сервера (его показывает
timedatectl):crontab -e30 2 * * * /usr/local/bin/backup-db.sh
--single-transaction выгружает таблицы InnoDB в согласованном состоянии, не блокируя их. Скрипт работает от root, который входит в MariaDB через сокет. Если вы задали пароль для root в MariaDB, сохраните его в /root/.my.cnf, в секции [client], с правами 600. Если команды crontab нет, установите пакет cron (Ubuntu, Debian) или cronie (AlmaLinux, CentOS Stream) и запустите службу. Выгрузки занимают место: следите за диском с помощью df -h (Диск сервера заполнен).
Важно Выгрузки в
/var/backups/dbлежат на том же диске, что и база: если диск выйдет из строя или сервер будет удалён, пропадут и они. BLACKBOX не делает автоматических резервных копий сервера, а кнопка «Резервные копии» на карточке сервера не работает. Регулярно копируйте выгрузки в другое место: Стратегия резервного копирования для вашего сервера
Проверяйте восстановление
Непроверенная копия может не сработать. Хотя бы раз в месяц восстанавливайте выгрузку в тестовую базу, проверяйте таблицы и удаляйте эту базу. MariaDB:
mariadb -e "CREATE DATABASE test_restore"
gunzip -c /var/backups/db/mariadb-ИМЯ_БАЗЫ-2026-10-09.sql.gz | mariadb test_restore
mariadb -e "SHOW TABLES" test_restore
mariadb -e "DROP DATABASE test_restore"PostgreSQL:
cd /tmp
sudo -u postgres createdb test_restore
gunzip -c /var/backups/db/pg-ИМЯ_БАЗЫ-2026-10-09.sql.gz | sudo -u postgres psql -q test_restore
sudo -u postgres psql -d test_restore -c '\dt'
sudo -u postgres dropdb test_restoreПеред настоящим восстановлением остановите приложение. В PostgreSQL восстанавливайте выгрузку в пустую базу, созданную командой createdb --owner=ИМЯ_ПОЛЬЗОВАТЕЛЯ.
Память на небольших тарифах
Значения по умолчанию — 128 МБ для innodb_buffer_pool_size (MariaDB) и для shared_buffers (PostgreSQL) — подходят для 1 ГБ RAM. На серверах с большим объёмом памяти их можно увеличить, но осторожно, особенно если на том же сервере работают веб-сервер или приложение. Объём памяти показывает free -h.
| RAM | Примеры тарифов | innodb_buffer_pool_size |
shared_buffers |
|---|---|---|---|
| 1 ГБ | Basic XS | 128M (по умолчанию) | 128MB (по умолчанию) |
| 2 ГБ | Basic S, CPU S, Standard S | 256M | 256MB |
| 4 ГБ | Basic M, CPU M, Standard M | 512M | 512MB |
| 8 ГБ | Basic L, CPU L, Standard L | 1G | 1GB |
Если на сервере работает только база данных, под innodb_buffer_pool_size можно выделить до половины RAM, а под shared_buffers — до четверти. Каждое подключение тоже расходует память: не увеличивайте max_connections без необходимости.
MariaDB: запишите значение в 99-local.cnf (если файл уже есть, добавьте только вторую строку в секцию [mysqld]), затем перезапустите службу и проверьте результат:
[mysqld]
innodb_buffer_pool_size = 256Msystemctl restart mariadb
mariadb -e "SELECT @@innodb_buffer_pool_size/1024/1024 AS MB"PostgreSQL (shared_buffers применяется только после перезапуска):
sudo -u postgres psql -c "ALTER SYSTEM SET shared_buffers = '256MB'"
systemctl restart postgresql
sudo -u postgres psql -c "SHOW shared_buffers"На тарифах с 1–2 ГБ RAM добавьте и swap: Добавление файла подкачки (swap). Если база данных останавливается сама по себе, проверьте, не завершила ли её система из-за нехватки памяти:
journalctl -k | grep -i "out of memory"Если это повторяется, серверу нужно больше RAM: Апгрейд сервера: переход на больший тариф.
Частые вопросы
Приложение получает «Access denied for user». Что проверить?
Имя базы, пользователя, пароль и хост: пользователь, созданный для 'localhost', подключается только с самого сервера или через туннель. Если в сообщении указано 'ИМЯ_ПОЛЬЗОВАТЕЛЯ'@'127.0.0.1', создайте пользователя и для '127.0.0.1' теми же командами CREATE USER и GRANT.
Забыли пароль пользователя базы данных. Как его сменить?
От root на сервере. В консоли mariadb:
ALTER USER 'ИМЯ_ПОЛЬЗОВАТЕЛЯ'@'localhost' IDENTIFIED BY 'НОВЫЙ_ПАРОЛЬ';В PostgreSQL команда ниже дважды запросит новый пароль:
sudo -u postgres psql -c "\password ИМЯ_ПОЛЬЗОВАТЕЛЯ"Затем обновите пароль в настройках приложения.
Как скачать выгрузку на компьютер? Выполните на компьютере команду ниже, указав нужный файл. Другие способы: Передача файлов на сервер (scp, rsync, SFTP).
scp root@IP_СЕРВЕРА:/var/backups/db/ФАЙЛ.sql.gz .Можно ли держать MariaDB и PostgreSQL на одном сервере? Да, они используют разные порты. Но память у них общая, поэтому для обеих выбирайте значения меньше, чем в таблице.