Apache HTTP Server Version 2.2
DNS와 아파치와 관련된 사항
이 문서를 한 문장으로 요약할 수 있다. 아파치가 설정파일을 읽을때 DNS를 의존하지않도록 하라. 아파치가 설정파일을 읽는데 DNS가 필요하다면 서버는 신뢰성 문제 (시작이 안될 수도 있다) 혹은 서비스거부 공격과 (사용자가 다른 사용자에 대한 접근을 가로채는 것을 포함하여) 서비스도둑(theft of service) 공격에 시달릴 수 있다.
간단한 예제
<VirtualHost www.abc.dom>
ServerAdmin [email protected]
DocumentRoot /www/abc
</VirtualHost>
아파치가 정상적으로 동작하기위해서는 각 가상호스트에
대해 두가지 정보가 절대적으로 필요하다. 이 정보는
ServerName
과 서버가
기다리고 응답할 최소 한개의 IP 주소이다. 이 예는 IP 주소가
없기때문에, 아파치는 DNS를 사용하여 www.abc.dom
의
주소를 찾아야 한다. 서버가 설정파일을 읽을때 어떤 이유에서건
DNS를 사용할 수 없다면 가상호스트를 만들 수 없다.
이 가상호스트는 요청에 응답할 수 없다. (아파치 1.2 이전
버전에서는 심지어 서버가 부팅도 안한다.)
www.abc.dom
의 주소가 192.0.2.1이라고 가정하자.
그리고 다음 설정을 보라:
<VirtualHost 192.0.2.1>
ServerAdmin [email protected]
DocumentRoot /www/abc
</VirtualHost>
이제 아파치는 이 가상호스트의 ServerName
을
찾기위해 역DNS를 사용해야 한다. 역찾기가 실패하면 아파치는
가상호스트를 부분적으로 끈다. (아파치 1.2 이전 버전에서는
심지어 서버가 부팅도 안한다.) 즉, 이 경우 이름기반
가상호스트라면 가상호스트는 완전히 동작하지않고, ip기반이라면
대부분 동작한다. 그러나 아파치가 서버명을 포함하여 서버의
전체 URL을 만들어야 한다면 정상적인 URL을 만들지 못한다.
아래 경우 이 두가지 문제가 없다.
<VirtualHost 192.0.2.1>
ServerName www.abc.dom
ServerAdmin [email protected]
DocumentRoot /www/abc
</VirtualHost>
서비스거부 (Denial of Service)
(최소한) 두가지 종류의 서비스거부가 발생할 수 있다.
아파치 1.2 이전 버전의 경우 어떤 가상호스트에서라도
위에서 말한 두 DNS 검색이 실패하면 서버가 켜지지도 않는다.
DNS가 당신의 권한 밖의 문제일 수도 있다. 예를 들어,
abc.dom
이 고객 사이트이고 고객이 자신의 DNS를
관리한다면, www.abc.dom
레코드를 지우기만 해도
(1.2 이전) 서버는 시작하지 못한다.
훨씬 더 교활한 방법도 있다. 다음 설정을 살펴보자:
<VirtualHost www.abc.dom>
ServerAdmin [email protected]
DocumentRoot /www/abc
</VirtualHost>
<VirtualHost www.def.dom>
ServerAdmin [email protected]
DocumentRoot /www/def
</VirtualHost>
당신이 www.abc.dom
에 192.0.2.1,
www.def.dom
에 192.0.2.2를 할당했다고 하자.
또, def.dom
은 자체 DNS를 사용한다고 가정하자.
이 설정과 함께 def.dom
을 abc.dom
으로
가는 모든 통신을 가로챌 수 있는 장소에 두었다. 그렇다면 그들은
www.def.dom
을 192.0.2.1로 설정하기만 하면 된다.
그들이 자체 DNS를 사용하기때문에 당신은 그들이 원하는데로
www.def.dom
레코드를 설정하는 것을 막을 수
없다.
(사용자가 http://www.abc.dom/whatever
형식의
URL을 입력하는 경우를 포함하여) 192.0.2.1로 오는 모든 요청을
def.dom
가상호스트가 서비스하게 된다. 왜 이런
일이 일어나는지 이해하려면 아파치가 어떻게 가상호스트로
오는 요청을 처리하는지에 대한 설명이 필요하다.
여기에 대강 설명되있다.
"주서버" 주소
아파치 1.1에서 이름기반
가상호스트 지원이 포함되었기때문에 아파치는 웹서버를
실행하는 호스트의 IP 주소(들)를 알 필요가 생겼다. 이 주소는
(있다면) 전역 ServerName
혹은 C 함수 gethostname
으로 (명령프롬프트에
"hostname"을 입력했을때와 같은 결과) 얻는다. 그러면 이 주소로
DNS 검색을 한다. 현재 이 검색은 피할 수 없다.
DNS 서버가 죽어서 이 검색이 실패할 것 같다면
/etc/hosts
에 호스트명을 집어넣을 수 있다.
(컴퓨터가 정상적으로 부팅되었다면 아마 이미 들어있을 것이다.)
그리고 DNS가 실패하면 서버가 /etc/hosts
를
사용하는지 확인하라. 사용하는 운영체제에 따라
/etc/resolv.conf
혹은 /etc/nsswitch.conf
를
수정하면 될 것이다.
서버가 어떤 이유에서건 DNS를 검색하면 안된다면
HOSTRESORDER
환경변수를 "local"로 설정하고
아파치를 실행할 수 있다. mod_env
를
사용하여 환경을 변경하지 않는다면 이 환경변수는
CGI에도 영향을 준다. 운영체제의 manpage나 FAQ를 참고하는
것이 좋다.
이 문제를 피하기위한 팁
-
VirtualHost
에 IP 주소를 사용하라 -
Listen
에 IP 주소를 사용하라 -
모든 가상호스트는 명시적으로
ServerName
을 가지게 하라 - 어떤 페이지도 서비스하지않는
<VirtualHost _default_:*>
서버를 만들어라
부록: 앞으로는
DNS와 관련된 상황은 매우 바람직하지 못하다. 아파치 1.2에서 우리는 DNS가 실패한 경우에도 최소한 서버가 켜지도록 노력했지만 결과는 나빴다. 어쨌든 설정파일에 직접 IP 주소를 요구하는 것은 번호를 다시 설정해야할 요즘 인터넷에 매우 바람직하지 못하다.
위에서 설명한 서비스도둑 공격을 막는 한가지 방법은 검색한 IP 주소에 다시 역DNS 검색을 하여 두 이름을 비교하는 것이다. 서로 다른 경우 가상호스트를 가동하지 않을 수 있다. 이 방법은 역DNS가 올바로 설정되야 한다. (FTP 서버나 TCP wrapper가 "중복-역" DNS 검색을 자주 사용하기때문에 대부분의 관리자에게 익숙할 것이다.)
어쨌든 IP 주소를 사용하지않으면 DNS가 실패한 경우 가상호스트 웹서버를 믿을 수 있게 시작할 수 없다. 설정의 일부를 무시하는 것과 같은 부분적인 해결책은 웹서버 전체를 시작하지않는 것보다 더 나쁠 수도 있다.
HTTP/1.1이 나왔고 브라우저와 프록시가 Host
헤더를 보내기 시작했으므로 IP기반 가상호스트를 완전히
사용하지않는 것이 가능해질 것이다. 그러면 웹서버는 설정중에서
DNS 검색을 할 필요가 없어진다. 그러나 1997년 3월에는 중요한
웹서버에 포함할 정도로 이름기반 가상호스트가 널리 사용되지
않았다.