9.2 KiB
SSH-туннель от веба к БД ядра
Для Ubuntu/Debian и production Compose этого проекта. Адрес сервера ядра, SSH-порт и SSH-пользователь заменяются вашими значениями. Настройка выполняется на двух серверах. SSH-пароль и пароль MariaDB — разные данные.
Схема: app → core-db-tunnel:3306 → SSH → 127.0.0.1:13306 → MariaDB ядра.
Порт 3306 туннеля доступен только в сети контейнеров веба; на хост он не публикуется.
Ключ хранится вне репозитория в /etc/moonwell/ssh-tunnel, в образ он не копируется.
1. На сервере ядра: доступ к MariaDB через localhost
В папке с production compose.yaml ядра создайте дополнительный файл:
cat > compose.ssh-db.yaml <<'YAML'
services:
db:
ports:
- "127.0.0.1:13306:3306"
YAML
docker compose -f compose.yaml -f compose.ssh-db.yaml up -d --no-deps db
Этот шаг пересоздаёт контейнер MariaDB, сохраняя его volume; соединения с БД
прервутся на время перезапуска. Выполните его в подходящее для этого время.
Если MariaDB уже доступна на localhost сервера ядра, используйте существующий порт
и пропустите этот шаг. В будущих командах управления ядром сохраняйте
-f compose.ssh-db.yaml, чтобы порт не пропал после пересоздания БД.
Проверка:
ss -lnt | grep ':13306'
docker compose -f compose.yaml -f compose.ssh-db.yaml ps db
При использовании другого имени сервиса замените db на имя MariaDB вашего ядра.
На сервере ядра SSH должен разрешать локальный TCP forwarding
(AllowTcpForwarding yes или local); ограничения пользователя и ключа
должны разрешать 127.0.0.1:13306.
2. На сервере веба: отдельный SSH-ключ
Выполняйте команды от root, как в текущем сеансе. Подставьте адрес, SSH-порт и существующего SSH-пользователя сервера ядра:
CORE_HOST=IP_ИЛИ_ДОМЕН_ЯДРА
CORE_PORT=22
CORE_USER=SSH_ПОЛЬЗОВАТЕЛЬ
apt-get update
apt-get install -y openssh-client
install -d -m 700 /etc/moonwell/ssh-tunnel
ssh-keygen -t ed25519 -N '' \
-C moonwell-web-db-tunnel \
-f /etc/moonwell/ssh-tunnel/id_ed25519
ssh-copy-id -p "$CORE_PORT" \
-i /etc/moonwell/ssh-tunnel/id_ed25519.pub \
-o UserKnownHostsFile=/etc/moonwell/ssh-tunnel/known_hosts \
"$CORE_USER@$CORE_HOST"
ssh-copy-id запросит SSH-пароль выбранного пользователя и сохранит публичный ключ.
При первом подключении сверьте показанный fingerprint с ключом сервера ядра,
проверенным через его существующую SSH-сессию или консоль:
# На сервере ядра:
ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub
Не запускайте ssh-keygen повторно поверх существующего ключа. Если вход
по SSH-паролю отключён, добавьте содержимое id_ed25519.pub в
~/.ssh/authorized_keys выбранного пользователя через существующий доступ
и выполните первое подключение вручную с параметром UserKnownHostsFile выше.
На веб-сервере проверьте, что вход теперь работает без пароля:
chmod 600 /etc/moonwell/ssh-tunnel/id_ed25519 /etc/moonwell/ssh-tunnel/known_hosts
ssh -p "$CORE_PORT" \
-i /etc/moonwell/ssh-tunnel/id_ed25519 \
-o IdentitiesOnly=yes -o BatchMode=yes -o StrictHostKeyChecking=yes \
-o UserKnownHostsFile=/etc/moonwell/ssh-tunnel/known_hosts \
"$CORE_USER@$CORE_HOST" true
3. Настройки веба
Перенесите обновлённый compose.prod.yaml и новые файлы этого проекта на веб-сервер:
compose.prod.ssh-tunnel.yaml;docker/ssh-tunnel/Dockerfile;docker/ssh-tunnel/start.sh.
В .env веба укажите фактические SSH-данные и подключения через туннель:
CORE_SSH_HOST=IP_ИЛИ_ДОМЕН_ЯДРА
CORE_SSH_PORT=22
CORE_SSH_USER=SSH_ПОЛЬЗОВАТЕЛЬ
CORE_DB_HOST=127.0.0.1
CORE_DB_PORT=13306
VMANGOS_AUTH_DB_HOST=core-db-tunnel
VMANGOS_AUTH_DB_PORT=3306
VMANGOS_AUTH_DB_DATABASE=realmd
VMANGOS_AUTH_DB_USERNAME=vmangos
VMANGOS_AUTH_DB_PASSWORD="ПАРОЛЬ_БД_ЯДРА"
VMANGOS_CHARACTERS_DB_HOST=core-db-tunnel
VMANGOS_CHARACTERS_DB_PORT=3306
VMANGOS_CHARACTERS_DB_DATABASE=characters
VMANGOS_CHARACTERS_DB_USERNAME=vmangos
VMANGOS_CHARACTERS_DB_PASSWORD="ПАРОЛЬ_БД_ЯДРА"
Здесь CORE_DB_HOST=127.0.0.1 означает localhost сервера ядра, а не веба.
Порты 13306 (MariaDB на сервере ядра) и 3306 (туннель в сети веба) различаются.
CORE_SSH_PORT — SSH-порт, он может отличаться от 22.
Настройки DB_* MySQL самого веба и AWS_* S3 остаются прежними.
Удалите старые VMANGOS_AUTH_DB_URL и VMANGOS_CHARACTERS_DB_URL, если они
указаны: иначе Laravel может использовать адреса из URL вместо настроек выше.
VMANGOS_DOCKER_NETWORK для production с удалённым ядром не используется.
Для проверки статуса игрового сервера укажите MOONWELL_REALM_STATUS_HOST
равным доступному с веба адресу игрового сервера, а не mangosd из локального Docker.
4. Запуск на веб-сервере
Из папки moonwell-web:
docker compose -f compose.prod.yaml -f compose.prod.ssh-tunnel.yaml up -d --build core-db-tunnel
docker compose -f compose.prod.yaml -f compose.prod.ssh-tunnel.yaml ps core-db-tunnel
docker compose -f compose.prod.yaml -f compose.prod.ssh-tunnel.yaml logs --tail=30 core-db-tunnel
После состояния healthy пересоздайте приложение и nginx:
docker compose -f compose.prod.yaml -f compose.prod.ssh-tunnel.yaml up -d --no-deps --force-recreate app web
docker compose -f compose.prod.yaml -f compose.prod.ssh-tunnel.yaml exec -T --user app app php artisan config:cache
Docker запускает туннель после перезагрузки и перезапускает завершившийся SSH-процесс.
SSH keepalive обнаруживает обрыв соединения. healthy подтверждает, что SSH
создал локальный слушающий порт; доступность самой MariaDB проверяется следующим шагом.
5. Проверка из Laravel
docker compose -f compose.prod.yaml -f compose.prod.ssh-tunnel.yaml exec -T --user app app php artisan tinker --execute='foreach (["vmangos_auth", "vmangos_characters"] as $name) { DB::connection($name)->select("SELECT 1"); echo $name." OK\n"; }'
Ожидаемый результат:
vmangos_auth OK
vmangos_characters OK
Команда выполняет только SELECT 1, игровые аккаунты не меняются.
Если tinker не установлен в вашей production-сборке, проверьте наличие
laravel/tinker в production-зависимостях перед запуском этой команды.
Ошибки:
Permission denied (publickey): SSH-пользователь, публичный ключ или права файла ключа.Host key verification failed: известный ключ не соответствует адресу/порту; сверьте fingerprint и обновите файлknown_hostsчерез подтверждённое подключение.administratively prohibited: сервер SSH запретил forwarding или цель туннеля.connect failed: Connection refused: MariaDB не слушает на адресе/портуCORE_DB_HOST:CORE_DB_PORTна сервере ядра.Access denied for user: туннель работает, но неверны учётные данные или MariaDB не разрешает этому пользователю подключение с адреса хоста Docker.
Документация: OpenSSH forwarding, OpenSSH keepalive, Docker published ports.