LINUX GAZETTE
...리눅스를 좀 더 재미있게!
TCPdump와 Tethereal과 함께 TCP/IP 탐험
By Vinayak Hegde

한글번역 전정호

이 글은 한글번역판입니다. 원문은 여기에서 볼 수 있습니다.

가장 짧은 TCP/IP 소개

TCP/IP는 컴퓨터통신에 사실상 표준 프로토콜이 되었다. IP는 (Internet Protocol) 네트웍층(주소와 라우딩) 기능을 제공하고, TCP는 (Transmission Control Protocol) 통신하는 양쪽 끝사이에 (가상의) 연결을 만든다. TCP/IP에는 이외에도 ICMP (Internet Control Message Protocol), IGMP (Internet Group management protocol), UDP (User Datagram Protocol) 같은 여러 유용한 프로토콜들이 있다. 오늘날 거의 대부분의 네트웍이 TCP/IP를 사용한다. 오늘날 많은 프로그램들이 네트웍 기능을 포함하기때문에, 프로그래머라면 최소한의 TCP/IP 지식을 가질 필요가 있다.

컴퓨터들은 서로 패킷(packet)을 교환하여 TCP/IP 통신을 한다. IP 수준에서 패킷을 PDU (Protocol Data Unit)라고 한다. TCP 수준에서 PDU를 세그먼트(segment)라고 하고, (이더넷(Ethernet) 등) 데이터링크(data-link)층에서는 PDU를 플레임(frame)이라고 한다. 그러나 일반적으로 패킷이란 용어는 TCP/IP층간에, 또 두 컴퓨터간에 교환되는 자료 단위를 지칭한다.

이더넷 플레임은 다음과 같다:

	+------------------------------------------------------------------+	
	|	  |		|		|		|	   |	
	|  이더넷  |     IP  	|     TCP	|  포함하는    	|  이더넷   |	
	|  헤더    |     헤더   	|     헤더   	|    자료  	|  말단     |	
	|         |		|		|		|  (FCS)   |	
	+------------------------------------------------------------------+	
		  <- 20 바이트 -> <- 40 바이트 ->					
					
	  	  <----------  최대 길이 = 1500 바이트  ---------->
	
			FCS는 Frame Check Sequence를 뜻한다.
	

TCPdump와 Tethereal

TCPdump는 네트웍장치를 통과하는 패킷을 가로채서 사용자에게 보여주는 도구다. 프로그래머가 네트웍 프로그램을 손볼때 사용하는 작고 매우 유용한 도구다. 이 도구가 네트웍장치가 받은 모든 패킷을 잡기때문에 불법적인 용도에도 사용될 수 있다.

보통 주소가 해당 네트웍장치를 지칭하는 패킷만이 TCP/IP 프로토콜 상위층에 올라간다. 그 장치에 해당하지않는 패킷들은 무시한다. 그러나 Promiscuous 모드는 그 장치가 받지않을 패킷까지 잡아서 프로토콜 상위층으로 보낸다. TCPdump는 네트웍장치를 promiscuous 모드로 동작한다.

TCPdump는 자유롭게 공개된 (패킷 잡는 라이브러리) libpcap을 사용한다. libpcap 라이브러리는 다용도로, BSD 패킷 필터, SVR4 Data-link Provider Interface (DLPI), 리눅스 SOCK_PACKET 인터페이스와 동작할 수 있다. 인기있는 네트웍 분석도구 ethereal의 명령행 버전인 Tethereal도 패킷 잡는 라이브러리 pcap을 사용한다. Tethereal은 네트웍 통행을 분석하고, TCPdump와 달리 패킷을 해석하는 기능이 있는 강력한 도구이다. 패킷을 분석하는 GUI 도구인 Ethereal은 매우 좋은 도구로, 계층적인 방식으로 패킷의 여러 플래그와 옵션을 보여준다. ethereal의 가장 좋은 기능은 두 컴퓨터간 통신의 여러 조각을 붙여서 통신중에 교환한 전체 ASCII 내용을 보여주는 점이다.

TCP와 IP 패킷 형식

RFC 791 에서 가져온 ASCII 표현

    0                   1                   2                   3   
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 	    
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+	
   |Version|  IHL  |Type of Service|          Total Length         |	
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+	
   |         Identification        |Flags|      Fragment Offset    |	
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+	
   |  Time to Live |    Protocol   |         Header Checksum       |	
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+	
   |                       Source Address                          |	
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+	
   |                    Destination Address                        |	
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+	
   |                    Options                    |    Padding    |	
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+	
									
			IP 헤더 형식        				

RFC 793 에서 가져온 ASCII 표현

    0                   1                   2                   3   	
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1	 
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+      
   |          Source Port          |       Destination Port        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                        Sequence Number                        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                    Acknowledgment Number                      |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |  Data |           |U|A|P|R|S|F|                               |
   | Offset| Reserved  |R|C|S|S|Y|I|            Window             |
   |       |           |G|K|H|T|N|N|                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |           Checksum            |         Urgent Pointer        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                    Options                    |    Padding    |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                             data                              |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

                            TCP 헤더 형식         

TCPdump와 Tethereal을 사용하여 패킷을 잡는 예

TCPdump는 네트웍에 연결된 어떤 인터페이스에도 사용할 수 있다. 시스템에 연결된 인터페이스 목록을 보려면 다음 명령을 실행한다

#ifconfig -a				

그러면 loopback 인터페이스를 포함하여 시스템에 연결된 모든 네트웍 인터페이스 목록을 출력한다. 전화선으로 네트웍에 연결했다면, TCPdump에 ppp0 인터페이스를 사용하여 프로그램을 테스트하고 디버깅할 수 있다.

예제 #1
다음은 전화선을 (PPP) 사용하여 패킷을 잡는 (파일 tcpdumpppp로) 예이다. -vvv 옵션은 tcpdump의 출력을 매우 자세하게 만든다. 자세함을 조절하는 다른 옵션에는 -v 와 -vv 가 있다.

#tcpdump -vvv > tcpdumpppp		
tcpdump: listening on ppp0		

CTRL-C를 누르면 패킷을 그만 잡는다.

15:57:58.181078 207.219.33.101.http > 203.94.236.47.33003: P 1:1399(1398) ack 736 win 31856  (DF) [tos 0x10]  (ttl 38, id 28827, len 1450)

위의 패킷 출력에서 다음과 같은 정보를 얻을 수 있다

예제 #2
다음은 (eth0로 지칭하는 인터페이스) NIC에서 잡은 패킷 출력이다

#tcpdump -a -i eth0		


06:21:11.414863 > pca03.nt.co.in.ssh > pcc03.mum.nt.co.in.4944: P 252143283:252143331(48) ack 2638534821 win 62780 (DF) [tos 0x10] 

			  E^P ^@ X ....  @^@  @^F .. N .... ....
			 .... .... ^@^V ^S P ^O^G  f.. .. D ....
			  P^X .. < .. t ^@^@  k +  Y^Q .... .. (
			  ^..  )^G  c 3 ^\ v  t.. ..^G ^J.. .. t
			  9.. .. -  F.. ....  6..  /.. ....  9..
			  [.. ....  G.. .. d
(-a) 가능하면 IP로 도메인명을 찾고, 명확하게 eth0 인터페이스에서 패킷을 잡는다고 지시했다. (-i) 옵션을 주지않으면 TCPdump 스스로 인터페이스를 찾아서 모든 인터페이스에서 패킷을 잡는다. 위의 패킷 출력에서 얻을 수 있는 정보는 다음과 같다:-

예제 #3

다음은 SYN (연결요청) 패킷의 출력이다 이 패킷은 이더넷에서 잡았다.

15:57:56.074928 203.94.236.47.33003 > 216.239.33.101.http: S [tcp sum ok] 937694521:937694521(0) win 5840  (DF) (ttl 64, id 54537, len 60)

위에서 다음과 같은 정보를 알 수 있다:-

예제 #4
tethereal을 사용하여 잡은 패킷 출력이다

#tethereal -i lo		


26  19.624878 localhost.localdomain -> localhost.localdomain TCP 33283 > http [FIN, ACK] Seq=877643253 Ack=882239950 Win=37296 Len=0

tethereal의 출력은 TCPdump와 비슷하다. 이 경우는 (연결을 닫으려는) FIN,ACK 패킷이다. Tethereal을 프론트앤드 ethereal과 같이 사용하면 네트웍 이상을 발견하는데 매우 유용하다.

마치는 말

TCPdump는 매우 좋은 도구지만 TCP/IP 프로토콜만을 처리한다. 이 도구는 이 작업을 매우 잘 한다. Ethereal은 매우 기능이 많으며 여러 프로토콜을 이해할 수 있다. 또, ethereal의 사용자 인터페이스는 잘 설계되어, 초보자도 잡은 패킷과 패킷에 든 정보를 이해할 수 있다. 좋은 인터페이스로 더 즐겁게 배울 수 있다.

참고자료

 

[BIO] 내 인생은 리눅스를 만나고 달라졌다. 갑자기 컴퓨터가 흥미로워졌고, 소스코드를 쉽게 얻을 수 있기때문에 리눅스에서 많은 일들을 시도해볼 수 있었다. 나는 네트웍, 임베디드 시스템, 프로그래밍언어에 관심이 매우 많다. 나는 현재 Aparna Web services에서 학교나 기업에서 원격 부트 스테이션(Thin Clients)으로 리눅스를 사용할 수 있게 하는 일을 하고 있다.


Copyright © 2003, Vinayak Hegde. Copying license http://www.linuxgazette.com/copying.html
Published in Issue 86 of Linux Gazette, January 2003