WEB & WAS/Apache

mod_rewrite 실전 2

서버엔지니어 2023. 3. 8.
728x90

게다가 아파치의 한계로 인해 무한히 가상 서버를 등록할 수도 없다.

(정확한 수치는 모르나... 100여개 이내로 보인다.)

​

아파치에는 rewrite라는 아주 훌륭한 기능이 있다.

"mod_rewrite를 사용할 수 없다면 당신이 아파치에서 사용할 수 있는 것은 없다." 라는 말이 있을 정도다.

​

이글은 rewrite모듈을 이용하여 보다 편리하게 가상도메인을 관리하고자 하는 이들을 위한 작은 팁을 제공한다.

​

몇가지 전제 조건

​아파치 버전 :  1.3.20

서버IP : 192.168.0.1

서버기본 도큐먼트루트* : /var/www/html/ (Redhat 기본)

가상도메인들의 루트* : /var/www/vhost/도메인네임

ex) /var/www/vhost/wiki.domain.com/ /var/www/vhost/domain.com/

등록되지 않은 가상도메인들은 모두 서버기본 도큐먼트루트가 시작된다.

(* 상기의 내용은 충분히 변경 가능하다.)

​

운영방법

가상도메인의 등록이 필요하면..

ftp나 쉘접속으로 /var/www/vhost에

해당 도메인네임과 동일한 디렉토리를 만들어 주는 것으로 마무리된다.

ex) mkdir /var/www/vhost/new.domain.com

​

그밖의 기능

자동 리다이렉션.

DNS에 *.domain.com 등으로 등록되어 있고,

/var/www/vhost/www.domain.com이란 디렉토리를 생성했을 때

http://domain.com http://foobar.domain.com 모두

http://www.domian.com 으로 자동 리다이렉트가 된다.

하지만, foobar.domain.com란 디렉토리 역시 있을 경우..

http://foobar.domain.com 은 /var/www/vhost/foobar.domain.com으로

연결되고 그밖에는 모두 http://www.domain.com 으로 리다이렉션이 된다.

​

만약

/var/www/vhost/domain.com으로 등록되어 있을 경우에는

http://www.domain.com http://foobar.domain.com 모두

http://domian.com 으로 리다이렉트가 된다.

여기서도 마찬가지로 foobar.domain.com란 디렉토리 있을 경우..

http://foobar.domain.com 은 /var/www/vhost/foobar.domain.com으로

연결되고 그밖에는 모두 http://domain.com 으로 리다이렉션이 된다.

​

디렉토리 이름끝에 자동으로 / 붙여주기.

ex) http://domain.com/somedir -> http://domain.com/somedir/

​

한계

mod_rewrite가 참으로 유용하긴 하나.. 한계도 있다.

일단 alias나 scriptalias가 반영되지 않는다.

및의 예에는 /cgi-bin/이라는 scriptAlias를

rewriteRule를 사용 강제로 반영시키는 예제다..

​

ScriptAlias /cgi-bin/ "/var/www/cgi-bin/"

RewriteRule /cgi-bin(/.*)$ /cgi-bin$1 [L,PT]

​

또 한가지 자동 리다이렉션은..

http://domain.com http://www.domain.com 이 두유형에 대해서만 지원한다.

물론 변경할 수는 있다.

​

가상도메인내에 파일에서는

환경변수 DOCUMENT_ROOT값이 무의미하다.. (/var/www/html로 고정..)

그래서 VIRTUAL_DOCUMENT_ROOT라는 새로운 환경변수를 사용한다.

만약 DOCUMENT_ROOT를 스크립트중에 사용한다면.

대신 VIRTUAL_DOCUMENT_ROOT를 이용하면된다.

​

마무리

​

아래의 내용을 편집하거나 혹은 자세한 설명이 필요하다면.

아래의 URL을 참조하기 바란다.

http://httpd.apache.org/docs/mod/mod_rewrite.html

http://httpd.apache.org/docs/misc/rewriteguide.html

​

그리고 디버깅이 필요하면 아래의 두줄에 주석을 풀어주면 된다.

​

# RewriteLog "/var/www/vhost/rewrite.log"

# RewriteLogLevel 9

​

경고 상당히 많은 로그가 발생하므로 디버깅 목적이 아니면...

반드시 주석처리를 해놓을 것!!

​

사용중 문제가 발생하거나, 의문이 생기면.. 이글에 리플을 달아주세요. :)

자세한 동작방식에 대해서는 언급하지 않았는데..

기회가 나면, mod_rewrite의 간략한 문법 소개와 함께 올리도록 하겠습니다.

​

​

<VirtualHost 192.168.0.1>

ServerAdmin <a href="mailto:foo@bar.com">foo@bar.com</a>

ServerName *

DocumentRoot /var/www/html/

​​

DirectoryIndex index.php index.html index.htm

ScriptAlias /cgi-bin/ "/var/www/cgi-bin/"

​

RewriteEngine On

​

# for Debug

# RewriteLog "/var/www/vhost/rewrite.log"

# RewriteLogLevel 9

​

RewriteRule ^/cgi-bin(/.*)$ /cgi-bin$1 [L,PT]

​

RewriteRule ^(.*) %{HTTP_HOST}$1

​

RewriteCond /var/www/vhost/%{HTTP_HOST} -d

RewriteRule ^(.+) /var/www/vhost/$1 [s=4,E=VIRTUAL_DOCUMENT_ROOT:/var/www/vhost/%{HTTP_HOST}/]

​

​

RewriteCond /var/www/vhost/www.%{HTTP_HOST} -d

RewriteRule ^(.*) http://www.$1 [L,R]

​

RewriteCond %{HTTP_HOST} !^www\..+$

RewriteCond /var/www/vhost/www.$2 -d

RewriteRule ^([^.]+.)([^/]+)(.+)$ http://www.$2$3 [L,R]

​

RewriteCond /var/www/vhost/$2 -d

RewriteRule ^([^.]+.)([^/]+)(.+)$ http://$2$3 [L,R]

​

​

RewriteRule ^([^/]+/)(.*) %{DOCUMENT_ROOT}$2 [s=1]

​

RewriteCond $1$2 ^.*[^/]$

RewriteCond $1$2 -d

RewriteRule ^(/var/www/vhost/)(.+[^/])$ http://$2/ [L,R]

​

RewriteCond $1$2 ^.*[^/]$

RewriteCond $1$2 -d

RewriteRule ^(/var/www/html/)(.+[^/])$ http://%{HTTP_HOST}/$2/ [L,R]

​

HostNameLookups off

</VirtualHost>

​

​

****************************************************************************************

​mod_rewrite의 개념...

​

일반 적인 아파치의 기능은 요청된 URL에 적절한 파일을 HTTP에 맞게 전송하는 것이다.

​mod_rewrite는 요청된 URL에 대해 관리자가 목적에 맞게 변경하여 요청자에게 응답할 수 있는 기능을 제공한다.

​

예 일반적인 경우

httpd.conf :

DocumentRoot : /some/local/path/

​

요청 :

http://host/somedir/somefile.html

​

서버가 응답하는 실제 내용

/some/local/path/somedir/somefile.html

​

​

예 :Rewrite

httpd.conf :

DocumentRoot : /some/local/path/

RewriteRule ^/somedir/(.*)$ /anotherdir/$1

​

요청 :

http://host/somedir/somefile.html

​

서버가 응답하는 실제 내용

/anotherdir/somefile.html

​

​

이와 같이 실제 요청자의 웹브라우저에 표시되는 URL을 통해

서버의 예상되는 위치에 존재하는 파일을 읽어 전송하는 것이 아니라,

별도의 위치에서 전송할 수 있도록 해주는 것이다.

​

이런 기능외에 로드발랜싱이나 프록시와 같은 기능으로 연결하거나,

혹은 다른 URL로 redirect를 시킬 수도 있다.

​

기본적으로 rewrite엔진에 넘겨지는 것은 경로(path)이다.

경로라 하면... http://host:80/somedir/somefile.html 에서

/somedir/somefile.html 까지를 의미하고, 포트와 호스트네임은 포함되지 않는다.

​

웹서버는 이 내용을 기준으로 하여 절적한 파일을 읽어 들이게 되는데...

바로 mod_rewrite는 웹서버가 이 경로와 다른 경로를 읽어 들일 수 있도록 하는 기능을 제공하는 것이다.

​

몇가지 접근하는대 필요한 개념은 아래와 같다.

​

​

입력자 : 웹서버

응답대상: 웹서버

입력값 : "(상대) 경로(path)"

출력값 : "(절대)경로 혹은 요청자에게 답변하는 내용."

​

mod_rewrite라고 했듯이 모듈이기 때문에..

상대자는 오직 웹서버 뿐이다. 즉 입력값을 받는 것도 답변을 하는 것도

웹서버라는 것이다.

​

그리고... 입력값은 상대 경로이다. (당연하겠지만)즉 서버내 물리적 위치가 아니다.

하지만 응답을 하는 것은 절대경로로 응답해야 한다. 서버가 실제로 읽어 들일

물리적 위치를 지정하는 것이다.

​

이정도의 주의 사항을 가지고 접근하기 바란다.

​

RewriteRule 1

​

RewriteRule은 입력값을 변경해주는 유일한 키워드이며, mod_rewrite의

핵심이라고 할 수 있다.

​

​

#Syntax:

RewriteRule Pattern Substitution flags

​

패턴에 따라 넘겨 받은 값을 치환(Substitution)하는 것이다.

​

패턴과 치환에 관한 방식은 펄의 정규화 표현식과 유사하다.

php의 ereg_replace나 혹은 sed, vi의 치환 명령에 익숙하다면

쉽게 접근할 것이다.

이 것에 대한 자세한 내용은 나중에 다루고..

이번엔 이명령의 중요한 개념에 대해서 설명하고자 한다.

​

문법에서 보여주는 것대로 한다면,

패턴에 맞게 입력값을 나누고, 거기에 맞게 치환하는 것으로 보인다.

근데 여기에 함정이 있다.

​

아래의 PHP Code를 보자.

​

<?php

​function RewriteRule($pattern, $Substitution, $flags= 0)

{

//웹서버에서 넘겨 받아 거나 이전의 RewriteRule의 결과값

global $URL;

​

// 정규화 표현식 실행

$tmp = ereg_replace($pattern,$Substitution,$URL);

 

// 결과물이 URL과 일치하면.. 즉 패턴에 일치하지 않고

//아무런 변화가 없으면 함수를 빠져나간다.

if($tmp == $URL) return ;

​

//정규화표현식의 실행값을 반영한다.

$URL = $tmp;

​

//추가적인 기능이 지정되어 있지 않으면, 함수를 종료한다.

if($flags== 0) return ;

​

//추가적인 기능에 L이 있으면 해당 기능을 수행한다.

if(ereg("L",$flags){

something about "L";

}

​

//추가적인 기능에 P가 있으면 해당 기능을 수행한다.

if(ereg("P",$flags){

something about "P";

}

}

?>

​

좋은 코드는 아니다.

하지만.. RewriteRule의 동작방식을 이해하는 데는 충분하다고 본다.

RewrieRule은 단순히 치환기능만이 있는 것이 아니라

Condition 즉 특정한 패턴의 검출 여부에 따라

동작을 수행 혹은 수행하지 않는

조건문을 함께 포함하고 있는 구조다.

​

이 점을 놓치면, rewrite를 이해하는데 매우 고생스럽다.

​

RewriteRule /cgi-bin(/.*)$ /cgi-bin$1 [L,PT]

​

먼저 설명이 안됀 플래그 L,PT가 있다..

PT에 대해서는 나중에 설명을 하고..

L에 대해서만 설명하겠다.

L이란 Last Rule의 약자로... 이 RewriteRule 뒤의 라인을 점부 무시하라는 뜻이다.

위의 내용은

요청된 URL중에 /cgi-bin이란 내용이 포함된 내용을 치환하고,

/cgi-bin$1이란 내용을 중심으로 Rewrite를 종료하라는 뜻이다.

그런데.. 요청된 내용에 /cgi-bin이란 내용이 없으면 어떻게 될까?

정답은 해당 RewriteRule은 무시가 된다.

이렇듯 단순한 치환명령이 아니라, 조건이 포함되어 있는 명령이라는 것을 명심하자.

​

» 댓글을 쓰실려면 로그인하거나 사용자 등록하십시오.

mudori 씀 (목, 2004/01/15 - 11:43am)

그래도 버철호스트 올인입니다.

​

» 댓글을 쓰실려면 로그인하거나 사용자 등록하십시오.

i09000 씀 (목, 2004/01/15 - 1:25pm)

저는 어떤 주소로 접속을 하던지 간에... 같은 페이지로 이동을 하고 싶은데요....

​

예> 사용자ID.도메인.com이렇게 접속을하면

​

php등을 이용해서 접속경로에 따라서 처리를 다르게 해줄 생각인데요....

​

어떻게 해야 할지........

​

영.... 많이 복잡한데요... 어떻게 해야 하죠??

​

» 댓글을 쓰실려면 로그인하거나 사용자 등록하십시오.

​

지리즈 씀 (화, 2004/01/20 - 11:59pm)

<VirtualHost 192.168.0.1>

ServerAdmin foo@bar.com

ServerName *

DocumentRoot /var/www/html/

</VirtualHost>

​

간단히 위와 같이 ServerName에 *을 사용하면 됩니다.

혹은

ServerName *.foobar.com

이런 식으로 처리하면 됩니다.

​

<VirtualHost 192.168.0.1>

ServerName *.bar.com

DocumentRoot /var/www/bar

</VirtualHost>

​

<VirtualHost 192.168.0.1>

ServerName *.foo.com

DocumentRoot /var/www/foo

</VirtualHost>

'WEB & WAS > Apache' 카테고리의 다른 글

Apache의 httpd.conf 지시자 정리  (0) 2023.03.08
http -> https 리다이렉트  (0) 2023.03.08
Apache cronolog  (0) 2023.03.08
유료인증서를 위한 key, csr 생성  (0) 2023.03.08
Apache 마이그레이션 (2.2, 2.4)  (0) 2023.03.08

댓글