태그 : kraken

2010/02/27   Kraken: Syslog File Logging #1
2010/02/26   크라켄 튜토리얼 예고
2010/01/31   크라켄 스레드 모니터링 [3]
2010/01/23   Kraken 1.3.0-SNAPSHOT

Kraken: Syslog File Logging #1

원격에서 전송한 Syslog를 받아서 단순하게 파일 하나에 로깅하는 경우를 구현하면서 크라켄 필터의 기능을 알아봅시다.

개발환경으로는 이클립스, m2eclipse 플러그인, maven을 준비해주세요. 이클립스 갈릴레오 버전부터는 기본적으로 m2eclipse 플러그인이 내장되어 있을테니 굳이 따로 설치할 필요는 없을 것입니다.

명령줄에서 아래와 같이 메이븐 프로젝트를 생성합니다.

mvn archetype:generate -DarchetypeGroupId=org.krakenapps -DarchetypeArtifactId=kraken-template -DarchetypeVersion=1.0.1 -DgroupId=org.krakenapps.tutorial -DartifactId=logmon -Dversion=1.0.0 -Dpackage=org.krakenapps.tutorial.logmon

이클립스로 logmon 프로젝트를 임포트 하고 나면, org.krakenapps.tutorial.logmon 패키지에 sources.txt 파일이 하나 들어있고 리소스는 metadata.xml 파일이 있는 것을 확인할 수 있습니다. sources.txt 파일은 잉여이므로 그냥 지우시면 됩니다. metadata.xml은 iPOJO 설정 파일인데 앞으로 계속 사용하게 됩니다.

제일 먼저 POM 파일을 설정해야 하는데, <name>YOUR_PROJECT_NAME</name>으로 된 부분을 마음에 드는 이름 (혹은 그냥 Log Monitor)로 고쳐주시고, <Bundle-SymbolicName>logmon</Bundle-SymbolicName>으로 된 부분은 그대로 놔둬도 딱히 문제되지는 않지만 일반적으로 사용되는 번들 작명 관례에 따라 org.krakenapps.tutorial.logmon 으로 수정하도록 합시다.

위의 Bundle-SymbolicName 외에도 Export-Package와 Private-Package, Import-Package 설정이 있는 것을 볼 수 있는데, 이 설정들은 패키징(mvn package)를 실행할 때 maven-bundle-plugin이 JAR 파일의 매니페스트(MANIFEST.MF)에 OSGi 번들과 관련된 메타데이터를 넣는데 사용됩니다.

OSGi에 대해서 약간 설명이 필요하겠지요. OSGi는 자바용 동적 모듈 시스템이라고 할 수 있습니다. 동적 모듈 시스템은 런타임에 모듈을 설치하거나 제거하는 기능을 지원합니다. 이 때문에 A라는 모듈이 의존하고 있던 B라는 모듈이 제거되는 경우 A 모듈은 동작이 불가능해질 수 있습니다. 제거되어 버린 B 모듈에 있었던 클래스를 사용하려고 한다면 ClassNotFoundException이 발생하게 될 겁니다. 의존 관계를 명확하게 하기 위해서 OSGi 명세는 JAR 매니페스트에 패키지 관련된 메타데이터를 전부 명시적으로 기록할 것을 요구합니다. 이 때문에 Export-Package, Private-Package, Import-Package 같은 설정이 존재합니다.

Export-Package나 Private-Package의 경우 하나의 모듈 안에 들어가는 패키지가 그렇게 많지 않으므로 직접 쓴다고 해도 별 부담은 안 될텐데, Import-Package의 경우에는 이 모듈이 사용하는 패키지를 모두 적어줘야 하니 소스를 일일이 뒤져서 쓰기도 그렇고 만만치 않은 일입니다. 이런 중노동을 하는 대신 maven-bundle-plugin 플러그인을 사용하면 어떤 패키지를 사용하는지 자동으로 분석해서 메타데이터를 기술해줍니다. 물론 리플렉션을 사용하는 경우 문자열 등으로 참조된 패키지는 직접 추가적으로 설정에 걸어줘야 합니다. 따라서 이번 예제의 경우 아래와 같이 됩니다.

<Bundle-SymbolicName>org.krakenapps.tutorial.logmon</Bundle-SymbolicName>
<Export-Package>org.krakenapps.tutorial.logmon</Export-Package>
<Private-Package>org.krakenapps.tutorial.logmon.impl</Private-Package>
<Import-Package>*</Import-Package>

이제 하단의 dependencies 설정을 보면 기본적으로 kraken-api가 걸려있는 것을 볼 수 있습니다. kraken-api는 크라켄 코어에서 제공하는 스크립트 확장 기능을 사용할 때 사용됩니다. Script와 ScriptFactory 인터페이스를 구현하면 텔넷에서 사용자 정의 스크립트를 바로 사용할 수 있습니다.

스크립트에 대해서는 나중에 알아보도록 하고, 지금은 필터 사용법만 논의할테니 <dependencies> 밑에 아래 설정을 추가하도록 합시다.

<dependency>
  <groupId>org.krakenapps</groupId>
  <artifactId>kraken-filter</artifactId>
  <version>1.1.0</version>
</dependency>

크라켄 필터(kraken-filter)는 OSGi의 특성을 이용하여 동적으로 필터를 로딩하고 바인딩할 수 있도록 하는 기능을 제공합니다. 앞으로 예제를 구현하면서 차차 알아가게 되겠지만, 관제시스템을 구현하다보면 로그가 흘러가는 메시지 경로를 반드시 구현하게 되어있습니다. 이 메시지 경로를 하드코딩할 필요 없이 동적으로 연결하거나 떼어낼 수 있도록 지원하는 것이 크라켄 필터입니다. 동일한 메시지 명세(MessageSpec)를 가지고 있는 경우에 필터 바인딩이 가능합니다.

이번 예제에서는 Syslog를 받아서 파일에 기록하는 기능을 구현해야 하는데, 이미 kraken-syslog 모듈에 SyslogReceiver 필터가 구현되어 있습니다. 따라서 메시지를 전달 받아서 파일에 쓰는 필터만 구현하게 되면 바로 연결해서 사용할 수 있습니다. 아래와 같이 일단 콘솔에 출력을 하도록 SyslogFileLogger 클래스를 구현해봅시다.

package org.krakenapps.tutorial.logmon;

import java.net.InetAddress;

import org.krakenapps.filter.DefaultFilter;
import org.krakenapps.filter.DefaultMessageSpec;
import org.krakenapps.filter.Message;
import org.krakenapps.filter.MessageSpec;

public class SyslogFileLogger extends DefaultFilter {

public MessageSpec[] getInputMessageSpecs() {
return new MessageSpec[] { new DefaultMessageSpec("kraken.syslog", 1, 0) };
}

public void process(Message message) {
InetAddress remoteIp = (InetAddress) message.get("remote_ip");
String msg = (String) message.get("message");
System.out.println(remoteIp + " => " + msg);
}
}

이제 크라켄 코어를 실행하고 텔넷으로 접속할 차례입니다. 크라켄 코어는 현재 1.3.2 버전이 최신 버전이고 구글 코드에서 다운로드 가능합니다. 아래 명령으로 실행하세요.

java -jar kraken-core-1.3.2-package.jar

putty를 사용해서 텔넷으로 localhost:7004 주소에 접속합니다. 크라켄 코어는 별도의 옵션을 주지 않는 경우 로컬 인터페이스를 통한 접속만 허용합니다. 접속하고 나면 코어에 내장된 기본 명령들을 실행할 수 있습니다. 크라켄 코어는 패키지 관리 기능을 지원하는데 아까 언급했던 syslog 패키지를 먼저 아래 명령으로 설치합시다.

pkg.install kraken-syslog

이 상태에서 bundle.list 명령을 내리면 ipojo, kraken-ipojo, kraken-syslog가 설치된 모습을 확인할 수 있습니다. 이제 우리가 개발한 모듈을 올릴 차례입니다. 다음 명령으로 로컬 파일시스템에 위치한 JAR 파일을 설치합니다.

bundle.install file:///c:/users/ACCOUNT/path/to/logmon/target/logmon-1.0.0.jar

성공적으로 설치가 되면 bundle.list 를 쳤을 때 org.krakenapps.tutorial.logmon을 목록 끝에서 찾아볼 수 있을 것입니다. bundle.start [번호] 명령으로 방금 설치한 logmon을 시작시킵니다.

이제 크라켄 콘솔에서 아래 명령을 실행하여 Syslog 수신기를 초기화합니다.

kraken> syslog.load
syslog receiver name: syslogd
bind address (default to localhost):
bind port (default to 514):
charset (default to utf-8):

syslogd라는 필터 인스턴스 이름과 기본값으로 Syslog 수신기를 초기화 했습니다. filter.status 명령을 치면 현재 생성된 필터 인스턴스 목록을 확인할 수 있습니다.  

이제 우리가 개발한 필터를 올릴 차례인데, filter.list 명령을 치면 필터 목록에서 우리가 만들었던 org.krakenapps.tutorial.logmon.SyslogFileLogger를 확인할 수 있습니다. 아래 명령으로 로딩합니다.

filter.load [번호] logger
혹은
filter.load org.krakenapps.tutorial.logmon.SyslogFileLogger logger

이름은 아무거나 상관없지만 이 예제에서는 logger라는 인스턴스 이름을 사용하겠습니다.

다음은 아래 명령으로 Syslog 수신기와 우리가 만든 필터를 바인딩합니다.

filter.bind syslogd logger

마지막으로 syslog.send 명령으로 syslog 메시지를 전송해서 크라켄 코어를 실행한 콘솔에서 로그가 찍히는지 확인합니다.

syslog.send localhost 514 hello

제대로 되었다면 콘솔에서 /127.0.0.1 => hello 라는 메시지를 확인할 수 있을 것입니다. 원한다면 syslog.load 할 때 bind address를 공인 IP로 설정해서 실제 외부에서 들어오는 로그가 콘솔에 찍히는지 확인해 볼 수도 있습니다. filter.unbind syslogd logger 명령을 치면 필터 연결이 끊어져서 더 이상 로그가 콘솔에 찍히지 않는 것도 살펴보시기 바랍니다.

기존에 동작하고 있는 필터 인스턴스를 삭제할 때는 filter.unload [인스턴스 이름] 명령을 사용하면 되고, 소스를 수정하고 새로 패키징한 경우에는 bundle.update [번들 번호] 명령으로 업데이트 할 수 있습니다. 그 외에 syslog 패키지의 세부 내용은 위키의 KrakenSyslog 항목을 참조하시기 바랍니다. 크라켄 텔넷 콘솔에서 바로 syslog를 트레이스 할 수 있습니다.

크라켄 필터로 개발된 경우 나중에 임의로 필터를 연결하거나 해제함으로써 기존 코드를 수정하지 않고도 런타임에 메시지 경로를 쉽게 확장할 수 있다는 점을 기억하시기 바랍니다.

다음 시간에는 필터 속성을 설정하는 방법과 필터 속성으로 지정된 파일 경로에 로그를 쓰는 방법을 설명하고 마무리합니다.
by xeraph | 2010/02/27 01:18 | NCHOVY | 트랙백 | 덧글(0)

크라켄 튜토리얼 예고

관제 시스템 개발 예제
  • 원격에서 수신한 로그를 파일에 기록하기
  • 원격에서 수신한 로그를 데이터베이스에 기록하기
  • 원격에서 수신한 로그의 릴레이
  • 로그 필터링의 실시간 제어
  • Aho-Corasick을 이용한 고속 로그 필터링
  • 실시간 로그 통계 구현 (공격자, 공격대상, 패턴명)
  • 데이터베이스를 이용한 기간별 로그 통계
  • AJAX 기반 실시간 로그 관제 구현
  • 퓨전차트를 이용한 Top N 통계 출력
  • RRD를 이용한 로그 발생 추이 구현
  • XML-RPC 로그 검색 및 통계 조회 API 구현
PCAP 활용 예제
  • ARP를 이용한 IP 관리
  • HTTP 디코더와 Trie를 사용한 유해사이트 접속 탐지
  • FTP 스니핑으로 계정과 패스워드 자동 수집
  • MSN 대화내용 기록 및 키워드 패턴 매칭
  • SMTP/POP3 디코더를 이용한 메일 본문의 도메인 수집 및 Fast Flux 모니터 구현
by xeraph | 2010/02/26 02:01 | NCHOVY | 트랙백 | 덧글(0)

크라켄 스레드 모니터링

디버거 붙여야 스레드 리스팅 볼 수 있는 것도 귀찮고 잘못 만들어진 프로그램들이 스레드 하나 잡고 가사 상태에 빠지는 경우들도 있고 그래서 전체 스레드 제어가 가능하게 기능 추가하고 있다. 그냥 다 찍었더니 출력이 흉악하네..

kraken> thread.stacks
Name: Signal Dispatcher, Status: RUNNABLE
Name: FelixStartLevel, Status: WAITING
        java.lang.Object.wait (Object.java:-2)
        java.lang.Object.wait (Object.java:485)
        org.apache.felix.framework.StartLevelImpl.run (StartLevelImpl.java:242)
        java.lang.Thread.run (null:-1)
Name: Reference Handler, Status: WAITING
        java.lang.Object.wait (Object.java:-2)
        java.lang.Object.wait (Object.java:485)
        java.lang.ref.Reference$ReferenceHandler.run (null:-1)
Name: FelixPackageAdmin, Status: WAITING
        java.lang.Object.wait (Object.java:-2)
        java.lang.Object.wait (Object.java:485)
        org.apache.felix.framework.PackageAdminImpl.run (PackageAdminImpl.java:314)
        java.lang.Thread.run (null:-1)
Name: Timer-0, Status: TIMED_WAITING
        java.lang.Object.wait (Object.java:-2)
        java.util.TimerThread.mainLoop (null:-1)
        java.util.TimerThread.run (null:-1)
Name: FelixDispatchQueue, Status: WAITING
        java.lang.Object.wait (Object.java:-2)
        java.lang.Object.wait (Object.java:485)
        org.apache.felix.framework.util.EventDispatcher.run (EventDispatcher.java:931)
        org.apache.felix.framework.util.EventDispatcher.access$000 (EventDispatcher.java:54)
        org.apache.felix.framework.util.EventDispatcher$1.run (EventDispatcher.java:106)
        java.lang.Thread.run (null:-1)
Name: Finalizer, Status: WAITING
        java.lang.Object.wait (Object.java:-2)
        java.lang.ref.ReferenceQueue.remove (null:-1)
        java.lang.ref.ReferenceQueue.remove (null:-1)
        java.lang.ref.Finalizer$FinalizerThread.run (null:-1)

(...생략)
by xeraph | 2010/01/31 17:02 | NCHOVY | 트랙백 | 덧글(3)

Kraken 1.3.0-SNAPSHOT

킹황짱이 잉여력을 발휘하여 크라켄 쉘에서 home, end 키 먹고 커서 이동하면서 편집할 수 있게 구현함 (..) scriptContext.readLine()에서만 커서 이동 편집이 되고 쉘에서는 안 되어서 그동안 애로사항이 꽃피다 못해 아주 적응해서 살았었지...-_-;; (만세)

http://krakenapps.org/changeset/533/kraken-core

그 외에 kraken-jpa는 1.2.0으로 정리하면서 너덜너덜한 로깅은 다 trace 레벨로 돌리고 번들 재시작해도 설정 안 없어지게 수정해서 많이 편해졌고.. rrd는 버그 잡고 있고.. pcap은 디코더들을 별도의 번들로 쪼개야 되겠다.. (udp 패킷 처리 과정까지 다 끝남)
by xeraph | 2010/01/23 16:00 | 잡담 | 트랙백 | 덧글(0)
<< 이전 페이지 다음 페이지 >>