Веб-сервер и обратный прокси Nginx [208.4]

Рейтинг: 64.6% · 12 голосов
Курс LPIC-2 (201-450 и 202-450): емкостное планирование, ядро, хранилище и RAID/LVM, продвинутая сеть, DNS/BIND, Apache/Nginx, Samba/NFS, DHCP/LDAP, почта, безопасность и VPN.
Ответить
Аватара пользователя
Sergey_Sysadmin
Сообщения: 134
Зарегистрирован: 11 май 2026, 05:31

Веб-сервер и обратный прокси Nginx [208.4]

Сообщение Sergey_Sysadmin »

Оглавление курса (41)
  1. Введение в LPIC-2 и уровень инженера
  2. Измерение и устранение проблем с ресурсами [200.1]
  3. Прогнозирование потребности в ресурсах
  4. Компоненты ядра Linux [201.1]
  5. Сборка ядра из исходников [201.2]
  6. Управление модулями ядра в рантайме [201.3]
  7. Кастомизация запуска системы [202.1]
  8. Восстановление системы [202.2]
  9. Альтернативные загрузчики [202.3]
  10. Работа с файловой системой Linux [203.1]
  11. Обслуживание файловых систем [203.2]
  12. Создание и настройка опций ФС [203.3]
  13. Программный RAID [204.1]
  14. Тюнинг доступа к устройствам хранения [204.2]
  15. Менеджер логических томов LVM [204.3]
  16. Базовая конфигурация сети [205.1]
  17. Продвинутая конфигурация сети [205.2]
  18. Диагностика сетевых проблем [205.3]
  19. Сборка и установка программ из исходников [206.1]
  20. Резервное копирование [206.2]
  21. Оповещение пользователей о событиях
  22. DNS-сервер BIND: базовая настройка [207.1]
  23. Зоны DNS: создание и сопровождение [207.2]
  24. Безопасность DNS-сервера [207.3]
  25. Веб-сервер Apache: базовая настройка [208.1]
  26. Apache и HTTPS [208.2]
  27. Кэширующий прокси Squid [208.3]
  28. Веб-сервер и обратный прокси Nginx [208.4] (вы здесь)
  29. Файловый сервер Samba [209.1]
  30. Файловый сервер NFS [209.2]
  31. DHCP-сервер [210.1]
  32. Аутентификация PAM и SSSD [210.2]
  33. Использование LDAP-клиента
  34. Сервер OpenLDAP [210.4]
  35. Почтовый сервер Postfix [211.1]
  36. Управление доставкой почты и Sieve [211.2]
  37. Доступ к почтовым ящикам: Dovecot [211.3]
  38. Linux как маршрутизатор и фильтр [212.1]
  39. FTP-серверы [212.2]
  40. SSH углублённо [212.3]
  41. Безопасность, IDS и VPN [212.4 + 212.5]
Урок 27. Веб-сервер и обратный прокси Nginx [208.4]

Apache ты уже знаешь по прошлому уроку. Теперь возьмём второй столп веб-стека - Nginx. Задача администратора тут двоякая: раздать статику быстро и дёшево, а главное - поставить Nginx фронтом перед бэкендами (PHP-FPM, Node, Python, тем же Apache) как обратный прокси, балансировщик и точку терминации TLS. Разберём архитектуру, блоки server и location, proxy_pass, upstream и сравним с Apache, чтобы ты понимал, когда какой инструмент брать.

Изображение

Как это работает

Главное отличие от классического Apache (prefork/worker) - модель обработки соединений. Apache по умолчанию выделяет на запрос поток или процесс, и тысяча медленных клиентов съедает тысячу потоков. Nginx работает событийно: небольшое число рабочих процессов (обычно по одному на ядро) внутри цикла epoll обслуживают тысячи соединений неблокирующе. Один воркер не ждёт медленного клиента, а переключается на готовые сокеты. Отсюда крошечное потребление памяти на простаивающее keepalive-соединение и устойчивость под нагрузкой со множеством коннектов.

Конфиг устроен как дерево директив в контекстах. Корень - nginx.conf, в нём контекст http, внутри - блоки server (виртуальные хосты), а внутри server - блоки location (правила по URI). Запрос проходит две фазы выбора. Сначала по паре слушающего адреса/порта и заголовку Host подбирается нужный server (директивы listen и server_name). Если совпадения по server_name нет - берётся default_server для этого listen. Затем внутри server по пути URI выбирается location.

Порядок выбора location не сверху вниз, а по приоритету префиксов: сначала точное совпадение (= /path), потом самый длинный префикс с ^~ (стоп без regex), затем регулярки (~ с учётом регистра, ~* без) в порядке их записи, и в конце - обычный самый длинный префикс. Это частый источник путаницы, поэтому держи правило в голове.

Reverse proxy - сердце темы. Директива proxy_pass перенаправляет запрос на бэкенд. Nginx принимает клиентское соединение, сам открывает соединение к апстриму, отдаёт ответ обратно. Заодно он терминирует TLS (расшифровывает HTTPS на себе, к бэкенду идёт обычный HTTP), кеширует, сжимает, раздаёт статику напрямую, а динамику отдаёт приложению. Блок upstream описывает пул бэкендов и метод балансировки: round-robin по умолчанию, least_conn по числу активных соединений, ip_hash для липкой сессии по IP клиента.

Команды и примеры

Установка и расположение конфигов различаются по семействам.

Код: Выделить всё

# Debian 13 / Ubuntu 24.04
sudo apt update && sudo apt install nginx
# конфиги: /etc/nginx/nginx.conf, сайты в /etc/nginx/sites-available + симлинки в sites-enabled

# RHEL 10 / Fedora 41+
sudo dnf install nginx
# конфиги: /etc/nginx/nginx.conf, дропины в /etc/nginx/conf.d/*.conf (схемы sites-* нет)

sudo systemctl enable --now nginx
nginx -t            # проверить синтаксис ДО перезагрузки
sudo systemctl reload nginx   # мягко перечитать конфиг без обрыва соединений
Виртуальный хост со статикой:

Код: Выделить всё

server {
    listen 80;
    listen [::]:80;
    server_name shop.example.ru;
    root /var/www/shop;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }
    location /static/ {
        expires 30d;            # заголовки кеширования для браузера
        access_log off;
    }
}
Обратный прокси с апстримом, балансировкой и TLS-терминацией:

Код: Выделить всё

upstream backend {
    least_conn;
    server 10.0.0.11:8080 weight=3;
    server 10.0.0.12:8080;
    server 10.0.0.13:8080 backup;   # включится, когда основные лягут
}

server {
    listen 443 ssl;
    http2 on;                       # в Nginx 1.25+ http2 отдельной директивой
    server_name app.example.ru;

    ssl_certificate     /etc/letsencrypt/live/app.example.ru/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/app.example.ru/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;

    location / {
        proxy_pass http://backend;
        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;
    }
}
server {
    listen 80;
    server_name app.example.ru;
    return 301 https://$host$request_uri;   # редирект на HTTPS
}
Связка с PHP через сокет FPM (типовая роль в LEMP):

Код: Выделить всё

location ~ \.php$ {
    include fastcgi_params;
    fastcgi_pass unix:/run/php/php8.3-fpm.sock;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
Частые грабли
  • Слеш в proxy_pass меняет поведение. http://backend (без пути) шлёт URI как есть; http://backend/ (со слешем) отрезает префикс location. Перепутал - получил 404 на бэкенде.
  • Забыл proxy_set_header Host - бэкенд видит Host: backend и отдаёт не тот виртуальный хост. X-Forwarded-For нужен, чтобы приложение знало реальный IP клиента, а не IP прокси.
  • Правишь конфиг и делаешь restart вместо reload. reload не рвёт активные соединения, restart рвёт. И всегда nginx -t перед перезагрузкой.
  • В Debian создал файл в sites-available, но забыл симлинк в sites-enabled - сайт не подхватился. В RHEL этой схемы нет, кладёшь сразу в conf.d.
  • Регулярочный location перехватил запрос раньше префиксного, потому что забыл про приоритеты. Для статики, которую нельзя отдать в regex, используй ^~.
  • SELinux на RHEL по умолчанию запрещает Nginx ходить по сети к апстриму - reverse proxy выдаёт 502. Лечится setsebool -P httpd_can_network_connect 1.
  • TLS терминируется на Nginx, но приложение генерирует http:// ссылки, потому что не передан X-Forwarded-Proto - получаешь mixed content и циклы редиректов.
Мини-лаба
  • Поставь Nginx на свой стенд и подними простой бэкенд: два контейнера или два процесса, отдающих разный текст на портах 8081 и 8082.
  • Опиши блок upstream с этими двумя серверами и методом least_conn, проксируй на него корневой location.
  • Проверь балансировку: curl в цикле 10 раз и убедись, что ответы чередуются между бэкендами.
  • Добавь второй server для раздачи статики из /var/www с заголовком expires 7d, проверь заголовок Cache-Control в curl -I.
  • Выпусти самоподписанный сертификат (openssl req -x509), включи listen 443 ssl и редирект с 80 на 443.
  • Погаси один бэкенд и убедись, что Nginx сам перестал слать на него запросы, а сайт продолжает работать.
  • Каждое изменение проверяй через nginx -t и применяй через systemctl reload, а не restart.
Контрольные вопросы
  • Чем событийная модель Nginx принципиально отличается от prefork-модели Apache и как это влияет на потребление памяти под нагрузкой?
  • В каком порядке Nginx выбирает блок location при совпадении нескольких правил (точное, ^~, regex, префикс)?
  • Как наличие или отсутствие завершающего слеша в proxy_pass меняет итоговый URI на бэкенде?
  • Какие proxy_set_header обязательны при reverse proxy и зачем нужен каждый из них?
  • Чем отличаются методы балансировки round-robin, least_conn и ip_hash и когда выбирать каждый?
  • Что такое TLS-терминация на прокси и какой заголовок нужно передать бэкенду, чтобы он знал об исходном HTTPS?
👍3 ❤️3 🔥1 😄 🤔1
Аватара пользователя
wizard_dasha
Сообщения: 1
Зарегистрирован: 30 май 2026, 15:29

Re: Веб-сервер и обратный прокси Nginx [208.4]

Сообщение wizard_dasha »

Запутался с приоритетом location. Если есть и location /api/ и location ~ \.php$, а запрос /api/x.php - кто победит? По логике урока regex старше префикса, значит уйдёт в php-блок?
👍1 ❤️ 🔥1 😄 🤔2
Аватара пользователя
docker
Сообщения: 1
Зарегистрирован: 15 май 2026, 12:32

Re: Веб-сервер и обратный прокси Nginx [208.4]

Сообщение docker »

На RHEL поставил reverse proxy и ловил 502 пол часа, пока не вспомнил про setsebool httpd_can_network_connect. На Debian такого нет, SELinux реально кусается.
👍1 ❤️2 🔥 😄 🤔
Ответить
← Предыдущая глава
Кэширующий прокси Squid [208.3]
Следующая глава →
Файловый сервер Samba [209.1]

Все главы курса «LPIC-2: инженер Linux (201 + 202)»

Поделиться темой: ✈ Telegram VK

Вернуться в «LPIC-2: инженер Linux»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость