Ich versuche, einen Stapel von Diensten in Docker einzurichten: Unifi, PHP, Nginx und Certbot, wobei Unifi und PHP die Backend-Dienste sind und Nginx sie im Reverse-Proxy-Modus bereitstellt, während Certbot regelmäßig ausgeführt wird, um SSL-Zertifikate für Nginx abzurufen.
Bei mir funktioniert es größtenteils; alle GET-Anfragen funktionieren und ich kann die von Unifi bereitgestellte Seite anzeigen. Alle POST-Anfragen über AJAX werfen jedoch aufgrund von CORS einen 403-Fehler aus.
Ich bin nicht besonders vertraut damit, wie man CORS-Header manipuliert oder was den Fehler verursacht. Liegt es am Browser, an Nginx oder an Unifi? Allerdings kann ich nur die Konfiguration von Nginx ändern.
Dies ist der Fehler, den ich bei allen AJAX-Postanfragen vom Browserinspektor/Netzwerkmonitor erhalte:
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)
Hier ist die Nginx-Konfiguration:
# 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 "";
}
}
Ich habe es satt, mir mehr Anleitungen auf und außerhalb von Stack Exchange anzuschauen, als ich im Auge behalten konnte. Deshalb ist meine Konfiguration jetzt so chaotisch.
Wie ändere ich also Nginx, um die XHR-Anfragen zu bedienen, ohne dass es aufgrund von CORS zu Fehlern kommt?
Bearbeitung 1: Ich habe Port 443 neben 8443 zu den Nginx-Abhörports hinzugefügt. Wenn ich über 443 auf Unifi zugreife und es per Proxy an unifi:8443 weiterleite, funktioniert es wie erwartet. Aber ich brauche es, damit es transparent auf 8443 funktioniert.
Bearbeitung 2: Ich habe versucht, einen weiteren „Middle-Man“-Nginx-Container mit einer leicht geänderten Konfiguration hinzuzufügen. Ich habe Anfragen an Port 8443 des ursprünglichen Nginx-Containers per Proxy an den zweiten Container an Port 443 weitergeleitet und das per Reverse-Proxy an Unifi an 8443. Dasselbe Ergebnis wie ohne den „Man-in-the-Middle“-Proxy wie zuvor. Also Web -> Nginx an 8443 --> Nginx an 443 -> Unfi an 8443. Diese Konfiguration wurde entfernt, da sie nicht funktionierte und außerdem ineffizient ist.