출처 : http://theeye.pe.kr


지금 작성할 글은 어찌보면 [이곳]의 글의 연장선상에서 봐야 할 글일꺼 같습니다.

ProxyAJP에 대해 잘 모르신다면 링크의 글을 보시거나 좀더 검색해 보시고 보시면 좋을 것같습니다.

제가 운영하는 투명아이 호스팅에서 JSP 호스팅을 좀더 편하게 구현할 방법을 찾아보니 여기까지 왔습니다.

정말 간단하다 못해 너무 단순하게 강력한 효과를 얻을 수 있는 방법이라고 생각합니다.

우선 보통의 경우 mod_jk를 이용하여 연동을 하게 되는데요, 이때에 볼 수 있는 설정 파일은 대충 다음과 같습니다.

LoadModule          jk_module       modules/mod_jk.so

JkWorkersFile /usr/local/tomcat/conf/workers.properties
JkLogFile /var/log/httpd/mod_jk.log
JkOptions +ForwardKeySize +ForwardURICompat -ForwardDirectories -ForwardLocalAddress
JkLogStampFormat "[%a %b %d %H:%M:%S %Y] "
JkRequestLogFormat "%w %V %T"
JkLogLevel info

JkMount             /servlet/*      ajp13
JkMount             /manager/*      ajp13
JkMount             /flex/*         ajp13
JkMount             /*.jsp          ajp13
JkMount             /*.do           ajp13

위의 방법은 Apache 2.2의 ProxyAJP 모듈을 이용한 방법으로 고쳐 보겠습니다. [참고]

다음과 같은 설정 파일을 proxy_ajp.conf 파일로 만들어 Apache의 설정 파일에 Include되도록 합시다.
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so

ProxyRequests Off
ProxyVia Block
ProxyMaxForwards 100
ProxyPreserveHost On

ProxyPass /manager/ ajp://localhost:8009/manager/
ProxyPass /servlet/ ajp://localhost:8009/servlet/
ProxyPass /flex/ ajp://localhost:8009/flex/
ProxyPassMatch ^/.*\.(jsp|do)$ ajp://localhost:8009/

# 보안을 위해 WEB-INF 접근 불가설정
<LocationMatch "/WEB-INF">
    deny
from all
</LocationMatch>

# 보안을 위해 META-INF 접근 불가설정
<LocationMatch "/
META-INF">
    deny from all
</LocationMatch>

ProxyPass를 사용하여 특정 디렉토리를 톰캣에서 처리하게 할 수 있습니다.

ProxyPassMatch를 이용하여 특정 확장자를 가진 파일을 톰캣에서 처리하도록 할 수 있습니다. 정규식을 잘 쓰면 되겠네요.

이제는 더이상 worker.properties니 하는 파일이 필요없습니다. 위와 같은 방법으로 간단하게 처리 가능합니다.

WEB-INF나 META-INF 디렉토리로의 접근 보안 문제는 위와같이 해결할 수 있습니다.

위와 같은 설정으로 웹호스팅 환경의 멀티 가상호스트상황에서도 일일이 연동 설정을 할 필요없어졌습니다.

출처 : http://theeye.pe.kr
출처 : http://theeye.pe.kr

아래에 쓴글은 정상적으로 작동하지 않으며 다음의 방법이 보안을 위한 정상적인 방법입니다.
ProxtRequests 설정을 Off로 변경 :
외부 요청이 차단됨, 이후에도 ProxyPass, ProxtPassMatch등 정상 사용 가능


- 기존의 글

기존에 다음과 같은 ProxyAJP를 이용한 Apache2와 Tomcat의 연동법에 대한 글을 썼었습니다.

- Proxy AJP + mod_rewrite를 이용하여 Apache 2.2 + Tomcat 완벽 연동하기
- Apache 2 Proxy AJP를 이용한 호스팅 환경에서의 완벽 연동

하지만 위의 방법들에 중대한 보안 문제가 있다는 것을 알게 되었습니다. 어느 순간부터인가 서버에 엄청난 트래픽이 유입되더군요.

저는 단순히 DDOS공격인줄 알았습니다. IP는 정체를 알수 없이 전세계에서 들어오더군요. 사실상 끝나기를 기다리며 내 서버에는 사실상 영리목적의 사이트가 없는데 무엇이 목적일까 고민하게 되었습니다.

우선 쌓이는 로그가 매우 특이한것을 알수 있었습니다. 로그는 대충 다음과 같은 형식이었습니다.

202.109.175.224 - - [17/Apr/2009:21:17:39 +0900] "GET http://www.dfwater.com/Index.asp HTTP/1.1" 503 28 "http://www.dfwater.com/" "Mozilla/4.0 (compatible; MSIE 6.0; Windows 5.1)"
84.16.227.121 - - [17/Apr/2009:21:17:35 +0900] "GET http://www.google.com/ie?q=puts+inurl:?p%3D&hl=en&num=100&start=200&sa=N HTTP/1.0" 302 335 "http://www.google.com/ie?q=puts+inurl:?p%3D&hl=en&num=100&start=200&sa=N" "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)"
64.91.72.166 - - [17/Apr/2009:21:17:39 +0900] "CONNECT 205.188.251.26:443 HTTP/1.0" 200 - "-" "-"
61.160.211.12 - - [17/Apr/2009:21:17:36 +0900] "GET http://www.kiss888mu.cn HTTP/1.1" 500 3847 "http://www.baidu.com" "Mozilla/4.0 (compatible; MSIE 6.0; Windows 5.1)"
118.69.166.3 - - [17/Apr/2009:21:17:39 +0900] "GET http://69.147.112.211/config/isp_verify_user?l=mmg&p=0011 HTTP/1.0" 200 26 "-" "-"
208.70.78.177 - - [17/Apr/2009:21:17:36 +0900] "GET http://www.google.com/ie?as_q=inurl:/guestbook.html+tampa+fl+gay+life+and+dating&num=100&hl=en HTTP/1.0" 302 355 "http://www.google.com/ie?as_q=inurl:/guestbook.html+tampa+fl+gay+life+and+dating&num=100&hl=en" "Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.8b2) Gecko/20050224 Firefox/1.0+"
78.30.203.105 - - [17/Apr/2009:21:17:39 +0900] "GET http://inmarket73.ru/forum/index.php?s=fb2bade970f814c6d66c67f414a2328b&act=Reg&CODE=image&rc=35f728107e6ae6292a22c4e6f16634ac&p=3 HTTP/1.0" 200 68 "http://inmarket73.ru/forum/index.php?act=Reg&CODE=image&rc=7f430230e31d334872d1b5136a57b9ce&p=1" "Mozilla/4.0 (compatible; MSIE 6.0; AOL 9.0; Windows NT 5.1)"
94.76.199.2 - - [17/Apr/2009:21:17:36 +0900] "GET http://superschurke.de/comments/feed/ HTTP/1.1" 404 809 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)"


로그가 좀 지저분 합니다만 형식이 다음과 같다는것만 보시면 됩니다. 요청이 GET 메서드 이후에 http로 시작하는 것을 알수 있습니다. 그것도 전혀 쌩뚱 맞은 도메인과 호스트에 요청을 합니다.

이것이 왜 이상하냐면 보통의 브라우저는 요청을 할때 다음과 같이 합니다. theeye.pe.kr/index.html의 요청이 있다면 DNS에 질의 하여 theeye.pe.kr 도메인의 호스트 IP를 알아낸 이후에 그곳에 접속하여 GET /index.html 과 같은 방법으로 요청을 하게 됩니다.

위와 같은 방법은 마치 여의도에 가서 "롯데월드가 어딧나요?" 라고 물어보는 꼴이 되는 것입니다.

왜 저런 요청이 자꾸 들어오는 것인지 궁금하여 서버에 다음과 같이 테스트를 해보았습니다.

telnet theeye.pe.kr 80
GET http
://www.naver.com

자, 상식적으로 잘못된 요청이라고 나와야 하지만 정상적으로 페이지가 출력됩니다. 아니 왜 내 서버에서 엉뚱한 사이트의 요청을 처리해 주는 것이지!?

이제 여의도에 가서 "롯데월드가 어딧나요?" 라고 물었더니 상대방이 자기 차에 태워 롯데월드에 데려다 주었습니다.

친절한 사람이군요;;; 근데 문제가, 이걸 악용해서 소문이 나서 세상의 모든 사람이 이 친절한 사람에게 와서 자신이 가고싶은 곳이 어딧는지를 물어본다는 것이 문제가 됩니다.

서버가 엉뚱한 요청을 받아 대리 요청후에 결과를 되돌려 주는 문제는 일전의 Proxy설정의 잘못이었습니다.

ProxyAJP설정을 별다른 보안 절차 없이 설정하게 되면 이 세상 모든 http 요청의 IP세탁 시스템으로 둔갑되어질 수 있습니다.

이문제를 해결하기 위해서는 간단하게 Proxy 요청은 로컬호스트에서만 가능하게 설정하시면 됩니다.

<Proxy *>
Order Deny,Allow
Deny from all
Allow from localhost
</Proxy>

간단하게 해결되었죠? Proxy 설정을 하시고 서버를 운영하시는 분들은 다른 호스트로의 요청을 해보시기 바랍니다.

에러없이 요청이 정상처리 된다면, 이제 표적이 되기전에 설정을 조금 손보시기 바랍니다.

첨언 : 추가로 로그들을 쭉 분석해 봤는데, 위와 같은 방법을 사용하는 이유는 특정 사이트의 검색요청을 계속하여 검색랭킹을 올린다거나, 추천사이트의 어뷰징 혹은 사이트 페이지뷰를 높이는데 사용되어지는 듯 싶습니다.

출처 : http://theeye.pe.kr

출처 : http://theeye.pe.kr


블로그 글에 자꾸 반말/존칭이 섞여가는거 같아 껄끄럽긴 하지만 이번에는 존댓말로 써봅니다;;

여러분의 JAVA/JSP는 어떤 WAS에서 돌리고 계신가요? 톰캣을 쓰신다고요?

그럼 웹서버는 아파치를 사용하시겠군요. 연동을 위해 톰캣 사이트에서 받을 수 있는 mod_jk를 많이들 쓰실것입니다.

하지만 아파치 2.2.x에서 제공하는 Proxy AJP를 사용하면 매우 깔끔하게 연동을 할 수 있습니다.

톰캣은 설치가 되어 정상적으로 동작하고 있는 상황이라 가정하고 아파치 설정만을 적어보겠습니다.

[이곳]에서 가장 최신의 아파치 2.2 버젼을 다운받습니다. 압축을 풀고 컴파일을 합니다.

설정(쓰레드 방식)

[root@Theeye src]$ CC="gcc" CFLAGS="-O2" ./configure --prefix=/usr/local/httpd --enable-so --enable-proxy-ajp --enable-cgi --enable-rewrite --enable-speling --enable-usertrack --enable-deflate --enable-ssl --enable-cache --enable-disk-cache --enable-expires --enable-file-cache --enable-headers --enable-mem-cache --enable-mime-magic --enable-proxy --enable-mods-shared=all --with-mpm=worker

설정(프로세스 방식)
[root@Theeye src]$ CC="gcc" CFLAGS="-O2" ./configure --prefix=/usr/local/httpd --enable-so --enable-proxy-ajp --enable-cgi --enable-rewrite --enable-speling --enable-usertrack --enable-deflate --enable-ssl --enable-cache --enable-disk-cache --enable-expires --enable-file-cache --enable-headers --enable-mem-cache --enable-mime-magic --enable-proxy --enable-mods-shared=all --with-mpm=prefork

컴파일
[root@Theeye src]$ make
[root@Theeye src]$ make install


아파치가 설치된 디렉토리의 conf/httpd.conf 파일을 열어 다음의 두가지가 정상적으로 존재하는지 확인합니다.
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
LoadModule rewrite_module modules/mod_rewrite.so


그리고 마지막쯤에 있는 가상호스팅 관련 설정을 인클루드 하도록 설정합니다.
Include conf/extra/httpd-vhosts.conf


아파치 설치 디렉토리의 conf/extra/httpd-vhost.conf 파일을 열어 가상호스트를 추가합니다.
<VirtualHost *:80>
    ServerAdmin
your@emailhere
    DocumentRoot /var/www/html
    ServerName theeye.pe.kr
    ErrorLog logs/theeye.pe.kr-error_log
    CustomLog logs/theeye.pe.kr-access_log common

    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} \.(htm|html|xhtml|js|css|jpg|gif|png|swf)$
    RewriteRule (.*) - [L]
    RewriteRule (.*) ajp://localhost:8009$1 [P]
</VirtualHost>


위 와같은 rewrite를 통한 설정은 htm, html, xhtml, js, css, jpg, gif, png, swf 확장자를 가진 요청은 아파치가 처리하도록 하고 나머지는 톰캣이 처리하도록 합니다. 원하시는 확장자를 마음껏 추가하셔도 됩니다.

톰캣이 설치된 디렉토리의 conf/server.xml의 설정을 변경합니다. Connector설정을 확인합니다.
<Connector port="8009" protocol="AJP/1.3" maxThreads="150" minSpareThreads="25" 
   
maxSpareThreads="75" enableLookups="false" redirectPort="8443" acceptCount="100"
   
debug="0" connectionTimeout="20000" disableUploadTimeout="true" URIEncoding="UTF-8" />


아파치 가상호스트에 지정한것과 동일한 호스트를 설정합니다.
<Host name="theeye.pe.kr" debug="0" appBase="/var/www/html" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false">
<Context path="" docBase="/var/www/html" debug="0" reloadable="false" crossContext="true" />
</Host>


자, 이제 아파치와 톰캣의 설정이 모두 끝났습니다. 위와 같이 사용하시면 아파치에서 처리할 파일과 톰캣이 처리할 파일들을 따로 분리할 필요도 없으며 확장자에 따라 정확히 아파치와 톰캣이 분산 처리를 하게 됩니다.

정적인 파일들을 톰캣이 처리할 필요는 없으니깐요^^

추가로 특정 호스트에게만 오픈하는 관리자 페이지거나 개발서버일 경우 다음과 같이 접근 가능 아이피를 지정할 수 있습니다.

<VirtualHost *:80>
    ServerAdmin
your@emailhere
    DocumentRoot /var/www/html
    ServerName theeye.pe.kr
    ErrorLog logs/theeye.pe.kr-error_log
    CustomLog logs/theeye.pe.kr-access_log common

    RewriteEngine On
    RewriteCond !%{REMOTE_ADDR} ^127\.0\.0\.1$
    RewriteRule ^.*$ - [F]
    RewriteCond %{REQUEST_FILENAME} \.(htm|html|xhtml|js|css|jpg|gif|png|swf)$
    RewriteRule (.*) - [L]
    RewriteRule (.*) ajp://localhost:8009$1 [P]
</VirtualHost>



127.0.0.1 아이피를 가진 호스트가 아니라면 아파치에서 바로 에러페이지를 출력하게 됩니다.

위의 방법을 사용할 경우 보안 문제가 있으니 [ProxyAJP를 이용한 Apache2 + Tomcat 연동시 중대한 보안 문제]을 참고하세요

출처 : http://theeye.pe.kr

<connector .....  useBodyEncodingForURI="true"  URIEncoding="UTF-8" >

추가




Tomcat Plugin for Eclipse

http://www.eclipsetotale.com/tomcatPlugin.html#A3


'PDS' 카테고리의 다른 글

Desy Edit (무료 편집기)  (0) 2010.10.18
프록시 우회 프로그램 ultraSurf  (0) 2010.09.25
Tomcat Plugin for Eclipse  (0) 2010.03.30
JAD - java Decompiler  (0) 2010.03.30
DDL2iBatis  (0) 2009.09.01
네이트온 글꼴 바꾸기.  (0) 2009.08.14
이걸 내가 다시 적을 줄 몰랐다;;;;

설치버전

RedHat Linux 기반의 Sulinux 1.5 (http://www.sulinux.net)
Apache 2.2.4 (http://www.apache.org - httpd)
Mysql 5.0.37 (http://www.mysql.com)
Tomcat 6.0.10 (http://www.apache.org - tomcat )
JDK 6.0 (http://java.sun.com)
Apache-Tomcat Connector (Jk Connector 1.2.21) (http://www.apache.org - tomcat - connector)

모두  linux 용, Non-RPM 버전으로 받아서 설치하였음.
받은 모든 파일들은 /usr/local/ 로 ftp 전송등으로 복사.

Mysql

SHELL> tar xzvf mysql파일명.확장자

SHELL> ln -s /usr/local/mysql디렉토리명  mysql
           
            mysql디렉토리에 대한 링크를 만듬. (윈도우의 바로가기 같은 개념--;)

SHELL> cd mysql

SHELL> adduser -M mysql

SHELL> chown -R root /usr/local/mysql

SHELL> chown -R mysql /usr/local/mysql/data

SHELL> ./configure

자동으로 실행까지 한다.

SHELL> cp /usr/local/mysql/support-files/my-medium.cnf   /etc/my.cnf

SHELL> ps  
            (mysqld_safe 가 있는지 확인.)

SHELL> cd bin  (/usr/local/mysql/bin)

SHELL> ./mysqladmin -u root password 'mysql root계정 비밀번호'

SHELL> ./mysql -u root -p
            (비밀번호를 입력하고 접속되는지 확인)

mysql> show databases;
            (information_schema , mysql , test DB가 있는지 확인 - 절대삭제하지 말것)

mysql> quit  (빠져나오기)
 
apache

SHELL> tar xzvf apache파일명.확장자

SHELL> cd 풀린apache디렉토리

SHELL> ./configure --prefix=/usr/local/apache --enable-so --enable-modules=all
                             --enable-mods-shared=most

SHELL> make && make install

SHELL> cd /usr/local/apache/

SHELL> vi conf/httpd.conf

            httpd.conf 설정내용중 ServerName 부분을 찾아서.
            주석처리되어있는 #를 삭제하여 활성화시키고, 도메인네임이나 IP Address를 적는다.
            예>ServerName www.도메인이름
                 ServerName 2xx.xx.xx.xx

            저장하고 vi편집기 빠져나오기.

SHELL> cd bin
SHELL>./apachectl start   아파치 실행.

웹브라우저를 실행시켜서 설정한 도메인네임이나 IP주소를 쳐서 접속을 한다.

"It works!!"

라는 메세지가 뜨면 아파치 설치 성공.

JDK

다운로드 받은 JDK파일은 .bin

SHELL> chmod o+x  jdk파일명
            (실행할 수 있게 권한을 준다)

SHELL> ./jdk파일명 (엔터)
          
            (아니면 sh jdk파일명)

Do you agree to the above license terms?

동의한다고 한다. (yes)

착하게 알아서 다 설치한다.

SHELL> ln -s /usr/local/jdk디렉토리명  jdk

Tomcat

SHELL> tar xzvf 톰켓파일이름

SHELL> ln -s /usr/local/tomcat디렉토리이름  tomcat

환경변수 설정

SHELL> vi /etc/profile

profile문서 제일 끝에 아래를 추가 한다.

JAVA_HOME=/usr/local/jdk
CATALINA_HOME=/usr/local/tomcat
APACHE_HOME=/usr/local/apache
export JAVA_HOME CATALINA_HOME APACHE_HOME

PATH=$JAVA_HOME/bin:$CATALINA_HOME/bin:$APACHE_HOME/bin:$PATH
export PATH=$PATH:/usr/local/bin:/usr/local/tomcat/bin
export CLASSPATH=$JAVA_HOME/lib/tools.jar:$CATALINA_HOME/lib/servlet-api.jar:$CATALINA_HOME/lib/jsp-api.jar

저장하고 나가기

SHELL> source /etc/profile

SHELL> catalina start
            웹브라우저에서 IPAddress 나 도메인 :8080 으로 접속한다.
            왠 고양이 한마리 나오면 톰켓 설치 완료.

Tomcat Connector

SHELL> cd connector디렉토리

SHELL> cd native

SHELL> ./buildconf.sh

SHELL> ./configure --with-apxs=/usr/local/apache/bin/apxs
SHELL> make && make install

SHELL> ls /usr/local/apache/modules
            (mod_jk.so 파일이 생성되었는지 확인)

SHELL> cd /usr/local/apache/conf

SHELL> vi workers.properties

            아래 내용 작성
           
            workers.tomcat_home=/usr/local/tomcat
            workers.java_home=/usr/java/jdk1.5.0_05
            ps=/
            worker.list=ajp13

            worker.default.port=8009
            worker.default.host=localhost
            worker.default.type=ajp13
            worker.default.lbfactor=1

            저장하고 나가기.

SHELL> vi httpd.conf

             LoadModule 부분을 찾는다.
             LoadModule jk_module modules/mod_jk.so 를 추가한다.
             
             DocumentRoot "usr/local/apache2/htdocs" 부분을 찾아서
             DocumentRoot "/usr/local/tomcat/webapps/ROOT"  로 바꾼다.
             
             DirectoryIndex 부분을 찾아서
             index.jsp 를 추가한다.

             아래 Mod_Jk Setting 부분
             문서 제일 밑에 추가

             # Mod_jk settings -----------------------------------------------------
             #
                JkWorkersFile conf/workers.properties
                JkLogFile logs/mod_jk.log
                JkLogLevel debug
                JkLogStampFormat "[%a %b %d %H:%M:%S %Y] "
                JkOptions +ForwardKeySize +ForwardURICompat -ForwardDirectories
                JkRequestLogFormat "%w %V %T"

                JkMount /examples/jsp/* ajp13
                JkMount /examples/servlets/* ajp13
                JkMount /*.jsp ajp13
                JkMount /servlet/* ajp13
             #---------------------------------------------------------------------

             저장하고 나가기.

SHELL> apachectl start
SHELL> catalina.sh start

웹브라우저에서 http://자기아이피 or http://도메인주소 로 접속

:8080을 붙이지 않고 고양이가 나와야하며
사이드메뉴에 JSP example 과 Servlet example 를 클릭하여
실행이 모두 되면 연동까지 성공!

이상있으면 댓글.
  1. 거룩한밤 2008.07.11 16:06 신고

    안녕하세요^^ 톰캣연동설치하는데 큰도움되었습니다.
    저도 sulinux1.5사용해서 설치했는데
    그대로 보고 끝까지 다 따라했습니다. 그런데
    서버아이피:8080치면 고양이 모습이 잘나오는데요,
    서버아이피만 치면
    '페이지를 볼수 있도록 승인되지 않았습니다.'
    라고 나옵니다. 디렉토리를 chown으로 변경시켜줘야 하는것이 있나요?

  2. 거룩한밤 2008.07.11 18:04 신고

    아! 해결했습니다. http.conf에 Documentroot 주소와 밑으로 내려가면 보이는 디렉토리태그의 주소와 똑같아야 하더군용^^ 다른분들 보시면서 어려움겪지 마시라고 올려놉니다.

  3. Favicon of http://blog.naver.com/imisehi BlogIcon 돌고래꿈 2009.01.22 19:04 신고

    Centos 5.2에서 아파치와 톰캣 연동하는데 많은 도움이 되었습니다.
    감사합니다 ㅎㅎ

+ Recent posts