Введение
Часто бывает полезно сделать приложение, находящееся в локальной разработке, временно доступным в публичном интернете. В Blended Edge, например, наша работа по автоматизации интеграций означает, что мы используем много потоков OAuth2, а использование OAuth2 для разрабатываемого приложения (обычно) требует общедоступной конечной точки с SSL-сертификатом.
Ngrok — это инструмент обратного прокси, который делает это очень просто, но также довольно легко настроить обратный прокси, используя экземпляр AWS EC2, certbot от Let’s Encrypt и команду ssh
.
Это описание предполагает наличие базовых знаний о DNS, ssh
и экземплярах EC2 (или аналогичных облачных вычислительных ресурсах).
Создание удаленного сервера
Мы начнем с запуска экземпляра EC2 на AWS, который будет выступать в качестве удаленного сервера. Конечно, это можно сделать с помощью любого облачного провайдера, например Azure или Digital Ocean.
Задайте имя экземпляра как «Reverse-Proxy», а в разделе «Образы приложений и ОС» выберите Ubuntu. На момент написания этой статьи образ Ubuntu по умолчанию — 22.04.
У меня уже есть пара ключей SSH, которую я буду использовать для доступа к этому экземпляру, но если у вас ее нет или вы хотите использовать новую пару ключей, просто нажмите «Создать новую пару ключей».
Создайте новую группу безопасности, которая разрешит HTTP/HTTPS трафик с любого IP адреса, но ограничит SSH трафик только вашим собственным IP.
Нажмите «Launch Instance», перейдите на страницу обзора экземпляров и подождите, пока пройдет проверка состояния нового экземпляра. Это может занять пару минут.
Когда экземпляр будет готов, перейдите на страницу обзора экземпляра и нажмите «Подключиться» в правом верхнем углу. Выполните следующие шаги для подключения.
# if this is a new ssh key you may need to specify the path to the key
# ssh -i /path/to/key.pem <user>@<address>
ssh ubuntu@ec2-13-59-152-133.us-east-2.compute.amazonaws.com
Установите Nginx
Обновите список пакетов, обновите пакеты и установите nginx.
sudo apt update
sudo apt upgrade -y
sudo apt install nginx
Если вы отправите GET-запрос на IP-адрес вашего экземпляра через веб-браузер или curl, вы получите страницу nginx по умолчанию.
curl http://13.59.152.133
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
...
Домен и SSL
Укажите домен на публичный IP-адрес вашего экземпляра. Серверы имен для моего домена hydewd.com
находятся в DigitalOcean, поэтому в моем случае обновление записи A
для указания домена на мой экземпляр выглядит следующим образом:
Примечание: Если вы собираетесь выполнять серьезную или долгосрочную работу с этой установкой, вам следует выделить эластичный IP-адрес, связать его с вашим экземпляром и указать ваш домен на эластичный IP.
Установите certbot
от Let’s Encrypt для автоматической установки SSL-сертификата.
sudo apt install certbot python3-certbot-nginx -y
Теперь запустите certbot
, чтобы сделать запрос на SSL-сертификат. Здесь я указываю, что хочу покрыть как голый домен hydewd.com
, так и www.hydewd.com
. Вам будет предложено указать адрес электронной почты для уведомлений о продлении, согласиться с условиями предоставления услуг, а также спросить, согласны ли вы предоставить свою электронную почту Electronic Frontier Foundation (последнее необязательно).
sudo certbot --nginx -d hydewd.com -d www.hydewd.com
Если все сработало, теперь вы должны иметь возможность загрузить страницу nginx по умолчанию по адресу https://<your-domain>
.
Конфигурация Nginx
Следующий шаг — указать nginx перенаправлять http/https запросы на другой порт (8080
). На следующем шаге мы туннелируем этот порт на нашу локальную машину.
sudo vi /etc/nginx/sites-available/default
В блоке location
стандартного блока server
добавьте строку для перенаправления трафика на http://127.0.0.1:8080
.
Мы будем изменять содержимое блока location
. Вот как это выглядит для начала:
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}
Измените содержимое блока location
на:
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://127.0.0.1:8080/;
}
Сохраните файл и убедитесь, что конфигурация верна, выполнив команду sudo nginx -t
. Если ошибки нет, перезапустите nginx, чтобы применить последние изменения.
sudo nginx -s reload
Удаленная переадресация SSH
Последним шагом будет туннелирование запросов с порта 8080
сервера на локальную машину. Это можно сделать с помощью команды ssh
remote forwarding.
ssh -R 8080:localhost:8080 ubuntu@ec2-18-217-182-155.us-east-2.compute.amazonaws.com
Теперь запустите сервер локально на порту 8080
. Вот, например, простой сервер node, использующий фреймворк express, который будет отвечать на все запросы GET
с некоторой информацией о том, что сервер видит во входящем запросе.
mkdir local-server && cd local-server
npm init -y
npm install express
Создайте файл index.js
со следующим содержимым:
const express = require('express')
const app = express()
const port = 8080;
app.get('*', (req, res) => {
const { baseUrl, headers, hostname, ip, method, originalUrl, path, protocol } = req;
res.json({
baseUrl,
headers,
hostname,
ip,
method,
originalUrl,
path,
protocol
})
});
app.listen(port, () => console.log(`App listening at http://localhost:${port}`));
node index.js
Отправка запроса на ваш домен теперь будет возвращать ответ с вашего локального экспресс-сервера.
curl -s 'https://www.hydewd.com/some/path?some=query&another=123'
Пример ответа:
{
"baseUrl": "",
"headers": {
"host": "www.hydewd.com",
"x-real-ip": "104.1.2.3",
"connection": "close",
"user-agent": "curl/7.68.0",
"accept": "*/*"
},
"hostname": "www.hydewd.com",
"ip": "::ffff:127.0.0.1",
"method": "GET",
"originalUrl": "/some/path?some=query&another=123",
"path": "/some/path",
"protocol": "http"
}
Обратите внимание, что заголовок x-real-ip
отображает IP-адрес конечного пользователя, делающего запрос, а не IP-адрес экземпляра. Это результат работы строки конфигурации proxy_set_header X-Real-IP $remote_addr;
.
Заключение
Этот подход будет работать для некоторых базовых случаев использования, но в целом он довольно ограничен. В одной из следующих статей мы рассмотрим использование Traefik для обеспечения более функциональной настройки.
Полезные ссылки
Руководство Digital Ocean: Как установить Nginx
Nginx Docs: Документация по обратному прокси
Документы Nginx: Установка Lets Encrypt