Перенаправление Yii2 с прокси OpenShift - PullRequest
1 голос
/ 07 июля 2019

Я развернул Yii2 приложение PHP на OpenShift. По сути, Yii2 работает в контейнере на основе alpine с установленными PHP и Nginx. Контейнер предоставляет port 8080, который затем привязывается к сервису OpenShift, где, в свою очередь, создается защищенный маршрут с Edge encryption.

Большая часть приложения работает нормально, однако при выполнении сообщения HTTP и позже в контроллере, выполняющем перенаправление, Yii2 перенаправляет на http://<sitename> вместо того, чтобы оставаться с https, что приводит к тому, что приложение не будет работает больше. Сам запрос POST работает, поскольку впоследствии в БД вносятся изменения, он перенаправляет их обратно к обзору, который не работает в этом контексте.

Действие контроллера очень простое и стандартное:

public function actionUpdate($id)
{
    $model = $this->findModel($id);

    if ($model->load(Yii::$app->request->post()) && $model->save()) {
        return $this->redirect(['index']);
    }

    return $this->render('update', [
        'model' => $model,
    ]);
}

Некоторая информация о конфигурации OpenShift:

~ oc get routes 
NAME       HOST/PORT                PATH   SERVICES  PORT     TERMINATION   WILDCARD
backend    backend.apps.<instance>         backend   backend  edge          None
frontend   frontend.apps.<instance>        frontend  frontend edge          None

~ oc describe route backend
Name:           backend
Namespace:      <project>
Created:        10 hours ago
Annotations:        openshift.io/host.generated=true
Requested Host:     backend.apps.<instance> 
                    exposed on router router 10 hours ago
Path:           <none>
TLS Termination:    edge
Insecure Policy:    <none>
Endpoint Port:      backend

Service:    backend
Weight:     100 (100%)
Endpoints:  <ip>:8080

Dockerfile для создания приложения не очень впечатляющий, он в основном устанавливает PHP, Nginx и устанавливает некоторые разрешения. Тем не менее, конфигурация Nginx может быть частью проблемы, опубликовав очищенную версию ниже.

worker_processes  1;
error_log stderr warn;
pid /run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    log_format  main_timed  '$remote_addr - $remote_user [$time_local] "$request" '
                            '$status $body_bytes_sent "$http_referer" '
                            '"$http_user_agent" "$http_x_forwarded_for" '
                            '$request_time $upstream_response_time $pipe $upstream_cache_status';

    access_log /dev/stdout main_timed;
    error_log /dev/stderr notice;

    keepalive_timeout  65;

    server {
        listen [::]:8080 default_server;
        listen 8080 default_server;
        server_name _;

        sendfile off;

        root /var/www/html/backend/web/;
        index index.php index.html;

        location / {
            # First attempt to serve request as file, then
            # as directory, then fall back to index.php
            try_files $uri $uri/ /index.php?q=$uri&$args;
        }

        # redirect server error pages to the static page /50x.html
        #
        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
            root /var/lib/nginx/html;
        }

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        location ~ \.php$ {
            try_files $uri =404;
            fastcgi_split_path_info ^(.+\.php)(/.+)$;
            fastcgi_pass  127.0.0.1:9000;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_param SCRIPT_NAME $fastcgi_script_name;
            fastcgi_index index.php;
            include fastcgi_params;
        }

        location ~* \.(jpg|jpeg|gif|png|css|js|ico|xml)$ {
            expires 5d;
        }

        # deny access to . files, for security
        #
        location ~ /\. {
            log_not_found off;
            deny all;
        }

        # allow fpm ping and status from localhost
        #
        location ~ ^/(fpm-status|fpm-ping)$ {
            access_log off;
            allow 127.0.0.1;
            deny all;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            include fastcgi_params;
            fastcgi_pass 127.0.0.1:9000;
        }
    }
}

Редактировать 1:

Добавление следующей строки в конфигурацию Nginx как-то заставляет его работать, однако это не очень хорошее решение:

location ~ \.php$ {
    [...]
    fastcgi_param HTTPS on;

Однако предполагается, что всегда используется HTTP. Однако это зависит от конфигурации маршрута OpenShift. Есть ли лучшее (более универсальное) решение для этого?

Ответы [ 2 ]

1 голос
/ 21 июля 2019

Благодаря всем комментариям и ответам я смог разобраться.Я не использую здесь Nginx в качестве прокси, но я использую FastCGI для PHP, поэтому я не уверен, сработает ли предложенный Джейсоном ответ.Следующие решения работают для меня:

location ~ \.php$ {

    set $my_https 'off';
    if ($http_x_forwarded_proto = 'https') {
        set $my_https 'on';
    }

    fastcgi_param HTTPS $my_https;

Возможно, есть более элегантное решение, но это работает для меня

1 голос
/ 18 июля 2019

Маршрутизатор OpenShift (который предоставляет созданный вами защищенный маршрут) установит количество заголовков в запросе к бэкэнд-модулю, на котором запущено приложение Yii2.

Первоемы должны доверять этим заголовкам в Nginx, чтобы они передавали их бэкэнд-приложению Yii2.

location ~ \.php$ {
    proxy_pass_header   X-Forwarded-Proto;
    proxy_pass_header   X-Forwarded-Host;
    proxy_pass_header   X-Forwarded-Port;
    [...]

X-Forwarded-Proto будет установлено на https и выглядит как Yii2 будет правильно обрабатывать заголовок, но я раньше не использовал эту среду PHP.Это был бы второй шаг, если это требуется, который должен был бы иметь URL ответа фреймворка фреймворка с протоколом, который находится в заголовке x-forwarded-proto.

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

...