فهرست مطالب
مقدمه
دستور tcpdump ابزاری برای کپچر و فیلتر بستههای شبکه در سیستمعاملهای مبتنی بر یونیکس و لینوکس استفاده میشود. در این مقاله، به نحوه استفاده از دستور و تمامی سوییچ های مهم و در نهایت به تحلیل اصطلاحات گزارش خروجی آن میپردازیم.
تحلیل ترافیک خروجی دستور، نیامند مقاله دیگری میباشد که در این قسمت به آن پرداخته نمیشود. این آموزش برای افرادی مناسب میباشد که آشنایی کلی با مباحث شبکه دارند.
روند شبکه در لینوکس به این روال است که Packet ها به NIC میرسد. NIC خودش Buffer دارد به همین خاطر درون آن ذخیره میکند. اگر که به دلیل سرریز شدن آن Buffer درواقع Packet ها Drop شوند، هیچ راهی ندارد که ما از آن خبردار شویم.
Buffer Size مربوط به NIC ها متفاوت میباشد. به نظر میاد NIC های Desktop های امروزی که 1 Gbps هستند، Buffer Size آنها یه چیزی بین 32 KB تا 256 KB متفاوت باشد. به طور مثال با سرعت 1 گیگابیت بر ثانیه، حدوداً 2 میلی ثانیه طول میکشد تا اینکه یک Buffer درواقع 256 کیلوبایتی پر شود. درواقع سرریز شدن این Buffer به دلیل این اتفاق میافتد که CPU فرصت مناسب برای Interrupt های NIC را ندارد.
پس از اینکه Kernel سیستم عامل از NIC خواند. حال در اینجا کتابخوانه ای به نام libpcap معرفی میشود که برای Capture کردن Packet ها میباشد. این کتابخوانه از سیستم عامل بسته های خام شبکه را دریافت میکند. نرمافزار tcpdump با استفاده از libpcap این کار را انجام میدهد.
دستور
Syntax آن چنین است:
tcpdump [OPTION] [EXPRESSION]
OPTION های مهم:
--interface
-i
مشخص میکند که روی چه Interface ای باید گوش کند. اگر any نوشته شود، روی همهی Interface ها گوش میکند.
-n
آدرسهای IP را به Domain درواقع Resolve نمیکند. سعی کنید همیشه این گزینه را بگذارید وگرنه خیلی کند میشه عملیات Capturing شما.
-l
به صورت پیشفرض Packet ها توسط در Buffer مربوط به libpcap ذخیره میشوند (که به همان Kernel Buffer معروف میباشد) و سپس به tcpdump میرسد که آن را چاپ کند. اما اگر این Option را استفاده کنیم که مخفف Line Buffered میباشد، باعث میشود که انتهای هر Line ای که به Buffer میرود، سریعاً به tcpdump ارسال کند.
--packet-buffered
-U
به صورت پیشفرض Packet ها توسط در Buffer مربوط به libpcap ذخیره میشوند (که به همان Kernel Buffer معروف میباشد) و سپس به tcpdump میرسد که آن را چاپ کند. اما اگر این Option را استفاده کنیم، باعث میشود که انتهای هر Packet ای که به Buffer میرود، سریعاً به tcpdump ارسال کند.
--immediate-mode
به صورت پیشفرض Packet ها توسط در Buffer مربوط به libpcap ذخیره میشوند (که به همان Kernel Buffer معروف میباشد) و سپس به tcpdump میرسد که آن را چاپ کند. اگر این Option را تنظیم کنیم، باعث میشود که Packet ها Buffer نشوند و مستقیماً به خروجی tcpdump برود که نتیجتاً کمترین Latency را خواهیم داشت.
--buffer-size
-B
به صورت پیشفرض Packet ها توسط در Buffer مربوط به libpcap ذخیره میشوند (که به همان Kernel Buffer معروف میباشد) و سپس به tcpdump میرسد که آن را چاپ کند. حال اگر که این Option را به کار ببریم، اندازه Kernel Buffer را به KiB (Kebi Byte) تعیین میکند.
-t
به صورت پیشفرض Timestamp برای هر Packet چاپ میشود. با این Option این کار اتفاق نمیافتد.
--snapshot-length SNAPSHOT_LENGTH
-s SNAPSHOT_LENGTH
به صورت پیشفرض حداکثر تا 262144 Bytes از هر Packet خوانده خواهد شد. با این Option میتوان تنظیم کرد که چند Byte باید خوانده شود.
-v
همهی اطلاعات بسته در حالت پیشفرض نمایش داده نمیشود. با اضافه کردن این Option، شما از جزئیات بیشتری برخوردار خواهید شد. در نظر داشته باشید که خروجی این Option باعث میشود که اطلاعات مربوط به هر Packet در دو خط چاپ شود. یکسری اطلاعات در خط اول و یکسری اطلاعات در خط دوم قرار میگیرد. در نظر داشته باشید که هر دو خط دارای Field ای به نام length میباشد. در خط اول length مربوط به اندازه کل IP Packet میباشد و length در خط دوم مربوط به اندازه IP Payload میباشد.
-w FILE
بسته ها را در FILE ذخیره میکند به جای اینکه نمایش دهد. بسته ها به صورت Buffer شده در File قرار خواهند گرفت.
-r FILE
بسته های ذخیره شده از FILE را میخواند.
--no-promiscuous-mode
-p
اجازه نمیدهد که interface در حالت promiscuous اجراء شود اگر که از قبل تنظیم شده بوده که در این حالت اجراء شود.
-A
محتویات هر بسته را در ASCII چاپ میکند (به غیر از Link Level Header)
-c COUNT
بعد از Capture کردن COUNT تا Packet ، از برنامه خارج میشود.
-F FILE
باعث می شود از FILE در واقع EXPRESSION ها را بخواند به جای اینکه جلوی دستور آنها را وارد کنیم. اگر جلوی دستور EXPRESSION ای وارد شود، نادیده گرفته خواهد شد.
-XX
به غیر از نمایش Header بسته ها، خود محتویات را در قالب Hex و Ascii نمایش میدهد.
حال در اینجا Expression های مهم را مرور میکنیم ولی همه ی آن ها در man pcap-filter موجود می باشند:
dst host HOST(IP_OR_DOMAIN) # dst host 192.168.1.100 OR dst host google.com
src host HOST(IP_OR_DOMAIN) # src host 192.168.1.100 OR src host google.com
host HOST(IP_OR_DOMAIN) # host 192.168.1.100 OR host google.com
dst net NETWORK(IP_WITH_CIDR) # dst net 127.0.0.0/8
src net NETWORK(IP_WITH_CIDR) # src net127.0.0.0/8
net NETWORK(IP_WITH_CIDR) # net 127.0.0.0/8
dst port PORT # dst port 22
src port PORT # src port 22
port PORT # port 22
dst portrange PORT_RANGE(START-END) # dst portrange 1000-2000
src portrange PORT_RANGE(START-END) # dst portrange 1000-2000
portrange PORT_RANGE(START-END) # dst portrange 1000-2000
PROTOCOL_NAME(tcp, udp, icmp, ip, ip6, ...) # tcp
ip proto PROTOCOL_DECIMAL_NUMBER # 6 (TCP)
ip6 proto PROTOCOL_DECIMAL_NUMBER # 6 (TCP)
proto PROTOCOL_DECIMAL_NUMBER # 6 (TCP)
ether dst eHOST(MAC) # 00:11:22:33:44:55
ether src eHOST(MAC) # 00:11:22:33:44:55
ether host eHOST(MAC) # 00:11:22:33:44:55
میتوان چند Expression را با Operator های زیر Combine کرد:
A parenthesized group of primitives and operators.
Negation (`!' or `not').
Concatenation (`&&' or `and').
Alternation (`||' or `or').
چند خط خروجی اول tcpdump شامل توضیحات درباره برخی Option هایی که tcpdump با آنها اجراء شدهاند میباشد. این خطوط در stderr قرار میگیرند. سپس خطوط مربوط به Packet ها آغاز میشود و پس از Terminate کردن برنامه نیز سه گزارش زیر نمایش داده میشود:
X packets captured
X packets received by filter
X packets dropped by kernel
packets captured نشان دهنده تعداد Packet هایی میباشد که Capture و پردازش برای نمایش به شما شده است. این عدد با تعداد Packet هایی که در خروجی مشاهده میکنید یکی است.
packets received by filter میتواند نشان دهنده تفاسیر مختلفی در سیستم عامل ها باشد. ولی به نظر میاد تعداد Packet هایی میباشد که در libpcap Buffer موجود میباشد و هنوز توسط libpcap خوانده نشدهاند که به دست tcpdump برسد و یا اینکه توسط libpcap خوانده شده است ولی هنوز به دست tcpdump نرسیده است.
Packets dropped by kernel نشان دهنده تعداد Packet هایی میباشد که به خاطر کمبود فضای Kernel Buffer درواقع tcpdump مجبور میشود آنها را Drop کند. طبیعتاً وقتی سرعت پر شدن Buffer از سرعت پردازش Packet ها بیشتر باشد، این اتفاق میافتد. برای اینکه Packet ای Drop نشود، بهتر است اندازه Buffer را بیشتر کنید و همچنین از Option -n استفاده کنید تا Resolve کردن اتفاق نیافتد. همچنین میتوانید از Option -s نیز استفاده کنید تا فقط قسمتهایی که میخواهید را Capture کنید و نه بیشتر.