[질문] 커널 내부를 지나가는 패킷들의 자세한 통계정보를 계산

swunk의 이미지

랜카드가 2개인 리눅스 머신이고 라우터로 동작하고 있습니다.

제가 하고싶은 것은 각각의 랜카드로 입/출력되는 모든 패킷들을 IP주소와 TCP/UDP별로 각각 분류해서 시스템이 처리하는 트래픽의 대역폭을 계산하고자 합니다.

예를 들어서 아래와 같은 정보를 알고 싶은거죠...

eth0
10.1.1.1 ----> 100.1.1.1 TCP 3Mega
10.1.1.2 -----> 23.1.1.1 UDP 30Kbytes

eth1
1.1.1.1 ----> 2.2.2.2 TCP 20Mega
3.3.3.3 ----> 4.4.4.4 UDP 30Mega

디바이스 드라이버에 통계정보를 알아오는 함수가 있기는 한데(ifconfig 하면 출력되는 통계 값들), 프로토콜 별로 나눠서(위와 같이 IP주소별, UDP TCP별) 계산이 불가능하더군요...소스를 좀 들여다 봤더니 레지스터 값만 읽어오는 거라 단순히 하드웨어를 지나가는 byte수 혹은 패킷갯수정도의 수치만 알 수 있더라구요....

pcap library를 사용해서 하려는건 아니구요...
지금 대략적으로 2가지 방법을 생각하고 있는데요...

첫번째는 netfilter를 써서 패킷을 후킹한 후에 입출력되는 패킷들의 IP 주소와 프로토콜 필드등을 검사해서 계산을 하여 통계값을 작성하는 것이고

두번째는 rx/tx 인터럽트 걸렸을때, rx인 경우는 top half에서 입력된 패킷의 정보들을 분석해서 통계정보를 갱신하고, tx인 경우도 패킷을 송신하기 전에 정보들을 분석해서 통계정보를 갱신하려 합니다.

위와 같이 실시간으로 패킷들을 분석해서 통계값을 계산하는 것이 가능하기는 한건가요 ?
가능한 얘긴지...아니면 말도 안되는 얘긴지 알려주세요...

감사합니다.

꾸뻑....[/list]

hie의 이미지

먼저 가능합니다.

개인적으로 NETFILTER HOOK 메커니즘이 맘에 들지 않아
다른 방식으로 HOOK을 하여 통계를 작성했었습니다.
( 2.4.X 커널 사용 )

통계를 내기 위한 루틴때문에 발생하는 성능저하를 줄이는
방법을 생각해 보시구요~~ 방법은 매우 많이 존재하니
익숙한 혹은 자신있는 방식으로 구현하면 될듯..

NAT환경도 잘 생각해 보시면 정확한 통계를 쉽사리 구현
가능합니다.

그럼 즐프~~

swunk의 이미지

먼저 답변 감사합니다.

실례가 안된다면 님께서는 어떤 방식으로 구현 하셨는지 여쭤봐도 될까요 ?
혹은 아주 많은 방법들이 존재한다고 하셨는데 어떤 방법들이 존재하는 알 수 있을까요 ?

성능저하를 말씀하셨는데...넷필터로 수행하게 되면 어느정도의 성능저하가 발생하게 되나요 ?(너무 멍청한 질문인감?--;)

제가 걱정하는 부분은 성능저하도 성능저하지만...
초당 몇십메가에서 백메가 이상으로 (양방향)입출력되는 트래픽들을 하드웨어의 도움없이 계산가능하겠는가 ? 라는 부분입니다.

답변 주시면 감사하겠습니다.

그럼 꾸벅...

익명 사용자의 이미지

단순 카운터는 거의 라인스피트(line speed)에서 연산가능합니다.

침입탐지룰같이 좀 더 복잡한 연산을 수행하는 것은 다른 방법론이 필요하나,
위와 같이 단순한 카운터는 좀~ 좋은 하드웨어를 사용해서 하면... 됩니다.
위와 같은 정도라면, 성능문제는 언급할 필요도 거의 없어보입니다.
단지, 송신자/수신자의 페어별로 어떻게 자료구조를 잡을 것인가?라는 문제가 오히려 고민거리겠군요.

swunk의 이미지

Anonymous wrote:
단순 카운터는 거의 라인스피트(line speed)에서 연산가능합니다.

침입탐지룰같이 좀 더 복잡한 연산을 수행하는 것은 다른 방법론이 필요하나,
위와 같이 단순한 카운터는 좀~ 좋은 하드웨어를 사용해서 하면... 됩니다.
위와 같은 정도라면, 성능문제는 언급할 필요도 거의 없어보입니다.
단지, 송신자/수신자의 페어별로 어떻게 자료구조를 잡을 것인가?라는 문제가 오히려 고민거리겠군요.

말씀하신 단순 카운터라는게 단순히 패킷의 갯수만 카운트하는 작업을 말씀하신건가요 ? 그런 경우라면 레지스터값을 읽어오기만 하면 되기때문에 아무 문제가 없을것 같은데요...
질문에도 말씀드렸지만 패킷을 잡아다가 헤더내용을 분석하고 그 내용을 통계값으로 계산하려고 합니다.

시스템이 도는 동안 계속하려는건 아니고 예를 들어서 3초동안 감시하고 싶다고 하면 그동안 지나가는 패킷들을 분석하려고 합니다.
그런데 우려가 되는것이 양방향 100메가 정도 즉, 시스템에 200메가 정도의 트래픽을 흘려보면 지금 테스트하는 시스템에서는 cpu 성능을 거의다 잡아 먹고 있거든요...테스트해본 상황은 단순 라우팅기능만 수행한 경우입니다. 이러한 상황에서 위에서 말씀드린 추가적인 내용을 수행코자 하는데도...아무 문제가 없을까요 ?

cpu 한 클럭에만도 패킷이 수십,수백개가 들어오고 나갈텐데 지금 해당하는 패킷을 처리하고 있는 중간에 패킷이 계속들어오고 그럴텐데 해당 프로세싱을 처리하는게 가능할지가 의문이라서 드리는 질문입니다.

그럼 답변 부탁드립니다.

꾸벅....

익명 사용자의 이미지

게이트웨이 장비에서 유통량을 측정하겠다는 것인가요?

무슨 이유가 있겠지만, 양의 측정을 위해 게이트웨이 장비 본연의 처리를 위한 성능의 감소를 감수할 수 밖에는 없을텐데. 그정도 가치가 있는 일인지는 모르겠습니다.
보통 유통량의 측정은 게이트웨이 장비(예. CISCO의 NetFlow)에서도 행해지지만, NTOP과 같이 패시브(비 게이트웨이장비)모드로 동작하는 경우도 있습니다. 또한, 디바이스 드라이버 및 QoS를 위한 모듈들도 이를 일부 포함하고 있습니다.

게이트웨이 장비에서 측정할 경우, 패킷의 정보추출을 위한 처리와 패킷 포워딩을 위한 처리를 둘다 해야 함으로써 보다 많은 프로세싱 파워와 버스사용을 필요로 하게되고, 이를 위한 로직의 에러는 네트워크 마비로 이어질 수 있습니다.
반면 패시브 장비에서 측정할 경우, 패킷의 정보추출을 위한 처리만이 존재하게 됨으로써 보다 유리한 면이 있습니다.

단순한 카운터라고 한것은 패킷의 컨텐츠를 보는(IDS, IPS를 염두)것이 아닌 헤더 정보(IP,TCP헤더등)만을 보는 경우를 의미했습니다. 물론 이경우에도 버스 스피드의 능력 및 NIC의 디바이스 드라이버 처리방식(폴링/인터럽트)에 따라 그 성능의 차이를 보입니다. 소위 PCI(PCI-X등)버스의 스피드도 고려하게 된다는 것이지요.
또한 인터럽트에 기반해서 네트워크 디바이스 드라이버가 되어 있다면, 이는 가장 느린(사이클이 긴) 머신 연산인 인터럽트 연산으로 CPU를 매우 빈번하게 사용하게 됨으로써, FastEthernet(100M)정도의 트래픽 처리에도 버거울 수 있습니다. 따라서, 이 경우에는 인터럽트에 기반한 디바이스 드라이버를 사용하지 않는게 좋습니다. 당근, 폴링이지요. 이는 10여년전부터의 추세이기도 합니다.
또는, 가격문제가 있겠으나, NPU를 채택하는 것도 방법입니다.

그러나, 이러한 성능해결 방법론보다는 제가 보기에 현시점에서는,
패킷이 NIC에 도착하고 이를 비교연산하기 위해 메모리로 복사하고, 처리 결과를 특정 자료구조에 저장/갱신/출력하는 루틴의 완성이 보다 중요해 보입니다.

단지 가능성 타진이라면 가능하다 라고 말씀드리는 바입니다. 단지, PC라면 좀 ~ 좋은 ...컴퓨터를 써야 겠지요. 한 100만원(??)넘는... --;

swunk의 이미지

Anonymous wrote:
또한 인터럽트에 기반해서 네트워크 디바이스 드라이버가 되어 있다면, 이는 가장 느린(사이클이 긴) 머신 연산인 인터럽트 연산으로 CPU를 매우 빈번하게 사용하게 됨으로써, FastEthernet(100M)정도의 트래픽 처리에도 버거울 수 있습니다. 따라서, 이 경우에는 인터럽트에 기반한 디바이스 드라이버를 사용하지 않는게 좋습니다. 당근, 폴링이지요. 이는 10여년전부터의 추세이기도 합니다.
또는, 가격문제가 있겠으나, NPU를 채택하는 것도 방법입니다.

먼저 답변 감사드립니다.
왜 인터럽트 방식보다 폴링 방식이 더 성능이 좋은가요? 게이트웨이 장비라고 해도 패킷의 송수신은 비동기적으로 발생할 것이고 항상 트래픽이 많이 흐른다는 보장도 없기때문에 인터럽트 방식이 더 유리할것 같은데요...음...솔직히 폴링 방식으로 처리한다는게 잘 이해가 되지 않는데 조언좀 부탁드려도 될까요?

그리고 NPU라고 하신거는 Network Processor를 말씀하시는건 가요? 안그래도 성능측정을 해 본결과 너무 저조해서 NP를 하다 달려고 합니다. (지금 개발하고 있는 시스템이 단순 게이트웨이 역할만 하는것은 아니거든요...) 지금 생각으로는 IXP425정도 생각하고 있는데요...여기에 대해서도 조언을 주실 수 있으면 부탁드리겠습니다.

제가 확인해본 바로는 IXP425에서 메인코어는 xscale533(셀러론 533과 유사..)정도인데 이더넷 트래픽을 흘려서 비교를 해보면 팬티엄 1기가 이상보다 성능이 더 잘나오더군요. 특히나 cpu의 점유율은 생각했던것 이상으로 차이가 나더라구요...(고놈참...)

Anonymous wrote:
그러나, 이러한 성능해결 방법론보다는 제가 보기에 현시점에서는,
패킷이 NIC에 도착하고 이를 비교연산하기 위해 메모리로 복사하고, 처리 결과를 특정 자료구조에 저장/갱신/출력하는 루틴의 완성이 보다 중요해 보입니다.

단지 가능성 타진이라면 가능하다 라고 말씀드리는 바입니다. 단지, PC라면 좀 ~ 좋은 ...컴퓨터를 써야 겠지요. 한 100만원(??)넘는... --;

조언 감사합니다.

익명 사용자의 이미지

* 아시다시피, 인터럽트는 CPU가 IO에 신경을 덜 쓰고(IO가 상대적으로 빈도가 낮다는 가정), 수치및논리연산에 최대한의 시간을 소모하도록 고안된 메카니즘입니다.
인터럽트는 비동기적으로 발생하므로, 인터럽트요구에 대한 처리를 위해, CPU는 많은정보를 대피시켜야하고 인터럽트 처리후 많은 정보를 복구해야하는 부담을 가지고 있습니다. 그리고, IO는 아주 미미하다는 가정에서 이는 좋은 메카니즘이었습니다.
그러나, 범용시스템이 아닌 특별한 시스템들, 특히, 네트워크 장비등 IO집약적인 장비, 는 주 작업이 연산이라기 보다는 IO입니다. 즉, 패킷 받아서 넘기는게 주된 연산이 되겠습니다.
중간에 경로계산이라던지를 약간(?)하겠지만요. 대부분은 IO가 되겠습니다.
또한 IO가 매우 빈번합니다. 똑똑똑...누구 왔나 가보자!가 아니라..... 대문활짝열고, 당연히 누구 왔다...,즉, 안가봐도 안다는 얘기지요.
그래서, 이러한 경우에는 CPU의 시간을 IO에 집중하도록 하는게 나을 수 있습니다. 각 레지스터 대피시키고, 복구시키고, 이를 패킷단위(?)로 하지말고 아예 그냥 미리 가서 처리하는 것이지요. 아예 CPU타임의 일부를 이를 위해 미리 배정하도록 한다고 할까요?
그렇게 하기 위해서는 zero copy, polling, napi등의 기술이 사용됩니다. 이를 이용해서 디바이스 드라이버를 만드는 것이지요.

이를(특히, 폴링+버퍼링으로 성능개선한...) ....한 좋은 페이퍼가 있어서 소개해드리면, Improving Passive Packet Capture: Beyond Device Polling - Luca - 인데, http://luca.ntop.org/Ring.pdf 입니다.

* NPU(Network Processor Unit)는 좋~습니다. 일단... 가격, 유지보수, 호환성이 가장 변수겠지요. 그외, 목적(ids/ips rule, 웜, 메일, 바이러스등)에 따라 Content processor등도 함께 고려하실 수 있으리라고 보입니다.

** 좋은 프로그램 만드세요.

swunk의 이미지

조언주셔서 고맙습니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.