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 Managerrestart: unless-stopped
- контейнер будет перезапускаться при сбоях, если только не остановлен вручнуюports
- открытые порты: 80 и 443 для web-трафика, порт 81 для администрирования самого Nginx Proxy Managervolumes
- папки, смонтированные внутрь контейнера.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-адресов или сетей.