Apache 2.2 перенаправляет на SSL *, затем * выполняет аутентификацию (с решением <, но это дерьмо?) - PullRequest
7 голосов
/ 23 июня 2011

Кажется, что это место для Apache, так что здесь идет:)

Старая проблема: как я перенаправляю HTTP-> HTTPS, тогда и только если HTTPS, сделать аутентификацию?

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

вот что у меня, похоже, работает:

В верхней части блока VirtualHost

# Set ssl_off environment variable 
RewriteEngine on
RewriteCond %{HTTPS} =on
RewriteRule ^ - [E=ssl]

В блоке местоположения или каталога

RewriteEngine on
# Case 1 redirect port 80 SSL
RewriteCond %{HTTPS} !=on
RewriteCond %{SERVER_PORT} =80
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [R=301]

AuthType Basic
AuthBasicProvider external
AuthExternal auth_pam
AuthName "My Underpants"
AuthzUnixgroup on
Order Deny,Allow
Deny from all
Allow from env=!ssl
Satisfy any
Require group nice-users

Плюсы

Все эти строки, которые требуются, могут быть абстрагированы в файл сниппета для включения в одну строку в каждом местоположении

Он исправляет принудительное использование SSL и аутентификации для каждого местоположения, поэтому меньше вероятность ошибок

Минусы

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

Есть ли лучший способ (не то, что я нашел ...)?

Комментарии будут очень приветствоваться, если это имеет какое-либо серьезное значениенедостатки:)

Помимо Жизнь была бы намного проще, если бы у Apache был разумный синтаксис конфигурации с общим

блок, который можно использовать где угодно.У него есть определенные блоки особого случая, такие как IfModule, и у вас есть особые условия прецедента, такие как RewriteCond (который очень трудно получить, если вы к нему не привыкли).Тим

Ответы [ 3 ]

3 голосов
/ 26 июня 2011

Если вы хотите заставить весь сайт использовать https, вы можете использовать директивы VirtualHost , и тогда все довольно просто:

<VirtualHost *:80>
    ServerName example.com

    RedirectMatch (.*) https://example.com$1

</VirtualHost>

<VirtualHost *:443>
    ServerName example.com

    ...
    ...
    ...
</VirtualHost>
2 голосов
/ 15 декабря 2013

Решение Тима Уоттса, кажется, работает лучше всего для меня, но нужно немного доработать.Кроме того, моя ситуация немного отличается тем, что я хочу разрешить определенные IP-адреса без аутентификации HTTP, но это просто добавляет дополнительную строку.

mod_rewrite не будет наследовать конфигурацию от VirtualHost по умолчанию.

См .: http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html#rewriteoptions

Я собирался использовать «наследование RewriteOptions», но кажется, что это применяет родительские правила ПОСЛЕ дочерних.В любом случае, я подумал о другом решении.

В моем SSL у меня есть строка:

SetEnvIf Request_URI "/" using_ssl=yes

Это устанавливает переменную среды using_ssl, если URI запроса содержит форвардкосая черта (то есть все время.) Это немного хак, так как я предпочел бы использовать безусловный SetEnv, но очевидно:

Внутренние переменные среды, установленные этой директивой, устанавливаются после самой ранней обработки запросавыполняются директивы, такие как управление доступом и сопоставление URI-имен и имен файлов.Если переменная среды, которую вы устанавливаете, предназначена для ввода в этот ранний этап обработки, такой как директива RewriteRule, вам следует вместо этого установить переменную среды с помощью SetEnvIf.

(источник: http://httpd.apache.org/docs/2.2/mod/mod_env.html#setenv)

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

# Require a basic HTTP auth user
AuthName "realm-name-goes-here"
AuthType Basic
AuthUserFile /var/www/etc/htpasswd
Require valid-user

# OR allow from non-SSL (which will be redirected due to mod_rewrite below!)
Order Allow,Deny
Allow from env=!using_ssl

# OR allow from a trusted IP range
# NB: This allows certain IPs without a username & password
Allow from 192.168.0.0/16

Satisfy Any

# Force a redirect to HTTPS
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [L,R=permanent]

Вы, вероятно, сначала хотите попробовать просто "R" вместо "R = постоянный" для целей тестирования.

Надеюсь, что это полезно для других:)

0 голосов
/ 19 октября 2011

Я проверил ваше решение, и оно не сработало ...

После долгого времени поиска решения, слишком много погуглив и обнаружил всегда одни и те же вещи, которые не работали, я наконец-то сделал это: я использую SSLRequireSSL и ErrorDocument 403, настроенный со статической страницей, содержащей код JavaScript (спасибо этой странице блога ).

in /etc/apache2/conf.d.opt/redirect_if_not_https.conf:

SSLRequireSSL
ErrorDocument 403 "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\
<html><head>\
<title>403 Forbidden</title>\
<script language=\"JavaScript\">\
window.location='https://'+window.location.hostname+window.location.pathname;\
</script>\
</head><body>\
<h1>Forbidden</h1>\
<p>You don't have permission to access that resource using simple HTTP. Please use HTTPS instead.</p>\
</body></html>"

(обратите внимание, что я создал /etc/apache2/conf.d.opt/)

А в приложении app включите этот файл (например, в /etc/apache2/conf.d/trac.conf):

<LocationMatch "/trac">
    # All the classical configurations here
    # ...

    Include conf.d.opt/redirect_if_not_https.conf
</LocationMatch>
...