user www-data;
worker_processes auto;
worker_rlimit_nofile 65535;
pid /run/nginx.pid;

include /etc/nginx/modules-enabled/*.conf;

events {
    worker_connections 4096;
    multi_accept off;
}

http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    server_tokens off;
    charset utf-8;

    types_hash_max_size 4096;
    variables_hash_max_size 2048;
    proxy_headers_hash_max_size 1024;
    proxy_headers_hash_bucket_size 128;

    client_max_body_size 16m;
    client_body_buffer_size 128k;
    client_header_buffer_size 1k;
    large_client_header_buffers 4 16k;

    client_header_timeout 10s;
    client_body_timeout 15s;
    send_timeout 30s;
    keepalive_timeout 15s;
    keepalive_requests 1000;
    reset_timedout_connection on;

    open_file_cache max=10000 inactive=60s;
    open_file_cache_valid 60s;
    open_file_cache_min_uses 2;
    open_file_cache_errors on;

    log_format hardened '$remote_addr - $remote_user [$time_local] '
                        '"$request" $status $body_bytes_sent '
                        '"$http_referer" "$http_user_agent" '
                        'host="$host" request_id="$request_id" '
                        'request_time=$request_time '
                        'upstream_addr="$upstream_addr" '
                        'upstream_status="$upstream_status" '
                        'upstream_time="$upstream_response_time"';

    access_log /var/log/nginx/access.log hardened;
    error_log /var/log/nginx/error.log warn;

    gzip on;
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 5;
    gzip_min_length 1024;
    gzip_types
        application/atom+xml
        application/geo+json
        application/javascript
        application/json
        application/ld+json
        application/manifest+json
        application/rss+xml
        application/xml
        application/xhtml+xml
        font/otf
        font/ttf
        image/svg+xml
        text/css
        text/javascript
        text/plain
        text/xml;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_session_cache shared:SSL:20m;
    ssl_session_timeout 1d;
    ssl_session_tickets off;
    ssl_prefer_server_ciphers off;
    ssl_ecdh_curve auto;
    ssl_early_data off;

    limit_req_status 429;
    limit_conn_status 429;

    limit_req_zone $binary_remote_addr zone=api_per_ip:20m rate=20r/s;
    limit_req_zone $binary_remote_addr zone=login_per_ip:10m rate=5r/m;
    limit_req_zone $binary_remote_addr zone=static_per_ip:10m rate=100r/s;
    limit_conn_zone $binary_remote_addr zone=conn_per_ip:20m;

    map $http_upgrade $connection_upgrade {
        default upgrade;
        ''      close;
    }

    map $http_x_forwarded_proto $forwarded_proto {
        default $scheme;
        https   https;
        http    http;
    }

    # Отбрасывает запросы без подходящего Host/SNI.
    server {
        listen 80 default_server;
        listen [::]:80 default_server;
        server_name _;
        access_log off;
        return 444;
    }

    server {
        listen 443 ssl default_server;
        listen [::]:443 ssl default_server;
        http2 on;
        server_name _;

        # Замените сертификат либо оставьте этот server выключенным до выпуска сертификата.
        ssl_certificate     /etc/nginx/certs/default-fullchain.pem;
        ssl_certificate_key /etc/nginx/certs/default-privkey.pem;
        ssl_reject_handshake on;
        access_log off;
    }

    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
}
