Nextcloud за роутером: проброс портов и безопасный доступ
Открываем Nextcloud из интернета: белый IP и DDNS, проброс портов 80 и 443, HTTPS через обратный прокси, настройка trusted_proxies и fail2ban. Плюс честное сравнение с VPN и туннелями.
Nextcloud на домашнем сервере — удобная замена облаку: файлы, календари, контакты и клиенты для телефона живут у вас, а не у чужой компании. Но пока облако доступно только внутри домашней сети, это ещё не облако: на улице, в гостях или в командировке вы останетесь без доступа. Чтобы открыть сервер наружу, нужно решить три разные задачи — маршрутизацию, сертификат и защиту.
Разберём путь от «облако работает дома» до «облако доступно по https из интернета»: что проверить до настройки, как открыть порты 80 и 443, как поставить обратный прокси с сертификатом Let's Encrypt, что обязательно прописать в Nextcloud за прокси и как закрыть сервер от брутфорса. Если базовая установка ещё не сделана, начните с материала о Nextcloud на одноплатнике: здесь считаем, что облако уже работает в локальной сети и открывается по внутреннему адресу.
Что понадобится до проброса портов
Проброс портов — это настройка сети, а не Nextcloud. И первым делом нужно понять, можно ли вообще опубликовать домашний адрес наружу: если провайдер выдал серый адрес, никакие правила в роутере не помогут.
Белый IP или CGNAT
Логика простая: WAN-адрес роутера должен совпадать с адресом, который видит внешний сервис. Порядок проверки такой:
- Найдите WAN-адрес роутера. В OpenWrt он виден в Status → Overview на интерфейсе
wan, на других прошивках — в разделе о состоянии подключения. - Узнайте внешний адрес со стороны интернета — например, с сервера командой
curl -s https://api.ipify.org; echoили через любой сервис определения IP. - Если адреса различаются, вы за NAT провайдера. Отдельный признак CGNAT — адрес из диапазона
100.64.0.0/10, то есть100.64.x.x–100.127.x.x.
Вариантов два: попросить у провайдера выделенный («белый») адрес — обычно это отдельная услуга, — или отказаться от проброса портов в пользу VPN и туннелей. Третий, уже совсем плохой случай — двойной NAT, когда перед вашим роутером стоит модем провайдера, работающий как роутер: тогда проброс нужен на обоих устройствах, а проще перевести модем в режим моста.
DDNS вместо статического IP
Домашний адрес меняется: после перезагрузки роутера, аварии у провайдера или смены тарифа. Прописывать его в конфигах вручную бессмысленно, поэтому используют DDNS — постоянное имя, которое клиент обновляет при смене адреса. Подойдёт сервис провайдера, Duck DNS, Cloudflare или любой другой; на OpenWrt это пакет ddns-scripts, на остальных прошивках — раздел DDNS в веб-интерфейсе.
Проверка приёмки: отключаете роутер, ждёте смены адреса, включаете — и имя должно снова указывать на вас. Если клиент DDNS не отработал, сайт «пропадёт» именно в тот момент, когда он нужнее.
Свободны ли порты 80 и 443
Часть домашних тарифов закрывает входящие 80 и 443 на стороне провайдера. Проверяется за пять минут: временно пробросьте нестандартный порт (например, 8443 на 443 вашего сервера) и проверьте оба адреса снаружи. Если нестандартный порт открывается, а 443 нет — фильтр у провайдера, и открытый веб на стандартном порту не поднять. Тогда остаются нестандартные порты, которые неудобны для клиентов и шаринга, или VPN с туннелем.
Схема: где ставить обратный прокси
Публиковать Nextcloud напрямую на 80 и 443 не стоит: сертификатами, виртуальными хостами и заголовками должен заниматься отдельный веб-сервер. Типовая схема выглядит так: интернет → роутер с пробросом 80 и 443 → обратный прокси → контейнер Nextcloud во внутренней сети.
- Вариант A, рекомендуемый: прокси на том же хосте, что Nextcloud — Caddy или Nginx Proxy Manager в Docker. Роутер пробрасывает 80 и 443 на этот хост, дальше прокси сам решает, куда отдать запрос.
- Вариант B: прокси на роутере (OpenWrt плюс nginx или HAProxy). Экономит один хост, но обновление прошивки или сброс настроек роутера ломает публикацию, а сертификаты живут в неудобном месте.
Порты распределяются так: 443 — рабочий, 80 нужен только для проверки домена при выпуске сертификата Let's Encrypt. После выпуска 80 можно закрыть, но тогда продление сертификата придётся переводить на DNS-проверку, иначе он не обновится через три месяца.
Не превращайте этот хост в «швейцарский нож»: чем меньше сервисов доступно через проброшенный 443, тем меньше поверхность атаки. Админки — панель прокси, Portainer, веб-интерфейс роутера — наружу выставлять не нужно.
Проброс портов на роутере
Задача: трафик на внешние 80 и 443 отдать внутреннему адресу прокси. В OpenWrt это делается в Network → Firewall → Port Forwards, а в файле /etc/config/firewall правило выглядит так:
config redirect
option name 'Nextcloud HTTPS'
option target 'DNAT'
option src 'wan'
option src_dport '443'
option dest 'lan'
option dest_ip '192.168.1.50'
option dest_port '443'
option proto 'tcp'
config redirect
option name 'Nextcloud ACME HTTP'
option target 'DNAT'
option src 'wan'
option src_dport '80'
option dest 'lan'
option dest_ip '192.168.1.50'
option dest_port '80'
option proto 'tcp'
После правки примените конфигурацию командой /etc/init.d/firewall restart (в LuCI достаточно кнопки Save & Apply). На бытовых прошивках поля те же: внешний порт, протокол TCP, внутренний адрес и внутренний порт. Название правила ни на что не влияет, кроме порядка в списке.
Обязательно закрепите внутренний адрес прокси — статический IP или резервирование в DHCP. Иначе после перезагрузки хост получит другой адрес, и проброс начнёт вести в пустоту, а симптомы будут выглядеть как «провайдер что-то сломал».
Проверять нужно снаружи, с мобильного интернета, а не из домашней сети — изнутри запрос пойдёт по внутреннему маршруту и создаст ложное ощущение, что всё работает:
curl -I https://cloud.example.com
curl -s https://cloud.example.com/status.php
Первый ответ должен быть успешным — 200 или редирект на https, второй — JSON вида {"installed":true,"maintenance":false,...}. Если /status.php отвечает, значит домен, сертификат и связка «роутер → прокси → Nextcloud» работают целиком.
Типичные ошибки проброса
- Правило есть, но снаружи ничего не открывается: проверьте, что сервис слушает нужный порт на самом хосте (
ss -lntp | grep -E ':80|:443') и что его не блокирует локальный файрвол сервера. - Сайт открывается с одного оператора и не открывается с другого: скорее всего вы за NAT провайдера или под ним остался модем в режиме роутера.
- По IP работает, по имени нет: не обновляется DDNS-запись или домен ещё не разошёлся по DNS-серверам.
- Порт открыт, но вместо облака отдаётся страница роутера: оба устройства слушают 80, и запрос попадает на панель роутера вместо сервера.
HTTPS и сертификат Let's Encrypt
Самый короткий путь к сертификату — Caddy: он получает и продлевает его автоматически, если домен указывает на ваш адрес и открыт порт 80.
# /etc/caddy/Caddyfile
cloud.example.com {
reverse_proxy 192.168.1.50:8080
encode gzip
}
Официальный Docker-образ Nextcloud слушает 80 внутри контейнера, поэтому во внутренней сети вы публикуете его, например, как 8080:80 и проксируете на 192.168.1.50:8080. Наружу при этом смотрит только прокси.
Если вместо Caddy используется Nginx Proxy Manager, логика та же: контейнер Nextcloud слушает внутренний порт, NPM выпускает сертификат и проксирует домен — интерфейс другой, принцип тот же, что разобран выше.
После выпуска сертификата включите HSTS (в Caddy он ставится автоматически для https-сайтов, в NPM — заголовком Strict-Transport-Security: max-age=31536000; includeSubDomains) и редирект с http на https. Это не косметика: без HSTS первый запрос пользователя уходит по открытому каналу и может быть перехвачен в общественной сети.
Настройка Nextcloud за прокси
Здесь чаще всего и ломается. Для Nextcloud обратный прокси — чужой: запросы приходят с его адреса, а реальный клиент виден только в заголовке X-Forwarded-For. Пока это не учтено, вы получите ошибку о недоверенном домене, ссылки, ведущие на внутренний адрес, и предупреждение о том, что сайт доступен по http.
Минимальный набор параметров в config/config.php:
'trusted_domains' => [
0 => 'cloud.example.com',
1 => '192.168.1.50',
],
'trusted_proxies' => ['172.16.0.0/12'], // подсеть Docker: адрес прокси
'overwriteprotocol' => 'https',
'overwrite.cli.url' => 'https://cloud.example.com',
trusted_proxies — не формальность. Если указать адрес прокси неверно или не указать вовсе, Nextcloud будет считать клиентом сам прокси: журнал входов и защита от брутфорса начнут работать по одному внутреннему адресу, а подделка заголовка даст возможность обойти ограничения.
Если Nextcloud развёрнут в Docker, те же значения можно задать переменными окружения при первом запуске — тогда править config.php вручную не придётся:
environment:
NEXTCLOUD_TRUSTED_DOMAINS: cloud.example.com
TRUSTED_PROXIES: 172.16.0.0/12
OVERWRITEPROTOCOL: https
OVERWRITECLIURL: https://cloud.example.com
APACHE_DISABLE_REWRITE_IP: 1
APACHE_DISABLE_REWRITE_IP заставляет Apache внутри контейнера не подменять адрес клиента собственным — без этого реальный IP не доедет ни до журнала, ни до fail2ban.
Уже работающий экземпляр настраивается через occ, без остановки контейнера:
docker compose exec -u www-data app php occ config:system:set trusted_domains 1 --value=cloud.example.com
docker compose exec -u www-data app php occ config:system:set trusted_proxies 0 --value=172.16.0.0/12
docker compose exec -u www-data app php occ config:system:set overwriteprotocol --value=https
docker compose exec -u www-data app php occ config:system:set overwrite.cli.url --value=https://cloud.example.com
Проверка — в админке, в разделе настроек с предупреждениями по безопасности и настройке. После корректной конфигурации там не должно остаться пунктов про недоверенный домен, https и обратный прокси. Заодно посмотрите, что предлагает система: обычно это недостающие индексы базы (occ db:add-missing-indices) и отсутствующие PHP-модули.
Защита: fail2ban и ограничения доступа
После появления DNS-записи сервер увидят сканеры — обычно в течение нескольких часов. Это не повод отказываться от идеи, но повод закрыть базовые защиты до публикации, а не после.
fail2ban
Nextcloud пишет неудачные входы в nextcloud.log на уровне loglevel = 2, и этого достаточно, чтобы fail2ban блокировал адреса после нескольких попыток. Фильтр и jail из официальной документации:
# /etc/fail2ban/filter.d/nextcloud.conf
[Definition]
_groupsre = (?:(?:,?\s*"\w+":(?:"[^"]+"|\w+))*)
failregex = ^\{%(_groupsre)s,?\s*"remoteAddr":"<HOST>"%(_groupsre)s,?\s*"message":"Login failed:
^\{%(_groupsre)s,?\s*"remoteAddr":"<HOST>"%(_groupsre)s,?\s*"message":"Two-factor challenge failed:
^\{%(_groupsre)s,?\s*"remoteAddr":"<HOST>"%(_groupsre)s,?\s*"message":"Trusted domain error.
datepattern = ,?\s*"time"\s*:\s*"%%Y-%%m-%%d[T ]%%H:%%M:%%S(%%z)?"
# /etc/fail2ban/jail.d/nextcloud.local
[nextcloud]
backend = auto
enabled = true
port = 80,443
protocol = tcp
filter = nextcloud
maxretry = 3
bantime = 86400
findtime = 43200
logpath = /path/to/nextcloud/data/nextcloud.log
Замените logpath на фактический путь к журналу. В Docker-развёртывании файл журнала нужно смонтировать на хост, а бан вешать на цепочку DOCKER-USER: правила в стандартной цепочке INPUT трафик опубликованных портов не увидят. Проверка работы простая: сделайте несколько заведомо неудачных входов с телефона и посмотрите fail2ban-client status nextcloud.
Двухфакторная аутентификация и пароли приложений
Пароль от облака, доступного из интернета, — уже не «домашний» секрет. Включите приложение с TOTP, задайте второй фактор и при необходимости требуйте его принудительно:
docker compose exec -u www-data app php occ twofactorauth:enforce --on
Мобильные и настольные клиенты при этом работают по паролям приложений: они создаются в настройках профиля, живут отдельно от основного пароля и отзываются по одному — например, когда телефон потерян.
Ограничение доступа по адресам
Админские разделы не должны быть доступны всему интернету. В конфигурации прокси их можно закрыть списком адресов — пример для nginx:
location ^~ /index.php/settings/admin {
allow 203.0.113.10; # ваш постоянный адрес или VPN-подсеть
deny all;
proxy_pass http://192.168.1.50:8080;
}
Разумная мера для домашнего сервера: обычная работа и клиенты — через https, а админка и остальные сервисы — через VPN или Tailscale. Заодно проверьте, что регистрация новых пользователей выключена, обновления ядра и приложений включены, а резервные копии снимаются и хотя бы раз были проверены восстановлением.
Альтернативы: VPN и туннели
Проброс портов — не единственный вариант и не всегда лучший. Если доступ нужен только вам и вашим устройствам, разумнее вообще не открывать сервер наружу.
| Вариант | Как работает | Плюсы | Минусы |
|---|---|---|---|
| WireGuard на домашнем сервере | Наружу открыт один UDP-порт VPN, внутри сети доступны все сервисы | Минимум открытых портов, шифрование, полноценный доступ к домашней сети | Нужен клиент на каждом устройстве; расшарить ссылку постороннему человеку нельзя |
| Tailscale | Устройства соединяются исходящими подключениями, порты не открываются | Работает за CGNAT, минимум настройки, есть доступ к подсети | Зависимость от стороннего координатора и его политик |
| Cloudflare Tunnel | Туннель из дома к Cloudflare, наружу отдаётся их edge | Серый IP не мешает, сертификаты и защита на стороне провайдера | Трафик и TLS проходят через третью сторону — «своё облако» перестаёт быть полностью своим |
| Проброс 80/443 | Сервер напрямую доступен из интернета | Работают любые клиенты, публичные ссылки, веб-интерфейс без дополнительных программ | Нужен белый IP, сервер виден сканерам, вся ответственность за защиту на вас |
Часто выбирают комбинацию: Nextcloud открыт по https для клиентов и публичных ссылок, а админка и остальные сервисы доступны только через VPN. Так сохраняется удобство веб-доступа без необходимости выставлять наружу всё домашнее хозяйство.
Чеклист после настройки
- Домен резолвится в актуальный адрес, DDNS-клиент обновляет запись.
- Снаружи доступны только 443 и 80 (второй — при необходимости), остальные порты закрыты.
https://cloud.example.com/status.phpотвечает{"installed":true,...}с телефона по мобильной сети.- Сертификат выдан на ваш домен, редирект с http на https и HSTS включены.
- В предупреждениях админки нет пунктов про недоверенный домен, https и обратный прокси.
- В журнале входов видны реальные внешние адреса клиентов, а не адрес прокси.
- fail2ban включён и видит журнал Nextcloud, второй фактор обязателен, пароли приложений используются.
- Резервные копии снимаются автоматически и проверены восстановлением.
Заключение
Проброс портов для Nextcloud — это три независимых шага: сеть (белый адрес или DDNS, правила на роутере), сертификат (обратный прокси с Let's Encrypt) и конфигурация самого облака под прокси. Каждый из них проверяется отдельно, и именно поэтому диагностика обычно занимает минуты, а не часы: status.php показывает, работает ли связка целиком, журнал входов — доехал ли реальный адрес клиента, а список предупреждений в админке закрывает оставшиеся хвосты.
Если публичный доступ нужен только вам, начните с VPN или Tailscale и открывайте 443 лишь тогда, когда действительно требуются веб-ссылки и сторонние клиенты. А если решили открывать — держите на этом хосте минимум сервисов и включайте защиты до публикации, а не после первых попыток взлома в журнале.
Понравилась статья?
Поставьте лайк и сохраните полезный материал в закладки.
Как проверить IP на блокировку в ТСПУ: рабочий Python-скрипт для диагностики
Routerich AX3000: настройка роутера на OpenWrt, Mesh, TorrServer и сетевое хранилище
Nginx Proxy Manager: установка и первоначальная настройка reverse proxy с HTTPS в Docker
Как выбрать LTE/5G-модем для Routerich AX3000: от простого E3372 до T77W968, T99W175 и FM350
Как работают ТСПУ Роскомнадзора? Разбираемся вместе
VPN только для выбранных сайтов и устройств в OpenWrt: раздельная маршрутизация трафика