Я пытаюсь настроить стек сервисов в Docker: Unifi, PHP, Nginx и Certbot, где Unifi и PHP являются серверными сервисами, а Nginx обслуживает их в режиме обратного прокси, а Certbot периодически запускается для получения SSL-сертификатов для Nginx. .
У меня это в основном работает; все запросы GET работают, и я могу просматривать страницу, которую обслуживает Unifi. Однако все запросы POST через AJAX вызывают ошибку 403 из-за CORS.
Теперь я не очень хорошо разбираюсь в том, как манипулировать заголовками CORS или в чем причина ошибки. Браузер, Nginx или unifi? Тем не менее, Nginx — это все, что я могу изменить в конфигурации.
Вот ошибка, которую я получаю во всех почтовых запросах AJAX от инспектора браузера/сетевого монитора:
ПУБЛИКОВАТЬ
схема https
хост example.com:8443
имя файла /api/stat/device
Адрес (server_ip_address):8443
Статус 403 Запрещено
Версия HTTP/2
Передано 141 Б (размер 0 Б)
Политика реферера: строгое происхождение при перекрестном происхождении
ЗАГОЛОВКИ ОТВЕТОВ
длина содержимого 0
тип содержимого текстовый/обычный
дата Пт, 17 Сен 2021 00:59:09 GMT
сервер nginx
X-Firefox-Spdy h2
ЗАГОЛОВКИ ЗАПРОСА
Принять application/json, text/plain, */*
Accept-Encoding gzip, deflate, br
Accept-Language en-US,en;q=0,5
Поддержание соединения
Длина содержимого 0
Cookie unifises=(здесь случайный токен); csrf_token=(здесь случайный токен)
ДНТ 1
Хост example.com:8443
Происхождение https://example.com:8443
Реферер https://example.com:8443/setup/configure/имя-контроллера
Sec-Fetch-Dest пуст
Корс Sec-Fetch-Mode
Sec-Fetch-Site того же происхождения
прицепы ТЭ
User-Agent Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:92.0) Gecko/20100101 Firefox/92.0
X-Csrf-Token (случайный токен здесь)
Вот конфиг Nginx:
# включает сжатие GZIP
gzip включен;
# уровень сжатия (1-9)
# 6 — хороший компромисс между использованием процессора и размером файла.
gzip_comp_level 6;
# ограничение минимального размера файла в байтах, чтобы избежать отрицательного сжатия
gzip_min_length 256;
# сжимаем данные для клиентов, подключающихся через прокси
gzip_proxy любой;
# указывает прокси-серверам кэшировать как обычную, так и GZIp-версию актива
gzip_vary включен;
# отключает сжатие GZIP для старых браузеров
gzip_disable "msie6";
сервер {
слушать 80;
слушать [::]:80;
имя_сервера пример.com;
местоположение ~ /.well-known/acme-challenge {
позволять все;
корень /var/www/certbot/;
}
# Перенаправление соответствующих путей Unifi Адрес и порт Unifi
место расположения / {
переписать ^ https://$host:8443$request_uri?;
}
}
сервер {
слушать 8443 ssl http2;
слушать [::]:8443 ssl http2;
имя_сервера пример.com;
server_tokens отключены;
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 включен;
ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;
ssl_ecdh_curve secp384r1;
ssl_session_tickets выключен;
ssl_stapling включен;
ssl_stapling_verify включен;
преобразователь 1.1.1.1 1.0.0.1 208.67.222.222 208.67.220.220;
место расположения / {
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';
прокси_пасс https://unifi:8443/;
proxy_set_header Авторизация "";
proxy_pass_request_headers включен;
proxy_set_header Хост $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 $ схема;
proxy_set_header X-Forwarded-Ssl включен;
прокси_http_версия 1.1;
прокси_буферизация выключена;
прокси_перенаправление выключено;
proxy_set_header Обновить $http_upgrade;
proxy_set_header Соединение "Обновление";
auth_basic "Ограничено";
proxy_set_header Реферер "";
}
}
Я устал искать больше руководств по Stack Exchange и вне его, чем мог уследить, поэтому моя конфигурация теперь такая беспорядочная.
Итак, как мне изменить Nginx для обслуживания запросов XHR без сбоев из-за CORS?
Редактировать 1: я добавил порт 443 к портам прослушивания Nginx вместе с 8443. Если я получаю доступ к Unifi через 443 и проксирую его на unifi:8443, он работает, как и ожидалось. Но мне нужно, чтобы он работал прозрачно на 8443.
Редактировать 2: я попытался добавить еще один контейнер Nginx «посредник» с немного измененной конфигурацией.Я проксировал запросы на порт 8443 исходного контейнера Nginx во второй контейнер на порту 443 и обратно проксировал его на Unifi на 8443. Тот же результат, что и раньше, без прокси-сервера «человек посередине». Итак, Web -> Nginx на 8443 -> Nginx на 443 -> Unfi на 8443. Удалил этот конфиг, так как он не работал, к тому же он неэффективен.