Назад | Перейти на главную страницу

Обратный прокси-сервер подкаталога в подкаталог с Apache

Я понимаю концепцию прокси (хотя никогда не устанавливал их). Я пытаюсь проксировать Drupal, но совершенно уверен, что моя проблема не связана с Drupal. Поскольку с сегодняшнего утра я пытался определить волшебный ингредиент, с помощью которого это работало, я сразу перейду к нему:

Окружающая среда

У меня два сервера, как описано ниже. Оба являются общедоступными, но определенные части сайта drupal должны быть доступны с прокси-сервера - в частности, контент, требующий входа в систему.

Прокси-сервер (c5.domain.com)

Сервер Drupal (drupal.domain.com)

Что работает (но мне не нужно)

Хотя это позволяет получить полный доступ к сайту drupal, включая возможность входа в систему, это имеет очевидный и досадный побочный эффект, заключающийся в предотвращении доступа к сайту specific5.

ProxyPass         /        http://drupal.domain.com/
ProxyPassReverse  /        http://drupal.domain.com/
ProxyPassReverseCookieDomain   c5.domain.com    drupal.domain.com

Что я сейчас пытаюсь

При следующей настройке я могу получить доступ к страницам drupal, используя URL-адрес http://c5.domain.com/my-account/..., но я не могу войти в систему - при попытке сделать это меня перенаправляет на http://c5.domain.com/proxy/ (который перенаправляет на / my-account /)

Apache

<Location /my-account/>
    ProxyPass http://drupal.domain.com/proxy/
    ProxyPassReverse http://drupal.domain.com/proxy/
    ProxyPassReverseCookieDomain drupal.domain.com c5.domain.com
    # the cookie path seems important...
    ProxyPassReverseCookiePath / /my-account/
</Location>

# These rules seem necessary, since drupal's mod-alias seems to
# feed the browser a path like `https://c5.domain.com/proxy/...`
RewriteRule ^/proxy/(.*)$ /my-account/$1 [R,L]
RewriteRule ^/my-account/proxy/(.*)$ /my-account/$1 [R,L]

Конфигурация Drupal

Здесь я пытаюсь заставить Drupal хорошо работать с прокси-сервером:

if (isset($_SERVER['HTTP_X_FORWARDED_HOST']) &&
    'drupal.domain.com' === $_SERVER['HTTP_X_FORWARDED_HOST']
) {
  $base_url = "$protocol://{$_SERVER['HTTP_X_FORWARDED_HOST']}/proxy";
  $cookie_domain = '.drupal.domain.com';
  $conf['reverse_proxy'] = TRUE;
  $conf['reverse_proxy_addresses'] = array('55.55.55.55',);
} else {
  $base_url = "$protocol://{$_SERVER['SERVER_NAME']}";
}

Эта проблема:

Форма входа отправляется по URL-адресу, о котором знает Drupal: /proxy. Это означает, что прокси-сервер получает запрос на http://c5.domain.com/proxy, вместо того http://c5.domain.com/my-account. Я думал, что смогу решить эту проблему с помощью перенаправления:

RewriteRule ^/proxy/(.*)$ /my-account/$1 [R,L]
RewriteRule ^/my-account/proxy/(.*)$ /my-account/$1 [R,L]

Как оказалось, данные POST не пересылаются с большинством перенаправлений.

Решение:

Есть исключение из этого правила: 307 пересылает данные POST. Примерно так работает:

RewriteRule ^/proxy/(.*)$ /my-account/$1 [R=307,L]
RewriteRule ^/my-account/proxy/(.*)$ /my-account/$1 [R=307,L]

Предупреждение:

Естественно, у этого решения есть свои плюсы и минусы. Большинство браузеров уведомляют пользователя о перенаправлении (соответственно, поскольку данные POST могут быть отправлены куда угодно) и спрашивают пользователя, имеют ли они в виду отправить данные по новому URL-адресу. Поскольку немногие пользователи, вероятно, поймут уведомление, этот вариант может привести к путанице.