Как настроить сервер резервных копий в Proxmox LXC через HTTPS PUT без SSH

Содержание16 разделов
Централизованный сервер резервных копий можно развернуть в LXC-контейнере Proxmox VE без Proxmox Backup Server, SFTP и выдачи SSH-доступа каждому источнику. Если приложения уже создают готовые архивы .tar.gz, .zip или дампы баз данных, достаточно принимать их по HTTPS методом HTTP PUT.
В инструкции используется Debian 13, Nginx, индивидуальные HTTP-учётные записи и отдельный том для хранения файлов. Получится простой приёмник бэкапов для Linux-серверов, Windows и других систем, способных отправлять HTTP PUT-запросы.
Как работает схема резервного копирования
Linux / Windows / приложение
|
| HTTPS PUT :443 + индивидуальный пароль
v
Proxmox VE → LXC Debian 13 → Nginx
|
+-- /srv/backups/server1/
+-- /srv/backups/server2/
+-- /srv/backups/.tmp/
|
отдельный том / ZFSКаждому источнику назначаются собственный URL и пароль. Сервер server1 загружает архивы в https://backup.example.com/server1/, а server2 — в /server2/. SSH на стороне отправителей не используется.
Решение подходит именно для готовых файлов. Nginx не выполняет инкрементальное копирование, дедупликацию, создание архивов и восстановление систем: эти задачи остаются за программами резервного копирования.
Что потребуется
- Proxmox VE с возможностью создать непривилегированный LXC-контейнер на Debian 13.
- Отдельный том для архивов, желательно на ZFS или другом хранилище со снапшотами.
- Домен, например
backup.example.com, направленный на внешний IP сервера или маршрутизатора. - Доступ извне к TCP 443. Для выпуска и продления сертификата Let’s Encrypt методом HTTP-01 также потребуется TCP 80.
- Программы-отправители, которые создают архивы и могут выполнить
curlили аналогичный HTTP PUT-запрос.
Все IP-адреса, домены и имена серверов ниже приведены как примеры. При работе за NAT нужно настроить переадресацию портов на IP контейнера. Если приём доступен только через VPN, сертификат можно выпускать через DNS-01, не открывая порт 80 в интернет.
Шаг 1. Создание LXC-контейнера в Proxmox
В веб-интерфейсе Proxmox VE выбрать Create CT и указать следующие параметры:
Параметр | | Рекомендуемое значение | |
|---|---|
Hostname | | backup-server | |
Template | | Debian 13 | |
Unprivileged container | | Включено | |
CPU | | 1 vCPU | |
RAM | | 512 МБ – 1 ГБ | |
Root Disk | | 8 ГБ | |
Network | | Статический IP в локальной сети | |
После создания контейнера открыть CT → Resources → Add → Mount Point, выбрать нужное хранилище и подключить отдельный том по пути /srv/backups. Размер зависит от объёма и срока хранения архивов. Для большого хранилища не следует использовать маленький корневой диск LXC.
Если создаётся управляемый Proxmox mount point, параметр Backup определяет, попадёт ли его содержимое в vzdump. Для большого архива часто удобнее отключить включение в бэкап контейнера и настроить резервирование данных отдельно. Bind mount имеет другую семантику: его данные в vzdump не включаются.
Запустить контейнер, открыть его консоль и убедиться, что хранилище действительно подключено:
findmnt /srv/backups
df -h /srv/backupsЕсли findmnt не показывает отдельный mount point, сначала исправить подключение тома. Иначе архивы могут незаметно заполнить корневой диск контейнера.
Шаг 2. Установка Nginx и необходимых пакетов
Все последующие команды выполняются от root внутри LXC через консоль Proxmox:
apt update && apt upgrade -y
apt install -y nginx apache2-utils certbot python3-certbot-nginx curlДля приёма HTTP PUT нужен модуль ngx_http_dav_module. Проверить поддержку в установленной сборке Nginx:
nginx -V 2>&1 | grep -- '--with-http_dav_module'Если строка --with-http_dav_module отсутствует, требуется сборка Nginx с этим модулем. Штатный DAV-модуль обрабатывает PUT, DELETE, MKCOL, COPY и MOVE, но сам по себе не является полноценным WebDAV-сервером для клиентов, которым нужны PROPFIND и другие методы.
Шаг 3. Подготовка каталогов для резервных копий
Создать директории для двух источников и временных файлов загрузки:
install -d -o root -g www-data -m 0750 /srv/backups
install -d -o www-data -g www-data -m 0700 \
/srv/backups/server1 \
/srv/backups/server2 \
/srv/backups/.tmpСтруктура каталогов:
/srv/backups/
├── .tmp/
├── server1/
└── server2/Каталог .tmp должен находиться на той же файловой системе, что и конечные файлы: Nginx сначала пишет тело PUT-запроса во временный файл, после чего перемещает его в целевой каталог. На разных файловых системах вместо быстрого переименования потребуется копирование.
Пример рассчитан на стандартного пользователя процесса Nginx в Debian — www-data. При использовании bind mount в непривилегированном LXC могут понадобиться дополнительные настройки UID/GID на хосте Proxmox.
Шаг 4. Создание отдельных учётных записей
Для авторизации используется HTTP Basic Authentication через HTTPS. Пользователи существуют только в файлах .htpasswd; системные аккаунты Linux и доступ по SSH не создаются.
install -d -o root -g www-data -m 0750 /etc/nginx/backup-auth
htpasswd -cB /etc/nginx/backup-auth/server1.htpasswd server1
htpasswd -cB /etc/nginx/backup-auth/server2.htpasswd server2
chown root:www-data /etc/nginx/backup-auth/*.htpasswd
chmod 0640 /etc/nginx/backup-auth/*.htpasswdКаждая команда htpasswd запросит пароль. Для каждого источника используется отдельный файл — поэтому параметр -c здесь безопасен. При добавлении нового пользователя в уже существующий файл -c использовать нельзя: он перезаписывает файл.
Благодаря разделению файлов аутентификации пароль server1 не подходит к URL /server2/. Учётные данные передаются только через действительный HTTPS-сеанс; без TLS HTTP Basic использовать нельзя.
Шаг 5. Настройка домена и сертификата Let’s Encrypt
Убедиться, что домен backup.example.com указывает на доступный контейнер, а TCP 80 и 443 корректно перенаправлены. На новом LXC можно отключить стандартный сайт Nginx:
rm -f /etc/nginx/sites-enabled/defaultСоздать временную конфигурацию виртуального хоста:
cat > /etc/nginx/sites-available/backup-upload <<'EOF'
server {
listen 80;
server_name backup.example.com;
location / {
return 404;
}
}
EOFln -s /etc/nginx/sites-available/backup-upload \
/etc/nginx/sites-enabled/backup-upload
nginx -t && systemctl reload nginxВыпустить TLS-сертификат:
certbot certonly --nginx -d backup.example.comCertbot запросит необходимые данные для регистрации и выполнит проверку владения доменом. Сертификат будет сохранён в /etc/letsencrypt/live/backup.example.com/. Если порт 80 недоступен из интернета, проверка HTTP-01 не пройдёт.
Шаг 6. Конфигурация Nginx для загрузки только через PUT
Заменить содержимое /etc/nginx/sites-available/backup-upload конфигурацией ниже. В ней предусмотрены два независимых URL, два файла авторизации и разрешён только метод PUT.
server {
listen 80;
server_name backup.example.com;
# Порт 80 используется для проверки Let's Encrypt.
location / {
return 404;
}
}
server {
listen 443 ssl;
server_name backup.example.com;
ssl_certificate /etc/letsencrypt/live/backup.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/backup.example.com/privkey.pem;
server_tokens off;
client_max_body_size 20G;
client_body_timeout 600s;
client_body_temp_path /srv/backups/.tmp 1 2;
# Все остальные URL закрыты.
location / {
return 404;
}
# Загружать можно только файлы с безопасными именами
# непосредственно в каталог server1.
location ~ ^/server1/[A-Za-z0-9][A-Za-z0-9._-]*$ {
root /srv/backups;
auth_basic "Backup Server 1";
auth_basic_user_file /etc/nginx/backup-auth/server1.htpasswd;
dav_methods PUT;
create_full_put_path off;
limit_except PUT {
deny all;
}
}
# Отдельная авторизация для server2.
location ~ ^/server2/[A-Za-z0-9][A-Za-z0-9._-]*$ {
root /srv/backups;
auth_basic "Backup Server 2";
auth_basic_user_file /etc/nginx/backup-auth/server2.htpasswd;
dav_methods PUT;
create_full_put_path off;
limit_except PUT {
deny all;
}
}
}Особенности конфигурации:
dav_methods PUTвключает загрузку файлов, но не включает DELETE или MOVE.limit_except PUTотклоняет GET, HEAD, POST и другие методы.- Регулярное выражение ограничивает имя файла латинскими буквами, цифрами, точками, дефисами и подчёркиваниями. Вложенные каталоги через URL создавать нельзя.
client_max_body_size 20Gзадаёт максимально допустимый размер одного файла. Для больших архивов значение увеличивается.client_body_temp_pathразмещает временные файлы на том же разделе, что и архивы.auth_basic_user_fileпривязывает отдельный пароль к каждому источнику.
Проверить и применить конфигурацию:
nginx -t && systemctl reload nginxШаг 7. Проверка загрузки и прав доступа
На первом сервере создать небольшой тестовый файл:
printf 'Backup test\n' > /tmp/backup-test.txtОтправить его через HTTPS. Команда curl запросит пароль пользователя server1:
curl --fail --show-error \
--user server1 \
--upload-file /tmp/backup-test.txt \
--write-out '\nHTTP %{http_code}\n' \
https://backup.example.com/server1/backup-test.txtПри успешном создании нового файла ожидается HTTP 201 Created. Код 204 No Content при повторной загрузке может означать, что существующий файл был перезаписан.
Проверить наличие архива из консоли LXC:
ls -lh /srv/backups/server1/Убедиться, что удаление запрещено:
curl --user server1 -o /dev/null -sS -w 'HTTP %{http_code}\n' \
-X DELETE \
https://backup.example.com/server1/backup-test.txtВ этой конфигурации ожидается HTTP 403 Forbidden. Аналогично GET и HEAD должны быть запрещены. Для проверки изоляции источников повторить PUT на URL /server2/ с паролем server1: ожидается HTTP 401 Unauthorized.
После тестирования удалить backup-test.txt из консоли контейнера, а не через публичный интерфейс.
Шаг 8. Автоматическая отправка готовых архивов
Пароль не рекомендуется помещать прямо в параметры командной строки или в cron. На отправляющем Linux-сервере создать файл /root/.backup-netrc:
machine backup.example.com
login server1
password REPLACE_WITH_STRONG_PASSWORDОграничить права доступа:
chmod 600 /root/.backup-netrcПример отправки уже существующего архива:
FILE="/var/backups/backup-2026-11-03.tar.gz"
NAME="$(basename "$FILE")"
curl --fail --show-error --silent --retry 3 \
--netrc-file /root/.backup-netrc \
--upload-file "$FILE" \
"https://backup.example.com/server1/$NAME"Название архива должно соответствовать ограничению в Nginx и быть уникальным, например с датой, временем и идентификатором задания. Команду загрузки следует запускать после успешного завершения создания архива, а не параллельно с ним. Проверять нужно и код завершения curl, и результат самого задания бэкапа.
Для автоматизации можно использовать cron, systemd timer или механизм резервного копирования приложения. Внешние программы, которые требуют полноценный WebDAV с PROPFIND, с этой минимальной схемой могут быть несовместимы.
Шаг 9. Продление сертификата, мониторинг и очистка
Автоматическое продление сертификата
Чтобы Nginx перечитывал обновлённые сертификаты, создать deploy hook:
install -d /etc/letsencrypt/renewal-hooks/deploy
cat > /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh <<'EOF'
#!/bin/sh
set -eu
/usr/sbin/nginx -t
/usr/bin/systemctl reload nginx
EOF
chmod 755 /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh
certbot renew --dry-runПроверить, что в системе активирован штатный механизм автоматического продления Certbot, и не закрывать TCP 80, если используется проверка HTTP-01.
Свободное место и логи
Проверять заполнение тома и журнал ошибок Nginx:
df -h /srv/backups
journalctl -u nginx --since '1 day ago'
tail -n 100 /var/log/nginx/error.logКонтролировать следует не только общее свободное место, но и состояние ZFS-пула, свободную ёмкость с учётом снапшотов, ошибки отправки и факт поступления свежих архивов от каждого источника.
Очистка старых архивов
Для просмотра файлов старше 30 суток:
find /srv/backups/server1 \
-maxdepth 1 -type f -mtime +30 -printУдаление лучше выполнять отдельной задачей на принимающем сервере после определения политики хранения: например, ежедневные копии за 14 дней, недельные за 8 недель и месячные за 6 месяцев. Простое удаление всех файлов старше 30 дней подходит не для каждого сценария и может оставить систему без пригодной точки восстановления.
Безопасность: что ещё обязательно учесть
- Не публиковать SSH для отправителей. Для администрирования достаточно консоли Proxmox или отдельного защищённого канала.
- Ограничить источники по IP или принимать загрузки через WireGuard, если это позволяет инфраструктура.
- Не использовать одни учётные данные для всех клиентов. Отдельные пароли упрощают отзыв доступа.
- Неизменяемость не обеспечивается Nginx DAV. При компрометации пароля злоумышленник может перезаписывать файлы в каталоге отправителя.
- Настроить снапшоты и независимую копию. Снапшот на том же диске не защищает от отказа самого диска, хоста или потери всего пула.
- Периодически проверять восстановление. Успешный HTTP 201 подтверждает загрузку файла, но не пригодность самого архива.
Если требуется действительно create-only/write-once хранилище, штатный Nginx PUT без дополнительного серверного обработчика не подходит. Для строгой неизменяемости стоит использовать специально реализованный upload API с атомарной проверкой создания или S3-совместимое хранилище с политиками и Object Lock. Это отдельная задача, не решаемая одним запретом DELETE.
Частые ошибки
Симптом | | Вероятная причина | |
|---|---|
401 Unauthorized | | Неверный логин/пароль или отправка в чужой каталог. | |
403 Forbidden | | Запрещён HTTP-метод, недостаточны права или файл недоступен. | |
404 Not Found | | Неправильный URL или имя файла не подходит под разрешённый шаблон. | |
413 Content Too Large | | Файл больше |
500 Internal Server Error | | Проверить error.log, права на |
Не выпускается сертификат | | DNS, NAT или порт 80 недоступен для проверки HTTP-01. | |
Документация
- Nginx: модуль ngx_http_dav_module.
- Nginx: limit_except, размеры и временные каталоги.
- Nginx: HTTP Basic Authentication.
- Proxmox VE: особенности резервирования mount points LXC.
- Certbot: получение и обновление TLS-сертификатов.
Частые вопросы
Можно ли заменить Proxmox Backup Server таким решением?
Только если нужно принимать готовые архивы. Nginx через HTTP PUT не поддерживает функции PBS: дедупликацию, специализированное резервное копирование виртуальных машин и управление точками восстановления.
Можно ли отправлять резервные копии с Windows?
Да. Подойдёт любой клиент Windows, способный отправлять HTTPS PUT с HTTP Basic Authentication, например curl.exe. Программа должна сначала создать архив, а затем отправить его.
Защищает ли запрет DELETE от удаления и перезаписи архивов?
Удаление через HTTP DELETE запрещено, но существующий файл можно перезаписать методом PUT. Для защиты нужны снапшоты, отдельные копии или хранилище с настоящей неизменяемостью.
Можно ли использовать обычный WebDAV-клиент?
Не всегда. Штатный модуль Nginx DAV не поддерживает PROPFIND, необходимый многим WebDAV-клиентам. Для этой схемы нужен клиент, отправляющий обычный HTTP PUT без дополнительных WebDAV-запросов.
Нужно ли открывать SSH для серверов-отправителей?
Нет. Отправителям достаточно HTTPS-доступа к соответствующему URL и отдельной HTTP-учётной записи. Администрирование самого контейнера выполняется независимо от сервиса загрузки.
Заключение
Debian LXC + Nginx + HTTPS PUT — простой способ построить центральное хранилище готовых резервных копий в Proxmox без SSH-доступа для клиентов. Отправители получают отдельные HTTP-учётные записи и каталоги, а загрузка сводится к одной команде curl. Для рабочей эксплуатации необходимо дополнить приём архивов контролем доставки, политикой хранения, снапшотами и второй независимой копией. Важно помнить, что это сервис приёма файлов, а не полнофункциональная система неизменяемого резервного копирования.