Все системы работают Ваш IP: 216.73.217.36 info@cloudhosting.lv +371 66 66 29 69 Личный кабинет

← Все вопросы

Как настроить nginx как обратный прокси с бесплатным SSL

Это руководство показывает, как поставить nginx перед одним или несколькими веб-приложениями на одном Linux-сервере, терминировать TLS с бесплатным сертификатом Let's Encrypt и оставить продление автоматике. Оно написано для тех, кто запускает приложения на Node.js, Python, Go или похожих стеках на VPS или выделенном сервере и хочет одну аккуратную точку входа по HTTPS. Команды приведены для Debian и Ubuntu; в других дистрибутивах отличаются только вызовы пакетного менеджера.

Зачем вообще нужен обратный прокси

Обратный прокси - это один процесс, который владеет портами 80 и 443 и пересылает запросы приложениям, слушающим на локальных портах. Три практические причины его использовать:

  • Одна точка входа. В интернет смотрит только nginx. Ваши приложения привязаны к 127.0.0.1:3000, 127.0.0.1:8080 и так далее, и напрямую до них добраться нельзя.
  • Терминация TLS. Сертификаты живут в одном месте. Бэкенды говорят по обычному HTTP на localhost, и их TLS-код вы никогда не трогаете.
  • Несколько приложений на одном сервере. nginx маршрутизирует по имени хоста, поэтому app.example.com и api.example.com могут быть разными процессами на одной машине с одним IP-адресом.

Заодно вы получаете журналы доступа, gzip, ограничение частоты запросов и раздачу статики, но главная причина - три пункта выше.

Установка nginx

sudo apt update
sudo apt install nginx
sudo systemctl enable --now nginx

Проверьте, что он отвечает:

curl -I http://127.0.0.1

Вы должны увидеть HTTP/1.1 200 OK и заголовок Server: nginx. Если используется файрвол, откройте оба веб-порта, например sudo ufw allow "Nginx Full". Прежде чем продолжать, убедитесь, что DNS-запись A вашего домена указывает на сервер: без этого certbot позже завершится ошибкой.

Чистый server-блок с proxy_pass

Допустим, приложение слушает порт 3000. Создайте /etc/nginx/sites-available/app.example.com:

server {
    listen 80;
    listen [::]:80;
    server_name app.example.com;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Заголовки важны не меньше, чем строка proxy_pass:

  • Host сообщает бэкенду, какой домен был запрошен. Без него приложение видит 127.0.0.1:3000 и строит неправильные абсолютные URL и редиректы.
  • X-Forwarded-For передает реальный IP-адрес клиента. Без него каждый посетитель выглядит в журналах приложения как 127.0.0.1, а ограничение частоты запросов или бан по IP становятся бесполезными.
  • X-Forwarded-Proto сообщает приложению, каким был исходный запрос, HTTP или HTTPS, и это предотвращает петли редиректов после включения TLS.

Включите сайт и перезагрузите конфигурацию:

sudo ln -s /etc/nginx/sites-available/app.example.com /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

Запускайте nginx -t каждый раз перед перезагрузкой; он ловит синтаксические ошибки, пока старая конфигурация продолжает работать. Для второго приложения скопируйте блок, поменяйте server_name и порт в proxy_pass, готово.

Бесплатный SSL с certbot и плагином nginx

sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d app.example.com

Плагин nginx подтверждает владение доменом через порт 80, получает сертификат Let's Encrypt и правит ваш server-блок: добавляет секцию listen 443 ssl с путями к сертификату и, если вы соглашаетесь в диалоге, редирект с HTTP на HTTPS. Соглашайтесь. Итоговый редирект выглядит так, его можно написать и вручную:

server {
    listen 80;
    listen [::]:80;
    server_name app.example.com;
    return 301 https://$host$request_uri;
}

Несколько доменов в одной команде тоже работают: -d app.example.com -d www.app.example.com.

Проверьте, что автопродление действительно работает

Сертификаты Let's Encrypt действительны 90 дней. Пакет certbot устанавливает systemd-таймер, который срабатывает дважды в день и продлевает все, чему осталось меньше 30 дней. Доверяйте ему только после проверки:

sudo certbot renew --dry-run
systemctl list-timers | grep certbot
sudo certbot certificates

Пробный запуск имитирует полное продление, не трогая настоящий сертификат. Если он проходит, продление будет работать. Плагин после каждого продления перезагружает nginx, поэтому новый сертификат подхватывается без простоя. Все равно поставьте напоминание в календаре через 60 дней и один раз проверьте certbot certificates; тихие сбои продления редки, но обходятся дорого.

Типичные ошибки

  • Нет проброшенных заголовков. Самая частая ошибка. Симптомы: неправильные URL в редиректах, все клиенты в журналах как 127.0.0.1, петля входа после включения HTTPS. Четыре строки proxy_set_header выше закрывают все три проблемы.
  • WebSocket не подключается. nginx по умолчанию не пробрасывает переключение протокола. Для пути с WebSocket добавьте:
    location /ws/ {
        proxy_pass http://127.0.0.1:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_read_timeout 3600s;
        proxy_buffering off;
    }
    Без proxy_read_timeout nginx обрывает простаивающие соединения через 60 секунд.
  • Буферизация ломает стриминг. Server-sent events и long-polling приходят одним запоздалым куском, потому что nginx буферизует ответ. Для таких location задайте proxy_buffering off;.
  • Загрузка файлов падает с 413. Значение client_max_body_size по умолчанию равно 1m. Поднимите его в server-блоке, например client_max_body_size 50m;.
  • Перезагрузка без проверки. Одна опечатка кладет все сайты, которые обслуживает nginx. Сделайте nginx -t рефлексом.

Где это запускать

Все описанное спокойно помещается на небольшом виртуальном сервере; самому nginx хватает нескольких мегабайт памяти. Если вам нужна машина для экспериментов или для боевого проекта, наши тарифы VPS работают в нашем собственном дата-центре уровня Tier 3+ в Риге в нашей собственной сети. А если проект перерастает Let's Encrypt с проверкой домена, например когда интернет-магазину нужна проверка организации или сертификат с гарантией, посмотрите наши коммерческие SSL-сертификаты. Конфигурация nginx остается той же, меняются только файлы сертификата.

Хотите, чтобы это делали мы?
VPS. NVMe виртуальные серверы, запуск за минуту.
Подробнее

Готовы начать?

Запустите за минуты или обсудите с инженером, что подходит вашему проекту.