Публикация

Reverse proxy - обратный прокси, как и зачем

Если в домашней сети живет один Nextcloud или какой-нибудь медиа-сервер вроде Plex - обратный прокси вам не сдался. Когда домашних сервисов переваливает за десяток - помнить и вбивать их адреса и порты начинает уже утомлять.

Общая схема

   flowchart LR
      a1[nextcloud.doma.net] ---> B((Обратный прокси сервер))
      a2[speedtest.doma.net] ---> B((Обратный прокси сервер))
      a3[plex.doma.net] ---> B((Обратный прокси сервер))
      B ---> b1[192.168.88.10:8080]
      B ---> b2[192.168.88.10:9000]
      B ---> b3[192.168.88.20:3000]
          subgraph node1[Сервер 1]
            b1
            b2
          end
          subgraph node2[Сервер 2]
            b3
          end

Домустим у нас есть три сервиса:

  • наш внутренний или внешний домен doma.net
  • Nextcloud - работает на сервере 192.168.88.20, порт 3000
  • Сервис для измерения скорости speedtest - работает на сервере 192.168.88.10, порт 8080
  • Медиа сервер Plex - - работает на сервере 192.168.88.10, порт 9000

Зачем нам обратный прокси, нельзя ли обойтись DNS?

Частично - можно. DNS позволит сделать связку имя ---> ip-адрес. В браузере все равно придется вбивать еще и порты:

  • nextcloud.doma.net:3000
  • speedtest.doma.net:8080
  • plex.doma.net:9000

При этом, speedtest и plex запущены на одном сервере 192.168.88.10. Т.е фактически получится, что:

  • plex будет доступен еще и по адресу speedtest.doma.net:9000
  • а в сервис speedtest можно зайти по адресу plex.doma.net:8080

Такая вот чехарда с DNS.

Используя обратный прокси - мы эти три записи nextcloud.doma.net, speedtest.doma.net и plex.doma.net с помощью DNS направляем на адрес прокси сервера. А уже он, в зависимости от того, какой адрес ему поступил перенаправит запрос к нужному ip-адресу с указанным портом.

Практика

Запускаем прокси

Обратных прокси-серверов существует несколько - traefik, caddy, nging и др. Cамый интуитивно понятный, на мой взгляд - Nginx Proxy Manager. С ним и будем работать.

Делать будем просто и быстро - в контейнерах докера. Для этого нам понадобится сам docker и docker compose.

Nginx Proxy Manager можно запускать на отдельном узле, а можно на одном узле вместе с остальными контейнерами. В нашем примере - допустим мы запускаем наш прокси на сервере 2, на одной машине вместе с nextcloud.

Создадим папку

1
2
mkdir -p nginxproxy/{data,letsencrypt}
cd nginxproxy

Создадим файл запуска контейнера

1
nano docker-compose.yml

И вставим в него следующее содержимое

1
2
3
4
5
6
7
8
9
10
11
12
13
version: '3.8'
services:
  app:
    image: 'jc21/nginx-proxy-manager:latest'
    restart: unless-stopped
    ports:
      - '80:80'
      - '81:81'
      - '443:443'
    volumes:
      - ./data:/data
      - ./letsencrypt:/etc/letsencrypt

  • jc21/nginx-proxy-manager:latest - образ Nginx Proxy Manager
  • restart: unless-stopped - контейнер будет перезапускаться при сбоях, если только не остановлен вручную
  • ports - открытые порты: 80 и 443 для web-трафика, порт 81 для администрирования самого Nginx Proxy Manager
  • volumes - папки, смонтированные внутрь контейнера. data для разных внутренних данных и логов. А в папке letsencrypt будут храниться сертификаты, выпущенные одноименным сервисом.
1
sudo docker compose up -d

Ждем, когда скачается образ и запустится контейнер.

В этом примере Nginx Proxy Manager запускаем на сервере 2, поэтому вбиваем в браузер адрес этого сервера и добавляем порт администрирования http://192.168.88.20:81

Первоначальные логин и пароль

1
2
Email:    admin@example.com
Password: changeme

Настройки

Первым делом меняем логин/пароль администратора.

Вторым действием - сразу добавим шифрование. В 2023 большинство современных браузеров откажется открывать сайт без хоть какого-нибудь ssl сертификата.

Как легко создать самоподписные сертификаты у меня есть небольшая статья.

1
2
3
openssl req -x509 -newkey rsa:4096 -sha256 -days 3650 -nodes \
  -keyout domanet.key -out domanet.crt -subj "/CN=*.doma.net" \
  -addext "subjectAltName=DNS:*.doma.net" 

Это командой создается ключ и сертификат для всех поддоменов *.doma.net

Перейдем в Nginx Proxy Manager на вкладку SSL Certificates ---> Add SSL Certificate ---> Custom и добавим только что сгенерированный сертификат и ключ к нему.

Теперь к конфигурированию наших сервисов. Вкладка Hosts ---> Proxy Hosts ---> Add Proxy Host Вводим данные для Nextcloud

На вкладке SSL - добавляем сертификат Жмем Save.

Результат

   flowchart LR
      a1[nextcloud.doma.net] --->|DNS|B((Обратный прокси сервер))
          subgraph node2[Сервер 2]
            b3
          end
      B ---> b3[192.168.88.20:3000]

Теперь при вводе в строке браузера nextcloud.doma.net DNS перенаправит наш запрос на прокси сервер, а он уже перенаправит запрос на сервер 192.168.88.20:3000

А еще

  • Можно генерировать сертификаты Let’s Encrypt, которые будут самообновляться
  • Добавить дополнительную аутентификацию для сервисов
  • Разрешать или запрещать доступ с определенных ip-адресов или сетей.

Комментарии и вопросы в Телеграм или Дзен

Публикация защищена лицензией CC BY 4.0 .