Ошибка HTTP/HTTPS в среде Proxy/Docker/LXC

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

Я занимаюсь настройкой нового сайта WordPress и столкнулся с некоторыми проблемами в моей конфигурации, особенно касательно внутреннего трафика loopback и REST API. Сам сайт работает без видимых проблем — я не вижу никаких проблем с кешированием или предупреждений XSS. Сгенерированные ссылки также правильно включают https:// в URI.

Моя инфраструктура:

Один из моих серверов работает на Proxmox, среде виртуализации на основе QEMU. В этой конфигурации у меня есть несколько контейнеров LXC, один из которых является NGINX Proxy Manager. Этот контейнер — единственный в моей конфигурации с публичным IP-адресом; все остальные контейнеры общаются внутри сети 192.168.0.0/16. Cloudflare расположен перед NGINX Proxy Manager.

WordPress работает внутри Docker-контейнера, управляемого сервером Docker. Следующий файл docker-compose.yml используется для запуска WordPress:

services:
  db:
    image: mariadb
    command: '--default-authentication-plugin=mysql_native_password'
    volumes:
      - ./data/mariadb:/var/lib/mysql
    restart: always
    environment:
      - MYSQL_ROOT_PASSWORD={password}
      - MYSQL_DATABASE=wordpress
      - MYSQL_USER=wordpress
      - MYSQL_PASSWORD={password}
    expose:
      - 3306
  web:
    image: wordpress
    depends_on:
      - db
    ports:
      - 80:80
    restart: always
    environment:
      - WORDPRESS_DB_HOST=db
      - WORDPRESS_DB_USER=wordpress
      - WORDPRESS_DB_PASSWORD={password}
      - WORDPRESS_DB_NAME=wordpress
      - WORDPRESS_DEBUG=0
      - WORDPRESS_CONFIG_EXTRA=define('WP_CONTENT_DIR', '/var/www/html/wp-content'); define('WP_CONTENT_URL', 'https://static.example.com'); define('COOKIE_DOMAIN', 'www.example.com'); define('SITECOOKIEPATH', '.'); define('WP_HOME', 'http://www.example.com'); define('WP_SITEURL', 'http://www.example.com');
    volumes:
      - ./data/wordpress:/var/www/html
      - ./data/wordpress-static:/var/www/html/wp-content
      - ./config/apache2/sites-enabled:/etc/apache2/sites-enabled
      - ./config/apache2/conf-enabled/server-name.conf:/etc/apache2/conf-enabled/server-name.conf
      - ./config/php/custom.ini:/usr/local/etc/php/conf.d/config.ini
      - ./log/apache2:/var/log/apache2
    extra_hosts:
      - www.example.com:127.0.0.1

Apache2 работает внутри Docker-контейнера по HTTP, так как SSL-сертификат обрабатывается Cloudflare и применяется на моем NGINX Proxy Manager.

Проблема:

Проблема, с которой я столкнулся, заключается в том, что WordPress пытается выполнить loopback-запросы через HTTPS, что приводит к ошибке:

The loopback request to your site failed, this means features relying on them are not currently working as expected.
Error: cURL error 7: Failed to connect to www.example.com port 443 after 0 ms: Couldn't connect to server (http_request_failed)

Проверка состояния сайта — рекомендованные улучшения:

Страница Состояние сайта WordPress показывает следующие проблемы:

1. Адрес WordPress и адрес сайта не используют HTTPS

Вы заходите на этот сайт используя HTTPS, но ваш адрес WordPress и адрес сайта не настроены для использования HTTPS по умолчанию.
Обратитесь к вашему веб-хосту по поводу поддержки HTTPS для вашего сайта.
Узнайте больше о том, почему вы должны использовать HTTPS.

2. Кэш страницы не обнаружен

Не удается обнаружить кэш страницы из-за возможной проблемы с loopback-запросом. Пожалуйста, проверьте, проходит ли тест loopback-запроса успешно.
Ошибка: cURL error 7: Failed to connect to www.example.com port 443 after 0 ms: Couldn't connect to server (Code: http_request_failed)

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

WordPress проверяет наличие кэша страницы, выполняя несколько запросов на главную страницу и ищет один или несколько из следующих заголовков HTTP-ответа о кешировании:
cache-control, expires, age, last-modified, etag, x-cache-enabled, x-cache-disabled, x-srcache-store-status, x-srcache-fetch-status.

Также я заметил проблему с запланированными задачами (WP-Cron):

Запланированное событие wp_privacy_delete_old_export_files не удалось выполнить. Ваш сайт все еще работает, но это может означать, что запланированные сообщения или автоматические обновления могут не работать должным образом.

Это указывает на то, что фоновые задачи WordPress (WP-Cron), запланированные сообщения и автоматические обновления могут не функционировать правильно из-за сбоя loopback-запроса.

Предварительно настроенный wp-config.php для настройки обратного прокси:

Тем не менее, Docker-образ WordPress уже включает предварительно настроенный wp-config.php, предполагая настройку обратного прокси. Прокси также правильно добавляет необходимые заголовки:

// Если мы находимся за прокси-сервером и используем HTTPS, нужно уведомить об этом WordPress
// также см. https://wordpress.org/support/article/administration-over-ssl/#using-a-reverse-proxy
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && strpos($_SERVER['HTTP_X_FORWARDED_PROTO'], 'https') !== false) {
        $_SERVER['HTTPS'] = 'on';
}
// (мы включаем это по умолчанию, поскольку обратное проксирование чрезвычайно распространено в контейнерных средах)

Конфигурация NGINX:

real_ip_header CF-Connecting-IP;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect off;

Диаграмма потока сети:

            +---------------------------+
            |     Посетитель (Браузер)   |
            +------------+--------------+
                         |
                         v
       +--------------------------------+
       |       CDN Cloudflare (SSL)     |
       +-----------------+--------------+
                         |
                         v
      +--------------------------------------+
      |  my.real.server.ip:443 (NGINX PM)    |
      |       Обратный прокси (SSL)          |
      +------------------+-------------------+
                         |
                         v
      +-----------------------------------------+
      |  http://192.168.1.1:80 (WordPress LXC)  |
      |  Внутренняя сеть (контейнер LXC)        |
      +------------------+----------------------+
                         |
                         v
      +--------------------------------------+
      |  http://172.18.0.3:80 (Docker WP)    |
      |  Apache2 внутри контейнера Docker   |
      +--------------------------------------+

Попытки исправления:

Я пытался настроить $WP_HOME и $WP_SITEURL как с https://, так и с http://, и даже полностью убрать их из файла docker-compose.yml. Я также добавил extra_host в файл docker-compose.yml. Однако ни одна из этих попыток не решила проблему.

Конфигурация Apache VirtualHost:

Конфигурация базовая, с минимальными изменениями, кроме измененного формата журнала:

<VirtualHost *:80>
        ServerName www.example.com

        ServerAdmin [email protected]
        DocumentRoot /var/www/html

        LogFormat "%v:%p %a %{c}a %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" proxy_combined
        LogFormat "%v %{CF_CONNECTING_IP}i (via cloudflare:%h) %l %u %t \"%r\" %>s %b" cloudflare
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log cloudflare
</VirtualHost>

Кроме этого, домен правильно установлен в файле server-name.conf Apache:

ServerName www.example.com

Есть идеи?

Я был бы признателен за любые предложения или инсайты по решению этой проблемы с loopback-запросами, особенно учитывая, что это затрагивает конфигурацию HTTPS, обнаружение кеширования страниц и запланированные задачи.

Спасибо за вашу поддержку!

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

Конфигурация инфраструктуры и развертывание приложения имеют критическое значение для стабильной работы веб-сайта. В данном случае, мы рассмотрим проблемы, связанные с HTTP/HTTPS ошибками в среде Proxy/Docker/LXC при настройке сайта на WordPress.

Теория

Для начала необходимо понять, почему возникает проблема с loopback-запросами на вашем сервере WordPress. Как правило, loopback-запросы используются для самопроверки приложения, выполнения фонов задач (как WP-Cron), и они играют важную роль в функциональности WordPress. Основная проблема в приведенном вами тексте заключается в том, что WordPress пытается выполнить loopback-запросы через HTTPS, но не может подключиться к серверу.

Пример

Ваша текущая архитектура выглядит следующим образом:

  1. NGINX Proxy Manager работает в LXC-контейнере и является публичной точкой доступа для трафика, который защищается Cloudflare.
  2. Контейнеры WordPress и MariaDB работают в среде Docker.
  3. Все внутренние соединения происходят через HTTP, так как сертификат SSL устанавливается на уровне NGINX.

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

Применение

Решение данной проблемы требует выполнения нескольких шагов:

  1. Настройка WordPress на использование HTTPS:
    Убедитесь, что в вашем docker-compose.yml параметры WORDPRESS_HOME и WORDPRESS_SITEURL используют протокол https://. Это позволит WordPress корректно генерировать внутренние ссылки на основе HTTPS.

    Пример:

    - WORDPRESS_HOME=https://www.example.com
    - WORDPRESS_SITEURL=https://www.example.com
  2. Конфигурация прокси и заголовков HTTP:
    Уже в вашей конфигурации wp-config.php используется условие для проверки, установлен ли HTTPS на основе заголовка HTTP_X_FORWARDED_PROTO. Убедитесь, что ваш NGINX Proxy Manager действительно правильно передает этот заголовок.

  3. Альтернативный способ обработки loopback:
    Используйте плагин, например, "Health Check & Troubleshooting", чтобы перенаправлять loopback-запросы. В нем можно задать альтернативные способы проверки.

  4. Настройка SSL:
    Если SSL устанавливается на уровне Cloudflare, убедитесь, что SSL метод на уровне Cloudflare активирован как "Full" или "Full (strict)", чтобы избежать проблем с безопасностью на уровне HTTPS.

  5. Дополнительные настройки для Apache:
    Убедитесь, что в настройках Apache корректно прописан ServerName, и добавьте правильный Redirect для HTTPS.

Пример конфигурации для VirtualHost может выглядеть следующим образом:

   <VirtualHost *:80>
       ServerName www.example.com
       Redirect permanent / https://www.example.com/
   </VirtualHost>
  1. Проверка конфигурации Cron:
    Добавьте в wp-config.php следующую строку, чтобы использовать системные Cron задания вместо WP-Cron, что поможет избежать проблемы с запуском запланированных задач:

    define('DISABLE_WP_CRON', true);

    Настройте задание Cron в вашей системе:

    */15 * * * * curl https://www.example.com/wp-cron.php?doing_wp_cron > /dev/null 2>&1

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

На основании вышеописанных шагов и рекомендаций можно устранить проблемы с loopback-requst запросами, обеспечить корректное выполнение фоновых задач WordPress и повысить общую безопасность и эффективность вашего сайта.

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

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