POST 요청 시 Nginx 역방향 프록시 403 오류

POST 요청 시 Nginx 역방향 프록시 403 오류

Unifi, PHP, Nginx, Certbot 등 Docker에서 서비스 스택을 설정하려고 합니다. 여기서 Unifi와 PHP는 백엔드 서비스이고 Nginx는 이를 역방향 프록시 모드에서 제공하는 반면 Certbot은 Nginx에 대한 SSL 인증서를 얻기 위해 주기적으로 실행됩니다. .

나는 대부분 그것을 작동하고 있습니다. 모든 GET 요청이 작동하고 Unifi가 제공하는 페이지를 볼 수 있습니다. 그러나 AJAX를 통한 모든 POST 요청은 모두 CORS로 인해 403 오류를 발생시킵니다.

이제 저는 CORS 헤더를 조작하는 방법이나 오류의 원인이 무엇인지 잘 모릅니다. 브라우저인가요, Nginx인가요, 아니면 unifi인가요? 하지만 구성을 변경할 수 있는 것은 Nginx뿐입니다.

브라우저 검사기/네트워크 모니터에서 모든 AJAX 게시 요청에 대해 발생하는 오류는 다음과 같습니다.

POST
scheme                    https
host                      example.com:8443
filename                  /api/stat/device
Address                   (server_ip_address):8443
Status                    403 Forbidden
Version                   HTTP/2
Transferred               141 B (0 B size)
Referrer Policy           strict-origin-when-cross-origin
    
    
RESPONSE HEADERS    
content-length            0
content-type              text/plain
date                      Fri, 17 Sep 2021 00:59:09 GMT
server                    nginx
X-Firefox-Spdy            h2
    
    
REQUEST HEADERS 
Accept                    application/json, text/plain, */*
Accept-Encoding           gzip, deflate, br
Accept-Language           en-US,en;q=0.5
Connection                keep-alive
Content-Length            0
Cookie                    unifises=(random token here); csrf_token=(random token here)
DNT                       1
Host                      example.com:8443
Origin                    https://example.com:8443
Referer                   https://example.com:8443/setup/configure/controller-name
Sec-Fetch-Dest            empty
Sec-Fetch-Mode            cors
Sec-Fetch-Site            same-origin
TE                        trailers
User-Agent                Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:92.0) Gecko/20100101 Firefox/92.0
X-Csrf-Token              (random token here)

Nginx 구성은 다음과 같습니다.

# enbables GZIP compression
gzip on;

# compression level (1-9)
# 6 is a good compromise between CPU usage and file size
gzip_comp_level 6;

# minimum file size limit in bytes to avoid negative compression
gzip_min_length 256;

# compress data for clients connecting via proxies
gzip_proxied any;

# directs proxies to cache both the regular and GZIp versions of an asset
gzip_vary on;

# disables GZIP compression for ancient browsers
gzip_disable "msie6";

server {
    listen 80;
    listen [::]:80;

    server_name example.com;

    location ~ /.well-known/acme-challenge {
        allow all;
        root /var/www/certbot/;
        }
    # Redirect relevant Unifi paths Unifi Address and Port
    location / {
        rewrite ^ https://$host:8443$request_uri?;
    }
}
server {
    listen 8443 ssl http2;
        listen [::]:8443 ssl http2;

    server_name example.com;

    server_tokens off;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    ssl_buffer_size 8k;

    ssl_dhparam /etc/ssl/certs/dhparam-2048.pem;

    ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
    ssl_prefer_server_ciphers on;

    ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;

    ssl_ecdh_curve secp384r1;
    ssl_session_tickets off;

    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 1.1.1.1 1.0.0.1 208.67.222.222 208.67.220.220;


    location / {

        add_header 'Access-Control-Allow-Origin' '*';
    add_header 'Access-Control-Allow-Credentials' 'true';
    add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
    add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';



        proxy_pass https://unifi:8443/;
        proxy_set_header Authorization "";
        proxy_pass_request_headers on;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Host $remote_addr;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Ssl on;
        proxy_http_version 1.1;
        proxy_buffering off;
        proxy_redirect off;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        auth_basic "Restricted";
        proxy_set_header Referer "";

    }
}

추적할 수 있는 것보다 Stack Exchange 안팎에서 더 많은 가이드를 찾는 데 지쳤기 때문에 내 구성이 이제 너무 지저분한 이유입니다.

그렇다면 CORS로 인해 실패하지 않고 XHR 요청을 처리하도록 Nginx를 어떻게 수정합니까?

편집 1: 8443과 함께 Nginx 수신 포트에 포트 443을 추가했습니다. 443을 통해 Unifi에 액세스하고 이를 unifi:8443으로 프록시하면 예상대로 작동합니다. 하지만 8443에서 투명하게 작동하려면 이것이 필요합니다.

편집 2: 구성을 약간 수정하여 또 다른 "중간자" Nginx 컨테이너를 추가해 보았습니다. 원래 Nginx 컨테이너의 포트 8443에 대한 요청을 포트 443의 두 번째 컨테이너로 프록시하고 이를 8443의 Unifi로 역방향 프록시했습니다. 이전과 같이 "중간자" 프록시가 없는 것과 동일한 결과입니다. 따라서 Web -> 8443의 Nginx -> 443의 Nginx -> 8443의 Unfi. 이 구성은 작동하지 않고 비효율적이므로 제거했습니다.

관련 정보