Инструменты пользователя

Инструменты сайта


how-to:nginx

Nginx

Тестирование конфигурации:

sudo nginx -t

Перезапустить nginx с проверкой новой конфигурацией:

sudo nginx -s reload

Твики

server_tokens off; #запретить выдавать версию nginx’а на страницах ошибок и в поле “Server” заголовка ответа.

https://nginx.org/ru/docs/http/ngx_http_core_module.html

Балансировка

Для активной проверки требуется модуль (не доступен в стандартном nginx): https://github.com/nginx-modules/nginx_upstream_check_module

Dockerfile

Dockerfile

FROM nginx:1.18.0-alpine
 
LABEL link1="https://github.com/nginx-modules/nginx_upstream_check_module"
 
RUN set -x \
  && tempDir="$(mktemp -d)" \
  && chown nobody:nobody $tempDir \
  && cd $tempDir \
  && wget "http://nginx.org/download/nginx-${NGINX_VERSION}.tar.gz" \
  && tar xzf nginx-${NGINX_VERSION}.tar.gz \
  && apk add --no-cache --virtual .build-deps gcc libc-dev make openssl-dev pcre-dev zlib-dev linux-headers curl gnupg libxslt-dev gd-dev geoip-dev git \
  && git clone --depth 1 https://github.com/nginx-modules/nginx_upstream_check_module nginx-${NGINX_VERSION}/nginx_upstream_check_module \
  && CONFARGS=$(nginx -V 2>&1 | sed -n -e 's/^.*arguments: //p') \
  && CONFARGS=${CONFARGS/-Os -fomit-frame-pointer/-Os} \
  && cd nginx-$NGINX_VERSION \
  && patch -p1 < nginx_upstream_check_module/check_1.16.1+.patch \
  && ./configure --with-compat $CONFARGS --add-module=nginx_upstream_check_module \
  && make \
  && make install \
  && cd / \
  && rm -rf $tempDir \
  && apk del .build-deps \
  && rm -rf /var/cache/apk/* \
  && ln -sf /dev/stdout /var/log/nginx/access.log \
  && ln -sf /dev/stderr /var/log/nginx/error.log
 
EXPOSE 80
 
STOPSIGNAL SIGTERM
 
CMD ["nginx", "-g", "daemon off;"]

Пример конфигурации с активной проверкой:

nginx.conf

nginx.conf

server_tokens off;

upstream docs {
  least_conn;
  server docs1.domain.com weight=10;
  server docs2.domain.com;
  check interval=5000 rise=1 fall=3 timeout=4000 type=http;
  check_http_send "HEAD / HTTP/1.1\r\nHost: docs.domain.com\r\nUser-Agent: nginx\r\n\r\n";
}

server {
        listen 80 default;
        return 307 https://$host$request_uri;
}

server {
  listen 443 ssl;
  server_name docs.domain.com;

  proxy_set_header Host                $http_host;
  proxy_set_header X-Real-IP           $remote_addr;
  proxy_set_header X-Forwarded-Ssl     on;
  proxy_set_header X-Forwarded-For     $proxy_add_x_forwarded_for;
  proxy_set_header X-Forwarded-Proto   $scheme;

  location / {
    proxy_pass http://docs;
  }

  ssl_protocols	SSLv3 TLSv1.2 TLSv1.3;
  ssl_certificate	/ssl/domain.com.crt;
  ssl_certificate_key	/ssl/domain.com.key;
  ssl_dhparam		/ssl/dhparam.pem;
}

SSL

Создать самоподписанный сертификат и ключ:

openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout /etc/nginx/ssl/selfsigned.key -out /etc/nginx/ssl/selfsigned.crt
openssl dhparam -out /etc/nginx/ssl/dhparam.pem 2048

Генератор SSL конфигурационных файлов для web серверов

Конфигурацию SSL можно выполнить для всех сайтов в секции http.

https://habr.com/ru/post/195808/
http://nginx.org/ru/docs/http/configuring_https_servers.html

log_format

http://nginx.org/ru/docs/http/ngx_http_log_module.html#log_format

На уровне http (/etc/nginx/nginx.conf) в «# Logging Settings»:

log_format detailed '$remote_addr - $remote_user [$time_local] '
  '"$request" $status $body_bytes_sent "$http_referer" '
  '"$http_user_agent" $request_length $request_time '
  '$upstream_response_length $upstream_response_time '
  '$upstream_status';

где:

  • $request_length – полный размер запроса, включая заголовки и тело, в байтах
  • $request_time – время обработки запроса, в миллисекундах
  • $upstream_response_length – длинна ответа полученного от отладочного сервера, в байтах
  • $upstream_response_time– время затраченное на получение ответа от отладочного сервера, в миллисекундах
  • $upstream_status – код статуса ответа от отладочного сервера

В необходимом месте добавляем:

access_log /var/log/nginx/application_access.log detailed;

https://habrahabr.ru/post/308880/ - NGINX: Перехват ошибок 5хх с помощью отладочного сервера

Модули

Модуль ngx_http_autoindex_module

Модуль ngx_http_autoindex_module обслуживает запросы, оканчивающиеся слэшом (‘/’), и выдаёт листинг каталога. Обычно запрос попадает к модулю ngx_http_autoindex_module, когда модуль ngx_http_index_module не нашёл индексный файл.

Пример конфигурации

location / {
    autoindex on;
}

Директивы

синтаксис: autoindex on | off;
умолчание: autoindex off;
контекст: http, server, location

- разрешает или запрещает вывод листинга каталога.

синтаксис: autoindex_exact_size on | off;
умолчание: autoindex_exact_size on;
контекст: http, server, location

- определяет, как выводить размеры файлов в листинге каталога: точно или округляя до килобайт, мегабайт и гигабайт.

синтаксис: autoindex_localtime on | off;
умолчание: autoindex_localtime off;
контекст: http, server, location

- определяет, в какой временной зоне выводить время в листинге каталога: в локальной или в UTC.

http://nginx.org/ru/docs/http/ngx_http_autoindex_module.html

Модуль ngx_http_core_module

Директивы

синтаксис: connection_pool_size размер;
умолчание: connection_pool_size 1m;
контекст: http, server

- задаёт максимально допустимый размер тела запроса клиента, указываемый в поле “Content-Length” заголовка запроса. Если размер больше заданного, то клиенту возвращается ошибка 413 (Request Entity Too Large). Следует иметь в виду, что браузеры не умеют корректно показывать эту ошибку. Установка параметра размер в 0 отключает проверку размера тела запроса клиента.

http://nginx.org/ru/docs/http/ngx_http_core_module.html

Модуль ngx_http_access_module

Директивы

синтаксис: allow адрес | CIDR | unix | all;
умолчание: -
контекст: http, server, location, limit_except

Разрешает доступ для указанной сети или адреса. Если указано специальное значение unix: (1.5.1), разрешает доступ для всех UNIX-сокетов.

синтаксис: deny адрес | CIDR | unix | all;
умолчание: -
контекст: http, server, location, limit_except

Запрещает доступ для указанной сети или адреса. Если указано специальное значение unix: (1.5.1), запрещает доступ для всех UNIX-сокетов.

http://nginx.org/ru/docs/http/ngx_http_access_module.html

Docker

Пример запуска Nginx, в /data/docker/nginx/etc_nginx_conf.d должен существовать default.conf, приложение должно быть в /data/docker/nginx/var_www:

docker run -d -p80:80 --mount type=bind,src=/data/docker/nginx/etc_nginx_conf.d,dst=/etc/nginx/conf.d --mount type=bind,src=/data/docker/nginx/var_www,dst=/var/www/ --name nginx nginx:alpine

Пример для PHP:

default.conf

default.conf

server {
  listen 80;

  root /var/www;
  index index.html index.php;

  location ~ \.php$ {
    fastcgi_pass   mngt.domain.com:9000;
    fastcgi_index  index.php;
    fastcgi_param  PATH_INFO $fastcgi_script_name;
    fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
    include /etc/nginx/fastcgi_params;
  }
  location = /favicon.ico {
    log_not_found off;
  }
}


https://hub.docker.com/_/nginx

nginx-spnego

Dockerfile

Dockerfile

FROM nginx:1.16.1-alpine

LABEL maintainer="domain" \
      release-date="2020–02–09" \
      link1="https://github.com/stnoonan/spnego-http-auth-nginx-module" \
      link2="https://gist.github.com/hermanbanken/96f0ff298c162a522ddbba44cad31081" \
      link3="https://github.com/fclmman/alpine-nginx-spnego/blob/master/Dockerfile"

RUN set -x \
  && tempDir="$(mktemp -d)" \
  && chown nobody:nobody $tempDir \
  && cd $tempDir \
  && wget "http://nginx.org/download/nginx-${NGINX_VERSION}.tar.gz" \
  && tar xzf nginx-${NGINX_VERSION}.tar.gz \
  && apk add --no-cache krb5 \
  && apk add --no-cache --virtual .build-deps gcc libc-dev make openssl-dev pcre-dev zlib-dev linux-headers curl gnupg libxslt-dev gd-dev geoip-dev git krb5-dev \
  && git config --global http.proxy $http_proxy \
  && git clone https://github.com/stnoonan/spnego-http-auth-nginx-module.git nginx-${NGINX_VERSION}/spnego-http-auth-nginx-module \
  && CONFARGS=$(nginx -V 2>&1 | sed -n -e 's/^.*arguments: //p') \
  && CONFARGS=${CONFARGS/-Os -fomit-frame-pointer/-Os} \
  && cd nginx-$NGINX_VERSION \
  && ./configure --with-compat $CONFARGS --add-dynamic-module=spnego-http-auth-nginx-module \
  && make modules \
  && cp objs/ngx_http_auth_spnego_module.so /etc/nginx/modules/ \
  && sed -i -e '1 s/^/load_module \/etc\/nginx\/modules\/ngx_http_auth_spnego_module.so;\n/;' /etc/nginx/nginx.conf \
  && cd / \
  && rm -rf $tempDir \
  && apk del .build-deps \
  && rm -rf /var/cache/apk/* \
  && ln -sf /dev/stdout /var/log/nginx/access.log \
  && ln -sf /dev/stderr /var/log/nginx/error.log

EXPOSE 80

STOPSIGNAL SIGTERM

CMD ["nginx", "-g", "daemon off;"]


ingress

Запустить:

Нажмите, чтобы отобразить

Нажмите, чтобы скрыть

#docker
docker run -d -p443:443 -p80:80 \
  -v /data/docker/nginx/conf:/etc/nginx/conf.d:ro \
  -v /data/docker/nginx/ssl:/ssl:ro \
  --name nginx nginx:stable-alpine
 
#docker-compose
docker-compose up -d
 
#swarm
docker service create -p 443:443 -p80:80 \
 --mount type=bind,source=/data/docker/nginx/conf,destination=/etc/nginx/conf.d,readonly \
 --mount type=bind,source=/data/docker/nginx/ssl,destination=/ssl,readonly \
 --name nginx nginx:stable-alpine
 
docker stack deploy --compose-file docker-compose.yaml nginx

docker-compose.yaml

docker-compose.yaml

version: '3.7'
volumes:
  conf:
    driver_opts:
      type: none
      device: ${VOLPATH-/data/docker/nginx}/conf
      o: bind
  ssl:
    driver_opts:
      type: none
      device: ${VOLPATH-/data/docker/nginx}/ssl
      o: bind

services:
 nginx:
  image: nginx:stable-alpine
  container_name: nginx
  ports:
    - mode: host
      protocol: tcp
      published: 80
      target: 80
    - mode: host
      protocol: tcp
      published: 443
      target: 443
  volumes:
   - conf:/etc/nginx/conf.d:ro
   - ssl:/ssl:ro
  restart: always


k8s

default-ssl-certificate

https://kubernetes.github.io/ingress-nginx/user-guide/tls/#default-ssl-certificate

Установить значение через helm:

helm --namespace ingress-basic upgrade --install --create-namespace nginx-ingress ingress-nginx/ingress-nginx \
 --set controller.extraArgs.default-ssl-certificate=namespace/secret-name

https://github.com/kubernetes/ingress-nginx/blob/master/charts/ingress-nginx/values.yaml

или изменить deployment, добавить args --default-ssl-certificate=namespace/secret-name:

kubectl edit deployment/nginx-ingress-controller

https://stackoverflow.com/questions/58972609/kubernetes-ingress-how-to-set-default-ssl-certificate

limit_req

Ограничить кол-во запросов

Ограничить кол-во запросов

По 2r/s на 1 IP, с всплесками до 1 и общим по 4r/s с всплесками до 3 на определённый путь.

Обновить configmap в nginx, для helm:

  --set controller.allowSnippetAnnotations=true \
  --set controller.config.http-snippet='limit_req_zone $binary_remote_addr_map zone=ip_v3request:10m rate=2r/s;
map $request_uri $binary_remote_addr_map {
  ~*^/api/v3/Request $binary_remote_addr;
}
limit_req_zone $v3request_map zone=v3request:10m rate=4r/s;
map $request_uri $v3request_map {
  ~*^/api/v3/Request 1;
}'

и добавить в ingress сервиса:

ingress:
  annotations:
    nginx.ingress.kubernetes.io/configuration-snippet: |
      limit_req zone=ip_v3request burst=1 nodelay;
      limit_req zone=v3request burst=3 nodelay;
      limit_req_status 429;


Ошибки

client intended to send too large body

В nginx/error.log. Необходимо увеличить размер connection_pool_size.

open() ".../favicon.ico" failed (2: No such file or directory)

В nginx/error.log. Добавляем в конфигурацию сайта:

location = /favicon.ico {
  log_not_found off;
}

Upstream sent too big header while reading response header from upstream

В nginx/error.log. Добавляем в конфигурацию сайта в блок с опцией fastcgi_pass:

fastcgi_buffers 16 32k;
fastcgi_buffer_size 32k;

либо в блок с опциями proxy_

proxy_buffer_size 64k;
proxy_buffers 4 128k;
proxy_busy_buffers_size 128k;

http://eddnet.org/?p=2121

how-to/nginx.txt · Последнее изменение: 127.0.0.1