Nextcloud внутри, а снаружи OpenLiteSpeed: настраиваем обратное проксирование
Как настроить OpenLiteSpeed на обратное проксирование в Nextcloud, находящийся во внутренней сети?
Удивительно, но поиск на Хабре по запросу OpenLiteSpeed не даёт ничего! Спешу исправить эту несправедливость, ведь LSWS – достойный веб-сервер. Я люблю его за скорость и модный веб-интерфейс администрирования:
Несмотря на то, что OpenLiteSpeed наиболее знаменит как «ускоритель» вордпреса, в сегодняшней статье я покажу довольно специфичное его применение. А именно обратное проксирование запросов (reverse proxy). Вы скажете, что для этого привычнее использовать nginx? Я соглашусь. Но больно уж нам полюбился LSWS!
Проксирование ок, но куда? В не менее замечательный сервис – Nextcloud. Мы используем Nextcloud для создания частных «файлообменных облаков». Для каждого клиента мы выделяем отдельную VM с Nextcloud, и не хотим выставлять их «наружу». Вместо этого мы проксируем запросы через общий reverse proxy. Это решение позволяет:
1) убрать сервер, на котором хранятся данные клиента, из интернета и
2) сэкономить ip-адреса.
Схема выглядит так:
Понятно, что схема упрощена, т.к. организация инфраструктуры веб-сервисов – не тема сегодняшней статьи.
Также в данной статье я опущу установку и базовую настройку некстклауда, тем более что на Хабре есть посвящённые этой теме материалы. Но обязательно покажу настройки, без которых Nextcloud не будет работать за прокси.
Дано:
Nextcloud установлен на хосте 1 и настроен на работу по http (без SSL), имеет только локальный сетевой интерфейс и «серый» IP-адрес 172.16.22.110.
Настроим OpenLiteSpeed на хосте 2. У него два интерфейса, внешний (смотрит в интернет) и внутренний с IP-адресом в сети 172.16.22.0/24
На IP-адрес внешнего интерфейса хоста 2 ведет DNS-имя cloud.connect.link
Задача:
Попадать из интернета по ссылке ‘https://cloud.connect.link‘ (SSL) на Nextcloud во внутренней сети.
Добавляем виртуалхост (Virtual Hosts > Add).
При добавлении появится сообщение об ошибке – отсутствии конфигурационного файла. Это нормально, решается нажатием Click to create.
Во вкладке General укажем Document Root (хоть он и не понадобится, без него конфиг не взлетит). Domain Name, если его не указывать, будет взят из Virtual Host Name, который мы назвали именем нашего домена.
Теперь пора вспомнить, что у нас не просто веб-сервер, а reverse proxy. Следующие настройки укажут LSWS, что проксировать и куда. В настройках виртуалхоста открываем вкладку External App и добавляем новую аппликацию типа Web server:
Указываем имя и адрес. Имя можно указать произвольное, но его надо запомнить, пригодится на следующих шагах. Адрес – тот, где живёт Nextcloud во внутренней сети:
В тех же настройках виртуалхоста открываем вкладку Context и создаём новый контекст типа Proxy:
Указываем параметры: URI = /, Web server = nextcloud_1 (имя из предыдущего шага)
Перезапускаем LSWS. Это делается одним кликом из веб-интерфейса, чудеса! (во мне говорит потомственный мышевоз)
Ставим сертификат, настраиваем https. Процедуру получения сертификата мы опустим, договоримся что он у нас уже есть и лежит вместе с ключом в директории /etc/letsencrypt/live/cloud.connect.link.
Создадим «слушателя» (Listeners > Add), назовём его «https». Укажем ему на 443 порт и отметим, что он будет Secure:
Во вкладке SSL укажем путь до ключа и сертификата:
«Слушатель» создан, теперь в разделе Virtual Host Mappings добавим к нему наш виртуалхост:
Если LSWS будет проксировать только до одного сервиса, настройку можно заканчивать. Но мы планируем использовать его для передачи запросов в разные «инстанции» в зависимости от доменного имени. И у всех доменов будут свои сертификаты. Поэтому надо пойти в конфиг виртуалхоста и снова указать во вкладке SSL его ключ и сертификат. В будущем это надо делать для каждого нового виртуалхоста.
Осталось настроить перезапись url, чтобы http-запросы адресовались на https. (Кстати, когда уже это кончится? Пора уже браузерам и прочему софту по умолчанию ходить на https, а пересылку на no-SSL делать вручную при необходимости).
Включаем Enable Rewrite и записываем Rewrite Rules:
Применить Rewrite rules привычным Graceful restart по странному недоразумению нельзя. Поэтому перезапустим LSWS не изящно, а грубо и эффективно:
sudo systemctl restart lsws.service
Чтобы сервер слушал и 80-й порт, создадим ещё один Listener. Назовём его http, укажем 80-й порт и то, что он будет не-Secure:
По аналогии с настройкой https listener, примапим к нему наш виртуалхост.
Теперь LSWS будет слушать 80-й порт и направлять с него запросы на 443, переписывая url.
В завершение рекомендую снизить уровень логирования LSWS, который по умолчанию установлен как Debug. В таком режиме логи размножаются молниеносно! Для большинства случаев достаточно уровня Warning. Идём в Server Configuration > Log:
На этом настройка OpenLiteSpeed в качестве обратного прокси завершена. В очередной раз перезапускаем LSWS, идём по ссылке https://cloud.connect.link и видим:
Чтобы Nextcloud пустил нас, необходимо внести домен cloud.connect.link в список доверенных. Идём править config.php. Nextcloud я ставил автоматически при установке Ubuntu и конфиг находится тут: /var/snap/nextcloud/current/nextcloud/config.
Ключу trusted_domains добавляем параметр ‘cloud.connect.link’:
Далее, в том же конфиге надо указать IP-адрес нашего прокси. Обращаю внимание, что адрес надо указать тот, который виден серверу Nextcloud, т.е. IP локального интерфейса LSWS. Без этого шага работает веб-интерфейс Nextcloud, но не авторизуются приложения.
Отлично, после этого мы можем попасть в интерфейс авторизации:
Задача решена! Теперь каждый клиент может безопасно пользоваться «файловым облаком» по своему персональному url, сервер с файлами отделён от интернета, будущие клиенты получат всё тоже самое и ни один дополнительный IP-адрес не пострадает.
Дополнительно можно использовать reverse proxy для доставки статического контента, но в случае Nextcloud это не даст ощутимого прироста скорости. Так что это опционально и по желанию.
Рад поделиться этой историей, надеюсь кому-нибудь будет полезно. Если вы знаете более изящные и эффективные методы решения поставленной задачи – буду благодарен за комментарии!