Apache HTTP Server Version 2.4
아파치의 환경변수
아파치 웹서버는 환경변수(environment variable)라는 변수에 정보를 저장할 수 있다. 이 정보를 사용하여 로그나 접근제어 등 여러 작업을 조절한다. 또, 환경변수는 CGI 스크립트와 같은 외부 프로그램과 통신하는 수단이 된다. 이 문서는 환경변수를 다루고 사용하는 다양한 방법들을 설명한다.
이 변수들을 환경변수라고 부르지만, 운영체제에서 말하는 환경변수와 다르다. 이 변수는 아파치 내부에 저장되고 사용된다. 환경변수는 CGI 스크립트나 Server Side Include 스크립트로 넘겨질때만 실제 운영체제 환경변수가 된다. 서버를 실행하는 운영체제 환경을 수정하고 싶다면 운영체제 쉘에서 환경을 수정해야 한다.
환경변수 설정하기
관련된 모듈 | 관련된 지시어 |
---|---|
기본적인 환경설정
아파치에서 환경변수를 설정하는 가장 기본적인 방법은
무조건적인 SetEnv
지시어를 사용하는 것이다. PassEnv
지시어를 사용하여
서버를 시작한 쉘에서 환경변수를 가져올 수도 있다.
요청에 따른 조건부 설정
더 유연하게, mod_setenvif가 제공하는 지시어는 요청마다
요청의 특징에 따라 환경변수를 설정한다. 예를 들어, 특정
브라우저로 (User-Agent) 요청하거나 특정 Referer (맞춤법이
틀리지 않았다) 헤더가 있는 경우에만 변수를 설정할 수
있다. 심지어 mod_rewrite에 있는 RewriteRule
의
[E=...]
옵션을 사용하여 더 유연하게 환경변수를
설정할 수도 있다.
유일한 식별자
마지막으로 mod_unique_id는 각 요청에 대해 어떤 경우에도
"모든" 요청중에 확실히 유일한(겹치지않은) 값으로
UNIQUE_ID
환경변수를 설정한다.
표준 CGI 변수
CGI 스크립트와 SSI 문서는 아파치 설정에서 설정하였거나 쉘에서 가져온 환경변수 외에 추가로 CGI 규약이 규정한 요청에 대한 정보를 알려주는 환경변수들을 받는다.
주의할 점
- 환경설정 지시어를 사용하여 표준 CGI 변수를 무시하거나 수정할 수 없다.
- suexec가 CGI 스크립트를
실행하는 경우, 시작하기전에 CGI 스크립트의 환경은
안전한 변수들만 가지도록 청소된다.
안전한 변수 목록은 컴파일시
suexec.c
에 정의된다. - 포팅을 위해 환경변수 이름에는 오직 문자, 숫자, 밑줄문자만 사용하는 것이 좋다. 또, 첫번째 문자로 숫자를 사용하지않는 것이 좋다. CGI 스크립트나 SSI 페이지에 넘어갈때 이외의 문자는 밑줄로 대체된다.
환경변수 사용하기
관련된 모듈 | 관련된 지시어 |
---|---|
CGI 스크립트
환경변수의 주된 용도중 하나는 CGI 스크립트와 정보를 교환하는 것이다. 앞에서 설명했듯이 아파치 설정에서 설정한 변수외에 요청에 대한 표준 정보를 가진 변수가 CGI 스크립트로 넘어간다. 더 자세한 내용은 CGI 투토리얼을 참고하라.
SSI 페이지
mod_include의 INCLUDES
필터가 처리하는
서버파싱 (SSI) 문서는 echo
요소를 사용하여
환경변수를 출력할 수 있고, 환경변수를 사용하여 요청의
특징에 따라 흐름제어 요소로 페이지의 일부를 변경할 수
있다. 아파치는 또 SSI 문서에게 위에서 설명한 표준 CGI
환경변수를 제공한다. 더 자세한 내용은 SSI 투토리얼을 참고하라.
접근제어
allow from env=
과 deny from env=
지시어를 사용하여 환경변수 값에 따라 서버로의 접근을
조절할 수 있다. SetEnvIf
와 같이 사용하면
클라이언트의 특징에 따라 자유롭게 서버로의 접근을 제어할
수 있다. 예를 들어, 특정 브라우저의 (User-Agent) 접근을
거부할 수 있다.
조건부 로그
LogFormat
의
%e
옵션을 사용하여 환경변수를 접근 로그에
기록할 수 있다. 또, CustomLog
지시어의
조건부 형식을 사용하면 환경변수의 상황에 따라 요청을
로그할지 여부를 결정할 수 있다. SetEnvIf
와 같이 사용하여
어떤 요청을 로그할지 자유롭게 결정할 수 있다. 예를 들어,
파일명이 gif
로 끝나는 요청은 로그하지 않거나,
외부 네트웍에 있는 클라이언트의 요청만을 로그할 수 있다.
조건부 응답 헤더
Header
지시어는 클라이언트에게 응답을 보낼때 환경변수의 유무에
따라 어떤 HTTP 헤더를 포함할지 결정할 수 있다. 예를
들어, 클라이언트의 요청에 특정 헤더가 있는 경우에만
어떤 응답 헤더를 보낼 수 있다.
외부 필터 실행하기
mod_ext_filter
의 ExtFilterDefine
지시어로 설정한 외부 필터를 disableenv=
와
enableenv=
옵션을 사용하여 환경변수에 따라
선택적으로 실행할 수 있다.
URL 재작성(Rewriting)
RewriteCond
의
TestString에 %{ENV:...}
형식을
사용하면 mod_rewrite의 재작성 엔진이 환경변수에 따라
다르게 행동한다. mod_rewrite에서 앞에 ENV:
를
붙이지않고 접근하는 변수는 실제 환경변수가 아님을 주의하라.
그들은 다른 모듈에서 읽을 수 없는 mod_rewrite에 한정된
변수다.
특별한 목적의 환경변수
클라이언트와 원활한 동작하기위해 아파치는 특별한
클라이언트에 대해 자신의 행동을 수정한다. 보통 BrowserMatch
에서
환경변수를 정의하여 이런 문제를 해결한다. 그러나 SetEnv
와 PassEnv
로도 가능하다.
downgrade-1.0
요청이 이후 버전을 사용하더라도 HTTP/1.0 요청으로 처리한다.
force-gzip
DEFLATE
필터를 사용할때 이 환경변수는
브라우저의 accept-encoding 설정을 무시하고 무조건
압축된 결과를 보낸다.
force-no-vary
응답을 클라이언트에게 보내기 전에 응답 헤더에서
Vary
필드를 뺀다. 어떤 클라이언트는 이
필드를 제대로 해석하지 못한다. 이 변수는 이런 문제를
해결한다. 또한, 이 변수는
force-response-1.0을 가정한다.
force-response-1.0
HTTP/1.0 요청을 하는 클라이언트에게 HTTP/1.0 응답을 강제한다. 원래 AOL 프록시에 문제가 있어서 만들어졌다. 어떤 HTTP/1.0 클라이언트는 HTTP/1.1 응답을 받으면 제대로 동작하지 않으므로, 이 문제를 해결하기위해 사용한다.
gzip-only-text/html
값이 "1"이면 text/html
이 아닌 content-type에
대해 mod_deflate
의 DEFLATE 출력필터를
사용하지 않는다. (gzip 뿐만 아니라 "identity"가 아닌 모든
인코딩의) 정적으로 압축한 파일의 경우에도
mod_negotiation
은 이 변수를 참고한다.
no-gzip
이 옵션을 설정하면 mod_deflate
의
DEFLATE
필터를 사용하지 않고,
mod_negotiation
은 인코딩된 자원을
보내지 않는다.
nokeepalive
KeepAlive
를
무시한다.
prefer-language
이 변수는 mod_negotiation
의 행동에
영향을 미친다. 변수가 (en
, ja
,
x-klingon
등) 언어태그를 담고있다면,
mod_negotiation
는 그 언어로 된 변형을
보내길 시도한다. 그런 변형이 없다면 일반적인 협상 과정을 시작한다.
redirect-carefully
서버가 더 조심히 클라이언트에게 리다이렉션을 보낸다. 보통 리다이렉션을 처리하는데 문제가 있는 클라이언트을 위해 사용한다. 원래 Microsoft의 WebFolders 소프트웨어가 DAV 메써드를 통해 디렉토리 자원의 리다이렉션을 처리하는데 문제가 있어서 만들어졌다.
suppress-error-charset
2.0.40 이후 버전에 있다
아파치가 클라이언트의 요청에 대한 응답으로 리다이렉션을 보낼때 클라이언트가 자동으로 리다이렉션을 따라가지 못하는(혹은 않는) 경우에 대비하여 응답에 사용자에게 보여줄 문구를 포함한다. 아파치는 보통 이 글을 아파치가 사용하는 문자집합인 ISO-8859-1로 표시한다.
그러나 리다이렉션된 페이지가 다른 문자집합을 사용할 경우 어떤 이상한 브라우저 버전은 실제 페이지가 아니라 리다이렉션 페이지의 문자집합을 사용하려고 한다. 예를 들어, 그리스어가 이상하게 보일 수 있다.
이 환경변수는 아파치가 리다이렉션 페이지에 문자집합을 설정하지않도록 하여, 이런 브라우저가 실제 페이지의 문자집합을 올바로 사용하게 만든다.
예제
잘못 동작하는 클라이언트들을 위해 프로토콜 행동 변경하기
클라이언트들의 이미 알려진 문제를 해결하기위해 httpd.conf에 다음 내용을 포함하길 바란다.
# # 다음 지시어들은 일반적인 HTTP 응답을 변경한다. # 첫번째 지시어는 Netscape 2.x와 이를 가장한 브라우저에게 # keepalive를 사용하지 않는다. 이들 브라우저 구현에 문제가 있다. # 두번째 지시어는 HTTP/1.1 구현이 잘못되었고 301이나 302 # (리다이렉션) 응답에 사용한 keepalive를 제대로 지원하지 # 못하는 Microsoft Internet Explorer 4.0b2를 위한 것이다. # BrowserMatch "Mozilla/2" nokeepalive BrowserMatch "MSIE 4\.0b2;" nokeepalive downgrade-1.0 force-response-1.0 # # 다음 지시어는 기본적인 HTTP/1.1 응답을 이해하지 못하여 # HTTP/1.0 규약을 어기는 브라우저에게 HTTP/1.1 응답을 보내지 않는다. # BrowserMatch "RealPlayer 4\.0" force-response-1.0 BrowserMatch "Java/1\.0" force-response-1.0 BrowserMatch "JDK/1\.0" force-response-1.0
접근 로그에 이미지에 대한 요청을 로그하지 않기
이 예제는 이미지에 대한 요청을 접근 로그에 기록하지 않는다. 특정 디렉토리에 대한 혹은 특정 호스트에서 온 요청을 로그하지 않도록 쉽게 수정할 수 있다.
SetEnvIf Request_URI \.gif image-request SetEnvIf Request_URI \.jpg image-request SetEnvIf Request_URI \.png image-request CustomLog logs/access_log common env=!image-request
"이미지 도둑" 방지
이 예는 현재 서버외의 사용자가 페이지에 서버에 있는 이미지를 포함하지 못하도록 하는 방법을 설명한다. 이 설정을 권장하지는 않으며, 제한된 경우에만 동작한다. 우리는 모든 이미지가 /web/images 디렉토리 안에 있다고 가정한다.
SetEnvIf Referer "^http://www.example.com/" local_referal # Referer 정보를 보내지 않는 브라우저를 허용한다 SetEnvIf Referer "^$" local_referal <Directory /web/images> Order Deny,Allow Deny from all Allow from env=local_referal </Directory>
이 기법에 대한 자세한 설명은 ApacheToday 투토리얼 " Keeping Your Images from Adorning Other Sites"를 참고하라.