아파치가 "디렉터리 컨텍스트" 내에서 다시 쓰기 처리를 다시 시작하지 못하도록 방지하는 방법

아파치가 "디렉터리 컨텍스트" 내에서 다시 쓰기 처리를 다시 시작하지 못하도록 방지하는 방법

SSL 연결을 위한 가상 호스트에 다음이 있습니다. SSL이 아닌 가상 호스트는 동일해 보이지만 리디렉션을 위한 첫 번째 규칙이 설정되어 있지 않습니다.

DocumentRoot /var/www/example.com/public/
<Directory "/var/www/example.com/public/">
  #only mod_rewrite configuration is shown here

  RewriteEngine on
  RewriteBase /

  RewriteCond $1 !=signup
  RewriteCond $1 !=login
  RewriteCond $1 !=welcome
  RewriteCond $1 !=thankyou
  RewriteRule ^(.*)$ http://example.com/$1 [L,R,QSA]

  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_URI} !=/favicon.ico
  RewriteRule ^(.+)$ index.php?q=$1 [L,QSA]
</Directory>

내 의도는 일치하지 않는 페이지 요청(가입|로그인|환영|감사합니다)을 추가 처리 없이 SSL이 아닌 가상 호스트로 리디렉션하도록 하는 것입니다. 그렇지 않으면 리디렉션하지 않고 SSL 가상 호스트 내에서 요청을 처리합니다.

첫 번째 RewriteRule 세트는 리디렉션을 담당하고, 두 번째 RewriteRule 세트는 일반 페이지 처리를 담당합니다.

첫 번째 규칙 세트가 없으면 모든 요청이 SSL 가상 호스트 아래에 올바르게 로드됩니다.

첫 번째 규칙 세트를 사용하면 나열된 리소스와 일치하지 않는 리디렉션이 제대로 작동합니다. 예. 에 대한 요청

https://example.com/about

다음으로 리디렉션됩니다.

http://example.com/about

그런데 회원가입, 로그인, 환영, 감사 페이지를 요청할 때 문제가 발생합니다. 이러한 요청은 SSL이 아닌 사이트로도 리디렉션되지만 손상된 방식으로 리디렉션됩니다. 에 대한 요청

https://example.com/signup

다음으로 리디렉션됩니다.

http://example.com/index.php?q=signup

첫 번째 규칙 세트는 예상대로 일치하지 않는 것처럼 보이고 두 번째 규칙 세트가 처리된 후 첫 번째 규칙 세트가 다시 적용됩니다(예상하지 않음).

이 예상치 못한 동작을 문서화된 기능과 일치시킬 수 없습니다.

어떤 아이디어가 있나요?

편집하다

"디렉터리 컨텍스트" 내에서 규칙 일치가 발생할 때 Apache가 규칙을 다시 실행하는 것에 대한 일부 모호한 참조를 문서에서 발견했습니다. 그러나 해당 참조는 .htaccess에 관한 것입니다. 내 <VirtualHost> 태그 내의 <Directory> 태그 내에서 재작성이 발생하고 있습니다. 현재 <Directory> 컨텍스트 외부로 다시 쓰기를 이동하는 것을 테스트 중입니다. 이는 확실히 동작을 변경하는 것처럼 보이지만 아직 필요한 대로 작동하도록 만들지는 않았습니다.

편집2

이 문제는 확실히 규칙 처리가 디렉터리 컨텍스트 내에 존재할 때 Apache가 다시 쓰기 처리를 다시 시작함으로써 발생합니다. <Directory> 태그 외부로 규칙 처리를 이동했습니다. 그러나 이제 RewriteCond 줄이 작동하지 않습니다.

RewriteCond %{REQUEST_FILENAME} -f

Apache가 아직 DocumentRoot를 사용하여 요청된 리소스를 파일 매핑으로 확인하지 않았기 때문입니다. 정말 엉망이군요.

그런 다음 DocumentRoot에서 지정한 값을 RewriteCond 앞에 수동으로 추가합니다. 그러나 이것은 좋지 않은 해킹처럼 보입니다. 예.

RewriteCond /var/www/example.com/public%{REQUEST_FILENAME} -f

그래서 이제 저는 디렉토리 컨텍스트 내에서 Apache가 다시 쓰기 프로세스를 다시 시작하지 못하도록 하는 방법을 찾고 있습니다. 두 번째로 좋은 방법은 <VirtualHost> 수준에서 필요한 RewriteConds를 지정하는 더 나은 방법입니다.

답변1

mod_rewrite가 수행하는 작업과 그 이유에 대한 자세한 로그를 제공하는 구성에 다음을 추가하는 것이 좋습니다. 그러면 그러한 행동이 나타나는 이유를 명확히 하는 데 도움이 될 수 있습니다.

RewriteLog /tmp/rewrite.log
RewriteLogLevel 9

분석을 마친 후에는 성능에 영향을 미치므로 이 줄을 제거해야 합니다.

답변2

나는 <Directory ...> 섹션 외부에 재작성을 배치하여 다음 솔루션을 결정했습니다. 이를 통해 SSL이 아니어야 하는 요청을 SSL이 아닌 사이트로 리디렉션하는 동시에 SSL을 통해 정적 콘텐츠(이미지, CSS, js 등)를 제공할 수 있습니다.

<VirtualHost ...>
  ...
  RewriteEngine on

  RewriteCond $1 !=signup
  RewriteCond $1 !=login
  RewriteCond $1 !=welcome
  RewriteCond $1 !=thankyou
  RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f
  RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-d
  RewriteRule ^/(.*)$ http://example.com/$1 [R=303,QSA,L]

  RewriteCond %{REQUEST_URI} !=/favicon.ico
  RewriteCond %{REQUEST_URI} !=/robots.txt
  RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f
  RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-d
  RewriteRule ^/(.+)$ /index.php?q=$1 [QSA,L]
  ...
</VirtualHost>

관련 정보