wiki/docs/nginx/Nginx.md
2025-03-20 23:39:48 +03:00

396 lines
24 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

### root vs alias
#### root
Добавляет URL к указанному пути.
```
location /images/ {
root /var/www/myapp/static/;
}
```
Если запрошен URL `/images/photo.jpg`, Nginx будет искать файл по пути `/var/www/myapp/static/images/photo.jpg`.
#### alias
Заменяет часть URL на указанный путь.
```
location /images/ {
alias /var/www/myapp/static/;
}
```
Если запрошен URL `/images/photo.jpg`, Nginx будет искать файл по пути `/var/www/myapp/static/photo.jpg`.
В `alias` корреткно не работают регулярки
!!! tip ""
Не забывай добавлять `/` в конце строки в директиве `location`
### Директивы
#### http
Блок `http` используется для настройки параметров, связанных с обработкой HTTP-запросов.
#### server
Блок `server` определяет виртуальный сервер (хост). Внутри этого блока настраиваются параметры для обработки запросов к определенному домену или IP-адресу.
- `listen`: Порт и IP-адрес, на котором сервер будет принимать запросы.
- `server_name`: Имя сервера (домен или поддомен). `server_name _`: Nginx использует этот блок server как сервер по умолчанию для запросов, которые не соответствуют другим блокам `server`.
- `location`: Блоки для обработки конкретных URL.
#### map
```
map $переменная $новая_переменная {
значение1 результат1;
значение2 результат2;
default результат_по_умолчанию;
}
```
```
map $remote_addr $backend {
192.168.1.100 backend_special; # Для конкретного IP
default backend_default; # По умолчанию
}
upstream backend_default {
server 192.168.1.1;
}
upstream backend_special {
server 192.168.1.2;
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://$backend;
}
}
```
#### Разное
- `upstream`: Используется для настройки балансировки нагрузки между несколькими серверами
```
http {
upstream backend {
server 192.168.1.1;
server 192.168.1.2;
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend;
}
}
}
```
- `include`: Позволяет подключать дополнительные конфигурационные файлы
- `error_page`: Настройка страниц ошибок
- `access_log` и `error_log`: Настройка логов
---
Директива `worker_processes` определяет количество процессов (worker processes), которые Nginx будет использовать для обработки запросов. При значение `auto` Nginx автоматически определяет оптимальное количество worker-процессов на основе количества ядер CPU. Каждый worker-процесс может обрабатывать множество соединений (зависит от параметра `worker_connections`).
---
Блок `location`
- `root`: Корневая директория для поиска файлов.
- `alias`: Замена части URL на другой путь.
- `proxy_pass`: Перенаправление запросов на другой хост.
- `try_files`: Попытка найти файл по указанному пути.
---
`access_log` глобально задать нельзя. Можно переопределять на уровне `http`, `server` или `location`.
`error_log` можно задать глобально. Можно переопределять на уровне `http`, `server` или `location`.
---
- `allow 127.0.0.1` - разрешить доступ только с ip 127.0.0.1
- `deny allow` - запрещает доступ всем ip адресам, кроме `allow`
- `stub_status on`
Включает модуль `ngx_http_stub_status_module`, который предоставляет статистику о работе Nginx. Например:
- Активные соединения.
- Количество принятых запросов.
- Количество обработанных запросов.
- Текущее состояние (чтение, запись, ожидание).
```
# Передаёт backend-серверу доменное имя хоста из запроса клиента
proxy_set_header Host $host;
# Передаёт backend-серверу ip-адрес клиента
proxy_set_header X-Real-IP $remote_addr;
# Передаёт цепочку прокси-серверов, через которые прошёл запрос и добавляет в конец реальный ip-адрес клиента
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# Передаёт backend-серверу протокол, который использовал клиент (например, http или https)
proxy_set_header X-Forwarded-Proto $scheme;
```
#### http-заголовки
- `add_header` Добавляет произвольный заголовок в ответ сервера
- `proxy_hide_header` Удаляет заголовки, которые передаются от проксируемого сервера
- `proxy_set_header` Позволяет изменять или добавлять HTTP-заголовки, которые Nginx передаёт проксируемому серверу. Добавляет заголовок, если его нет. Перезаписывает, если он уже есть.
- `set_header` Аналогично proxy_set_header, но используется для других типов запросов (не только прокси).
- `proxy_pass_header` Разрешает передачу определённых заголовков клиенту (если они были скрыты по умолчанию).
- `server_tokens off;` Отключает вывод версии Nginx в заголовке Server.
- `etag on|off;` Включает или отключает генерацию заголовка ETag для статических файлов.
- `if_modified_since` Управляет поведением заголовка If-Modified-Since.
- `expires` Устанавливает заголовок Expires для управления кэшированием.
- `expires 1h;` Кэшировать на 1 час
- `expires max;` Кэшировать на максимальный срок
- Модуль `ngx_headers_more` Предоставляет дополнительные возможности для работы с заголовками
- `more_set_headers` Добавляет или изменяет заголовки.
- `more_clear_headers` Удаляет заголовки.
- `more_set_input_headers` Изменяет заголовки входящих запросов.
- `more_clear_input_headers` Удаляет заголовки входящих запросов.
#### Cache-Control
- `add_header Cache-Control` - это HTTP-заголовок, который указывает, как и насколько долго контент может кэшироваться.
!!! info ""
Браузеры и прокси-серверы будут кэшировать контент в соответствии с Cache-Control.
Очистка кэша:
Если файл изменился, нужно изменить его имя или добавить версию (например, style-v2.css).
Cache-Control имеет приоритет над устаревшим заголовком Expires.
##### Параметры Cache-Control
- `public` - указывает, что контент может кэшироваться любыми кэширующими устройствами, включая браузеры, прокси-серверы, CDN
- `max-age` - ремя (в секундах), на которое контент может быть кэширован
- `private` - Контент может кэшироваться только в браузере, но не на прокси-серверах
- `must-revalidate` - Кэш должен проверять актуальность контента на сервере после истечения max-age
- `no-store` - Контент не должен кэшироваться.
- `no-transform` - Запрещает промежуточным прокси-серверам изменять контент (например, сжимать изображения или изменять кодировку). Прокси-серверы обязаны передавать контент в оригинальном виде.
- `immutable` - Браузер кэширует контент и помечает его как "неизменяемый" на время, указанное в max-age. При повторном запросе браузер не отправляет запрос на сервер для проверки актуальности. Браузер просто использует кэшированную версию.
- `no-cache` - Браузер кэширует контент, но помечает его как "требующий проверки". При повторном запросе браузер отправляет на сервер запрос с заголовками (If-None-Match: Значение ETag (уникальный идентификатор контента). If-Modified-Since: Время последнего изменения контента.) Сервер проверяет: Если контент не изменился, сервер возвращает 304 Not Modified, и браузер использует кэшированную версию. Если контент изменился, сервер возвращает новый контент с 200 OK.
### Проксирование
Когда Nginx получает запрос от клиента, он не изменяет заголовки по умолчанию. Однако, если Nginx выступает в роли прокси (используется proxy_pass), он может изменить или удалить некоторые заголовки.
При проксировании Nginx передаёт следующие заголовки:
- `Host` - По умолчанию Nginx передаёт заголовок Host из запроса клиента, но если используется proxy_pass, Nginx может заменить Host на IP-адрес backend-сервера, если не указано иное.
- `Connection` - Nginx автоматически добавляет или изменяет заголовок Connection для управления keepalive-соединениями (значение заголовка: `keep-alive`, `close`)
- `X-Real-IP`
- `X-Forwarded-For`
- `X-Forwarded-Proto`
Nginx автоматически добавляет заголовки `X-Forwarded-For`, `X-Real-IP` и `X-Forwarded-Proto`, если они не указаны явно.
Остальные заголовки не передаются, если не указаны явно с помощью `proxy_set_header`.
### Переменные в Nginx
- `$host` - доменное имя сервера и порт (если указан), содержит значение заголовка Host из запроса клиента
- `$content_type` - значение заголовка `Content-Type` из запроса клиента
- `$content_length` - значение заголовка `Content-Length` из запроса клиента
- `$remote_addr` - ip-адрес клиента, который сделал запрос
- `$scheme` - протокол запроса
- `$request_method` - http метод запроса
- `$request_uri` - полный URL запроса
- `$uri` - URL без параметров
- `$args` - параметры запроса, часть после `?`
- `$cookie_*` - переменные для доступа к кукам, из запроса клиента.
- `$http_*` - переменные для доступа к любым HTTP-заголовкам, из запроса клиента.
- `$http_user_agent` — заголовок User-Agent.
- `$http_referer` — заголовок Referer.
- `$server_name` - значение, указанное в директиве server_name в конфигурации Nginx
- `$server_port` - порт на который пришел запрос
- `$status` - http статус ответа
- `$upstream_*` - содержат информацию о взаимодействии Nginx с backend-серверами (upstream)
- `$upstream_addr` - IP-адрес и порт backend-сервера, который обработал запрос
- `$upstream_status` - HTTP-статус ответа от backend-сервера
- `$upstream_response_time` - Время, которое backend-сервер потратил на обработку запроса (в секундах)
- `$upstream_header_*` - Заголовки, полученные от backend-сервера.
### Уровни логирования
1. `debug`: Отладочные сообщения (самый подробный уровень).
2. `info`: Информационные сообщения.
3. `notice`: Важные, но не критические события.
4. `warn`: Предупреждения.
5. `error`: Ошибки (например, проблемы с конфигурацией).
6. `crit`: Критические ошибки.
7. `alert`: Ещё более критические ошибки.
8. `emerg`: Аварийные ситуации (Nginx не работает).
### Пример конфига
```
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on; # использование системного вызова sendfile Вместо того чтобы читать файл в память и затем отправлять его клиенту, Nginx использует sendfile, чтобы передать файл напрямую из файловой системы в сетевой интерфейс.
keepalive_timeout 120; # секунд держится открытым соединение
keepalive_requests 10000; # запросов можно отправить в открытое соединение
server_tokens off; # Отключает отображение версии Nginx в HTTP-заголовках и страницах ошибок.
# Сжатие
gzip on; # Включает сжатие gzip.
gzip_types text/plain text/css application/json application/javascript text/javascript application/pdf application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; # Указывает типы файлов, которые нужно сжимать
gzip_min_length 1000; # Сжимает только файлы размером больше 1000 байт. Мелкие файлы сжимать неэффективно
gzip_comp_level 5; # Устанавливает уровень сжатия. Значение 5 — это баланс между скоростью и степенью сжатия. (gzip от 1 до 9)
gzip_proxied any; # Cжатие для проксируемые запросов
gzip_vary on; # Добавляет заголовок Vary: Accept-Encoding, чтобы прокси-серверы правильно кэшировали сжатые и несжатые версии файлов.
gzip_disable "msie6"; # Отключает сжатие для старых версий Internet Explorer (6 и ниже)
server {
# TLS
listen 443 ssl;
http 2 on;
server_name ${DOMAIN};
ssl_certificate /etc/letsencrypt/live/${DOMAIN}/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/${DOMAIN}/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/${DOMAIN}/chain.pem; # Предоставляет цепочку доверия для проверки OCSP-ответов
ssl_protocols TLSv1.3; # Разрешает только TLS 1.3 (самая современная и безопасная версия TLS).
ssl_prefer_server_ciphers on; # Указывает, что сервер выбирает шифры, а не клиент
ssl_session_timeout 1d; # ремя жизни SSL-сессии — 1 день. Это позволяет повторно использовать SSL-сессии для уменьшения нагрузки на сервер.
ssl_session_cache shared:MozSSL:10m; # размер кэша для SSL-сессий
ssl_early_data on; # В TLS 1.3 клиент может отправить данные до завершения полного рукопожатия, если он уже подключался к серверу ранее
ssl_session_tickets off; # Отключает TLS session tickets (устаревший механизм, который может быть уязвим).
# требуется ssl_trusted_certificate
ssl_stapling on; # Включает OCSP stapling. Сервер сам проверяет статус сертификата и отправляет клиенту, что ускоряет загрузку.
ssl_stapling_verify on; # Включает проверку OCSP ответов
# Безопасность
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always; # Заставляет браузеры использовать только HTTPS для подключения
add_header X-Content-Type-Options "nosniff" always; # Запрещает браузерам "угадывать" MIME-тип файла (MIME sniffing), что может предотвратить атаки, связанные с неправильной интерпретацией содержимого
add_header X-XSS-Protection "1; mode=block" always; # Включает встроенную защиту браузера от межсайтового скриптинга (XSS)
add_header Referrer-Policy "strict-origin-when-cross-origin" always; # strict-origin-when-cross-origin — полный URL отправляется только при переходе внутри одного домена. При переходе на другой домен отправляется только источник (origin, например, https://example.com), а при переходе с HTTPS на HTTP реферер не отправляется
add_header Content-Security-Policy "default-src 'self';" always; # разрешает загрузку ресурсов (скрипты, стили, изображения и т.д.) только с текущего домена (и запрещает встраивание из внешних источников)
# Проксирование
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
root /usr/share/nginx/html;
try_files $uri $uri/ /index.html;
}
location / {
proxy_pass http://frontend:1234;
}
# Прокси для API и admin
location /api/ {
proxy_pass http://backend:8000;
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;
}
location /admin/ {
proxy_pass http://backend:8000;
}
location /django_static/ {
alias /app/staticfiles/;
access_log off;
etag on; # это уникальный идентификатор файла, который используется для проверки, изменился ли файл на сервере
if_modified_since exact; # Указывает Nginx использовать точное сравнение времени модификации файла (вместо учета возможных погрешностей)
add_header Cache-Control "max-age=31536000, public, no-transform, no-cache";
}
}
server {
listen 80;
server_name ${DOMAIN};
return 301 https://$host$request_uri;
}
}
```
### Древовидная схема архитектуры Nginx
```
/ (корневая директория)
├── etc/
│ └── nginx/ # Основная конфигурация Nginx
│ ├── nginx.conf # Главный конфигурационный файл
│ ├── conf.d/ # Дополнительные конфигурационные файлы
│ │ └── example.conf # Конфигурация для конкретного сайта
│ ├── sites-available/ # Доступные конфигурации сайтов
│ │ └── example.com # Конфигурация для example.com
│ ├── sites-enabled/ # Активированные конфигурации сайтов (симлинки на sites-available)
│ │ └── example.com -> ../sites-available/example.com
│ ├── modules-available/ # Доступные модули
│ ├── modules-enabled/ # Активированные модули (симлинки на modules-available)
│ ├── mime.types # MIME-типы файлов
│ ├── fastcgi.conf # Конфигурация FastCGI
│ ├── proxy_params # Параметры проксирования
│ └── snippets/ # Общие фрагменты конфигурации
│ └── ssl.conf # Настройки SSL
├── var/
│ └── www/ # Корневая директория для сайтов
│ ├── html/ # Стандартная директория для статических файлов
│ │ └── index.html # Стандартный индексный файл
│ └── example.com/ # Директория для сайта example.com
│ ├── public_html/ # Корневая директория сайта
│ │ └── index.html # Индексный файл сайта
│ └── logs/ # Логи сайта
│ ├── access.log # Лог доступа
│ └── error.log # Лог ошибок
├── usr/
│ └── lib/
│ └── nginx/ # Модули и бинарные файлы Nginx
│ ├── modules/ # Динамически загружаемые модули
│ └── nginx # Исполняемый файл Nginx
└── run/
└── nginx.pid # PID-файл Nginx (хранит ID процесса)
```