RSS구독하기:SUBSCRIBE TO RSS FEED
즐겨찾기추가:ADD FAVORITE
글쓰기:POST
관리자:ADMINISTRATOR
'Web_developing'에 해당되는 글 102
Smarty에 내장된 캐시 내용들을 다양한 저장장치에 담을 수 있고, 사이트 내의 컨텐츠들이 업데이트될 때 손쉽게 캐시를 갱신할 수 있다. 이번 호에는 각 상황에 맞는 캐시 사용 방법과 Smarty의 보안 설정 방법에 대해 알아보도록 하겠다.
조한석 |마소 Jr.에 PHP를 연재하던 필자는 최근 Smarty에 흠뻑 빠져 살고 있다. 많은 PHP 프로그래머들과 Smarty를 함께 공유하고 싶은 마음이 간절하며, 지금도 틈틈이 Smarty 매뉴얼을 번역중이고, 최근 들어 학교 프로젝트를 수행하기 위해 파이썬을 공부하는 중이다.

지금까지 템플릿 파일들은 $template_dir에만 위치해 있었고, 이것을 읽어 들이는 방법은 다음과 같았다.

// PHP Script에서
$smarty->display(‘index.tpl’);
{* 템플릿에서 *}
{include file=’home/index.tpl’}

만일 $template_dir에 없는 템플릿들을 불러오기 위해서는 다음과 같이 절대경로를 이용해 템플릿을 가져오면 된다.

// PHP Script에서(Unix)
$smarty->display(‘/home/sizer/template/index.tpl’);
{* 템플릿에서(Windows) *}
{include file=’C:/My Website/template/index.tpl’}

앞의 표현들은 사실 웹 브라우저에서 ‘http://’를 생략하고 URL을 입력하는 것처럼 완전한 것은 아니다. 웹 브라우저들이 프로토콜 타입인 ‘http://’가 생략된 URL에 대해 기본적으로 ‘http://’라고 가정하는 것처럼, Smarty 엔진은 앞에서 생략된 리소스 타입으로 로컬 머신의 파일 시스템에 있는 파일들을 가리키는 리소스 타입인 ‘file’을 가정하고 있다. 그리고 앞의 표현들은 다음과 같이 좀더 길게 타이핑해줄 수도 있다.

$smarty->display(‘file:index.tpl’);
{include file=’file:home/index.tpl’}
$smarty->display(‘file:/home/sizer/template/index.tpl’);
{include file=’file:C:/My Website/template/index.tpl’}

리소스 플러그인 작성하기
Smarty를 사용하는 프로그래머는 파일 시스템이 아닌 데이터베이스나 LDAP, 혹은 공유 메모리 같은 저장장치에 저장할 수 있도록 별도의 리소스 플러그인을 작성하는 것이 가능하다. 그러나 다른 저장장치를 템플릿의 저장소로 사용하는 것은 아주 규모가 큰 카페와 같은 기능을 구현할 때나 고려해 볼 만한 것이고, 일반적인 성격의 웹 사이트에서는 거의 쓰일 일이 없다고 생각된다. 그런 이유로 데이터베이스에서 템플릿을 읽는 리소스 플러그인은 이 글을 다 읽고나서 독자 여러분들이 스스로 해보기를 바라며(Smarty 매뉴얼에 그렇게 실전적이지는 않은 예제가 있으니 참조하기 바란다), 이번 호에는 스킨 기능을 이용하는 웹 애플리케이션에서 필요한 템플릿들을 좀더 편리하게 지정할 수 있도록 리소스 플러그인을 추가하는 예제를 알아보도록 하겠다. <리스트 1>에 나와 있듯이 리소스 플러그인에 필요한 함수는 다른 플러그인과는 달리 4개가 필요하다.

◆ smarty_[resource_name]_template($tpl_name, &$tpl_source, &$smarty) : 템플릿 내용을 &$tpl_source를 통해 반환하는 함수, 지정한 템플릿을 찾는 데 성공하면 true를, 실패하면 false를 반환한다.
◆ smarty_[resource_name]_timestamp($tpl_name, &$tpl_source, &$smarty) : 템플릿이 만들어진 시간을 &$tpl_timestamp를 통해 반환하는 함수, 지정한 템플릿을 찾는 데 성공하면 true를, 실패하면 false를 반환한다.
◆ smarty_[resource_name]_secure($tpl_name, &$smarty) : 해당 리소스 타입이 안전한 것인지를 체크하는 함수(뒤에 나오는 보안과 관련된 함수)
◆ smarty_[resource_name]_trusted($tpl_name, &$smarty) : 해당 리소스 타입이 신뢰할 수 있는 것인지를 체크하는 함수(뒤에 나오는 보안과 관련된 함수)

<리스트 1>은 이와 같은 형식으로 작성된 리소스 플러그인을 plugins 디렉토리에서 자동으로 읽어 들이게 하는 방식이 아니라, 수동으로 register_resource() 함수로 등록시켰는데(이런 경우 플러그인 함수 이름 앞에 ‘smarty_’ 접두어를 붙일 필요가 없다), 일부 특정한 Smarty 자식 클래스에서만 사용하는 플러그인의 경우 이런 식으로 플러그인을 등록하는 방법이 종종 이용되므로 참조하기 바란다. 그리고 스킨을 순수한 템플릿만으로 만드는 것이 아니라 설정파일도 같이 사용하고 싶다면, 스킨 디렉토리의 설정파일을 로드할 수 있는 {skin_config_load} 같은 함수도 만들어 등록해줘야 할 것이다.

기본적인 캐시 사용법
사실 템플릿 리소스들은 컴파일된 이후에는 사용되지 않으므로 아무리 빠른 저장장치(예를 들어, 공유 메모리와 같은)에 저장한다고 해도 웹 사이트에서 얻는 성능상의 이익은 거의 없다고 봐야한다. 실제로 Smarty로 된 웹 애플리케이션의 성능을 개선하기 위해서는 지난 호에 배운 필터와 이번 호의 캐시 기능을 잘 활용해야 한다. 간단하게 Smarty에서 캐시를 활성화시키기 위해서는 다음과 같이 $cache_dir에 웹 서버가 읽기/쓰기가 가능하게 디렉토리의 퍼미션을 줄 필요가 있다.
// ‘/any_cache_path’는 읽기 쓰기가 가능해야 한다.
$smarty->cache_dir = ‘/any_cache_path’;

$smarty->caching을 1이나 2로 설정해주면 된다.

// 캐시가 종료되는 시간을 $cache_lifetime에 설정된 값으로 결정
$smarty->caching = 1;
// 캐시가 종료되는 시간을 캐시가 생성될 때 기록된 cache_lifetime에 의해 결정
$smarty->caching = 2;

또한 $cache_lifetime은 기본적으로 3600초(1시간)로 설정되어 있으며, 0일 경우 항상 캐시를 다시 만들어내고 -1일 경우 명시적으로 캐시를 지우지 않는 이상 영속적으로 사용된다.

$smarty->cache_lifetime = 60; // 캐시 종료시한을 1분으로 결정
$smarty->cache_lifetime = -1; // 캐시 만료시한을 두지 않는다.
$smarty->cache_lifetime = 0; // 캐시를 항상 다시 만들어낸다(테스트할 때 유용).

Smarty는 캐시를 활성화시킨 뒤 템플릿이나 설정파일에 변화가 있을 때마다 새롭게 캐시를 생성하게 되는데 $compile_check를 false로 설정하면 템플릿이나 설정파일이 바뀌어도 이전의 캐시를 그대로 사용하게 되며, 이것은 실제 사이트를 운영할 때 약간의 성능 개선 효과를 준다.

// 템플릿, 설정파일이 바뀌어도 캐시가 갱신되지 않는다.
$smarty->compile_check = false;

그럼 여기서 캐시의 종료시한을 15분으로 설정하고 템플릿과 설정파일의 변화유무를 감지할 수 있도록 설정한 <리스트 2>를 살펴보도록 하자. 얼핏 보면 <리스트 2>에는 별 문제가 없어 보인다. 하지만 이 스크립트는 성능상으로 그다지 캐시의 효과를 얻을 수 없고 사이트의 갱신된 내용을 효과적으로 반영하지도 못하는데, 그 이유는 다음과 같다.

짾 첫째, 만약 $mode가 ‘list’인 상태라면 캐시가 되었든 안되었든 항상 데이터베이스에 접속해서 결과를 가져오는 루틴이 필요하다. 데이터베이스에 저장된 내용의 변화가 없는 상태라면 이런 동작은 할 이유가 전혀 없고, 귀중한 데이터베이스 서버의 리소스만 낭비할 뿐이다.
짿 둘째, 템플릿이나 설정파일의 변화는 캐시에 반영되지만 PHP 스크립트의 변화는 캐시에 반영되지 않으므로 막상 데이터베이스에 변화가 있다고 하더라도 사이트 방문자는 왜 새로운 글이 올라가지 않는지 화를 낼 것이다(운 나쁘면 15분 정도 기다려야 새로운 글이 게시판에 확인할 수 있을 것이다).
스크립트 내에서 캐시 행동 제어하기
먼저 필요 없는 데이터베이스 연결 루틴 부문을 캐시 유무에 따라 수행여부를 결정할 수 있도록 개선해 보자. 특정한 템플릿이 캐시가 되었는지 안되었는지는 is_cached($tpl_name) 메쏘드를 통해 알아낼 수 있다. 다음과 같이 하면 캐시가 된 상태에서는 쓸데없이 데이터베이스에 접속하지 않게 될 것이다.

if (!$smarty->is_cached(‘list.tpl’)) {
// 데이터베이스에 접속해 결과를 가져온다.
}
$smarty->display(‘list.tpl’);

그 다음에 clear_cache() 메쏘드를 이용하면 해당 템플릿의 캐시된 결과를 명시적으로 지울 수 있다. <리스트 3>은 이 두 개의 메쏘드를 이용해서 기존의 캐시를 사용할지 아니면 데이터베이스에 업데이트된 내용을 반영해서 새롭게 캐시를 만들어내야 할지 처리하는 스크립트이다.

템플릿마다 별도의 캐시를 만들어내고 제어하기
<리스트 3>을 보면 $mode가 ‘list’인 경우 리스트가 길어도 그냥 한 페이지에 다 출력한다. 그러나 게시판과 같은 기능을 구현할 때는 리스트를 일정한 길이로 잘라 페이지별로 보여줄 필요가 있다. 이런 경우 $page_num과 같은 별도의 변수에 따라 출력을 달리해서 출력해야 한다.

$smarty->display(‘list.tpl’);

같은 식으로 템플릿을 출력한다면 ‘list.tpl’에 대해 오직 하나의 캐시만을 가지기 때문에 제대로 된 페이지 네비게이션을 구현할 수 없게 된다. 마찬가지로 게시판에서 특정한 글을 읽는 동작 역시 다음과 같이 하면 ‘view.tpl’에 대해 오직 하나의 캐시만을 가지므로 게시판에 접속하는 사용자들은 언제나 같은 글만을 읽게 될 것이다.

$smarty->display(‘view.tpl’);

이것을 해결하는 가장 간단한 방법은 특정한 매개변수에 따라 변동이 심한 페이지 영역에 대해서 캐시 기능을 끄는 것일 테지만, 게시판과 같은 웹 애플리케이션에서 리스트를 보여주는 부분과 글을 읽은 부분에서 캐시 기능을 끄는 것은 사실상 캐시 기능을 사용하지 않겠다는 소리나 마찬가지이다. 지금까지 $smarty->display($tpl_ name)과 같은 형식으로만 템플릿을 읽어 들여 출력했지만, 사실 display() 메쏘드의 완전한 형식은 다음과 같다.

display($tpl_name, $cache_id, $compile_id);

여기서 $cache_id 매개변수를 달리 설정하면 같은 템플릿에 대해 별도의 캐시를 만들어줄 수 있다. ? 과 같은 코드는 같은 ‘list.tpl’에 대해 각각 다른 캐시를 만들어 내는데, ? 와 같이 하면 $page_num에 따라 별도의 캐시들이 생성하게 된다.

$smarty->display(‘list.tpl’, ‘1’); → ?
$smarty->display(‘list.tpl’, ‘2’); → ?
$smarty->display(‘list.tpl’, $page_num); → ?

이렇게 생성된 별도의 캐시들을 지우기 위해서는 clear_cache()를 display()와 같은 형식으로 호출하면 된다.

$smarty->clear_cache(‘list.tpl’, $page_num);

그러나 아쉽게도 이런 방법으로 진행해도 문제는 발생한다. 만약 게시판에 새로운 글이 올라온다면, 리스트와 관련된 모든 캐시를 지워줘야 하는데, 앞과 같이 캐시를 생성했다면 다음과 같은 코드로 캐시를 하나하나 지워줘야 할 것이다.

for ($i=0; $i < $page_total; $i++) {
$smarty->clear_cache(‘list.tpl’, $i);
}

이런 식으로 하면 캐시 제어가 너무 복잡해질 가능성이 있다. 하지만 관련된 페이지들을 묶어서 $cache_id로 표현할 수 있으므로 걱정하지 말기 바란다. 게시판의 예를 계속해서 들어보면, 게시판의 리스트나 글 조회로 인해 생성되는 캐시들은 ‘|’를 이용해서 다음과 같이 그룹핑해주는 것이 가능하다(‘|’로 그룹핑하는 깊이에는 한계가 없다).

$smarty->display(‘list.tpl’, “board|list|$page_num”);
$smarty->display(‘view.tpl’, “board|view|$id”);

만일 특정한 글이 수정되었다면 리스트에는 변동이 없을 테니, “board|view|$id”에 해당하는 캐시만 새롭게 생성해 주면 될 것이다.

$smarty->clear_cache(‘view.tpl’, “board|view|$id”);

그러나 새로운 글이 올라왔다면 리스트 전체에 해당하는 캐시를 갱신해 줄 필요가 있는데, 다음과 같이 “board|list|$page_num”에서 $page_num을 생략한 채 캐시를 clear_cache()를 호출해 주면 자동으로 ‘board|list’에 속하는 모든 캐시들이 만료된다.

$smarty->clear_cache(‘list.tpl’, ‘board|list’);
또한 게시판 전체의 모든 캐시를 깨끗이 지우고 싶다면 clear_all_cache()를 사용해도 어느 정도 비슷한 효과를 낼 수 있겠지만, 그것보다는 다음처럼 $tpl_name을 null로 지정한 채 clear_cache()를 호출하면 list.tpl과 view.tpl과 상관없이 ‘board’에 속하는 모든 하위 캐시들을 만료시키게 된다.

$smarty->clear_cache(null, ‘borad’);

캐시 핸들러 제작과 등록하기
앞에서 리소스들은 아무리 빠른 장치에 저장하더라도 그로부터 발생하는 성능상의 이득은 그렇게 크지 않다고 했다. 하지만 캐시의 경우는 저장하고자 하는 장치가 빠르면 빠를수록 좋다. 여건만 된다면 모든 캐시된 내용들을 메모리에 저장해 보는 것도 생각할 수 있다. 로컬 파일 시스템이 아닌 다른 저장소를 캐시로 이용하기 위해서는 $cache_handler_func에 적당한 캐시 핸들러 함수를 만들어 등록시키면 된다.

$smarty->cache_handler_func = ‘database_cache_handler’;

등록할 캐시 핸들러 함수의 레이아웃은 다음과 비슷한 모습으로 작성하게 된다.

function any_cache_handler($action, &$smarty, &$cache_content,
$tpl_file = null,
$cache_id = null,
$compile_id = null) {
switch ($action) {
case ‘read’: // 캐시로부터 캐시된 내용을 읽는 루틴
case ‘write’: // 캐시에 새로운 캐시 내용을 쓰는 루틴
case ‘clear’: // 캐시 내용을 삭제하는 루틴
default: // ‘read’, ‘write’, ‘clear’이외의 행동은 에러이다.
}
}

<리스트 5>는 Smarty 메뉴얼에 있는 MySQL용 캐시 핸들러 예제인데, 이것은 앞에서 소개한 캐시 그룹핑 기능을 지원하지 못한다. 따라서 앞에서 언급한 대로 캐시들을 하나하나 제거하는 루틴을 구현해 주거나 좀더 기능을 추가할 필요가 있다. $CacheId 이외에 $tpl_file, $cache_id, $compile_id를 나타내는 컬럼을 테이블에 추가한 뒤 그에 맞는 쿼리문을 수행하는 루틴을 핸들러에 삽입하면 될 텐데, 이것은 다음 시간까지 독자 여러분들의 숙제로 남기도록 하겠다(기본 캐시 핸들러의 알고리즘을 살펴보려면 ‘Smarty.class.php’를 참조하면 된다).

Smarty를 안전하게 실행시키기
Smarty는 템플릿 안에 {php}..{/php}나 {include_php}..{/include_ php}를 통해 PHP 코드들이 삽입돼 실행될 수 있다. 그리고 말한 적은 없지만 {if}..{/if} 동적 블럭문이나 변수 변환자에서 일반 PHP 함수를 사용할 수도 있다.
{if count($array) > 1}
..
{/if}
즉, 템플릿 내에서 이와 같은 문장을 사용할 수 있다는 의미인데, 여기서 물론 count는 템플릿 함수가 아닌 PHP 함수 count를 가리킨다. 이런 특징들은 잘만 사용되면 나름대로 편리함을 줄 수도 있겠지만, 편리함을 위해 여러분의 웹 사이트의 안전을 포기할 수는 없는 법이다. Smarty는 보안에 민감한 영향을 줄 수 있는 특징들을 템플릿에서 사용할 수 없도록 하거나, 또 신뢰할 수 있는 위치에 있는 템플릿만을 처리할 수 있도록 멤버 변수들을 설정해 줄 수 있다. 먼저 가장 기본적인 보안 관련 멤버 변수에는 $security가 있는데, 이것을 true로 하면 기본적으로 Smarty 템플릿 엔진은 다음과 같이 행동하게 된다(다음에 나오는 행동들은 $security_setting에 의해 조정될 수 있다).

◆ $secure_dir에 설정된 디렉토리들 밑에 있는 템플릿들만을 사용할 수 있다. (display(), fetch() 메소드와 {include} 템플릿 함수 등에서 이 값을 체크한다)
◆ 만일 $php_handling가 SMARTY_PHP_ALLOW로 설정되어 있으면, 이 값은 묵시적으로 SMARTY_PATH_PATHTHRU로 교체된다.
◆ {php}..{/php} 템플릿 함수는 허용되지 않는다.
◆ {if}..{/if} 동적 블럭문에서 $security_setting에서 허용하는 함수를 제외한 일반 PHP 함수를 사용할 수 없다.
◆ 변수 변환자에서 $security_setting에서 허용하는 함수를 제외한 일반 PHP 함수를 사용할 수 없다.

앞에 나오는 멤버 변수들을 하나하나 살펴보도록 하자. 우선 $secure_dir의 값은 허용할 템플릿 디렉토리를 다음과 같이 설정하면 되는데, 허용할 템플릿 디렉토리가 많다면 배열로 설정해주면 된다.

$smarty->template_dir = ‘/home/sizer/public_html/source/template’;
$smarty->compile_dir = ‘/tmp/site/localhost/compile’;
$smarty->security = true;
$smarty->secure_dir = ‘/home/sizer/public_html/source/template’;
$smarty->display(‘/home/sizer/public_html/source/not_allowed_template/index.tpl’);
$smarty->display(‘/home/sizer/public_html/source/template/index.tpl’);

허용되지 않는 템플릿을 포함하는 부분에서 다음과 같은 메시지를 볼 수 있다.

◆ PHP Warning: Smarty error : (secure mode) accessing “/home/sizer/ public_html/source/not_allowed_template/index.tpl” is not allowed in /usr/local/share/php/smarty/Smarty.class.php on line 595

두 번째로 $php_handling 멤버변수는 템플릿 내에 삽입된 {php}..{/php} 문장을 어떻게 처리할지 결정하는 함수로서 다음과 같이 네 가지 동작을 따른다.

짾 SMARTY_PHP_PASSTHRU : 해당 태그 내용을 있는 그대로 출력한다.
짿 SMARTY_PHP_QUOTE : 해당 태그 내용을 HTML 태그로 감싸 출력한다.
쨁 SMARTY_PHP_REMOVE : 해당 태그 내용을 삭제한다.
쨂 SMARTY_PHP_ALLOW : 태그 안에 있는 PHP 코드를 실행한다.

다음으로 $security_setting 멤버변수는 $security가 true로 설정된 상태에서 보안 수준을 결정할 수 있는 배열로서 다음과 같은 요소들을 가지고 있다.

◆ INCLUDE_ANY : true로 설정하면 $secure_dir에 있는 값을 무시한다. 기본 값은 false이다.
◆ PHP_TAGS : true로 설정하면 템플릿 내에서 {php}..{/php}를 사용할 수 있다. 기본 값은 false이다.
◆ PHP_HANDLING : true로 설정하면 $php_handling에 있는 값을 체크하지 않고 PHP 코드를 항상 실행한다.
◆ IF_FUNCS : {if}..{/if} 문에서 사용할 수 있는 함수들을 설정하며, 기본적으로 허용되는 함수로는 ‘array’, ‘list’, ‘isset’, ‘empty’, ‘count’, ‘sizeof’, ‘in_array’, ‘is_array’가 있다.
◆ MODIFIER_FUNCS : 변수 변환자에서 사용할 수 있는 함수들을 설정하며, 기본적으로 허용되는 함수는 ‘count’이다.

그리고 $trusted_dir이라는 멤버변수가 있는데, 이 변수로 설정한 디렉토리 밑에 있는 템플릿들은 {include_php}를 통해 PHP 코드를 실행할 수 있게 되는데, $secure_dir과 $trusted_dir에 같은 디렉토리가 중복되어 있다면 $secure_dir이 우선권을 가진다.

다음에는 스킨 메모장 제작
이번 호에는 리소스 플러그인과 캐시 제어법, 그리고 보안과 관련된 멤버변수들에 대해 알아보았다. 여러분들은 이제 Smarty 템플릿 엔진에 대해 대부분의 이론적인 지식을 쌓은 셈인데, 막상 Smarty를 이용해서 웹 사이트를 어떻게 구축할 것인가에 대해 고민이 될 것이다. 사실 필자도 아직까지 짙은 안개 속에서 방황하는 감이 없지 않았는데, 아무래도 Smarty를 이용한 실전 코드들이 아직 그렇게 많이 살펴보지 않은 탓이라고 생각한다(Smarty를 이용한 사이트나 웹 애플리케이션은 아직까지 그렇게 많지 않은 편이기도 하다). 약속한 커리큘럼을 따르려면 다음 호에는 Smarty를 이용해서 간단한 스킨 메모장을 만들어 봐야겠지만, 사정이 된다면 PEAR와 Smarty를 이용한 좀 더 큰 규모의 웹 사이트 구축 방법을 소개할지도 모르겠다.

2006/11/01 18:43 2006/11/01 18:43
이 글에는 트랙백을 보낼 수 없습니다
SELECT {...} FROM {테이블} WHERE {조건} LIMIT M, M+N
형식의 문법을 많이들 사용하실텐데..
전체 결과값을 구하기 위해 LIMIT를 제외한 앞문장에서 {...} 부분에 "COUNT(*)"을 써서 쿼리를 한 번 더 날려서 처리하곤 했습니다.
WHERE {조건}을 2번 처리해야 하는 비효율적인 코드를 남발했는데,
MySQL 4.0대에서 지원하는 Query Caching 기능의 일부로서 SQL_CALC_FOUND_ROWS가 들어간 문장에 대해 LIMIT와 상관없이 전체 결과값을 버퍼에 저장하고 FOUND_ROWS() 함수로 값을 가져올 수 있습니다.

검색 결과 리스트를 구할 때 아래와 같은 쿼리를 썼다면,

SELECT SQL_CALC_FOUND_ROWS
CI.cid, CI.sid, CI.ts, CI.perm, CD.title, W.wid, W.name
FROM ContentInfo CI LEFT JOIN ContentData CD USING (cid)
LEFT JOIN Writer W ON W.wid=CI.wid
WHERE INSTR(CD.title, '검색') OR INSTR(CD.body, '검색')
ORDER BY CI.ts DESC
LIMIT 0, 20

아래와 같이 LIMIT와 상관없는 전체 결과값을 얻을 수 있습니다.

SELECT FOUND_ROWS()


*주의: InnoDB 타입이 아닌 경우, 또는 동시접속이 많은 곳에서 TRANSACTION과 함께 사용하지 않을 때 제대로 작동할지 여부에 대해서는 아직 알아보지 못했습니다.

다른 데이터 베이스에서는 아직 미지원입니당 ~

참조 페이지입니다.
http://www.mysql.com/doc/en/Query_Cache_How.html
http://www.mysql.com/doc/en/SELECT.html
2006/10/09 10:40 2006/10/09 10:40
이 글에는 트랙백을 보낼 수 없습니다
Web_developing/PHP  2006/09/16 22:04
출처 블로그 > 행복이네 집
원본 http://blog.naver.com/prebetty79/100028415343

폼변수 다루기

  폼변수

   PHP 스크립트에서 폼 필드 값은 PHP 변수처럼 접근 할수 있다.

   3가지 방법이 있다.

     ex)

          $tireqty                                  //짦은 스타일

          $_POST['tireqty']                   // 중간 스타일

          $HTTP_POST_VARS['tireqty']  // 긴 스타일

    1. 짧은 스타일 : register_globals를 활성화 시켜야 쓸수 있다. (비추천)

                            지역변수와 혼란을 야기 한다. 4.2.0이후로 비활성화 되어있다.

    2. 중간 스타일 : 추천되는 방식(4.1.0이후에서만 가능)

    3. 긴 스타일 : 지양되어 왔다. 모든 버전에서 사용할수 있어 이식성은 높다.

                        성능에 좋지 않다. registre_long_arays로 비활성화 할수 있다.

식별자(Identifier)

dfe

  - 식별자는 변수의 이름을 말한다.

 - 길이 제한은 없으며 문자,숫자,'_', '$'로 만들 수 있다.

  - '$'는 가변변수때문에 조심해서 사용해야 한다.

  - 숫자는 매 앞에 올수 없다.

  - 대소문자를 구분한다.

변수형

: 변수의 형(type)은 저장된 데이터의 종류에 따라 정해진다.

   기본데이터형

     ■ Integer : 모든 숫자

     ■ Float

     ■ String

     ■ Boolean

     ■ Array

     ■ Object

     이 외에 NULL형과 resource형(외부자원 ex DB연결)이 있다.

형 강도(Type Strength)

PHP는 형 강도가 매우 약한다. 변수에 저장된 값에 따라 형이 결정된다.

     $a = 0;

     $a = 0.00;

       // $a는 처음엔 정수형이였다가 실수형으로 바뀐다.

     $a = 'Hello';  // 이것도 가능하다 이제 $a는 문자열이다

가변 변수(variable varialbes)

:  가변변수를 사용하면 변수의 이름을 동적으로 바꿀수있다.

  ex)

   $varname = 'b';

   $$varname = 5;

 

  위는 $b = 5 와 하는 것과 동일하다.

  

상수

  - 상수는 define 함수를 사용하여 상수를 정의한다.

    ex)

        define('TIREPRICE' , 100);

        define('OILPRICE', 10);

        define('SPARKPRICE', 4);  

  - 상수의 사용

     : 변수는 $를 붙이지만 상수는 상수의이름만 적어주면 된다.

    ex)

      echo TIREPRICE;


변수의 범위(scope) 6개의 범위를 가지고 있다.

- 수퍼글로벌 변수는 스크립트 전역에서 사용할 수 있다.

- 한번 선언된 상수는 스크립트 전역에서 사용할 수 있다. 즉 함수의 안과 밖 모두에서 사용할 수 있다.

- 전역변수는 스크립트 내에서 정의된 변수로 스크립트 내에서 사용할 수 있지만, 함수 안에서는 사용할 수 없다.  

- 함수 안에서 정의된 변수는 함수 내에서만 사용할 수 있다.

- 함수 안에서 전역으로 정의된 변수는 함수 밖에서는 사용할 수 없지만 매 사용 시마다 값이 저장되어 다음에 사용할 수 있다 ???

- 함수 안에서 사용된 변수는 함수가 끝나면 삭제된다.


수퍼글로벌 전체 리스트

  - $GLOBALS

  - $_SERVER

  - $_GET

  - $_POST

  - $COOKIES

  - $_FILES

  - $_ENV

  - $_REQUEST

  - $_SESSION



Operation(연산자)

대부분 C, Java랑 비슷하고 틀린부분만 정리

- 문자열 연산자   '.' : 문자열을 앞뒤로 붙여서 새로운 문자열을 만든다.

  ex)

     $a = "Bob's";

     $b = 'Auto Parts';

     $result = $a.$b;


   결과 $result에 저장된 값은 "Bob's Auto Parts"이다.

  - 산술 연산자

   : 산술 연산자의 operand(피연산자)는 정수와 실수형으로만 쓰일 수 있다. 만약 문자열로 산술연산을 시도한면 문자열을 숫자로 바꾸어서 실행한다. 문자열에 "e"나 "E"가 들어있다면 실수형으로 변화 한다. 그 외에는 정수형으로 변환. PHP는 문자열 처음에서 숫자를 찾아서 그것을 값으로 인식하는데, 만약에 문자열에 숫자가 없다면 문자열의 값은 0이 된다.


 - 참조 연산자(Reference)

   : C의 &연산자와 같음..

    ex) $a = 5

          $b = $a; --> $a, $b 서로 다른 메모리 영역을 가진다.


          $a = 5;

          $b = &a; 

          &b = 7    // $a, $b 서로 같은 메모리영역을 가진다 즉 $a, $b가 7


           unset($a)  : 서로의 참조를 다르게 한다 (관계를 떼어놓을 수 있다)


- 비교연산자(Comparison Operatiors)

     identical operator (===) : 두 피연산자가 값이 같고 같은형일 때만 true를 리턴한다.

     Not Identical (!==)  : != 와는 다르다

     Not Equal (<>) : 같지 않다. (!=) 와 같이 동일한 의미로 쓰인다.

- 에러 억제 연산자(error suppression operator) : @

    : '@'은어떠한 표현식에도 쓸수 있다.

    ex) $a = @(57/0)

     '@'가 없다면 위 문장은 "0으로 나누기"에 의한 에러가 발생하지만 '@'를 앞에 써주어서 에러는 무시하고 넘어간다. 만약 이런 방식으로 억제한다면 에러를 처리하는 코드를 작성해야 한다. 만약 PHP에서 track_error를 설정해 놓았다면 에러메시지를 전역변수인 $PHP_erromsg에 저장한다.


- 실행 연산자(execution operation)

 :  '`' 와 '`'로 이루어진 한 쌍의 연산자로 '`'는 홑따옴표(')와는 다른 키보드 ~아래에 있다.

   PHP에서 서버의 커맨드 라인에서 실행하고 싶은 것이 있다면 `` 사이에 명령어를 쓰면된다.

   그러면 ``의결과값이 표현식의 리턴값이 된다.

   EX)

      유닉스 환경

        @out = `ls -la`;

        echo '<pre>'.$out.'</pre>';

     그러면 시 디렉토리의 파일 리스트가 보이게 된다.


    

- 배열 연산자

   +       |    $a + $b    |  $a와 $b가 가지고 있는 모든값을 반환한다(합집합)

  ==       : $a, $b가 같은 요소를 가지고 있으면 true

  ===     | $a, $b가 같은 요소를 같은 순서로 가지고 있으면 true

  !=

  <>

  !==


변수와 관련된 함수

- 변수의 데이터 형을 검사하고 설정하기

 

      string gettype(mixed var);

         : 'boolean", "integer", "double", "string", "array", "object", "resource", 혹은 NULL을 반환한다. 표준 데이터 형이 아니면 "unknown"을 반환


      bool settype(mixed var, string type);


       ■ is_array()

       ■ is_double(), is_float(), is_real() (모두 같은 함수)

       ■ is_long(), is_int(), is_integer() (모두 같은 함수)

       ■ is_string()

       ■ is_object()

       ■ is_null()

       ■ is_scalar() - 변수가 스칼라 변수인지 확인한다. 즉 정수형, 불리어형, 문자열이나 실수형인지 확인한다.

       ■ is_numeric() - 변수가 숫자나 혹은 숫자 문자열인지 확인한다.

       ■ is_callable() - 변수에 저장된 값이 호출할 수 있는 함수의 이름인지 확인한다.


- 변수 상태 검사

   boolean isset(mixed var);

     : 이 함수는 변수의 이름을 인자로 받아서 만약 이 변수가 존재한다면 true를 반환한다.

      , 로 연결된 변수들을 주면 모든 변수가 존재해야 true를 반환

   boolean unset(mixed var);

    : 인자로 받은 변수의존재 자체를 없애고 true를 반환한다.

  empty(mixed var);

    : 변수가 존재하고, 비어 있지 않으며, 0이 아닌값을 가지고 있다면 true를 리턴

   

 - 변수형 변환

   int intval(mixed var[, int base]);  base :진수 (10, 2, 16)

   float floatval(mixed var);

   string strval(mixed var);

     

== 제어문 ==

 대부분 C와 비슷하지만, 틀린점만 요약하면

 

  1.  else if    -->  elseif  와 같이 붙여서 쓴다   

  2. 루프를 빠져나갈때 'continue', 'break' 이외에 'exit' 라는 제어문이 있다.

     'exit' : 루프를빠져나가 PHP 스크립트를 완전히 끝낸다.

  3. 대체 제어 구조

      { } 로 구역을 정하는 것이 아니라

        '{' 대신에 ':' 를 쓰고,

        '}' 대신에 사용한 제어구조에 따라, endif, endswitch, endwhile, endfor, endforeach를 쓸수있다.

     ex)

      if( $totalqty == 0 )

      {

           echo 'You did not ... ';

           exit;

      }

        를 아래와 같이 쓸수 있다.

      if( $totalqty == 0 ) :

           echo 'You did not ... ';

           exit;

      endif

   4. declare

     declare (directive)

     {

           // block

     }

       이 구조는 코드 블록에서 실행 지침(execution directive)를 설정하기 위해 사용된다.

       단 하나의 실행 지침인 tricks 만이 구현되어있는데 tricks=n이라는 방식으로 지침을 삽입할 수 있다. 코드 블록내에 있는 특정 함수 중 n개의 코드 행을 실행 시킬 수 있어 디버깅에 매우 유용한다.

2006/09/16 22:04 2006/09/16 22:04
이 글에는 트랙백을 보낼 수 없습니다
Web_developing/PHP  2006/09/13 12:21
array_change_key_case -- 모두 대문자나 소문자화된 문자열 키를 갖는 배열로 반환한다
array_chunk -- 배열을 여러 덩어리로 분산시킨다
array_combine --  키를 위한 배열과 값을 위한 배열을 각각 사용하여 배열을 생성한다
array_count_values -- 배열내의 중복된 키값의 개수를 배열로 리턴한다. [배열값]=>중복된갯수
  ::array array_count_values(array input)
array_diff_assoc -- 인덱스 검사와 함께 배열간의 차이를 계산한다
array_diff_uassoc --  Computes the difference of arrays with additional index check which is performed by a user supplied callback function
array_diff -- 배열간의 차이를 계산한다
array_fill -- 배열을 특정값으로 채운다
array_filter --  배열에서 두번째인자로 지정한 함수리턴값(TRUE,FALSE)에 맞는(TRUE)키값을 가진 키와키값을 골라 배열로 리턴.
  ::array array_filter(array input [,mixed callback]) 
array_flip -- 배열안의 모든 키를 각 키의 연관값으로 바꾼다.
array_intersect_assoc -- 인덱스 검사과 함께 배열의 중복을 계산한다
array_intersect -- 배열의 중복을 계산한다
array_key_exists -- 주어진 키와 인덱스가 배열에 존재하는지 확인한다
array_keys -- 배열의 모든 키를 반환한다
array_map --  Applies the callback to the elements of the given arrays
array_merge_recursive -- 두개 이상의 배열을 재귀적으로 병합한다
array_merge -- 인자로 주어진 배열들을 합한 배열을 리턴한다.
  ::array array_merge(array array1, array array2 [,array ..])
array_multisort -- 여러개의 배열 또는 다차원 배열을 정렬한다
array_pad --  설정된 길이만큼 특정 값으로 배열을 채운다
array_pop -- 배열 끝의 요소를 뽑아낸다
  :: mixed array_pop (array array)
array_push --  배열의 끝에 하나 이상의 원소를 넣는다.첫번째 인자인 배열끝에 두번째이후의 인자들을 추가한다.
  :: int array_push (array array, mixed var [, mixed ...]) 
array_rand --  배열안에서 하나 이상의 임의 원소를 뽑아낸다. srand()와 함께 사용하여 난수테이블을 초기화 해주는것이 좋다.
  리턴타입은 두번째 인자가 1일 경우 int 이고 2이상일경우에는 배열이다.
  :: mixed array_rand (array input [, int num_req]) 
array_reduce --  콜백 함수를 사용하여 배열을 반복적으로 단일 값으로 축소시킨다
array_reverse --  배열 원소를 역순으로 반환한다
  :: array array_reverse (array array [, bool preserve_keys])
array_search --  배열에서 주어진 값을 검색하고 성공하면 해당 키를 반환한다.존재하지 않으면 false(널문자)를 돌려준다.
  :: mixed array_search (mixed needle, array haystack [ , bool strict]
  예) $array = array(1,2,3,4,5,6); echo array_search(3, $array) ;
array_shift --  array_pop()과 반대되는 기능을 가지고 있고 배열에서 맨처음값을 삭제하고 삭제한 값을 리턴한다.
  :: mixed array_shift ( array array)
array_slice -- 배열에서 특정부분만 추출한 배열을 리턴한다. 두번째 인자는 시작할 인덱스이고 세번째 인자는 길이이다. 세번째인자가
     음수로 지정될 경우에는 역으로 진행된다. (0부터 시작한다)
  :: array array_slice ( array array, int offset [, int length])
array_splice --  배열의 일부를 삭제하고, 그 위치에 다른 내용을 대체한다
array_sum --  배열내의 값들의 합을 계산한다
  :: mixed array_sum (array arr)
array_udiff_assoc -- Computes the difference of arrays with additional index check. The data is compared by using a callback function.
array_udiff_uassoc -- Computes the difference of arrays with additional index check. The data is compared by using a callback function. The index check is done by a callback function also
array_udiff -- Computes the difference of arrays by using a callback function for data comparison.
array_unique -- 배열에서 중복된 값을 제거한다
array_unshift --  배열의 맨 앞에 하나 이상의 원소를 첨가한다.array_push()와 반대되는 기능을 하는 함수로서,두번째 이하 인자값을 배열에 추가하는데 기존 배열의 키는 뒤로 밀리게 된다.
  :: int array_unshift(array array, mixed var [, mixed ...])
array_values -- 배열의 연관배열을 스칼라 배열로 리턴하는 함수이다. 문자열키나 정수키는 무시되고 0 부터 순서대로 정수 인덱싱됨.
  :: array array_values (array input)
array_walk_recursive --  Apply a user function recursively to every member of an array
array_walk --  배열의 각 키와 값에 대해 두번째 인자로 지정한 함수를 실행케 한다. 세번째 인자는 이때 실해되는 함수의 인자로 쓰인다.
  ::int array_walk( array arr, string func [, mixed userdata])  (예제)
array --  배열을 생성한다
arsort --  배열을 내림차순 정렬하고 인덱스의 상관관계를 유지한다.
  :: void arsort(array array [, int sort_flags]) (예제) 
asort -- 배열을 오름차순 정렬하고 인덱스 상관 관계를 유지한다.즉 배열을 값에 따라 순서대로 정렬시키고 인덱스는 유지.
  :: void  asort(array array [, int sort_flages]) (예제)
compact --  주어진 인자를 변수명으로 갖는 연관배열을 리턴한다.변수명으로 배열변수명을 쓸수도 있다.
  :: array compact (mixed varname[,mixed ..]) (예제)
count -- 변수의 원소 갯수를 구한다
  :: int count(mixed var);
current -- 배열의 현재 원소를 반환한다.배열의 범위를 넘어서면 false를 리턴한다.
  :: mixed current(array array) 
each --  배열에서 현재의 키와 값 쌍을 반환하고 배열 커서를 전진시킨다
  :: array each (array array)
end --  내부 배열 포인터를 마지막 원소를 가리키게 한다
  :: mixed end( array array)
extract --  배열의 현재 심볼 테이블로 변수들을 입력한다
in_array -- 첫번째 이자가 두번째 인자로 주어진 배열의 원소로서 존재하는지 여부를리턴한다. 세번재 인자를 TRUE로 줄경우 데이타타입의 일치 여부까지 검사하게 된다. 리턴값을 false/true로 리턴하지 않고 true일경우 "1"을 false 일경우 널스트링""을 리턴한다.
  :: bool in_array(mixed needle, array haystack [, bool strict])
key -- 연관배열에서 현재 포인터의 키를 꺼낸다 . pos()와 current()는 현재 포인터의 값을 꺼낸다.
  :: mixed key (array array)
krsort -- 역순으로 키에 의해 배열을 정렬한다
  :: int krsort (array array [, int sort-flags]);
ksort -- 키에 의해 배열을 정렬한다
  :: int ksort (array array [, int sort-flags]);
list --  배열처럼 변수들을 지정한다.배열의 각 원소를 인자로 지정한 각 값들을 변수명으로 하는 변수값에 할당.
  :: void list (mixed ...)
  (예) $array = array('공부','노래',미술');  list('a','b','c')= $array;  결과) a=공부,b=노래,c=미술  
natcasesort --  대소문자를 구별하지 않고 "natural order" 알고리즘을 사용하여 배열을 정렬한다
natsort --  "natural order" 알고리즘을 사용하여 배열을 정렬한다.sort()와 비슷하나 sort()가 문자의 등장순으로 순서를 단순비교하여 정렬하는데 비해 의미론적 자연어 정렬을 가능케 해주는 특징이 있다.
  :: void natsort (array array) 
next --  배열의 내부 배열 포인터를 전진시킨다
pos -- 배열에서 현재 원소를 꺼내온다. current()의 alias 이다. 
prev -- 내부 배열 포인터를 앞으로 돌린다
  :: mixed prev (array array)
range --  특정 범위의 원소를 갖는 배열을 생성한다. low~high사이의 정수(또는 알파벳)를 원소로 하는 배열을 리턴한다.
  :: array range(mixed low, mixed high)
  (예) $array= range(5,9);  $array값이 {5,6,7,8,9}이다.
reset --  배열의 내부 포인터가 배열의 첫번째 원소를 가리키게 한다
  :: mixed reset (array array) 
rsort -- 역순으로 배열을 정렬한다.배열원소의 값을 기준으로 역정렬시킨다. 연관배열의 경우 스칼라 배열로 바뀌는 점 유의
  :: mixed rsort( array array [, int sort-flags]) (예제) 
shuffle -- 배열을 뒤섞는다.(주)다른 난수관련 함수들과 마찬가지로 srand()를 이용하여 시드의 초기화를 이뤄줘야한다.
  :: void shuffle( array array) 
sizeof -- count()의 별칭
sort -- 배열을 정렬한다.오름차순(0,1,2,3,4,....)
uasort --  사용자-정의 비교함수로 배열을 정렬하고 인덱스 연관성을 유지한다
uksort --  사용자-정의된 비교함수를 사용하여 키에 의해 배열을 정렬한다
usort --  사용자-정의된 비교함수를 사용하여 값들에 의해 배열을 정렬한다
2006/09/13 12:21 2006/09/13 12:21
이 글에는 트랙백을 보낼 수 없습니다
basename --  경로명에서 파일이름만 반환합니다
   :: string basename( string path [, string suffix])
  예) $path= $PHP_SELF ; echo basename($path);
chgrp -- 파일의 그룹을 변환합니다
chmod -- 파일의 모드 변경하고 성공여부를 리턴한다.

   :: int chmod(string filename, int mode);   첫번째인자는 경로명, 두번째인자는 10진수가 아니라 8진수이다.

chown -- 파일의 소유자 변경
clearstatcache -- 파일의 통계(stat) 캐시를 삭제합니다.
   :: void clearstatcache(void) 
     stat(),lstat(),file_exists() 등등의 statcaching-function을 사용후 다시 쓸일이 없다면 이 함수를 사용하여 리소스를 제거. 
copy -- 파일업로드시 많이 쓰이는 함수로 첫번째인자인 파일을 두번째 인자인 파일명으로 복사하고 성공여부 리턴한다.
   :: int copy( string source, string dest)
delete -- 실제로는 없는 명령
dirname -- 경로의 구성요소중에서 디렉토리 이름만 반환합니다.
   :: string dirname(string path)
disk_free_space -- 인자로 지정한 디렉토리의 남은 용량을 리턴한다. (원도우 버전에 오동작)
   :: float disk_free_space( string directory)
disk_total_space -- 해당 디렉토리의 총용량을 바이트 단위로 리턴한다.
   :: float disk_total_space( string directory) 
diskfreespace -- 디렉토리의 사용가능한 공간을 반환합니다. (리눅스,윈도우 정상동작)
   :: float diskfreespace( string directory)
fclose -- 열려있는 파일 포인터를 닫습니다.
feof -- 파일의 끝이 파일포인터에 있는지 테스트합니다.
fflush -- 출력결과를 파일로 보냅니다.
fgetc -- 파일포인터로부터 문자 가져오기. eof를 만나면 false를 리턴한다.
fgetcsv --  fgets()와 비슷한 용법을 가지나,일반 text파일에서 한라인씩 읽어오는데 반해 CVS파일의 한라인을 읽어서 두번째 인자로
    주어진 구분자를 기준으로 한 배열을 리턴하는데 차이가 있다. 두번째 인자 디폴트는 "." 이다.
   :: array fgetcvs(int fp, int length [, string delimiter]) 
fgets -- 파일 포인터에서 개행문자나 eof를 만날때까지 두번째인자인 byte수 만큼 읽어들인다.
   :: string fgets (int fp [, int length])
fgetss --  파일포인터에서 라인을 가져오고 HTML 태그를 없애기
file_exists -- 파일이 있는지 체크
file_get_contents -- Reads entire file into a string
file_put_contents -- Write a string to a file
file -- 파일전체를 한라인씩 배열로 읽어들임
   :: array file(string filename [, int use_include_path]) 
fileatime -- 최근에 파일에 최종 접근한 시간을 가져옴 (리턴형태는 unix_timestamp이다)
   :: int fileatime(string filename)
filectime -- 파일의 아이노드 변경시간을 가져옵니다 (리턴형태 unix_timestamp)
filegroup -- 파일의 그룹을 가져옵니다
fileinode -- 파일의 아이노드를 가져옵니다
filemtime -- 파일이 수정된 시간을 timestamp 값으로 리턴한다.
fileowner -- 파일의 소유자를 가져옵니다
fileperms -- 파일의 권한을 가져옵니다
filesize -- 파일의 크기를 byte단위로 리턴한다.
   :: int filesize( string filename) 
filetype -- 파일의 형식을 가져옵니다 (파일인지 디텍토리인지 구별하는 용도로 쓰일수 있다)
   :: string filetype (string filename)
flock -- 파일 잠김에 관한 간단한 도움말
fnmatch -- Match filename against a pattern
fopen -- 파일이나 URL을 엽니다
   :: int fopen(string filename, string mode [, int use_include_path])
fpassthru --  파일 포인터에 남아있는 모든 데이타를 출력하고 파일을 닫는다.
   :: int fpassthru(int fp) 
fputs -- 파일 포인터에 기록하기. fwrite()동일하다. 참고바람. 
fread -- 파일을 binary로 읽어온다. 모든내용을 읽고 싶다면 filesize()를 이용.
fscanf -- 형식에 따라서 파일로 부터 분석하여 입력하기
fseek -- 파일포인터를 두번째 인자로 지정한 위치로 옮긴다.
   :: int fseek (int fp, int offset [,int whence]) 
fstat --  오픈 파일 포인터를 사용하는 파일에 대한 정보 가져오기
   :: array fstat (int fp)
ftell -- 파일포인터의 읽기/쓰기 위치값을 리턴한다.
   :: int ftell (int fp) 
ftruncate --  주어진 길이로 잘라내기
fwrite -- Binary-safe 파일 쓰기 . fputs()와 동일하게 사용된다.
   :: int fwrite (int fp, string string [,int length])
glob -- Find pathnames matching a pattern
is_dir -- filename 이 디렉토리인지 아닌지 여부를 리턴한다.
   :: bool is_dir (string filename)
is_executable -- filename이 실행가능한 것인지 아닌지 이야기하기
is_file --  filename이 보통 파일인지 아닌지 이야기하기
is_link --  filename이 심볼릭 링크인지 아닌지 이야기하기
is_readable --  filename이 읽기 가능한 것인지 아닌지 이야기하기
is_uploaded_file -- file이 HTTP POST를 통해 업로드된 것인지 아닌지 이야기하기
is_writable -- filename이 쓰기가능한 것인지 아닌지 이야기하기
is_writeable -- Alias of is_writable()
link -- hard link 만들기
   :: int link(string target , string link) 
linkinfo -- 링크 정보 가져오기
lstat --  파일이나 심볼릭 링크에 관한 정보를 제공
mkdir -- 디렉토리 만들기
   :: int mkdir(string pathname, int mode)
move_uploaded_file -- 업로드된 파일을 다른곳으로 이동하기
parse_ini_file -- ini 확장자를 가진 파일을 열어 각 항목을 첨자로 하는 연관배열을 리턴한다.
   :: array parse_ini_file(string filename [,bool process_sections])
pathinfo -- 인자로 주어진 경로+파일명을 각 요소로 하는 연관배열을 리턴한다.
   :: array pathinfo (string path)
   예) [dirname][basename][extension]이와 같은 연관배열 형태로 출력한다.
pclose -- 진행되는 파일 포인터 닫기
popen -- 진행되는 파일 포인터를 열기
readfile -- 파일을 출력합니다
readlink -- symbolic link의 target 반환
realpath -- 웹경로가 아닌 실제 서버의 로컬경로를 리턴한다.
   :: array pathinfo( string path)
rename -- 파일을 새 이름으로 고치기
rewind -- 파일포인터의 위치를 되돌립니다(rewind).
rmdir -- 디렉토리 제거하기
set_file_buffer --  주어진 파일 포인터에 파일 버퍼링 설정하기
stat -- file에 대한 정보 제공
   :: array stat(string filename)
symlink -- 심볼릭 링크 만들기
tempnam -- 유일한 파일 이름 만들기
tmpfile -- 임시 파일 만들기
touch -- 파일의 수정시간을 설정합니다
umask -- 현재의 umask를 변경하기
unlink -- 파일을 삭제하기
2006/09/12 13:12 2006/09/12 13:12
이 글에는 트랙백을 보낼 수 없습니다
출처 블로그 > [스케치]
원본 http://blog.naver.com/tripsketch/3703720
=======================================================================
출처 : http://www.ricky.co.kr/jsboard/read.php?table=system&no=17&page=1
=======================================================================
[제목] 아파치 로그 파일 - 특이한 녀석들은 따로 담거나 없애기* 제목이 좀 이상하네요........^.^작성자 : 김칠봉 <san2(at)linuxchannel.net>작성일 : 2001. 04. 30대상자 : 초보- 힌트 URL : 임은재님이 쓴 글을 보고 나서   http://kltp.kldp.org/stories.php?story=00/10/22/9724184- 관련 문서 : 아파치 제공 문서   http://httpd.apache.org/docs/mod/mod_log_config.html   http://httpd.apache.org/docs/mod/mod_setenvif.html목차1. 배경2. 기초지식  2-1. 로그포맷과 CustomLog 지시자  2-2. 아파치 환경변수 설정3. 예제  3-1. 특정 IP 주소만 환경변수로 설정하기  3-2. 특정 타입의 파일만 환경변수로 설정하기  3-3. 특정 User-Agent 만 환경변수로 설정하기  3-4.  종합예제 : 사오정(?) 로그 분석 피하기------------------------------------------1. 배경몇 달 전부터 Webalizer 라는 로그 분석기로 제가(이하 '필자') 운영하는 싸이트의로그를 대충 분석(?)해 봤는데 사오정(?) 분석이 되어 버렸더군요.결정적으로 필자가 운영하는 싸이트의 대부분은 php로 구성되어 있는데, 이는 실제로 - 방문자 외에 localhost에서 php가 실행하는 로그 기록 - 로봇들의 접근 기록 - 운영자(필자)가 접근한 로그 기록 등등이 함께 기록되어 있어 순수 방문자 통계에 약간 덜(?) 정확한 통계가 나오더군요. 따라서 이런 유형들의 로그는 없애거나 따로 로그기록하는 것이 낫을 것 같더군요. 위의 내용이 이하 다루는 내용입니다.2. 기초지식2-1. 로그포맷과 CustomLog 지시자Module mod_log_config 은 아파치 기본 모듈입니다.    로그 포맷 스트링    %a : 원격의 IP 주소    %b : 헤더를 포함한 전송량(bytes)    %{var}e : 환경 변수 "var"    %f : 파일이름    %h : 원격의 호스트    %{hdr}i : 서버에 들어오는(요청) 헤더 값 "hdr"    %l : 원격의 로그인 ID(지원한다면)    %{label}n : 다른 모듈에서 "label" 구성    %{hdr}o : 응답 헤더 값 "hdr"    %p : 서버의 Canonical 포트 번호    %P : 자식 프로세스 ID(PID)    %r : 첫번째 요청 라인    %s : 상태코드    %t : 시간 포맷(CLF 포맷)    %{format}t : "format"으로 구성된 시간 포맷    %T : 서버에 요청하는 시간(초)    %u : 원격의 유저이름(인증시)    %U : 요청한 URL    %v : 클라이언트 요청에 따른 Canonical 서버네임    %V : UseCanonicalName 설정에 따른 서버네임일반적으로 아파치를 설치하고 나면, 다음과 같이 기본설정되어 있을 겁니다.(굳지 수정할 필요없음)    LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined    LogFormat "%h %l %u %t \"%r\" %>s %b" common    LogFormat "%{Referer}i -> %U" referer    LogFormat "%{User-agent}i" agent    CustomLog /usr/local/apache/logs/access_log common물론 이 정도는 다 알고 계시리라 믿습니다.    로그 기록 지시자    CookieLog    CustomLog    LogFormat    TransferLogCookieLogs는 제외하고 나머지 지시자에 대해서 알아봅시다.LogFormat 지시자Syntax: LogFormat format|nickname [nickname]Default: LogFormat "%h %l %u %t \"%r\" %>s %b"Context: server config, virtual hostStatus: BaseCompatibility: Nickname only available in Apache 1.3 or laterModule: mod_log_configCustomLog 지시자Syntax: CustomLog file|pipe format|nickname [env=[!]environment-variable]Context: server config, virtual hostStatus: BaseCompatibility: Nickname only available in Apache 1.3 or later.Conditional logging available in 1.3.5 or later.Module: mod_log_configTransferLog 지시자Syntax: TransferLog file|pipeDefault: noneContext: server config, virtual hostStatus: BaseModule: mod_log_configLogFormat 지시자는 앞에서 예제가 있으므로 생략하고 비슷한 기능을 가진CustomLog, TransferLog 지지자에 대해서 잠깐 알아봅시다.둘다 file 에 로그를 기록한다는 면에서는 동일한 기능입니다.(pipe 기능도 동일)    같은점    1. 둘다 file에 로그를 기록한다.    2. |pipe 에 설정한 외부 프로그램을 인자로 사용할 수 있다.    3. 둘다 다중 로그를 사용할 수 있다.    다른점    1. CustomLog 지시자는 LogFormat 지시자에서 설정한 nickname이나 Log format을        인자로 사용할 수 있다.    2. CustomLog 지시자는 환경변수를 인자로 가질 수 있다.따라서,이하 다룰 내용은 환경변수를 설정하고 이 환경변수(env)와 동일(=)하거나 그렇지 않은(!=)특정 유형에 대해서 로그에 기록해야하 하므로 당연히 CustomLog 지시자를 사용해야합니다.*주의)환경변수를 인자로 사용할 경우 하나만 가능.이해가 되셨는지 모르겠네요....2-2. 아파치 환경변수 설정아파치에서 환경변수를 설정하는 방법은 몇가지 있습니다.예를 들어,    - mod_env 모듈에 의한       SetEnv       지시자 이용    - mod_setenvif 모듈에에 의한       BrowserMatch       BrowserMatchNoCase       SetEnvIf       SetEnvIfNoCase       지시자 이용등이 있습니다.여기에서 주로 사용할 지시자는 BrowserMatch 지시자와 SetEnvIf 지시자입니다.*참고)xxxxNoCase 지시자는 대소문자를 구분하지 않겠다는 의미입니다.이 두개의 지시자에 대한 사용법만 간단하게 알아봅시다.BrowserMatch 지시자Syntax: BrowserMatch regex envar[=value] [envar[=value]] ...Default: noneContext: server config, virtual host, directory, .htaccessOverride: FileInfoStatus: BaseModule: mod_setenvifCompatibility: Apache 1.2 and above (in Apache 1.2 this directive was found in thenow-obsolete mod_browser module); use in .htaccess files only supported with1.3.13 and laterSetEnvIf 지시자Syntax: SetEnvIf attribute regex envar[=value] [envar[=value]] ...Default: noneContext: server config, virtual host, directory, .htaccessOverride: FileInfoStatus: BaseModule: mod_setenvifCompatibility: Apache 1.3 and above; the Request_Protocol keyword andenvironment-variablematching are only available with 1.3.7 and later; use in .htaccess files only supportedwith 1.3.13 and later   환경변수 지정 및 값 지정 방법   1.varname, or   2.!varname, or   3.varname=value   예 :   BrowserMatch ^Mozilla forms jpeg=yes browser=netscape   BrowserMatch "^Mozilla/[2-3]" tables agif frames javascript   BrowserMatch MSIE !javascript   BrowserMatchNoCase Robot is_a_robot   SetEnvIfNoCase User-Agent Robot is_a_robot   BrowserMatchNoCase mac platform=macintosh   BrowserMatchNoCase win platform=windows   SetEnvIf Request_URI "\.gif$" object_is_image=gif   SetEnvIf Request_URI "\.jpg$" object_is_image=jpg   SetEnvIf Request_URI "\.xbm$" object_is_image=xbm        :   SetEnvIf Referer www\.mydomain\.com intra_site_referral        :   SetEnvIf object_is_image xbm XBIT_PROCESSING=1   SetEnvIfNoCase Host Apache\.Org site=apache   SetEnvIf 지자자에서 attribute 에 올 수 있는 것들 :   Remote_Host - the hostname (if available) of the client making the request   Remote_Addr - the IP address of the client making the request   Remote_User - the authenticated username (if available)   Request_Method - the name of the method being used (GET, POST, et cetera)   Request_Protocol - the name and version of the protocol with which the request                                    was made (e.g., "HTTP/0.9", "HTTP/1.1", etc.)   Request_URI - the portion of the URL following the scheme and host portion   그외   Host, User-Agent, and Referer 가능   see http://www.rfc-editor.org/rfc/rfc2616.txt따라서,BrowserMatch와 SetEnvIf User-Agent 는 서로 동일하다는 것을 알 수 있을 겁니다.*중요)CustomLog 지자자와 다르게 환경변수 인자에 여러 개를 설정할 수 있음.여기까지 이해가 되셨다면 다음은 보지 않아도 될듯 하군요.......^.^3. 예제3-1. 특정 IP 주소만 환경변수로 설정하기- 환경변수 이름 : do_not_log- 목적 : 이 환경변수에 해당되는 특정 IP 주소는 access_log에 기록하지 않는다.    SetEnvIf Remote_Addr "^127.0.0.1$" do_not_log    SetEnvIf Remote_Addr "^211.35.159.12[89]$" do_not_log    SetEnvIf Remote_Addr "^211.35.159.1[345][0-9]$" do_not_log    위에서 설정한 특정 IP 주소는    127.0.0.1 자기자신을 말하는 루프백 주소    211.35.159.128, 211.35.159.129 두개의 IP 주소    211.35.159.130 ~ 211.35.159.139 10개의 IP 주소    211.35.159.140 ~ 211.35.159.149 10 개의 IP 주소    211.35.159.150 ~ 211.35.159.159 10 개의 IP 주소즉 원격의 IP 주소(Remote_Addr)가 위와 일치하면 do_not_log 환경변수에 지정하는 예임.*참고)^ 은 시작을 의미$ 은 마지막을 의미[0-9] 0~9까지의 숫자중 어느 하나3-2. 특정 타입의 파일만 환경변수로 설정하기    SetEnvIfNoCase Request_URI "\.(gif|jpg|png|css|js|java)$" do_not_log    요청 URI(Request_URI) 파일이    *.gif    *.jpg    *.png    *.css    *.js    *.java    로 끝난 파일인 경우(대소문자를 구별하지 않음) do_not_log 환경변수에 지정함3-3. 특정 User-Agent 만 환경변수로 설정하기- 환경변수 이름 : do_not_log 과 is_a_robot- 목적 : 이 환경변수에 해당되는 특정 User-Agent는 access_log에 기록하지 않고,             따로 로그(robot-log)에 기록하거나 기록하지 않기 위함.    BrowserMatchNoCase "ru-robot" do_not_log is_a_robot    BrowserMatchNoCase "Slurp/si" do_not_log is_a_robot    BrowserMatchNoCase "Mercator" do_not_log is_a_robot    BrowserMatchNoCase "Gulliver" do_not_log is_a_robot    BrowserMatchNoCase "SyncIT/" do_not_log is_a_robot    BrowserMatchNoCase "FAST-WebCrawler" do_not_log is_a_robot    BrowserMatchNoCase "Lycos_Spider" do_not_log is_a_robot    BrowserMatchNoCase "^ia_archive" do_not_log is_a_robot    BrowserMatchNoCase "^tv" do_not_log is_a_robot    BrowserMatchNoCase "Scooter" do_not_log is_a_robot    BrowserMatchNoCase "ZyBorg/" do_not_log is_a_robot    BrowserMatchNoCase "KIT-Fireball" do_not_log is_a_robot    BrowserMatchNoCase "Googlebot/" do_not_log is_a_robot    BrowserMatchNoCase "DIIbot/" do_not_log is_a_robot    BrowserMatchNoCase "teoma_agent3" do_not_log is_a_robot    BrowserMatchNoCase "empas_robot" do_not_log is_a_robot모두 로봇으로 맞게 설정되었는지 모르겠네요...............T.T각각의 정규표현식 조건에 맞는 User-Agent 인 경우, do_not_log 환경변수와is_a_robot 이라는 두개의 환경변수에 설정한 예입니다.is_a_robot 이라고 또 하나의 환경변수를 지정한 이유는 앞서 얘기했듯이이 조건게 맞는 User-Agent가 접근할 경우 따로 로그에 기록하기 위함입니다.이 BrowserMatchNoCase 지시자 대신에 SetEnvIfNoCase User-Agent 로 대신할 수 있는데첫번째 부분을 다음과 같이 설정할 수 있습니다.(둘다 똑 같은 결과임)    SetEnvIfNoCase User-Agent "ru-robot" do_not_log is_a_robot3-4.  종합예제 : 사오정(?) 로그 분석 피하기앞의 3개의 예제를 모두 적용하면 다음과 같습니다.목적은 배경에서 설명했듯이 가능한 access_log 파일에 - 방문자 외에 localhost에서 php가 실행하는 로그 기록은 기록하지 않는다. - 로봇들의 접근 기록은 따로 robot-log 파일에 기록한다. - 운영자가 주고 접근할 IP 주소는 로그에 기록하지 않는다. - *.gif, *.jpg, *.png, *.css, *.js, *.java 등과 같은 파일은 로그에 기록하지 않는다. 이 정도의 조건이라면 가능한 어느 정도 수준으로 순수 방문자의 접근 기록만 access_log 파일에 기록할 수 있습니다. -- httpd.conf(실제로 필자가 운영하는 아파치 설정 내용임) --------------------#### 중간 생략##LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combinedLogFormat "%h %l %u %t \"%r\" %>s %b" commonLogFormat "%{Referer}i -> %U" refererLogFormat "%{User-agent}i" agentLogFormat "%h %l %u %t \"%r\" %>s %b \"%{User-Agent}i\"" use_robot#### 중간 생략#### 환경변수 do_not_log에 일치하지 않은 접근만 access_log 파일에 기록함.##CustomLog /usr/local/apache/logs/access_log combined env=!do_not_log## 중간 생략## 로봇들은 따로 robot_log 파일에 user_robot 포맷에 맞게 기록함##CustomLog /usr/local/apache/logs/robot_log use_robot env=is_a_robot## 중간 생략## 특정 IP 주소는 로그에 기록하지 않는다.## 주로 서버 IP 주소와 운영자가 자주 접속하는 IP 주소들##SetEnvIf Remote_Addr "^127.0.0.1$" do_not_logSetEnvIf Remote_Addr "^211.35.159.12[89]$" do_not_logSetEnvIf Remote_Addr "^211.35.159.1[345][0-9]$" do_not_log## 중간 생략## 주로 이미지 파일을 요청했을 경우 로그에 기록하지 않는다.##SetEnvIfNoCase Request_URI "\.(gif|jpg|png|css|js|java)$" do_not_log## 중간 생략## 로봇들의 환경변수 지정##BrowserMatchNoCase "ru-robot" do_not_log is_a_robotBrowserMatchNoCase "Slurp/si" do_not_log is_a_robotBrowserMatchNoCase "Mercator" do_not_log is_a_robotBrowserMatchNoCase "Gulliver" do_not_log is_a_robotBrowserMatchNoCase "SyncIT/" do_not_log is_a_robotBrowserMatchNoCase "FAST-WebCrawler" do_not_log is_a_robotBrowserMatchNoCase "Lycos_Spider" do_not_log is_a_robotBrowserMatchNoCase "^ia_archive" do_not_log is_a_robotBrowserMatchNoCase "^tv" do_not_log is_a_robotBrowserMatchNoCase "Scooter" do_not_log is_a_robotBrowserMatchNoCase "ZyBorg/" do_not_log is_a_robotBrowserMatchNoCase "KIT-Fireball" do_not_log is_a_robotBrowserMatchNoCase "Googlebot/" do_not_log is_a_robotBrowserMatchNoCase "DIIbot/" do_not_log is_a_robotBrowserMatchNoCase "teoma_agent3" do_not_log is_a_robotBrowserMatchNoCase "empas_robot" do_not_log is_a_robot## 이하 생략##------------------------------------------------------END
2006/09/11 14:11 2006/09/11 14:11
이 글에는 트랙백을 보낼 수 없습니다
출처 블로그 > 정신없이 어디로 뛰어야 하는걸까?
원본 http://blog.naver.com/vhfpss/20002975774

* tomcat 4. 대까지 적용


앞으로 test 라는 context에서 작업 하고자 한다면.....

구조는 c:\Tomcat4.1\webapps\test 폴더를 하나 만드시고,
test\WEB-INF\classes 가 되도록 폴더 구조를 만드시면 됩니다.(WEB-INF 반드시 대문자)

그리고, server.xml 에서 268 라인 쯤에


<Context path="/test" docBase="test" debug="0" reloadable="true"/>


<Context path="/test" docBase="webapps/test" debug="0" reloadable="true"/>라고 하니깐 안되더군요...



라고 하시면 끝....reloadable="true"는 무엇이냐 하면, 소스 코드가 바뀌었을 때 Tomcat 를 껐다 켜지 않아도 자동적으로 리로드 되게 하는 것입니다.
그러나, 경험에 의하면 자동적으로 되긴 되는데 빨리빨리는 안된다는 말씀...ㅠㅠ;;

파일들이 가야할 위치는, 앞으로 작업하게 될 jsp, html 등은 test 밑에 있으면 됩니다.
그리고, servlet 이나 기타 .java 파일들, 즉 class 파일들은 test\WEB-INF\classes 밑에 가면 됩니다.

여기까지 하시고, 간단한 html 을 작성하여 test 밑에 두시고,
브라우저에서 호출할 땐, http://localhost:8080/test/hello.html 하시면 됩니다.....



* tomcat 5. 대 적용


1. 톰캣 어드민 페이지를 연다. 예)http://도메인:8080/admin

2. $TOMCAT_HOME/conf/tomcat-users.xml파일을 아래와 같이 수정


---------------------------------------------------------------------------------------

<?xml version='1.0' encoding='utf-8'?>
<tomcat-users>
  <role rolename="admin"/>
  <role rolename="manager"/>
  <user username="tomcatusername" password="tomcatpassword" roles="admin,manager"/>
</tomcat-users>

---------------------------------------------------------------------------------------

3. tomcat-users.xml에서 기재했던 사용자아이디와 패스워드를 이용 admin페이지에 로그인한다.

4. 오른쪽 상단에 commitchange버튼을 클릭한다.

5. $TOMCAT_HOME/conf/Catalina/localhost 디렉토리에 기존에 없던 ROOT.xml 파일이 생성된다.

6. ROOT.xml 파일을 자신이 원하는 디렉토리 경로로 변경하면 된다.


----------------------------------------------------------------------------------------

** default 설정 예)

<?xml version='1.0' encoding='utf-8'?>
<Context displayName="Welcome to Tomcat" docBase="/usr/local/tomcat/webapps/ROOT" path="" workDir="work/Catalina/localhost/_">
</Context>

----------------------------------------------------------------------------------------

----------------------------------------------------------------------------------------

** 변경된 설정 예)

<?xml version='1.0' encoding='utf-8'?>
<Context displayName="Welcome to Tomcat" docBase="/usr/local/tomcat/webapps" path="" workDir="work/Catalina/localhost/_">
</Context>

----------------------------------------------------------------------------------------


2006/09/11 14:07 2006/09/11 14:07
이 글에는 트랙백을 보낼 수 없습니다
목록보기 | 아파치 (70) 목록열기

[펌] httpd.conf 완벽 가이드! (비공개) | 아파치 포스트 삭제 2004/12/14 23:26
http://blog.naver.com/zeldign/40008797301
출처 카페 > windows 와 linux.. / 고슴도치
원본 http://cafe.naver.com/praying4u/22


 httpd.conf 파일은 크게 세부분으로 나누어져 있다.

   Section 1: Global Environment  : 아파치 전체적인 영향이 미치는 설정
   Section 2: 'Main' server configuration : 주 서버에 대한 설정
   Section 3: Virtual Hosts : 가상 호스트에 대한 설정

 자, 그럼 이제부터 이 아파치웹서버의 모든 환경을 설정하는 아파치환경파일 httpd.conf파일의 설정방법에 대해서 상세히 알아보도록 하자.


### Section 1: Global Environment

 전제환경설정 파트로 Section 1에서 설정하는 것들은 아파치 웹서버에
전반적인 영향을 미친다.

ServerType standalone

 서버의 구동방법으로는 standalone과 inetd방식이 있는데,  standalone
방식은 하나의 웹데몬(아파치서버)이 클라이언트의 접속을 모두 처리하는
방식으로 응답속도가 빠른 방법으로 주로 이방식을 사용한다. inetd 방식은
inetd라는 시스템의 /etc디렉토리 끝에 존재하는 inetd라는 슈퍼데몬이
클라이언트의 접속요구가 있을 때마다 웹서버를 구동하는 방식이다.
일반적으로 응답속도가 빠르고 효율적인 standalone으로 설정하여 사용한다.


ServerRoot "/usr/local/apache"

 아파치서버의 홈디렉토리를 지정하며 절대경로로 지정한다. 이후로 나오는
대부분의 패스들은 이 경로에 대한 상대경로로 지정이 된다. 예를 들어
환경설정파일, 에러로그파일등의 상대경로의 기준이 되는 위치이다.


LockFile logs/accept.lock

 아파치 컴파일시 USE_FCNTL_SERIALIZED_ACCEPT나
USE_FLOCK_SERIALIZED_ACCEPT으로 컴파일 했을 때 사용되는
LockFile의 경로지정시에 사용된다. 가급적 기본값으로 사용한다.


PidFile logs/httpd.pid

 PidFile 설정은 ServerType을 Standalone으로 설정했을때만 유효한
것으로 아파치 서버의 프로세스가 생성되어 있을 때 그 프로세서ID(PID)를
기록하는 파일을 지정한다.  당연히 아파치서버가 재시작되거나 과부하로
인해 PID가 바뀌게 될 경우에는 이 파일의 PID값도 바뀌게 된다.  즉
다시말해서 여기서 지정된 파일(httpd.pid)에 실행되고 있는 아파치서버의
프로세스번호(PID)값이 기록된다고 하면 정답이다. ServerRoot를 기준으로한
상대경로로 지정된다.  절대경로로 지정하려면 "/"로 시작하는 절대경로를
적어주면 된다.



ResourceConfig conf/srm.conf
AccessConfig conf/access.conf

 아파치 서버의 환경설정파일은 3개이au httpd.conf, srm.conf, access.conf
가 그것이다. 그러나 하나의 설정파일로 하는 것이 효율적이기 때문에
지금은 httpd.conf파일안에 3개의 파트(Section)로 나누어서 하나의
파일안에서 설정을 하고 있다. srm.conf와 access.conf파일의 내용은 현재
비어있는 상태이지만, 필요하다면 이 파일 내에도 설정을 할 수 있다.
아파치 서버가 실행이 될 때는 httpd.conf, srm.conf, access.conf 순으로
언제나 이 3개의 파일을 모두 읽고 난뒤에 실행이 되기 때문이다. 만약 이
두 개의 파일을 서버가 무시하도록 하려면 다음과 같이 하거나 "#"으로 붙여
두면 주석처리되어 무시된다.

ResourceConfig /dev/null
AccessConfig /dev/null


Timeout 300

 클라이언트의 요청에 의해 서버와 연결이 되었을 때 클라이언트와
서버간에 아무런 메시지가 발생하지 않았을 때 오류로 처리될 시간을
초단위로 설정한다. 초기값은 1200이며 보통은 300초로 지정을 한다.
네트웍의 속도가 나쁠수록 수치값은 높게 설정하는 것이 좋다.

KeepAlive On

 접속한 채로 특별한 요청없이 지속적인 연결을 허용할 것인지를 설정한다.
허용하지 않으려면 off

MaxKeepAliveRequests 100

 클라이언트가 접속된 시간동안 아파치서버에 요청할 수 있는 최대의
개수를 지정한다. 0을 지정하면 제한없음을 의미하며, 서버의 성능향상을
위하여 가능한 높은 값이 좋다.

KeepAliveTimeout 15

 아파치 서버는 같은 접속상태의 클라이언트에서 여기서 지정한 초만큼의
요청이 없었을 때 접속을 끊게 된다.

MinSpareServers 5
MaxSpareServers 10

 아파치 웹서버는 성능향상과 빠른 응답속도를 위해 유휴서버(현재
서비스대기 중인 프로세스)를 만들게 되는데 이 유휴서버의 개수는 시스템의
상황에 따라 달라지게 된다. 유휴서버가 MinSpareServers의 개수(5) 보다
적게되면 추가로 생성을 하게 되며 MaxSpareServers의 개수(10)보다 많게
되면 죽이게 된다. 즉, 유휴서버의 개수를 적절히 조절하기 위한 것이라
생각하면 된다.


StartServers 5  

 아파치 웹데몬이 구동될 때 자식프로세스를 몇 개로 할 것인가를
지정한다. 시작할 때 동시에 띄우게 될 웹데몬의 개수이다. 그러나 웹데몬이
구동되고 난 뒤엔 시스템의 상황(부하율등)에 따라 대부분 합리적인
개수만큼 동적으로 생성되었다가 죽기도 하므로 큰 의미를 가지는 것은
아니다.

MaxClients 150

 아파치웹서버에 접근할 수 있는 클라이언트의 최대갯수는 이 상한값으로
제한한다. 여기서 지정한 개수이상의 클라이언트의 요청이 생긴다면
아파치는 응답하지 않고 이 요청을 무시한다.  이를 제한하는 이유는
시스템의 자원을 아파치 웹서버가 무한정 차지하는 것을 방지하기 위한
것이다.

MaxRequestsPerChild 30

 아파치 웹서버의 자식프로세스들이 클라이언트의 요청 개수를 지정한다.
만약 자식프로세스가 이 값만큼의 클라이언트요청을 받았다면 이
자식프로세스는 자동으로 죽게된다. 이 값이 0으로 설정이 된다면
자식프로세스가 자동으로 죽는일은 없을 것이다. 그러나 0아닌 다른 값으로
설정함으로서 프로세스의 수를 적절히 조절하여 시스템의 부하조절과
자원낭비를 어느정도 방지 할 수 있다.

Listen 3000
Listen 12.34.56.78:80

 시스템의 기본값이외에 다른 IP Address와 포트에 대해서도 연결할 수
있도록 해 준다. 환경설정파일(httpd.conf) 맨뒤에 나오는 가상호스트(Virtual
Host)부분에서 설정되는 가상호스트를 설정하기 위해 필요하다.


BindAddress *

 서버가 응답할 수 있는 IP Address를 설정하는 것이다. 하나의 시스템에
있는 아파치웹서버 하나로 여러 웹서버처럼 관리하는 웹호스팅서비스등에서
많이 이용하는 것으로 여러 IP Address를 인식할 수 있게 한다. "*"으로
설정이 되었다면 모든  IP Address에 대해 응답할 수 있으며, IP Address를
지정한다면 지정한 IP Address에 대해서만 응답할 수 있게 된다.  여러개의
IP Address를 ISP로부터 할당받아서 웹호스팅서비스를 하고자 한다면
이부분에서 지정해 주면된다. 이 설정파일의 맨 뒷부분에 나오는
<VirtualHost>~</VirtualHost>부분의 IP bind 가상호스트부분에서 아파치
웹서버가 응답할 수 있도록 하려면 여기서 IP Address를 지정해 줘야 한다.

ExtendedStatus On

 server-status로 아파치웹서버의 상태를 상태를 모니터링 할 때
"자세한상태정보"기능을 제공할 것인지(On) 아닌지(Off)를 설정하는 것이다.

### Section 2: 'Main' server configuration

 Section 2에서 설정하는 항목들은 아파치의 주된서버가 사용할 값들을
지정한다. <VirtualHost>에 정의된 가상호스트들에서 지정하지 않는 것은
여기서 지정된 값이 기본값으로 적용된다. 또한 여기서 지정하는 값을 각
<VirtualHost>내에도 지정할 수 있으며 이경우엔 각<VirtualHost>내에서
지정한 값이 우선적용된다.

Port 80

 아파치웹서버의 기본포트를 지정한다. 특별하게 사용하는 것이 아니라면
80번으로 해둬야 한다. 사용가능한 포트는 0 ~ 65535이며 1024이하의
포트번호는 시스템에서 특별하게 예약되어 있으므로 80번 이외의 다른
포트를 사용하려면 1024이상의 포트번호를 지정해서 사용해야 할 것이다.
특별한 지정이 없다면 <VirtualHost>에 정의된 각각의 가상호스트들의
기본포트가 된다. 만약 <VirtualHost> 내에서 Port가 지정이 된다면 그
포트번호가 우선한다.

(특별히 PORT를 따로 지정해 줄 필요가 있을 때는 따로 지정해 주며,
이때는 웹서버로 접근할 때 반드시 따로지정한 PORT번호로 접근해야 한다.
예를들어 Port 1234로 지정했다면, 접근시 : http://www.domain.co.kr:1234
로 접속해야한다. 단, 80번은 default이므로 Port번호를 입력하지 않아도
도메인만으로 그냥 접근할 수 있다. 예: http://www.domain.co.kr )

User nobody
Group nobody

 아파치 웹데몬이 요청을 받았을 때 여기서 지정한 user와 group으로
응답을 하게된다. 이 설정은 ServerType이 Standalone방식이며, 아파치의
실행이 root권한으로 실행이 되었을 때 유효한 것이다. 많은
웹서버관리자들이 nobody로 설정을 해 두고 있으며, 만약 시스템에 nobody
user가 없다면 새로생성(useradd)을 해야 할 것이다. 단, root로 설정하는
것은 절대로 있어서는 안되며 nobody이외의 다른 시스템사용자 id로 지정을
한다면 정말 신중히 모든면(시스템 보안 및 자원사용등)에서 깊게 고려를
해봐야 한다.

ServerAdmin webmaster@www.domain.co.kr

 여기서 지정하는 email address는 웹문서 로딩에러등의 문제에서
클라이언트측으로 보내질 메일주소값이다. 대부분
웹서버관리자의 email address로 설정을 한다.

ServerName new.host.name

 클라이언트에게 보여주는 호스트이름을 지정한다. www를 쓰지않는
호스트에서 www를 쓰는 것처럼 보이게 할 수 있다. 예를 들어
bbs.manualand.co.kr을 www.manualand.co.kr로 지정해서 쓸 수 있다.
이곳에 IP Address를 적게 되면 클라이언트에는 Ip Address를 보여준다.

DocumentRoot "/usr/local/apache/htdocs"

 아파치 웹서버의 웹문서가 있는 경로를 지정한다. 예를 들어
"http://www.manualand.co.kr/index.html"의 초기 문서라면 이 초기문서의
절대 경로는 여기서 지정된 "/usr/local/apache/htdocs/index.html"이 된다.
경로의 맨 마지막에 "/"를 추가해서는 안된다. Alias를 사용하여 다른 위치를
지정할 수도 있다.

<Directory />
   Options FollowSymLinks
   AllowOverride None
</Directory>      
               

<Directory>에서 지정되는 값에 대한 옵션은 다음과 같은 의미를 가지고
있다.
       None : 일단 모든허용을 하지 않는다.
       All : 모든허용을 한다.
       Indexes :
       Includes :
       FollowSymlinks :
       ExeCGI :
       MultiViews :


UserDir public_html

 하나의 아파치 웹서버에서 여러 사용자의 홈페이지를 별도로 만들어
관리할 때 필요한 개별 가입자의 홈페이지 디렉토리이름이다. 예를 들어
sspark이란 계정가입자의홈페이지는 "http://manualand.co.kr/~sspark"라는
홈페이지를 가지고 있을 때 sspark의 계정에서 "public_html"이란
디렉토리가 홈디렉토리가 되어 이 디렉토리에 있는 초기문서 index.html을
불러서 보여주게 된다.

<Directory /home/*/public_html>
   AllowOverride FileInfo AuthConfig Limit
   Options MultiViews Indexes SymLinksIfOwnerMatch
IncludesNoExec
   <Limit GET POST OPTIONS PROPFIND>
       Order allow,deny
       Allow from all
   </Limit>
   <Limit PUT DELETE PATCH PROPPATCH MKCOL COPY
MOVE LOCK UNLOCK>
       Order deny,allow
       Deny from all
   </Limit>
</Directory>

계정사용자의 홈페이지(public_html)의 접근에 대한 옵션을 지정한 것이다.


DirectoryIndex index.html

 디렉토리만을 지정했을 경우에 그 디렉토리에서 찾게될 문서의 순서를
지정해 준다. 즉, 디렉토리 이름만을 지정하더라도 여기서 지정한
index.html을 찾아서 웹브라우즈에 보여준다. 여러개의 파일을 지정할 수
있으며, 이런 경우에는 순서대로 찾아서 보여준다. 예를 들어
"DirectoryIndex index.html index.htm"로 지정했다면 먼저 "index.html"을
찾아서 있다면 이 파일을 로딩하고, "index.html"이 없다면 "index.htm"을
찾아서 로딩해 준다.

AccessFileName .htaccess

 디렉토리별로 접근제어할 정보(ID, Password)를 담고 있는 파일을
지정한다. 디렉토리별로 인증을 거쳐서 접근할 수 있는 설정을 하기위한
것이다. 예를 든다면 어떤 홈페이지의 전부나 혹은 일부에로 접근하려고 할
때 ID, Password를 묻는 창이 뜨면서 맞게 입력한 경우에만 접근허용하는
것이다.  보안상의 이유로 이 파일의 이름을 다른 이름으로 바꾸로 싶다면
".htaccess"대신에 다름이름을 적어주면 된다.

<Files ~ "^\.ht">
   Order allow,deny
   Deny from all
</Files>

 바로위에서 설정한 파일(".htaccess")의 내용을 볼 수 없게 할 때 사용하는
옵션이다. 보안상의 이유로 이 옵션은 설정해 두는 것이 좋다. 만약 이
옵션을 주석처리해 둔다면 ".htaccess"파일에 대한 보안은 누구도 장담할 수
없을 것이다.


UseCanonicalName On


TypesConfig conf/mime.types

웹서버의 mime type을 지정한 파일을 지정한다. mime.types파일은 서버에
의해 리턴될 수 있는 파일명과 mime형식을 기술해 놓은 파일이다.

DefaultType text/plain

mime.types 파일에 정의 되어있지 않은 파일형식에 대한 요청을 받았을 때
알 수 없는 문서타입에 대하여 사용할 기본적인 mime 타입을 정해둔다.


HostnameLookups Off

 웹서버의 로그(access_log)를 지정하는 Format에서 "DNS Lookup"으로
지정하였을 때, domain으로 남길 것인가, IP Address로 남길 것인가를
지정한다. Default로 Off는 IP Address로 남기는 것이며, Domain으로 변경할
필요가 없으므로 on으로 설정한 것보다는 속도가 조금빠르다.on으로 하게
되면 IP address를 IP Domain으로 변환해야 하므로 속도가 조금 느릴 수
있다.

ErrorLog logs/error_log

 아파치 웹서버의 에러로그 기록파일을 지정한다.  참고할 사항은 맨
마지막에 설정하는 <VirtualHost>부분에서 각서버에 대한 에러파일을
지정해 두지 않으면 그에 대한 에러로그도 여기에 기록되며, 지정해 두게
되면 그에 해당하는 로그는 이 파일에 기록되지 않는다.

LogLevel warn

 바로위에서 설정한 에러로그 파일에 얼마나 자세하게 적을 것인지를
결정한다. 다음에 해당하는 순서대로 중요도가 정해진다. " debug → info →
notice → warn → error → crit → alert → emerg "

LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\"
\"%{User-Agent}i\"" combind
LogFormat "%h %l %u %t \"%r\" %>s %b" common
LogFormat "%{Referer}i -> %U" referer
LogFormat "%{User-agent}i" agent

 바로 아래에서 사용할 CustomLog에서 사용할 몇가지 로그형식의 별명을
정한 곳이다.
웹서버의 관리자나 서버관리자는 이 부분을 특히 유심히 봐둬야 한다.
웹서버의 로그를 어떤 식으로 남길 것인가를 결정하는 Format을 지정하는
곳이다. 원하는 정보를 지정해서 볼 수 있으므로, 관리자에게 필요한
Format으로 설정해야 하며, 또한 접속통계를 내기에 적당한 Format으로
설정해 둬야 한다.

CustomLog logs/access_log common

 위에서 정한 로그형식(여기선 common)대로 로그를 남기게 된다.
맨마지막에서 지정하는 <VirtualHost>부분에서도 아파치 1.3.9버전 부터는
CustomLog를 가상호스트별로 지정할수 있도록 CustomLog를 제공한다.
<VirtualHost>에서 CustomLog를 지정하지 않으면 여기서 지정한 형식대로
로그를 남기게 되며 <VirtualHost>부분에서 CustomLog를 지정했을
경우에는 여기서 지정한 로그형식은 무시된다.

#CustomLog logs/referer_log referer
#CustomLog logs/agent_log agent
#CustomLog logs/access_log combined

 위에서 지정한 4가지의 로그형식(combind, common, referer, agent)중에서
원하는 부분의 #(주석행)을 제거하면 지정된다.

ServerSignature On

 서버가 생성하는 문서(error documents, FTP directory listings,
mod_status and mod_info output etc., but not CGI generated documents)의
trailing footer line의 설정을 가능하게 한다.

Alias /icons/ "/usr/local/apache/icons/"

 필요한 만큼의 디렉토리 별칭을 만들어 쓸 수 있다. 사용하는 형식은
다음과 같다.
Alias fakename(가상이름) realname(진짜이름)

ScriptAlias /cgi-bin/ "/usr/local/apache/cgi-bin/"

 ScriptAlias는 서버스크립트를 포함한다. ScriptAlias는 실제디렉토리 안에
들어있는 문서를 서버에 의해 응용프로그램으로 취급되어 실행되는 것을
제외하고는 근본적으로 Aliases와 같다.


IndexOptions FancyIndexing

 IndexOPtions는 디렉토리목록을 표시할 때 사용할 옵션을 지정한다.
Standard는 표준적인 디렉토리를 나타내며, FancyIndexing은 좀더 예쁜
디렉토리목록을 표시해 준다.


 아래에서 지정하는 AddIcon으로 시작하는 설정은 바로위에서 설정한
디렉토리인덱싱 옵션을 FancyIndexing으로 한 경우에 해당하며 디렉토리
목록을 표시할 때 각 파일 확장자에 따라서 어떤 아이콘을 선택하여 보여줄
것인지를 지정한다.

AddIconByEncoding (CMP,/icons/compressed.gif) x-compress x-gzip
AddIconByType (TXT,/icons/text.gif) text/*
AddIconByType (IMG,/icons/image2.gif) image/*
AddIconByType (SND,/icons/sound2.gif) audio/*
AddIconByType (VID,/icons/movie.gif) video/*

AddIcon /icons/binary.gif .bin .exe
AddIcon /icons/binhex.gif .hqx
AddIcon /icons/tar.gif .tar
AddIcon /icons/world2.gif .wrl .wrl.gz .vrml .vrm .iv
AddIcon /icons/compressed.gif .Z .z .tgz .gz .zip
AddIcon /icons/a.gif .ps .ai .eps
AddIcon /icons/layout.gif .html .shtml .htm .pdf
AddIcon /icons/text.gif .txt
AddIcon /icons/c.gif .c
AddIcon /icons/p.gif .pl .py
AddIcon /icons/f.gif .for
AddIcon /icons/dvi.gif .dvi
AddIcon /icons/uuencoded.gif .uu
AddIcon /icons/script.gif .conf .sh .shar .csh .ksh .tcl
AddIcon /icons/tex.gif .tex
AddIcon /icons/bomb.gif core

AddIcon /icons/back.gif ..
AddIcon /icons/hand.right.gif README
AddIcon /icons/folder.gif ^^DIRECTORY^^
AddIcon /icons/blank.gif ^^BLANKICON^^


DefaultIcon /icons/unknown.gif

 여기서 지정한 확장가가 아닌 경우에 여기서 지정한 기본아이콘으로
보여준다.

AddDescription "GZIP compressed document" .gz
AddDescription "tar archive" .tar
AddDescription "GZIP compressed tar archive" .tgz

 AddDescription은 서버가 생성한 인덱스의 파일 뒤에 간단한 설명을
표시할 때 사용한다. 이 설정은 IndexOptions가 FancyIndexing으로
설정되었을때만 표시되며, 설정형식은 다음과 같다.
형식 : AddDescription "표시할 설명" 파일확장자

ReadmeName README

 ReadmeName은 디렉토리목록표시 뒤에 붙여서 보여줄 README파일의
이름을 지정한다.(일종의 꼬릿말)

HeaderName HEADER

 HeaderName은 디렉토리목록표시 앞에 붙여질 파일의 이름을 지정한다.
(일종의 머릿말)

IndexIgnore .??* *~ *# HEADER* README* RCS CVS *,v *,t

 디렉토리목록을 인덱싱할 때 제외할 파일명을 지정한다. 즉 디렉토리
목록에 포함하지 않을 파일을 지정한다. 쉘스타일의 와일드카드(*, ?)가
허용된다.

AddEncoding x-compress Z
AddEncoding x-gzip gz tgz

 AddEncoding은 특정브라우즈(Mosaic/X 2.1+)에서 받고있는 중에 정보에
대한 압축해제를 할 수 있도록한다. 단 모든 웹브라우즈에서 이 기능을
제공하는 것은 아니다.

AddLanguage en .en
AddLanguage fr .fr
AddLanguage de .de
AddLanguage da .da
AddLanguage el .el
AddLanguage it .it

 AddLanguage는 문서의 언어를 지정하게 한다.

LanguagePriority en fr de

 언어의 우선순위를 내림차순으로 지정한다.

AddType application/x-httpd-php3 .php3
AddType application/x-httpd-php3-source .phps
AddType application/x-tar .tgz

 AddType은 mime.types의 실제 편집없이도 mime을 설정할 수 있다.

AddHandler cgi-script .cgi

 AddHandler는 파일확장자를 처리기(Handler)에 매핑(연결)시켜주게 된다.

AddType text/html .shtml
AddHandler server-parsed  .shtml

 SSI(Server Side Include)문서를 인식하게 하기위한 설정이다. SSI코드가
들어가 있는 문서는 확장자가 *.shtml이다. 시스템의 날짜와 카운터등
CGI프로그램을 하지 않아도 HTML문서에서 단 몇줄로 CGI의 효과를 낼 수
있는 SSI기능을 인식하게끔 하는 설정이다. "7장. 아파치와 SSI"편에서 자세히
설명되어 있다.


#Format: Action media/type /cgi-script/location
#Format: Action handler-name /cgi-script/location

 Action은 매칭되는 파일이 호출될때마다 스크립트를 실행시킬 수 있도록
미디어 타입을 정의한다.

MetaDir .web

 MetaDir은 아파치가 찾을 메타정보파일들의 디렉토리이름을 지정한다. 이
파일들은 문서를 전송할 때 포함되는 HTTP 헤더정보가 포함되어 있다.

MetaSuffix .meta

 MetaSuffix는 메타정보를 포함하고 있는 접미어의 이름을 지정한다.


에러발생시 응답을 정의할 수 있는 방법을 3가지 나타내고 있다.

   1) 일반적인 텍스트

ErrorDocument 500 "The server made a boo boo.

   2) 지역적인 방향전환

ErrorDocument 404 /missing.html
ErrorDocument 404 /cgi-bin/missing_handler.pl

   3) 외부 방향전환

ErrorDocument 402
http://some.other_server.com/subscription_info.html


 다음의 BrowserMatch는 keepalives기능을 쓰지못하게 하며 HTTP
헤드방식을 설정한다.

BrowserMatch "Mozilla/2" nokeepalive

 이 설정은 Netscape 2.x 또는 이를 따르는 브라우즈에 대하여 KeepAlive
기능을 쓰지 못하게한다.

BrowserMatch "MSIE 4\.0b2;" nokeepalive downgrade-1.0
force-response-1.0

 이 설정은 잘못구현된 HTTP/1.1과 301또는 302반응에 대하여
KeepAlive를 적절히 제공하지 못하는 마이크로소프트 인터넷익스플로러
4.0b2d에 관한 것이다.

BrowserMatch "RealPlayer 4\.0" force-response-1.0
BrowserMatch "Java/1\.0" force-response-1.0
BrowserMatch "JDK/1\.0" force-response-1.0

 위의 3가지 설정은 기본적인 1.1반응도 처리하지 못하며 HTTP/1.0 스팩을
제한하고 있는 브라우즈에 대하여 HTTP/1.1반응을 하지 못하게 한 것이다.

<Location /server-status>
   SetHandler server-status
   Order deny,allow
   Deny from all
   Allow from www.manualand.co.kr
</Location>

 서버의 상태를 점검할 수 있게하는 설정이다. 이는
"http://www.manualand.co.kr/server-status"와 같은 형식으로 서버의 상태를
점검할 수 있다. "6장. 아파치서버 모니터링"편에서 자세히 설명되어 있다.
여기서 지정한 "SetHandler server-status"의 설정으로 인해 서버
모니터링을 할 수 있는 것이다.

<Location /server-info>
   SetHandler server-info
   Order deny,allow
   Deny from all
   Allow from www.manualand.co.kr
</Location>

 이설정을 위해서는 mod_info.c가 적재되어야 하며, 이는
"http://www.manualand.co.kr/server-info"와 같은 방식으로 서버의 정보를
볼 수 있다. 위에서 설정한 server-status와 함께 실행중인 웹서버의
상태점검을 위한 것이다.

<Location /cgi-bin/phf*>
   Deny from all
   ErrorDocument 403 http://phf.apache.org/phf_abuse_log.cgi
</Location>

 아파치 1.1이전 버전의 오래된 버그에 대한 악용이 있을시에는 지정한곳
(http://phf.apache.org/phf_abuse_log.cgi) 으로 방향을 전환시킨다.


<IfModule mod_proxy.c>
ProxyRequests On

 아파치 웹서버를 Proxy서버로 사용할 때 on을 해줘야 한다. 즉  
프락시서버 지시자로서 프락시서버를 on 시킨다.

<Directory proxy:*>
   Order deny,allow
   Deny from all
   Allow from .your_domain.com
</Directory>

ProxyVia On

 HTTP/1.1 "Via:"헤드처리를 활성화시킬 것인지 비활성화 시킬것인지를
지정한다. Off, On, Full, Block중 하나가 올 수 있으며 Full은 서버버전을
포함하며, Block은 나가는 모든 것에 대해 Via:헤더를 제거한다.

CacheRoot "/usr/local/apache/proxy"
CacheSize 5
CacheGcInterval 4
CacheMaxExpire 24
CacheLastModifiedFactor 0.1
CacheDefaultExpire 1
NoCache a_domain.com another_domain.edu joes.garage_sale.com

 이 설정은 캐시기능을 활성화 하기 위한 것이다.

### Section 3: 가상호스트 설정

 여러분의 시스템에서 여러개의 도메인이나 호스트네임을 설정하여
관리하고자 한다면 <VirtualHost>부분을 설정해 줘야 한다. 가상호스트에
대한 정보는 http://www.apache.org/docs/vhosts/를 참조해 보면 좀더
자세한 정보를 얻을 수 있다.  '-S'옵션을 사용함으로써 가상호스트의 설정에
대한 점검을 할 수 있다.  name-based 가상호스트를 사용하길 원한다면
적어도 한 개이상의 IP Address를 정의할 필요가 있다. "4-2절의 내용"과
"10장.웹호스팅 서비스를 위한 가상호스트"편에서 자세히 설명되어 있다.

NameVirtualHost 12.34.56.78:80
NameVirtualHost 12.34.56.78

<VirtualHost www.manualand.co.kr>
   ServerAdmin webmaster@manualand.co.kr
   DocumentRoot /home/sspark/public_html
   ServerName www.manualand.co.kr
   ErrorLog /home/sspark/public_html/aw/error_log
   CustomLog /home/sspark/public_html/aw/access_log common
</VirtualHost>

       ServerAdmin은 해당서버의 관리자 전자우편이며,
       DocumemtRoot는 해당서버의 홈디렉토리이며,
       ServerName은 해당서버의 도메인이며,
       ErrorLog는 해당서버의 에러파일 위치이며
       CustomLog는 로그파일위치와 포맷을 지정한 것이다.

<VirtualHost _default_:*>
</VirtualHost>

 Default 가상호스트 설정으로 위에서 설정되지 않은 다른 모든 호스트에
대해서 응답을 하고자 할 경우설정해 준다.

2006/09/11 13:37 2006/09/11 13:37
이 글에는 트랙백을 보낼 수 없습니다
출처 블로그 > xinfra님의 블로그
원본 http://blog.naver.com/xinfra/80008688603
/
인터넷 검색 사이트에서 특정 단어를 입력했을 때 검색 순위를 인위적으로 올려주는 업체들이 성행하고 있다.

이러한 기법은 불법이 아니고 워낙 교묘한 방법을 동원하기 때문에 포털 사이트들도 속수무책이다. 하지만 돈을 주고 인기 순위를 올리는 사이트가 늘어나면서 반대로 정상적인 사이트가 순위가 떨어져 피해를 입는 사례가 많아지고 있다.

아이뉴스24 * 2003/4/5 기사 중에서

검색결과 첫 페이지가 중요한 홍보 방법으로 알려지면서 소위 '상위등록'에 대한 관심이 높아지고 있다. 그에 따른 오해와 부작용도 함께.

검색결과 상위에 올라가려는 이런 노력을 한 쪽에서는 검색순위 조작이라고 비난을 하고, 다른 쪽에서는 정당한 마케팅 방법이라고 단호하다. 어느 쪽 말이 맞는 걸까?

결론부터 말하자. 검색결과 상위에 올라가려는 노력은 비난 받을 일이 아니다. 다만 적절한 선을 무시하는게 문제일 뿐이다. 스팸메일은 문제지만 이메일을 이용한 홍보 자체는 비난받을 일이 아닌 것 처럼.

포탈에 돈내고 광고 한 것은 괜찮고, 검색결과에 올라가려고 HTML 문서를 잘 꾸미고 키워드를 배치한 것은 비난 받아야 한다면 어딘가 굉장히 어색하다.

  • 홈페이지를 만드는 이유는 다른 사람에게 보여주기 위해서다.
  • 사람들은 검색엔진으로 필요한 정보(홈페이지)를 찾는다.
  • 그래서 홈페이지를 만들 때 검색엔진을 염두에 두고 만든다.
  • 이런 노력 자체에는 아무런 문제가 없다. 다만 일부 업체들이 마술사처럼 거짓말을 하거나 적절한 선을 넘는 것이 문제다.

    인기 키워드에 대한 집착만 버린다면 상위등록이 그리 어렵지 않다고 말하고 싶지만, 어떤 경우에는 부득이 전문업체에 상위등록 대행을 맡겨야 하는 경우가 있다.

    그동안 "믿을 만한 상위등록 업체"를 알려달라는 질문을 많이 받았다. 특정 업체를 지목할 수는 없다. 대신 좋은 업체를 고를 몇 가지 기준을 함께 생각해보자.

    첫째, '상위등록'이 아닌 '마케팅'을 말하는 업체

    엄밀히 말해서 상위등록과 검색엔진 마케팅은 다르다. 상위등록은 어떤 키워드에서든 높이 올라가면 그만이지만 마케팅은 고객을 부르고 상품을 파는 활동이다.

    검색결과에 먼저 나오는 것은 마케팅 전략의 한 부분일 뿐이다. 적절한 키워드 선정, 홈페이지 구성, 효과분석, 고객 흐름의 설계와 관리 등 종합적인 노력이 필요하다.

    검색엔진 마케팅을 하겠다면 조회수만 보고 엉뚱한 키워드를 공략하는 일은 무의미하다. 1000 트래픽(Traffic) 보다는 10명의 고객이 나은 법이다.

    검색순위 조작 능력을 자랑하는 업체보다는 마케팅 전략을 말하는 업체를 고르자.

    둘째, 고객 방문 그 이후를 말하는 업체

    고객은 움직인다. 키워드 검색을 하고, 사이트를 방문하고, 활동을 하고, 다시 찾아온다. 검색엔진 마케팅은 이 모든 고객 흐름을 염두에 두어야 한다.

    공략 키워드 선택에서 메뉴 이름까지 하나하나 연결 시켜야 한다.

    셋째, 합리적인 가격을 말하는 업체

    누구나 싼 가격에 흔들리기 마련이다. 그러나 마케팅을 할인 판매할 수는 없는 것이다. 검색엔진 마케팅은 저렴하지만 그래도 돈이 들어간다. 어떤 경우에는 스폰서링크 같은 광고를 해야하는 경우도 있다.

    타겟별로, 예산과 전략에 따라 가격은 다를 수밖에 없다. 때로는 유료 광고를 해야하는 경우도 있다. 공장에서 기계를 찍듯이 가격을 말하는 업체 보다는 합리적인 가격을 제시하는 업체를 찾자. 마술쇼를 하듯이 터무늬없는 가격을 부르는 곳도 마찬가지로 다시 살펴보자.

    넷째, 효과분석을 철저히 하는 업체

    검색결과 상위에 올라갔다고? 그게 그렇게 대단할까?

    • 트래픽은 얼마나 늘었는가?
    • 고객은 얼마나 늘었는가?
    • 매출은 얼마나 늘었는가?
    • 늘지 않는다면 그 이유는 무엇이고 어떻게 개선할 것인가?

    ROI(투자수익률)를 말할 수 없다면 투자는 의미가 없다. 로그분석에 효과분석까지 철저히 짚어주는 업체를 찾아보자.

    다섯째, 검색엔진 구석구석을 이용하는 업체

    통합 검색결과에 먼저 나오려면 디렉토리 상위등록이 중요하다. 그러나 디렉토리는 한계가 뻔한 곳이다. 먼저 나온다는 것 빼고는 차별화도 불가능하다. 자유로운 마케팅이 불가능하다. 웹페이지 검색, 스폰서링크 등 검색엔진 각 검색결과를 총체적으로 이용하는 전략이 필요하다.

    여섯째, 미디어 믹스(또는 마케팅 믹스) 전략을 말하는 업체

    당연한 말이지만 인터넷 마케팅에는 검색엔진만 있는 것이 아니다. 이메일, 입소문 등 다른 매체 전략과의 연계가 있어야 더 큰 효과를 발휘한다. 때로는 오프라인과의 연계도 필요하다.

    종합적인 마케팅 대행사를 찾으라는 의미는 아니다. 이런 총체적인 시각으로 전략을 구사할 줄 아는 곳을 찾으라는 의미다.

    일곱째, 장기 전략을 말하는 업체

    디렉토리 빠른 등록은 길어야 일주일이면 끝난다. 상위등록이 바로 될 수도 있다. 그러나 마케팅은 속전속결일 수 없다. 단기간에 이룰 수 있는 건 어떤 키워드에서 높이 올라간다는 사실 뿐이다.

    제대로 검색엔진 마케팅을 하려면 6개월 내외의 장기전 준비를 해야한다. 이런 정도 기간의 단계별 전략과 경험을 제시하는 업체를 찾아야 한다.

    ◆◇◆◇◆◇

    이런 업체를 찾기가 힘든가? 그렇다면 만나는 상위등록 업체에게 요구하라. 이제까지는 검색결과 첫 페이지 올리기로 충분했는지 모른다. 그러나 이제는 더 큰 효과로 더 큰 시장을 만들어야 한다.

    일부 업체들은 말한다. "제대로 하고 싶지만 고객들이 상위등록 요구만해서 마케팅 이야기는 엄두도 못내요."

    시장을 제대로 키우는 책임은 소비자에게도 있다. 업체를 비교하자. 없다면 요구하자.

    세상엔 많은 검색엔진이 있다. 사람들다마 각자의 성향에 따라 즐겨 사용하는 검색엔진도 다 다르다. 그 가운데서 유독 전세계적으로 많은 매니아층을 끌어 들이는 구글 검색엔진은 여러 가지 신선한 아이디어로 항상 매니아층을 흥분시키곤 했다. 비록 일반 사용자들이 야후, 네이버, 엠파스, 한미르 등을 더 많이 사용한다고는 하지만(구글의 사이트 순위), 어느 정도 검색 엔진에 조예가 있는 사람들에겐 언제나 구글은 동경심의 대상이었다.

    이러다보니 구글과 관련한 사이트들도 전세계적으로 상당히 많이 생겨났다. 이들 중에는 단순히 구글을 사랑하는 사람들이 만든 팬사이트 형식의 사이트부터, 구글 기술과 관련한 사이트, 구글 검색 결과의 상위에 노출되는 방법을 알려주는 사이트 등 여러 사이트들이 있다. 그만큼 애정을 가진 사람들이 많다는 것이다.

    오늘은 이런 사이트들 중 흥미있는 사이트를 하나 소개하도록 하겠다.

    사이트를 운영하는 사람치고 검색엔진 결과 리스트의 상위에 노출되고 싶지 않은 사람은 없을 것이다. 오늘 살펴 볼 사이트는 구글의 검색 스파이더가 사이트를 어떻게 해석하는지 잘 보여주는 사이트이다.

    푸들 프리딕터(Poodle Predictor)란 사이트인데, 이 사이트는 구글 검색엔진이 각각의 사이트를 어떻게 해석하는지 시뮬레이션 해주는 사이트이다.

    이 사이트에 가서 korea.internet.com으로 검색한 결과는 다음과 같다.

    이 검색 결과의 첫 번째 항목은 구글 검색 결과에 어떻게 나타날지를 시뮬레이션 해준 것이고, 그 아래 쪽 결과는 검색엔진이 수집한 해당 페이지의 모든 링크를 보여준 것이다.

    이번엔 구글 검색엔진에서 korea.internet.com으로 검색한 결과를 한 번 보자.

    푸들 프리딕터에서 검색을 한 경우와 구글에서 검색을 한 경우 검색 결과에 나타날 요약문이 거의 동일함을 알 수 있을 것이다.

    푸들 프리딕터 이럴 때 유용하다

    하지만 이 요약문이 서로 다른 경우도 많이 있다. 이것은 푸들 프리딕터는 해당 페이지의 실시간 결과를 보여주는 것이고, 구글은 과거에 수집한 내용을 기반으로 결과를 보여주기 때문이다.

    이것은 무엇을 의미하나? 그렇다. 만일 검색엔진에 나타날 결과를 예측하여 페이지를 수정하였는데 막상 구글 검색엔진에 반영되는데 걸리는 시간은 1달 이상 걸릴 수 있다. 그런데 1달이 지나고 나서 결과를 보니 예상했던 것과 다르다면 얼마나 난처한 일일까? 다시 결과를 바로 잡기 위해 1달을 더 기다린다? 이럴 때 푸들 프리딕터의 도움을 받을 수 있다. 푸들 프리딕터는 현재 페이지에 대한 실시간 결과를 시뮬레이션 해서 보여주기 때문에 향후 구글 검색엔진 결과에 어떻게 나타날지를 쉽게 예측할 수 있게 해준다.

    푸들 프리딕터의 사이트 바라보기

    앞서 푸들 프리딕터는 구글 검색엔진이 각각의 사이트를 어떻게 해석하는지 시뮬레이션 해준다고 하였는데, 과연 어떤식으로 시뮬레이션 해주는 것일까?

    아래 그림처럼 푸들 프리딕터의 결과 요약문 아래 있는 "Diagnostics View" 메뉴를 클릭해 보기 바란다.

    이 메뉴의 결과를 보면 검색엔진 스파이더가 어떻게 페이지를 해석하는지 잘 알려준다. 즉, 스파이더 입장에서 페이지 내용중 관심 없는 항목들은 과감히 생략하여 보여주기 때문에, 즉, 스파이더가 관심있는 항목들만 정리하여 결과를 보여주기 때문에, 검색엔진 마케팅을 위해 페이지를 어떤 식으로 수정하면 좋을지 시뮬레이션 하는데 많은 도움을 얻을 수 있을 것이다. 이 결과들을 보면서 자신의 홈페이지를 검색엔진 스파이더가 관심을 갖도록 바꿔보는 것은 꽤 흥미있는 일이 될 것이다.


    /

    "검색엔진들이 지식 검색에 열을 올리고 있다. 검색엔진의 미래와 어떤 관련이 있을까?"

    최근에 받았던 질문이다. 아주 오랜만에 포탈 검색 서비스에 변화가 생겼다. 반가운 일이다. 변화가 생기고 경쟁이 생겨야 사용자가 행복하고 소비자가 즐겁다. 그리고 산업과 기술도 발전한다.

    최근 검색엔진 변화에 불을 당긴 것은 네이버의 지식인(지식iN) 서비스(이하 지식인)이다. 네티즌끼리 질문과 답을 주고 받는 서비스로 네이버 검색결과에서 먼저 나타난다.

    네이버의 중고차 검색 결과

    ▲ 네이버의 '중고차' 검색 결과 처음

    2002년 10월에 시작해서 5개월만에 인기있는 서비스로 자리잡았다.

    • 하루 이용자 수 650만명에 40만 건 이상의 자료가 구축되었다.
      (네이버 발표)
    • 네이버 사용자 100명중 24명이 지식인을 이용한다.
      (인터넷메트릭스 2월말 조사)
    • 일반 검색에 비해서 두배 이상의 체류 시간을 보인다.
      (인터넷메트릭스 2월말 조사)

    이제 네이버 검색의 슬로건은 '지식까지 찾아주는 검색'이다.

    다른 포탈들의 움직임도 심상치 않다. 엠파스는 지식인의 원조격인 디비딕(DBDIC)을 인수해서 '지식거래소'라는 이름으로 통합을 추진하고 있다. 세이클럽은 세이테마(SayTheme)라는 서비스를 이미 시작한 상태이다. 다른 포탈도 비슷한 서비스를 한창 준비하고 있다.

    지식인 서비스 자체는 성공적이라고 할 수 있다. 화제로 떠오르고 사람들이 모이니 말이다. 그럼 아까 받았던 질문으로 넘어가 보자.

    "지식 검색을 검색의 미래로 볼 수 있을까?"

    이 바람을 일으킨 네이버 지식인을 검색의 관점에서 살펴보는 것이 답변의 출발이 될 것 같다.

    ■ 지식인이 성공한 이유

    잘 알다시피 지식인은 이 분야 최초의 서비스가 아니다. 2000년 디비딕이란 서비스가 이미 화제가 되었다. 그런데 요즘 새삼스럽게 네이버의 지식인이 인기를 얻는 이유는 무얼까? 서비스 자체의 장점 말고 바깥쪽의 관점, 즉 검색의 관점에서 살펴보자.

    1. 검색엔진과 연결되었기 때문이다.

    기존의 디비딕은 독립 서비스였다. 그러나 네이버의 지식인은 검색과 연결되어 있다. 검색과 연결되어 있지 않았다면 오늘의 성공은 없었을 것이다. 'SM5'로 검색한 사용자가 'SM5 랑 옵티마랑 둘 중에 어느거 살까여?'라는 질문을 발견했기 때문에 지식인이 성공하는 것이다.

    포탈은 수십, 수백개의 서비스로 이루어져 있다. 그동안 브랜드는 하나였으나 제각각 움직이고 있었다.

    네이버는 지식인을 별도의 서비스로 놔두지 않고, 검색이라는 끈으로 연결했다. 사실 포털이 그렇게도 되고 싶은 미디어(Media)의 열쇠 하나가 검색엔진이다. 미디어는 메시지이고, 메시지는 기본적으로 연결 고리가 필요하다.

    포털의 검색은 여러 서비스 중의 하나가 아니다. 검색은 서 말의 구슬을 꿰어 보배로 만드는 힘이다. 때로는 포탈 그 자체이다.

    2. 웹페이지 검색 정보가 부족하기 때문이다.

    웹페이지 검색의 정보가 부족한 것도 지식인 활성화에 도움이 되었다. 우리나라는 영어권에 비해 웹 정보가 부족한 편이다. 수량에서도 차이가 나지만 내용에 있어서도 분야별 편차가 다소 심하다. 작년 모 언론사와 함께 우리나라 개인 홈페이지를 조사할 기회가 있었다. 엔터테인먼트(영화, 게임 등)와 컴퓨터 분야는 다양했으나 정치, 경제 분야 같은 경우는 홈페이지를 찾기가 쉽지 않았다.

    안타깝게도 우리나라는 정보 소비자는 많지만 아직 상대적으로 정보 생산자는 적은 편이다. 이런 정보 소비자 중심의 구조는 웹페이지 정보 부족으로 곧바로 연결된다.

    또 하나 국내 검색엔진의 웹페이지(웹문서) 검색에 대한 게으름도 한 몫한다. 국내 검색엔진들은 웹페이지에 신경을 덜 쓰는 경향이 있다. 업데이트 주기, 스파이더의 개선 등 여러 곳에 아쉬움이 있다.

    웹페이지가 늘어나고 복잡해질수록 검색엔진도 함께 발전해야 한다. 국내 웹페이지 검색엔진 시장이 워낙 작기 때문에 개선을 위해 큰 비용을 계속 들이는 것이 쉽지는 않을 것이다. 그러나 운영과 관리도 소홀하다면 이야기는 다르다.

    통합검색과 테마검색(혹은 컨텐츠 검색)이라는 이름으로 서퍼들의 편집 부분에 노력을 기울이는 것도 중요하다. 그러나 웹페이지 검색을 사용하는 사람 역시 적지 않다. 이 둘은 서로 상호보완적인 영역이지 어느 한쪽을 완전히 대신할 수가 없다.

    3. 정리된 지식을 찾을 수 있는 행운이 있다.

    얼마전 진심반 시험반으로 해외 리조트(resort) 여행에 관한 질문을 올린 적이 있다. 질문을 올린지 하루만에 2건의 답변이 올라왔고 그 중 하나는 제법 만족스러운 것이었다. 그리고 "때가 어느 때인데 해외여행에 외화를 낭비하느냐"는 따끔한 충고도 덤으로 얻을 수 있었다.

    로봇에게 묻든 사람에게 묻든 우리가 원하는 것은 답을 얻는 것이다. 자동 로봇이 찾아온 결과는 대개 생자료(raw data)인 경우가 많기 때문에 그것을 비교분석하는 것은 사용자의 몫이다. 그러나 지식인의 검색결과는 완결된 답변의 형태로 돌아올 가능성이 상대적으로 높다.

    필자가 이것을 행운이라고 표현했다. 답변이 돌아올 것이라는 보장도, 그 답변이 정확할 것이라는 보장이 없기 때문이다.(이에 대해서는 뒤에서 더 다루기로 하자.)

    ■ 지식인은 검색이 아니다?

    그러나 지식인은 정확히 말해서 검색이 아니다. 지식인은 하나의 데이터베이스(DB)일 뿐이다. 지식인이 성공했냐고 물으면 '네'라고 말하지만, 지식인이 검색의 나아갈 방향이냐고 물으면 '아니오' 혹은 '글쎄요'라고 말하는 것이 맞다.

    기존에 디렉토리-웹페이지-뉴스 등으로 붕어빵 같던 데이터베이스에 Q&A 자료라는 신선한 내용이 더해진 것은 분명하다. 그러나 그것이 곧 검색 자체의 발전을 의미하는 것은 아니다.

    Q&A 라면 지식인보다, 디비딕보다도 더 다양하고 오래된 서비스들이 있다. 다음(Daum) 카페는 아주 훌륭한 데이터베이스이다. 분야별 커뮤니티가 좋은 자료들을 계속 생산해내고 있다.(그러나 안타깝게도 다음의 검색은 이 훌륭한 보물 창고를 크게 활용하지 못하고 있다) 그보다 훨씬 전에도 있다. 웹이 등장하기 이전부터 존재한 뉴스그룹이 있다. 아주 오랫동안 토론과 정보 교환의 장으로 애용되어 왔다. 다만 미국이 뉴스그룹 ▶ 웹 의 발전 단계를 거쳤던 것에 반해서 우리나라는 웹이 먼저 들어와 버려서 뉴스그룹이 크게 발전하지 못했다. (물론 지금은 미국도 뉴스그룹이 웹 인터페이스 속으로 많이 흡수되었다.)

    다음 카페 - 중고차 관련

    ▲ 다음(Daum)의 '중고차'관련 카페

    지식인은 데이터베이스이지 검색 자체가 아니기 때문에 검색의 미래로 볼 수 없다고 말했다. 그럼 검색 자체가 된다는 것은 어떤 의미일까? 여러 방법이 있겠지만 인터페이스와 검색 결과 관점에서 한가지씩 살펴보기로 하자.

    ■ 검색과의 통합 1 - 인터페이스

    앞서 필자는 '리조트'에 관한 질문을 예로 들었다. 좋은 답변도 얻었다고 했다. 그러나 여기서 아쉬운 점은 지식인에 '리조트'에 대해 물어보려면 별도의 서비스로 찾아들어가야한다는 점이다.

    필자는 이미 '리조트'로 검색을 한 상태다. 거기에서 검색결과를 살펴보았다. 그 검색결과는 이미 고정되어 있는 데이터베이스 자료(디렉토리, 웹페이지, 뉴스 그리고 지식인까지)에 있는 내용이다. 이미 만들어진 정보에서 없으니까 필자는 곧바로 '사람들'에게 묻고 싶다. 지식인에게 묻고 싶다.

    그러나 네이버 검색에는 지식인에게 현재 검색한 키워드(리조트)를 그대로 가지고 질문을 하게 해주는 연결이 없다.

      '리조트'에 대해서 '지식인' 사람들에게 직접 물어보시겠습니까?

    이렇게 되어 있다면 로봇과 사람이 결합된 검색 시스템으로 볼 수 있다. 로봇에게 묻든, 사람에게 묻든 사용자에겐 모두 검색 행위이기 때문이다. 그러나 현재의 지식인은 별도 서비스에서 만들어진 데이터베이스에 대한 검색결과 정도의 통합이다.

    (현재 하단에 비슷한 문장이 있기는 하지만 '검색결과 더 보기' 정도의 역할을 할 뿐이다.)

    ■ 검색과의 통합 II - 결과 순서

    지식인의 검색 통합에 관련된 또 하나의 문제는 검색결과의 순서다. 현재 지식인 검색결과는 거의 최상단에 나타난다. 그러나 과연 지식인 검색결과가 '언제나' 먼저 나올만큼 '언제나' 좋은 내용인지는 다시 생각해볼 필요가 있다.

    어떤 분이 '세계 최초의 검색엔진과 한국 최초의 검색엔진이 무엇이냐'는 질문을 했고 두 분이 답변을 했다. 그러나 두 분의 답변이 모두 틀렸다.

    세계 최초의 검색엔진은 야후(Yahoo)가 아니다. 웹검색의 경우라면 갤럭시(Galaxy)라는 검색엔진이 더 빨리 나왔고, 만약 웹 이전의 인터넷 검색을 생각하면 Archie나 Veronica가 더 앞선 검색엔진이다.

    사실 인터넷이 본질적으로 정보 신뢰성의 문제를 안고 있기는 하다. 별도 홈페이지는 진실이고 지식인만 틀리다고 이야기할 수는 없다. 그러나 검색엔진에서 검색 결과 순서는 정보의 정확성에 대한 묵시적인 약속이다. 더구나 지식인은 네이버 내부 서비스이다.

    때로는 일부 왜곡의 소지도 안고 있다. 상품명이나 쇼핑 관련 키워드에서 의도적인 '작업'이 가능할 것이다. 실제 어떤 키워드에서는 그런 현상이 보이기도 한다. 어떤 쇼핑몰에 대해 질문을 하고, 어떤 쇼핑몰이 좋다는 답변을 함으로서 자연스런 홍보를 하는 구조를 만들 수 있다는 의미가 된다.

    네티즌이 자체적으로 꾸며가는 사이트는 장점과 동시에 단점을 가진다. 활성화만 되면 많은 양의 정보가 생산되고, 전문성도 어설픈 전문 사이트보다 좋을 경우가 많지만, 동시에 악의적이고 편파적인 정보가 늘어날 가능성도 함께 높아진다.

    자원봉사자들에 의해 운영되는 세계에서 가장 큰 디렉토리 서비스인 오픈 디렉토리(Open Directory)도 같은 문제를 겪는다. 정보량은 오래전부터 세계 최고이고 너무나 멋진 서비스가 분명하다. 그러나 카테고리별로 편차가 있고 일관성도 가끔 부족한 단점이 있다. 자기가 아는 사이트를 높이 평가하고, 경쟁 관계에 있는 사이트에 대한 평가를 나쁘게 하는 경우도 없지 않다.

    사람과 시스템이 결합한 자체적인 정화 구조가 있기 때문에 계속해서 흐름을 유지하고 있다. 지식인의 경우도 정보의 신뢰성을 높이기 위한 여러 장치를 가지고 있다. 그러나 어쩔 수 없는 한계도 있다고 본다.

    그럴 경우 지식인의 노출 정도와 방법에 대한 고민이 더 필요하지 않을까?

    그런가하면 지나치게 가볍게 흐르는 게 아닌가하는 일부 우려도 있다. 재미있는 지식도 좋지만 검색은 목적이 분명한 행위이다. 그 자체를 즐기는 구조는 별도의 서비스이지 검색이 아니라는 시각이다. 또 일부에서는 '지식검색결과' 박스안에 광고(AD표시)가 섞여있는 것에 대해서 문제를 제기하기도 한다.

    ■ 진정한 지식 검색을 기다리며

    검색에서 늘 한발 앞선 모습을 보여주던 네이버가 이번에는 지식인으로 검색 서비스 경쟁에 새로운 불을 붙였다. 검색의 영역에 신선한 데이터베이스를 소개해 주었다. 후발 주자들이 어떤 모습으로 나타날지도 기대 된다.

    지식 검색이 데이터베이스 차원을 넘어서, 사람-사람의 검색 커뮤니케이션 채널로 발전해가길 바란다. 지금까지 웹이 보여준 단절적인 인터페이스를 벗어나서 검색이라는 행위 아래 단순하고 쉬운 인터페이스 아래 묶여지기를 바란다. 이제 메신저와 모바일도 유기적으로 연결되기를 바란다.

    검색엔진의 미래는 인터페이스, 미디어, 디바이스(Device), 메신저, 에이전트 등 몇 가지 키워드를 통해 한조각 한조각 퍼즐이 되어 우리 곁에 올 것이다.

    1994년 야후가 등장한지 올해로 꼭 10년이다. 변화의 퍼즐 한 조각이, 아니 훨씬 더 많은 조각이 우리나라에서 시작되기를 기대해 본다.

    스파이더는 웹사이트에 찾아가도 홈페이지 문서를 다 가져오지 않는다. 한 웹사이트에서 가져오는 문서수에 제한이 있다. 웹사이트의 중요도에 따라 수집 정도도 다르다. 전체를 수집하지 않는 것은 검색엔진의 성능도 관련이 있지만 쓸모없는 페이지들이 많이 섞여 있는 것도 한 이유가 된다.

    만약 여러분의 웹사이트에서 모든 파일이 다 수집되는 것이 아니라면 거기에도 신경을 써야 한다.

    ■ 스파이더는 움직이지 않는다 - 동적인 페이지(Dynamic Pages)

    옥션

    옥션(Auction.co.kr)의 경우를 보자. 어떤 검색엔진은 "?"가 들어가 옥션의 동적인 페이지를 하나도 수집하지 못했다. 수집한 곳들도 문서 수에서 큰 차이를 보이고 있다.

    HTML 파일을 미리 만들지 않고 ASP, PHP 같은 기술을 사용해서 필요할 때 즉시 만드는 방식이다. 게시판, 회원관리, 쇼핑몰 등에서 널리 쓰인다. 10만개의 상품이 있다고 10만개의 HTML 페이지를 만들어 놓을 수는 없는 일이다. 데이터베이스와 연결해서 필요할 때마다 페이지를 만들면 관리가 편리하다. 디자인을 바꾸기도 쉽다.

    그러나 어떤 검색엔진은 이런 동적인 페이지를 잘 읽지 못한다. 정확히 말하면 페이지를 읽지 못하는 것이 아니라 주소(URL)를 읽지 못하는 것이다. 일반적으로 동적인 페이지의 주소 형식은 아래와 같다.

    http://www.web.com/bbs.cgi?db=file

    검색엔진은 ‘?’ 표시에서 문제를 일으킨다. http://www.website.com/bbs.cgi 까지만 보게 되는 것이다. 보통 데이터베이스 프로그래밍을 할 때 ?, #, +, % 같은 기호는 충돌을 일으키기 때문에 피하는데 검색엔진 역시 관련된 문제가 있다.

    http://www.web.com/cgi-bin/my1.htm

    또 한 주소 안에 CGI 관련 폴더(cgi-bin,cgi 등) 있는 경우도 문제가 생긴다. 데이터베이스와 연결된 곳에 들어갔다가 무한대의 자료를 읽는 문제가 생길 수 있기 때문에 미리 멈추는 것이다.

    검색엔진들이 이 문제를 해결하고 있어서 상황은 많이 좋아졌다. 그러나 어느 검색엔진 운영자의 말을 들어보자.

      “동적인 페이지는 게시판과 같이 중요하지 않은 내용들이 많다. 그리고 주소 방식이나 내용이 금방 바뀌어서 사용자가 찾아가면 전혀 다른 내용이 있는 경우가 많다. 물론 뉴스 사이트처럼 다른 경우도 있다. 사이트 상황에 따라 판단할 수 밖에 없다. 무한정 수집하기가 힘들다.”

    한 사이트에서의 동적인 페이지 수집 비율을 제한하는 경우가 있다는 것이다.

    여러분의 동적인 페이지가 등록될지 미리 정확히 알 수 있는 방법은 없다. 비슷한 방식의 페이지를 사용하는 다른 웹사이트가 어떻게 등록되어 있는지를 살펴보는 것이 가장 좋은 방법이다.

    ○ 스파이더를 생각한 대책

    답은 의외로 단순하다. 주소 방식에서 문제가 생기니까 주소 방식을 바꾸는 것이다. 서버 관리자의 도움을 받아서 해결할 수 있다.

    [ASP]

    웹사이트가 ASP(Active Server Pages)를 사용하고 있다면 아래의 사이트를 참고해서 주소 방식의 변화를 준다.

    [아파치 웹서버]

    아파치 웹서버를 사용한다면 ‘rewrite’ 모듈(mod_rewrite)로 주소방식을 바꿀 수 있다. 이 모듈을 사용해서 아파치 컴파일을 다시 하면 검색엔진에 좋은 주소 방식이 된다.

    ○ 최고의 해결책

    검색엔진 홍보에 중요한 페이지는 반드시 독립적인 HTML 페이지(Static Pages)로 만든다. 서버 설정에 손을 대지 않더라도 반드시 일반 형식의 주소(?,&표시 없는 URL)를 따라 따만들어 놓자. 최소한 각 메뉴의 메인 페이지 정도는 만들어 놓는 것이 좋다. 그래야 동적인 페이지를 읽지 못하거나 동적인 페이지 수집 비율 제한에 걸리지 않을 수 있다.

    스파이더는 웹사이트에 찾아가도 홈페이지 문서를 다 가져오지 않는다. 한 웹사이트에서 가져오는 문서수에 제한이 있다. 웹사이트의 중요도에 따라 수집 정도도 다르다. 전체를 수집하지 않는 것은 검색엔진의 성능도 관련이 있지만 쓸모없는 페이지들이 많이 섞여 있는 것도 한 이유가 된다.

    만약 여러분의 웹사이트에서 모든 파일이 다 수집되는 것이 아니라면 거기에도 신경을 써야 한다.

    2006/09/11 13:37 2006/09/11 13:37
    이 글에는 트랙백을 보낼 수 없습니다
    출처 카페 > wsdcafe / ??
    원본 http://cafe.naver.com/wsdcafe/22
    #####################################################################
      #
      # 다음 한글화된 설정 파일은 Apache 1.3.12을 위한 것입니다.
      #
      # 번역         : 이 만 용 <yong@linuxkorea.co.kr>
      # 수정 및 추가 : 김 정 균 <admin at oops.org>
      #
      # 번역 상의 오류나 더 매끄러운 번역을 위한 제안 사항은 언제나
      # 환영합니다.
      #
      #####################################################################
      #
      # 베테랑 아파치 서버 관리자들에게 보내는 메시지)
      # -----------------------------------------------
      #
      # 아파치 설정 파일은 전통적으로 httpd.conf, srm.conf, access.conf
      # 이렇게 3 개로 구성되어 있다.  그러나 내부적으로는 3 개의 파일에
      # 대한 구별을 하지 않고 순차적으로 읽어나갈 뿐이다.
      #
      # 3 개의 파일 내용은 관례적인 것일 뿐이다.  아파치 신 버전부터는
      # 모든 설정 내용이 하나의 거대한 파일 httpd.conf에 들어 있고 나머지
      # 두 파일은 빈 파일로 제공되고 있다.
      #
      # 이런 사실을 알아두기 바란다.
      #
      #####################################################################
      #
      # 팁하나!)
      #
      # 1) 문제가 발생했을 때에는 httpd.conf (srm.conf, access.conf) 설정
      #    파일의 문법을 제대로 지켰는지 먼저 점검하고 다른 아파치 관리자
      #    들에게 도움을 요청하는 것이 좋습니다.
      #
      #    /usr/sbin/httpd 명령에 -t 옵션을 주면 문법만 점검합니다.
      #    기타 다른 옵션에 대하여 알고 싶을 때에는 -h 옵션을 사용하십시오.
      #
      #    예1) 문제가 없는 경우
      #
      #    # /usr/sbin/httpd -t
      #    Syntax OK
      #
      #    예2) 설정에 실수가 있는 경우
      #
      #    #/usr/sbin/httpd -t
      #    Syntax error on line 91 of /etc/httpd/conf/httpd.conf:
      #    ServerType must be either 'inetd' or 'standalone'
      #
      #####################################################################
      #
      # Rob McCool 씨의 NCSA 서버 설정 파일에 기초한 것임.
      #
      # 이 파일은 아파치(Apache) 서버 주 설정 파일이다.  이 파일에 들어있는
      # 설정 지시자(directive)를 통해 서버의 작동 방식을 지시한다.
      # 각 지시자에 대한 자세한 정보를 원하면 http://www.apache.org/docs를
      # 참고하라.
      #
      # 정확한 이해 없이 대충 읽어나가는 일이 없도록 하자. 여기에 적은
      # 내용을 그대로 여러분의 상황에 적용시키려 하지 말라.  다음 내용은
      # 실제 지시 내용을 위한 힌트라고 생각하자.  내용에 대하여 의문이
      # 있을 때에는 온라인 문서를 참조하라.  이 사실에 대하여 지금 여러분
      # 에게 충분히 경고해두었음을 밝히는 바이다.
      #
      # 아파치 서버는 이 파일을 읽고 난 후, /home/httpd/conf/srm.conf
      # 파일을 처리하고 그 다음 /home/httpd/conf/access.conf 파일을
      # 읽는다. 지금 현재 이 설정 파일에서 ResourceConfig, AccessConfig
      # 지시자를 사용하여 설정 파일 이름을 바꾸면, 변경된 이름의 설정 파일을
      # 읽는다. (여기서 /home/httpd 부분은 아파치 서버의 기본 디렉토리로
      # 대체하여 생각하면 된다.  예를 들어 여러분이 직접 아파치를 컴파일하여
      # 설치하는 경우에는 일반적으로 /usr/local/apache 가 된다.)
      #
      # 지시자는 3 개의 기본적인 섹션으로 묶여 있다:
      #  1. 아파치 서버 프로세스의 전반적인 작동을 제어하는 지시자
      #     ('global environment, 전체 환경')
      #  2. 가상 호스트에 의해 처리되지 않는 요청을 모두 처리하는 주 서버
      #     또는 기본 서버의 작동을 제어하는 지시자.
      #     이 지시자 내용은 모든 가상 호스트의 기본값이기도 하다.
      #  3. 다른 IP 주소 또는 다른 호스트 이름에 대한 요청을 처리할 가상
      #     호스트 설정
      #
      # 설정 파일과 로그 파일 이름 : 만약 파일 이름이 "/"로 (또는 Win32
      # 버전의 경우 "드라이브명:/" ) 시작하면 주어진 파일 이름 그대로를
      # 사용한다. 그러나 "/" 로 시작하지 않을 때에는 ServerRoot 의 값이
      # 그 앞에 추가된다. 따라서 "logs/foo.log"는 ServerRoot 값 (예를
      # 들어 "/usr/local/apache")이 앞에 추가되어 서버는 최종적으로
      # "/usr/local/apache/logs/foo.log"를 사용한다.
      #####################################################################

      ### 섹션 1 : 전체 환경 (Global Environment)
      #
      # 이 섹션에 적힌 지시자는 예를 들어 아파치 서버가 처리할 수 있는
      # 동시 요청의 갯수라든지 다른 설정 파일의 이름 등 아파치 서버의
      # 전반적인 작동에 영향을 미친다.
      #

      #
      # 서버 유형(ServerType)은 inetd 또는 standalone 둘 중 하나이다.
      # inetd 방식은 유닉스 플랫폼에서만 지원된다.
      #
      ServerType standalone

      Server의 Type을 지정하는 것으로, standalone은 httpd 데몬 프로세스가
      사용자의 요청을 처리하는 것이고, inetd는 inetd 데몬프로세스가 처리하게
      하는것이다. web demon처럼 사용자의 query가 많을 때는 standalone이 더
      효율적인 방법이다.

      #
      # 서버 루트(ServerRoot) : 서버의 설정 파일, 에러 파일, 로그 파일이
      # 기록되는 디렉토리의 최상위 경로명.
      #
      # 주의! 만약 서버 루트를 NFS (또는 기타 네트웍 파일 시스템) 마운트된
      # 곳에 두고자 한다면 LockFile 문서를 꼭 읽어보아야 한다.
      # (<URL:http://www.apache.org/docs/mod/core.html  #lockfile>);
      # 문서를 읽고 나면 앞으로 닥칠 지 모르는 몇 가지 문제점을 피할 수
      # 있다.
      # 디렉토리 경로 뒤에 슬래쉬(/) 문자를 쓰지 않는다!!!
      #
      ServerRoot "/etc/httpd"

      Apache 설정 file에서 사용될 경로중 상대 경로의 기준을 위해서 정해
      진다. Web의 Root directory와는 상관이 없다. DSO의 지원으로 인하여
      ServerRoot의 상대 경로를 주의있게 설정해야 한다. Alzza 에서는 DSO
      module들의 절대 경로가 /etc/httpd/modules 가 되므로 아래의 DSO
      쪽의 상대 경로와 틀어지지 않게 조심해야 한다.

      #
      # LockFile 지시자는 아파치를 USE_FCNTL_SERIALIZED_ACCEPT 또는
      # USE_FLOCK_SERIALIZED_ACCEPT 옵션을 주고 컴파일한 경우, 잠금
      # 파일을 경로를 지정할 때 사용한다.  이 지시자 값은 일반적으로 기본
      # 값이 되도록 놔둔다.  이 값을 바꾸는 경우는 로그 디렉토리가 NFS
      # 마운트된 곳에 있는 경우로서 잠금 파일은 항상 네트웍 파일 시스템이
      # 아닌 로컬 디스크에 저장되어야 하기 때문이다.  주 서버 프로세서의
      # PID 값이 자동으로 파일 이름 뒤에 붙는다.
      #
      #LockFile logs/accept.lock

      #
      # PidFile: 서버가 시동될 때 자신의 프로세스 고유 번호를 기록할 파일
      #
      PidFile /var/run/httpd.pid

      #
      # ScoreBoardFile: 내부 서버 프로세스 정보를 기록하는데 사용하는 파일.
      # 모든 아키텍쳐에서 꼭 필요한 것은 아니다.  하지만 필요하다고 생각하는
      # 경우에는 하나의 아파치 프로그램을 두 번 이상 실행시키는 경우 값이
      # 중복되지 않도록 해주는 것만 잊지 않으면 된다.
      #
      ScoreBoardFile logs/apache_runtime_status

      #
      # 표준 설정에서 서버는 httpd.conf, src.conf, access.conf 파일을
      # 차례대로 읽어나간다.  나중에 있는 2 개의 파일은 현재 아무 내용도
      # 없는 빈 상태로 배포되고 있다.  왜냐하면 모든 지시자를 그냥 하나의
      # 파일에 적는 것이 더욱 명료하기 때문이다.  주석으로 처리되어 있는
      # 값은 기본값이다.  서버가 이 파일 내용을 무시하도록 하기 위해서는
      # "/dev/null" (유닉스의 경우) 또는 "nul" (Win32) 값을 지정한다.
      #
      #ResourceConfig conf/srm.conf
      #AccessConfig conf/access.conf

      #
      # Timeout: 받기/보내기 타임 아웃 시간
      #
      Timeout 300

      클라이언트가 정보를 받을때까지 소요되는 대기시간의 최대값을
      지정한다. 쉽게 말해서 요청한 url이 없을 경우 error message가
      뜨기 까지의 시간이다. 네트워크가 응답이 늦을 수록 수치를 늘리는
      것이 좋다.

      #
      # KeepAlive: 지속성(persistent) 접속을 허가할 것인가 말 것인가?
      # (한 번의 접속에서 여러 개의 요청을 처리할 것인가 여부)
      # 허가하지 않기 위해서는 "Off"로 설정한다.
      # 허가하지 않는 것과 허가하는 것과의 효율 차이는 매우 크다.
      #
      KeepAlive On

      HTTP 1.0에서는 요청이 일어날 때마다 client와 Server간에 새로운
      연결이 만들어 지는데 이 설정으로 인하여 하나의 연결에서 여러
      요청이 가능하므로 요청을 처리하는 시간을 증진 시킨다. 이 기능을
      끄려면 off로 한다.

      필자의 경험상의 생각은 대형 site일 경우에는 이 기능을 끄기를
      권장한다. 이 기능을 Off를 시킬 경우에 system의 부하가 상당히 늘어
      나는 것을 느낄수는 있으나 Web상의 속도에서는 속도가 On일 경우보다
      더욱 빠르다는 것을 체감할수 있다. 즉 Web Server만을 돌린다면 Off로
      하는 것을 권장하며 여러 서비스를 할 경우에는 On으로 하라는 의미이다.
      참고로 이런 것을 체험할 정도의 대형 서비스란 하루 웹로그가 1G이상
      쌓이는 경우를 의미 하며 왠만한 site에서는 이 부분에 대해서 신경을
      쓰지 않아도 상관이 없다.

      #
      # MaxKeepAliveRequests: 지속성 접속 기간 동안 처리할 수 있는 최대
      # 요청 갯수 0 을 넣으면 무한대이다.  높은 성능을 내기 위해서 높은 값을
      # 추천한다.
      #
      MaxKeepAliveRequests 100

      접속된채로 특별한 요청이 없음에도 계속 연결을 유지시킬 수치를 지정
      한다. 값이 너무 크면 하나의 client가 Server의 resource를 독점 할 수
      있으므로 적당 하게 잡는 것이 좋다.

      #
      # KeepAliveTimeout: 같은 접속 상태에서 같은 클라이언트의 요청이 타임
      # 아웃되는 시간 (초 단위)
      #
      KeepAliveTimeout 15

      #
      # 서버 풀(Server-pool) 크기 조정.  몇 개의 프로세스가 필요한지 여러분
      # 에게 추측하도록 하기 보다는 현재의 부하 상태에 자동으로 적응하도록
      # 되어 있다. 아파치 서버는 현재의 부하 상태와 순간적으로 급격히 상승
      # 하는 경우 값 (예를 들어 하나의 네스케이프 브라우져에서 동시에 여러
      # 개의 요청이 들어올 수 있다)을 처리할 수 있는 충분한 갯수의 서버
      # 프로세스를 유지하려 노력한다.
      #
      # 아파치 서버는 주기적으로 몇 개의 서버가 요청 대기 상태인지 점검한다.
      # 만약 MinSpareServers 보다 적다면 여유 서버 프로세스를 생성한다.
      # 만약 MaxSpareServers 보다 많으면 불필요한 여유 프로세스를 제거한다.
      # 이 곳에 제시된 기본값은 거의 대부분의 사이트에 적합하다.
      #
      MinSpareServers 8
      MaxSpareServers 20

      httpd 데몬프로세스의 child 프로세스에 대해 MinSpareServers보다
      작으면 새로운 프로세스를 생성하고, MaxSpareServers보다 많으면
      여분의 프로세스를 죽이는 것을 지정한다.

      #
      # 처음 시동할 때 만들 서버의 갯수 -- 합리적인 근사치여야 한다.
      #
      StartServers 10

      httpd 서버를 처음 실행시킬때, 여분의 프로세스를 생성시킬 수치를
      지정한다. 반응 시간을 짧게 하기 위해 StartServers항목에서 말하는
      만큼의 Server process를 이미 만들어 두는 것인데, 실제로
      Service를 하고 있지 않을 경우에는 잠자고 있으므로 System에
      부하를 주거나 하지는 않는다.

      #
      # 서버 프로세스의 최대값, 즉 동시에 접속할 수 있는 클라이언트 갯수를
      # 제한하는 값이다. -- 만약 이 값에 도달한다면 클라이언트의 요청은
      # 봉쇄될 것이다.  따라서 이 값이 너무 낮아서는 안된다.  이 값은
      # 아파치 서버가 너무 많은 자원을 소비하여 전체 시스템을 먹통이 되도록
      # 하는 것을 방지하기 위해 사용될 뿐이다.
      #
      MaxClients 150

      동시에 접속할 수 있는 Client의 수를 지정한다.

      #
      # MaxRequestsPerChild: 각 자식 프로세스가 죽기 전까지 처리할
      # 수 있는 요청 갯수.  한 프로세스가 너무 오랫 동안 사용되면 메모리
      # 누출이나 자원 누출(아파치 때문에 또는 잘못된 라이브러리 때문에)
      # 이 발생할 수 있으므로 자식 프로세스는 자동으로 죽는다.  대부분의
      # 시스템에서는 필요치 않으나 솔라리스에서와 같이 라이브러리에서의
      # 자원 누출 현상을 막기 위해 필요하다.
      #
      MaxRequestsPerChild 100

      child 프로세스가 응답할 수치를 지정한다. 대부분의 system에서는
      이 기능이 필요 없다. 다만 Solias와 같은 몇몇의 system에서는 이
      기능을 지정해 줘야 하는 듯 하다.

      #
      # Listen: 아파치를 기본값 이외에도 특정 IP 주소 또는 포트에 연결
      # 하도록 해준다.  <VirtualHost> 지시자도 참고하라.
      #
      #Listen 3000
      #Listen 12.34.56.78:80

      Virtual host설정에 관한 부분이다. Virtual Host에 관한 사항은 Name
      Server와 관련이 있으므로 따로 강좌를 하게 될 것이다.

      #
      # BindAddress: 이 옵션을 사용하여 가상 호스트를 지원할 수 있다.
      # 이 지시자를 이용하여 서버가 귀기울일 IP 주소를 지시할 수 있다.
      # "*", IP 주소, 또는 완전한 인터넷 도메인 이름을 사용할 수 있다.
      # <VirtualHost>, Listen 지시자도 참고하라.
      #
      #BindAddress *

      하나 이상의 IP address가 있는 Server에서 사용한다. Server가 어떤
      address에서 요청을 기댜려야 할지 정한다. Default로 주석 처리 되어
      있어 Server가 모든 address를 청취한다. Default로 나두면 된다.

      # 동적 공유 객체(Dynamic Shared Object, DSO) 지원
      #
      # DSO 방식으로 만들어진 모듈의 기능을 사용하기 위해서는 그 기능에
      # 관련된 지시자를 사용하기에 앞서 알맞게 `LoadModule' 지시자로
      # 모듈을 지시해주어야 한다.  DSO 작동방식에 대하여 자세히 알고 싶은
      # 사람은 아파치 1.3 배포 파일의 README.DSO 를 읽어보라.  여러분이
      # 갖고 있는 httpd 바이너리에 내장된(정적으로 링크되어 항상 사용
      # 가능한) 모듈 목록을 알고 싶을 때에는 `httpd -l' 명령을 실행한다.
      #
      # 주의: 모듈을 적재하는 순서는 매우 중요하다.  전문가의 조언 없이
      #       아무렇게나 순서를 바꾸지 말라.
      #
      # 예:
      # LoadModule foo_module libexec/mod_foo.so
      #
      # 모듈 관련 문서는 HTML 형식으로 "/home/httpd/manual/mod" 에
      # 놓아두었다.
      #
      # 주의: LoadModule 설정을 하나라도 바꾸었다면 LoadModule 설정 뒤에
      #       따라 나오는 AddModule 설정도 똑같이 바꾸어주기 바란다.
      #

      #LoadModule mmap_static_module  modules/mod_mmap_static.so
      LoadModule env_module           modules/mod_env.so
      LoadModule config_log_module    modules/mod_log_config.so
      LoadModule agent_log_module     modules/mod_log_agent.so
      LoadModule referer_log_module   modules/mod_log_referer.so
      #LoadModule mime_magic_module   modules/mod_mime_magic.so
      LoadModule mime_module          modules/mod_mime.so
      #LoadModule negotiation_module  modules/mod_negotiation.so
      LoadModule status_module        modules/mod_status.so
      LoadModule info_module          modules/mod_info.so
      LoadModule includes_module      modules/mod_include.so
      LoadModule autoindex_module     modules/mod_autoindex.so
      LoadModule dir_module           modules/mod_dir.so
      LoadModule cgi_module           modules/mod_cgi.so
      #LoadModule asis_module         modules/mod_asis.so
      #LoadModule imap_module         modules/mod_imap.so
      LoadModule action_module        modules/mod_actions.so
      #LoadModule speling_module      modules/mod_speling.so
      LoadModule userdir_module       modules/mod_userdir.so
      #LoadModule proxy_module        modules/libproxy.so
      LoadModule alias_module         modules/mod_alias.so
      LoadModule rewrite_module       modules/mod_rewrite.so
      LoadModule access_module        modules/mod_access.so
      LoadModule auth_module          modules/mod_auth.so
      #LoadModule anon_auth_module    modules/mod_auth_anon.so
      #LoadModule dbm_auth_module     modules/mod_auth_dbm.so
      LoadModule db_auth_module       modules/mod_auth_db.so
      #LoadModule digest_module       modules/mod_digest.so
      #LoadModule cern_meta_module    modules/mod_cern_meta.so
      LoadModule expires_module       modules/mod_expires.so
      LoadModule headers_module       modules/mod_headers.so
      #LoadModule usertrack_module    modules/mod_usertrack.so
      #LoadModule example_module      modules/mod_example.so
      #LoadModule unique_id_module    modules/mod_unique_id.so
      LoadModule setenvif_module      modules/mod_setenvif.so
      #LoadModule bandwidth_module    modules/mod_bandwidth.so
      #LoadModule put_module          modules/mod_put.so

      #
      # 확장 모듈
      #LoadModule php_module         modules/mod_php.so

      PHP2를 위한 Module로서 요즘에는 별로 사용을 안한다. 무시해랏!

      #
      # 다음 모듈은 MySQL 데이터베이스와 더불어 서버 스크립팅 언어로
      # 인기를 누리고 있는 PHP3 모듈입니다.
      #
      # 참고 사이트 : http://www.php.net
      #
      #LoadModule php3_module        modules/libphp3.so

      PHP3 module을 설치했을 경우 주석을 풀어주고 사용을 하면 된다.

      #
      # 다음 모듈은 아파치 펄 모듈로서 CGI 스크립트로 펄을 많이
      # 사용하는 사람들에게 펄 코드 실행 속도의 향상을 가져다 줍니다.
      #
      # 주의 : 설정을 바꾼 후 한 가지 할 일이 더 있다.
      #
      #        <Location /perl> ... </Location>
      #
      #        위와 같은 설정을 찾아서 펄 스크립트를 사용할 수 있는
      #        디렉토리를 설정해주어야 한다.
      #
      #LoadModule perl_module        modules/libperl.so

      #
      #  모듈 실행 순서를 정확하게 하기 위해 사용 가능한 모듈(정적 또는
      #  공유 모듈 포함)로부터 완전한 목록을 다시 만들어 둔 것이다.
      #  [LOADMODULE 섹션을 하나라도 수정했다면 이 부분도 역시 알맞게
      #  수정하라]
      #
      ClearModuleList
      #AddModule mod_mmap_static.c
      AddModule mod_env.c
      AddModule mod_log_config.c
      AddModule mod_log_agent.c
      AddModule mod_log_referer.c
      #AddModule mod_mime_magic.c
      AddModule mod_mime.c
      #AddModule mod_negotiation.c
      AddModule mod_status.c
      AddModule mod_info.c
      AddModule mod_include.c
      AddModule mod_autoindex.c
      AddModule mod_dir.c
      AddModule mod_cgi.c
      #AddModule mod_asis.c
      #AddModule mod_imap.c
      AddModule mod_actions.c
      #AddModule mod_speling.c
      AddModule mod_userdir.c
      #AddModule mod_proxy.c
      AddModule mod_alias.c
      AddModule mod_rewrite.c
      AddModule mod_access.c
      AddModule mod_auth.c
      #AddModule mod_auth_anon.c
      #AddModule mod_auth_dbm.c
      AddModule mod_auth_db.c
      #AddModule mod_digest.c
      #AddModule mod_cern_meta.c
      AddModule mod_expires.c
      AddModule mod_headers.c
      #AddModule mod_usertrack.c
      #AddModule mod_example.c
      #AddModule mod_unique_id.c
      AddModule mod_so.c
      AddModule mod_setenvif.c
      #AddModule mod_bandwidth.c
      #AddModule mod_put.c

      # Extra Modules
      #AddModule mod_php.c
      #AddModule mod_php3.c
      #AddModule mod_perl.c

      #
      # ExtendedStatus 지시자는 "server-status" 처리기가 호출되었을
      # 때 아파치가 "매우 자세한" 상태 정보를 생성시킬 것인지
      # (ExtendedStatus On) 아니면 매우 기본적인 정보만 생성시킬
      # 것인지를 (ExtendedStatus Off) 제어한다.  기본값은 Off 이다.
      #
      ExtendedStatus On

      #
      #####################################################################

      ### 섹션 2: '주(Main)' 서버 설정
      #
      # 이 섹션에 있는 지시자는 <VirtualHost> 정의에 의해 처리되지
      # 않는 모든 요청에 응답할 '주' 서버가 사용할 값을 정한다.
      # 이 값들은 또한 이 파일 뒷 부분에서 정의할 모든 <VirtualHost>
      # 컨테이너의 기본값을 제공하기도 한다.
      #
      # 여기 나오는 모든 지시자는 <VirtualHost> 컨테이너 안에서도
      # 사용할 수 있으며 그 안에서 사용되면 해당 가상 호스트에 대하여
      # 전체 기본값을 무시하고 새롭게 정한 값이 채택된다.
      #

      #
      # 만약 ServerType ('Global Environment' 섹션에서 설정)이
      # "inetd"인 경우, inetd 설정 내용을 따르기 때문에 다시 몇 가지
      # 지시자는 아무런 효력을 발휘하지 않는다.
      # ServerAdmin 지시자까지 그냥 건너뛴다.
      #

      #
      # Port: 독립실행형(standalone) 서버가 요청을 기다리는 포트.
      # 1023 번보다 낮은 번호의 포트에 대해서는 httpd가 처음에는
      # root 권한으로 실행되어야 한다.
      #
      Port 80

      시스템에 의해 미리 httpd를 위해 예약된 포트 번호는 80번이다.
      0에서 1023까지의 포트번호는 시스템에 의해 미리 예약되어 있다.
      그 이상의 포트번호를 지정하여 일반사용자도 httpd을 설치,
      운영가능하다. http://aaa.bbb.ccc:8080/ 등으로 사용할 수 있다.
      만약 Server type을 Inetd로 했다면 /etc/services에서 지정을 해
      줘야 한다.

      #
      # httpd가 다른 사용자 또는 그룹 권한으로 실행되게 하려면 우선은
      # httpd가 root 사용자 권한으로 실행되고 나서 설정한 다른 사용자
      # 권한으로 전환해야 한다.
      #
      # User/Group: httpd가 실행된 권한의 사용자/그룹의 이름(또는 #번호)
      #  . SCO (ODT 3)에서는 "User nouser"와 "Group nogroup"을
      #    사용한다.
      #  . UPUX 에서는 nobody로 실행하는 경우 공유 메모리를 사용할 수
      #    없을 것이다.  이 때는 www 등의 사용자를 만들고 그 사용자
      #    권한으로 실행되도록 한다.
      # 주의) 몇몇 커널들은 60000 이상의 (unsigned) 그룹 값을 설정하면
      # setgid(Group), semctl(IPC_SET) 함수를 거부한다.
      # 이런 시스템에서는 Group   #-1을 사용하지 말라!
      #
      User nobody
      Group nobody

      이 항목은 Default로 나두기를 권한다. 지정한 사용자와 그룹이 존재
      하지 않으면 서버가 동작하지 않기 때문이다. 굳이 설명을 하자면 이
      설정은 ServerType이 standalone일 때만 적용되는 것으로, 서버가
      사용자의 요청에 대해서 생성하는 child httpd 프로세스에 대한
      user id, group id 이다. 일반적으로 시스템에서 사용하지 않는
      것들로 지정하는 것이 바람직하다.

      #
      # ServerAdmin: 서버에 문제가 발생했을 때 메일을 보낼 메일 주소.
      # 이 주소는 예를 들어 에러 문서와 같이 서버가 생성하는 페이지에
      # 나타날 것이다.
      #
      ServerAdmin admin at oops.org

      #
      # ServerName은 클라이언트 프로그램에게 돌려주는 서버 이름이
      # 다른 경우 호스트 이름을 설정할 수 있게 해준다. (예를 들어,
      # 호스트의 실제 이름이 아닌 'www'를 사용하도록 하는데 사용할
      # 수 있다.)
      #
      # 주의: 호스트 이름을 아무렇게나 만들어선 안된다.  이 이름은
      # 여러분의 호스트에 주어진 타당한 DNS 이름이어야 한다. 잘
      # 모르겠으면 네트웍 관리자에게 문의하라.
      # 호스트가 등록된 DNS 이름을 갖고 있지 않는 경우에는 이 곳에
      # IP 주소를 적는다.  어찌 되었든 IP 주소를 사용하여(예를 들어
      # http://123.45.67.89/) 접속할 수 있다.  이런 식으로 해서
      # 리다이렉션이 작동하도록 할 수 있다.
      #
      ServerName www.oops.org

      서버의 도메인 네임을 지정한다. 자신의 서버가 도메인 네임을
      가지지 않았다면 ip address로라도 꼭 적어 주어야 계정 접속을
      할때 ~account 뒤에 "/"를 붙이지 않고 접속을 할수가 있다.
      도메인 이름을 가지고 있다면 주의할 것은 꼭 실제로 존재하는
      URL 이어야 한다는 것이다.

      #
      # DocumentRoot: 제공할 문서의 상위 디렉토리.
      # 기본적으로 모든 요청은 이 디렉토리로부터 처리된다. 하지만
      # 심볼릭 링크나 앨리어스(alias)를 사용하여 다른 위치를
      # 가리키도록 할 수 있다.
      #
      DocumentRoot "/home/httpd/html"

      웹 문서의 기본 directory이다. 보통 우리가 url을 쳤을때 접속되는
      최초의 directory이다. 소스로 apache server를 설치했을 경우에는
      default로 /usr/local/apache/htdocs이며 알짜 RedHat에서는
      /home/httpd/html 이다. 참고로 이전 버전의 apach를 소스로
      compile을 했을 경우에는 /usr/local/etc/httpd/htdocs 가 된다.
      1.3.4 부터 위와 같이 변경이 되었다. "@@ServerRoot@@ 를 이용
      하여 ServerRoot 인자의 directory 경로의 값을 변수와 같이 사용
      할 수도 있다.

      <IfModule mod_bandwidth.c>
       #
       # 전송속도 제한에 관한 설정이다. BandWidthModule 지시자는
       # 전체 설정에 사용이 되어지며, BandWidth, LargeFileLimit,
       # MinBandWidth는 지역 설정에서 사용을 할수도 있다.
       #
       BandWidthModule On

       #
       # 문  법: BandWidth <도메인|IP주소|all> <속도>
       # 기본값: 없음
       # 사용처: 전체 설정, 디렉토리별 설정, .htaccess
       #
       # 호스트에 따라 속도의 제한을 걸 수 있다. all은 모든 호스트에
       # 대해서 제한을 거는 것이며 도메인이나 IP주소로 접속 호스트를
       # 지정할 수 있다. 그리고 네트워크/마스크 포맷*으로 지정할 수도
       # 있다. (예: 192.168.0.0/24)
       #
       # 속도는 Bytes/second로 지정을 하며 0의 경우는 제한이 없다.
       #
       # 디렉토리별 설정 예
       #
       # <Directory /home/httpd/html>
       #   BandWidth 192.168.1 0
       #   BandWidth foobar.net 0
       #   BandWidth all 1024
       # </Directory>
       #
       # /home/httpd/html 디렉토리에서의 제한을 한 것이다. 192.168.1.*
       # IP 주소를 가진 호스트와 *.foobar.net이라는 도메인명을 사용하는
       # 호스트에 대해서는 제한을 걸지 않으며 그 외 모든 접속에 대해서
       # 1024Bytes/sec으로 제한을 한다.
       #
       BandWidth       all     0

       #
       # 문  법: LargeFileLimit <파일크기> <속도>
       # 기본값: 없음
       # 사용처: 전체 설정, 디렉토리별 설정, .htaccess
       #
       # 일정 이상의 크기를 가진 파일을 누군가가 받아 가려 할 때
       # 그 속도의 제한을 걸 수 있다. 파일크기는 KByte 기준이며 속도는
       # 역시 Bytes/secound 이다.
       #
       # LargeFileLimit 1024 4096
       # LargeFileLimit 2048 2048
       #
       # 위 예제는 1024 ~ 2047KB 크기의 파일을 받아가려 할 때 속도를
       # 4KB/sec으로 제한하고 2048KB 이상의 파일은 2KB/sec으로 제한을
       # 하는 것이다.
       #
       # LargeFileLimit 1024 4096

       #
       # 문  법: MinBandWidth <도메인|IP주소|all> <속도>
       # 기본값: all, 256
       # 사용처: 전체 설정, 디렉토리별 설정, .htaccess
       #
       # 데이타 전송의 최저 속도를 지정한다.
       #
       # BandWidth를 4096 (4KBytes/sec)으로 지정하고 MinBandWidth가
       # 1024로 지정이 되어 있을 때:
       #
       #   - 지정된 호스트에서 하나만 접속할 경우, 4096bytes/sec이
       #     최고의 속도가 된다.
       #
       #   - 지정된 호스트에서 두개가 동시에 접속할 경우, 각각의 세션에
       #     대해 2048Bytes/sec이 최고의 속도가 된다.
       #
       #   - 더 많은 동시 접속이 일어나도 세션 당 최고 속도는
       #     1024Bytes/sec 이하로는 줄지 않는다.
       #     (MinBandWidth 값이 1024기 때문에)
       #
       # MinBandWidth가 "-1"로 지정되면 모든 세션에 대해 최고 속도는
       # BandWidth나 LageFileLimit에서 지정한 속도가 나올 수 있게 된다.
       #
       # BandWidth를 4096으로 지정하고 MinBandWidth가 -1이라면 동시에
       # 지정된 호스트에서 몇개의 접속을 하더라도 각 세션의 속도는
       # 4096Bytes/sec 까지 나오게 되는 것이다.
       #
       MinBandWidth    all     -1
      </IfModule>

      IfModule 이라는 지시자는 module을 올렸을 경우에만 작동을
      가능하게 해 주는 지시자 이다. 즉 Module로 올라와 있지 않을
      경우에는 작동을 하지 않는다.


      #
      # 아파치가 접근할 수 있는 각 디렉토리에 대하여 어떤 서비스와
      # 기능을 허용할 것인지 거부할 것인지 여부를 설정할 수 있다.
      # 디렉토리에 대한 설정 내용은 그 하부 디렉토리에도 영향을 미친다.
      #
      # 우선, "기본값"을 매우 제한적인 상태로 설정한다.
      #

      <directory> tag에 의하여 각 directory마다 적절하게 permission을
      걸수가 있다.

      <Directory />
       Options FollowSymLinks
       AllowOverride None
       Order allow,deny
       Allow from all
       Deny from env=no_access
      </Directory>

      "Deny from env=no_access" 설정에 대해서는 뒤에 다루기로 한다. 

      #
      # 이 곳부터 허용할 특정 기능을 알맞게 설정해나간다는 사실을
      # 주목하자. 여러분이 기대한 대로 작동하지 않는 것이 있다면 그
      # 기능을 가능 상태로 설정해두었는지 점검하기 바란다.
      #

      #
      # 다음 내용은 여러분이 설정한 DocumentRoot 값으로 변경해서
      # 사용한다.
      #
      <Directory "/home/httpd/html">

      #
      # 다음 값에는 "None", "All", 또는 "Indexes", "Includes",
      # "FollowSymLinks", "ExecCGI", "MultiViews"의 자유로운
      # 조합이 가능하다.
      #
      # "MultiViews" 만큼은 "Options All"을 사용한다 할 지라도
      # 명시적으로 적어야만 작동한다는 사실을 알아두자.
      #
         Options Indexes FollowSymLinks Includes

      지정할수 있는  옵션의 예이다.
    None어떤 옵션도 이용할 수 없다.
    All지정한 directory에서 모든 명령을 이용할 수 있다.
    IndexesURL에 지정된 디렉토리에 (index.html 같은) 지정된 파일이 없을 경우 디렉토리의 파일 목록을 보여주는 옵션.
    Includes서버측의 추가적인 정보를 제공할 수 있게 한다.
    IncludesNoExec서버측의 추가적인 정보를 제공할 수 있게 하지만, 어떠한 실행 파일을 실행하는 것을 방지한다.
    FollowSymLinks 디렉토리상의 심볼릭 링크를 사용가능하게 한다.
    ExecCGICGI 스크립트를 실행할 수 있게 한다.
    MultiViews All 옵션이 설정되었을 때만 지정된 목록의 multiviews를 허용한다.
      #  # 다음은 각 디렉토리에 위치한 .htaccess 파일에서 어떤 옵션을   # 마음대로 제어할 수 있는지 결정한다.    # "All" 또는 "Options", "FileInfo", "AuthConfig", "Limit"의  # 자유로운 결합이 가능하다.  #      AllowOverride None  .htaccess파일은 서버의 각 디렉토리에 만들어서 각 디렉토리에  대한 접근을 제어하기 위한 것으로 디렉토리에 .htaccess파일이  있으면, 서버 전체에 작용하는 access.conf 보다 우선권을 가진다.   .htaccess파일에 대한 Override에 대한 옵션이다. 가능한 옵션은  다음과 같다.
    None.htaccess파일을 읽을 수 없게 한다.
    All모든 지정에 대해 가능하게 한다.
    Options규정된 디렉토리 형식을 콘트롤하는 지정의 사용을 허락한다.
    FileInfo문서형식을 콘트롤하는 지정의 사용을 허용한다.
    AuthConfig 사용자 인증 지정의 사용을 허용한다. 사용자 인증 변수를 사용한다.
    Limit호스트 접근을 콘트롤하는 지정을 허용한다.
      #  # 서버로부터 자료를 얻어갈 수 있는 위치를 제어한다.  #    Order allow,deny    Allow from all    Deny from env=no_access  Limit에 관련된 부분을 설정을 한다.  order : 서버가 access control을 수행하는 순서를 나타낸다. 여기서는          allow기능을 먼저 수행하고, deny기능을 수행하라는 것이다.  deny, allow - deny 지시자 부터 검사하고 allow 지시자를 검사   allow, deny - allow 지시자 부터 검사하고 deny 지시자를 검사   mutual-failure - allow목록에 없는 모든 host에게 접속을 거부  allow from : 나열되는 주소들에 대한 access control을 가능하게 한다.           사용 가능한 주소는 도메인 네임, 호스트 이름 주소, 호스트 ip          주소, ip 주소의 앞부분 3바이트, 모든 주소에 해당하는 all         이 있다.  deny from : allow from과 반대되는 개념이며, 사용가능한 주소는          allow from과 같다.  require : 사용자, 그룹에 대한 접근을 통제할 수 있다.         사용방법 : require entity en1 en2 ... enn         entity에 들어갈 수 있는 것은 user, group, valid-user의          세가지이다.  user : 지정된 사용자들에게만 접근을 허용하는 것으로, 지정된 사용자에          대한 정보는 AuthUserFile에서 지정한 파일에 있다.  group : 지정된 그룹에게만 접근을 허용하는 것으로, 지정된 그룹에 대한          정보는 AuthGroupFile에서 지정한 파일에 있다.  valid-user : AuthUserFile에 있는 모든 사용자에 대해 접근을 허용한다.  </Directory>  #  # UserDir: ~user 요청을 받았을 때 사용자의 홈 디렉토리 뒤에 추가할  # 디렉토리 이름.  #  UserDir htdocs  계정 사용자들의 home directory를 지정한다.  보통 http://url/~계정 이런식으로 접속했을때 계정에 이곳에 지정된  이름의 directory를 만들고 home directroy로 사용하면 된다. 보통   public_html 이나 htodcs, home 을 많이 쓴다. 다른 이름으로 해도  상관은 없다. 계정 사용자가 사용을 못하게 하려면 DISABLED 옵션을  주면 된다.  참고를 할것은 RedHat 계열에서는 user를 생성을 하면 user의 home  directory는 700의 권한을 갖게 되므로 httpd.conf에서 아무리 설정을  해 줘도 forbidden error만 만나게 된다. 그러므로 계정에서 homepage를  운영하기 위해서는 꼭 chmod a+x ~accountname 명령을 실행을  해 줘야 한다.  #  # UserDir 디렉토리에 대한 접근을 제어한다.  다음은 사용자 홈  # 페이지에 대하여 읽기만 가능하도록 한 예제 설정 내용이다.   # 참고 자료로 사용하기 바란다.  #  #<Directory /*/public_html>  #    AllowOverride FileInfo AuthConfig Limit  #    Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec  #    <Limit GET POST OPTIONS PROPFIND>  #        Order allow,deny  #        Allow from all  #    </Limit>  #    <Limit PUT DELETE PATCH PROPPATCH MKCOL COPY MOVE LOCK UNLOCK>  #        Order deny,allow  #        Deny from all  #    </Limit>  #</Directory>  위의 설정중 "*" 사용에 관해서 언급을 할것이 있다. 보통 "*"는 all의  의미로 많이 사용이 된다. 즉 위에서 /*/public_html 은 어떠한  경로에 있는 모든 public_html을 뜻한다고 할수 있다. 하지만 이는  그렇게 호락호락하게 되지는 않는듯 하다. 필자의 경험에 의하면  같은 레벨의 깊이에 있는 public_html 만 적용이 되는듯 하다. 즉  위의 설정대로라면 /home/public_html은 적용이 되지만  /home/oops/publci_html 은 적용이 되지 않더란 말이다.  #  # DirectoryIndex: 준비된 HTML 디렉토리 인덱스로 사용할 파일이나  # 파일 목록의 이름을 나열한다.  여러 개를 나열할 때는 스페이스로  # 구분한다.  #  DirectoryIndex index.html index.htm index.shtml index.php3 index.cgi  특정 파일을 지정하지 않고 디렉토리만 지정했을 때 불러들일  문서를 지정한다. 앞에서 부터 써나간 대로 지정된 file이 있는  지 확인을 하고 없으면 그 다음으로 지정한 file을 찾는다.  #  # AccessFileName: 각 디렉토리에 대하여 접근 제어 정보 내용을  # 담고 있을 파일 이름  #  AccessFileName .htaccess  서버가 디렉토리를 출력할 때 참고할 파일을 지정한다. directory  user들은 그 directory에 .htaccess라는 file에 지시자를 넣어  srm.conf의 설정을 덮어 쓸수 있다. 인증을 시도하기 위하여 참조  하는 file이라고 생각하면 된다. <Directory> tag 에 관련 분이  설명되어 있다.  #  # 다음 행은 웹 브라우져가 .htaccess 파일을 접근할 수 없도록  # 하는 설정이다.  .htaccess에는 인증 정보가 들어있는 경우가  # 빈번하므로 보안 상 이유로 이 파일에 대한 접근은 불허해야  # 한다. 웹 방문객들이 이 파일을 보게 하고 싶으면 다음 행들을  # 주석 처리하라. 만약 AccessFileName 설정을 다른 파일명으로  # 바꾸었다면 알맞게 .htaccess를 그 이름으로 바꾸어준다.  #  <Files "^\.ht">      Order allow,deny      Deny from all  </Files>  이 설정 역시 1,3,4에서 부터  새로 추가된 설정이다. .htaccess에  접근을 하여 password file을 훔쳐가려고 하는 것을 미연에 방지  하기 위하여 file 자체에도 permission을 걸수 있도록 해 놓았다.  문법은 <directory> tag에서 설명을 한 limit 문법과 동일하다.  위의 설정은 정규 표현식(RegEx)을 이용한 것으로 .ht로 시작하는  모든 파일을 의미한다.  #  # CacheNegotiateDocs: 기본적으로 아파치는 내용에 따라 협상된  # 문서에 대해서는 "Pragma: no-cache" 내용을 전송한다.  이 행은  # 프록시 서버로 하여금 문서를 캐쉬하지 않도록 요청한다. 다음 행의  # 주석을 풀면 이 기능을 해제하고 모든 프록시가 문서들을 캐쉬할 수  # 있도록 한다.  #  #CacheNegotiatedDocs  이 설정은 Proxy Server를 거치는 사용자들을 위한 것이다. Proxy  Server가 "교섭" 문서, 즉 CGI script의 출력이나 Server가 생성한   index page처럼 직접 수신되지 않는 문서를 cache 하도록 한다.   Default로 주석 처리 되어 있고 그냥 이대로 두면 된다.  #  # UseCanonicalName: (1.3 버전에 새롭게 등장) 이 설정을 켜두면,  # 아파치가 자기 참조 URL(반응이 오고 있는 서버를 다시 가리키는  # URL)을 만들 필요가 있을 때마다 "공식적인" 이름을 만들기 위해  # ServerName과 Port를 사용한다.  그렇지 않으면 아파치는 가능한 한  # 클라이언트가 제공한 호스트이름:포트 값을 사용한다.  # 이 설정은 CGI 스크립트의 SERVER_NAME, SERVER_PORT에도 영향을  # 미친다.  #  UseCanonicalName On  #  # TypesConfig 는 mime.types 파일 또는 이에 해당하는 파일을 찾을  # 위치를 결정한다.  #  TypesConfig /etc/mime.types  #  # DefaultType이란 파일 확장자와 같은 것을 통해 MIME 타입을  # 알 수 없는 문서에 대하여 사용할 기본 MIME 타입을 말한다.   # 여러분의 서버에 주로 텍스트나 HTML 문서가 많다면   # "text/plain"을 쓰는 것이 좋다. 대부분이 실행 프로그램이나  # 이미지 등 바이너리인 경우에는 웹 브라우져가 텍스트라고  # 생각하여 바이너리 파일을 화면에 표시하지 않도록 하기 위해   # "application/octet-stream"를 적는다.  #  DefaultType text/plain  Server가 갖고 있지 않은 MIME type의 확장자가 있는 file을 client  가 요청 했을경우 DefaultType의 MIME type이 사용된다. file  확장자에서 MIME type으로의 map은 AddType 지시자로 추가할  수도 있다.  #  # mod_mime_magic 모듈을 사용하면 파일의 내용을 가지고 파일의  # 타입에 힌트를 얻는다.  MIMEMagicFile 지시자를 사용하여  # 모듈에게 힌트 정보가 저장되어 있는 파일을 설정한다.  # mod_mime_magic은 기본 서버의 일부가 아니다.(따라서  # LoadModule 설정을 사용하여 모듈을 추가해야 한다.) 또는  # 서버를 다시 컴파일해서 mod_mime_magic을 추가해야 한다.  # 그렇기 때문에 <IfModule> 컨테이너에 포함되어 있는 것이다.  # 다음 설정은 모듈이 서버에 포함되어 있을 때에만 MIMEMagicFile  # 지시자를 처리하도록 해준다.  #  <IfModule mod_mime_magic.c>      MIMEMagicFile conf/magic  </IfModule>  이것 역시 1.3.12에서 부터 새로 추가된 module이다. 사용을 하기  위해서는 DSO 설정에서 mod_mime_magic line의 주석을 해제해야  한다.  #  # HostNameLookups: 클라이언트의 이름 또는 IP 주소만을 기록할  # 지 여부. 예를 들어 www.apache.org (on) 또는   # 204.62.129.132 (off) 기본값이 off 인 이유는 각 클라이언트 요청이  # 올 때마다 최소한 1 번 이상의 네임 서버 요청이 발생하기 때문이다.  #  그러나 꼭 필요한 경우에는 이 기능을 켜둔다.  #  HostnameLookups Off  웹서버에 대한 접근을 도메인네임이나 ip주소 (on) 또는 ip주소  만으로(off) 접근하게 할 것인지를 결정하는 것이다. Apache   1.3.4 부터 이 기능은 default가 off로 변경되었다. 이것이 off로   설정되어 있다고 해서 도메인으로 접근을 못하는 것은 아니다.  다만 webserver에서 해당 request에 대한 도메인을 해석을   할것인지 안할 것인지를 지정하는 것이므로 그리 걱정은 하지  않아도 상관이 없다. 대표적인 예로는 on으로 되어 있으면   log에 revers mapping이 가능한 ip address들은 domain   name으로 log를 남기며, 그렇지 않은 것들은 ip address로  남기게 된다. off일 경우에는 무조건 ip address로 남게 된다.  또한 이 지시자의 값이 Off일 경우에는 apache에서 제공하는  Cookie인 REMOTE_HOST 역시 작동을 하지 않는다.  #  # ErrorLog: 에러 기록 파일의 위치.  # <VirtualHost> 컨테이너 안에서 ErrorLog 설정을 하지  # 않으면 그 가상 호스트에 관련된 에러 메시지도 역시 이 곳에  # 기록된다. <VirtualHost> 컨테이너 안에서 에러 로그 파일을  # 정의하면 관련된 에러 메시지는 그 파일로 저장된다.  #  ErrorLog logs/error_log  Server에서 발생하는 error를 기록하는 log file을 지정한다.  상대 경로로 지정을 하면 위의 Server Root의 값이 앞에 자동으로  부여 된다.  만약 ErrorLog를 남기고 싶지 않다면 /dev/null로 지정을 해 주면  된다. 예: ErrorLog /dev/null  #  # LogLevel: error_log에 기록될 메시지 분량을 제어한다.  # debug, info, notice, warn, error, crit, alert, emerg 등의  # 값이 가능하다.  # alert, emerg.  #  LogLevel warn  #  # 다음 지시자는 CustomLog 지시자(아래 참고)에서 사용할 몇   # 가지 형식에 대한 별명을 정의한다.  #  LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\"                     \"%{User-Agent}i\"" combined  LogFormat "%h %l %u %t \"%r\" %>s %b" common  LogFormat "%{Referer}i -> %U" referer  LogFormat "%{User-agent}i" agent  #  # 접근 로그 파일의 위치와 형식(공통 로그파일 형식)  # <VirtualHost> 컨테이너 안에서 접근 로그파일 설정을 하지  # 않으면 모든 기록이 이 파일에 남게 된다.  이와 반대로 각  # <VirtualHost> 마다 접근 로그파일을 정의하면 모든 처리가  # 바로 그 파일에 기록된다.  #  CustomLog logs/access_log common  만약 CustomLog를 남기고 싶지 않다면 ErrorLog와는 달리 Log에  대한 설정을 모두 주석 처리를 하면 된다. ErrorLog와 같이  /dev/null로 설정을 해도 상관은 없다.  #  # 에이전트 로그파일과 참조자(referer) 로그파일을 갖기 위해서는  # 다음 지시 내용의 주석 처리를 해제하라.  #  #  # 여기서 에이전트란 여러분의 사이트에 방문하는 브라우져를 말한다.  # 에이전트 로그를 남기면 여러분의 사이트에 방문하는 브라우져의  # 종류에 대한 통계를 낼 수 있다.  #  # 참조자란 주로 배너 광고주에게 중요한 것으로서 여러분의 사이트  # 바로 직전에 방문한 사이트를 말한다.  #  #CustomLog logs/referer_log referer  #CustomLog logs/agent_log agent  #  # 하나의 로그파일에 접근, 에이전트, 참조자 정보를 다 저장하기  # 위해서는 (통합 로그파일 형식) 다음 지시 내용을 사용하라.  #  # 몇 달만 운영해도 접속이 많은 사이트에서는 combined 로그 파일이  # 어마어마하게 커져서 루트 파일 시스템을 꽉 채워 버리는 일이  # 발생할 수 있다!  #  #CustomLog logs/access_log combined  이 설정은 위의 CustomLog logs/referer_log referer,   CustomLog logs/agent_log agent 를 합쳐 놓은 것이라   생각하면 된다. 이 행의 주석을 풀어 주기 위해서는 위의 두행이   주석처리가 되어 있어야 한다.   #  # 부차적으로 서버가 생성하는 페이지(에러 문서, FTP 디렉토리  # 목록, mod_status, mod_info 출력 등, 그러나 CGI 생성 문서는   # 제외)에 서버 버전과 가상 호스트 이름을 포함하는 행을 추가  # 하도록 한다. "Email"로 설정하면 ServerAdmin으로의 mailto:  # 링크를 포함한다. On | Off | EMail 중 하나로 설정한다.  #  ServerSignature On  역시 1.3.4에서 새로 추가된 module이다. 에러 메시지에   ServerName과 ServerAdmin을 표시해 줄수 있다.  #  # Aliases: 필요한 만큼의 별칭을 만들어 사용한다.(제한 없음)  # 형식은 다음과 같다.  # Alias 가짜이름 실제이름  #  # 가짜 이름 뒤에 / 를 포함하면 아파치 서버는 URL에도 / 이 있어야  # 처리함을 잘 알아두자.  따라서 "/icons"는 별칭 처리되지 않고  # "/icons/"만 별칭 처리된다.  #  Alias /icons/ "/home/httpd/icons/"  <Directory "/home/httpd/icons">      Options Indexes MultiViews      AllowOverride None      Order allow,deny      Allow from all  </Directory>  #  # ScriptAlias: 서버 스크립트를 포함하는 디렉토리를 제어한다.  # ScriptAlias는 근본적으로 Alias와 같으나 가리키고 있는 실제  # 디렉토리 안에 들어있는 문서를 실행 프로그램으로 취급하여  # 실행한다. 맨 뒤에 붙는 "/" 에 대한 규칙은 Alias와 마찬가지이다.  #  ScriptAlias /cgi-bin/ "/home/httpd/cgi-bin/"  서버에서 사용하는 cgi를 담은 디렉토리를 지정한다. 이 디렉토리의  파일들은 서버에 의해 cgi스크립트로 인식되어 활성화 시켜준다.  주의할 것은 ScriptAlias로 지정한 곳에서는 오로지 실행 파일만  인식을 한다는 것이다. 일반 파일들은 권한 에러를 발생하게 된다.  #  # "/home/httpd/cgi-bin" 부분은 ScriptAlias로 별칭 처리된 실제 CGI  # 디렉토리로 설정해야 한다.  #  <Directory "/home/httpd/cgi-bin">      AllowOverride None      Options ExecCGI      Order allow,deny      Allow from all  </Directory>  #  # PUT 방법에 의한 업로드를 허용할 것인지 아닌지 결정을 한다.  # 이 기능은 mod_put module을 dso로 설정을 해 놓아야지 가능하다.  #  <IfModule mod_put.c>    Alias /upload /tmp    <Location /upload>       EnablePut On       AuthType Basic       AuthName "Upload Area"       AuthUserFile /etc/httpd/conf/passwd       EnableDelete Off       umask 007       <Limit PUT>         require valid-user       </Limit>    </Location>  </IfModule>  #  # Redirect를 사용하면 서버의 이름공간에 존재했으나 현재에는   # 존재하지 않는 문서에 대하여 클라이언트에게 통보할 수 있도록  # 해준다.  이렇게 함으로써 위치가 변한 새로운 문서를 어디에서  # 찾을 수 있는지 클라이언트에게 알려줄 수 있다.  # 형식: Redirect 예전URI 새URI  #  자료파일을 url에 지정된 문서로 Redirect 한다.  #  # 서버가 생성하는 디렉토리 목록의 표시 상태를 제어하는 지시자.  #  #  # FancyIndexing은 예쁜 디렉토리 목록 또는 표준적인 디렉토리  # 목록 여부를 결정한다.  #  IndexOptions FancyIndexing  #  # AddIcon으로 시작하는 지시자는 서버에게 다양한 파일, 파일명  # 확장자에 대하여 어떤 아이콘을 보여 줄 것인지 말해준다.  이  # 값들은 FancyIndexing을 사용하는 경우에만 해당된다.  #  AddIconByEncoding (CMP,/icons/compressed.gif) x-compress x-gzip  AddIconByType (TXT,/icons/text.gif) text/*  AddIconByType (IMG,/icons/image2.gif) image/*  AddIconByType (SND,/icons/sound2.gif) audio/*  AddIconByType (VID,/icons/movie.gif) video/*  IndexOptions에서 FancyIndexing이 지정되었을 때 이 지시자는   file마다 MIME type에 따라 어떤 icon을 사용 할지 정한다.  AddIcon /icons/binary.gif .bin .exe  AddIcon /icons/binhex.gif .hqx  AddIcon /icons/tar.gif .tar  AddIcon /icons/world2.gif .wrl .wrl.gz .vrml .vrm .iv  AddIcon /icons/compressed.gif .Z .z .tgz .gz .zip  AddIcon /icons/a.gif .ps .ai .eps  AddIcon /icons/layout.gif .html .shtml .htm .pdf  AddIcon /icons/text.gif .txt  AddIcon /icons/c.gif .c  AddIcon /icons/p.gif .pl .py  AddIcon /icons/f.gif .for  AddIcon /icons/dvi.gif .dvi  AddIcon /icons/uuencoded.gif .uu  AddIcon /icons/script.gif .conf .sh .shar .csh .ksh .tcl  AddIcon /icons/tex.gif .tex  AddIcon /icons/bomb.gif core  AddIcon /icons/back.gif ..  AddIcon /icons/hand.right.gif README  AddIcon /icons/folder.gif ^^DIRECTORY^^  AddIcon /icons/blank.gif ^^BLANKICON^^  Server가 file과 Directofy를 표시하는데 어떤 icon을 사용할 지   지정한다.  #  # DefaultIcon이란 명시적인 아이콘을 갖고 있지 않는 파일에 대한  # 기본 아이콘 파일을 설정한다.  #  DefaultIcon /icons/unknown.gif  #  # AddDescription은 서버 자동 생성 인덱스의 파일명 뒤에 간단한  # 설명을 넣을 때 사용한다.  FancyIndexing을 사용할 때에만 보인다.  # 형식: AddDescription "설명" 화일명  #  AddDescription "GZIP compressed document" .gz  AddDescription "tar archive" .tar  AddDescription "GZIP compressed tar archive" .tgz  # META 태그를 사용하여 Content-type의 charset을 설정하지 않은  # 문서에 대하여 기본 문자셋을 iso-8859-1 로 해 버리는 패치에  # 대한 설정. 1.3.12에서 추가됨.  AddDefaultCharset Off  #AddDefaultCharset euc-kr  이 설정은 apache 1.3.12에 들어와서 Cross Site Scripting 보안 문제  패치를 하면서 기본 글꼴을 iso-8859-1 로 하는 현상이 발생 하므로  한글 사용을 위해서는 어쩌면 필요한 설정일지도 모른다. 일단 문제가  없으면 그냥 놔두는 것도 괜찮을지 모르겠지만 문제가 된다면 설정을  해보는 것도 괜찮을것 같다. 일단 필자의 테스트 로는 euc-kr로의  설정은 문제가 발생한다.  #  # ReadmeName은 서버가 디렉토리 목록 뒤에 내용을 덧붙여 넣을  # README 파일의 이름을 설정한다.  #  # HeaderName은 디렉토리 인덱스 앞에 내용을 덧붙일 파일명을   # 설정한다.  #  # 서버는 먼저 name.html을 찾고 그것이 있으면 그 내용을 포함  # 한다. 만약 없다면 서버는 name.txt 파일을 찾고 평범한 텍스트   # 내용으로 추가한다.  #  ReadmeName README  HeaderName HEADER  디렉토리 목록을 보여줄 때 목록의 마지막 부분 뒤와 목록의 시작  전에 보여줄 내용을 담고 있는 파일을 지정한다. 여기서는 목록의  뒤에 README, 목록의 처음에 HEADER를 보여주게 지정되어 있다.  #  # IndexIgnore는 디렉토리 인덱싱에 있어 목록에서 제외시킬 파일  # 명을 설정한다. 쉘 스타일의 와일드 카드를 사용할 수 있다.  #  IndexIgnore .??* *~ *  # HEADER* README* RCS CVS *,v *,t  디렉토리를 출력할 때 무시할 파일들을 지정한다.  #  # AddEncoding은 특정 브라우져(모자익/X 2.1+)로 하여금 자료를  # 받으면서 정보의 압축을 풀 수 있도록 해준다.    #   # 주의:  모든 브라우져가 이 기능을 지원하는 것은 아니다.    # 이름이 유사하기는 하지만 다음부터 나오게 될 Add로 시작하는  # 지시자 들은 FancyIndexing과는 관련이 없다.  #  AddEncoding x-compress Z  AddEncoding x-gzip gz  압축 코드에 대한 인코딩정보를 지정한다.  #  # AddLanguage는 문서의 언어를 명시한다.  내용 협상 과정을 통해   # 브라우져가 이해할 수 있는 언어의 문서를 제공하는 것이 가능하다.  # 접미어(suffix)는 언어 키워드와 꼭 같은 필요는 없다.  예를   # 들어 폴란드어(Polish)로 된 문서는 네트웍 표준 언어 코드가 pl   # 이지만 펄 스크립트와 확연히 구별하기 위해 "AddLanguage pl .po"  # 라고 사용한다.  #  <IfModule mod_negotiation.c>    AddLanguage ko .ko    AddLanguage en .en    AddLanguage fr .fr    AddLanguage de .de    AddLanguage da .da    AddLanguage el .el    AddLanguage it .it  </IfModule>  Server가 다국 언어로 문서를 제공한다면 이 지시자를 사용해 file   확장자를 언어를 지정 하는 약어에 대응시킨다. 언어의 약어는 보통   인터넷 국가 코드를 사용한다. client가 home.html이라는 file을   요청하면 browser는 프랑스어 사용자라는 것을 전하고 server는   이 지시자를 찾아서 어떤 file 확장자가 프랑스어 문서에 사용되는지   알아본다. 프랑스어 사용자라면 home.html.fr을 받게 된다. 다만   home.html이라는 file이 존재 한다면 home.html.fr을 받지 못하고   home.html을 받아 버리게 된다.  #  # LanguagePriority는 내용 협상 중 동점이 발생하는 경우 언어   # 우선권을 부여한다.  언어의 우선권을 내림차순으로 나열하면 된다.  #  <IfModule mod_negotiation.c>    LanguagePriority ko en fr de  </IfModule>  site에 위에서 지정한 것과 같은 home.html.fr과 같은 문서가 있고   client가 언어를 선택하지 않고 home.html을 요청할때(home.html이   없을 경우) 서버가 보낼 문서를 지정한다. 이 지시자는 여러 언어를   내침 차순으로 나열한다.  #  # AddType를 사용하면 mime.types 파일 수정없이 MIME 설정을 할 수   # 있고 또는 어떤 파일들에 대하여 특정 타입으로 처리하도록 할 수   # 있다.  #  # 예를 들어, PHP3 모듈(아파치 배포파일에 포함되어 있지 않다)에  # 대해서는 다음과 같이 사용한다.  #  <IfModule mod_php3.c>    AddType application/x-httpd-php3 .php3 .ph .html .ins    AddType application/x-httpd-php3-source .phps  </IfModule>  php3를 사용할 확장자를 지정하는 mime type이다. php3를 사용했을  경우 웹상에서 source를 보여 주고 싶다면 xhttpd-php3-source mime  type을 이용하면 된다.  php는 확장 module이다. 그렇기 때문에 apache에 기본적으로 포함  되어 있지는 않다. php를 사용하기 위해서는 php source를 구해서  apache module로 compile을 하여 사용하여야 한다. Alzza user 같은  경우에는 설치시에 mod_php package를 설치 하였다면 별 지장없이  위의 주석만 풀어주고선 사용을 할 수가 있다.  #다음은 PHP/FI (PHP2)를 위한 것이다.  <IfModule mod_php.c>    AddType application/x-httpd-php .phtml  </IfModule>  요즘은 잘 안쓰인다. 무시해 버리자..  #  # AddHandler를 사용하면 특정 파일 확장자와 "처리기"를 연결  # 하거나 특정 파일 타입에 특정 동작(action)을 연결할 수 있다.  # 서버에 내장되어 있거나 또는 Action 명령을 사용하여 추가할 수  # 있다.(아래 참고)  #  # 서버 측 포함(SSI) 또는 ScriptAlias 처리된 디렉토리 외부에  # 존재하는 CGI 스크립트를 사용하고 싶을 때는 다음 내용의  # 주석을 없앤다.  #  # CGI 스크립트를 사용하기 위해:  #  #AddHandler cgi-script .cgi .pl .sh  서버의 어떤 위치에 있던지 '.cgi' 확장자를 가진 파일은   cgi-script로 인식하게 한다. '.pl', '.sh' 등의 다른 확장자도   추가할 수 있다. 보안을 이유로 account user들에게 CGI 권한을   주지 않으려면 이행을 주석 처리해야 한다. 반대로 account user  들에게 CGI권한을 주기 위해서는  이 행의 주석을 풀어 줘야 한다.  #  # 서버 처리 HTML 파일 사용하기 위해:  #  AddType text/html .shtml  AddHandler server-parsed .shtml  AddHandler text/x-server-parsed-html .html .txt  Server Side Includes (SSI)를 사용할 때 필요하다. SSI는 HTML파일   속에 어떤 실행 프로그램의 결과나 특정 파일을 포함할 수 있게 한다.  shtml 확장자가 아닌 파일에서도 SSI를 사용할 수 있게 하려면 위에서와  같이 x-server-parsed-html mime type설정을 이용한다.  #  # 아파치의 send-asis HTTP 파일 기능을 사용하기 위해..  #  <IfModule mod_asis.c>    AddHandler send-as-is asis  </IfModule>  #  # 서버 처리 이미지 맵 파일을 사용하려면...  #  <IfModule mod_imap.c>    AddHandler imap-file map  </IfModule>  #  # type map을 사용하려면...  #  #AddHandler type-map var  # perl 모듈을 사용하려면 다음 세션의 주석을 풉니다.  #  #Alias /perl/ /home/httpd/perl/  #<Location /perl>  #SetHandler perl-script  #PerlHandler Apache::Registry  #Options +ExecCGI  #</Location>  #  # Action을 사용하면 매칭되는 파일이 호출될 때마다 그 미디어  # 타입에 맞는 스크립트를 시행시킬 수 있다.  빈번하게 사용되는   # CGI 파일 프로세서에 대하여 반복적으로 URL을 사용하지   # 않아도 된다.  # Format: Action media/type /cgi-script/location  # Format: Action handler-name /cgi-script/location  #  # MetaDir: 아파치 서버가 메타 정보 파일을 찾을 디렉토리 이름.  # 이 파일에는 문서를 보낼 때 추가하고자 하는 추가 HTTP 헤더   # 정보가 들어있다.  #  #MetaDir .web  CERN HTTP 서버의 meta information을 emulate해 주는 부분이다.   자세한 내용은 CERN HTTP 서버문서를 읽어보길 바란다.  #  # MetaSuffix: 메타 정보를 담고 있는 파일의 접미어를 설정한다.  #  #MetaSuffix .meta  #  # 사용자 정의 에러 반응 메시지 (아파치 스타일)  #  다음 3 가지 방법으로 가능하다.  #  #    1) 보통의 텍스트  #ErrorDocument 500 "The server made a boo boo.  #  주목: " 표시는 텍스트임을 알려주는 것으로서 그 자체는 출력  #        되지 않는다.  #    2) 지역적인 방향 전환  #ErrorDocument 404 /missing.html  #  지역적 URL인 /missing.html로 방향 전환하기  #ErrorDocument 404 /cgi-bin/missing_handler.pl  #  주목: 스크립트나 SSI로 방향 전환시킬 수 있다.  #  #    3) 외부 방향 전환  #ErrorDocument 402 http://some.othercom.com/subscription.html  #  주목: 원래 요청과 관련있는 환경 변수의 상당수가 스크립트에  #  전달되지 못한다는 점을 알고 있어야 한다.  서버에러에 대한 응답을 지정해 주는 부분이다. 각 에러 코드에   대한 응답을 cgi나 일반 텍스트로 만들어서 사용자에게 보여줄   수 있다. 어떤 서버에 접속하면 해당 URL이 없다는 등의 한글  메시지가 가능한 것도 이것을 이용하는 것이다.   아래는 (2)번의 내부 redirects를 사용한 예이다. 나의 경험 상으  로는 외부 방향 전환을 이용했을때 CGI와 htaccess 인증시에 505   Internal Server error가 발생 했다. 왜 그런지 이유는 잘 모르겠다.   내부 방향 전환에는 전혀 이상이 없었다.   ErrorDocument 400 /message/400error.html  ErrorDocument 401 /message/401error.html  ErrorDocument 403 /message/403error.html  ErrorDocument 404 /message/404error.html  ErrorDocument 405 /message/405error.html  ErrorDocument 500 /message/500error.html  ErrorDocument 501 /message/501error.html  또는 스크립트를 이용하여 변수를 전달시킬수도 있다.  ErrorDocument 400 /message/error.php?ecode=400  ErrorDocument 401 /message/error.php?ecode=401  ErrorDocument 403 /message/error.php?ecode=403  ErrorDocument 404 /message/error.php?ecode=404  ErrorDocument 405 /message/error.php?ecode=405  ErrorDocument 500 /message/error.php?ecode=500  ErrorDocument 501 /message/error.php?ecode=501  #  # 다음 지시자는 보통의 HTTP 반응 방식을 수정한다.  # 첫번째 것은 네스케이프 2.x 또는 그를 흉내내는 브라우져에   # 대하여 KeepAlive 기능을 쓰지 않도록 한다.  이 브라우져들은   # KeepAlive 구현에 문제점을 갖고 있기 때문이다.  # 두번째 것은 HTTP/1.1을 잘못 구현하였고 301 또는 302 (redirect)  # 반응에 대하여 KeepAlive를 제대로 지원하지 못하는 Micro$oft  # 인터넷 익스플로러 4.0b2를 위한 것이다.  #  BrowserMatch "Mozilla/2" nokeepalive  BrowserMatch "MSIE 4\.0b2;" nokeepalive downgrade-1.0 \                              force-response-1.0  "\"는 한줄로 쓰라는 것을 의미하는 것이다.  #  # 다음은 기본적인 1.1 반응도 제대로 처리하지 못함으로써 HTTP/1.1   # 스펙을 위반하고 있는 브라우져에 대하여 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  #  # BrowserMatch 지시자를 이용하여 User Agent별로 접근을 제어  # 하도록 한다.  #  BrowserMatch "WebZIP" no_access  BrowserMatch "Teleport" no_access  BrowserMatch "NamoWebEditor" no_access  BrowserMatch "WebTrack-HTTPP" no_access  BrowserMatch "WebSymmetrix" no_access  <Directory "/home/httpd/html/edu">  AllowOverride None  Options ExecCGI  Order allow,deny  Allow from all  Deny from env=access_forbidden  </Directory>  이 부분은 기본적으로 들어 있는 설정이 아니다. Apache 문서를   참고하여 작성을 해본 예일 뿐이다. 이를 응용하면 접근을 막고 싶은   application들을 유용하게 막을 수가 있다. 위의 예제는 Teleport와   WebZIP을 이용하여 긁어 가는 것을 막고 있다. 일단 BrowserMatch   지시자로 환경 함수를 정의한 다음 <Directory> 지시자의   Limit부분에서 Deny부분을 설정을 해 주는 것이다.  #  # http://servername/server-status을 통해 서버 상태 보고를 허용한다.  # 여기서 ".your_domain.com" 부분을 허용할 도메인으로 바꿔 사용하라.  #  <IfModule mod_status.c>    <Location /server-status>        SetHandler server-status        Order deny,allow        Deny from all        Allow from localhost        #Allow from all        #AuthName "administrator Area"        #Authtype Basic        #AuthUserFile /home/.htpasswd        #AuthGroupFile /dev/null        #require valid-user        #satisfy all    </Location>  </IfModule>  서버의 상태결과를 http://servename/server-status의 URL에 접근   하면 볼 수 있게 해주는 옵션이다. 'allow from 서버 도메인네임'의   형식 으로 접근이 가능하다.  하단의 주석 처리가 되어진 부분은 .htpasswd file에 기록되어 있는  User와 Password로 인증을 하여 보게 하는 설정의 예이다.  .htpasswd 인증을 위해서는 mod_auth.c 가 활성화되어 있어야 한다.  그럼 여기서 살짝 꽁수를 써보도록 하겠다. 일정 ip address에서는  ip address check만하고 인증을 안하도록 하고 다른 ip address에서  는 인증을 하게 하는 방법을 설정해 보도록 하겠다.  <IfModule mod_status.c>    <Location /server-status>        SetHandler server-status        Order deny,allow        Deny from all        Allow from localhost        AuthName "administrator Area"        Authtype Basic        AuthUserFile /home/.htpasswd        AuthGroupFile /dev/null        require valid-user        satisfy any    </Location>  </IfModule>  원래의 설정과 위의 설정과의 차이를 보도록 하면, 일단 원래의 설정에서  주석 처리 되어 있는 부분이 모두 주석이 제거가 되어 있다. 그리고 제일  마지막 option인 satisfy의 값이 all에서 any가 되어 있다. 이것이 바로  키포인트이다. 즉 Allow from에 지정된 ip address나 domain name은 인증  을 안하고 바로 보여주며, 그 외의 주소들은 /home/.htpasswd 에 있는 유  저의 이름과 패스워드를 비교하여 인증을 해서 출력을 하게 된다.  이것은 아래의 server-info에도 적용이 가능하다.  #  # http://servername/server-info를 통하여 원격 서버 설정 보고를   # 허용한다. 여기서 ".your_domain.com" 부분을 허용할 도메인으로  # 바꿔  사용하라.  #  <IfModule mod_info.c>    <Location /server-info>        SetHandler server-info        Order deny,allow        Deny from all        Allow from localhost        #Allow from all        #AuthName "administrator Area"        #Authtype Basic        #AuthUserFile /home/.htpasswd        #AuthGroupFile /dev/null        #require valid-user        #satisfy all    </Location>  </IfModule>  1.3.4 에서 부터 새로 추가된 module이다. 이 기능은   http://servername/server-info의 url으로 접근을 했을 경우 apache  에서 실행이 가능한 module들의 목록등 apache의 전반적인 정보를   보여준다.  #  # 1.1 버전 이전의 오래 된 버그를 악용하려는 사람들이 있다는 보고를  # 받았다. 이 버그는 아파치 일부분으로 제공한 CGI 스크립트와 연관  # 있다. 이 부분의 주석 처리를 없애면 이 버그를 악용하는 공격이 있을  # 때 phf.apache.org 상의 기록 스크립트로 방향 전환시킬 수 있다.  # 또는 support/phf_abuse_log.cgi 스크립트를 사용하여 여러분 직접   # 기록할 수도 있다.  #  <Location /cgi-bin/phf*>      Deny from all      ErrorDocument 403 http://phf.apache.org/phf_abuse_log.cgi  </Location>  #  # 프록시 서버 지시자.  프록시 서버 기능을 작동시키려면 다음 행의  # 주석을 해제시켜준다.  #  <IfModule mod_proxy.c>    #ProxyRequests On    #    #<Directory proxy:*>    #    Order deny,allow    #    Deny from all    #    Allow from .your_domain.com    #</Directory>  #  # HTTP/1.1 "Via:" 헤더를 처리할 것인지 여부를 결정한다.  # ("Full"은 서버 버전을 포함하고 "Block"은 나가는 모든 자료에서  # Via: 헤더를 제거한다.)  # Off | On | Full | Block 중 하나의 값을 지정한다.  #    #ProxyVia On  #  # 캐쉬 기능도 사용하기 위해서는 다음 행의 주석을 풀어준다:  # (CacheRoot가 없으면 캐쉬하지 않음)  #    #CacheRoot "/home/httpd/proxy"    #CacheSize 5    #CacheGcInterval 4    #CacheMaxExpire 24    #CacheLastModifiedFactor 0.1    #CacheDefaultExpire 1    #NoCache a_domain.com another_domain.edu joes.garage_sale.com  </IfModule>  # 프록시 설정 끝  #  #  # 섹션 3: 가상 호스트  #  # VirtualHost: 여러분의 리눅스 박스에 여러 개의 도메인/호스트  # 이름을 관리하고 싶다면 각각에 대하여 VirtualHost 컨테이너를 설정  # 한다. 가상 호스트를 설정하기에 앞서 자세한 설명을  # <URL:http://www.apache.org/docs/vhosts/>에 들러 읽어보기 바란다.  # 가상 호스트 설정 내용을 점검해보기 위해서는 아파치를 실행할 때  # 명령행 옵션으로 '-S'를 사용한다.  #  # 이름 기반의 가상 호스트를 사용하려면 사용할 IP 주소 (최소 1 개,  # 그리고 포트 번호)를 정의해주어야 한다.  #  #NameVirtualHost 12.34.56.78:80  #NameVirtualHost 12.34.56.78  #  # 가상 호스트 예제:  # 거의 모든 아파치 지시자가 VirtualHost 컨테이너에 올 수 있다.  #  #<VirtualHost ip.address.of.host.some_domain.com>  #    ServerAdmin webmaster@host.some_domain.com  #    DocumentRoot /www/docs/host.some_domain.com  #    ServerName host.some_domain.com  #    ErrorLog logs/host.some_domain.com-error_log  #    CustomLog logs/host.some_domain.com-access_log common  #</VirtualHost>  #<VirtualHost _default_:*>  #</VirtualHost>
    2006/09/11 12:59 2006/09/11 12:59
    이 글에는 트랙백을 보낼 수 없습니다
    웅쓰:웅자의 상상플러스
    웅자의 상상플러스
    전체 (379)
    게임 (5)
    영화 (2)
    기타 (23)
    맛집 (5)
    영어 (2)
    대수학 (3)
    형태소 (5)
    Hacking (9)
    Linux (112)
    HTML (48)
    Application_developing (48)
    Web_developing (102)
    Window (11)
    «   2024/04   »
      1 2 3 4 5 6
    7 8 9 10 11 12 13
    14 15 16 17 18 19 20
    21 22 23 24 25 26 27
    28 29 30        
    1. 2016/01 (1)
    2. 2015/12 (3)
    3. 2015/10 (3)
    4. 2015/03 (2)
    5. 2015/01 (4)