deploy/backup/README.md — подробная пошаговая инструкция по всему, что делается вручную: пароль шифрования, SSH-ключ, VPS (пользователь fsbackup только для SFTP, проверки sshd), сборка образов, включение на Pi (с разбором каждой переменной и контрольными проверками), доступ с ПК и выгрузка, учебное восстановление на тест-клоне, восстановление прода и из архива, катастрофа «Pi умер», повседневные действия, таблица неполадок, справочник, чек-лист. Команды разделов VPS и Pi прогнаны на локальном стенде. deploy/pi, deploy/vps §8, deploy/README — ссылки на новую схему. Удалены scripts/backup.sh и scripts/restore.sh (restore.sh ещё и оставлял БД root-овой: docker cp пишет файлы с uid 0); их архивы fs_*.tar.gz восстанавливаются через fs-backup import. #64 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013jBxs9nBCk5nBdTLzcGz91
7.3 KiB
VPS (186.246.51.17) — реверс-прокси Caddy + точка входа SSH-туннелей
Единственная публичная точка. На VPS: Caddy терминирует HTTPS твоими сертификатами для двух доменов и проксирует трафик в SSH reverse-туннели от Pi (прод) и ПК (dev/test).
forbiddenstars.ru → 127.0.0.1:9000 ← Pi (autossh, постоянно) PROD
forbidden-stars.ru → 127.0.0.1:9001 ← ПК (по требованию) DEV/TEST
Туннель
ssh -Rпо умолчанию слушает на loopback VPS (127.0.0.1) — ровно туда смотрит Caddy.GatewayPortsвключать НЕ нужно. Снаружи порты 9000/9001 недоступны.
0. DNS
A-записи обоих доменов → 186.246.51.17:
forbiddenstars.ru A 186.246.51.17
forbidden-stars.ru A 186.246.51.17
Проверка: dig +short forbiddenstars.ru (и второго) должны вернуть этот IP.
1. Зайти на VPS
ssh root@186.246.51.17 # пароль введёшь сам
2. Обновление + файрвол
apt update && apt -y upgrade
apt -y install ufw curl gnupg
ufw allow OpenSSH
ufw allow 80/tcp
ufw allow 443/tcp
ufw --force enable
3. Установить Caddy (официальный репозиторий)
apt -y install debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' \
| gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' \
| tee /etc/apt/sources.list.d/caddy-stable.list
apt update && apt -y install caddy
4. Пользователь под туннели
useradd -m -s /bin/bash tunnel
install -d -m 700 -o tunnel -g tunnel /home/tunnel/.ssh
install -m 600 -o tunnel -g tunnel /dev/null /home/tunnel/.ssh/authorized_keys
Публичные ключи Pi и ПК добавишь в /home/tunnel/.ssh/authorized_keys на шагах настройки
Pi (deploy/pi/README.md) и ПК (через ssh-copy-id).
5. Сертификаты
Caddy читает PEM (текст с -----BEGIN CERTIFICATE-----). Расширение неважно — .crt
от GlobalSign обычно УЖЕ PEM. Проверь первой строкой: head -1 файл.crt.
- если
-----BEGIN CERTIFICATE-----→ это PEM, конвертировать НЕ нужно; - если бинарь/абракадабра → это DER, сконвертируй:
openssl x509 -inform DER -in файл.crt -out файл.pem.
На каждый домен нужны два файла:
fullchain.pem= твой сертификат (leaf) + промежуточный(е) GlobalSign, в одном файле, именно в таком порядке (сначала leaf, потом промежуточный).privkey.pem= приватный ключ (-----BEGIN PRIVATE KEY-----, без пароля; обычно это.key).
Удобно собрать прямо на VPS — залей свои файлы и склей:
mkdir -p /etc/caddy/certs/forbidden-stars.ru /root/certs-tmp
# с локальной машины (пример для домена forbidden-stars.ru):
scp forbidden-stars.crt intermediate.crt forbidden-stars.key root@186.246.51.17:/root/certs-tmp/
# на VPS — собрать fullchain (leaf + промежуточный) и положить ключ:
cat /root/certs-tmp/www_forbidden_stars_ru_2026_12_31.crt /root/certs-tmp/intermediate_pem_globalsign_ssl_dv_free_1.crt \
> /etc/caddy/certs/forbidden-stars.ru/fullchain.pem
cp /root/certs-tmp/forbidden-stars.key /etc/caddy/certs/forbidden-stars.ru/privkey.pem
# то же для forbiddenstars.ru (свои crt/intermediate/key), затем права
# (папкам нужен x-бит → 750, файлам 640; иначе пользователь caddy не прочитает):
chown -R caddy:caddy /etc/caddy/certs
find /etc/caddy/certs -type d -exec chmod 750 {} \;
find /etc/caddy/certs -type f -exec chmod 640 {} \;
rm -rf /root/certs-tmp
Если GlobalSign дал не отдельный промежуточный, а готовый bundle/chain — используй его как «промежуточную» часть. Если дал один файл, где leaf и chain уже вместе, — это и есть
fullchain.pem(склейка не нужна).
6. Caddyfile + страница-заглушка
Скопируй deploy/vps/Caddyfile из репозитория в /etc/caddy/Caddyfile и положи страницу
«сайт недоступен» (показывается, когда туннель к хосту лежит — вместо зависшей «Загрузки» SPA):
mkdir -p /etc/caddy/maintenance
# с локальной машины:
scp deploy/vps/maintenance.html root@186.246.51.17:/etc/caddy/maintenance/maintenance.html
# на VPS:
caddy validate --config /etc/caddy/Caddyfile
systemctl reload caddy
Заглушка живёт в сниппете
(offline)Caddyfile: при ответе апстрима 502/503/504 Caddy отдаёт/etc/caddy/maintenance/maintenance.htmlсо статусом 503 иCache-Control: no-store. Правки текста/вида — вdeploy/vps/maintenance.html, затем повториscp(reload Caddy не нужен, файл читается на каждый запрос).
7. Проверка
- Подними туннель прода на Pi (см.
deploy/pi/README.md) и/или dev/test на ПК (run.ps1приLOCAL_PUBLIC=vps). - Открой
https://forbiddenstars.ruиhttps://forbidden-stars.ru. - Пока соответствующий туннель не поднят — Caddy отдаёт страницу-заглушку «Технические шоколадки» (HTTP 503), это ожидаемо.
Логи Caddy: journalctl -u caddy -f.
8. Приём бэкапов с Pi (оффсайт-копии)
Контейнер backup на Pi каждую ночь отправляет зашифрованный снимок (restic) на VPS по SFTP.
Для этого на VPS нужен отдельный пользователь fsbackup только для SFTP: без shell,
без туннелей, без пароля. Репозиторий лежит в /srv/fs-backups/restic, вне веб-корней
Caddy, так что бэкапы не публичны.
Имя не
backup: в Debian/Ubuntu системный пользовательbackupуже существует.
Пошаговая настройка: создание пользователя, ключ, sshd_config.d/60-fs-backup.conf,
проверки — deploy/backup/README.md, шаг 3.
Проверка приёма после первого бэкапа: ls -la /srv/fs-backups/restic (там config, data,
index, keys, snapshots). Старые снимки удаляет сам контейнер с Pi по политике хранения.