오늘은 제가 만든 "핫소스"라는 Tool을 소개 해드리고자 합니다.


저는 업무상 은행/공공기관등의 프로젝트 지원을 많이 다니곤 하는데요.




최근 들어 SVN을 사용하는 프로젝트를 많이 보게 됩니다.


그리고, SVN에 commit하면 WAS(tomcat, jeus, ... ) 에 배포가 되었으면 좋겠다 라고..


java의 경우는 컴파일도 되어야 하구요.


그렇게 시스템을 구성해달라는 요청을 받기도 합니다.




그래서 항상..Shell로 조잡하게 구성해서 제공해주곤 했는데....


제가 봐도 정리도 안되고....해서...


이번에 JAVA버젼으로 최대한 단순하게 만들어 보았습니다.




이름은 "핫소스" 라고 정했구요..ㅎㅎ...맵지는 않답니다..(먹어보지는 못했지만요...;;; )


다운로드는 ==> http://goo.gl/LvYsS3


사용법은..


hooks폴더에 위에 첨부한 jar파일을 복사해서 넣습니다.


그리고..


아래와 같이 pre-commit파일을 작성하면 끝!!


#!/bin/sh


REPOS="$1"

TXN="$2"


MAPPING="TEST_WAS=/tmp/test/washome"             # TEST_WAS프로젝트를 /tmp/test/washome 로 배포.

MAPPING="${MAPPING};TEST_WEB=/tmp/test/html" # TEST_WEB프로젝트를 /tmp/test/html 로 배포.


/home/nim/jdk1.7.0_25/bin/java -Dfile.encoding=UTF-8 -jar ${REPOS}/hooks/hotsrc.0.1.fat.jar  ${REPOS} ${TXN} ${MAPPING} <svn-id> <svn-passwd>


위에서 java의 경로는 JDK(javac가 포함)의 java를 지정해주시길 바랍니다.


* 위 프로그램의 저작권은 제가 속해있는 회사인 "주식회사 널리소프트" 에 있습니다.

* 위 프로그램은 svnkit을 사용하였으나 편의를 위하여 하나의 jar로 묶었습니다.

* svnkit과 svnkit에서 사용되는 라이브러리의 저작권은 각 소프트웨어에 있습니다.



아래는 SVN 생성부터 테스트 까지를 묶어보았습니다.^^



















최근 금융 IT에서는 "중복 로그인 방지" 라는 이야기가 나오고 있습니다.


금융결재원 권고 사항.으로 나왔거든요.


모...대부분의 은행은 각자의 알고리즘과 각자의 솔루션으로 적용 했겠지만.


저는 간단하게 중복로그인 방지를 어찌 해결 할수 있을까를 고민 해보고.


몇가지 "꼼수" (정석이 아니라는 말이죠.ㅎㅎ....모..IT개발엔 정석이 없겠지만요.ㅎㅎ)를


생각해 보았습니다.





고객의 요건들...(몇몇 은행 기준)


중복로그인방지를 위하여, 새로운 사용자가...현재 로그인 되어 있는 채널과 다른 채널을 통한


로그인 시도시...기존 로그인 되어 있는 채널의 사용자를 로그아웃 시켜주어야 한다.


(중복로그인되어 로그아웃 시킨다는 메시지가 있다면 좋겠죠.^^)


[ 채널 : IT거래 경로..보통 PC/Smart Phone/Tablet 등등을 각각 다른 채널이라고 부르더라구요..]







위 요건을 해결 하기 위해...어찌해야 할까요..


모든 채널이 하나의 DB에 접근이 가능하다면 ...이런 방법이 가능합니다.


(여기서 DB가 등장하면 어떨까?  D!B! .... 죄송.)





로그인 할때...현재 로그인한...PC의 ip와 Session(세션id), 사용자 id 정보 기타등등을 DB에 넣습니다.


(모든 채널이 하나의 DB를 보고 있다는 가정입니다.)




그리고 Servlet Filter를 하나 말들고...꼭 servlet filter가 아니라 공통 include에서 해결해도 되긴합니다...


거래 할때마다...DB를 조회합니다.


난 이미 로그인하고 거래중인데 ip나 정보가 나의 정보와 다르다면!!!


로그아웃 해버립니다.



...................................



너무 간단히 해결 되었네요.-_-;





하지만 문제가 있습니다.


우리의 고객분들께서는......거래가 일어날때마다 DB를 조회하는것을 원하지 않으십니다.-_-;


인덱싱까지 걸려 있는 DB Table에 매번 거래 로그남기는건 좋아하지만...이런 상황은 좋아하지 않으십니다.


어찌합니까~? 어떻게 할까요~~?




음...동일한 DB를 쓴다는 가정하에 고민하면...아직까지는 쉽게 해결 할수 있습니다.


로그인이 이루어질때마다. Session객체를 static형태 Hash Map에 담아두는 것입니다...


모 Thread에 안전한 ConcurrentHashMap 정도면 더 좋겠네요..



public static ConcurrentHashMap map = new ConcurrentHashMap();


이런놈을 두고.



map.put(sessionID, Session) 객체를 한군데 모아 둡시다.. (WAS별로 관리해야겠죠..)


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


그리고 "SessionKiller.jsp" 정도의 Servlet이나 jsp파일 한개 둡시다!!


인자로 SessionId정도 받아서.


SessionID에 해당하는 Session을 꺼내서 invalidate 시켜주면 됩니다....



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



여기서 치명적인 문제.-_-


map에다가 담기만 하고....자동 종료되는 session등등...은 꺼내지지 않고.


결국 메모리를 계속 잡아 먹는 괴물이 될것 입니다..



하아.-_-;




하지만  우리에겐.


SessionListener가 있습니다..


아래와 같은 소스를 만들면 됩니다.-_-


제가 짰냐구요?


귀찮아서..stackoverflow에서 훔쳐 왔습니다.


출처는 http://www.coderanch.com/t/365859/Servlets/java/session-object-session-ID


위와 같습니다.




    public class SessionListener implements HttpSessionListener{

   

       public void init(ServletConfig config){

       }

   

     /**

      * Adds sessions to the context scoped HashMap when they begin.

      */

     public void sessionCreated(HttpSessionEvent event){

         HttpSession    session     = event.getSession();

         ServletContext context     = session.getServletContext();

         Map            activeUsers = (Map)context.getAttribute("activeUsers");


         activeUsers.put(session.getId(), session);

     }


     /**

      * Removes sessions from the context scoped HashMap when they expire

      * or are invalidated.

      */

     public void sessionDestroyed(HttpSessionEvent event){

         HttpSession    session     = event.getSession();

         ServletContext context     = session.getServletContext();

         Map            activeUsers = (Map)context.getAttribute("activeUsers");


         activeUsers.remove(session.getId());

     }

 }





자..그럼...로그인 할때마다..기존 로그인 정보를 db에서 읽어와서


해당 하는 서버에 servlet으로 쏴주면 되겠네요?


해결 되었네요!!


하지만.....



우리에게....더 큰 위협이 다가 옵니다..


각각 System마다 다른 DB를 사용한다!!!


하아...-_-;


이쯤 글을 쓰다보면 도망가고 싶어집니다.-_-;;


힘듭니다...머리는 안돌아가고....


그런 분위기입니다..





일단 포스팅 여기까지만 하고..


To be Continue....라고 쓰고.


다음에 이어서 포스팅 하겠습니다.ㅎㅎㅎ






















지금 까지 나온 단서는.


1) LG U+ 망을 사용하는 곳들이 문제 였다는 점.


2) 인터넷에 떠도는 사진을 보면 부팅이 안되는 사진이 있다는 점..


추가적으로 "Whois"라는 해커팀이라는 정보도 있네요.




어떤 방법일까요?


무시무시한 북한의 소행일까요?





저도 금융권에서 프로그래머로 일하면서...위 뉴스를 듣고.


고객사(대부분 은행)에 나가 있는 회사 사람들에게 안부전화를 해보았습니다.



다행히....큰문제는 없다고 하네요.





무엇이 문제였을까요?


기존 사례를 찾아서 보면...==========================>


Daum 해킹 사건이 떠오르네요.




근데 어떻게 일부 회사가 아닌 LG U+망을 사용하는 업체들이 당한걸까요?


그냥 예측을 해보면..Daum해킹과 유사하게...Update서버 변경을 통한..


바이러스 유포   라고 생각이 듭니다.


LG U+ 사용자만 문제가 있었다는데서 보면...


LG U+ 의 라우팅 테이블을 조작 했거나 (이건 아닐거라고 봅니다.)


LG U+에서 제공하는 DNS서버 를 조작 했다면... (DNS변조 공격...)


이런 사태가 일어 날수 있다고 봅니다.



위 DNS서버를 가지고 본다면... 많은 사람이 사용하는 "알약" (다음 해킹 사례에서 보듯이..) 의 업데이트 서버에 대한 URL에 대한 IP매핑을 변경 하는 것입니다.




[여기서 알약이 문제였다는 말은 아닙니다.. 윈도우 업데이트나 어떤 프로그램의 업데이트인지는 잘 모르겠습니다.]



그렇게 된다면 알약 업데이트를 위해서 




Update URL(업데이트 요청)---> (DNS서버) 변경된 IP ---> Download및 Update(바이러스)



이순간 알약은 바이러스가 되버립니다.-_-;





보안생각하면 자동 업데이트 (Update Server) 구성에 대해서도 고민을 해야 할것 같습니다...




근데...문제는 왜 서버가 문제가 생겼을까요?...


윈도우 서버를 썼을까요?..


아니면 해킹된 PC를 통해서 Unix / Linux서버 해킹?



모;; 위 두가지다 가능성은 있습니다. 




세상 참 무섭습니다.ㅠ_ㅜ





ps) 위 내용은 저의 추측일뿐..사실이 아니므로 잘 필터링 해주시기 바랍니다..

틈틈히 Servlet 레퍼런스를 정리해볼까 합니다.


모 기본 스펙을 100% 번역하는것이 아니라.


그냥 필요한 사항을 정리하는 수준으로 하고..


아직 많이 쓰는 버전을 기본으로 2.5...정리하고.


차후에 3.0 스펙도 같이 정리 해볼까 합니다.




물론 게흘러서 잘 할지는 모르겠지만..


이렇게 공약이라도 해놔야.-_-;


정리를 하게 되겠지요.ㅎㅎ;;




아 윌비백~

얼마전 회사에서 WEB-APP으로 만든 프로그램이 IOS6에서 문제가 발생한다고 연락이 왔습니다.


그래서 테스트를 해보았더니..


동일한 AJAX를 두번 날리면, 먼저 날린 거래를 cache리하는 문제가 발생하는 것입니다.


....귀찮은 문제네요.ㄱ-;


하지만 어쩔수 없이 해결하기 위해 여러가지 테스트를 해보았습니다.


그중에 가장 확실한 방법은 header값을 담아서 날리면 되는것 같더군요.^^


다행히 AJAX util을 추상화 해놓아서.


공통 js파일 하나만 수정해서 해결이 되었습니다.



jQuery를 사용하신다면 아래 Header부분을 추가해주시면 정상적으로 거래가 이루어집니다.


물론 cache옵션은 false로 주는게 좋겠죠?.^^


jQuery.ajax( { type : "POST",

url : "url....",

data : {/*요청값*/},

cache : false,

async : false,

headers: { "cache-control": "no-cache","pragma": "no-cache" },

error : function(xhr, textStatus, errorThrown) {

// 에러시 처리

                                        },

success : function(msg) {


// 처리 로직..


 }

); 



아마 Safari ( 사파리 )에서도 동일한 증상이 있을것으로 예상됩니다.^^ 

+ Recent posts