ETC...

JEUS DB접속정보가 암호화된 DS, 외부에서 LOOKUP시 에러

FreeEnd 2010. 11. 11. 10:01
반응형

 

어느날  SSO 서버의 JEUS에 JEUSMain.xml의 DB 접속 정보 중 패스워드 암호화 이후 외부에서 WAS로 접근해 DS를 LOOKUP하는 클라이언트들이 getConnection 하는 도중 에러 발생. 


[2010.11.11 08:52:21][0][] [client-10] [JDBC-0055] Failed to create the driver DataSource instance

<<__Exception__>>

java.lang.NullPointerException

at java.io.File.<init>(File.java:194)

at jeus.security.util.EncryptionUtil.readSecretKey(EncryptionUtil.java:634)

at jeus.security.util.EncryptionUtil.decode(EncryptionUtil.java:355)

at jeus.security.util.EncryptionUtil.decryptPassword(EncryptionUtil.java:474)

at jeus.security.util.EncryptionUtil.decryptPassword(EncryptionUtil.java:551)

at jeus.jdbc.datasource.DataSourceGenerator.getDataSource(DataSourceGenerator.java:46)

at jeus.jdbc.connectionpool.ConnectionPool.getDataSource(ConnectionPool.java:318)

at jeus.jdbc.connectionpool.ConnectionPool.getPooledConnection(ConnectionPool.java:440)

at jeus.jdbc.connectionpool.ConnectionStore.createPooledConnection(ConnectionStore.java:343)

at jeus.jdbc.connectionpool.ConnectionStore.initStore(ConnectionStore.java:85)

at jeus.jdbc.connectionpool.ConnectionPool.initPool(ConnectionPool.java:394)

at jeus.jdbc.connectionpool.ConnectionPool.initialize(ConnectionPool.java:274)

… 중략…

 
 암호화 키를 찾는듯. ㅅㅂ 왜?

자 다시 이야기 하자면 Stand-alone client Application 이 WAS의 DataSource(이하 DS)를 이용해 DB에 접속하고자 WAS의 DS를 LOOKUP 할 때 WAS (JEUS)의 Database(이하 DB) 접속 정보 중 패스워드가 JEUS의 암호화 기능으로 Encyption되어 기록 되어 있을 때 LOOKUP 시 Decyption에러가 나는 문제이다.

문제는 간단했다. JEUS의 JNDI 외부 LOOKUP시 일어나는 보안성 취약점을 개선하기 위하여 JEUS 5.0의 업데이트 버전 별로 수정사항이 발생 하였기 때문이었다. 우선 업데이트 버전벌로 수정사항을 알아보자. 다음은 Tmax JEUS연구소에서 직접 보내온 FIX별 수정 사항이다. 


[~ fix23]
bind할 때, password를 decrypt합니다. 이 때 secret.key file이 필요하며 JEUS에서 그 위치를 알고 있으므로(manager 및 container에서 static하게 secret.key file의 위치를 초기화하여 가지고 있음) decryption이 가능합니다. stand-alone client는 lookup할 때, 이미 decrypt되어 있는 password를 가지고 connection pool 구성 작업을 하게 되므로 문제가 없습니다. 즉, stand-alone client가 굳이 secret.key file에 대하여 알지 못해도 상관이 없습니다.

 

[fix24, fix25]
lookup할 때 password를 decrypt합니다. 즉, bind할 때는 encrypt된 password가 그대로 올라갑니다. JEUS에 deploy된 application 같은 경우는 JEUS가 secret.key file을 알고 있으므로 lookup할 때 decryption에 문제가 없습니다. 그러나 stand-alone client는 lookup할 때 secret.key file의 위치를 알지 못하므로 decrypt를 할 수 없습니다. 이 버전에서는, password를 encrypt할 경우 stand-alone client에서 connection pool을 구성할 수 없는 단점이 있습니다.

 

[fix26~]
fix24, fix25의 단점을 보완하기 위해 -Djeus.security.keypath 옵션이 추가되었습니다. 이 옵션을 사용하여 secret.key file path를 설정하고 stand-alone client를 실행하면 stand-alone client가 lookup시 decrypt를 할 수 있게 됩니다.
ex) java -Djeus.security.keypath=/user/yahho02/webapps ...



 결국은 현재 우리 회사의 fix는 25로 외부의 Stand-Alone한 client가 외부에서 Lookup하였을 때 DB접속정보가 암호화 되어 넘어오므로 Decryption할 때 에러가 발생 하였던 것이다. 젠장. 이렇게 세세한 부분까지 어떻게 개발자가 인지하고 있냐는 말이다. 때문에 서비스에 30분 동안 장애가 발생하여 혼자 똥줄 엄청 탔다.ㅠㅠ

 위의 FIX별 수정사항에 나와있다시피 상기 문제를 해결하기 위해서는 -Djeus.security.keypath 옵션을 이용해 KEY설정해 주어야 한다. 해당 Tmax연구소에서는 외부에서 LOOKUP하는 방법과 독자적으로 JDBC를 구성하는 두가지 방법에 대하여 권고사항은 없으며 DB 커넥션 관리, 접근 정보와 횟수 등 개별적 어플리케이션의 특성에 따라 운영하라고 권고하고 있다. 

 자. 이제 왜 이렇게 Tmax JEUS 개발 연구소에서 업데이트할 때 2번이나 수정하면서 원격 JNDI LOOKUP에 대하여 고려했는지, 개인적인 생각으로 아래 그림 한번 처다보고 한번 생각해보자. 



그림 21. JEUS의Connection Pooling
(http://technet.tmax.co.kr/kr/edocs/jeus/50/index.htm : Tmax 테크넷 JEUS 5.0 매뉴얼 )

 상단 그림에서 보면 가운데 초록색 네모가 WAS 고 좌측 Client Application이 Stand-alone Client (독립적으로 실행되는 어플리케이션) 이다. 그리고 우측 빨간 그림이 Database이다. 설명 없이도 직관적으로 이해가 가능한 그림이다. 참 쉽죠잉~

우선 간단히 WAS와 웹 어플리케이션의 DBCP관리에 대해서 알아보자

 일반적으로 WAS는 DB접속 정보를 가지고 DB커넥션을 직접관리하며 웹 어플리케이션은 WAS에서 생성된 DBCP를 LOOKUP해 사용하는 간접적인 DB관리를 하고 있다. 이로 인해 WAS에 올라와 있는 모든 어플리케이션에서 굳이 각자 DBC를 관리 할 필요가 없고 또 DBCP도 각자 관리할 필요가 없어 자원 관리 면에서 효율적이다. (JNDI 를 참고하기 바란다.)

 하지만 보안성에 대해 문제가 있다. 일반적으로 DB에는 회사의 매출정보, 직원 인적 정보, 고객의 신상정보 등의 Private한 정보가 기록되어 있어 DB의 접근에 대한 제한이 필요하다. 하지만 WAS의 경우 설정파일에 이 DB정보를 직접 기록해서 관리 해야 하기 때문에 해당 서버에 접근 권한이 있는 사람, 접근 권한이 없더라도 해킹 등에 의해 DB의 접속 정보가 노출 될 수 있다. 어플리케이션에서 직접 DB접속정보를 관리하면 뭐 암호화를 하던 String을 쪼개던 해서 소스에 하드 코딩으로 박아버릴 수 있지만 WAS는 직접 설정 파일에 기록해야 한단 말이다. 그래서 JEUS에서는 JEUSMain.xml에 기록된 DB접속 정보를 암호화 하는 기능을 제공한다. JEUS의 설정 파일에 패스워드를 Encryption 하여 기록하면 자동으로 Decryption 하여 DB에 접근하게 된다. 웹 어플리케이션에서는 WAS에서 암호화된 패스워드를 Decryption 하여 DBCP를 관리하기 때문에 암호화를 하던 하지 않던 신경 쓰지 않고 DS를 이용 할 수 있다.

WAS에서는 DB접근에 관해 또 한가지의 기능을 제공한다. 외부의 Stand-alone한 Client들(외부에서 독립적으로 실행되는 어플리케이션)에 대해 자신의 DB접근 정보를 이용해 DB에 접근 할 수 있는 기능, 즉 외부 어플리케이션에 대해서도 해당 WAS의 DS정보를 LOOKUP해서 사용할 수 있게 제공하는 기능이 있다. 이러한 기능 때문에 굳이 WAS 어플리케이션 내에 서비스를 등록하지 않고 배치, 혹은 다른 Stand-alone(독립적인) 한 어플리케이션을 따로 개발해 독자적으로 운영하면서도 WAS의 DS를 이용하여 관리에 대한 효율성을 높일 수 있다는 것이다.

 아주 좋은 기능이다. WEB Application 뿐만 아니라 Stand-alone Client 까지도 DS정보에 구애 받지 않고 WAS의 DS를 LOOKUP하는 것으로 하나의 자원을 공유해 쓰기 때문에 효율적인 자원관리를 이룰 수 있기 때문이다. 참 좋다. 과연. 좋을까.

 위에서도 말했다시피 DB에는 Private한 정보들이 많이 있어 외부의 접근을 차단, 혹은 제한 해야 하는 이슈가 있다. 때문에 접속 정보도 대외비로 관리하고 해당 WAS의 패스워드 또한 Encryption하여 관리 하고 있는 것이다. 하지만 외부에서 LOOKUP할 때 , WAS에 접근이 가능해지면 어떠한 Stand-alone한 어플리케이션이던지 전부 DS정보를 LOOKUP하여 사용 할 수 있다는 보안성 취약점이 발생 한다. 물론 WAS의 DS정보를 얻기 위해선 WAS의 접근 하기 위한 계정이 필요하다. 하지만 대부분의 시스템 관리자들은 이러한 정보를 변경 하지도 않고 많은 신경을 쓰지 않는다. 때문에 JEUS의 각 업데이트 마다 서두에 말한 수정 사항이 발생 하였던 것이다.

 이쯤 되면 궁금 한 점이 하나 발생한다. 무엇 때문에 외부에서 LOOKUP하는데 DB에 접근하기 위한 접속정보가 필요할까. 단지 DS Object만 가져오면 되는데. 해답은 간단하다. JEUS에서 DS정보를 LOOKUP할 때 DS Object를 직접 가져오는 것이 아니라 DB접속 정보를 가져와 LOOKUP을 요청한 Stand-Alone Client의 JVM상에서 JDBC Pool을 새로 생성해 직접 DB에 접근하기 때문에 DB접속정보가 필요하였던 것이다. 나는 여태 WAS에서 Connection Pool을 직접 다 관리하는 줄 알았다. 때문에 이번에 발생한 외부 어플리케이션의 장애를 파악하는데 시간이 지체되어 간만에 쌍욕을…. 안타깝다. 

 자. 여튼 이러한 문제가 있고 이러한 문제를 이렇게 해석해 이러한 문제 개선 방향이 나와서 이러한 문제가 발생 하였다. ㅋ 다들 한번씩 읽어보고 나 같은 삽질 하지 않기 바란다. 지영옹.
반응형