<b>Дано</b> <br/> 1. Сервер в локальной сети с IP-адресом 192.168.0.10 (Ubuntu + Nginx) <br/> 2. Роутер, подключенный к интернету, с публичным IP-адресом <b>x.x.x.x</b>, на котором закрыты порты 80 и 443, но открыты и проброшены на локальный сервер порты <i>8080</i> и <i>8443</i> <br/> 3. Арендованный VPS с публичным IP-адресом <b>y.y.y.y</b> (Ubuntu + Nginx) <br/> 4. Домен <b>site.ru</b>, который указывает на VPS с IP <i>y.y.y.y</i> <br/> <br/> <b>Задача</b> <br/> Настроить доступ к <b>site.ru</b> с локального сервера через HTTPS. <br/> <br/> HTTP работает нормально: на VPS настроен проксирующий Nginx, который направляет запросы на другой IP и порт. <br/> <pre><code class="nginx">server {
listen 80;
server_name site.ru www.site.ru;
location / {
proxy_pass http://x.x.x.x:8080;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real_IP $remote_addr;
}
}</code></pre> <br/> <br/> В текущей настройке локальный сервер получает полную информацию о клиенте, в то время как клиент не получает информации о конечном сервере. <br/> <br/> Как осуществить эту настройку для HTTPS? <br/> <br/> Насколько я понимаю, здесь будут две зашифрованные связи: <br/> 1. от клиента к VPS (сертификат Let's Encrypt) <br/> 2. от VPS к локальному серверу (требуется самоподписанный сертификат?) <br/> <br/> Таким образом, клиент осуществляет шифрование, проксирующий Nginx расшифровывает, затем шифрует для второй связи, а конечный Nginx снова расшифровывает. <br/> <br/> Меня интересует именно эта вторая связь от проксирующего Nginx к конечному Nginx. Как правильно настроить безопасное шифрование между ними? <br/> <br/> Существуют ли альтернативные способы реализации HTTPS в данной сетевой архитектуре?
Для настройки HTTPS между двумя серверами с использованием Nginx в вашей архитектуре, вам действительно понадобится настроить две зашифрованные связи. Первая связь — это связь между клиентом и VPS, а вторая — между VPS и вашим локальным сервером.
### Пошаговая инструкция
#### 1. Настройка HTTPS на VPS
На VPS вам необходимо получить SSL-сертификат. Самый распространенный бесплатный сертификат предоставляется Let's Encrypt. Вот краткие шаги:
1. **Установите certbot** (если он ещё не установлен):
```bash
sudo apt update
sudo apt install certbot python3-certbot-nginx
```
2. **Получите сертификат** для вашего домена:
```bash
sudo certbot --nginx -d site.ru -d www.site.ru
```
Убедитесь, что вы следуете инструкциям и подтверждаете свой домен.
3. **Настройте Nginx на VPS** для поддержки HTTPS:
В конфигурации вашего Nginx на VPS замените текущую конфигурацию на следующую:
```nginx
server {
listen 80;
server_name site.ru www.site.ru;
# Редирект на HTTPS
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name site.ru www.site.ru;
# Настройки SSL
ssl_certificate /etc/letsencrypt/live/site.ru/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/site.ru/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'HIGH:!aNULL:!MD5';
location / {
proxy_pass http://x.x.x.x:8080;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
}
}
```
4. **Перезагрузите Nginx**:
```bash
sudo systemctl reload nginx
```
#### 2. Настройка самоподписанного сертификата на локальном сервере
Теперь необходимо создать самоподписанный сертификат на локальном сервере (192.168.0.10):
1. **Создайте самоподписанный сертификат**:
```bash
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout /etc/nginx/ssl/selfsigned.key \
-out /etc/nginx/ssl/selfsigned.crt
```
Убедитесь, что вы указываете правильные параметры на запрос (Common Name должен совпадать с тем именем, которое будет использовать ваш локальный сервер).
2. **Настройте Nginx на локальном сервере** для работы по HTTPS:
Пример конфигурации вашего Nginx на локальном сервере:
```nginx
server {
listen 443 ssl;
server_name localhost;
ssl_certificate /etc/nginx/ssl/selfsigned.crt;
ssl_certificate_key /etc/nginx/ssl/selfsigned.key;
location / {
# Директивы для обработки запросов
}
}
```
3. **Перезагрузите Nginx на локальном сервере**:
```bash
sudo systemctl reload nginx
```
#### 3. Настройка проксирования с VPS на локальный сервер
Теперь вам нужно изменить конфигурацию Nginx на VPS для того, чтобы он мог отправлять запросы на локальный сервер по HTTPS.
В разделе `location` вашего Nginx на VPS измените строку `proxy_pass` как показано ниже:
```nginx
location / {
proxy_pass https://192.168.0.10:443; # Изменение на HTTPS
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
# Установим игнорировать ошибки сертификатов
proxy_ssl_verify off; # Не проверять сертификат
}
```
### Альтернативные способы
1. **Использование VPN**: Если у вас есть возможность установить соединение по VPN между VPS и локальным сервером, вы можете настроить HTTPS только на VPS, а локальный сервер будет доступен по локальному IP без шифрования.
2. **Использование SSH Tunneling**: Если вы не можете использовать VPN, можно использовать SSH-туннелирование для
в принципе всё верно, правда что такое "первая нога" и "вторая нога" не сразу понял
для такого варианта какой-то сертификат для конечного nginx нужен, но какой именно неважно, ЕМНИП по умолчанию nginx не проверяет валидность сертификатов при proxy_pass на https
можно ещё посмотреть на модуль stream и proxy-протокол, тогда проксирующий nginx будет тупо перенаправлять трафик и ничего расшифровывать и снова шифровать не будет, терминированием ssl-сессии будет заниматься конечный nginx
у этого способа есть свои недостатки — порты на конечном nginx нужны отдельные чтобы принимать proxy-протокол, проксирующий nginx не будет ничего знать о доменах, т.к. по большому способу будет работать на уровне tcp