Я устал от ситуации с мессенджерами и настроил звонки через Nextcloud Talk для всей семьи. Потому что мама звонит в VK и не понимает, почему звонки не проходят — у меня iPhone, приложение VK удалено из стора. А значит, отозван токен для уведомлений и входящие вызовы проходят только если приложение открыто. А папа звонит в TG по старой привычке — пока включишь VPN, пока дождешься установления соединения…
Задача: дать возможность всей семье общаться через свой self-hosted сервер с Nextcloud Talk. В моём случае это TrueNAS, об этом писал ранее на Хабре. Для этого нужен домен с SSL-сертификатом и доступом к htaccess либо конфигам nginx. Схема выглядит так:
Шаг 1. Настройка хоста
Нам потребуется свой домен example.com. Допустим у него пописаны NS от хостера:
Я использую VPS с HestiaCP вместо виртуального хостинга, но данная схема будет работать с любой панелью. Работать будем дальше с ней. Далее в панели хостера создаём поддомен nextcloud.example.com (хотя можно и на основном домене делать) и меняем A-запись в настройках DNS на IP сервера с HestiaCP. Проверяем через терминал (PowerShell), что резолвится:
-
nslookup nextcloud.example.com
-
nslookup nextcloud.example.com 8.8.8.8
Мы должны увидеть IP сервера с HestiaCP. Выпускаем SSL от Let’s Encrypt — так SSL-сертификатом будет управлять HestiaCP и отвечать за его автоматический перевыпуск. DNS support для домена не нужен, т к DNS управлеятся хостером.
-
Enable SSL for this domain — вкл
-
Use Let’s Encrypt to obtain SSL certificate — вкл
-
Enable automatic HTTPS redirection — вкл
Шаг 2. Настройка Port Forwarding на домашнем роутере
Мне повезло, и провайдер выдал мне статичный IPv4 не за CGNAT, иначе потребовался бы DDNS. Сам Nextcloud у меня уже установлен на TrueNAS в домашней сети по адресу 192.168.0.17:30027 (порт 30027 — дефолтный для Nextcloud). Давайте сгенерируем рандомный порт и настроим Port Forwarding на роутере с этого порта на 30027.
На примере моего старенького роутера Asus RT-N12 — давайте настроим Port Forwarding c рандомного порта 56070 на 192.168.0.17:30027:
-
Service Name = Nextcloud # Называете как нравится
-
Source Target = IP вашего хостинга или VPS. Так доступ будет только у вашего VPS. Можно оставить пустым, но будет менее безопасно
-
Port Range = 56070
-
Local IP = 192.168.0.17 # локальный IP TrueNAS
-
Local Port = 30027
-
Protocol = TCP
Создаем сразу еще два правила — они понадобятся нам позже:
-
Service Name = Nextcloud coturn 3478 # Называете как нравится
-
Source Target = пусто # Если разрешаем подключения с любого IP
-
Port Range = 3478
-
Local IP = 192.168.0.17 # локальный IP TrueNAS
-
Local Port = 3478
-
Protocol = BOTH
И последнее:
-
Service Name = Nextcloud coturn relay # Называете как нравится
-
Source Target = пусто # Если разрешаем подключения с любого IP
-
Port Range = 49160:49200
-
Local IP = 192.168.0.17 # локальный IP TrueNAS
-
Local Port = 49160
-
Protocol = UDP
Шаг 3. Настройка реверс-прокси на хостинге
Наша задача в том, чтобы при открытии https://nextcloud.example.com/ открывалась страница логина. Есть несколько вариантов:
Вариант 1. Через htaccess (apache)
Создаем файл .htaccess в корне public_html сайта и прописываем туда 2 строчки:
# Проксирование всех запросов на домашний NextcloudRewriteEngine OnRewriteRule (.*) http://<ВНЕШНИЙ_IP_РОУТЕРА>:56070/$1 [P,L]
Эта история будет работать, если на хостинге включено 2 модуля:
-
proxy_module
-
proxy_http_module
Проверить можно подключившись к терминалу хостинга и ввести команду:
apachectl -M | grep proxy
Если этих 2х модулей не видно — то можно доустановить, например у меня не хватало одного модуля:
a2enmod proxy_httpsystemctl restart apache2
Я также попробовал данную схему с обычным виртуальным хостингом у одного из популярных хостеров в РФ — у него хоть и доступен терминал из браузера, но установить недостающие модули он не дал. Возможно стоит обратиться с вопросом к техподдержке.
Вариант 2. Через nginx
Создаем новый шаблон для Proxy Template и применяем его к nextcloud.example.com в HestiaCP. Признаюсь честно — код помогал писать Claude:
cat > /usr/local/hestia/data/templates/web/nginx/nextcloud_proxy.tpl << 'EOF'#=========================================================================## Nextcloud External Proxy Web Domain Template ## Custom template, proxies all requests including static assets ## to an external backend, without local try_files fallback. ##=========================================================================#server { listen %ip%:%proxy_port%; server_name %domain_idn% %alias_idn%; error_log /var/log/%web_system%/domains/%domain%.error.log error; include %home%/%user%/conf/web/%domain%/nginx.forcessl.conf*; location ~ /\.(?!well-known\/|file) { deny all; return 404; } location / { proxy_pass http://<ВНЕШНИЙ_IP_РОУТЕРА>:56070; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_read_timeout 3600s; proxy_send_timeout 3600s; client_max_body_size 10G; } location /error/ { alias %home%/%user%/web/%domain%/document_errors/; } include %home%/%user%/conf/web/%domain%/nginx.conf_*;}EOF
И повторяем тоже самое для HTTPS (stpl):
cat > /usr/local/hestia/data/templates/web/nginx/nextcloud_proxy.stpl << 'EOF'#=========================================================================## Nextcloud External Proxy Web Domain Template (SSL) ## Custom template, proxies all requests including static assets ## to an external backend, without local try_files fallback. ##=========================================================================#server { listen %ip%:%proxy_ssl_port% ssl; server_name %domain_idn% %alias_idn%; error_log /var/log/%web_system%/domains/%domain%.error.log error; ssl_certificate %ssl_pem%; ssl_certificate_key %ssl_key%; ssl_stapling on; ssl_stapling_verify on; if ($anti_replay = 307) { return 307 https://$host$request\_uri; } if ($anti_replay = 425) { return 425; } include %home%/%user%/conf/web/%domain%/nginx.hsts.conf*; location ~ /\.(?!well-known\/|file) { deny all; return 404; } location / { proxy_pass http://<ВНЕШНИЙ_IP_РОУТЕРА>:56070; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_read_timeout 3600s; proxy_send_timeout 3600s; client_max_body_size 10G; } location /error/ { alias %home%/%user%/web/%domain%/document_errors/; } proxy_hide_header Upgrade; include %home%/%user%/conf/web/%domain%/nginx.ssl.conf_*;}EOF
Затем проверяем:
# должно быть без ошибок nginx -t# ребутаем nginxsystemctl reload nginx# проверяем, что статика грузится (должно быть 200)curl -I https://nextcloud.example.com/core/css/server.css
Вариант 3. Для тех, кто понимает что делает
Не повторяйте это дома!
-
A-запись nextcloud.example.com указывает прямо на домашний IP.
-
На роутере открыть порты 80 и 443 на TrueNAS.
-
В каталоге приложений TrueNAS ставится обратный прокси с Let’s Encrypt, например Nginx Proxy Manager, и проксирует домен на Nextcloud.
—
После выполнения одного из вариантов — уже можно попробовать открыть https://nextcloud.example.com/ в браузере и мы увидим заглушку от Nextcloud.
Шаг 4. Отключить DoS protection на роутере
Со включеным DoS protection роутер пропускает без задержек лишь несколько запросов, а всем последующим даёт таймаут и ставит в очередь. Выглядит это так, что вы открываете страницу логина в Nextcloud по адресу https://nextcloud.example.com/, а там простая текстовая заглушка и статика загружается несколько минут. В Dev Tools браузера видно, как во вкладке Network запросы к статике летят с большой задержкой друг за другом.
Шаг 5. Настройка разрешенных хостов в Nextcloud
Открываем Shell Nextcloud в Truenas и добавляем наш домен в список разрешенных:
php occ config:system:get trusted_domains
У меня показало 4 хоста:
127.0.0.1192.168.0.17localhostnextcloud
Значит добавляем новый хост с индексом 4:
php occ config:system:set trusted_domains 4 --value=nextcloud.example.com
Дальше добавляем:
php occ config:system:set overwrite.cli.url --value="https://nextcloud.example.com"php occ config:system:set overwriteprotocol --value="https"php occ config:system:set overwritehost --value="nextcloud.example.com"
Перезагружаем приложение Nextcloud в TrueNAS. Теперь при запросе https://nextcloud.example.com/ должен происходить редирект на /login и открываться страница логина в Nextcloud. Проверяем статику в Dev Tools, если открылась почти пустая заглушка. Если все сделано верно — мы сможем авторизоваться.
Теперь уже можно попробовать создать пару тестовых учеток и обменяться сообщениями. Но для звонков надо сделать еще кое-что.
Шаг 6. Поднимаем coturn-сервер
Далее надо поднять свой Turn (coturn) сервер. Без него работают только сообщения, со звонками нормально работать не будет. К сожалению в каталоге приложений TrueNAS нет готового решения, как в случае с RustDesk Relay например. Для этого:
Создаём датасет на TrueNAS: main_pool/coturn (Owner = root)
Через Shell (или SSH) кладём файл конфига:
mkdir -p /mnt/main_pool/coturn/conf nano /mnt/main_pool/coturn/conf/turnserver.conf
Вставляем конфиг, меняем пароль:
listening-port=3478tls-listening-port=5349listening-ip=192.168.0.17external-ip=<ВНЕШНИЙ_IP_РОУТЕРА>relay-ip=192.168.0.17min-port=49160max-port=49200verbosefingerprintlt-cred-mechuser=talkuser:<СЛОЖНЫЙ_ПАРОЛЬ>realm=example.comno-tlsv1no-tlsv1_1
Выставляем права:
chown -R root:root /mnt/main_pool/coturn
Создаем кастомное приложение в TrueNAS: Apps — Discover Apps — Custom App с таким конфигом:
Application Name* = coturnRepository* = coturn/coturnPull Policy* = Pull the image if it is not already present on the host.Command turnserver -c /etc/coturn/turnserver.confRestart Policy* = Unless Stopped - Restarts the container irrespective of the exit code but stops restarting when the service is stopped or removed.Host Network = OnMount Path* = /etc/coturn/turnserver.confHost Path* = /mnt/main_pool/coturn/conf/turnserver.conf
Деплоим приложение и запускаем.
Шаг 7. Финальная настройка Nextcloud
Открываем с ПК Nextcloud — Administration settings — Talk — TURN servers, добавить сервер с префиксом turn:, адресом <ВНЕШНИЙ_IP_РОУТЕРА>:3478, секретом и протоколом UDP and TCP. Без этого шага звонки не смогут использовать ваш TURN. Там же стоит оставить стандартный STUN stun.nextcloud.com:443.
Дальше делаем тестовый звонок вне домашней сети. Всё должно работать.
Потом была проблема с тем, что нет уведомления о входящем звонке на айфоне (call kit не заработал) — перелогинился, выкинул приложение из памяти и всё заработало. Проверить доставку пуш-уведомлений можно командой (вводить в Shell приложения Nextcloud):
php occ notification:test-push --talk <USER>
Чем порадовал Nextcloud как мессенджер
-
Есть Screen Sharing для iPhone. Очень удобно объяснять родителям куда и что нажимать.
-
Есть подключение по ссылке к миту для рандомных гостей.
-
Есть отдельное приложение Talk без лишних функций облака, кроссплатформенное (любая ОС, на ПК сделано на базе Electron).
-
Уведомелния приходят на Apple Watch.
-
Есть реакции на сообщения, редактирование отправленных, онлайн-статусы, избранное, видео-звонки. Что еще надо для счастья?
Ну и конечно же приложение есть во всех сторах (работают уведомления), не страшны случайные блокировки РКН.
Вместо вывода
Теперь можно со спокойной душой отключить все уведомления в Telegram, чтобы не отвлекали от работы. А близкие достанут тебя через Nextcloud. Плюсом у вас появится возможность шарить файлы наружу из основного приложения Nextcloud — теперь он будет иметь основной адрес вашего хоста вместо IP.
Можно еще поработать над дополнительной безопасностью — у нас остался незащищенный участок между доменом и домашним роутером, а также стоит подумать над защитой нашего домена от посторонних глаз. Первое, что приходит на ум — посмотреть основные Request Headers от браузера и клиента Nextcloud и сделать их минимальную проверку в htaccess, остальным отдавать 403 код ответа.
Мой канал в Telegram — @barbolin, там я делюсь своими открытиями во всём, что касается работы.
ссылка на оригинал статьи https://habr.com/ru/articles/1101832/