Packet sniffing using tcpdump

tcpdump를 이용한 패킷 훔쳐보기

It is easy to monitor packets being exchanged by network applications in your desktop machine, because we have a great software called ‘Ethereal‘. But what if we are working on a remote console without any GUI? We have to use tcpdump. The following is typical tcpdump options I use to monitor the data being exchanged:

데스크탑 머신에서 네트워크 애플리케이션이 교환하는 패킷을 모니터링하는 것은 쉽습니다. Ethereal이라는 소프트웨어가 있기 때문이죠. 하지만 GUI가 없는 원격 콘솔에서 작업할 때는 어떻게 해야 할까요? tcpdump를 사용해야 합니다. 다음은 제가 교환되는 데이터를 모니터링하는 데 쓰는 전형적인 tcpdump 옵션들입니다:

tcpdump -N -f -s 0 -X -vvv -i eth0 
host 210.103.210.233 and tcp and port 9132 and
'tcp[13] & 8 == 8'

-N and -f option works around performance and stability issues on some systems. -s 0 option prevents tcpdump from printing captured packets as truncated. -X option is used to print captures packets as hexadecimal dump format. 'tcp[13] & 8 == 8' expression filters out all packets except DATA packets because what we have interest in are only DATA packets.

-N-f 옵션은 어떤 시스템에서 발생하는 성능이나 안정성 문제를 해결합니다. -s 0 옵션은 tcpdump가 캡처한 패킷의 뒷부분을 잘라버리고 출력하지 못하도록 합니다. -X 옵션은 캡처한 패킷을 16진 덤프 형식으로 출력하도록 하는데 쓰입니다. 'tcp[13] & 8 == 8' 표현은 DATA 패킷을 제외한 모든 패킷을 필터링합니다. 우리가 관심있는 것은 DATA 패킷뿐이니까요.

Tabbed Editing with GViM and Nautilus File Manager

The default text editor of GNOME desktop environment is ‘gedit‘. I prefer ViM because it has much better functionality and customizability, and moreover, it launches faster. One thing I’ve been missing from GViM, a GUI version of ViM, was tabbed editing. GViM already supports tabbed editing, but opening a text file from Nautilus File Manager always creates a new window by default.

GNOME 데스크탑 환경의 기본 텍스트 편집기는 gedit입니다. 저는 기능도 훨씬 많고 커스터마이즈도 용이한데다가 실행 속도도 더 빠른 ViM을 선호합니다. ViM의 GViM에서 한 가지 아쉬웠던 기능은 탭 편집 기능(탭 브라우징처럼 탭으로 여러 문서를 편집하는 기능)입니다. GViM은 이미 탭 편집 기능을 제공하지만 Nautilus 파일 관리자에서 텍스트 파일을 열면 기본적으로 새 창을 열게 되어 있습니다.

Fortunately, I finally found out how to change this behavior. Nautilus stores its file association information in ~/.local/share/applications directory. You can put customized .desktop files there, and then you can associate certain file type to the customized .desktop file. In my case, I want text files to be opened in a new tab of the current GViM window. I put gvim-usercustom.desktop file to ~/.local/share/applications directory:

운좋게도 이 동작을 바꾸는 방법을 결국 알아냈습니다. Nautilus는 파일 연결 정보를 ~/.local/share/applications 디렉토리에 저장합니다. 이 디렉토리에 커스터마이즈한 .desktop 파일을 넣고 특정 파일 유형을 그 .desktop 파일에 연결할 수 있습니다. 제 경우에는 현재 떠 있는 GViM 창의 새 탭에 텍스트 파일이 열리기를 원하는 것이죠. 그래서 gvim-usercustom.desktop 파일을 ~/.local/share/applications 디렉토리에 넣어 주었습니다:

[Desktop Entry]
Encoding=UTF-8
Name=GVim Text Editor (Tab)
Comment=Edit text files in a new tab
Exec=gvim --remote-tab %F
Terminal=false
Type=Application
Icon=/usr/share/pixmaps/vim.svg
Categories=Application;Utility;TextEditor;
StartupNotify=true
MimeType=text/plain;
NoDisplay=true

If you prefer other text editor and want to change its default bahavior, you could copy its .desktop file from /usr/share/applications/ and rename it to <appname>-usercustom.desktop and tweak it a little bit. Refering to this document will also help you if the application you want to associate with a certain file type isn’t listed in a default setting.

다른 편집기를 더 선호하고 그 편집기의 기본 동작을 바꾸고 싶다면 /usr/share/applications/ 디렉토리에서 그 편집기의 .desktop 파일을 복사해 <appname>-usercustom.desktop으로 이름을 바꾸고 손을 좀 보면 될 겁니다. 특정 파일 유형에 연결하고자 하는 어플리케이션이 기본 설정에 포함되어 있지 않다면 이 문서를 참조하면 도움이 될 것입니다.

Installing Subversion 1.4 in Ubuntu Edgy Eft (6.10)

Ubuntu Edgy Eft (6.10)에서 Subversion 1.4 사용하기

I’ve been using Subversive for a while because one of my colleagues told me it’s better than Subclipse, but I didn’t see any advantage from it, uninstalled it, and installed the latest version of Subclipse.

Subversive가 좋다는 이야기가 있어 사용하다가 그다지 좋은 점을 느끼지도 못했고 UI가 불필요하게 복잡하다는 생각이 들어 설치 제거한 뒤 Subclipse 최신 버전을 설치했습니다.

Duh! I didn’t know JavaHL shared object (DLL) is not provided for Linux. I had to configure Subclipse to use SVNKit instead of JavaHL, and I got another problem! The latest version of Subclipse was using the latest version of SVNKit which is using Subversion 1.4 working copy format and therefore not compatible with Subversion 1.3. Ubuntu Edgy Eft provides only Subversion 1.3, so my working copies didn’t work anymore with the command line Subversion client because SVNKit has upgraded the version of all my working copies to 1.4. svn up fails gracefully saying that I have to upgrade to 1.4.

그런데 Subclipse를 최근에는 윈도우즈에서만 사용해 왔던지라 리눅스에서는 JavaHL 공유 라이브러리가 있어야 제대로 동작한다는 사실을 까맣게 잊고 있었지 뭡니까. 어쩔 수 없이 JavaSVN을 사용하도록 옵션을 설정했는데, 여기서 문제가 발생했습니다. 최신 버전의 Subclipse가 최신 버전의 JavaSVN을 사용하고 있어서 Ubuntu Edgy Eft에서 제공하는 Subversion 1.3과 호환되지 않는 Subversion 1.4용 working copy로 제 로컬 카피를 변환해 버린 것이죠. 덕택에 명령행에서 svn up하니 제대로 되지를 않네요.

I could just check my stuff out again and revert back to Subversive, but I chose to install Subversion 1.4 because people are saying there are several performance improvements. The following is the installation procedure I stepped on.

저장소에서 다시 체크아웃하고 Subversive로 복구하면 되는 문제였지만 Subversion 1.4에서 많은 성능 향상이 있었다고 하여 Subversion 1.4를 설치하기로 했습니다. 다음은 설치 과정입니다.

$ sudo apt-get install gcc g++ libc6-dev libapr0-dev libneon25-dev
$ tar jxvf subversion-1.4.x.tar.bz
$ cd subversion-1.4.x
$ ./configure --enable-dso --enable-javahl --with-ssl
--with-jdk=/usr/lib/j2sdk1.5-sun --without-jikes
$ make
$ make javahl
$ sudo make install
$ sudo make install-javahl

Everything has been installed, so I tried to switch to JavaHL, but there was another problem; JVM bombs out because of a bug of libapr0. We can fix this problem by building apache2 manually.

모두 제대로 설치가 되어 Subclipse가 JavaHL을 사용하도록 하려고 하니, libapr0의 버그로 인해 JVM이 죽어버리는 문제가 있네요. 이 문제는 apache2를 다시 빌드하여 해결해야 합니다.

$ sudo apt-get install dpkg-dev devscripts fakeroot
$ sudo apt-get source apache2
$ cd apache2-2.0.xx/debian
$ vi rules

Looking into rules file, there’s a sentence that sets AP2_CONFFLAGS variable. Add the following line next to the sentence and save the file.

rules 파일 안을 보면 AP2_CONFLAGS 변수를 설정하는 부분이 있습니다. 바로 아래에 다음 라인을 추가하고 저장합니다.

AP2_CONFLAGS += -D_XOPEN_SOURCE=500

Now, let’s build the new deb package and install it.

이제 새 deb 패키지를 빌드해 설치합니다.

$ cd ..
$ sudo apt-get build-dep apache2
$ debchange -n # vi 뜨면 저장
$ dpkg-buildpackage -rfakeroot -b
$ cd ..
$ sudo dpkg --install libapr0*.deb

NOTE: If you encountered a dependency error while you run dpkg --install, you will also have to install the related packages whose name starts with apache2.

만약 dpkg --install 실행 중 의존성 에러가 나면 apache2로 시작하는 이름의 관련 패키지들도 설치해야 하니 주의하세요.

At last, adding -vmargs -Djava.library.path=/usr/local/lib option in your Eclipse command, JVM doesn’t bomb out anymore when Subclipse is reconfigured.

마지막으로 Eclipse 실행 옵션에 -vmargs -Djava.library.path=/usr/local/lib를 추가하면 이제 Subclipse 설정을 바꿔도 JVM이 죽지 않습니다.

다양한 객체 지향 원칙들이 존재하는 이유

재미있게 주몽을 보고 잠깐 들어와 보니 이런 저런 다양한 글들이 Context 개체가 남발되고 있다거나, 의미의 면적이 좁은 인터페이스를 제공하거나 그에 의존해서는 안된다거나, 최소 권한의 원칙과 같은 이야기를 하고 있습니다.

다 맞는 말씀입니다만, 저는 이런 원칙들의 궁극적인 목표를 생각해야 할 필요가 있다고 봅니다. 그것은 바로 소프트웨어 개발 비용을 절감시키는 것입니다. 소프트웨어 비용을 절감시켜야 한다고들 주장한다면 보나 마나 소프트웨어 비용이 늘어났다는 뜻이겠군요. 그렇다면 소프트웨어 개발 비용은 왜 늘어났을까요? 그것은 더 복잡한 소프트웨어를 만들어 내야 하기 때문입니다. 오늘날 모든 복잡한 소프트웨어는 다른 더 작은 소위 컴포넌트라 불리우는 소프트웨어에 기반해 개발되고 있습니다. 바꿔 말하면, 오늘날의 불필요한 소프트웨어 개발 비용 지출의 대부분이 의존하는 API의 사용성 (usability) 문제 때문에 발생하고 있다고 할 수 있습니다. 사용성 나쁜 API를 노출하는 컴포넌트를 사용하면 monolithic 하게 개발했을때처럼 생산성이 떨어질 수도 있습니다.

그런데 이 API의 사용성이란 것은 사실상 평가가 어려운 광범위한 분야로, 보통 객체 지향 설계 원칙이라는 고상한 말로 포장되어 왔습니다. 개발자의 입장에서 이 둘은 동의어나 마찬가집니다.

사용성이 높은 API는 전부를 모르더라도 쉽게 기본적이면서도 실무에 필요한 핵심적인 작업을 바로 시작할 수 있고, 좀 더 복잡한 케이스를 다뤄야 할 경우 다음 단계를 쉽게 배워 나아갈 수 있도록 학습 곡선을 정교하게 제어합니다. 그 과정에서 물론 과정보 (overinformation)은 억제됩니다. 즉, 누구나 빠르면서도 자신이 모르는 사이에 발전 가능한 방향으로 원하는 바를 성취하고, 학습의 즐거움을 느낄 수 있게 해 주는 것이 API 사용성의 핵심입니다.

그렇다면 Context 객체가 어떤 문제를 갖느냐, Context 객체 자체의 도입은 API 사용성 측면에서 매우 고무적입니다. 컨테이너나 커널이 제공하는 기능을 활용하여 동작하는 비즈니스 로직이 부모 컨테이너/커널이 노출하는 최소한의 기능만을 사용할 수 있도록 해 주는 개체가 Context 의 원래 역할이기 때문입니다. 첫 번째 글에서 static 하거나 ThreadLocal을 사용한 Context 객체를 예로 들었는데, 이는 부적절한 예입니다. static 하거나 ThreadLocal 하게 작성했다는 것이 문제이지, Context 객체 자체의 존재가 잘못된 것은 전혀 아닙니다. 문제가 있다면 Context 를 제공하는 컨테이너의 역할 정의가 모호했기 때문이겠죠. 그도 아니면 컨테이너도 아니면서 주제 넘게 intrusive한 인터페이스를 제공했기 때문이겠죠. 컨테이너나 프레임워크가 Context 개체를 제공하는 것은 전혀 잘못된 일이 아닙니다.

또한, 두 번째 글에서 이야기하고 있는 다양한 Context 개체가 한 코드에서 섞여서 쓰이는 문제는 그 코드가 동시에 다양한 기능을 사용하려고 했다는 뜻을 가질 뿐입니다. 동시에 여러 가지 일을 한다는 것이 항상 잘못된 것은 아니며, 적절한 검토가 필요할 따름입니다. 오캄의 면도날을 쫓는 것은 좋은 일이지만, 의존성에 지나치게 집착하는 것도 좋은 태도는 아닙니다. 클래스 하나 때문에 수백KB 짜리 JAR 쓰는게 왜 나쁩니까? 클래스 하나를 씀으로 인해 다른 원치 않는 부작용이 생겨야 나쁘지, 대부분의 잘 설계된 컴포넌트들은 그렇지도 않습니다. 글쓴이가 HTMLPageParser 하나 때문에 SiteMesh 를 사용한 것처럼요. 문제는 하고자 하는 일에 맞는 제대로 된 컴포넌트를 선택하는 것이지, 컴포넌트를 사용하느냐 마느냐가 아닙니다.

어떤 API 를 설계할 때 결과적으로 중요한 것은, 대상 – 엄밀히 말하면 다수의 – 사용자가 그 API를 편리하게 느끼느냐입니다. API가 불필요하게 많은 기능을 제공한다 하더라도 그것이 결국 그 API를 사용하는 대상이 편하게 느끼고 결과적으로 생산성을 가져다 주면 저는 상관 없다고 봅니다. 과연 관계의 수를 줄여 결국에는 다 제공해야 할 기능을 매우 복잡한 콜 그래프를 그리게 해야 할 필요가 있을까요? 전 당연히 없다고 봅니다. Humane interface 와 Minimal interface 에 대한 논쟁에서와 마찬가지로, 사용자가 얼마나 많은 정보에 노출되기를 바라느냐에 따라 호불호가 갈릴 뿐 정답은 없습니다.

중요한 것은 특정 원칙에 집중하는 것이 아니라, API 를 사용하게 될 사람의 마음을 헤아리고 그 사람이 가장 생산성 있게 개발할 수 있도록 하는 것입니다. 또한 나아가 사용자가 감동할 수 있는 API 를 제공해 그 설계 철학이 그 사용자가 개발하고 있는 컴포넌트에 전해질수 있도록 한다면 금상 첨화겠죠. 이것은 단순히 다양한 원칙들을 고수함으로서 이루어지는 것이 아니라 다분히 사용자층의 취향과도 결부되는 복잡한 상호작용의 결과, 즉, 매우 사회적인 과정입니다.

그러므로 우리는 오늘날 컴포넌트들이 얼마나 사용자를 고려해서 개발되고 있는지 생각해 볼 필요도 있습니다. 유명한 라이브러리나 프레임워크들을 보면 사용자층도 두텁고 피드백도 활발합니다. 닭이 먼저냐 계란이 먼저냐는 질문을 할 수도 있겠지만, 적절한 원칙을 세워 개발하였고, 그 과정에서 생길 수 있는 API의 까칠한 면을 커뮤니티의 도움을 받아 다듬어 나아가는 것이 지금까지 제가 보아 온 성공한 소프트웨어의 모습이었습니다. 원칙도 중요하지만 그 뒤에는 사용자가 있다는 것, 그리고 그 사용자와 상호작용이 제대로 이루어지지 않으면 그 좋은 원칙도 아무 소용 없다는 것 또한 명심해야 합니다.

Modifying Default ulimit Values for a Normal User in Linux

Linux에서 일반 사용자의 default ulimit 값 수정

The default value of ulimit -n (the maximum number of open file descriptors per process per user) is 1024 in Ubuntu Linux. There’s no problem with this default value in my daily life, but I start to get ‘Too many open files’ errors when I test the performance of server applications which accept from 1000 to tens of thousands client connections. A super user (root) can type a command like ulimit -n 10240 to increase the default limit value, but a normal user can’t. If you are at least a sudoer, you can resolve this problem by adding the following lines to /etc/security/limits.conf file.

제가 사용하고 있는 Ubuntu Linuxulimit -n (동시에 열 수 있는 파일의 총 수)의 기본값은 1024입니다. 일상 업무를 보는데는 전혀 지장이 없지만 서버 어플리케이션을 테스트하다 보면 적게는 1000개, 많게는 수만 개의 접속을 테스트해야 할 일이 생겨 ‘Too many open files’ 에러를 볼 수밖에 없습니다. 수퍼 유저 (root)라면 ulimit -n 10240과 같이 입력하여 그 제한을 올릴 수 있지만, 일반 사용자는 불가능합니다. 이때 만약 수퍼 유저 권한을 갖고 있다면 /etc/security/limits.conf 파일에 다음과 같은 내용을 추가하여 이 문제를 해결할 수 있습니다.

trustin         soft    nofile          10240
trustin         hard    nofile          10240
www-data        soft    nofile          10240
www-data        hard    nofile          10240

The example above increases the maximum number of open files per process per user to 10240 for two users; trustin and www-data.

위의 예시는 trustin과 www-data라는 사용자의 최대 연 파일 수를 10240으로 올려 줍니다.

인생, 책처럼은 되지 않는다!

요즘 잠이 많이 부족하다.

출퇴근 시간 다 합쳐 네 시간이다. 차 안에서 자고 싶지만 계속 버스 안에서 잤더니 목도 허리도 아파서 잠도 더 이상 못자겠다. 이사를 하려고 해도 돈이 너무 아깝다. 2억 가까운 돈을 전세금으로 써야 한다니, 그 돈이 있으면 차라리 펀드를 들겠다. 결혼할 때까지 이 생활을 계속할 생각을 하면 답답해지기만 한다. 차라리 가까운 곳이 아니라면 아예 머나먼 곳으로 떠나고 싶다.

다른 시간대의 회사에서 일을 했던 전력 때문에 밤낮 가리지 않고 연락이 온다. 솔직히 열받는다. 급한 마음에 문제 생기면 메신저 메시지와 전자 메일 날라오는 것, 이해할 수 있다. 하지만 오픈 소스인데 같은 서버 개발자로서 최소한 기본적인 소스 코드와 로그 메시지는 찬찬히 읽어 보고 물어 봤으면 하는 바람이 있다. 적어도 뭔가 이상한 낌새가 있으면 로그 레벨 낮춰 보고 메시지로 소스 코드 정도는 검색해 보고 물어봐야 하는 것 아닌가. 이렇게 지내다 보니 잘 시간은 주말 뿐인데, 주말에도 시차 때문에 자려고 하면 꼭 연락이 온다. 사실 주말에 몰아 자는 스타일도 아니라 악순환의 연속이다.

그래, 사실 제일 큰 문제는 나 자신이지. 돈에 눈이 멀어 제대로 해 놓은 일도 없이 인센티브를 덜컥 받아 안중에도 없던 근무지에서 이 고생을 하고 있는 나나, 용기있게 더 이상 그 프로젝트에 관심이 없어졌다고 말하지 못하는 나나, 참 문제다. 책에 적힌 대로 그냥 그렇게 내 자신의 다시는 돌아오지 않을 수도 있는 행복을 위해 입 싹 닫고 멋대로 해 버리기엔 내 양심이 너무나 찔린다. 인생, 책처럼은 되지 않는다. 아니면 혹시 아직 책을 덜 읽은 걸까? (웃음)

배고픔의 자서전

계절 탓에 일찍 드리워진 암흑을 헤치고 나아가는 버스 안에서 쏟아지지 않는 잠을 청했다. 하지만 고단한 몸은 삶의 의미를 맹목적으로 질문하고 있었다. 아마도 낮에 읽은 ‘배고픔의 자서전‘에서 아멜리 노통브와 니쇼상이 나눈 마지막 대화 때문이리라.

“아무려면 어때? 아직은 이렇게 목숨이 붙어 있는 걸.”

미칠것 같은 공허함, 결핍, 두려움, 절망 속에서 그래도 우리는 아직 살아 있다. 죽음이 찾아오는 순간까지 그러한 감정들을 잊지도, 버리지도 못할 것이다. 그것은 아프다고 부정해 버리기에는 존재의 너무나 많은 부분을 차지하고 있는 아픔이자, 아직 목숨이 붙어 있다는 징표다.

외롭지 않다면 기댈 곳도 없다. 힘들지 않다면 쉴 곳도 없다. 공기가 희박할 수록 숨이 가빠지듯, 절망 속에 갈구하는 희망이야말로 진정 가치 있다. 삶의 다양한 극한을 경험한 그녀가 천재적 글솜씨로 전하고 싶었던 메시지는 그래서 그 기교보다도 감탄스럽다.

mina.apache.org

10월 25일 ASF 보드 미팅 결과, Apache Directory Project의 서브 프로젝트였던 MINA의 TLP (Top Level Project) 승급 요청이 공식적으로 승인되었습니다. 곧 mina.apache.org 도메인 하에서 프로젝트를 진행하게 됩니다. 저는 투표를 통해 Apache MINA PMC (Project Management Committee)의 의장으로 선출되었습니다. ASF에서 신규 프로젝트에 대해 ASF member가 아닌 committer가 첫 PMC 의장이 된 사례는 최초입니다.

지난 2년 남짓한 시간 동안 ASF와 맺은 인연은 잊을 수 없는 경험이었습니다. 소프트웨어의 완성도란 한 개인의 능력이 아닌 커뮤니티 전체의 총합임을 깨닫는 데는 얼마 걸리지 않았습니다. 많은 사람과 협동을 하고 의사 결정을 내리는 과정에서 조금은 성숙해 진 제 자신을 느꼈습니다. 그리고 그 과정을 즐기고 있는 나 자신을 발견할 때면 정말 이 길은 내가 가야 할 길이라는 확신을 갖게 됩니다.

이제는 더 많은 권한과 책임이 주어진 만큼, 더 많은 것을 배우고 더 많은 아이디어를 현실화할 수 있는 능력을 키워야 겠습니다. 끝이 없는 도전, 그것만큼 가슴 뭉클한 것도 없지 않을까요?

Remember the Milk 완전 한글화

예전에 소개드린 바 있는 Remember the Milk가 완전 한글화되었습니다. RTM의 번역 시스템은 특이하게도 커뮤니티 멤버들이 웹 인터페이스를 통해 번역 데이터베이스에 문구를 집어 넣도록 되어 있습니다. 물론 운영자나 원 번역자의 검토를 거쳐서 최종 서비스에 통합되기는 하지만 정말 편리하고 인상적인 번역 시스템이 아닐 수 없습니다. 번역이 매끄럽지 못한 부분이 있으면 번역 시스템을 이용해 직접 수정 요청을 하시면 됩니다.

사실 90% 이상의 번역은 제가 했습니다. 영어를 아직 잘 못하는 여자친구가 할 일을 좀 더 체계적으로 관리할 수 있도록 도와주려고 번역한 것인데요, 다른 많은 분들도 한국어 버전의 RTM를 편리하게 쓸 수 있다면 기쁘겠네요.

June 15~18: Saipan Tour

첫눈 임직원분들과 함께 NHN 합병 발표 전에 다녀온 사이판 여행 사진들입니다. 예전에 포스팅한 적이 있지만, 내용이 없어서 몇 자 적어 봅니다.

첫눈 직원분들 얼굴도 약간 들어 있네요. 첫눈에서의 시간은 특정 인물과의 트러블이 많았고, 덕택에 힘들면서도 마음이 통하는 사람들을 많이 만나게 되어 지금까지의 직장 생활과는 또 다른 모습이었습니다. 하지만 한편으로는 갈 길을 알면서도 돌아온 것은 아닌가 하는 후회가 남습니다. 비록 첫눈은 사라졌지만, 어쨌든 지금은 제대로 된 팀을 만나 일할 수 있어 기쁘네요.

얼마 전에는 추석을 맞아 장병규 사장님께서 첫눈 직원들에게 카드를 돌리셨습니다. 가슴이 찡했습니다. 물론 첫눈이라는 조직이 작았기 때문에 가능한 일이기도 하지만, 그래도 이런 리더가 세상엔 흔치 않지 않나 싶네요.