В конфигурации обратного прокси-кода состояния 419 заменяется на 500.

Вопрос или проблема

Я немного изменил файл шаблона, с помощью которого генерируются конфигурации nginx, результат следующий:

# from nginxproxy/nginx-proxy
# uknp.dock/
upstream uknp.dock {
    # Container: WSDD-Web-Server-PHP8.3
    #     networks:
    #         wsdd-network (reachable)
    #     IP address: 172.18.0.2
    #     exposed ports (first ten): 10000/tcp 80/tcp
    #     default port: 80
    #     using port: 80
    server 172.18.0.2:80;
}
server {
    server_name uknp.dock;
    access_log /var/log/nginx/access.log vhost;
    http2 on;
    listen 80 ;
    location /.well-known/acme-challenge/ {
        proxy_intercept_errors off;
        fastcgi_intercept_errors off;
        auth_basic off;
        allow all;
        root /usr/share/nginx/html;
        try_files $uri =404;
        break;
    }
    listen 443 ssl ;
    ssl_session_timeout 5m;
    ssl_session_cache shared:SSL:50m;
    ssl_session_tickets off;
    ssl_certificate /etc/nginx/certs/uknp.dock.crt;
    ssl_certificate_key /etc/nginx/certs/uknp.dock.key;
    location / {
        proxy_intercept_errors off;
        fastcgi_intercept_errors off; 
        proxy_pass http://uknp.dock;
        set $upstream_keepalive false;
        # Add these headers to keep the original status codes
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        # Ensure that HTTP status codes are not modified
        proxy_ignore_headers Set-Cookie;
        proxy_pass_request_headers on;
    }
    # custom 419 error
    error_page 419 = /custom_419.html;
    location = /custom_419.html {
        internal;
        add_header Content-Type text/html;
        return 419 "Session expired or CSRF token invalid.";
    }
}

Это, предположительно, моя конфигурация обратного прокси, указывающая на контейнер Apache (который работал нормально, пока мне не пришлось реализовать статус код 419 для CSRF).

Независимо от моей конфигурации Nginx, он продолжает преобразовывать/перезаписывать ошибку 419 в 500…

<?php
// Set headers to avoid caching
header('Cache-Control: no-cache, no-store, must-revalidate');
header('Pragma: no-cache');
header('Expires: 0');

// Set custom header for CSRF
header('X-CSRF-TOKEN: expired_token_12345');

// Set status code 419 (CSRF Token Expired)
http_response_code(419);

// Response content in JSON format
header('Content-Type: application/json');

echo json_encode([
    'error' => true,
    'message' => 'CSRF token has expired',
    'code' => 419,
    'status' => 'CSRF_TOKEN_EXPIRED'
]);

Примечание: я уже перезапустил сервисы/контейнеры.

Ответ или решение

В приведенной вами конфигурации nginx выступает в роли обратного прокси, который необходим для маршрутизации запросов к Apache-серверу, находящемуся в контейнере. Основная проблема, с которой вы столкнулись, заключается в том, что при попытке вернуть статус код 419 для обработки ошибок CSRF, nginx почему-то заменяет этот статус код на 500. Давайте рассмотрим возможные причины и решения этой проблемы.

Теория

В мире веб-разработки статус код HTTP 419 не является официальным стандартом в спецификации HTTP. Однако он часто используется в приложениях для обозначения ошибок, связанных с истечением срока действия сессии или неправильно установленным CSRF-токеном. Обычно разработчики используют этот статус код для улучшения взаимодействия с пользователем.

При этом форматирование и обработка нестандартных кодов ошибок может вызывать проблемы в некоторых серверах и конфигурациях. Так как статус код 500 указывает на внутреннюю ошибку сервера, это может означать, что nginx просто не знает, как обрабатывать нестандартный статус код 419 и потому заменяет его на 500.

Пример

Давайте разберем вашу конфигурацию nginx:

server {
    ...
    location / {
        proxy_intercept_errors off;
        fastcgi_intercept_errors off; 
        proxy_pass http://uknp.dock;
        ...
    }
    error_page 419 = /custom_419.html;
    location = /custom_419.html {
        internal;
        add_header Content-Type text/html;
        return 419 "Session expired or CSRF token invalid.";
    }
}

Из этой конфигурации видно, что вы пытаетесь создать пользовательскую страницу ошибки для кода 419. Однако, несмотря на это, nginx, вероятно, интерпретирует ваш кастомный код 419 как ошибку и заменяет его на 500.

Применение

  1. Измените конфигурацию nginx:
    Убедитесь, что в вашем конфигурационном файле для nginx директивы proxy_intercept_errors и fastcgi_intercept_errors отключены. Это должно препятствовать nginx перехватывать и изменять статус код, который возвращает ваш бэкэнд сервер.

    proxy_intercept_errors off;
    fastcgi_intercept_errors off;
  2. Настройте Apache для обработки нестандартных кодов:
    Убедитесь, что ваш Apache-сервер также правильно настроен для обработки и возврата нестандартных кодов ошибок, таких как 419. Возможно, вам необходимо использовать модуль mod_proxy со специальной конфигурацией, если Apache проходит запросы через другой прокси.

  3. Изучите использование других стандартных кодов:
    Рассмотрите возможность использования стандартного HTTP кода, который наиболее близко совпадает с функциональностью 419. Например, для пользователя это может быть 403 (Forbidden) с соответствующим объяснением в теле ответа, а для серверного логирования и интерпретации можно дополнительно использовать специальные заголовки.

  4. Логирование и диагностика:
    Добавьте дополнительное логирование в nginx и Apache, чтобы точно понять, на каком этапе происходит замена статус кода. Это может быть достигнуто путем добавления строк в журналы доступа и ошибок.

  5. Исключения на стороне клиента:
    Проверьте, как ваш фронтенд обрабатывает такие ошибки. Важно убедиться, что фронтенд правильно интерпретирует ответ сервера и отображает понятное сообщение пользователю.

Если после этих изменений ситуация остается прежней, стоит рассмотреть обновление версии nginx или использование других инструментов для маршрутизации и обработки нестандартных кодов ошибок. Регулярно проверяйте официальные источники и документы, чтобы оставаться в курсе изменений в поведении и возможностях веб-серверов.

Возможность использовать нестандартные коды ошибок, такие как 419, является удобной для специфических приложений, но всегда необходимо учитывать ограничения и особенности инфраструктуры, чтобы обеспечить стабильную работу всей системы.

Оцените материал
Добавить комментарий

Капча загружается...