# For more information on configuration, see:
# * Official English Documentation: http://nginx.org/en/docs/
# * Official Russian Documentation: http://nginx.org/ru/docs/

user nginx;
worker_processes auto;
worker_rlimit_nofile 100000;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 8192;
    use epoll;
    multi_accept on;
}

http {
    log_format main_ext '$remote_addr - $remote_user [$time_local] "$request" '
                        '$status $body_bytes_sent "$http_referer" '
                        '"$http_user_agent" "$http_x_forwarded_for" '
                        '"$host" sn="$server_name" '
                        'rt=$request_time '
                        'ua="$upstream_addr" us="$upstream_status" '
                        'ut="$upstream_response_time" ul="$upstream_response_length" '
                        'cs=$upstream_cache_status' ;

    access_log off;
    server_tokens off;
    open_file_cache max=200000 inactive=20s;
    open_file_cache_valid 30s;
    open_file_cache_min_uses 2;
    open_file_cache_errors on;
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 30;
    keepalive_requests 100;
    types_hash_max_size 2048;

    reset_timedout_connection on;
    client_body_timeout 10;
    client_max_body_size 8M;
    send_timeout 2;

    gzip on;
    gzip_min_length 10240;
    gzip_comp_level 1;
    gzip_vary on;
    gzip_disable msie6;
    gzip_proxied expired no-cache no-store private auth;
    gzip_types
        text/css
        text/javascript
        text/xml
        text/plain
        text/x-component
        application/javascript
        application/x-javascript
        application/json
        application/xml
        application/rss+xml
        application/atom+xml
        font/truetype
        font/opentype
        application/vnd.ms-fontobject
        image/svg+xml;

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

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers off;

    # Global Security Headers
    add_header X-Content-Type-Options nosniff;
    add_header X-Frame-Options SAMEORIGIN;
    add_header X-XSS-Protection "1; mode=block";
    add_header Strict-Transport-Security 'max-age=31536000; includeSubDomains; preload;';
    add_header Referrer-Policy 'strict-origin-when-cross-origin';
    add_header Set-Cookie "user=$remote_user; Path=/; HttpOnly; Secure";

    # =========================================================================
    # 1. DETEKSI BAD BOTS & EXPLOIT SCANNER (GENERATE from GEMINI.AI)
    # =========================================================================
    map $http_user_agent $bot_scanner {
        default 0;
        ~*wp2shell-audit  1;
        ~*wp2shell-rce    1;
        ~*Go-http-client  1;
        ~*nikto           1;
        ~*sqlmap          1;
        ~*nmap            1;
        ~*dirbuster       1;
        ~*acunetix        1;
    }

    # MAP 1: Deteksi path admin / webmin (pakai regex wildcard ~*webmin biar kena semua variasi)
    map $request_uri $is_admin_path {
        default 0;
        ~*webmin 1;
    }

    # MAP 2: Deteksi IP Whitelist Kantor
    map $remote_addr $is_whitelisted_ip {
        default 0;
        ~^103\.86\.103\.   1;
        ~^103\.147\.218\.  1;
    }

    # MAP 3: Penentu Blokir (Jika Admin Path = 1 dan Whitelist = 0 -> Nilai $deny_admin jadi 1)
    map "$is_admin_path$is_whitelisted_ip" $deny_admin {
        default 0;
        "10"    1;
    }

    # =========================================================================
    # 2. RATE LIMITING ZONES (TAMBAHAN CONSULTANT)
    # =========================================================================
    # Zone Global: Maksimal 10 request per detik per IP (untuk lalu lintas normal)
    limit_req_zone $binary_remote_addr zone=global_limit:10m rate=10r/s;
    
    # Zone Login: Maksimal 1 request per detik per IP (cegah Brute-Force ke /webmin, wp-login, dll)
    limit_req_zone $binary_remote_addr zone=login_limit:10m rate=1r/s;

    # Response code saat kena limit (429 = Too Many Requests)
    limit_req_status 429;

    # Load modular configuration files
    include /etc/nginx/sites-enabled/*.conf;
    include /etc/nginx/conf.d/*.conf;

    include /etc/nginx/bots.d/*.conf;

    server {
        listen 80 default_server;
        listen [::]:80 default_server;
        server_name _;
        return 301 https://kominfo.kebumenkab.go.id$request_uri;

        include /etc/nginx/default.d/*.conf;
        include /etc/nginx/snippets/*.conf;

        location / {
        }

        location /stub_status {
            stub_status;
            allow 127.0.0.1;
            deny all;
        }

        error_page 404 /404.html;
        location = /40x.html {
        }

        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
        }
    }
}
