Получение HTTP-трафика для перенаправления на https

Я пытаюсь понять, как перенаправить HTTP-трафик на https. Я запустил apache2 с лаком. Кто-то более осведомленный, чем я, установил это для меня на других сайтах. Я создал новый сайт, имитирующий конфигурацию apache для одного из известных хороших сайтов, на котором работает перенаправление, но мне не удалось заставить его работать для нового сайта; HTTP-трафик просто появляется в браузере как обычный HTTP-трафик. Вот мой файл конфигурации apache:

<VirtualHost *>

ServerName thesite.org
ServerAlias *.thesite.org
Use letsencrypt-challenge thesite.org
Use ssl-upgrade thesite.org

# replace the brackets and string with the appropriate string as indicated
DocumentRoot /home/sites/wp_sites/thesite
ScriptAlias /cgi-bin/ /home/thesite/cgi-bin/
ScriptAlias /cgi /home/thesite/cgi-bin/

# not a typo, the user name is entered twice in the line below
SuexecUserGroup thesite thesite

# THIS HAS TO BE CORRECT. Double and triple check your typing here!
Use site_logging thesite

# These settings are the same for every site
ErrorDocument 404 /index.php
Use default_expire
Options IncludesNOEXEC FollowSymLinks
Use default_deny
Use default_php_fastcgi
</VirtualHost>


<VirtualHost *:443>
  ServerName thesite.org
  ServerAlias *.thesite.org
    Use letsencrypt-challenge thesite.org
    Use letsencrypt-ssl thesite.org
    Use ssl-proxy thesite.org
#ProxyPass / http://thesite.org/
#  ProxyPassReverse / http://thesite.org/
</VirtualHost>

И вот соответствующие макросы:

<Macro ssl-redirect $server_redirect>
    RewriteCond expr "%{HTTP_HOST} != '$server_redirect'"
    RewriteRule /?(.*) "https://$server_redirect/$1" [L,NE]
</Macro>
<Macro ssl-upgrade $server_upgrade>
    Use ssl-redirect "$server_upgrade"
    <If "! req_novary('X-Forwarded-Proto') =~ /https/">
        Redirect / "https://$server_upgrade/"
    </If>
</Macro>
<Macro ssl-proxy $server_proxy>
    Use letsencrypt-challenge "$server_proxy"
    Use letsencrypt-ssl "$server_proxy"
    Use ssl-redirect "$server_proxy"
    ProxyPass / "http://$server_proxy/"
    ProxyPassReverse / "http://$server_proxy/"
</Macro>
<Macro letsencrypt-ssl $server>
    SSLEngine On
    SSLProtocol all -SSLv2 -SSLv3
    SSLHonorCipherOrder on
    SSLCipherSuite "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS"
    SSLCertificateFile "/etc/letsencrypt/live/$server/fullchain.pem"
    SSLCertificateKeyFile "/etc/letsencrypt/live/$server/privkey.pem"
    RequestHeader set X-Forwarded-Proto "https"
</Macro>
<Macro letsencrypt-challenge $server>
  <Directory /etc/apache2/letsencrypt/$server/.well-known/acme-challenge>
    Require all granted
  </Directory>
  RewriteEngine On
  RewriteRule /.well-known/acme-challenge/(.*) /etc/apache2/letsencrypt/$server/.well-known/acme-challenge/$1 [L]
  </Macro>
0
задан 4 February 2020 в 03:00
1 ответ

Самый простой способ достичь своей цели - это добавить следующий код в файл .htaccess в корне вашего документа:

SetEnvIf X-Forwarded-Proto "https" HTTPS=on
Header append Vary: X-Forwarded-Proto

<IfModule mod_rewrite.c>
  RewriteEngine on
  RewriteCond %{HTTPS} !=on
  RewriteCond %{HTTP:X-Forwarded-Proto} !https [NC]
  RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</IfModule>

Что делает эти правила перезаписи настолько специфичным является тот факт, что они поддерживают протокол . Это важно для Varnish.

Varnish и TLS

Varnish обрабатывает только HTTP-трафик и взаимодействует с Apache по обычному HTTP. Вы, вероятно, разорвете соединение TLS где-нибудь еще.

Таким образом, даже если вы выполняете запрос HTTPS, Varnish выполнит HTTP-запрос к Apache, чтобы получить контент. Это всегда будет приводить к перенаправлению 301 , независимо от протокола, который использовался для начального соединения.

Конечным результатом является бесконечный цикл, которого мы хотим избежать. Вот почему рекомендуется выставлять заголовок X-Forwarded-Proto в vhost системы, завершающей TLS.

Установка X-Forwarded-Proto header

Следующий фрагмент кода, по-видимому, отвечает за завершение TLS. Однако часть, где трафик HTTPS проксируется на Varnish, закомментирована.

<VirtualHost *:443>
  ServerName thesite.org
  ServerAlias *.thesite.org
    Use letsencrypt-challenge thesite.org
    Use letsencrypt-ssl thesite.org
    Use ssl-proxy thesite.org
#ProxyPass / http://thesite.org/
#  ProxyPassReverse / http://thesite.org/
</VirtualHost>

Вам, вероятно, придется это исправить. Следующее выражение также должно быть добавлено, чтобы раскрыть протокол входящего запроса:

RequestHeader set "X-Forwarded-Proto" expr=%{REQUEST_SCHEME}

Пожалуйста, убедитесь, что mod_headers включен, если вы хотите установить заголовки.

Если установлено HTTPS-соединение, Apache вернет следующий заголовок ответа:

X-Forwarded-Proto: https

Правило перезаписи, которым я поделился, учитывает это и будет перенаправлять, только если X-Forwarded-Proto равно http или если заголовок не set.

Создание варианта кэша для Varnish

Эта стратегия условного перенаправления повлияет на ваш кеш: Varnish сохранит перенаправление 301 и предоставит его всем клиентам.

Проблема заключается в том, что Varnish не знает разницы в протоколе. Для Varnish все просто HTTP. Apache должен проинформировать Varnish о том, что он должен предоставить копию для версии HTTP и копию для версии HTTPS.

Это называется вариантом кеша , а HTTP позволяет использовать Vary для этого. В этом случае мы собирались варьировать различные значения, которые есть у X-Forwarded-Proto .

Вот почему вам нужно Header append Vary: X-Forwarded-Proto в вашем .htacccess файл .

Varnish интерпретирует это и создаст 2 версии этой страницы в кеше. Если вы не укажете Vary: X-Forwarded-Proto , Varnish будет либо всегда перенаправлять на HTTPS, даже для HTTPS-запроса, либо никогда, даже для простых HTTP-запросов.

Заключение

Сделайте протокол Apache осведомленным , используя X-Forwarded-Proto , который должен быть установлен на виртуальном хосте Apache, на котором вы завершаете TLS.

И, наконец, сделайте так, чтобы протокол Varnish знал , а также с помощью заголовка X-Forwarded-Proto в качестве значения Vary .

0
ответ дан 26 February 2020 в 00:43

Теги

Похожие вопросы