2008년 3월 31일 월요일

MySQL my.cnf 설정파일

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

my.cnf

=================================================================
-- 용도별 카피

my-small.cnf : 64M
my-medium.cnf : 128-256M
my-large.cnf : 512M
my-huge.cnf : 1~2G



[mysqld]

key_buffer

- 인덱스를 위한 버퍼 공간
- 키버퍼의 크기는 공유된 쓰레드의 크기이며 중복된 키를 자주 사용할 경우 속도증진
- show status 의 Key_blocks_used 를 체크
Key_blocks_used * 1024 의 2~3 배 ... (메모리충분할 경우)
Key_blocks_used * 1024 (보통)

ex) 아래와 같은 상태가 될때가 key_buffer 가 적당..
Key_reads / Key_read_request < 0.01
key_write / Key_write_requests = 1


max_connections

- show status 의 max_used_connections 를 체크 (최대값보다 10% 크게 설정)

table_cache

- MySQL 서버가 한번에 열수 있는 테이블의 개수설정
- show status 의 Opened_tables 값이 클 경우 table_cache 를 늘림
- max_connections 값이 100 일 경우 100 * n (조인해서 열수 있는 최대테이블개수)
ex) 테이블 20 , max_connections 100 이라면
table_cache = 512


sort_buffer / record_buffer

- max_used_connections 의 값에 따라 증가
- 한번에 많은 쓰레드가 동시에 붙을 경우는 증가
- max_used_connections 가 높은 경우
sort_buffer=6M
record_buffer=2M
(sort_buffer + record_buffer < 8M)
- 메모리가 4G 정도 된다면 sort_buffer 값을 32M 정도를 잡는 것이 좋다.
- order by , group by 절을 빠르게 하기 위해서 sort_buffer 값을 증가시킬수 있다.
- 많은 연속적인 테이블 스캔이 이루어진다면 record_buffer 값을 증가


thread_cache / thread_concurrency

- cpu 개수 * 2



-- 퀴리캐시 설정 방법

set-variable = query_cache_limit=1M
set-variable = query_cache_size=2M
set-variable = query_cache_type=1

-> 쿼리캐시 사용 안할려면 query_cache_size = 0 으로 설정.
-> query_cache_type
1) 0 : off 쿼리캐시 기능을 사용하지 않음
2) 1 : on , SELECT SQL_NO_CACHE 를 제외하고 쿼리캐시사용
3) 2 : DEMAND, SELECT SQL_CACHE 사용시만 쿼리캐시사용

-> 쿼리캐시 변수보기
show variables like 'query%';

+-------------------+----------+
Variable_name Value
+-------------------+----------+
query_cache_limit 1048576
query_cache_size 33554432
query_cache_type ON
+-------------------+----------+

-> 쿼리캐시 상태보기
show status like 'qcache%';

+-------------------------+----------+
Variable_name Value
+-------------------------+----------+
Qcache_queries_in_cache 12780 : 캐시에 등록된 쿼리수
Qcache_inserts 2084642 : 캐시에 추가된 쿼리수
Qcache_hits 173194 : 캐시에 있는 쿼리를 사용한 수
Qcache_lowmem_prunes 361897
Qcache_not_cached 23724 : 쿼리를 캐시에 저장하지 않은 수
Qcache_free_memory 20055720 : 캐시가 남은 공간
Qcache_free_blocks 6237 : 쿼리캐시에서 남은 메모리 블록
Qcache_total_blocks 32000 : 쿼리캐시가 사용하는 총 블록 수
+-------------------------+----------+
-> FLUSH
FLUSH QUERY CACHE 쿼리 캐시를 재정렬하므로 메모리를 유용하게 사용하도록 해준다.
(단 쿼리캐시를 비우지는 않는다)

FLUSH TABLES 쿼리 캐시 버퍼를 비운다.
( Qcache_queries_in_cache = 0 , Qcache_table_blocks = 1

FLUSH QUERY CACHE 는 모든 쿼리 캐시를 삭제



-- 로그설정

log-isam=파일경로
log-slow-queries=파일경로
long_query_time=5



EX ) MySQL 메모리 사용량

innodb_buffer_pool_size
+ key_buffer
+ max_connections * (join_buffer + record_buffer + sort_buffer + thread_stack + tmp_table_size)
+ max_connections * 2MB





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

튜닝참조

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

1. Opened_tables가 크면 table_cache variable의 값이 너무 작은것일지도 모른다

2. key_reads가 크면 key_cach의 값이 너무 작은것일지도 모른다

3. cache hit rate은 key_reads/key_read_requests이다

4. Handler_read_rnd가 크면 MySQL의 모든 테이블을 스캔하는 많은 쿼리가 있다거나 key를 적절히 사용하지 않는 조인들이 있을지 모른다

5. Threads_created가 크면 thread_cache_size값을 증가시키기를 바랄수도 있다

6. Created_tmp_disk_tables이 크면 디스크대신 임시테이블메모리를 얻기위해 tmp_table_size값을 증가시키기를 원할 수있다

7. 기본적으로 support-files밑에 my-huge.cnf, my-large.cnf, my-medium.cnf, my-small.cnf 를 기본으로 my.cnf 로 바꾸어 사용하면서 조정한다.

- memory (>=256M)이고 많은 테이블이 있으며, 적당한 클라이언트수에서 최고 성능을 유지하기 위해
shell> safe_mysqld -O key_buffer=64M -O table_cache=256 -O sort_buffer=4M -O record_buffer=1M &
이러한 옵션으로 서버를 실행하는데, my-cnf에서 이를 수정하여 사용하면 될 것이다.

- 128M메모리에 테이블이 적지만, 정렬이 많을 때
shell> mysqld_safe -O key_buffer=16M -O sort_buffer=1M

- 메모리는 적지만 많은 연결이 있을 때
shell> mysqld_safe -O key_buffer=512k -O sort_buffer=100k -O record_buffer=100k &
또는
shell> mysqld_safe -O key_buffer=512k -O sort_buffer=16k -O table_cache=32 -O record_buffer=8k -O net_buffer=1K &


8. group by와 order by작업이 가지고 있는 메모리보다 훨씬 클 경우, 정렬 후 row 읽는 것을 빠르게 하기위해 record_buffer값을 증가시켜라
[출처] my.cnf 설정파일작성자 아진

2008년 3월 27일 목요일

국내 UCC 동영상 서비스 화질 비교

<출처 : Mindstor.net @Tistory>

 

 

작년 이맘때 Daum과 엠앤캐스트 동영상 화질을 비교하였는데 1년이 지난 지금 많은 동영상 서비스들이 생겼네요. 그래서 다시 한번 화질 비교를 해보았습니다.

비교에 사용된 동영상 소스는 WMV9 코덱을 사용하여 크기는 720x486 px, 초당 프레임은 30fps 이며 비트레이트는 1.62Mbps 입니다. 음성 코덱은 WMA 128Kbps입니다. 동영상은 일부러 빠른 장면이 섞인 것을 사용하였습니다. 느리거나 정지장면에서는 비트레이트 차이가 잘 느껴지지 않더라고요. ^^

사용자 삽입 이미지

이번에는 시각적인 화질보다는 구체적으로 수치 데이타를 정리해보았습니다. 작년과 달리 1년만에 다들 비트레이트도 2배 이상 높아지고 Daum이 처음으로 400x300px를 했을 때 큰 사이즈였는데 지금은 제일 작은 사이즈가 될 정도로 빠른 변화의 모습을 보여주고 있습니다.

비교해보니 인트로 영상과 광고가 나오긴 하지만 화질과 크기에 있어서 엠군이 제일 발군의 모습을 보고 있습니다. 엠앤캐스트 서버 인코딩도 비트레이트가 엠군과 같이 1Mbps로 비슷하지만 공개 FLV 동영상 코덱을 써서 ON2VP6 코덱을 사용하고 있는 엠군과 비교가 되지 않습니다.

네이버는 최근 블로그 적용된 플레이어는 500px로 크고 보기 좋은데 플레이에서는 그렇지 않습니다. 8월7일 약관 개정 공지가 난 것을 보니 이때 개편하여 오픈하는 모양인데 개편 후에 블로그 크기와 동일한 형태로 바뀌지 않을까 싶습니다. 비디오 서비스로 개편을 하면서 플레이어 크기를 500x408px로 개편을 했습니다. 포탈서비스에서는 화질이나 크기에서 네이버의 제일 경쟁력이 가진 상태라고 생각하지만 문제는 늦은 감이 있다는 것이지요.

태그스토리는 동영상 저장형태를 변형하였는지 Sniff를 이용하여 다운로드도 불가하고 'UCC다바다'로 동영상을 받아도 FLV Player에서 재생이 불가능하여 비트레이트나 중요한 정보를 확인할 수 없었습니다. 다만, 용량이 11.8MB인 것을 보아 비트레이트는 400Kbps 이하가 아닐까 추측합니다.

마지막으로 다들 동영상에 노출되는 회사 로고를 동영상과 분리하여 레이어로 노출하고 있으나 하나포스 '앤유'와 프리챌 'Q'는 동영상에 박아서 이를 뺄 수 없게한 만행(-_-+)을 보여주고 있었습니다.

고화질로 돌아가는 동영상 시장 사업자쪽은 비용이 증가하여 괴로운 일이지만 이용자 입장에서는 좋은 화질로 즐길 수 있으니 좋은 일일까요? 6^^


 













2008년 3월 25일 화요일

[u미디어포럼]온라인 동영상 광고는 진화 중

방송통신 융합 시대를 맞아 얼마 전 온라인 검색 마케팅 시장의 변화를 한눈에 볼 수 있는 ‘검색 엔진 마케팅 콘퍼런스 2008’이 열렸다.

그 가운데 중요한 의제의 하나로 다뤄진 내용은 방송이 인터넷으로 서비스하면서 동영상 콘텐츠 양이 빠른 속도로 증가하고 이에 따라 검색 엔진도 기존에 텍스트 대상에서 점차 동영상 콘텐츠로 변화하고 있다는 것이었다.

인터넷 포털·방송사·UCC 업체도 기하급수적으로 증가하는 다양한 동영상 콘텐츠를 어떻게 수익으로 만들 수 있을지 고민하고 있다. 이런 시점에서 동영상 검색 엔진 마케팅은 관련 업체의 관심을 끌기에 충분했다. 

사실 이제까지 우리나라 대표 포털은 전문 데이터베이스를 누가 많이 확보하는지가 관건이었다. 네티즌은 검색어를 넣었을 때 얼마나 많은 정보가 정확하게 검색되는지에 따라 포털 사이트를 옮겨다니기 때문이다. 대부분 데이터베이스가 텍스트 기반이어서 검색 엔진도 텍스트 위주로 발전돼 왔다. 방송통신 융합과 UCC 세상이 열리기 전의 일이었다.


현재는 방송 콘텐츠와 더불어 이용자가 직접 올린 ‘UCC’ 검색 전쟁으로 승부처가 바뀌고 있다. 다음커뮤니케이션은 ‘우리들의 UCC세상 다음’이라는 캐치프레이즈 아래 동영상 서비스와 검색 엔진을 강화하고 네이버 역시 뉴스 서비스·UCC·블로그 등에서 라이브와 동영상 서비스를 향상시키고 동영상 검색 서비스에 주력하고 있다. 

동영상 검색 서비스 시장이 활발한 배경에는 온라인 광고의 질적 변화가 자리 잡고 있다. 지금까지 텍스트·이미지·플래시 형태였던 온라인 광고는 점차 동영상 광고로 발전하고 있다. 실제로 온라인 광고 분야를 살펴보면 텍스트 광고 영역은 감소한 반면에 동영상 광고 서비스 영역은 2006년 이래로 광고 집행 규모가 매년 10% 이상 꾸준히 증가하고 있다.

시장 움직임에 따라 시청률 조사 전문회사인 TNS미디어 코리아도 동영상 광고 시장에 관심을 갖고 전문 동영상 광고 미디어 렙과 제휴를 맺었다. 온라인 광고 기술은 단순한 동영상 광고가 아닌, 동영상 콘텐츠·매체별 각기 다른 광고를 집행할 수 있는 타깃 광고가 가능한 상황에 와 있다. 예컨대, 헤어스타일 동영상에는 머리 관련 상품과 서비스를 집중 광고하고, 어린이용 학습 동영상에는 어린이 완구나 학습지 광고를 집행해 타깃 소비자층의 소비를 극대화할 수 있다. 게임 사이트는 클라이언트 다운로드 시 해당 페이지에서 게임 사용자를 타깃으로 별도의 온라인 동영상 광고가 가능하다. 

특히 방송·통신 융합 시대에 발맞춰 방송 서비스와 광고 서비스를 접목하면 ‘브랜딩이 결합된 상호작용(Branded Interactivity)’을 이끌어낼 수 있다는 장점도 광고주의 구미를 당긴다. 그래서 많은 기업이 지상파TV 광고와 별도로 온라인 동영상 광고를 제작해 집행하고 있다. iMBC도 올 초 효율적인 광고 집행과 다양한 방식의 광고를 위해 동영상 광고 미디어 렙사와 계약을 했다. 지난해 UCC 시장이 급격히 팽창하면서 각 언론에서는 사업성을 우려했다. 더불어 방통 융합 시대에 접어들면서 온라인 광고 시장에 대한 기대는 막연히 커지고 있다. 

온라인 광고 시장은 더 이상 막연한 것이 아니며 구체적인 방법과 기술이 마련돼 있다. 기존 배너 광고와 일방적인 푸시(push)형 온라인 광고에 냉담한 네티즌은 자신들이 관심을 가질 수 있는 색다른 광고를 기대하고, 예산만 집행할 뿐 광고 효과를 측정할 수 없었던 광고주는 어느 대상에 얼마 만큼의 광고가 노출되었는지 효과를 객관적으로 검증하고 싶어한다. 

동영상 광고는 이런 네티즌과 광고주 요구를 해결해 줄 수 있는 매개 역할을 맡을 수 있는 절호의 기회에 있다. 동영상 광고 시장은 이미 움직이고 있고, 시장 요구에 대응하기 위해 미디어 렙도 지금까지의 관행을 벗어나 기술을 개발하고 아이디어를 접목시키면서 발빠르게 움직이고 있다. 광고 크리에이티브와 더불어 새 시장에 걸맞은 새 형태의 광고 콘텐츠를 아이디어와 결합해 운용하는 것이 어느 때보다 중요한 시점이다.

강영훈 엔톰애드 대표 (yhkang@ntomad.co.kr)

2008년 3월 17일 월요일

cannot restore segment prot after reloc: Permission denied 

[root@localhost libexec]# /usr/local/apache/bin/apachectl start
Syntax error on line 205 of /usr/local/apache/conf/httpd.conf:
Cannot load /usr/local/apache/libexec/mod_pyapache.so into server: /usr/local/apache/libexec/mod_pyapache.so: cannot restore segment prot after reloc: Permission denied

이런 황당한 에러는... 아래와 같이 하면 해결됨.

[root@localhost libexec]# restorecon -R -v /usr/local/apache/libexec

또는

[root@localhost libexec]# chcon -t texrel_shlib_t /usr/local/apache/libexec/mod_pyapache.so

2008년 3월 16일 일요일

웹 어플리케이션 취약점 종류 및 해결 방법

1) upload 취약점

.php .ph 등의 file을 업로드 한 후 bindshell을 통해 웹서버 권한을 획득하는 기법이다. 이러한 스크립트가 파일이 저장되는 디렉토리에 대해서 소스처리 하는 방법이다.

아파치(Apache) 설정 예제는 다음과 같다.




AddType application/x-httpd-php3-source .phps .php .ph .php3 .cgi .sh
.pl .html .htm .shtml .vbs .ins
AddType application/x-httpd-php-source .phps .php .ph .php3 .cgi .sh
.pl .html .htm .shtml .vbs .ins



Order allow,deny
Deny from all



2) setup file 노출

아파치의 httpd.conf에 다음 줄을 추가하여 패스워드, 데이터베이스 등의 설정파일이 노출되는 문제를 해결할 수 있다.

AddType application/x-httpd-php .php .php3 .ph .inc


3) 디렉토리, 파일 인가(Directory, File Permission)

웹 어플리케이션 설치 시 Directory 및 해당 File이 모든 유저에 대해 쓰기권한이 적용되는 경우가 존재한다. nobody를 제외한 유저들의 쓰기 권한을 제거하고, 해당 글이 저장되는 파일에 대한 인가(permission)을 검사한다.


4) shell 실행 함수 및 파일 오픈관련 함수

system(), passthru(), exec(), popen(), escapeshellcmd(),` `(Backticks) 및 fopen(), include() 함수 등을 사용할 경우, 메타캐릭터 문자인 .<>*|'&;$!#()[]{}:"/^\n\r 를 제거해주도록 하자.


5) 버퍼 오버플로우(Buffer Overflow)

아래와 같은 종류의 함수를 사용할 때는 버퍼 크기에 주의하도록 한다.

gets (),getenv(), strcpy (), strcat (), sprintf (),
fscanf (), scanf (), sscanf (), vscanf(),vsscanf (),
vfscanf(),vsprintf (),realpath (), getopt (), getopt_long(),
getpass (), streadd (),strecpy (), strtrns ()

되도록이면 bcopy(), fgets(), memcpy(), strncpy(), snprintf(), strccpy(), strcadd(), vsnprintf()으로 대체해서 사용하도록 한다.


6) SQL Injection

웹 어플리케이션은 보통 데이터베이스와 연동이 되는 경우가 많다.

SQL Injection은 사용자의 입력이 필요한 곳에 SQL Query 문을 넣어 악의적인 명령어를 수행하는 기법이다. 이에 대한 해결책으로는 사용자의 입력이 필요한 부분에 <>*|'&;$!#()[]{}:"/^\n\r 등의 쉘 메타캐릭터를 사용하지 못하도록 제거하는 것이다.

PHP의 설정화일인 php.ini에서는 보안을 강화하는 옵션이 존재한다. 다음 옵션을 조정하여 보안을 강화시킨다.

allow_url_fopen = Off
magic_quotes_gpc = On
register_globals = Off

현재 국내에서 사용되는 KorWeblog 그누보드, 제로보드, 테크노트등의 취약점이 존재하므로, 보안패치를 적용하지 않은 사용자들은 즉시 보안패치를 적용하도록 하자.

2008년 3월 13일 목요일

Windows에 아파치 + 톰캣 + modpython 적용하기

보통 개발시 아파치 + 톰캣, 또는 아파치 + modpython을 매번 사용해 왔는데, 특별히 정리해 놓은 문서가 없어 정리를 해 보았다.













1. 아파치 설치

아파치 다운로드
아파치 설치 (설치디렉토리예: C:/apache2)
2. 톰캣설치

톰캣 다운로드
톰캣 설치 (설치디렉토리 예: C:/tomcat)
3. 아파치에서 mod_jk2를 이용하여 톰캣 연동하기

modjk2 모듈다운로드 - mod_jk2
아파치설정 (c:/apache2/conf/httpd.conf)

LoadModule jk2_module modules/mod_jk2.so

아파치설정 (c:/apache2/conf/workers2.properties) - 없다면 생성하자.

[shm]
info=Scoreboard. Requried for reconfiguration and status with multiprocess servers.
file=anon

# Example socket channel, override port and host.
[channel.socket:localhost:8009]
port=8009
host=127.0.0.1

# define the worker
[ajp13:localhost:8009]
channel=channel.socket:localhost:8009

# Uri mapping
[uri:10.0.0.10/*.jsp]
worker=ajp13:localhost:8009

[uri:pey.avis.com/*.jsp]
worker=ajp13:localhost:8009

[uri:pey.automs.com/*.jsp]
worker=ajp13:localhost:8009
위 내용을 보면 알겠지만, uri에 설정한 URL(위:*.jsp)로 request가 들어올 경우 8009포트(톰캣)로 request를 전달하고 있다.


톰캣설정 (c:/tomcat/conf/server.xml)


enableLookups="false" redirectPort="8443" debug="0"
protocol="AJP/1.3" URIEncoding="KSC5601" />
8009포트에 AJP/1.3이라는 프로토콜을 사용하여 request를 처리한다. 요새 나오는 톰캣버전의 server.xml에는 위 사항이 디폴트로 적용되어 있으니 빠져있지만 않다면 특별히 수정할 사항은 없다. 단 GET방식의 request일 경우 URIEncoding에 KSC5601을 설정해 주어야 한글처리가 가능하다는 점을 유의해야 한다.

4. 가상 호스트 설정

한 PC에서 여러개의 웹싸이트를 개발하고 있다면 가상호스트를 설정하여 사용하면 편리하다. 아파치, 톰캣 설정을 반복하는짓을 그만둘수 있다.


hosts(C:/WINNT/system32/drivers/etc/hosts)파일 수정
필자의 hosts파일 예

127.0.0.1 localhost
127.0.0.1 pey.avis.com
127.0.0.1 pey.automs.com
127.0.0.1 pey.dev.com
127.0.0.1 pey.note.com

아파치 설정(c:/apache2/conf/httpd.conf)
필자의 Virtual Host예

NameVirtualHost *:80


ServerName pey.avis.com
ServerAlias www
ServerAlias localhost
ServerAdmin pey@tdd.or.kr
DocumentRoot "d:/AVIS/avis/httphome/avis/"
ErrorLog logs/avis-error.log
CustomLog logs/avis-access.log common


JkUriSet worker ajp13:localhost:8009




ServerName pey.automs.com
ServerAdmin pey@tdd.or.kr
DocumentRoot "d:/AVIS/automs/"
ErrorLog logs/automs-error.log
CustomLog logs/automs-access.log common


JkUriSet worker ajp13:localhost:8009




ServerName pey.dev.com
ServerAdmin pey@tdd.or.kr
DocumentRoot "d:/por/"
ErrorLog logs/por-error.log
CustomLog logs/por-access.log common



ServerName pey.note.com
ServerAdmin pey@tdd.or.kr
DocumentRoot "d:/note/"
ErrorLog logs/por-error.log
CustomLog logs/por-access.log common


톰캣설정 (c:/tomcat/conf/server.xml)
필자의 Host설정 예


localhost
www
10.0.0.10





5. mod_python 적용


mod_python download (http://www.modpython.org)
mod_python 설치 (win32용 프로그램으로 인스톨)
아파치 설정 (c:/apache2/conf/httpd.conf)

LoadModule python_module modules/mod_python.so


Options Indexes FollowSymLinks ExecCGI
AllowOverride None
Order allow,deny
Allow from all

AddHandler mod_python .py
PythonHandler mod_python.cgihandler
PythonDebug On



Options Indexes FollowSymLinks ExecCGI
AllowOverride None
Order allow,deny
Allow from all

AddHandler mod_python .py
PythonHandler mod_python.cgihandler
PythonDebug On

위에서 설정한 가상호스트를 modpython cgihandler와 연결시킨 예제이다.

document 접근에 contentDocument property의 사용

[Object].document 접근시
IE외에는 frame의 document 접근에 contentDocument property를 사용하면 됩니다.




f = document.getElementById("frame");

if ( f.contentDocument ) {

src_doc = f.contentDocument;

working_title = src_doc.title;

}

Linux 서버 점검사항들

1. SUID 점검하기.(root 소유의 SetUID및 SetGID 파일들 점검
find / -user root -perm -4000 -print (SetUID)
find / -user root -perm -2000 -print (SetGID)
find / -user root -perm -4000 -print -xdev
2. 파티션별 디스크사용량 점검
df –h

3. 파일무결성 점검.
tripwire 구성

4. 백도어 설치여부 점검.(/dev 체크 및 rootkit 점검)
find /dev -type f -exec ls -l {} ;
./chkrootkit

5. 현재 열려진 포트 및 응답가능한 포트 점검.
netstat -atp | grep LISTEN (사용 프로토콜 : TCP인가? 또는 UDP인가?
사용중인 포트번호
서버와 연결된 IP 및 도메인명
생성 PID
서비스중인 프로세스명
현재 응답가능상태인가?
lsof | grep LISTEN(현재 서비스 중인 프로세스명(데몬명)
현재 생성중인 PID번호.
현재 서비스중인 프로세스의 소유자
프로토콜 버전 : Ipv4 또는 Ipv6
TCP 또는 UDP의 여부
응답가능 상태인가?

6. 실생중인 프로세스 및 데몬점검.(프로세스의 생성관계)
Pstree

7. 시스템 운용상황 점검.
top -d2

8. 백업점검.
/home2/backup/nexfor/
/home2/backup/websea/

9. 스팸메일 점검.(메일큐 디렉토리 점검)
/var/spool/mqueue (동일한 날짜, 동일한 사이즈를 가진 다수 파일구분)

10. Core 점검.
서버내에 긴급한 이상이 발생하였을 경우나 시스템의 정확한 분석을 위해
서버의 메모리 상태를 순간적으로 dump 받는 경우의 파일
find / -name core -exec ls -l {} ;

11. 파일용량 점검
repquota -av -ag
df –h

12. 최근 서버 접속자 점검.

vi /var/log/secure
last -n 10 최근 10번째까지의 접속기록을 확인.

13. 계정별 최후접속기록 점검.
lastlog는 현재 /etc/passwd에 존재하는 모든 계정을 대상으로 하
여 언제 마지막으로
서버에 접속을 했는가를 확인.
Mail, adm, bin 등의 계정들은 모두 "** Never logged in **" 이라
고 되어 있는것이 정상.
Lastlog

14. 현재 서버접속자 보기
w (telnet)
ftpwho(ftp)

15. root명령어 사용기록 점검.
vi /root/.bash_history (.set nu)
cat /root/..bash_history | wc -l (1000라인 이상 되어야 정상)

16. 계정별 사용명령어파일 점검.
find / -name .bash_history -exec ls -l {} ; (각 계정
별 .bash_history 파일의 존재여부)
find / -name .bash_history -exec cat {} ; (파일의 내용까
지 모두 확인해 볼 수 있음)

17. root소유자 점검(UID와 GID가 0인 사용자 점검)
cat /etc/passwd | grep 0:0

18. 서버내에 중요한 디렉토리 점검
/etc/xinetd.d/ (xinetd로 서비스되는 인터넷서비스 파일들이 존재하는 디렉토리)
/etc/rc.d/ (부팅에 관계된 파일) (파일들을 복사 후 파일용량등을 비교하기) (커널패닉의원인)
/etc/rc.d/init.d/ (부팅시에 특정 서비스나 데몬들을 시작시키는 스키립트 파일)

19. .rhosts 파일 점검
원격에서 패스워드등의 확인과정없이 바로 접속하기 위해서 사용되는 파일

find / -name .rhosts -exec ls -l {} ;
find / -name .rhosts -exec cat {} ;

20. 메모리사용량 점검.
free -m
cat /proc/meminfo (free 와 top 는 이 파일을 참조하여 보여준다.)
top -d2

21. 중요 관리자용명령어 점검.
아래의 명령어들을 퍼미션을 100으로 설정한다. 변경 후 퍼미션 변경여부를 확인.

chmod 100 /usr/bin/top
chmod 100 /usr/bin/pstree
chmod 100 /usr/bin/w
chmod 100 /bin/ps
chmod 100 /usr/bin/who
chmod 100 /usr/bin/find
chmod 100 /bin/df
chmod 100 /bin/netstat
chmod 100 /sbin/ifconfig
chmod 100 /usr/sbin/lsof
chmod 100 /usr/bin/make
chmod 100 /usr/bin/gcc
chmod 100 /usr/bin/g++
chmod 100 /usr/bin/c++

22. su 명령어를 이용한 root권한 사용자 점검.
su 명령어의 사용내역을 확인할 수 있음.
cat /var/log/messages | grep root

23. 최근 n 일전 변경된 파일 점검. (단위는 일)
find / -ctime -1 -print | more

24. http://weblog 점검

25. find 를 이용한 특정파일 점검하기.
.exec 파일찾기
find / -name '.exec' -exec cat {} ; -print
.forward 파일체크
find / -name '.forward' -exec cat {} ; -print
write 퍼미션이 있는 파일(디렉토리)찾기
find / -type f ( -perm -2 -o -perm -20 ) -exec ls -lg {} ;
find / -type d ( -perm -2 -o -perm -20 ) -exec ls -ldg {} ;
SteUID SetGID 체크하기
find / -type f ( -perm -004000 -o -perm -002000 ) -exec ls -
lg {} ;
/dev 체크
find /dev -type f -exec ls -l {} ;
소유자없는 파일 및 디렉토리 찾기
find / -nouser -o -nogroup -print
원격리모트 접속허용 파일(.rhosts)찾기
find / -name .rhosts -print
최근 변경된 파일들 찾기.(파일or디렉토리) 단위는 일
find / -ctime -20 -type f or d
현재 서버에서 열려진 포트 및 접근저보 점검
netstat -an | grep LISTEN (포트들과 열결되어 있는 실행데몬들을 확인)
lsof | grep LISTEN (좀 더 자세히 확인)

26. 관리자용 명령어 퍼미션 수정하기.
chmod 100 /usr/bin/top
chmod 100 /usrbin/pstree
chmod 100 /usr/bin/w
chmod 100 /bin/ps
chmod 100 /usr/bin/who
chmod 100 /usr/bin/find
chmod 100 /bin/df
chmod 100 /bin/netstat
chmod 100 /sbin/ifconfig
chmod 100 /usr/sbin/lsof
chmod 100 /usr/bin/make
chmod 100 /usr/bin/gcc
chmod 100 /usr/bin/g++
chmod 100 /usr/bin/c++

27. 중요한 파일퍼미션과 소유권 제한 및 점검.
chmod 644 /etc/service
chmod 600 /etc/xinetd
chmod 644 /etc/mail/aliases
chmod 600 /etc/httpd/conf/httpd.conf
chmod 644 /var/log/wtmp
chmod 644 /var/run/utmp
chmod 644 /etc/motd
chmod 644 /etc/mtab
chmod 600 /etc/syslog.conf

/etc, /usr/etc, /bin, /usr/bin, /sbin, /usr/sbin
chmod 1777 /tmp
chmod 1777 /var/tmp

28. umask 값 확인하기.
root의 umask 값 확인하기.
umask
022 -->파일은 644 디렉토리는 755로 생성됨.
027 -->파일은 640 디렉토리는 750로 생성됨.

29. /dev 에 device 파일 이외의 것이 존재하고 있는지 확인.
find /dev -type f -exec ls -l {} ;

30. 일반사용자의 명령어 패스
/usr/local/bin:usr/local/mysql/bin:/home/hosting/bin/
일반사용자가 사용가능한 명령어를 모두 이것에 둠.

31. 관리자의 명령어 패스
:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:/usr/bin
/X11:/usr/X11R6/bin:/usr/kerberos/bin:/root/bin

32. 특정 그룹만의 su 사용권한 허용하기
vi /etc/group (wheel구릅에 su 사용권한을 가질 유저 추가하기)
wheel:x:10:root,cream
vi /etc/pam.d/su (두줄 추가하기)
auth sufficient /lib/security/pam_rootok.so
auth required /lib/security/pam_wheel.so allow group=wheel
vi /var/log/message 에서 확인

33. chmod 400 /etc/shadow

34. 시스템 기본로그파일.
/var/log/messages
/var/log/secure
/var/log/wtmp
/var/run/utmp
/var/log/lastlog

35. utmp, wtmp, lastlog 파일
utmp파일 : 현재시스템에 접속해 있는 사용자의 정보를 가지고 있음.

strings utmp | more

정보 이용 명령어
login(1), who(1), init(8), last(8), lastcomm(8)
wtmp파일 : 처음부터 접속했던 모든 사용자의 로그인정보와 로그아웃정보를 가지고 있음.
strings wtmp | more
정보 이용 명령어
login(1), who(1), init(8), last(8), lastcomm(8)
lastlog 파일
가장 최근에 로그인한 정보를 저장함.
last 라는 명령어로 확인할 수 있음.

36. 패스워드 유출대처방안(웹)
perl을 이용한 방법.

AllowOverride FileInfo AuthConfig Limit
Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
Options Indexes SymLinksIfOwnerMatch IncludesNoExec ExecCGI
Options Indexes SymLinksIfOwnerMatch IncludesNoExec

Order allow,deny
Allow from all


Order deny,allow
Deny from all


SSI의 exec 명령어를 이용하는 방법
# AddType text/html .shtml
# AddHandler server-parsed .노싀

37. PortSentry를 이용한 실시간 해킹방어 구현.(잘못 사용할시 서버접속 안됨)
tar -xvzf portsentry-1.1.tar.gz
make linux
make install
/usr/local/psionic/portsentry/portsentry -tcp
/usr/local/psionic/portsentry/portsentry -udp
/usr/local/psionic/portsentry/portsentry -stcp
/usr/local/psionic/portsentry/portsentry -atcp
/usr/local/psionic/portsentry/portsentry -stdp
vi /etc/hosts.deny 점검.

38. Chkrootkit 로 백도어 점검.
tar -xvzf chkrootkit.tar.gz
make sense
./chkrootkit (점검명령어)

39 ping 을 이용한 DOS 공격 막는 방법.
vi /etc/sysctl.conf
net.ipv4.icmp_echo_ignore_broadcasts = 1
sysctl -w
/etc/rc.d/init.d/network restart
sysctl -a | grep ignore_broadcasts

40. Nmap를 이용 포트스캔 하여 해킹가능성 체크.
nmap -sS -p80 211.42.48.110 -O -v 도메인
nmap -sS -O -v 211.42.48.114

출처: 멀티의 블로그 라이프

Exception handling과 readability

프로그래밍을 하다 보면 참으로 어처구니없이도 많은 Exception을 만나게 됩니다.
언어와 플랫폼에 무관하게 언제든지 exception은 프로그래머를 잡아먹을 기세로 눈을 번뜩이고 있습니다. 그래서 사용하는 exception처리 기법이 try-catch 구조 입니다.

의외로 경력 깨나 된다는 분들도 try-catch 구문을 무시하는 경향이 있습니다.
readability(가독성)을 몹시 떨어뜨리는 데다가 로직의 흐름을 한눈에 보기 힘들게 만들기도 하고, 코드가 길어지게 합니다. 때로는 디버그를 위해서 어떤 에러가 나는지를 직접 에러를 일으켜 보면서 따라가 봐야 할 때도 있습니다. 그래서 경험많은 프로그래머들도 깜빡 빼먹기 쉽습니다.

이쯤 읽으셨으면 "나는 이거 안읽어도 되겠다", 혹은 "한번 읽어봐야겠다"는 판단이 드실겁니다. 맞게 판단하셨으니 그렇게 하시면 됩니다^^ 어렵게 익힌 테크닉이나 심오한 로직따위는 나오지 않습니다.;;;

각설하고..
try-catch의 아이디어는 간단합니다.

어떤 코드를 우선 try(시도)합니다. 시도 결과 exception이 발생하면, 미리 정의된 exception 대응 행동(catch)을 수행합니다. 요즘의 대부분의 CPU는 exception이 생기는 몇가지 상황을 정의해 두었고 이 때에 특정 핀에 신호가 뜸으로서 exception을 알려줍니다. 이를 직접 사용하기도 하고, 컴파일러, 특정 API 또는 인터프리터레벨에서 한단계 더 포장하여 사용하는 경우도 많이 있습니다.
뭐가 됐건 간에 시도후에 실패하면 처리할 코드를 미리 정의해 두는게 기본 아이디어입니다.

C++, C# 등에서는,
[CODE type=cpp]
try {
// some statements...
} catch (Exception e) {
// handling statements...
}
[/CODE]
이와 같은 구문을 쓰죠.. 발생한 exception은 보통 객체(객체의 참조)로 전달받을수 있는데, 이는 사용하는 컴파일러, API, SDK, Framwork등 오만가지 이름으로 불리워지는 개발 플랫폼-_-에 의해 그 Type 명이 달라지기도 하므로 사용하는 개발환경의 문서를 참고하여 만들면 됩니다.

Python에서는
[CODE type=python]
try:
# some statements
except:
# handling statements
[/CODE]
이렇게 쓰면 됩니다.

미리 정의된 구체적인 Exception을 핸들링 할 때에는, 예를들어,
[CODE type=python]
try:
# some statements
except KeyboardInterrupt:
# Ctrl-C handling statements
except:
# handling statements
else:
# No exception
[/CODE]
이런 구문으로 Ctrl-C키를 눌러 중단시그널을 보냈을 경우와 기타 exception이 일어났을 경우, exception이 하나도 안생겼을 경우 수행할 코드까지 모두 정의 가능합니다.
[CODE type=python]
try:
# some statements
finally:
# whether an exception is asserted or not
[/CODE]
이렇게 하면 try후에 exception이 있던 없던 간에 finally 코드가 수행됩니다.
하지만 except: 구문과 finally: 구문은 함께 있을수는 없습니다. Python document에 의하면, 어떤 것을 먼저 수행해야 하는지가 모호해 지기 때문에 막는다고 되어있군요..

어찌됐건 예기치 못한 에러 상황에서 애써 작성한 프로그램이 죽어버리는 일이 생기지 않도록 하려면 exception handler를 만들어 주어서 에러를 견뎌 내도록 만들어 주어야 합니다.
이게 말이 쉽지 막상 그렇게 코드를 만들려고 하면 보통 짜증나는 일이 아닙니다.ㅡ_ㅡ

다음 예를 보죠..
[code type=python]
def get_host_and_port(s_addr='localhost:13579'):
'''
s_addr로 hostname:port notation의 서버주소를 받아서 호스트명과 포트번호를 쪼갠다.
'''
s_fields = s_addr.split(':')
from string import atoi
return s_fields[0], atoi(s_fields[1])
[/code]
이 간단한 함수는 고맙게도 왠만해서는 매우 훌륭히 작동해 줍니다^^
Python의 interactive-mode prompt에서 수행하면 이렇게 됩니다.
[code type=python]
>>> get_host_and_port('asdf.com:1234')
('asdf.com', 1234)
[/code]

그런데 문제가 있죠..
[code type=python]
>>> get_host_and_port('asdf.com')
Traceback (most recent call last):
File "", line 1, in ?
File "", line 4, in get_host_and_port
IndexError: list index out of range
[/code]
그렇습니다. 포트번호를 안주면 에러가 납니다.
그래서 코드를 고칩니다.
[code type=python]
def get_host_and_port(s_addr='localhost:13579'):
'''
s_addr로 hostname:port notation의 서버주소를 받아서 호스트명과 포트번호를 쪼갠다.
'''
s_fields = s_addr.split(':')
from string import atoi
try:
hostname = s_fields[0]
portnum = atoi(s_fields[1])
except:
portnum = 13579 # default port로 가정
return hostname, portnum
[/code]
이번에는 잘 될까요?

[code type=python]
>>> get_host_and_port('asdf.com')
('asdf.com', 13579)
>>> get_host_and_port(3)
Traceback (most recent call last):
File "", line 1, in ?
File "", line 5, in get_host_and_port
AttributeError: 'int' object has no attribute 'split'
[/code]
이전에 exception을 내던 문제는 해결됐는데 다른 문제가 또 있군요..
이번 문제는 parameter의 type문제 입니다. 결정을 해야 합니다. 숫자 파라메터를 받을수 없다고 exception을 내버리던지, 에러를 리턴하던지, 무시하고 미리 정의된 기본값으로 리턴할지..

이렇게 수정해 봅니다.
[code type=python]
def get_host_and_port(s_addr='localhost:13579'):
'''
s_addr로 hostname:port notation의 서버주소를 받아서 호스트명과 포트번호를 쪼갠다.
'''
try:
s_fields = s_addr.split(':')
except:
return ('localhost', 13579)

from string import atoi
try:
hostname = s_fields[0]
portnum = atoi(s_fields[1])
except:
portnum = 13579 # default port로 가정
return hostname, portnum
[/code]
처음의 단 두줄짜리 함수가 이렇게 지저분하게 indenting되며 늘어집니다.
자칫 코드에 로직이 선명히 보이지 않게 될 수 있습니다.
지금 예로 든 함수도 적절히 디버그되지 못하였습니다. 다만 try-catch 구문의 거의 유일한 단점인 가독성 저해를 강조해 보려고 일부러 저렇게 만든 것입니다. 가져다 쓰지 마세요. 위험한 프로그램을 만들어 줄겁니다;;;
(참고로 위 함수는 리턴이 두번 나옵니다. 매우 바람직하지 못하므로 도저히 피해갈수 없는 상황을 제외하고서는 절대 여러개의 리턴을 가지는 함수를 만들지 마세요. 석달후에 후회합니다. 게다가 아직도 핸들링되지 않은 exception발생가능성이 10,12,16 라인 등에 도사리고 있습니다. 로직 자체에도 결함이 있습니다. 귀차니즘의 압박으로...쿨럭;;;)

이렇게 코드가 더러워진듯 보여도 실제 저 코드를 사용하는 프로그램이 죽어버릴 가능성은 많이 줄어들었습니다^^

안정적으로 잘 돌아가는 프로그램일수록 소스코드는 try-catch로 얼룩져 있습니다.
개발직후 갖은 혹독한 테스트 환경에서 수도없이 많은 어처구니없는 exception을 리포팅 받아 모두 적절히 견뎌낼 수 있도록 만들어지기 때문에 안정적인 프로그램이라고 칭송받는 겁니다. 많은 이들이 욕하는 M$의 제품군들 역시 수많은 try-catch로 얼룩져 있으며, 윈도우98시절에 비해 현재는 M$의 소프트웨어가 대단한 안정성 향상을 이룩했다는 것을 누구나 인정합니다.
(절대 밝혀져서는 안될 어둠의 루트로 M$ 코드의 일부를 본적이 있습니다^^;;;)

try-catch의 거의 유일한 단점이 코드를 지저분하게 만드는 것이라고 했는데, 사실 습관 들이기 나름으로 가독성을 저해하지 않기도 합니다. 이건 제가 뭐라 말할 수 있는 성격이 아니군요.. 프로그래머 각자가 exception handling 코드를 포함해서도 읽기 좋은 코드로 만드는 습관을 들이는 것이 스스로에게도 도움되는 일일 것입니다. try-catch를 가급적 nesting안한다던지.. 등등등

유일한 단점이 아니라 "거의" 유일한 단점이라고 했는데, 다른 단점들도 많이 있겠지만 또 한가지 들수 있는 단점은, 완벽한 try-catch는 에러를 내지 않는다는 겁니다. 이건 또 무슨 말일까요?ㅡ_ㅡ

try-catch로 잘 막아서 절대 에러가 나지 않는 어떤 함수를 만들었다고 해 봅시다.
이런 함수를 다른팀의 누군가가 사용하려고 합니다. 이사람은 잘못된 parameter를 입력으로 넘겨주는 엄청난 버그를 만들어 놓고도 절대 발견하지 못합니다. 우리가 제공해준 함수는 어떤 잘못된 입력이 와도 어쨌거나 에러 없이 코드를 수행하고 적당히 리턴값을 만들어 주니까요.. 버그를 만든 사람은 역시 다른팀 코드를 가져다 쓰니 로직에 문제가 생긴다고 생각해 버리겠죠..

그래서 assert나 raise (어떤 언어에서는 throw)구문을 활용해서 적절히 일부러 exception을 일으켜 주거나, 전통적인 C함수의 방법처럼 리턴코드를 항상 리턴값에 포함시켜서, 현재 리턴값은 exception handling의 결과임을 알리는 방법을 사용해야 합니다. exception으로 인해 소프트웨어가 멈추지는 않더라도 call-stack의 상위 코드에 exception발생사실을 알려줄 필요가 있다는 거죠..

도무지 엔지니어링의 세계는 얼마나 많은 trade-off를 더 해야 할지 모르는 세계입니다.
저는 아직도 어디까지를 raise하고 어디까지를 감춘채 handling할지를 결정보지 못했습니다. 아마 적어도 제가 죽기전에는 그런 공식은 나오지 않을겁니다.

마지막으로 은근히 유용한 try-catch 구문의 장점을 말씀드리겠습니다.
"실력있어 보인다"는 겁니다.ㅡ_ㅡ;;; 서두에도 말했던 것처럼 생각보다 많은 개발자 분들이 십수년의 경력에도 불구하고 exception에는 관대합니다. 이 글을 읽으신 여러분이 exception에 엄격해 진다면 실력있어 보이는 것을 넘어 실력있는 개발자로 인정 받으실 겁니다.

자신감을 가지세요.. 여러분이 생각하는것보다 훨씬 많은 사람이 당신의 코드를 보고 감탄합니다. 진짜로 여러분이 만든 코드는 뛰어납니다. 모든 사람의 머리가 다르기 때문에 항상 새로운 코드가 만들어지기 때문입니다. 자신있게 작성하고 테스트하고 진화(evolution, innovation)해야 더 훌륭한 코드를 만들수 있을 겁니다.

[출처 : 루미넌스 - TechNote]

2008년 3월 12일 수요일

httpd.conf 설정파일(1.*) 설정법정리

이 문서를 다른 웹이나 출판물에 게시할 때는 출처를 밝혀 주시기 바랍니다.

최종 수정일 : 2001년 8월 3일
글쓴이 : 윤 일 (yunil@dreamwiz.com)

HOW-TO Configuration httpd.conf(apache)

ServerType Standalone
# 서버 타입을 설정하는 지시자 이다.
# ServerType 에서 설정할 수 있는 것은 Standalone 과 inetd 두가지 설정이 있다.

ServerRoot /usr/local/apache
# 아파치 서버의 루트 디렉토리를 설정한다.

PidFile /usr/local/apache/logs/httpd.pid
# 아파치가 실행될 때 생성되는 httpd.pid 파일이 생성될 경로를 지정한다.

ScoreBoardFile /usr/local/apache/logs/httpd.scoreboard
#부모 프로세스가 자식 프로세스와 의사 소통을 할 때 사용되는 지시자와 그 파일을 지정한다.

Timeout 300
# Timeout은 클라이언트에서 서버로 접속할 때 클라이언트나 서버의 통신장애로 인해 300초 동안
# 클라이언트에서 완벽한 처리를 하지 못할 때 클라이언트와의 연결을 해제한다.

KeepAlive On
# 서버와의 지속적인 연결을 하도록 설정되어 있다. 즉 한번의 연결에 대해 한번의 요청만 처리하는
# 것이 아니라 또 다른

# 요청을 기다리게 된다. 하지만 지속적인 연결 시간은 KeepAliveTimeout 값에 설정한 만큼 유지된다.
# KeepAlive를 Off로 설정하게 되면 클라이언트로 부터 한번의 요청을 받은 후 바로 접속을 해제한다.
# 특별한 경우가 아니라면 On 상태로 유지하는 것이 좋다.

MaxKeepAliveRequests 100
# KeepAlive 상태에서 처리할 최대 요청 처리 건수를 설정한다.
# 보통의 웹 사이트에서는 설정값 100으로 충분하다.

KeepAliveTimeout 15
# KeepAlive 상태를 유지할 시간을 초 단위로 설정한다.

MinSpareServers 5
# 아파치가 실행될 때 최소 예비 프로세스 수를 설정한다. 이 값에 의해 현재 nobody 소유의
# 아파치 프로세스가 5보다 작을 경우 자동으로 부족한 만큼의 아파치 프로세스 생성한다.
# 8 정도 설정하는 것이 적당하다.

MaxSpareServers 10
# 아파치가 실행될 때 최대 예비 프로세스 수를 설정한다. 이 값에 의해 현재 nobody 소유의
# 아파치 프로세스가 10보다 클 경우 불필요한 프로세스를 제거한다.
# 20 정도 설정하는 것이 적당하다.

StartServers 5
# 아파치가 실행될 때 생성 시키는 자식 프로세스 수이다.
# 하지만 이 값이 MinSpareServers 값보다 작을 경우 아파치 실행 후에 바로 MinSpareServers 의
# 설정만큼 생성하기때문에 아무런 의미가 없게 된다. StartServer 값과 MinSpareServers 값은 같은
# 값을 설정하는것이 바람직하다.

MaxClients 150
# 아파치 서버의 동시 접속자 수를 정의한다.
# 최대 값은 256이다.
# 256 이상의 값을 설정하고 싶을 때는 아파치 소스의 httpd.h 헤어 파일의 HARD_SERVER_LIMIT 부분을
# 수정하고 아파치를 다시 컴파일 해야 된다.

MaxRequestsPerChild 0
# 아파치의 자식 프로세스가 처리할 수 있는 최대 요청 처리 건수를 설정한다.
# 0 은 무제한을 뜻한다.

BindAddress *
# 가상 호스트를 지워한다. 기본적으로 주석 처리 되어 있지만 실제로는 가상 호스트에 영향을
# 주지 않았다.

Port 80
# 아파치가 사용할 기본 포트를 지정한다.

User nobody
Group nobody
# 자식 프로세스가 생성될 때 그 프로세스의 소유자와 소유그룹을 결정한다.
# 보안상 절대 root 로 설정하는 일은 없도록 한다.

ServerAdmin admin@rootman.co.kr
# 아파치 서버 관리자 e-mail을 설정하는 부분이다.

ServerName rootman.co.kr
# 아파치 서버가 작동중인 서버 이름을 설정한다. 기본적으로 주석 처리 되어 있다.
# 도메인이 아닌 IP 주소로 사용자의 홈페이지에 접속할 때 URL 끝에 /를 붙여야 접속이 되는 경우가
# 있는데 이럴 경우ServerName 지시자에 주석을 제거 하고 아이피 주소를 설정해 주면 된다.

DocumentRoot "/usr/local/apache/htdocs"
#아파치의 웹 문서들의 루트 디렉토리를 지정한다.

# 아래 부터 디렉토리 제어이다. Directory 구문에 대한 자세한 설명은 아래에 있다.
# 시스템 루트( / ) 디렉토리에 대한 제어

Options FollowSymLinks
AllowOverride None


# /usr/local/apache/htdocs 디렉토리에 대한 제어

Options Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
Allow from all


# 사용자 홈 디렉토리인 public_html 디렉토리에 대한 제어

AllowOverride FileInfo AuthConfig Limit
Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec

Order allow,deny
Allow from all


Order deny,allow
Deny from all



##############################################################################################
# 디렉토리 제어와 관련된 설정과 옵션 설 #
##############################################################################################
디렉토리 제어문의 시작은 로 시작해서 로 끝난다.

# -->> Options(옵션) 설명 ;
옵션 구문은 Options 라는 키워드로 시작된다.
FollowSymLinks : 실볼릭 링크를 허용한다.
SymLinksIfOwnerMatch : 링크를 허용하지만 링크 하고자 하는 사용자의 소유로 되어 있는 것만 링크
# 가능하다.
ExecCGI : CGI 실행을 허용한다.
Includes : SSI를 허용한다.
IncludesNOEXEC : SSI를 허용하지만 "#exec" 와 "include"로 정의한 CGI 실행은 거부한다.
Indexes : 웹 서버의 디렉토리에 접근 했을 때 DirectoryIndex 지시자로 설정한 파일이 없을
#경우 디렉토리안의 파일 목록을 보여준다.
MultiViews : 클라이언트의 요청에 따라 적절하게 페이지를 보여준다. 쉽게 생각하면 HTTP 헤드 정보가
# Accept-Language:ko 라면 Korea 언어에 맞게 데이터를 클라이언트에 전송한다.
None : 모든 설정을 부정한다.
All : MultiViews를 제외한 옵션을 의미한다.

# -->> AllowOverride 설명
AllowOverride는 클라이언트의 디렉토리 접근 제어에 관한 설정이다.
AllowOverride 는 AccessFileName 지시자와 밀접한 관계를 가지고 있다.

아래의 각 설정값들은 AccessFileName 지시자에서 설정한 파일에 적용된다.
None : AllowOverride를 off 한다는 것이다.
All : AccessFileName 지시자로 설정한 파일에 대해 민감하게 반응한다. 모든 지시자를 사용할 수 있다.
AuthConfig : AccessFileName 지시자에 명시한 파일에 대해서 사용자 인증 지시자 사용을 허락한다.
--> AuthDBMGroupFile, AuthDBMUserFile, AuthGroupFile, AuthName, AuthType, AuthUserFile,
# require등을 사용할 수 있다.
FileInfo : AccessFileName 지시자로 설정한 파일에 대해서 문서 유형을 제어하는 지시자 사용을 허락한다.
#-> AddEncoding, AddLanguage, AddType, DefaultType, ErrorDocument,
#LanguagePriority등을 사용할 수 있다.
Indexes : AccessFileName 지시자로 설정한 파일에 대해서 디렉토리 Indexing을 제어하는 지시자
#사용을 허락한다.
--> AddDescript-xion, AddIcon, AddIconByEncoding, AddIconByType, DefaultIcon, DirectoryIndex,
#FancyIndexing, HeaderName, IndexIgnore, IndexOpions, ReadmeName등을 사용할 수 있다.
Limit : AccessFileName 지시자로 설정한 파일에 대해서 호스트 접근을 제어하는 지시자 사용을 허락한다.
--> Allow, Deny, order 등을 사용할 수 있다.
Options : AccessFileName 지시자에 명시한 파일에 대해서 Options 그리고 XBiHack 등과 같은 지시자
#사용을 허락한다.
--> Options, XBitHack등을 사용할 수 있다.

AloowOverride와 AccessFileName에 설정한 파일을 이용해서 아파치 인증 기능을 사용할 수 있다.
아파치 인증에 관한 자세한 설명은 "아파치 인증" 강좌를 참고하길 바란다.
##############################################################################################

DirectoryIndex index.html
# 파일 이름을 명시하지 않고 디렉토리에 접근할 경우 자동으로 보여줄 파일 이름을 설정한다.
# 여러개의 파일 이름을 설정할 수 있다. 파일 이름에 대한 구분은 Space 키, 즉 빈 공간으로 구분한다.

AccessFileName .htaccess
# 특정 디렉토리의 접근 제어를 할 파일 이름을 정의한다.
# 단, 해당 디렉토리의 AllowOverride 에서 None으로 설정되어 있지 않아야 된다.
# 자세한 설명은 "아파치 인증" 강좌 참고

CacheNegotiatedDocs
# 프록시 서버에 문서를 캐시하도록 설정한다. 기본적으로 주석 처리 되어 있다.

HostnameLookup Off
# 아파치의 로그 파일에는 기본적으로 클라이언트의 IP 주소 정보가 기록되는데 이 설정을 On 하면
# 호스트 네임(도메인)이 기록된다. 하지만 DNS 질의를 해야 되므로 속도가 느리다는 단점이 있다.
# 그냥 Off로 사용하는것을 추천한다.

ErrorLog /usr/local/apache/logs/error_log
# 아파치 서버 접속 에러 로그를 기록할 결로와 파일 이름을 설정한다.

LogLevel warn
# 에러 로그 내용의 레벨을 설정한다.

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
# 사용자 접속을 기록할 로그 포멧을 정의한 부분이다. 위와 같이 4가지 형식의 로그 포멧이
#기본적으로 설정되어 있다.
common : 가장 일반적인 로그 기록
referer : 현재 아파치 서버에 접속하기 전에 머물렀던 URL으 기록한다.
agent : 접속자의 웹 브라우저(OS 포함) 종류를 기록한다.
combined : 위의 3가지 로그 포멧을 모두 조합한 것이다.
접속자에 대한 많은 정보를 기록하길 원한다면 combined으로 설정하면 된다.
# %h %I 등과 같은 아파치 로그 포멧을 알고 싶으면 아파치 메뉴얼를 참고 하기 바란다.

CustomLog /usr/local/apache/logs/access_log common
# 로그 파일의 경로와 파일 이름, 그리고 로그의 포맷을 설정한다.
# common 이외에 위에서 정의한 로그 포멧을 지정할 수 있다.

ServerSignature On
# apache 서버가 생성하는 Error 페이지와 Ftp 디렉토리 목록, mod_status, mod_info 등에 apache
#서버 버젼과 가상 호스트
# 네임을 추가적으로 표시해 준다.(On 설정시) Email 설정시 ServerAdmin의 E-mail 주소를 페이지에
#링크해 준다.
# On, Off, Email을 설정해서 사용할 수 있다.

Alias /icons/ "/usr/local/apache/icons/"
# 특정 디렉토리를 alias 한다. 위의 경우는 /usr/local/apache/icons/ 디렉토리를 icons 라는 이름으로
# alias 한것이다
# icons 디렉토리 앞의 /(슬래쉬)는 DocumentRoot를 의미한다.

Script-xAlias /cgi-bin/ "/usr/local/apache/cgi-bin/"
# Alias와 같은 형식이고 실행할 스크립트 디렉토리를 alias할 때 사용한다.

Redirect old-URL new-URL
# old-URL을 new-URL로 코딩해준다. 하지만 HTML태그로 위의 기능을 대신할 수 있기때문에 사용할 일이
# 거의 없을것이다.

IndexOptions Fancy Indexing
# 디렉토리에 DirectoryIndex에 설정된 파일명이 없을경우 아파치서버는 디렉토리목록을 보여주는데
# Fancy Indexing을 설정 할 경우 파일의 크기, 생성날짜 등을 같이 출력해준다.

DefaultIcon /icons/unknown.gif
# 아이콘이 설정되어 있지 않은 파일 확장자들의 아이콘을 대신한다

AddDescript-xion "GZIP compressed document" .gz
AddDescript-xion "tar archive" .tar
AddDescript-xion "GZIP compressed tar archive" .tgz
# 아파치가 디렉토리 목록을 보여줄 경우 파일 확장자에 대해 간략한 설명을 할 수 있게 한다. 단,
# IndexOptions에서 FancyIndexing이 적용되어 있어야 된다.

ReadmeName README
HeaderName HEADER
# 아파치가 디렉토리가 목록을 보여줄 경우 페이지 위(HEADER)와 아래(README)에 추가로 출력할
# 텍스트들을 설정할 수 있다.
# 각 디렉토리에 README, HEADER 라는 이름으로 텍스트 파일을 만들면 된다.

ErrorDocument 500 "The server made a boo bo"
ErrorDocument 404 /missing.html
ErrorDocument 402 http://some.other_server.com/subscript-xion_info.html
# 클라이언트의 요구에 의해 발생하는 아파치 서버의 에러페이지에 출력할 텍스트나 문서를 정의할
# 수 있다.
# 각 페이지는 에러 코드별로 설정할 수 있으며 외부의 URL을 지정할 수도 있다.
# 문자열을 설정을 경우네는 " "안에 문자열을 설정하면 되고 내부 html 문서를 지정해줄 경우에는
# 문서의 경로를 지정해 주면 된다. 단, (/)최상위 경로는 DocumentRoot를 의미한다.


SetHandler server-status
Order deny,allow
Deny from all
Allow from .your_domain.com


SetHandler server-info
Order deny,allow
Deny from all
Allow from .your_domain.com

# 위의 설정을 함으로써 웹 브라우저에서 아파치 서버의 상태와 정보를 볼수 있다. 보안상 특정
# 호스트에서만 볼 수 있게 설정할 수 있으며 기본적으로 주석 처리되어 있다.


Deny from all
ErrorDocument 403 http://phf.apache.org/phf_abuse_log.cgi

# 아파치 1.1 이전 버젼의 버그를 악용하는 경우가 있는데 이 설정에 해 두면 이러한 공격을
# phf.apache.org의 로깅 스키립트로 리다이렉트 시켜준다. 요즘은 필요없는 설정이고 위의 URL에
# cgi스크립트가 존재하지도 않는다.

DefaultType text/plain
# 아파치가 처리할 기본 문서들을 정의한다. 위의 설정은 html과 text 파일을 포함시킨 것이다.
# 위의 설정 때문에 text 파일도 웹 브라우저에 표시해 줄수 있는 것이다.

mod_python 설치

mod_python은 Apache의 module로서 python interpreter를 항상 띄워 놓고, apache의 내부객체를 노출시켜, python으로 성능 좋고, 편리한 웹코딩을 할 수 있게 해준다.

설치 시작해보까

1. 다운을 받는다. Apache 2.0 이상이라면 mod_python 버전 3이상을, Apache1.3 이라면 mod_python 버전 2를 다운 받는다.

2. configure 실행..
Apache의 DSO를 쓰려면 axps위치를 지정해야 하고, python도 제위치에 안깔았다면 지정해야 한다.

./configure --with-apxs=/usr/local/apache2/bin/apxs --with-python=/data/python/bin/python

3. make -> make install
만일 make install에서 에러가 나면... 다음과 같이...

/usr/bin/install -c src/mod_python.so /usr/local/apache2/modules /usr/bin/install: cannot stat `src/mod_python.so': No such file or directory make[1]: *** [install_dso] Error 1 make[1]: Leaving directory `/home/hobb/mod_python-3.0.1' make: *** [install] Error 2 #

이것은 apache에서 제공하는 libtool의 bug때문이란다...
그래서 /usr/local/apache2/build/libtool 을 백업하고 /usr/bin/libtool 을 그 디렉토리로 복사한다. 그리고 make install 하면 잘 될 것이다. libtool은 version 1.4.2 이상이어야 한단다.

4. Apache 설정 바꾸기

LoadModule python_module /usr/local/apache2/modules/mod_python.so

그리고 mod_python을 쓰는 방법은 여러가지가 있으나, psp(Python server page)와 cgihandler로 쓰는 것이 제일 쉬울 것이다. 이렇게 두개를 동시에 설정하려면 AddHandler하나에 여러개의 PythonHandler를 다는 것인데... 그 방법은 다음과 같다.

AddHandler mod_python .psp .psp_ .py
PythonHandler mod_python.psp | .psp .psp_
PythonHandler mod_python.cgihandler | .py
PythonDebug On

위 세 라인을 httpd.conf 파일에 넣으면 된다. (루트에) .psp_ 는 psp 디버깅을 위해 추가하는 것이다.

만일 publisher 등을 쓸려면 확장자를 달리 하던지, 태그안에 넣던지 해야 할 것이다.

5. 흔히 발생하는 문제...

mod_python을 해서 cgihandler/publisher/psp 등을 시험해보았는데... Apache의 error_log에 Segmentation Fault가 나는 이상한 현상을 보인다. 그래서 google을 샅샅이 뒤졌다.

그런데 결론은... 너무도 허무하다.

문제는 apache가 가지고 있는 공용 라이브러리와 mod_python이 가지고 있는 공용 라이브러리의 version이 다르면 안된다는 점이다.

내가 테스트한데서 문제가 된것은 xmlrpclib을 import할 경우에의 segmentation fault인데, 이는 apache의 소스에도 expat이 있고, python도 expat을 가지고 있는데, apache의 expat는 1.85.1, python의 expat는 1.85.8 이라는데 있다. 이렇게 버전 다른 expat을 공용라이브러리로 쓰면 Bug이 난다고 한다.

비슷한 오류는 php와 mod_python을 쓸때도 난다고 한다. php의 mysql binding과 python의 Mysql binding에서 충돌이 나는 경우도 적지 않다고...

그러면 해결책은...
----------------------------------
expat 최신버전 1.85.8를 다운받아서 설치한다.

./configure --prefix=/usr

로 해야 제 위치 (/usr/lib)에 깔린다.

다음 make/make install

그리고 이 expat 소스를 apache소스의 apache/srclib/apr-util/xml/expat 에 넣는다. 적당히 넣고 이름바꾸고 configure /make/make install 한다.

그러면 이제 잘 될 것이다. 정말 힘들었다. 이렇게 세팅하는데...

===============================================================
Intel Solaris 5.8, gcc 3.2.2 버전 이상인 경우 Python 컴파일은 잘 되나, mod_python 컴파일은 다음과 같은 에러를 내며 안된다.

*** Warning: Linking the shared library mod_python.la against the non-libtool
*** objects _eprintf.o _floatdidf.o _muldi3.o is not portable!

이러면서 에러메시지가 죽 뜬다.

구글링 결과 eprintf 등은 Solaris에서 문제가 있는 파일들인데, gcclib에서 ar -x 로 뽑아낸다고 한다. 그런데 이게 Python과 안맞다는 건데... 무슨 말이냐면 gcc는 shared형태이고, Python은 static이면 이런 에러가 나는 것이다.

이를 해결하기 위해서는 Python을 동적으로 컴파일해야 한다. 다음과 같이 Python 컴파일시 --enabled-shared를 넣고 컴파일하면 잘된다.

./configure --with-threads --enable-thread --without-pymalloc --enable-shared

python 2.2 에서 MySQL_Python1.2.0 설치할 경우 에러 발생시

invalid distribution option 'download_url' 애러시
setup.py 의 39번째 라인에 추가.

if sys.version < '2.2.3':
from distutils.dist import DistributionMetadata
DistributionMetadata.classifiers = None
DistributionMetadata.download_url = None
추가 해준다.

apache 설치시 Error Output for sanity check

======== Error Output for sanity check ========

cd ..; gcc -DLINUX=22 -DUSE_HSREGEX -DUSE_EXPAT -I./lib/expat-lite `./apaci` -o helpers/dummy helpers/dummy.c -lm

============= End of Error Report =============

아파치 설치시 위와 같은 에러가 발생했을 경우 처리 방법은 apache 인스톨 폴더명을 확인

해보도록 하자 혹시나 폴더 네임에 스페이스바가 들어가 있다면 제거 하고 인스톨하도록 하자.

그러면 에러가 나지 않고 설치가 될것이다.