메뉴 건너뛰기

Dev tips

Apache+Tomcat 아파치~ 그대로 따라하라~ 서버관리

taknim 2006.03.17 20:20 조회 수 : 12900 추천:1899

[ 빠른설치 ]

설치에 중요한 부분만 빠르게 설치할 수 있도록 하였습니다.


[ 설정+설명+TIP 설치 ]

1. 기존 패키지 삭제
2. 패키지 다운로드
3. imap 설치
4. MySQL의 설치
5. MySQL 서버의 실행
6. Apache 설정
7. PHP 컴파일과 설치
8. 아파치 컴파일과 설치
9. php.ini 파일 복사
10. httpd.conf 수정하기
11. 아파치 시작하기
12. 작동테스트
13. 부팅할 때 자동으로 서버 실행되게 설정하기
14. Zend Optimizer설치
15. 아파치 튜닝
16. 서버 재시작
17. 보안 관련 소식들


[ 빠른 설치 ]


설치과정만 설명없이 차례대로 적겠습니다.
자세한 설정과 추가로한 설명들은 아래 부분의 [ 설정+설명+TIP 설치 ] 에 적었습니다.
이 부분은 그냥 주요 설치부분만 쭉 적었습니다.

이전에 작동하는 아파치와 mysql 프로세스 작동시에는 종료한후에 시작하세요.

# ps -ef|grep httpd
# killall httpd
# ps -ef|grep mysqld
# killall mysqld


패키지 확인
# rpm -qa | grep apache
# rpm -qa | grep mysql
# rpm -qa | grep php
# rpm -qa | grep imap

패키지 삭제
# rpm -e --nodeps `rpm -qa | grep apache `
# rpm -e --nodeps `rpm -qa | grep mysql `
# rpm -e --nodeps `rpm -qa | grep php `
# rpm -e --nodeps `rpm -qa | grep imap `

패키지 다운로드
사이트를 방문하셔서 직접 받으실 수 있습니다.
그게 귀찮으시다면, 제 홈페이지에 오셔서 받으시면 됩니다.
게시판에 올려두었으니 아래 링크로 오셔서 받아주세요.

mysql http://linuxnew.com/zero/view.php?id=download&no=178
zend http://linuxnew.com/zero/view.php?id=download&no=177
php http://linuxnew.com/zero/view.php?id=download&no=176
apache http://linuxnew.com/zero/view.php?id=download&no=175
imap http://linuxnew.com/zero/view.php?id=download&no=174

imap 설치
# tar zxvf imap-2002.RC2.tar.Z
# mv imap-2002.RC2 /usr/local/imap
# cd /usr/local/imap
# make slx
# cp imapd/imapd ipopd/ipop3d /usr/sbin

imap 설정
vi /etc/services 로 주석 없는지 확인
-------
pop3 110/tcp pop-3 # POP version 3
pop3 110/udp pop-3
-------
imap 143/tcp imap2 # Interim Mail Access Proto v2
imap 143/udp imap2
-------

xinetd 데몬으로 imapd와 ipop3d를 실행
# vi /etc/xinetd.d/imapd
imapd 실행을 위한 환경설정화일
< 파일내용 >

service imap
{
disable = no
socket_type = stream
wait = no
user = root
server = /usr/sbin/imapd
log_on_success += HOST DURATION
log_on_failure += HOST
}

# vi /etc/xinetd.d/ipop3d
ipop3d 실행을 위한 환경설정화일
< 파일내용 >

service pop3
{
disable = no
socket_type = stream
wait = no
user = root
server = /usr/sbin/ipop3d
log_on_success += HOST DURATION
log_on_failure += HOST
}

xinetd 데몬을 재가동해줍니다.
# /etc/init.d/xinetd restart

MySQL의 설치
# tar zxvf mysql_3.23.51.tar.gz
# cd mysql-3.23.51
# ./configure --prefix=/usr/local/mysql --with-charset=euc_kr
# make;make install
# /usr/local/mysql/bin/mysql_install_db
# useradd mysql
# chown -R mysql.mysql /usr/local/mysql/var

mysql 계정의 설정
# vipw 를 실행하여서 mysql 의 뒷쪽에 있는 /bin/bash 를 삭제해 줍니다.
mysql:x:500:500::/home/mysql:/bin/bash <-- 이 /bin/bash 부분을
계정이름 uid gid 기본홈 유저의쉘
mysql:x:500:500::/usr/local/mysql/var:/sbin/nologin 이렇게 해줍니다.
:x를 통해 저장후 종료하게 되면 아래와 같이 나오면,
You are using shadow passwords on this system.
Would you like to edit /etc/shadow now [y/n]
n 이라고 하면 됩니다.
# rm -rf /home/mysql

MySQL 서버의 실행
# /usr/local/mysql/bin/safe_mysqld --language=korean &
# /usr/local/mysql/bin/mysql
# /usr/local/mysql/bin/mysqladmin -uroot password '새로지정할암호'
# mysql -uroot -p 로 하고 암호를 치고 접속확인


편의를 위해 PATH를 걸어 준다
# vi /etc/profile 로 수정
export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE INPUTRC <-- 이라인 아래에
export PATH=$PATH:.:/usr/local/apache/bin:/usr/local/mysql/bin:/usr/sbin
이렇게 추가 합니다.

Apache 설정
# tar zxvf apache_1.3.26.tar.gz
# mv apache_1.3.26 /usr/local/apache
# cd /usr/local/apache
# ./configure

PHP 컴파일과 설치
# tar zxvf php_4.2.2.tar.gz
# mv php-4.2.2 /usr/local/php
# cd /usr/local/php
# ./configure --with-mysql=/usr/local/mysql --with-exec-prefix=/usr/local/bin --with-imap=/usr/local/imap --with-apache=/usr/local/apache --enable-track-vars --disable-debug --with-gd --with-language=korean --with-charset=euc_kr
# make;make install

아파치 컴파일과 설치
# cd /usr/local/apache
# ./configure --activate-module=src/modules/php4/libphp4.a --enable-shared=all
# make;make install

php.ini 파일 복사
# cd /usr/local/php
# cp php.ini-dist /usr/local/lib/php.ini

php.ini 내용수정
upload_max_filesize = 10M 업로드 용량의 수정이 필요하신 분은 수정하세요.
register_globals = On 그리고 전역변수의 사용이 필요하신 분은 수정하세요!

httpd.conf 수정하기
# vi /usr/local/apache/conf/httpd.conf
AddType application/x-tar .tgz 이 부분이 있으면, 이 아래에
AddType application/x-httpd-php .php
AddType application/x-httpd-php .php3
AddType application/x-httpd-php .html
AddType application/x-httpd-php .htm
AddType application/x-httpd-php-source .phps
AddType application/x-httpd-php .inc
AddType application/x-httpd-php .phtml
이렇게 추가 해줍니다.
그리고 (DirectoryIndex index.html 부분을 찾아서 다음과 같이 index.php 를 추가합니다.)
DirectoryIndex index.html index.htm index.php

※ #ServerName localhost (이 부분의 주석(#)을 꼭 지웁니다.) <- localhost를 아이피로 변경하세요!

:wq 나 :x 로 저장하시고 나오세요.

아파치 서버 실행
# /usr/local/apache/bin/apachectl start
아파치 서버 종료
# /usr/local/apache/bin/apachectl stop
아피치 서버 재시작
# /usr/local/apache/bin/apachectl restart

부팅할 때 자동으로 서버 실행되게 설정하기

# vi /etc/rc.d/rc.local 파일에 추가

#mysql start
/usr/local/mysql/bin/safe_mysqld --language=korean &
#apache start
/usr/local/apache/bin/apachectl start &

Zend Optimizer설치
# tar zxvf ZendOptimizer-1.3.3-Linux_glibc21-i386.tar.gz
# cd ZendOptimizer-1.3.3-Linux_glibc21-i386
# ./install.sh
이제 차례대로 질문에 답을 하면 됩니다.
Default 값이 다 우리가 셋팅한 값으로 되어 있어서 엔터만 치시면 됩니다.

아파치 재시작
# /usr/local/apache/bin/apachectl restart

여기까지 한후에 잘 되는지 간단한 테스트 해보시고, 서버를 리붓시켜서 서버가 원격에서 리붓했을때에도
잘되는지도 확인할겸 키보드와 모니터를 제거한후에 리붓을 해주십시요.
# /sbin/shutdown -r now 이나
# /sbin/reboot 으로 하시면 됩니다.
여기서 주의 할점은 CMOS 셋업에서 키보드와 모니터등 특정장치가 없을시엔 부팅이 안되는 설정이 되어 있다면
원격에서 리붓시키면 CMOS 셋업 설정때문에 부팅이 안된다는 것입니다.
만약 리붓을 했는데, 부팅이 안되신다면 CMOS 셋업에서 장치가 없어서 에러로 처리하는 부분을
NO ERROR 로 키보드가 안 꼽아져 있더라도 부팅이 되도록 해주셔야 합니다.





[ 설정+설명+TIP 설치 ]


위의 퀵설치에는 없는 설명과 자세한 설정들과 간단한 TIP 들이 포함 되어 있습니다.
빠른 설치를 원하시면 윗 부분을 참고하세요.
보통 처음 설치하시는 분들이나 설정 참고 하실 분들은 여기부터 보시면서 셋팅하세요.


1. 기존 패키지 삭제

기존의 있던 패키지가 있는데 덮어 깔게 되면 고생하신게 물거품이 되버립니다.^^;
rpm으로 설치되어 이전의 프로세스가 돌아가는 것이 있다면 종료후에 아래와 같이 삭제 합니다.
프로세스 검색은 ps -ef | grep httpd 처럼 해주신후에 만약 발견되면 killall httpd 를 해주시면 됩니다.
mysql 도 작동 하고 있다면 ps -ef | grep mysql로 검색하셔서 종료시킨후에 시작하세요~

# ps -ef|grep httpd
# killall httpd
# ps -ef|grep mysqld
# killall mysqld

# rpm -qa | grep apache

# rpm -qa | grep mysql

# rpm -qa | grep php

# rpm -qa | grep imap

이렇게 패키지가 깔렸는지 확인을 먼저 하시구요...
그다음에...
위 명령의 결과로 패키지들이 나온다면 'rpm -e 패키지' 명령을 하여 모두 삭제합니다.

의존성이 걸려있다고 나온다면 그 의존성 나온것부터 먼저 지운다음에 나중에 의존성이 풀린후에
다시 지우셔야 합니다...

의존성 걸린거 하나하나 지우기 귀찮으시면 강제로 전체 걸리는 패키지를
# rpm -e --nodeps `rpm -qa | grep apache `
# rpm -e --nodeps `rpm -qa | grep mysql `
# rpm -e --nodeps `rpm -qa | grep php `
# rpm -e --nodeps `rpm -qa | grep imap `
이렇게 지우시면 됩니다....


2. 패키지 다운로드

사이트를 방문하셔서 직접 받으실 수 있습니다.
그게 귀찮으시다면, 제 홈페이지에 오셔서 받으시면 됩니다.
게시판에 올려두었으니 패키지 이름 아래 링크로 오셔서 받아주세요.

Apache
http://www.apache.org
apache_1.3.26.tar.gz
http://linuxnew.com/zero/view.php?id=download&no=175

mysql
http://www.mysql.com
mysql-3.23.51.tar.gz
http://linuxnew.com/zero/view.php?id=download&no=178

php
http://www.php.net
php-4.2.2.tar.gz
http://linuxnew.com/zero/view.php?id=download&no=176

imap
ftp://ftp.cac.washington.edu/imap
imap-2002.RC2.tar.Z
http://linuxnew.com/zero/view.php?id=download&no=174

Zend
https://www.zend.com
ZendOptimizer-1.3.3-Linux_glibc21-i386.tar.gz
http://linuxnew.com/zero/view.php?id=download&no=177


모두 소스버젼으로 직접 컴파일하면 됩니다...

디렉토리는
Apache
/usr/local/apache

php - 4.2.2 버젼의 php.ini 디폴트 옵션에 전역변수가 OFF 되어있으니 필요하신 분들은 ON 으로 변경해야 합니다.
이 옵션 입니다. register_globals = On 주의 하세요~
/usr/local/php

mysql
/usr/local/mysql



3. imap 설치

# tar zxvf imap-2002.RC2.tar.Z
# mv imap-2002.RC2 /usr/local/imap
# cd /usr/local/imap

압축을 풀은후에

# make slx 로 imap을 컴파일 합니다.

컴파일이 완료되면 imapd 디렉토리에 imapd가 ipopd디렉토리에는 ipop3d가 생성됩니다.
그 둘을 /sbin에 복사합니다.
# cp imapd/imapd ipopd/ipop3d /usr/sbin
그리고
vi /etc/services 파일에서
-------
pop3 110/tcp pop-3 # POP version 3
pop3 110/udp pop-3
-------
imap 143/tcp imap2 # Interim Mail Access Proto v2
imap 143/udp imap2
-------
이렇게 앞에 주석처리가 안되있는지 확인해서 만약 주석처리 되있으면 지우시고, 없으면 그냥 놔두면 됩니다.

xinetd 데몬으로 imapd와 ipop3d를 실행시키기 위해서 아래 파일을 생성합니다.

# vi /etc/xinetd.d/imapd
imapd 실행을 위한 환경설정화일
< 파일내용 >

service imap
{
disable = no
socket_type = stream
wait = no
user = root
server = /usr/sbin/imapd
log_on_success += HOST DURATION
log_on_failure += HOST
}

# vi /etc/xinetd.d/ipop3d
ipop3d 실행을 위한 환경설정화일
< 파일내용 >

service pop3
{
disable = no
socket_type = stream
wait = no
user = root
server = /usr/sbin/ipop3d
log_on_success += HOST DURATION
log_on_failure += HOST
}

이제 xinetd 데몬을 재가동해줍니다.

# /etc/init.d/xinetd restart

그리고 접속이 잘 되는지 확인합니다.

110번 포트는 pop 이고, 143번 포트는 imap 입니다.

# telnet localhost 110

Trying 127.0.0.1...
Connected to localhost.localdomain.
Escape character is '^]'.
+OK POP3 localhost.localdomain v2001.78 server ready

이렇게 나오면 잘된겁니다.
quit 를 치고 나오시면 됩니다.



4. MySQL의 설치

# tar zxvf mysql_3.23.51.tar.gz

# cd mysql-3.23.51

# ./configure --prefix=/usr/local/mysql --with-charset=euc_kr

# make;make install

# /usr/local/mysql/bin/mysql_install_db

--prefix=/usr/local/mysql 는 MySQL 서버가 설치된 경로를 지정하는 것이며,
--with-charset=euc_kr 는 데이터베이스에서 한글데이터의 정렬을 위해 한글 문자셋을 사용 가능하게 설정하는 것입니다.

주의할점은...
mysql_install_db 스크립트는 반드시 한번만 실행하도록 합니다.
여러번 실행할 경우 서버가 정상적으로 실행되지 않습니다.

이 버젼에선 mysql 의 계정을 새로 추가 하여서 mysql 권한으로 돌아가게 하시거나 root 권한으로 띄울 수 있습니다.
# /usr/local/mysql/bin/safe_mysqld --user=root &
위처럼 띄울 수 있지만 계정을 만들어서 하겠습니다.
일단 mysql 그룹을 만들고 계정을 mysql그룹으로 설정해서 만듭니다.

계정을 만들시에 그룹을 지정하지 않으면 계정이름과 동일하게 계정이 생성됩니다.
그리고 chown 으로 유저 소유권과 그룹 소유권을 지정할 때에는 mysql.mysql 로 하시면,
mysql 유저와 . mysql 그룹으로 . 으로 구분하여 지정이 됩니다.
보안을 위해서 /usr/local/mysql/data 의 데이터들을 지정해 줍니다.

# useradd mysql
# chown -R mysql.mysql /usr/local/mysql/var

그리고 mysql 계정이 쉘을 가지고 있으므로 이것을 삭제 해줍니다.

# vipw 를 실행하여서 mysql 의 뒷쪽에 있는 /bin/bash 를 삭제해 줍니다.

mysql:x:500:500::/home/mysql:/bin/bash <-- 이 /bin/bash 부분을
계정이름 uid gid 기본홈 유저의쉘


mysql:x:500:500::/usr/local/mysql/var:/sbin/nologin 이렇게 해줍니다.


:x를 통해 저장후 종료하게 되면 아래와 같이 나오면,

You are using shadow passwords on this system.
Would you like to edit /etc/shadow now [y/n]

n 이라고 하면 됩니다.

그리고 계정 생성시 초기 홈디렉토리인 /home/mysql를 삭제 합니다.

# rm -rf /home/mysql

mysql 계정정보를 이렇게 변경해 주시면 됩니다.



5. MySQL 서버의 실행

/usr/local/mysql/bin/safe_mysqld --language=korean &

# /usr/local/mysql/bin/mysql

실행하셔서 되는지 확인하시구요~~

# /usr/local/mysql/bin/mysqladmin -uroot password '새로지정할암호'
이렇게 해서 root의 암호를 지정해 줍니다.
그리고 다음 접속부터는 mysql -uroot -p 로 하고 암호를 치고 접속하면 됩니다.

이제 tar 풀었던 것은 지우셔두 됩니다^^;
/usr/local/mysql에 설치가 되었으니깐요~


※ 여기서 원격 관리시 편하게 PATH를 걸어 줍니다.
# vi /etc/profile 을 해서

export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE INPUTRC <-- 이라인 아래에

export PATH=$PATH:.:/usr/local/apache/bin:/usr/local/mysql/bin:/usr/sbin

이렇게 적어 줍니다.
그러면 apache와 mysql, /usr/sbin 의 원격에서 관리시에 편합니다.

참고로 mysql 의 관리툴은 웹에서 관리하도록 된 phpmyadmin 과 원격 컴퓨터에서 관리할 수 있도록
되어 있는 TMysql 이 편리 합니다.
phpmyadmin 은 외국 프로그램으로 http://sourceforge.net/projects/phpmyadmin/ 소스포지에서 받으시면 편합니다. 물론 제 홈페이지에도 올려두었습니다.
설정은 간단히 config.inc.php 설정 파일에 자신의 mysql 아이디와 암호만 적어주면 웹상에서 접속 됩니다. 접속하신후에 하나씩 살펴보시면 쉽게 익숙해질 수 있을 것입니다.
그리고 우리나라 제품인 TMysql 은 http://www.thinktech.co.kr/ 씽크텍이라는 곳에서 만든 제품으로 무료 제품으로 윈도우에서 설치한후에 리눅스 mysql 을 관리 할 수 있도록 만든 툴입니다.
이 프로그램도 무료배포가 허용 된 것이므로 제 홈페이지에 올려두었습니다.
이 프로그램은 원격에서 접속을 한다는 점때문에 mysql의 host명에 주의를 해야 합니다.
host에 접속할 곳의 아이피를 적던지 아니면 모두 들어올수 있게하는 %를 적어야 원격에서 접속할 수 있게 해주기 때문에 약간의 주의가 필요합니다.
기본 localhost로 되어 있기때문에 사람들이 이부분에서 혼동을 많이 하게 됩니다.
mysql의 관리는 이렇게 하면 편하다는 참고사항 이였습니다^^



6. Apache 설정

# tar zxvf apache_1.3.26.tar.gz

# mv apache_1.3.26 /usr/local/apache

아파치를 /usr/local/apache 에다가 풀은 것을 이곳에다가 옮긴후에

# cd /usr/local/apache

# ./configure

이렇게 함으로써 apache의 디렉토리를 설정하게 됩니다...



7. PHP 컴파일과 설치

# tar zxvf php_4.2.2.tar.gz

# mv php-4.2.2 /usr/local/php

# cd /usr/local/php

php를 /usr/local/php에다가 푼것을 옮기신후에

# ./configure --with-mysql=/usr/local/mysql --with-exec-prefix=/usr/local/bin --with-imap=/usr/local/imap --with-apache=/usr/local/apache --enable-track-vars --disable-debug --with-gd --with-language=korean --with-charset=euc_kr

이 옵션들은 차례대로 mysql연동, /usr/local/bin 안에 php 바이너리파일을 넣는 옵션입니다.
imap, apache 연동, --enable-track-vars 옵션은 HTTP_GET_VARS, HTTP_POST_VARS, HTTP_COOKIE_VARS 배열에 들어 있는
GET, POST, cookie 변수들이 어디서 왔는지 기억하며, --disable-debug 옵션은 Zend Optimizer 를 위한 옵션입니다.
그리고 gd 라이브러리 옵션이고, 마지막은 한국어 설정이며, 문자셋 지정도 한국어로 했습니다.

# make;make install

여기서 컴파일 하므로써 apache 안의 src아래 module 에 php4가 생성 되는 것입니다.
그래서 아래 아파치 컴파일시에 --activate-module=src/modules/php4/libphp4.a 라는 옵션이 들어가는 것입니다.
그러므로 php가 컴파일 잘 되었는지 확인하실려면
/usr/local/apache/src/module/php4안에 php의 모듈들이 잘 들어와있는지 확인하시면 됩니다.

이렇게 하셔서 설치를 하시면 mysql과 apache가 php와 연동이 됩니다^^;



8. 아파치 컴파일과 설치

여기서 주의 할 점은 php 모듈이 기본적으로 패키지에 안들어 있다는 것입니다.
그러므로 php모듈을 apache 디렉토리의 src/modules/php4아래에 넣어주는 과정인 php설치를 마친후에 컴파일을 하셔야 하는 것입니다.
우리는 이미 7과정을 지나왔기때문에 src/modules/php4/libphp4.a 가 생겨 있게 되는 것입니다.

그리고 아파치의 동적 설치란 DSO(Dynamic Shared Object)방식으로 설치하는 것을 말합니다.
DSO 방식은 아파치를 먼저 컴파일하고 다른 모듈들을 추가로 설치할 때는 아파치를 재 컴파일하지 않고 한번 설정되어 컴파일된 아파치를 계속 사용하는 것으로 한번 설치하고 나면 필요한 모듈을 추가를 하여서 사용하므로 관리는 편리하지만 서버 시작이 20% 정도 느려질 수 있으며 실행속도가 5% 정도 느려질 수 있습니다.
설치법은 아파치 configure 시에 --enable-shared=max 또는 all 을 추가하여 설치하는 것을 말하고 반대의 방식으로 --enable-shared 옵션을 제거후 설치하면 정적 설치로 필요한 모듈을 추가할 때마다 아파치를 재 컴파일 해주어야 하므로 PHP 업그레이드시에 항상 아파치를 재 설치 해주셔야 합니다. 이 방식은 DSO방식에 비하여 속도가 빠릅니다.
여기서 --enable-module=so 는 dynamic shared object를 사용하겠다는 것입니다. --enable-shared=all 이 이미 DSO 설치를 뜻하므로 이 옵션은 생략해도 됩니다.

하 지만 시스템 측면에서 보면, 먼저 DSO는 아파치에 설치된 모듈이 필요할 때 시스템에 적재되므로 이는 클라이언트의 요청에 응답하는 요청시간이 다소 느릴 수 있지만, 하드웨어의 속도가 뒷받침된다면 어느 정도 해결이 될 수 있으며, 시스템의 리소스(메모리, CPU)들을 적절하게 효율적으로 사용한다고 볼 수 있습니다.
또 다른 방식인 Static 방식은 아파치에 추가된 모듈이 아파치의 기동과 함께 모든 모듈을 포함하여 시스템에 적재하기 때문에 만약 아파치의 기동과 함께 적재된 어떤 모듈이 클라이언트에 의해 거의 쓰지 않는다면 쓸데없이 시스템 리소스를 점유하고 있으므로 이는 비효율적이라 볼 수 있습니다. 또한 아파치와 각 모듈들은 설치시 복잡하며, 각 모듈과 설정된 아파치에 또 다시 모듈을 추가하려 할 때 아파치와 모듈을 다시 컴파일하여야 합니다.

이 부분은 사용자들께서 원하시는 방법을 택하시면 됩니다.


# cd /usr/local/apache

/usr/local/apache에 가셔서...

# ./configure --activate-module=src/modules/php4/libphp4.a --enable-shared=all

# make;make install

이렇게 하여 apache를 설치합니다...



9. php.ini 파일 복사

# cd /usr/local/php

# cp php.ini-dist /usr/local/lib/php.ini

php.ini-dist라는 파일을 /usr/local/lib에다가 php.ini로 이름을 바꾸어서 옮기는 겁니다.

php.ini 안의 내용중에

upload_max_filesize = 10M 업로드 용량의 수정이 필요하신 분은 수정하세요.

register_globals = On 그리고 전역변수의 사용이 필요하신 분은 수정하세요!

그럼 php 는 설정이 끝납니다.



10. httpd.conf 수정하기

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

이렇게 치셔서 설정파일을 보시고...

AddType application/x-tar .tgz 이 부분이 있으면,
이 아래에

AddType application/x-httpd-php .php
AddType application/x-httpd-php .php3
AddType application/x-httpd-php .html
AddType application/x-httpd-php .htm
AddType application/x-httpd-php-source .phps
AddType application/x-httpd-php .inc
AddType application/x-httpd-php .phtml

이렇게 추가 해줍니다.

에러페이지의 이동을 지정해 주고 싶으시면

ErrorDocument 403 http://linuxnew.com
ErrorDocument 404 http://linuxnew.com
ErrorDocument 500 http://linuxnew.com

에러 코드별로 적어주시면 됩니다.

그리고 (DirectoryIndex index.html 부분을 찾아서 다음과 같이 index.php 를 추가합니다.)

DirectoryIndex index.html index.htm index.php

※ #ServerName localhost (이 부분의 주석(#)을 꼭 지웁니다.) <- localhost를 아이피로 변경하세요!

:wq 나 :x 로 저장하시고 나오세요.

* 이렇게 해주시면 php 파일을 아파치가 실행시켜 줍니다.

--잘 아시는 분들은 쓸데없는 주석의 행들은 다 지워주시는게 나을 꺼에요^^;

그리고 특정 에이전트들을 막으시거나 이미지 파일의 로그는 남기고 싶지 않으실때는
여기 안쪽에 아래와 같이 넣어주시면 됩니다.

============================================================================
# 특정 Agent 접근 거부
BrowserMatch "WebZIP" go_out
BrowserMatch "Teleport" go_out
BrowserMatch "GetRight" go_out
BrowserMatch "FlashGet" go_out
BrowserMatch "JetCar" go_out
BrowserMatch "Go!Zilla" go_out
BrowserMatch "NamoWebEditor" go_out
BrowserMatch "Namo" go_out
BrowserMatch "MSFrontPage" go_out
BrowserMatch "WebTrack-HTTPP" go_out
BrowserMatch "WebSymmetrix" go_out

# 로컬 호스트 접속일때 로그 남기지 않음
SetEnvIf Remote_Addr "^127.0.0.1$" not_log
# 이미지 파일 자바스크립트 파일등.. 남기지 않음.
SetEnvIfNoCase Request_URI "\.(bmp|gif|jpg|jpeg|png|css|js|java)$" not_log

# 엔진 로봇 로그를 남기 않음
BrowserMatchNoCase "ru-robot" not_log a_robot
BrowserMatchNoCase "Slurp/si" not_log a_robot
BrowserMatchNoCase "Mercator" not_log a_robot
BrowserMatchNoCase "Gulliver" not_log a_robot
BrowserMatchNoCase "SyncIT/" not_log a_robot
BrowserMatchNoCase "FAST-WebCrawler" not_log a_robot
BrowserMatchNoCase "Lycos_Spider" not_log a_robot
BrowserMatchNoCase "^ia_archive" not_log a_robot
BrowserMatchNoCase "^tv" not_log a_robot
BrowserMatchNoCase "Scooter" not_log a_robot
BrowserMatchNoCase "ZyBorg/" not_log a_robot
BrowserMatchNoCase "KIT-Fireball" not_log a_robot
BrowserMatchNoCase "Googlebot/" not_log a_robot
BrowserMatchNoCase "DIIbot/" not_log a_robot
BrowserMatchNoCase "teoma_agent3" not_log a_robot
BrowserMatchNoCase "empas_robot" not_log a_robot

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



11. 아파치 시작하기

아파치 서버는 다음과 같이 실행합니다.

# /usr/local/apache/bin/apachectl start

아파치 서버의 실행을 종료하고 싶다면,

# /usr/local/apache/bin/apachectl stop

아피치 서버를 재시작 하고 싶다면,

# /usr/local/apache/bin/apachectl restart

와 같이 합니다.



12. 작동테스트

/usr/local/apache/htdocs 디렉토리에 아래와 같이 pbi12.php 파일을 만들고 브라우저로 열어봅니다.

# cat > pbi12.php


phpinfo();

?>

컨트롤 D 눌르셔서 저장하시고요.
이런식으로 만든 파일을 웹에서 http://localhost/pbi12.php라고 쳐서 열어보시면 됩니다...

콘솔에서 바로 확인하고 싶으면 lynx http://localhost/pbi12.php 하시면 됩니다.
그러면 php의 버젼과 설명이 나옵니다~
그럼 일단은 완성^^;

그리고나서 계정을 주고도 실험을 해봅시다.

# adduser pbi12
# passwd 암호

# cd ~pbi12
# mkdir public_html
# cd public_html

# cat > index.html
Hi~
컨트롤 D로 저장

# chmod 711 /home/pbi12

그러고 나서 lynx http://localhost/~pbi12 라고 치셔서 Hi~! 라고 나오면 자~~알 되는겁니당^^;



13. 부팅할 때 자동으로 서버 실행되게 설정하기

# vi /etc/rc.d/rc.local 하셔서 파일의 맨 마지막에 아래의 명령어를 추가하면 됩니다.

파일의 맨마지막으로 가기 위해서는 vi에서 $G 를 누르시면 됩니다^^;


#mysql start
/usr/local/mysql/bin/safe_mysqld --language=korean &

#apache start
/usr/local/apache/bin/apachectl start &

#ping denied
echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all


마지막은 핑을 거부하는 옵션입니다. 필요하신분은 적으세요.
라고 추가 하신후에 :wq 나 :x 하셔서 저장하구나시면, 이제부터는 부팅하면서 자동으로 실행이 되어집니다.
부팅시 mysql과 apache 데몬이 자동 시작하는지 확인하기 위해서
시스템을 재부팅하여 시스템에 데몬이 올라왔는지 확인합니다.

# ps -aux | grep apache

# ps -aux | grep mysql



14. Zend Optimizer설치

Zend Optimizer는 표준 Zend 런 타임 컴파일러에 의해 생성되는 중간 코드를 조사하고,
더 빠른 실행으로 그것을 최적화했다고 합니다. Zend Optimizer의 tar를 풀고 다음과 같은 작업을 합니다.


# tar zxvf ZendOptimizer-1.3.3-Linux_glibc21-i386.tar.gz
# cd ZendOptimizer-1.3.3-Linux_glibc21-i386
# ./install.sh

이제 차례대로 질문에 답을 하면 됩니다.
(겁먹을 필요 없습니다~ 이쁜 화면에 친절하게 Default 값이 다 우리가 셋팅한 값으로 되어 있어서 엔터만 치시면 됩니다^^)

Welcome to the Zend Optimizer 1.3.3 Installation Script!
For more information on this script, see the Installation
section in the Zend Optimizer User Guide.

Specify the location where to install Zend Optimizer

/usr/local/Zend

Confirm the location of your php.ini file

/usr/local/lib

Are you using the Apache web server?

Yes

Specify the location of your Apache root directory

/usr/local/apache

Install has detected PHP version 4.2.2
Does this look correct?
Yes

Your php.ini is relocated to the /usr/local/Zend/etc directory
and symbolic link from the former place /etc/httpd/php.ini is created.
The installation completed successfully and your Zend Optimizer
is setup for use.


You must RESTART your Apache web server for the modifications to take effect

설치 완료 메시지 지시대로 아파치를 재시작 해야 합니다.

잘 설치 되었는지 확인하는 법은 /usr/local/lib/php.ini 파일의 마지막에

[Zend]
zend_optimizer.optimization_level=15
zend_extension=/usr/local/Zend/lib/ZendOptimizer.so

이렇게 되어 있으면 잘 된 것입니다.

# /usr/local/apache/bin/apachectl restart


마지막으로 잘 되었는지 확인은 아까 만든 pbi12.php 를 다시 확인 하셔서

====================
# cat > pbi12.php


phpinfo();

?>
====================

This program makes use of the Zend Scripting Language Engine:
Zend Engine v1.2.0, Copyright (c) 1998-2002 Zend Technologies
with Zend Optimizer v1.3.1, Copyright (c) 1998-2002, by Zend Technologies

이렇게 with Zend Optimizer v1.3.1 이라는 한줄이 더 추가 되었으면 잘 된 것입니다.



15. 아파치 튜닝

이부분은 트래픽 양이 큰 곳에서 사용하시면 좋습니다.
설정파일에서 참고할 부분들을 적은 것이니, 꼭 이렇게 바꾸실 필요는 없습니다.


MaxKeepAliveRequests 100 -> 10000
웹서버 프로세스가 지속적으로 접속을 유지하면서 처리할 수 있는 요청 개수입니다.

KeepAliveTimeout 15 -> 30
서버에 접속시에 웹페이지 객체들의 전송시 새로운 프로세스를 생성하지 않고 지속적으로 접속을 유지하고 담당하며,
이 클라이언트의 요청에 대한 타임아웃에 대한 값입니다.

StartServers 5 -> 20
MinSpareServers 5 -> 20
MaxSpareServers 10 -> 40
폭주하는 서버일 경우 SpareServer가 많으면 빨리 대처할 수 있습니다.
스탠드얼론 방식일 경우 새로운 접속 요청을 받으면 기존의 Spare Child Process를 포크해 새로운 자식 프로세스를
만들어 내므로 적당히 있어주면 좋습니다.

MaxRequestsPerChild 0 -> 1000
웹서버 프로세스가 일정 횟수의 클라이언트 요청을 처리하고 종료되는 수치입니다.

※ MaxClients 256 -> 1024
동시에 실행될 수 있는 최대 프로세스 수를 제한 하는 것입니다.
하지만 옵션을 1024로 확장하려면 소스레벨에서
아파치 설치전에 apache/src/include/httpd.h 파일에서
HARD_SERVER_LIMIT 256 으로 된것을 1280 으로 변경한후 컴파일 하여야 사용 가능하다.



16. 서버 재시작

여기까지 한후에 잘 되는지 간단한 테스트 해보시고, 서버를 리붓시켜서 서버가 원격에서 리붓했을때에도
잘되는지도 확인할겸 키보드와 모니터를 제거한후에 리붓을 해주십시요.
서버 관리자들이 주로 하는 실수중에 하나로 작업시에는 잘 되었는데 원격에서 리붓을 했더니 안되버린다는 경우가
종종 있습니다. 이러한 점을 방지하기 위해서 키보드를 뽑아주시고 리붓을 합니다.
# /sbin/shutdown -r now 이나
# /sbin/reboot 으로 하시면 됩니다.
여기서 주의 할점은 CMOS 셋업에서 키보드와 모니터등 특정장치가 없을시엔 부팅이 안되는 설정이 되어 있다면
원격에서 리붓시키면 CMOS 셋업 설정때문에 부팅이 안된다는 것입니다.
만약 리붓을 했는데, 부팅이 안되신다면 CMOS 셋업에서 장치가 없어서 에러로 처리하는 부분을
NO ERROR 로 키보드가 안 꼽아져 있더라도 부팅이 되도록 해주셔야 합니다.



17. 보안 관련 소식들

최근 문제시 되었던 문제들 입니다.
참고 하시길 바랍니다.
이문서에서 설치한 버젼들은 아래 권고문들에서 해결책으로 내놓은 버젼들로 설치를 했습니다.

이 문서는 아파치에 관련하여 생긴 문제점으로 전세계적으로 많이 사용되어 지고 있는 아파치 웹서버에 보안 취약점이 보고되었습니다.
이번취약점은 HTTP 프로토콜의 기능인 'chunked' 엔코딩을 이용하여 잘못된 요청을 할 경우에 발생하는데,
아파치의 모든 버전에 해당되어 질 만큼 이 요청을 처리하는 루틴에 버그를 가지고 있습니다.
이 취약점을 이용하여 원격에서 웹 문서의 수정 및 서비스 거부(Denial Of service) 상태가 가능합니다.

테스트는 아래와 같이 해볼수 있습니다.

먼저 telnet 으로 해당 서버의 80번 포트로 접속합니다.

telnet 자신의아파치주소 80
Escape character is '^]'. 상태에서

POST /x.html HTTP/1.1
Host: 192.168.0.1
Transfer-Encoding: chunked

80000000
를 붙여서 보냅니다.

이때 Connection closed by foreign host 와 같은 메시지가 나오면서 바로
끊기는 경우는 버그에 취약한 버젼입니다.

패치가 된 아파치라면 아래와 같이 나올겁니다.

HTTP/1.1 400 Bad Request
Date: Sat, 10 Aug 2002 14:29:54 GMT
Server: Apache/1.3.26 (Unix) PHP/4.2.2
Connection: close
Content-Type: text/html; charset=iso-8859-1

이 문서에서 설치한 버젼은 패치가 된 1.3.26 버젼입니다.


( 아파치 문제점에 대한 권고문 )


CERT? Advisory CA-2002-17 Apache Web Server Chunk Handling Vulnerability
Original release date: June 17, 2002
Last revised: August 8, 2002
Source: CERT/CC

A complete revision history can be found at the end of this file.



Systems Affected
Web servers based on Apache code versions 1.2.2 and above
Web servers based on Apache code versions 1.3 through 1.3.24
Web servers based on Apache code versions 2.0 through 2.0.36


Overview
There is a remotely exploitable vulnerability in the way that Apache web servers (or other web servers based on their source code) handle data encoded in chunks. This vulnerability is present by default in configurations of Apache web server versions 1.2.2 and above, 1.3 through 1.3.24, and versions 2.0 through 2.0.36. The impact of this vulnerability is dependent upon the software version and the hardware platform the server is running on.



I. Description
Apache is a popular web server that includes support for chunk-encoded data according to the HTTP 1.1 standard as described in RFC2616. There is a vulnerability in the handling of certain chunk-encoded HTTP requests that may allow remote attackers to execute arbitrary code.

The Apache Software Foundation has published an advisory describing the details of this vulnerability. This advisory is available on their web site at

http://httpd.apache.org/info/security_bulletin_20020617.txt
Vulnerability Note VU#944335 includes a list of vendors that have been contacted about this vulnerability.



II. Impact
For Apache versions 1.2.2 through 1.3.24 inclusive, this vulnerability may allow the execution of arbitrary code by remote attackers. Exploits are publicly available that claim to allow the execution of arbitrary code.

For Apache versions 2.0 through 2.0.36 inclusive, the condition causing the vulnerability is correctly detected and causes the child process to exit. Depending on a variety of factors, including the threading model supported by the vulnerable system, this may lead to a denial-of-service attack against the Apache web server.



III. Solution
Upgrade to the latest version
The Apache Software Foundation has released two new versions of Apache that correct this vulnerability. System administrators can prevent the vulnerability from being exploited by upgrading to Apache httpd version 1.3.26 or 2.0.39.

Due to some unexpected problems with version 1.3.25, the CERT/CC has been informed by the Apache Software Foundation that the corrected version of the software is now 1.3.26. Both 1.3.26 and 2.0.39 are available on their web site at

http://www.apache.org/dist/httpd/
Apply a patch from your vendor
If your vendor has provided a patch to correct this vulnerability, you may want to apply that patch rather than upgrading your version of httpd. The CERT/CC is aware of a patch from ISS that corrects some of the impacts associated with this vulnerability. System administrators are encouraged to ensure that the patch they apply is based on the code by the Apache Software Foundation that also corrects additional impacts described in this advisory.

More information about vendor-specific patches can be found in the vendor section of this document. Because the publication of this advisory was unexpectedly accelerated, statements from all of the affected vendors were not available at publication time. As additional information from vendors becomes available, this document will be updated.



이 문제점은 PHP 버젼 4.2.0 그리고 4.2.1들안에서 나타나는 문제로 침입자가 웹 서버의 특권들을 가지고 자의적 코드를 실행할 수 있습니다. 이 취약성이 웹서버를 조종 하는데 사용될 수 있습니다.
PHP 는 포스트 요청의 헤더들을 분석하기 위하여 코드를 포함 하게 되고, 이 코드는 multipart/form-data 요청에 의해서 보내진 변수와 파일들 사이에 다른점이 있는지 비교하기위하여 사용됩니다. 이때 파서가 분석을 할때 불 충분한 입력을 조사하고, 이 과정에서 취약성을 유발합니다.
해결방법은 PHP 4.2.0 과 4.2.1 패치를 적용하거나 4.2.2 최신 버젼을 사용하면 됩니다.
이 문서에서는 PHP 4.2.2 를 사용하고 있습니다.


( PHP 문제점에 대한 권고문 )


CERT? Advisory CA-2002-21 Vulnerability in PHP
Original release date: July 22, 2002
Last revised: Thu Jul 25 09:23:27 EDT 2002
Source: CERT/CC

A complete revision history can be found at the end of this file.


Systems Affected
Systems running PHP versions 4.2.0 or 4.2.1


Overview
A vulnerability has been discovered in PHP. This vulnerability could be used by a remote attacker to execute arbitrary code or crash PHP and/or the web server.


I. Description
PHP is a popular scripting language in widespread use. For more information about PHP, see

http://www.php.net/manual/en/faq.general.php



The vulnerability occurs in the portion of PHP code responsible for handling file uploads, specifically multipart/form-data. By sending a specially crafted POST request to the web server, an attacker can corrupt the internal data structures used by PHP. Specifically, an intruder can cause an improperly initialized memory structure to be freed. In most cases, an intruder can use this flaw to crash PHP or the web server. Under some circumstances, an intruder may be able to take advantage of this flaw to execute arbitrary code with the privileges of the web server.

You may be aware that freeing memory at inappropriate times in some implementations of malloc and free does not usually result in the execution of arbitrary code. However, because PHP utilizes its own memory management system, the implementation of malloc and free is irrelevant to this problem.

Stefan Esser of e-matters GmbH has indicated that intruders cannot execute code on x86 systems. However, we encourage system administrators to apply patches on x86 systems as well to guard against denial-of-service attacks and as-yet-unknown attack techniques that may permit the execution of code on x86 architectures.

This vulnerability was discovered by e-matters GmbH and is described in detail in their advisory. The PHP Group has also issued an advisory. A list of vendors contacted by the CERT/CC and their status regarding this vulnerability is available in VU#929115.

Although this vulnerability only affects PHP 4.2.0 and 4.2.1, e-matters GmbH has previously identified vulnerabilities in older versions of PHP. If you are running older versions of PHP, we encourage you to review http://security.e-matters.de/advisories/012002.html



II. Impact
A remote attacker can execute arbitrary code on a vulnerable system. An attacker may not be able to execute code on x86 architectures due to the way the stack is structured. However, an attacker can leverage this vulnerability to crash PHP and/or the web server running on an x86 architecture.

III. Solution
Apply a patch from your vendor
Appendix A contains information provided by vendors for this advisory. As vendors report new information to the CERT/CC, we will update this section and note the changes in our revision history. If a particular vendor is not listed below, we have not received their comments. Please contact your vendor directly.

Upgrade to the latest version of PHP
If a patch is not available from your vendor, upgrade to version 4.2.2.
Deny POST requests
Until patches or an update can be applied, you may wish to deny POST requests. The following workaround is taken from the PHP Security Advisory:


If the PHP applications on an affected web server do not rely on HTTP POST input from user agents, it is often possible to deny POST requests on the web server.

In the Apache web server, for example, this is possible with the following code included in the main configuration file or a top-level .htaccess file:


Order deny,allow
Deny from all


Note that an existing configuration and/or .htaccess file may have parameters contradicting the example given above.

Disable vulnerable service
Until you can upgrade or apply patches, you may wish to disable PHP. As a best practice, the CERT/CC recommends disabling all services that are not explicitly required. Before deciding to disable PHP, carefully consider your service requirements.



이 SQL Query 에 관련하여 생긴 문제로 magic_quotes_gpc 옵션이 Off인 상태에서 작동되는 DBMS연동 PHP 프로그램에 관련이 있습니다.
하지만 이 문서에서 셋팅한 php.ini 의 설정은 magic_quotes_gpc 옵션이 ON 으로 되어 있습니다.

( SQL Query Vulnerability In PHP )


Release date Aug 8, 2002
Author 윤성진 - chaos@ecrobot.com
한상진 - komnaru@ecrobot.com
Source (주) 이씨로봇 연구소
Application magic_quotes_gpc 옵션이 Off인 상태에서 작동되는 DBMS연동 PHP 프로그램.
Risk Critical
Reference http://lab.ecrobot.com/advisories/ec2002080801
Last modified 2002/08/09
문의 info@ecrobot.com



차례

0x00. Overview
0x01. 해당 환경
0x02. DBMS를 연동하는 프로그램의 일반적인 구조
0x03. 공격이 이루어지는 원리
0x04. Exploit: 제로보드의 예
0x05. 해결책
0x06. ';' 문자를 이용한 SQL statement 조작
0x07. 결론


0x00. Overview

최 근 웹 프로그래밍은 대부분 자료의 효율적인 저장 및 검색을 위해 DBMS를 거의 필수적으로 이용하는 추세이다. 웹 프로그래밍은 보통 PHP, JSP, ASP 등의 스크립트 언어를 이용하여 DBMS를 연동하여 프로그래밍을 하게 된다. 이러한 프로그램에서 생기는 문제점으로서, 잘못된 값을 웹 프로그램으로 넘겨줌으로써, 부적절한 SQL Query를 실행시키도록 할 수가 있다.
이 공격을 이용하면 불법적인 데이터베이스 query를 이용하여 인증을 위해 사용하는 SQL query 등을 비정상적으로 만들어서, 아이디나 암호가 맞지 않음에도 불구하고 인증을 정상적으로 한 것처럼 만들 수가 있다.
현재 대부분의 웹 기반 공개 게시판과 수많은 사이트들이 이 문제점에 노출되어 있는 것으로 확인되었다.
이 문서는 DBMS를 연동하는 웹 프로그램이 가질 수 있는 치명적인 문제점과 그 해결책에 대해 다룬다. 주로 PHP의 경우를 다루지만 다른 언어에서도 얼마든지 있을 수 있는 문제이다.


0x01. 해당 환경

이 문제점은 플랫폼과는 무관하다. 다만 PHP로 DBMS를 연동하는 경우, PHP의 설정에서 magic_quotes_gpc 옵션이 Off로 되어 있는 경우에 이 문제가 발생한다. 다른 프로그래밍 언어의 경우에도 사용자로부터 넘겨받은 데이터에 포함된 따옴표에 자동으로 escape처리가 되지 않는 경우에는 이 문제가 발생할 수 있다. 참고로 PHP 4.x 버전에 포함된 2개의 php 설정 파일 중, PHP 측에서 권장하는 설정 파일인 php.ini-recommend에는 성능상의 이유로 이 옵션이 기본적으로 Off로 설정되어 있어서 이 공격을 당할 수 있다.


0x02. DBMS를 연동하는 프로그램의 일반적인 구조

웹 프로그램은 HTML에서 form tag를 이용하여 사용자로부터 데이터를 입력 받고, GET이나 POST method를 이용하여 프로그램으로 데이터를 넘겨주면 프로그램에서 적절한 DBMS query를 통해 데이터 입출력을 하고 그 결과를 다시 사용자에게 보여주는 형태를 가지고 있다.
예로 ID와 암호를 입력받아 인증을 해주는 간단한 PHP 스크립트는 다음과 같은 형태를 가지고 있을 수 있다. 아래의 Login.html은 form tag를 이용하여 사용자로부터 id와 password를 입력받는 form을 출력하는 파일이고, login.php는 사용자가 입력한 데이터를 바탕으로 DBMS에 query를 하여 인증을 처리하는 프로그램이다.

- login.html




ID:



Password:









- login.php
$MySQL = mysql_connect("localhost", "user", "password");
mysql_select_db("database");

$result = mysql_query("SELECT id, passwd FROM user_table WHERE id='{$_POST['id']}' AND passwd='{$_POST['passwd']}'");
$data = mysql_fetch_assoc($result);

if (($data['id'] == $_POST['id']) && ($data['passwd'] == $_POST['passwd'])) {
/* 인증을 위해 세션 등을 설정 */
}

else {
/* 인증에 실패한 경우, 에러 출력 등의 처리 */
}
?>

위 의 형태는 아주 일반적인 형태의 웹 프로그램으로 대부분의 프로그램이 이런 식으로 사용자로부터 받은 데이터를 이용하여 SQL query를 하고, 그 결과에 따라 특정한 처리를 하게 된다. 여기서는 사용자로부터 "id"와 "passwd"라는 2개의 데이터를 POST 방식으로 받아서, 프로그램 내에서는 $_POST['ID'], $_POST['passwd']와 같은 식으로 SQL query에 이용하고 있다(PHP에서는 이런 식으로 처리한다).
일반적인 경우에는 위와 같은 코드는 별 문제가 되지 않고 잘 작동할 것이다. 그러나 만약 php.ini 설정 파일에서 magic_quotes_gpc 옵션이 Off로 되어 있다면 아주 치명적인 문제점이 있다.


0x03. 공격이 이루어지는 원리

PHP 의 설정 파일(php.ini) 중, magic_quotes_gpc 옵션이 하는 일은 사용자가 웹에서 입력한 데이터를 GET, POST으로 프로그램으로 넘겨줄 때나, 쿠키를 처리할 때에 ', ", \, 널 문자의 앞에 \를 하나 더 붙여 주어서 이러한 문자가 특수한 의미로 사용되지 않도록 escape시켜주는 것이다.

위에서 예로 든 코드 중 사용자가 입력한 id와 passwd라는 변수값을 SQL query에 넣어서 DBMS로 query를 하는 부분은 다음과 같다.

$result = mysql_query("SELECT id, passwd FROM user_table WHERE id='{$_POST['id']}' AND passwd='{$_POST['passwd']}'");

만약 사용자가 id로 chaos를, 비밀번호로도 chaos를 넣었다면 위의 코드는 사실상 다음과 같이 변환될 것이다.

$result = mysql_query("SELECT id, passwd FROM user_table WHERE id='chaos' AND passwd='chaos'");

원래 코드에 있었던 $_POST['id']와 $_POST['passwd'] 부분이 각각 chaos로 대체되면서 위와 같은 결과가 되는 것이다. 바로 이 부분에 헛점이 있다.

만 약 사용자가 id로 chaos와 같은 정상적인 값을 넣지 않고 a' or 1<2 or 'a'<'b라고 입력했다고 가정해보자. php.ini에서 magic_quotes_gpc 옵션이 On으로 되어 있을 경우에 원래 코드는 다음과 같이 변환될 것이다.

$result = mysql_query("SELECT id, passwd FROM user_table WHERE id='a\' or 1<2 or \'a\'<\'b' AND passwd='chaos'");

이런 경우에는 저런 희한한 아이디가 있을리도 없고 암호가 맞을리도 없기 때문에 이 query는 아무 row도 반환하지 않고 그 결과 인증에 실패하게 된다.

그 러나 이번에는 php.ini에서 magic_quotes_gpc 옵션이 Off로 되어 있는 경우를 가정해 보자. php.ini-recommend 설정 파일을 그대로 이용하는 경우가 바로 이 경우이다. 그러면 원래 코드는 다음과 같이 변환될 것이다.

$result = mysql_query("SELECT id, passwd FROM user_table WHERE id='a' or 1<2 or 'a'<'b' AND passwd='chaos'");

결 론부터 얘기하자면 위의 SQL 문에서 WHERE clause는 항상 true이고, 모든 row를 반환하게 된다. 그렇게 되면 첫번째로 반환되는 row의 정보를 기반으로 로그인이 수행되게 된다. 왜 이 WHERE clause가 항상 true인가? 그것은 logical AND 연산이 logical OR 연산보다 우선순위가 높기 때문이다. 언뜻 보기에 위의 WHERE clause는 상당히 confusing해 보인다. 그러나 사실은 전혀 헷갈릴 것이 없이 매우 명확한 논리적 연산이다. 위의 SQL 문을 우선순위에 따라 단계적으로 괄호를 쳐보면 다음과 같다.

1: SELECT id, passwd FROM user_table WHERE id='a' or 1<2 or ('a'<'b' AND passwd='chaos')
2: SELECT id, passwd FROM user_table WHERE (id='a' or 1<2) or ('a'<'b' AND passwd='chaos')

1 단계에서는 OR 연산보다 AND 연산이 우선순위가 높기 때문에 AND 쪽에 괄호를 쳤다. 그리고 나서 나머지 OR는 우선순위가 같은데, 이런 경우에는 앞에 있는 것이 더욱 우선순위가 높기 때문에 앞의 OR를 괄호로 묶었다. 이 상태에서 보면 앞의 괄호는 항상 true이다. "1<2" 연산 때문이다. 뒤에 괄호가 설사 false를 반환한다고 하더라도 이 두개의 결과가 or로 연결되었기 때문에 뒤의 괄호의 결과는 중요하지 않다. 이 WHERE clause는 항상 true인 것이다.

웹상의 로그인 form에 ID 등을 입력할 때 이런 식으로 ID를 교묘히 입력하면 SQL query 문을 비정상적으로 만들어서 아이디, 암호를 전혀 몰라도 아무 아이디로나 로그인이 가능하도록 할 수도 있고, 또한 아이디만 안다면 아이디만 적절히 지정하여 암호 없이 로그인을 통과할 수도 있다. 물론 대상 테이블 구조를 잘 알고 있다면 그 이상의 조작도 가능하다.


0x04. Exploit: 제로보드의 예

리 눅스에서 인기있는 공개형 게시판 중 제로보드가 있다. 이 제로보드의 경우를 예로 들어, 이 공격을 실제로 테스트해 보겠다. 테스트 환경은 PHP 4.2.2(설정 파일로 php.ini-recommend 사용), 제로보드 버전 4.1 pl2이다.



위 와 화면이 제로보드의 관리자 로그인 화면이다. 여기서 위와 같이 a' or 1<2 or 'a'<'b를 아이디 대신 입력하였다. 제로보드의 경우, 로그인을 체크하는 프로그램은 login_check.php이고 이 파일을 열어보면 인증을 하는 SQL query는 다음과 같이 적혀 있다.

$result = mysql_query("select * from $member_table where user_id='$user_id' and password=password('$password')") or error(mysql_error());

이런 경우에 아이디를 a' or 1<2 or 'a'<'b로 입력하고 암호는 아무것이나 입력하면 위의 SQL 문은 다음과 같이 변환된다.

select * from $member_table where user_id='a' or 1<2 or 'a'<'b' and password=password('asdfasdf');

이 SQL 문의 WHERE clause는 항상 true이며, 모든 row를 반환한다. 이런 경우에 맨 처음 반환되는 row에 의해 인증이 처리되도록 제로보드 프로그램이 만들어져 있다. 보통 게시판을 설치하면 관리자 아이디를 가장 먼저 만들게 되며, 그런 이유로 대부분 모든 row를 정렬없이 검색했을 때 관리자 아이디가 제일 먼저 반환되게 된다. 따라서 관리자로 로그인이 되는 것이다. 혹은 level=1인 row를 명시적으로 뽑아낼 수도 있을 것이다.


여기서는 관리자 페이지만 테스트를 해보았으나, 일반 사용자 계정으로도 얼마든지 불법적인 로그인이 가능하다. 그런 경우에는 아이디만 지정하고 비밀번호는 아무것이나 적어도 통과시킬 수 있다. 또한 이 문제는 제로보드만이 가지고 있는 문제는 아니다.


0x05. 해결책

php.ini 설정에서 magic_quotes_gpc = On으로 설정하면 안전하다. 그러나 PHP 측에서는 performance 향상을 위해 이 옵션을 Off로 설정하도록 권장하고 있다. 또한 현재 PHP에서 권장하는 설정 파일에도 이 옵션이 기본적으로 Off로 되어 있다.

이 옵션이 Off로 되어 있는 상태로 프로그램을 작동시키고 싶다면 DBMS로 query를 전송하기 전에, SQL query statement를 만들기 위해 사용되는 변수들에 따옴표 등이 있는가를 확실히 체크하여 이 문자들을 escape시켜주도록 해야 한다.

한 예로, PHP에서 MySQL을 연동하는 경우를 위해 mysql_escape_string()이라는 함수를 제공한다. 이 함수는 따옴표와 같이 잘못된 MySQL query를 유발할 수 있는 문자에 대해 escape 처리를 해준다. 따라서 MySQL을 사용하는 제로보드의 경우 login_check.php 파일 앞부분을 다음과 같이 고치면 이 문제를 피할 수 있다.

$user_id = mysql_escape_string(trim($user_id));
$password = mysql_escape_string(trim($password));

위 의 코드는 magic_quotes_gpc 옵션이 Off로 되어 있는 경우에만 사용해야 정상적으로 작동한다. magic_quotes_gpc 옵션이 On인 경우에는 이미 escape된 문자열에 또 escape 처리를 하게 되기 때문에 비정상적으로 작동하게 된다. 어느 경우에나 작동하도록 고치려면 get_magic_quotes_gpc()라는 함수를 이용하면 될 것이다.

오라클의 경우에는 ' 문자를 ''로 대체한 후에 SQL query를 작성하도록 하면 될 것이다.

제 로보드의 경우, 윗 부분만 고쳤다고 해서 완전히 안전하다고 할 수는 없을 것이다. 다른 SQL query를 사용하는 수많은 부분에서 모두 잠재적인 위험이 있기 때문이다. 결국은 모든 게시판의 개발자 측에서 조치를 취해주는 것이 가장 바람직할 것이다.


0x06. ';' 문자를 이용한 SQL statement 조작

한 번 더 생각해 보면, ID 등을 입력할 때에 아얘 ; DROP TABLE user_table; 등과 같이 입력해서 완전히 독립적인 SQL 문도 실행시킬 수 있지않을까 하고 생각될 수도 있다. 그러나 이 점은 안심해도 된다. PHP에서 MySQL로 query를 전송할 때에 ';' 문자가 포함되어 있으며 에러를 낸다.

0x07. 결론

PHP 언어가 버전 4.x 대로 넘어오면서 php.ini-recommend라는 설정 파일에 magic_quotes_gpc 옵션이 기본적으로 Off로 되어 있기 때문에, 기존의 설정대로라면 아무 문제없이 사용되던 게시판 프로그램 등이 보안 위험에 처하게 될 수 있다. 현재 만들어져 있는 많은 게시판 프로그램들이 PHP에서 자동으로 escape 처리를 해 줄것이라는 가정 하에 만들어졌기 때문에 이것이 더욱 위험한 것이다. 사실 이런 비슷한 유형의 문제는 예전에 perl로 웹 프로그래밍을 하던 시절부터 있던 문제였다. 다만 지금까지 PHP에서는 기본적으로 자동으로 특수 문자를 escape시켜주는 기능이 있기 때문에 보안 이슈가 되지 못했을 뿐이다.

또한 이 문제는 웹 프로그램에만 한정해서 생각할 문제는 아니다. C 언어로 system() 함수를 이용할 때에나 Perl 언어에서 `command`; 형식으로 다른 프로그램을 호출해서 사용할 때에도 항상 신중해야 한다.

만약 sendmail 프로그램을 호출하여 편지를 발송해주는 프로그램을 Perl이나 C 언어로 작성할 때에는 ; 문자를 조심해야 한다. 왜냐하면 만약 사용자가 이메일로 chaos@ecrobot.com; rm -rf / 이렇게 입력했다면 매우 심각한 문제를 가져올 수 있기 때문이다. 이런 경우에 sendmail chaos@ecrobot.com; rm -rf /과 같은 명령어가 쉘에서 실행되는 것이다.