2012년 1월 19일 목요일

기가비트 환경에서 패킷덤프 손실을 줄여보기 위한 도구, GULP

기가비트 환경에서 손실없이 패킷을 잡아내기 위한 방법들은 무엇이 있을까? 여러가지 것들이 있을 수 있겠지만, 우리가 흔히 사용하고 있는 리눅스 시스템에서 특별한 변경없이 간단하게 사용할 수 있는 도구 하나를 소개해 볼까 한다. 도구 하나만으로 완벽한 손실없이 패킷을 잡아내기에는 여러가지 환경적 제약이 따른다. 그러므로, 최대한 손실을 줄이면서 패킷을 잡아낼 수 있는 방법을 고민해야 하는데, 스레드 기반의 GULP 가 도움이 되지 않을까 한다.

이 도구를 만든 배경 및 세부적인 정보는 다음 URL 에서 얻을 수 있다.

http://staff.washington.edu/corey/gulp/

비교적 작성된지가 오래되었으므로 이점을 감안하기 바란다.

컴파일은 간단히 make 를 하는 것 만으로도 어렵지 않게 결과를 얻어낼 수 있다.

# make
cc -O    check64bit.c   -o check64bit
./check64bit; rm -f check64bit


If output from Gulp is not compatible with tcpdump or wireshark,
Please see: http://staff.washington.edu/corey/gulp/gulp.html#64bit


cc -g -O gulp.c -o gulp -lpthread -lpcap

실행해 보면 아래와 같은 도움말 정보를 얻을 수 있다.

$ ./gulp
./gulp: Sending raw pcap data to a terminal is not a good idea.
        If you really want to do that, pipe ./gulp through cat but you
        probably want to redirect stdout to a file or another program instead.
        Perhaps you meant to pipe into 'tcpdump -r-' or 'ngrep -I-' ?

Usage: ./gulp [--help | options]
    --help      prints this usage summary
    supported options include:
      -d        decapsulate Cisco ERSPAN GRE packets (sets -f value)
      -f "..."  specify a pcap filter - see manpage and -d
      -i eth#|- specify ethernet capture interface or '-' for stdin
      -s #      specify packet capture "snapshot" length limit
      -r #      specify ring buffer size in megabytes (1-1024)
      -c        just buffer stdin to stdout (works with arbitrary data)
      -x        request exclusive lock (to be the only instance running)
      -X        run even when locking would forbid it
      -v        print program version and exit
      -Vx...x   display packet loss and buffer use - see manpage
      -p #      specify full/empty polling interval in microseconds
      -q        suppress buffer full warnings
      -z #      specify write blocksize (even power of 2, default 65536)
    for long-term capture
      -o dir    redirect pcap output to a collection of files in dir
      -C #      limit each pcap file in -o dir to # times the (-r #) size
      -W #      overwrite pcap files in -o dir rather than start #+1
    and some of academic interest only:
      -B        check if select(2) would ever have blocked on write
      -Y        avoid writes which would block

여러 패킷 덤프 도구들을 사용해 보았다면 옵션만 보아도 어렵지 않게 사용할 수 있다. 참고로 덤프되는 데이터를 바로 터미널에 출력하는 것은 권장 되지 않으므로, 파일로 리다이렉션 하거나 또는 tcpdump, ngrep 과 같은 프로그램으로 리다이렉션 하는 것이 좋다

다음예는 , -i 로 덤프할 인터페이스를 지정하고 '>' 로 파일로 저장하고 있다.

#./gulp -i eth0 > tt

덤프된 파일의 타입을 살펴보면 캡쳐파일임을 알 수 있고 tcpdump 프로그램으로 확인할 수 있다.

# file tt
tt: tcpdump capture file (little-endian) - version 2.4 (Ethernet, capture length 65535)
# tcpdump -r tt
reading from file tt, link-type EN10MB (Ethernet)

다시 패킷을 덤프하는 과정에서 중지하고 살펴보면 12만개 패킷 중 31 개의 패킷이 drop 되었다. 추가로 나오는 정보에서 이런 drop 되는 패킷을 줄이기 위하여 rmem_max 와  rmem_default 값을 늘려주기를 권장하고 있다.

참고로  이전에 작성한 다음 블로그 글을 참고하여 파라미터 값을 조정하면 도움이 될 것이다.

[링크] 커널에서 drop 되는 패킷 수가 많다면...

# ./gulp -i bond0 > tt2
^C
121313 packets captured
121343 packets received by filter
31 packets dropped by kernel

Note ./gulp may drop fewer packets if you increase:
  /proc/sys/net/core/rmem_max and
  /proc/sys/net/core/rmem_default
to 4194304 or more

ring buffer use: 1.8% of 100 MB

느낌상으로는 다른 캡쳐 도구에 비해 손실이 적어 보이기도 한다. 그래서 tcpdump 와 gulp 로 테스트를 해 보았다.

# tcpdump -i bond0 -n -s 1514 -w tt
tcpdump: listening on bond0, link-type EN10MB (Ethernet), capture size 1514 bytes
^C207292 packets captured
208468 packets received by filter
1176 packets dropped by kernel

# ./gulp -i bond0 -s 1514 > tt5
^C
240675 packets captured
240674 packets received by filter
0 packets dropped by kernel
ring buffer use: 0.8% of 100 MB

위 결과를 보면 tcpdump 에서는 1176 개의 패킷이 drop 된 것에 비해 gulp 에서는 한개의 패킷도 drop 되지 않았다.  간단한 결과만 보아도 단순 패킷덤프에서는 gulp 가 tcpdump 보다 우수하다.
gulp 에서 패킷이 유실되는 개수 및 RingBuffer 사용률을 같이 볼 수 있는데 -Vx 를 추가로 주고 덤프를 해 보면 된다.

# ./gulp -i bond0 -Vx > tt3
pkts dropped: 0, ring buf: 0.0%, max: 0.1%
pkts dropped: 0, ring buf: 0.0%, max: 0.1%
pkts dropped: 0, ring buf: 0.1%, max: 0.1%
pkts dropped: 0, ring buf: 0.0%, max: 0.1%
pkts dropped: 0, ring buf: 0.0%, max: 0.1%
pkts dropped: 0, ring buf: 0.0%, max: 0.4%
pkts dropped: 0, ring buf: 0.1%, max: 0.4%
pkts dropped: 0, ring buf: 0.1%, max: 0.4%
pkts dropped: 0, ring buf: 0.0%, max: 0.4%
pkts dropped: 0, ring buf: 0.0%, max: 0.4%
pkts dropped: 0, ring buf: 0.0%, max: 0.4%
pkts dropped: 0, ring buf: 0.1%, max: 0.4%
pkts dropped: 0, ring buf: 0.0%, max: 0.4%
pkts dropped: 0, ring buf: 0.0%, max: 0.4%
pkts dropped: 0, ring buf: 0.0%, max: 0.4%
pkts dropped: 0, ring buf: 0.1%, max: 0.4%
^Cpkts dropped: 0, ring buf: 0.1%, max: 0.4%

27455 packets captured
27454 packets received by filter
0 packets dropped by kernel
ring buffer use: 0.4% of 100 MB

패킷 데이터를 바로 파일로 저장하는 것 외에 프로그램으로 리다이렉션 하여 다음과 같이 사용할 수도 있다.

# ./gulp -i bond0 | tcpdump -r - -w tt4
# ./gulp -i bond0 | ngrep -I - www

그럼 어떤면에서 gulp 가 더 우수한 성능을 보여줄까 ? gulp 를 백그라운드로 실행하고 해당 프로세스를 찾아 strace 로 살펴보았다.

# ./gulp -i bond0 -s 1514 > tt5 &
[2] 5798
# ps -ef | grep gulp
root      5798 18450  0 14:32 pts/1    00:00:00 ./gulp -i bond0 -s 1514
root      6749 18450  0 14:33 pts/1    00:00:00 grep gulp
# strace -p 5798
Process 5798 attached - interrupt to quit
restart_syscall(<... resuming interrupted call ...>) = 0
nanosleep({0, 500000000}, NULL)         = 0
nanosleep({0, 500000000}, NULL)         = 0
nanosleep({0, 500000000}, NULL)         = 0
nanosleep({0, 500000000}, NULL)         = 0
nanosleep({0, 500000000}, NULL)         = 0
nanosleep({0, 500000000}, NULL)         = 0
nanosleep({0, 500000000}, NULL)         = 0
nanosleep({0, 500000000}, NULL)         = 0
nanosleep({0, 500000000}, ^C <unfinished ...>
Process 5798 detached

nanosleep 만이 계속 보인다. 무엇인가 계속 기록하고 해야 할텐데, nanosleep 만 보인다? 혹시 스레드를 사용하는 것일까? 그렇다. 다음과 같이 스레드 카운트를 확인해 보면 3개로 보인다.

# ps -o pid,comm,thcount 5798
  PID COMMAND         THCNT
 5798 gulp                3

이와 달리 같은 형태로  tcpdump 를 살펴보자.

# tcpdump -i bond0 -n -s 1514 -w tt6 &
[2] 9793
# tcpdump: listening on bond0, link-type EN10MB (Ethernet), capture size 1514 bytes

# ps -ef | grep tt6
root      9793 18450  0 14:35 pts/1    00:00:00 tcpdump -i bond0 -n -s 1514 -w tt6
root     10080 18450  0 14:35 pts/1    00:00:00 grep tt6

# strace -p 9793
write(4, "\245\1(\37\315Y\265\206\207\fa\315\257\26\1771u\265\240\223\30309A0\304\362\\\257\7k>~"..., 4096) = 4096
recvfrom(3, "\0\33!R\3334\0PV\250]5\10\0E\0\0(\v\"@\0\200\6Hzo\3\4\22\314\240g"..., 1514, MSG_TRUNC, {sa_family=AF_PACKET, proto=0x800, if10, pkttype=PACKET_HOST, addr(6)={1, 005056a85d35}, [18]) = 60
ioctl(3, SIOCGSTAMP, 0xbfffec18)        = 0
recvfrom(3, "\0PV\250]5\0\33!R\3334\10\0E\0\5\320w+@\0@\6\26\311\314\240g~o\3\4"..., 1514, MSG_TRUNC, {sa_family=AF_PACKET, proto=0x800, if10, pkttype=PACKET_OUTGOING, addr(6)={1, 001b2152db34}, [18]) = 1502
ioctl(3, SIOCGSTAMP, 0xbfffec18)        = 0
recvfrom(3, "\0PV\250]5\0\33!R\3334\10\0E\0\5\320w,@\0@\6\26\310\314\240g~o\3\4"..., 1514, MSG_TRUNC, {sa_family=AF_PACKET, proto=0x800, if10, pkttype=PACKET_OUTGOING, addr(6)={1, 001b2152db34}, [18]) = 1502
ioctl(3, SIOCGSTAMP, 0xbfffec18)        = 0
write(4, "R\370\377\3627\t\2\275\230\22G\321\27414\0172\0\341\224(\4rb\326\275\322\246\333\270\303e\200"..., 4096) = 4096
recvfrom(3, "\0\33!R\3334\0PV\250]5\10\0E\0\0(\v#@\0\200\6Hyo\3\4\22\314\240g"..., 1514, MSG_TRUNC, {sa_family=AF_PACKET, proto=0x800, if10, pkttype=PACKET_HOST, addr(6)={1, 005056a85d35}, [18]) = 60
ioctl(3, SIOCGSTAMP, 0xbfffec18)        = 0
recvfrom(3, ^C <unfinished ...>

무엇인가 아주 바쁘게 기록을 하며 움직이고 있다. 스레드 카운트를 확인 해보면 1 이다.

# ps -o pid,comm,thcount -p 9793
  PID COMMAND         THCNT
 9793 tcpdump             1

즉, GULP 는 스레드로 동작하여 파일 기록시에도 별도의 스레드로 처리하여 더 높은 성능을 나타내고 있는 것이다.

기가비트 네트워크에서는 트래픽 양이 워낙 많기 때문에 운영체제의 네트워크 파라미터를 최적화 하고, 적절한 패킷 캡쳐 도구를 선택해야 한다. 사용환경과 패킷캡쳐의 목적에 따라서 달라지겠지만, 자기에게 맞는 적절한 도구를 테스트해보고 선택하여 사용하면 될 것이다.

2012년 1월 16일 월요일

NSA 가 공개한 더욱 안전한 안드로이드 플랫폼 SEAndroid

NSA(National Security Agency) 에서 공개한 SEAndroid 가 있다. Android 앞에 붙어 있는 SE 는 Security Enhanced(SE) 약자 의미이다. NSA 가 공개하고, 보다 안전한 안드로이드 플랫폼이라는 의미가 와 닿는다. NSA 에서 더욱 안전한 환경의 스마트폰 사용을 위해 공개한 것으로, 기존 안드로이드 플랫폼의 수정된 버전으로 SELinux 를 기반으로 하고 있다. 이 버전을 통해 악성 앱에 의한 위협을 줄이고 앱간 보안성을 더욱 유지시켜 준다고 한다. 이것은 처음 Linux Security Summit 2011 에서 언급되었고, 그 당시 발표 자료는 다음 경로에서 볼 수 있다.


세부적인 정보는 SEAndroid 위키 페이지에서 정보를 얻을 수 있다.

기존 안드로이와 차이점은 다음과 같다:
  • Per-file security labeling support for yaffs2,
  • Filesystem images (yaffs2 and ext4) labeled at build time,
  • Kernel permission checks controlling Binder IPC,
  • Labeling of service sockets and socket files created by init,
  • Labeling of device nodes created by ueventd,
  • Flexible, configurable labeling of apps and app data directories,
  • Userspace permission checks controlling use of the Zygote socket commands,
  • Minimal port of SELinux userspace,
  • SELinux support for the Android toolbox,
  • Small TE policy written from scratch for Android,
  • Confined domains for system services and apps,
  • Use of MLS categories to isolate apps.

2012년 1월 13일 금요일

와이어샤크 1.7 개발 버전 살짝 들여다 보기

작년 11월 초에 와이어샤크 1.7 개발버전이 공개되었다. 기존에 사용하던 최신 버전이 1.6.X 대 이니 1.7 이라고 하면 과연 어떤 새로운 기능이 있을까 하는 궁금증이 생긴다.

1.7 버전에서 크게 변경되는 것은 패킷파일을 저장하는 기본 포맷 형태가 PCAP-NG 바뀌었다는 것이다. 우리가 흔히 쓰고 있는 PCAP 포맷형태에서 차기 버전 포맷 형태로 바뀌는데 내부 형태의 구조는 많이 달라진다. PCAP 포맷에 대해서는 이미 한번 언급한 적이 있으므로 다음 글을 참고해 보면 된다.

PCAP 파일을 파헤쳐 보자 - 그 첫번째 이야기

PCAP 파일을 파헤쳐 보자 - 그 두번째 이야기


1.7 버전의 주요변경 내역을 정리해 보면 다음과 같다:

- 기본 포맷형태가 PCAP-NG 로 변경
- 동시에 여러개의 인터페이스에서 패킷 캡쳐 가능
- TCP 윈도우 업데이트에서 "Bad TCP" 로 더이상 칼라 표시되지 않는점
- TShark 커맨드 라인 옵션 일부 변경
- GeoIP IPv6 데이터베이스 지원 등이다.

1.7 버전을 실행해 보면 다음과 같은 화면이다. 1.7 개발버전이라는 것이 보이고 Start 부분에서 인터페이스가 여러개 보인다.



캡쳐를 시작할때 나타나는 화면을 보면 다르게 보이는 것이 하나 느껴질 것이다.


바로 상단 부분의 인터페이스로 여러개를 선택할 수 있도록 바뀌었다. 이제는 동시에 여러 인터페이스에서 패킷 캡쳐가 가능해 진 것이다. 그리고 패킷을 저장해 보면 기본 선택이 PCAP-NG 포맷이다. 해당 포맷을 살펴보면 아래 그림과 같은데, 기존 PCAP 포맷과는 달리 헤더 블럭이 더욱 길어졌다. 인터페이스 정보도 포함되어 있고, 좀더 많은 정보를 담고 있는 구조로 조만간 PCAP-NG 포맷에 대해 공유해 볼 까 한다.



2012년 1월 12일 목요일

와이어샤크 1.6.5, 1.4.11 버전 릴리즈

와이어샤크가 버전업 되었다. 최신 버전은 1.6.5 이며, 몇 가지 취약점이 수정되었다.
그리고 알려진 버그들도 해결되었고, 몇 가지를 살펴보면 다음과 같다.

- Export HTTP Objects 에서 모두 저장하기 할때 와이어샤크가 종료되는 문제점
- 최근 파일이 없을 경우 Crash 되는 문제
- 여러 프로토콜 해석기에서 발생된 메모리 누수
- 라우팅 헤더가 존재할 경우 IPv4 UDP/TCP 체크섬이 올바르지 않은 문제점 등이 있다.

새로운 기능 또는 프로토콜은 없으며, 기존 프로토콜 지원이 일부 업데이트 되었다.
1.4.X 의 최신버전은 1.4.11 이며, 다운로드는 다음 주소에서 가능하다.

http://www.wireshark.org/download.html

2012년 1월 11일 수요일

필요한 내용만 패킷파일로 저장하기

패킷덤프를 하는 과정에서는 통상
1) 네트워크 디바이스 전체를 대상으로 덤프를 하거나
2) 또는 캡처필터를 적용하여 저장하는 것이 일반적이다.

하지만 트래픽이 많은 경우라면 이 또한 여기서 원하는 데이터로 한정하여
필요한 데이터만 저장하기에는 사용자 수고가 따른다.

쉬운 방법으로 이용할 수 있는 것이 ngrep 이 있다. 간단하지만 잘 이용되지 않는것 같아 다시 소개해 본다.

-O 옵션을 이용하면 ngrep 에서 지정한 스트링이 검출된 패킷에 한해서만 PCAP 포맷형태로
저장되므로 필요한 패킷 데이터만을 저장할 수가 있다.

# ngrep -d eth0 -O extracted.pcap GET
or
# tcpdump -i eth0 | ngrep -I - -O extracted.pcap GET

ngrep 을 통해 바로 지정하여 사용하거나 또는 tcpdump 를 통해 입력을 ngrep 에
전달하여 사용할 수도있다.  매칭할 패턴만 잘 정의하고 사용한다면 아주 유용할 것이다.

이전에 ngrep 을 활용한 패킷데이터 추출에 대해 설명한 글이 있으므로 참고하길 바란다.

[링크] Ngrep 을 활용한 패킷 데이터 추출

2012년 1월 8일 일요일

1분에 640 테라바이트 트래픽이 흘러다닌다고?

과연, 인터넷에서 전송되고 있는 데이터량은 얼마나 될까? 최근 인텔(Intel)에서 재미있는 인포그래픽을 발표하였다. 매 분 인터넷 상에서 무슨일이 일어나는지 주요한 지표를 수치화 한 것이다. 트래픽 데이터 관점에서만 보더라도 인텔은 인프라에 대한 투자는 충분히 이뤄지고 있는지 질문을 던지고 있다. 인터넷에 접속되는 디바이스는 전 세계 인구를 넘어 설 만큼 크게 증가하고 있는데, 과연 네트워크는 이러한 예측에 충분히 대비하고 있는가에 대한 것이다.



















[이미지출처 : 인텔]

약간 관점을 달리해서 생각해 보자. 각국 정부는 사회기반시설에 대한 투자를 한다. 도로, 항만, 철도 기타 등에 말이다. 인터넷 인프라는 투자하면 안되는 것일까? 어찌보면 이제 인터넷은 세계 경제 움직임의 중심에 서 있기도 하다. 그런 의미에서 보면, 네트워크 인프라는 중요하지 않을 수 없다.

그건 그렇고, 인포그래픽의 주요한 부분을 정리하면 다음과 같다:

- 전세계 IP 네트워크에서 매 분 마다 거의 640 테라 바이트의 트래픽이 흘러다니고 있다.
- 6백만 페이스북 페이지 뷰어, 2백만개의 구글 검색 쿼리
- 유투브에 30시간의 비디오 데이터가 올려지고
- 130 만명이 비디오를 본다.

한달, 아니 1주도 아니고 매 분마다 발생하고 있는 데이터라고 한다.

수치화 해서 보니 어마어마한 데이터다. 인프라 관리 입장에서 보면 이 수많은 데이터를 어떻게 관리하고 저장하고 운영해야 할지 참 쉽지 않은 일들이다.

이렇게 엄청난 데이터가 네트워크를 통해서 흘러다니고 있는데, 분석한다면 ?
여러분의 상상력에 맡기겠다.


2012년 1월 5일 목요일

리눅스 커널 3.2 릴리즈 - TCP 스택 향상

리눅스 커널 3.2 버전이 릴리즈 되었다. 기존 2.X 대에서 Major 번호를 바꾸고 3.X 로 릴리즈 하고 있다는 소식은 이미 전해 들었을 것이다. 이번 릴리즈에서 퀄컴의 Hexagon 프로세서 아키텍처를 지원하고, Ext4 파일시스템의 향상 그리고 인텔, NVIDIA 의 그래픽 드라이버 등이 향상되었다. 패킷 인사이드에서 관심가질만한 부분은 네트워크 부분이다.

바로 이번 릴리즈에서는 구글 개발자에 의해 추가된 "Proportional rate reduction" 알고리즘이 TCP 스택에 추가되었다. 이로 인해 일시적인 데이터 전송 문제가 발생하여도 빠르게 네트워크 연결을 복구하여 전반적으로 속도 향상을 가져온다.

개발자에 따르면3 ~ 10 퍼센트 정도 HTTP 전송비율이 높아졌다고 한다.

참고로, 이전에 포스팅 하였던 XPS(Transmit Packet Steering) 도 참고해 보기 바란다.
리눅스 커널 2.6.38 에 포함된 XPS(Transmit Packet Steering)는 무엇이지?

[참고]
1. Proportional Rate Reduction for TCP
http://static.googleusercontent.com/external_content/untrusted_dlcp/research.google.com/en//pubs/archive/37486.pdf

2012년 1월 3일 화요일

네트워크 프로그램 언어, Frenetic

수 많은 언어가 있지만, 네트워크를 위한 언어가 있다. 그 이름은 Frenetic 이다. 다양한 컴퓨터 언어가 존재하고 이를 통해 프로그램을 하지만 현재의 모든 기능적인 것을 반영하기에는 한계가 있다. 그래서 네트워크 프로그램 언어가 제안되었고, Frenetic 라는 이름으로 진행되고 있다.

아직 많은 정보는 없으며, 관련 논문은 다음과 같다:
http://www.frenetic-lang.org/papers/

관심있는 분은 참고해 보길 바란다.

http://www.frenetic-lang.org/