WEB & WAS/Apache

mod_rewrite 실전

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

Rewrite 모듈이란?

mod_rewrite 는 apache 의 모듈 중 하나로써 서버로 요청하는 도메인을 포함한 url 을 정해진 rule 에 따라 지정된 url 표시, 파일 혹은 다른 페이지를 보여줄 수 있는 모듈입니다.

Rewrite 모듈을 이용하면 복잡한 url 을 짧고 간결하게 표현할 수 있으며, 이를 통해 보안성도 보장받을 수 있습니다. 
강력한 기능성을 보유한 반면에 사용법이 어려워 쉽게 이용하지 못하는 점도 있습니다. 
본 메뉴얼에선 rewrite 모듈 설치 및 간단한 사용법 몇 가지를 작성해 놓았습니다.

mod_rewrite Rule

RewriteEngine : mod_rewrite를 사용할지 여부(On/Off)
RewriteBase : 기본 경로 설정
RewriteCond : 문자열의 패턴 조건 비교
RewriteRule : 실제로 치환되는 조건

플래그 종류: 
forbidden|F - 403에러로 redirect
ex) RewriteRule ^/test /home/blog/html/test.php [F]

gone|G - 410에러로 redirect
Proxy request|P - proxy request로 보냄
last|L - 뒤에 어떤 룰이 있어도 적용하지 않고 빠져나옴
ex) RewriteRule ^/$ <보여질 주소> [L]

RewriteRule ^$ <보여질 주소> [L]
New|N - 새로운 룰 시작
Redirection|R - 무조건 redirect

NC - 대소문자를 구별하지 않음, 
QSA - Cond의 내용을 지닌 결과에 덧붙인다.
OR - OR
C
ex) RewriteRule ^([^.]+).example.com(.*) /home/$1/public_html$2

이 룰은 사용자 홈의 도메인을 2차 도메인으로 자동 설정해 줄 때 많이 쓰는 룰입니다.
즉 http://user_id. example.com/hello.html 이란 요청이 들어오면
/home/user_id/public_html/hello.html 로 redirect 시켜줍니다.

 

실습

1. www 강제

<VirtualHost *:80>
ServerAdmin budget74@nate.com
DocumentRoot /www/src
ServerName www.*.net
ServerAlias *.net www.*.com *com www.*.co.kr *.co.kr www.*.kr *.kr
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www [NC]
RewriteCond %{HTTP_HOST} !^$
RewriteRule ^/(.*) http://www.%{HTTP_HOST}/$1 [L,R]
</IfModule>
</VirtualHost>
<VirtualHost *:80>
ServerAdmin budget74@nate.com
DocumentRoot /www/src
ServerName www.*.net
ServerAlias *.net www.*.com *com www.*.co.kr *.co.kr www.*.kr *.kr
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^/act/([a-zA-Z0-9]+)/([a-zA-Z0-9]+)$ /member/?var1=$1&var2=$2 [R,L]
</IfModule>
</VirtualHost>

3. 특정 파라미터 값을 가지고 들어올 경우 redirect

<VirtualHost *:80>
DocumentRoot /home/www/public_html
ServerName www.domain.co.kr
ServerAlias domain.co.kr
RewriteEngine On
RewriteCond %{QUERY_STRING} ^(.*)mode=test$
RewriteRule ^/(.*) http://www.naver.com%{REQUEST_URI} [L,R]
</VirtualHost>

mode 값이 test 일 때 naver 로 보네버리는 겁니다. [R]은 해당 URL로 주소창의 변경합니다.

%{REQUEST_URI} : 호스트 부분을 제외하고 디렉토리 부분 부터 파라미터까지를 의미합니다.

ex) http://www.sample.co.kr/abc/def.php?param=test

%{REQUEST_URI} 부문은 "/abc/def.php?param=test" 가 되겠습니다.

cf ) http://httpd.apache.org/docs/2.0/misc/rewriteguide.html

4. index 교체

<VirtualHost *:80>
ServerAdmin budget74@nate.com
DocumentRoot /www/src
ServerName www.*.net
ServerAlias *.net www.*.com *com www.*.co.kr *.co.kr www.*.kr *.kr
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/index\.php
RewriteRule ^/(.*) /idx.php [L]
</IfModule>
</VirtualHost>

* RewriteRule 작성방법 및 해설

RewriteRule ^/sample/(.*)$ /shop/sample/$1 [L]

의 경우,

http://도메인명/sample/ 에 접속하면

http://도메인명/shop/sample/ 로 주소처리하여 표시하고,

브라우저에서는, http://도메인명/sample/ 으로 주소를 표시한다.

http://도메인명/sample/test/test.php 에 접속하면

http://도메인명/shop/sample/test/test.php 로 주소를 처리하여 표시하고

브라우저에서는, http://도메인명/sample/test/test.php 으로 주소를 표시한다.

[L]은 정의된 최종행을 의미한다.

이 행 이후의 RewriteRule은 무시된다.

가장 맨 마지막행에 적는다.

아무것도 적지 않아도 OK.

[R]은 리다이렉트를 실행.

RewriteRule ^/sample/(.*)$ /shop/sample/$1 [L,R]

의 경우,

http://도메인명/sample/ 으로 접속하면

http://도메인명/shop/sample/ 로 주소처리하여 표시하고,

브라우저는 http://도메인명/shop/sample/ 으로 주소를 표시한다.

http://도메인명/sample/test/test.php 으로 접속하면

http://도메인명/shop/sample/test/test.php 로 주소를 처리하여 표시하고 

브라우저는 http://도메인명/shop/sample/test/test.php 으로 주소를 표시한다.

RewriteRule ^/blog/view/([0-9]+)/?$ /blog/view/index.php?id=$1

의 경우,

http://도메인명/blog/view/1234/ 으로 접속하면

http://도메인명/blog/view/index.php?id=1234 로 주소처리하여 표시하고

브라우저는 http://도메인명/blog/view/1234/ 으로 주소를 표시한다.

「/」???「?」(을)를 넣어놓은 것은, 야후등의 검색 엔진에서는 URL의 뒤의 slash를 삭제한 URL를 인덱스에 등록하기 때문에, URL의 뒤로 slash가 있어도 없어도 액세스 할 수 있도록 하고 있다.

RewriteRule ^/abc/([0-9,a-z,A-Z]+)/([0-9,-]+)/?$ /abc/test.php?id=$1&date=$2

의 경우,

http://도메인명/abc/suzuki/2006-01-01/ 으로 접속하면

http://도메인명/abc/test.php?id=suzuki&date=2006-01-01 로 주소처리하여 표시하고

라우저는 http://도메인명/abc/suzuki/2006-01-01/ 으로 주소를 표시한다.

 

* RewriteRule 샘플

<VirtualHost 192.168.1.2>

ServerName www.example.com

DocumentRoot /test/htdocs

RewriteEngine On

RewriteRule ^/sample/(.*)$ /shop/sample/$1

RewriteRule ^/blog/view/([0-9]+)/?$ /blog/view/index.php?id=$1

RewriteRule ^/abc/([0-9,a-z,A-Z]+)/([0-9,-]+)/?$ /abc/test.php?id=$1&date=$2 [L]

<Directory "/test/htdocs">

Options Includes ExecCGI MultiViews

AllowOverride All

Order allow,deny

Allow from all

</Directory>

</VirtualHost>

=========================================================================

httpd.conf ,httpd-vhosts.conf 파일에 또는 root디렉토리의 .htaccess 파일에

RewriteEngine on

추가하면 rewrite엔진을 사용할 수 있다.

즉, 적용할 수 있는 곳은 3군데

1. httpd.conf 에서 <Directory "/usr/local/apache/htdocs/">디렉토리에 적기

2. extra/httpd-vhosts.conf 파일에 vhost마다 <Directory "/home/webadmin/pubilc_html"> 이런디렉토리별로 가능

3. 각디렉토리의 .htaccess파일에 가능 

vi /usr/local/apache/htdocs/.htaccess or vi /home/webadmin/pubilc_html/.htaccess

RewriteEngine on 를 넣어주면 가능.

원하는 내용은 아래처름 정규표현식을 사용하면 URI를 변경할 수 있다.

RewriteRule ^old\.html$ new.html

위 규칙은 old.html요청을 new.html요청으로 바꿔서 처리한다(transparently).

만약에 강제로 new.html로 표시하려면 flag로 [R]을 사용한다.

RewriteRule ^old\.html$ new.html[R]

아래 규칙은 static URI를 dynamic URI로 바꾸어 처리한다.

정규표현식을 통해 여러개의 요청에 대한 변환을 간단히 표현할 수 있다.

RewriteRule ^products/([0-9][0-9])/$ productinfo.php?prodID=$1

위 규칙은 URL이 products/12/ 또는 products/90/ 이런 형태의 요청이 발생할 경우

내부적으로 productinfo.php?prodID=12 또는 productinfo.php?prodID=90 으로

바꿔서 처리한다. [0-9]는 0~9까지의 임의의 숫자 하나를 의미 한다.

[a-z]는 소문자a~z를 [A-Z]는 대문자 A~Z, [a-zA-Z]는 영문자 한자를 의미한다.

()로 감싸고 있는 부분은 back-reference라고 하는 것으로 변수처럼 변환될 패턴에서

사용된다. back-reference 순서대로 $1,$2 형태로 사용하게 된다.

위의 예에서는 back-reference가 한개이며 $1부분이 치환되게 된다.

하지만, products/12 같은 요청은 처리를 못한다. '/'가 없기 때문인데

가능한 방법은 다양하겠지만, 간단히 다음처럼 룰을 작성하면 가능하다.

RewriteRule ^products/([0-9][0-9])$ products/$1/ [R] <-- flag를 사용하여 다시 rule적용

RewriteRule ^products/([0-9][0-9])/$ productinfo.php?prodID=$1

htaccess

.htaccess (HyperTesxt Access)는 Apache 웹 서버의 디렉토리 레벨을 설정하는 기본 파일입니다. .htaccess 는 한 특정 디렉토리에 위치하며, 모든 하위 디렉토리를 포함한 해당 디렉토리에 영향을 가지며 이 파일이 위치한 특정 폴더에 사용자가 정의한 Request 기능을 적용합니다. 파일 이름이 .으로 시작 하기 때문에 유닉스 계열의 운영체제에서는 숨김 파일로 저장이 됩니다.

vi /usr/local/apache/conf/httpd.conf​

=====================================================================

<IfModule mod_rewrite.c>
rewriteEngine On
</IfModule>

<Directory />

        AllowOverride All

</Directory>

=====================================================================

 

vi /도메인마다 설정된 디렉토리/.htaccess

해당 다큐먼트루트에 .htaccess 파일을 생성하여 아래 내용을 추가하여 줍니다.

RewriteEngine On

RewriteCond %{REQUEST_FILENAME} !-f

RewriteCond %{REQUEST_FILENAME} !-d

RewriteRule ^(.*)$ http://linuxkill.xyz/wordpress/test.php/$1

위처럼 설정을 하였을 경우

linuxkill.xyz/ttt 이런식으로 도메인을 입력하였을때

linuxkill.xyz/wordpress/test.php/ttt 라고 도메인에 보여지며

linuxkill.xyz/wordpress/test.php 로 연결이 됩니다.

RewriteCond 지시자는 RewriteRule 과 함께 사용되는 규칙으로 RewriteCond 다음에 오는 RewriteRule 은 RewrieteCond 에서 설정한 패턴과 일치해야지만 RewriteRule 들을 실행합니다.

-d : 디렉토리를 의미합니다. TestString 이 디렉토리를 가리키거나 포함하고 있을 때 처리됩니다.

-f : 파일을 의미합니다. TestString 이 파일을 가리키더나 포함하고 있을 때 처리됩니다.

vi /도메인마다 설정된 디렉토리/.htaccess

RewriteEngine On

RewriteCond %{HTTP_HOST} ^linuxkill\.xyz/wordpress$ [NC,OR]

RewriteCond %{HTTP_HOST} ^linuxkill\.xyz/([0-9]+) [NC]

RewriteRule ^(.*)$ http://ttt.linuxkill.xyz/$1 [R=301,L]

위에서 [NC] 의 의미는 대소문자를 구분하지 않는다는 의미입니다.

[OR]은 프로그래밍의 or 와 비슷합니다.

[R=301] 의 의미는 검색엔진이 인덱스를 다시 생성하게 한다는 뜻입니다.

(즉 ttt 를 붙여서 다시 보여지게 된다는 뜻이지요)

'linuxkill.xyz 로 접속하면 자동으로 'ttt'를 붙여줍니다.

vi /도메인마다 설정된 디렉토리/.htaccess

=====================================================================

RewriteEngine on 

RewriteCond %{REMOTE_HOST} ^linuxkill.xyz.* [OR] 

RewriteRule ^(.*)$ http://www.naver.com/ 

=====================================================================

 

도메인 linuxkill.xyz 로 접속시 www.naver.com 으로 포워딩 시켜주는 역할을 합니다. 

Linuxkill.xyz.* 의 의미는 linuxkill.xyz/ 뒤에 어떤 문자나 숫자를 써도 naver.com 으로 포워딩 시켜준다는 의미입니다.

정규표현식 기본 형태 

RewriteCond TestString CondPattern (Cond = Condition) 

RewriteRule Pattern Substitution [Flag]

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

Apache 마이그레이션 (2.2, 2.4)  (0) 2023.03.08
htpasswd 웹페이지 암호걸기  (0) 2023.03.08
Apache MPM 튜닝  (0) 2023.03.08
Apache 컴파일 옵션  (0) 2023.03.08
무료인증서 (letsencrypt, buypass)  (0) 2023.03.08

댓글