'Linux'에 해당되는 글 7건

  1. 2010/12/13 AWK vs SED
  2. 2009/07/30 TCP 자세히 보기
  3. 2009/01/07 sed를 이용한 highlight
  4. 2009/01/07 쉘에서 실행한 명령을 syslog로 자동 보내기
  5. 2008/08/19 iptables
  6. 2008/08/18 Tcpdump란?
  7. 2008/08/16 grep으로 검색된 문자에 색 넣기(highlight)
2010/12/13 13:20

AWK vs SED


awk 'BEGIN{ "date" | getline d ; print d}'
2010. 12. 01. (수) 13:10:25 KST
awk 'BEGIN{ "date" | getline d ; split(d, mon); print mon[2]}' 
12.

awk '$2 ~ /192/' arp => arp 에서 2번째가 192 인 행 출력
awk '$2 !~ /192/' arp => arp 에서 2번째가 192 아닌 행 출력

awk '{max=($1>$2)?$1:$2; prin $max}; filename


awk -F. '{ if ( $1 > 172 ) print $1, "high" ; else print $1, "too low" }' acl


cat katuri | grep -B 10 "192.168.25" | egrep "policy|--" | grep -B 1 "\-\-"  | grep -v "\-\-"


awk '{ for ( a=1 ; a<=NF ; a++ ) print $a } {OFS="\n"}' intra_nslist

평균값 = egrep "^09|^1[0-7]" 17.txt | awk '{print $4}' | awk '{ print (s += $1)/270 }' | tail -n 1
최대값 = egrep "^09|^1[0-7]" 17.txt | awk '{print $5}' | sort | tail -n 1
최소값 = egrep "^09|^1[0-7]" 17.txt | awk '{print $5}' | sort -r | tail -n 1

예를 들어 내용이 삽입되기 원하는 위치가 10번째 줄이면

sed -i '10izend_optimizer.optimization_level=1023' /usr/local/lib/php.ini

----------------------------

sed 's/preempt/preempt\
shit/g' hsrp | more

sed -e '/192.168.7.14/{h; }' -e '{ $G; }' arp

192.168.7.14 매칭 되는 줄을 맨 마지막 줄에 추가 (cf. g 는 마지막 줄 변경

 sed -e '/192.168.7.14/{h; d;}' -e '{ $G; }' arp

192.168.7.14 매칭 되는 줄을 맨 마지막 줄에 추가 (cf. g 는 마지막 줄 변경 , d; 는 매칭 줄 삭제, x 치환

\a 다음줄에 추가
\i 윗줄에 추가
\c 변경

Trackback 0 Comment 0
2009/07/30 10:18

TCP 자세히 보기

TCP 자세히 보기

윤 상배

dreamyun@yahoo.co.kr

고친 과정
고침 0.8 2004년 5월 12일
Contro Bits 내용보강, sequence number 내용 보강, 이미지 수정

1. 소개

우리는 IP 자세히보기 를 통해서 IP 프로토콜을 헤더차원에서 살펴보았다. 이번 문서에서는 TCP 프로토콜을 헤더차원에서 살펴보도록 할것이다.


2. TCP (Transmission Control Protocol)

2.1. TCP 란

TCP 개념에 대해선 이미 몇개의 문서를 통해서 다루어지긴 했지만 확인차원에서 다시한번 다루어 보도록 하겠다.

TCP 는 기본적으로 IP 와 함께 사용되며, 그런이유로 TCP/IP 라고 불리워진다. IP는 호스트 사이의 데이타 교환을 목적으로 만들어진 프로토콜인데, 기본적으로 IP는 오로지 데이타 교환을 위한 임무만을 수행한다. 즉 네트웍상에서 발생할수 있는 데이타 누락, 패킷의 순서 뒤바뀜 등의 데이타 교정과 관련된 기능을 가지고 있지를 않다.

그래서 만들어 진개 TCP 프로토콜이다. IP 프로토콜의 상위 레벨 프로토콜로써, IP가 제공하지 못하는 기능즉, 데이타 누락검사 패킷순서 뒤바뀜 등 데이타 교정과 관련된 기능을 제공한다.

 +---+----+-------------+
 |IPH|TCPH|Internet Data| 
 +---+----+-------------+

 IPH           : IP Header
 TCPH          : TCP Header
 Internet Data : 교환하고자하는 데이타
			
이러한 TCP 의 기능상 특징으로 인하여 흔히 TCP 프로토콜을 "신뢰성있는 프로토콜" 이라고한다. TCP 는 이러한 신뢰성 있는 데이타 전송을 위한 방법으로 서버와 클라이언트간에 연결을 설정한다. 이러한 연결을 만드는 특성으로 TCP 프로토콜은 "연결지향 프로토콜" 이라고 말한다.

그림 1. 전 이중통신 선로

TCP 는 이러한 연결을 설정시 위에서의 그림에서와 같은 "전 이중 통신 선로"를 개설한다. 하나는 읽기 전용의 선로이며, 다른 하나는 쓰기 전용의 선로로써, 각각의 전용선로를 이용함으로 써 읽기와 쓰기를 동시에 할수 있게 된다. 이것은 Unix 에서 IPC 목적으로 pipe 를 생성할때, 읽기와 쓰기전용의 파이프를 동시에 생성하는것과 동일한 원리이다.

TCP 헤더에는 위의 TCP 의 특성을 충족시켜주기 위한 여러가지 기능을 가지는 필드들로 구성되어 있다. 우리는 다음장에서 TCP 헤더의 이러한 필드들을 분석함으로써, 어떻게 TCP 가 서버 클라이언트간 연결을 만들고, 신뢰성 있도록 데이타를 전달하는지 알아보게 될것이다.


2.2. TCP 헤더 구조

TCP 는 다음과 같은 헤더 구조를 가진다. 두 호스트 사이에 전송되는 TCP 데이타 단위를 세그먼트라고 부른다. 그러므로 TCP 세그먼트는 TCP 헤더 + DATA 가 될것이다. 다음은 TCP 세그먼트의 구조이다.

그림 2. TCP 헤더 구조


2.2.1. SOURCE PORT/DESTINATION PORT

source port 는 메시지를 보내는 측에서 통신을 위해 사용하는 port 번호이며, destination port 는 목적지, 즉 메시지를 받는측의 통신 port 번호이다.

여기에 있는 port 번호와 더불어 IP 헤더에 있는 source/destination address 를 이용하면 유일하게 식별되는 통신연결을 만들수 있게 된다.

아마도 IP 의 출발지/목적지 주소와 TCP 헤더의 출발지/목적지 포트 번호가 어플리케이션간 통신을 위한 가장 핵심이라고 할수 있을것이다. 다른 정보들은 통신을 원할하도록 도와주기 위해서 부가적으로 존재하는 것이라고 볼수 있다.

이들 포트번호의 크기는 16bit 크기를 가진다. 그러므로 대략 65536 만큼의 포트를 가질수 있을것이다.


2.2.2. SEQUENCE NUMBER

TCP 세그먼트안의 데이터의 송신 바이트 흐름의 위치를 가리킨다. 다른 호스트로 전달되는 패킷은 여러개의 서로 다른 경로를 거치면서 전달되다 보니 패킷의 순서가 뒤바뀔 수 있다. 이를 수신측에서는 재 조립해야할 필요가 있는데, Sequence Number 를 이용해서 조립하게 된다.


2.2.3. ACK

acknowledgment number 라고 말한다. 다음에 받을것으로 예상되는 데이타 옥텟의 순서번호를 나타낸다.


2.2.4. HLEN

TCP 세그먼트의 길이를 정의한다.


2.2.5. RESERVED

현재는 사용하지 않지만, 나중을 위해서 예약된 필드이다.


2.2.6. (Control)CODE BITS

세그먼트의 용도와 내용을 결정하기 위해서 사용된다. URG, ACK, PSH, RST, SYN, FIN 6개의 비트가 정의되어 있다. TCP는 이러한 비트를 이용해서 패킷의 내용이 어떤 목적으로 전달될 것인지를 설정할 수 있다. 이들 비트중 SYN, ACK, RST를 주목할 필요가 있다.

SYN은 TCP연결을 만들 때, 양 호스간 sequence numbers의 동기화를 이루기 위한 목적으로 사용된다. ACK는 원격 호스트의 sequence number에 대한 응답을 위한 목적으로 사용된다. 즉 데이터를 잘 받았다는 걸 알려주기 위한 목적으로 사용되는데, 원격호스트의 sequence number의 번호에 +1을 해줘서 다시 전달하는 방법을 이용한다. SYN 비트는 특히 세번 악수 기법(three-way handshake)를 위해서 사용된다.

RST 비트가 설정되어 있을 경우 받은 호스트는 즉시 연결을 끊어 버리고 FIN 비트가 설정되어 있을 경우 여러가지 테스트를 거쳐서 연결을 끊게 된다. 일반적인 정상종료를 원한다면 FIN 비트를 설정해서 사용하게 된다. 이들 비트에 대한 자세한 내용은 2.3.3절를 참고하기 바란다.


2.2.7. OPTION & PADDING

옵션은 말그대로 옵션이다. TCP 헤더의 정보를 좀더 확장시키고자 할때 사용한다. PADDING 은 32bit 크기를 채우기 위해서 사용된다.


2.2.8. CHECKSUM

TCP 세그먼트 데이타는 중간에 훼손될수 있으며, 변조될수도 있다. 그러므로 이를 체크할수 있는 장치가 필요하다. CHECKSUM 을 만드는 방법(알고리즘)은 기회가 되면 별도로 설명하도록 하겠다.



2.3. 실제 통신상에서 TCP 패킷의 내용을 살펴보자

위에서 각 TCP 필드에 대한 설명을 해보았지만, 솔직히 위의 정보만을 가지고는 뭐가 뭔지 도대체 알수가 없을 것이다. 그래서 이번에는 실제 TCP/IP 통신이 어떻게 이루어지는지에 대해서 알아보고 이러한 통신이 이루어지도록 어떻게 TCP/IP 패킷(세그먼트)가 전송되어지는지 알아보도록 하겠다.


2.3.1. 테스트 프로그램 준비

셈플로 알아보는 소켓프로그램 에서 제작한 적이 있는 우편번호 서버/클라이언트 프로그램을 이용해서 테스트 하도록 할것이다. 서버 프로그램의 이름은 zipcode 이며 클라이언트 프로그램의 이름은 zipcode_cl 이다.

이와 더불어 tcp/ip 패킷분석을 위해서 tcpdump 를 사용할것이니 준비해놓기 바란다. (아마도 기본 설치되어 있겠지만)


2.3.2. 테스트 방법

테스트를 가장 효과적으로 수행하기 위해서는 서버와 클라이언트가 별도의 네트웍에 묶여 있는게 가장 좋겠지만, 여의치 않을경우 하나의 서버에 서버와 클라이언트를 두고 테스트를 해도 관계 없다.

여기에서의 테스트는 서버와 클라이언트가 별도의 네트웍환경에 묶여있는 것을 기준하여 이루어질것이다.

그림 3. 서버/클라이언트 테스트 환경

Server 은 Port 번호 4445 로 연결하도록 할것이다.


2.3.3. 서버와 클라이언트간의 연결

TCP 는 기본적으로 연결지향의 프로토콜이라고 했다. 이말은 처음 통신을 하기 전에 서로를 연결하는 전용의 통신선로를 개설한다라는 말이 된다. 이는 우리가 전화를 할때

홍길동 : "여보세요 아무개 씨 맞습니까 ?"
아무개 : "내 아무개 입니다."
홍길동 : "아그러세요 저는 홍길동 입니다"
...
.... 이런 저런 대화들 ....
...
				
실제 대화를 하기 위해서 서로간에 확인절차를 거치는 것과 마찬가지다.

TCP 도 통신선로를 만들기 위해서 처음에 이러한 확인 절차를 거친다. 우리가 보통 전화상에서 서로의 확인 작업을 위해서 3번 통화가 이루어지는 것처럼 TCP 상에서도 3번의 데이타 전송이 일어난다.

                 client                                server
                          ① 
         Send SYN seq=x   ---------------------------> Receive SYN segment
                                                              |
                          ②                                  |
Recevie SYN+ACK segment   <-------------------------- Send SYN seq=y, ACK x+1
                |
                |         ③
           send ACK y+1   --------------------------> Receive ACK segment 
				
그런 이유로 흔히 위의 과정을 "3 way Hand Shaking" 또는 "3번 악수기법" 이라고 한다. 최초에 클라이언트가 seq 번호 x 를 보내면 server 에서는 이 x 에 1 을 더해서 ACK 로 보낸다. 이때 자신의 seq 번호 y 도 포함해서 보낸다. 그러면 클라이언트에서는 server 부터 넘어온 패킷의 ACK가 자신의 seq 번호와 일치하는지 확인하고, 확인이 되면 server 의 seq 번호인 y 에 1을 더해서 ACK로 보낸다. server 에서는 client 가 보낸 ACK 의 번호와 자신의 seq 번호가 일치하는지 확인해서 일치하면 연결이 제대로 되었다는것을 인증하고 데이타 통신에 들어가게 된다.

그럼 tcpdump 를 이용해서 어떻게 위의 3번 악수기법 이 이루어지는 지 확인해 보도록 하겠다. 우선 tcpdump 를 다음과 같은 옵션으로 띄우도록 한다.

   
[root@localhost test]# tcpdump -x tcp 4445
Kernel filter, protocol ALL, TURBO mode (575 frames), datagram packet socket
tcpdump: listening on all devices
...
				
그다음에 zipcode_cl 을 이용해서 서버에 접근해보자 그러면 아래와 같은 패킷 dump 화면이 뜰것이다. ----- 1, ----- 2 는 구분하기 쉽도록 필자가 추가시킨 문자이다.
   
13:42:47.952336 eth0 > localhost.2310 > 211.234.96.141.4445: S 2850317194:2850317194(0) win 5840 <mss 1460,sackOK,timestamp 10265185 0,nop,wscale 0> (DF)
                         4500 003c c1eb 4000 4006 1f2e c0a8 6482                 ----- 1
                         d3ea 608d 0906 115d a9e4 638a 0000 0000
                         a002 16d0 0cc5 0000 0204 05b4 0402 080a
                         009c a261 0000 0000 0103 0300
13:42:48.202336 eth0 < 211.234.96.141.4445 > localhost.2310: S 2213490312:2213490312(0) ack 2850317195 win 5792 <
                                                                                                                       mss 1460,sackOK,timestamp 2310931230 10265185,nop,wscale 0> (DF)
                         4500 003c 0000 4000 3806 e919 d3ea 608d                 ----- 2
                         c0a8 6482 115d 0906 83ef 2e88 a9e4 638b
                         a012 16a0 cd8f 0000 0204 05b4 0402 080a
                         89be 031e 009c a261 0103 0300
13:42:48.202336 eth0 > localhost.2310 > 211.234.96.141.4445: . 1:1(0) ack 1 win 5840 <nop,nop,timestamp 10265210 2310931230> (DF)
                         4500 0034 c1ec 4000 4006 1f35 c0a8 6482                 ----- 3
                         d3ea 608d 0906 115d a9e4 638b 83ef 2e89
                         8010 16d0 fc0b 0000 0101 080a 009c a27a
                         89be 031e
				
3번 악수 기법을 위해서 3번의 패킷이 오고 갔음을 알수 있다. 언뜻 봤을때 절대 이해할수 없을것 같은 숫자로 된 정보들을 뿌려주는데 원리만 알면 간단하게 분석할수 있다. 위의 숫자로 된 정보들이 바로 TCP/IP 세그먼트의 정보를 16 진수로 나타낸 것이다. 4자리씩 구분되어 있는데, 이 4자리의 크기는 16 비트크기를 가진다(하나의 숫자는 4비트이다. 이 정보만 알고 있다면 위의 패킷정보에서 IP 영역과 TCP 영역을 분리해 낼수 있다.

IP 헤더의 크기는 유동적이긴 하지만 기본적으로 5 * (32 bit) 의 크기를 갖는다. 그러므로 ----- 1 번 패킷을 높고 보자면 IP 헤더는 다음과 같을 것이다.

                         4500 003c c1eb 4000 4006 1f2e c0a8 6482  
                         d3ea 608d 
				
정말 IP 헤더 정보가 맞는지 확인해보자. IP 헤더의 첫번째 4bit 는 IP의 버젼을 나타낸다. 위에서 보면 '4' 로 되어 있음으로 이 TCP/IP 패킷은 IPv4 를 이용하고 있음을 알수 있다. c0a8 6482 는 source IP, d3ea 608d 는 destination IP 이다.

이제 ---- 1 번 패킷에서 TCP 헤더 정보를 분석해 보도록 하자. 분석한 데이타는 tcpdump 헤더와 비교하면서 계산하도록 하자. TCP 헤더데이타는 0906 부터이다. TCP 의 처음 16bit 는 SOURCE PORT 다음 16bit 는 DESTINATION PORT 를 나타낸다. 0906 을 계산해 보면(진수변환 되는 계산기로) 2310 이며 115d 를 계산해보면 4445 이다. 정확하게 일치하고 있음을 알수 있다. 클라이언트측의 PORT 번호는 서버측 포트 번호와는 달리 임의의 번호로 할당된다.

우리는 ---- 1 번 패킷에서 a9e4 638a 가 시퀀스 넘버임을 유추해낼수 있을것이다. 이것을 계산해 보면 2850317194 임을 알수 있다. ACK는 0000 0000 이다. ACK 는 0000 0000 즉 0 으로 초기화 되어있는데 반해서, 시퀀스 넘버는 0으로 초기화 되어 있지 않다. 실지로 ACK 는 새로운 연결이 이루어질때 마다 0 으로 초기화 되는데 비해 시퀀스 넘버는 새로운 연결이 생길때 마다 임의의 번호로 새로 만들어진다.

Header Length 는 4bit 크기를 가지므로 a002 에서 'a' 임을 알수 있다. 해서 Header Length 는 10(a) 임을 계산할수 있는데, 이때 Length 의 단위는 워드(32 bit) 이다. 그러므로 헤더는 0906 에서 0300 까지의 데이타임을 유추해 낼수 있다.

                                   0906 115d a9e4 638a 0000 0000
                         a002 16d0 0cc5 0000 0204 05b4 0402 080a
                         009c a261 0000 0000 0103 0300
				
즉 최초 세번 악수 기법을 통한 세션 연결시에 오고 가는 3개의 패킷 데이타는 단지 TCP/IP 헤더정보만을 포함하고 있으며, 그외의 아무런 다른 정보도 포함하고 있지 않음을 알수 있다.


2.3.3.1. 패킷 분석을 통해서 알아보는 3번 악수 기법 - 연결

이전에 ---- 1 패킷을 분석함으로써, 우리는 dump 된 패킷을 분석하는 기본적인 기법을 배웠다. 이 방법들을 토대로 정말로 3번 악수 기법이 제대로 이루어 지는지 한번 확인해 보도록 하겠다.

3번 악수 기법을 보면 알겠지만 가장 핵심이 되는 키워드는 SEQ 번호와 ACK 번호 그리고 패킷의 타입을 나타내는 CODE BITS 이다. 이 세가지 필드의 의 계산만 잘하면 TCP 연결이 어떻게 이루어지는지 이해가 가능할것이다. 그럼 ---- 1, ---- 2, ---- 3의 dump 패킷을 분석해서 3번 악수 기법의 흐름을 알아보도록 하자.

---- 1

클라이언트는 자신의 SEQ 를 a9e4 638a (2850317194)로 만들고 . ACK 를 0000 0000 (0) 으로 만들어서 ---- 1 패킷을 서버측 측에 보낸다.

---- 2

서버는 클라이언트로 부터 ---- 1 패킷을 받는다. SEQ 는 a9e4 638a 인데, 여기에 +1 (a9e4 638b) 를 해서 ACK 를 만든다. 그리고 자신의 SEQ 를 83ef 2e88 로 세팅해서 ---- 2 패킷을 만들고 만들어진 패킷을 다시 클라이언트로 보낸다.

CODE BITS 를 보면 값이 02 임을 알수 있다. 2 는 2진수로 10 CODE BITS 의 세팅은 00 00 10 으로 되어있음을 알수 있다. 5번째 BIT 는 SYN 비트 임으로 이 패킷은 최초 연결을 시도하기 위한 패킷임을 알수 있다.

CODE BITS 를 보면 값이 12 임을 알수 있다. 이것을 2진수로 변경 시켜 보면 10 00 10 이다 그러므로 URG 와 SYN 비트가 세팅되어 있음을 알수 있다.

---- 3

클라이언트는 서버로 부터 ---- 2 패킷을 받는다. ---- 2 패킷에서 넘어온 ACK 를 확인해 본다. 최초에 클라이언트가 서버측으로 보낸 SEQ 에 +1 된 값이므로 올바른 데이타임을 확인할수 있다. 이제 ---- 2 에서 넘어온 ACK 를 자신의 SEQ 로 설정하고, ---- 2 에서 넘어온 SEQ (83ef 2e88)에 +1 을 해서 ---- 3 패킷을 만들고 이것을 서버로 보낸다.

CODE BITS 를 보면 값이 10 이다. 2진수로 10 00 00 임으로 URG 가 세팅되어 있음을 알수 있다.

이상 꽤 복잡한것 같지만 곰곰히 생각해 보면 별거 아니란걸 알수 있을것이다.


2.3.3.2. 패킷 분석을 통해서 알아보는 연결 종료

연결과는 좀 다르다. 완전한 종료를 위해서는 아래와 같이 4 번의 패킷 교환이 일어난다.

                 client                                server
                             ① 
         Send SYN seq=x      ---------------------------> Receive FIN segment
                                                                |
                             ②                                 |
         Recevie segment     <-------------------------- Send ACK x+1

                             ①
 Receive FIN + ACK segment   <-------------------------- Send FIN seq=y, ACK x+1 
                |
                |            ②
         Send ACK y + 1      --------------------------> Receive ACK segment
					
완전한 연결종료를 위해서 위의 zipcode 어플리케이션 대신에 telnet(port 23) 을 이용해서 테스트 하기로 했다. 테스트 방법은 telnet 로 해당 서버에 연결한 연결한 다음 login 프롬프트가 떨어지면 (CTRL + ]) 키를 이용해서 telnet> 프롬프트를 부르고 여기에 quit 를 입력해서 연결을 종료시키는 방법이다.
[root@coco test]# telnet 192.168.100.190
Trying 192.168.100.190...
Connected to 192.168.100.190.
Escape character is '^]'.


SunOS 5.8

login:                // 여기에서 CTRL+] 입력
telnet> quit
					
이 과정을 tcpdump 로 패킷 덤프 받은 데이타 내용은 다음과 같다.
17:03:01.412336 eth0 > localhost.2437 > develop.telnet: F 110:110(0) ack 89 win 5840 <nop,nop,timestamp 11466531 71617405> (DF)
                         4500 0034 980c 4000 4006 5826 c0a8 6482         ---- 1
                         c0a8 64be 0985 0017 9d14 6d27 1f57 e476
                         8011 16d0 3621 0000 0101 080a 00ae f723
                         0444 cb7d
17:03:01.412336 eth0 < develop.telnet > localhost.2437: . 89:89(0) ack 111 win 10136 <nop,nop,timestamp 71618004 11466531> (DF)
                         4500 0034 23c2 4000 ff06 0d70 c0a8 64be         ---- 2
                         c0a8 6482 0017 0985 1f57 e476 9d14 6d28
                         8010 2798 2302 0000 0101 080a 0444 cdd4
                         00ae f723

17:03:01.412336 eth0 < develop.telnet > localhost.2437: F 89:89(0) ack 111 win 10136 <nop,nop,timestamp 71618005 11466531> (DF)
                         4500 0034 23c3 4000 ff06 0d6f c0a8 64be         ---- 3
                         c0a8 6482 0017 0985 1f57 e476 9d14 6d28
                         8011 2798 2300 0000 0101 080a 0444 cdd5
                         00ae f723
17:03:01.412336 eth0 > localhost.2437 > develop.telnet: . 111:111(0) ack 90 win 5840 <nop,nop,timestamp 11466531 71618005< (DF)
                         4500 0034 0000 4000 ff06 3132 c0a8 6482         ---- 4
                         c0a8 64be 0985 0017 9d14 6d28 1f57 e477
                         8010 16d0 33c8 0000 0101 080a 00ae f723
                         0444 cdd5
					
패킷 분석방법은 위에서 모두 설명했으니 굳이 다시 설명하진 않겠다. 주의 해서 볼점은 CODE BITS 부분이다. ---- 1 번을 보면 CODE BITS 가 11 로 설정되어 있음을 볼수 있다. 이를 2진수로 변환하면 10 00 01 이다. FIN 비트 가 세팅되어 있음을 알수 있다.


2.3.3.3. 실 데이타 전송

실 데이타를 전송할때는 연결/종료 와 같은 3번 악수 기법에 의한 복잡한 (뭐 그리 복잡하지도 않지만) 그러한 패킷 교환은 없다. 단지 한쪽에서 데이타를 보내면 받은쪽에서는 데이타를 잘 받았다라는 패킷만을 보내게 된다.

이제 실제 데이타가 전송될때의 TCP/IP 패킷의 분석을 해보도록 하자. 여기에서는 다시 zipcode 의 서버/클라이언트가 사용될것이다. zipcode_cl 을 이용해서 서버여 연결하고 "지역이름 입력 : " 프롬프트가 떨어지면 a 를 입력해보도록 하자.

  
[root@s210-205-210-195 test]# ./zipcode_cl 4445
지역이름 입력 : a
지역이름 입력 : 
					
다음은 위의 결과 를 tcpdump 를 이용해서 dump 뜬 결과 이다.
23:32:49.951938 s210-205-210-195.thrunet.ne.kr.33638 > 211.234.96.141.4445: P 1:256(255) ack 1 win 5840 <nop,nop,timestamp 26681991 2314595836> (DF)
                         4500 0133 484f 4000 4006 176d d2cd d2c3   ---- 1
                         d3ea 608d 8366 115d 5b9e 5641 872e f2e8
                         8018 16d0 19eb 0000 0101 080a 0197 2287
                         89f5 edfc 6100 0000 5066 0140 0100 0000
                         dc81 0408 9460 0140 0f53 8e07 0f53 8e07
                         70f7
23:32:49.967321 211.234.96.141.4445 > s210-205-210-195.thrunet.ne.kr.33638: . ack 256 win 6432 <nop,nop,timestamp 2314596983 26681991> (DF)
                         4500 0034 1f16 4000 3806 49a5 d3ea 608d   ---- 2  
                         d2cd d2c3 115d 8366 872e f2e8 5b9e 5740
                         8010 1920 214f 0000 0101 080a 89f5 f277
                         0197 2287
23:32:49.971577 211.234.96.141.4445 > s210-205-210-195.thrunet.ne.kr.33638: P 1:256(255) ack 256 win 6432 <nop,nop,timestamp 2314596983 26681991> (DF)
                         4500 0133 1f17 4000 3806 48a5 d3ea 608d   ---- 3 
                         d2cd d2c3 115d 8366 872e f2e8 5b9e 5740
                         8018 1920 07d6 0000 0101 080a 89f5 f277
                         0197 2287 656e 6400 7365 6e64 2065 6e64
                         0a00 0000 0000 0000 0000 001c 9e04 0800
                         0000
23:32:49.971653 s210-205-210-195.thrunet.ne.kr.33638 > 211.234.96.141.4445: . ack 256 win 6432 <nop,nop,timestamp 26681993 2314596983> (DF)
                         4500 0034 4850 4000 4006 186b d2cd d2c3   ---- 4
                         d3ea 608d 8366 115d 5b9e 5740 872e f3e7
                         8010 1920 204e 0000 0101 080a 0197 2289
                         89f5 f277
					
---- 1 에서 실제 데이타를 보내고 있으며 여기에서는 서버측으로 'a' 를 보내게 될것이다. 실제 'a' 를 보내는지 확인을 해보자. IP 헤더의 크기는 (5*32) 로 고정되어 있을것이다. 문제는 TCP 헤더의 크기인데, 8018 에서 8 이 헤더의 크기를 나타냄을 알수 있다. 단위는 워드 이므로 계산을 해보면(8 * 32) 8366 에서 부터 edfc 까지가 TCP 헤더 임을 알수 있다. 그러므로 우리가 보내고자 하는 데이타는 6100 에서 부터가 될것이다. 61 은 'a' 라는걸 알수 있다. - 61 은 10 진수 97 을 나타내며 ASCII 코드를 보면 97 은 'a' 를 나타낸다.

서버에서 데이타를 받았다면 서버는 이에 대한 응답 메시지(저 메시지 잘 받았습니다) 를 클라이언트측에 보내야 할것이다. ---- 2 패킷이 바로 응답 메시지가 된다. ---- 2 패킷의 CODE BITS 를 보면 10 으로 세팅되어 있는데, 이것을 2진수로 변경하면 01 00 00 이 된다. 2번째 비트가 켜져 있는데 2번째 비트는 ACK 를 나타낸다. 그러므로 이 패킷은 응답용 패킷이라는 걸 알수 있다. 그렇다면 --- 2 패킷을 받은 클라이언트는 이게 과연 ----2 패킷이 ---- 1 에 대한 응답 메시지인지를 확인해야 하는데 이는 SEQ 번호와 ACK 번호를 계산함으로써 알나 낼수 있을것이다.

---- 3 번 데이타는 서버측에서 클라이언트로 보내는 패킷의 dump 내용이다. 클라이언트로 보내는 데이타는 "send end" 임을 알아낼수 있을 것이다. ---- 4 번 데이타는 이에 대한 응답으로 클라이언트에서 서버측으로 보내는 패킷 dump 내용이다.


3. 결론

이상 TCP 헤더에 대한 비교적 상세한 내용을 다루었다. 이러한 내용들은 나중에 다루게될 RAW 소켓등 낮은 수준에서의 네트웍 프로그래밍을 원한다면 알아두어야할 내용이다. 또한 네트웍 관련 문제해결을 하는데 많은 도움을 줄것이다.

이 문서에서 이해되지 않는 내용등이 있다면 댓글을 달아주길 바란다. 그러면 최대한 공부를 해서라도 답변을 해주도록 하겠다.

Trackback 0 Comment 0
2009/01/07 12:55

sed를 이용한 highlight


apache 웹로그, php 에러로그, syslog를 통한 로그를 모니터링할 때 특정 문자열에 대해서는 highlight해주면 원하는 부분만 쉽게 볼 수 있을 것이다. 또한 수치를 모니터링하는 경우, 0~59는 양호, 60~79 주의, 80~99는 경고를 나타내기위해 각각 녹색, 파란색, 빨간색으로 표시해준다면, 많은 로그가 순간적으로 스크롤되더라도 눈에 쉽게 띌 것이다.
이 글은 highlight 처리를 해주는 1) sed를 이용한 쉘스크립트와 2) 이보다 더 나은 perl 스크립트를 통해 모니터링하는 방법을 설명한다.

1. sed를 이용한 highlight 스크립트

* view.sh 내려받기

#!/bin/bash
#
# 특정 문자를 highlight한다. (view.sh)
#
# by 좋은진호(truefeel, http://coffeenix.net/ )

# color
szColBk="^[[;30m";      szColBk1="^[[1;30m"     # black
szColRe="^[[;31m";      szColRe1="^[[1;31m"     # red
szColGr="^[[;32m";      szColGr1="^[[1;32m"     # green
szColYe="^[[;33m";      szColYe1="^[[1;33m"     # yellow
szColBl="^[[;34m";      szColBl1="^[[1;34m"     # blue
szColPu="^[[;35m";      szColPu1="^[[1;35m"     # magenta(purple)
szColCy="^[[;36m";      szColCy1="^[[1;36m"     # cyan
szColGy="^[[;37m";      szColWh="^[[1;37m"      # white
szNormal="^[[;m"

#
sed \
        -e "s/^[A-Z][a-z][a-z] *[0-9]* //g" \
        \
        -e "s/ \(192.168.123.[0-9]*\)/${szColGr} \\1$szNormal/g" \
        \
        -e "s/\(httpd\)/${szColCy}\\1$szNormal/g" \
        -e "s/\(vsftpd\)/${szColCy}\\1$szNormal/g" \
        -e "s/\(proftpd\)/${szColCy}\\1$szNormal/g" \
        -e "s/\(ftpd\)/${szColCy}\\1$szNormal/g" \
        -e "s/\(sshd\)/${szColCy}\\1$szNormal/g" \
        -e "s/\(xinetd\)/${szColCy}\\1$szNormal/g" \
        -e "s/\(Connection attempt\)/${szColRe1}\\1$szNormal/g" \
        -e "s/\(authentication failure\)/${szColRe1}\\1$szNormal/g" \
        -e "s/\(BAD SU\)/${szColRe1}\\1$szNormal/g" \
        \
        -e "s/\(nfs server\)/${szColYe}\\1/g" \
        \
        -e "s/$/$szNormal/g"
[/quote]

사용은 tail -f 로그파일명 |./view.sh 형태로 사용하면 된다.

첫번째 부분은 색깔을 정의한 변수이다. 여기서 ^[[;31m ANSI코드로, ^[ 문자는 ESC키를 의미한다. 쉘에서 입력할 때 Ctrl+V를 누른 후 ESC키를 누르면 입력할 수 있다. 색깔은 사용하는 터미널에 따라서 약간 다르게 표시될 수도 있다.

사용자 삽입 이미지


그 다음부터는 sed를 이용해서 문자열을 변환처리하며, 한줄당 하나의 정규표현식을 사용하였다. 부분적으로 살펴보자.

 1:     -e "s/^[A-Z][a-z][a-z] *[0-9]* //g" \

기본적으로 -e s/변환전문자열/변환후문자열/g 형식을 사용하는데, 위는 syslog를 통해 남은 로그중 'Oct 30'과 같이 '월일'을 표시하지 않기 위한 정규표현식이다.
 
 1:     -e "s/ \(192.168.123.[0-9]*\)/${szColGr} \\1$szNormal/g" \
 2:     \
 3:     -e "s/\(httpd\)/${szColCy}\\1$szNormal/g" \
 4:     -e "s/\(vsftpd\)/${szColCy}\\1$szNormal/g" \

첫번째줄은 특정 IP대역을 highlight하기 위한 것으로 서버의 IP, 접속하는 PC의 IP등을 한줄에 하나씩 적어주면 좋을 것이다. 두번째줄의 \ 은 보기 좋게 구분하기 위한 것이며, 세번째와 네번째줄은 각각 httpd와 vsftpd를 highlight한다.

 1:     -e "s/\(nfs server\)/${szColYe}\\1/g" \
 2:     \
 3:     -e "s/$/$szNormal/g"

첫번째줄은 'nfs server'로 문자열이 나온다면, 해당 줄 끝까지 highlight한다. ${szColYe}\\1과 server과 ${szColYe}\\1$szNormal 의 차이를 생각하면 쉽게 이해가 될 것이다. 세번째줄은 줄의 끝부분에서 색깔 표시는 정상으로 돌려놓으라는 의미이다.

2. perl을 이용한 highlight 스크립트


위의 예제를 통해서 원하는 문자열을 원하는 색깔로 highlight하는 것은 쉽게 할 수 있을 것이다. 이젠 perl이용한 방법을 소개한다.

* view.pl 내려받기

#!/usr/bin/perl
#
# 특정 문자를 highlight한다. (view.pl)
#
# by 좋은진호(truefeel, http://coffeenix.net/ )

# color
$szColBk ="^[[;30m";    $szColBk1 ="^[[1;30m";  # black
$szColRe ="^[[;31m";    $szColRe1 ="^[[1;31m";  # red
$szColGr ="^[[;32m";    $szColGr1 ="^[[1;32m";  # green
$szColYe ="^[[;33m";    $szColYe1 ="^[[1;33m";  # yellow
$szColBl ="^[[;34m";    $szColBl1 ="^[[1;34m";  # blue
$szColPu ="^[[;35m";    $szColPu1 ="^[[1;35m";  # magenta(purple)
$szColCy ="^[[;36m";    $szColCy1 ="^[[1;36m";  # cyan
$szColGy ="^[[;37m";    $szColWh  ="^[[1;37m";  # white
$szNormal="^[[;m";

#
$szBeep="\a";

#
while(&lt;STDIN&gt;) {
    # log에서 필요없는 부분 삭제 
        s/^[A-Z][a-z][a-z] *[0-9]* //g;

    # IP
        s/(192\.168\.123\.[1-9][0-9]{0,2})/$szColGr$1$szNormal/g;

    # 줄 끝은 정상 색으로 변경
    s/$/$szNormal/;

    # 원하는 문자열에 색을 입힌다
        s/(httpd)/$szColCy$1$szNormal/g;
        s/(vsftpd|proftpd|ftpd)/$szColCy$1$szNormal/g;
        s/(sshd)/$szColCy$1$szNormal/g;
        s/(xinetd)/$szColCy$1$szNormal/g;
        s/(Connection attempt)/$szColRe1$1$szNormal/g;
        s/(authentication failure)/$szColRe1$1$szNormal/g;
        s/(BAD SU)/$szColRe1$1$szNormal/g;

    # 원하는 문자열을 찾으면 줄 끝까지 색을 읽힌다.
        s/(nfs server)/$szColYe$1/g;

    print $_;
}

사용은 shell스크립트를 사용할 때와 동일하게 tail -f 로그파일명 |./view.pl 형태로 사용하면 된다.

 1:     s/(192\.168\.123\.[1-9][0-9]{0,2})/$szColGr$1$szNormal/g;
 2:     ... 생략...
 3:     s/(vsftpd|proftpd|ftpd)/$szColCy$1$szNormal/g;

첫번째줄에서 192\.168\.123\.[1-9][0-9]{0,2} 은 sed를 이용할 때보다 더 정교하게 IP를 체크한 것으로, 1) 192.168.123. 시작하는 IP대역 2) 그 다음 1~9까지 숫자이고, 그다음에 숫자가 오게된다면 0~9까지 숫자가 0자리~2자리까지 가능하다. 정규 표현식에 대한 자세한 사항은 이 글의 주제를 벗어나는 내용이므로 '4 참고 자료'를 살펴보기 바란다. 세번째줄은 vsftpd, proftpd, ftpd 등의 문자를 highlight한다.

다음은 위의 스크립트를 이용하여 로그를 모니터링한 화면이다.
사용자 삽입 이미지


3. 수치에 따라 다른 색으로 표시

어떤 로그에 수치가 다음과 같이 실시간으로 쌓인다고 가정하자. 그리고, 그 수치는 'disk 54'와 같은 형태로 되어 있다.

---------  ------   --------
측정수치    상태     색깔
---------  ------   --------
0~59       양호      녹  색
60~79      주의      파란색 
80~100     경고      빨간색
---------  ------   --------

다음은 perl을 이용하여 색을 표시하는 예이다. 그리고, 수치가 80이상일 땐 beep음을 발생한다. 이런한 방법은 서버의 load, disk 사용량, disk I/O, 커넥션 수, 메모리 사용량 등을 모니터링할 때 유용하게 사용할 수 있다.

 s/(disk [0-9][^0-9])/$szColGr$1$szNormal/;
 s/(disk [1-5][0-9][^0-9])/$szColGr$1$szNormal/;
 s/(disk [6-7][0-9])/$szColBl$1$szNormal/;
 s/(disk [8-9][0-9])/$szColRe1$1$szNormal$szBeep/;
 s/(disk 100)/$szColRe1$1$szNormal$szBeep/;

4. 참고 자료

* ANSI color codes
  http://pueblo.sourceforge.net/doc/manual/ansi_color_codes.html
* 정규표현식
  http://coffeenix.net/dir_catagory.php?cata_code=99
* Perl regular expressions
  http://www.perl.com/doc/manual/html/pod/perlre.html

Trackback 0 Comment 0
2009/01/07 12:52

쉘에서 실행한 명령을 syslog로 자동 보내기


서버에 접속한 유저가 어떤 명령을 내렸는지 실시간으로 확인하려면 어떻게 해야할까? history file을 뒤진다? 이건 너무 불편하다. 명령이 실행될 때마다 특정이벤트를 발생해서, 별도 저장해주면 효과적일 것이다. 그 것도 syslog를 통해서 명령이 저장된다면 원격지 서버에서 특정 서버의 실행 명령을 모조리 확인해볼 수 있을 것이다.

몇줄의 쉘 function으로 syslog로 실행명령을 보내는 방법을 알아보자.

function logging
{
        stat="$?"
        cmd=$(history|tail -1)
        if [ "$cmd" != "$cmd_old" ]; then
                logger -p local1.notice "[2] STAT=$stat"
                logger -p local1.notice "[1] PID=$$, PWD=$PWD, CMD=$cmd"
        fi
        cmd_old=$cmd
}
trap logging DEBUG

위 스크립트에서 중요한 부분은 logger와 trap이다.

1) logger는 지정한 메시지를 syslog로 보내주는 명령이다.
   위에서는 local1 서비스종류(facility)과 notice 레밸로 syslog로 메시지를 보내준다. 
   logger의 활용에 대해서는 '여러 서버의 load를 터미널에서 실시간 모니터링' (글 좋은진호, 2008.2)
   중 '2. 미리 준비되어 있어야할 사항' 부분을 살펴보기 바란다.
2) trap은 bash내부 명령으로 특정시그널이 발생할 때 지정한 명령어가 실행된다.
   형식) trap "명령" 시그널
   위에서는 DEBUG 형태로, 명령이 실행될 때마다 logging function을 호출한다.

위의 스크립트를 global하게 적용하려면 /etc/profile 에 추가하거나 /etc/profile.d/cmd_logging.sh 로 저장하면 된다. 유저별로 적용하려면 $HOME/.bash_profile 또는 $HOME/.bashrc에 넣어둔다. 이제 적용됐는지 로긴해보자.

Sep 30 17:11:32 cnx1 coffeenix: [2] STAT=0
Sep 30 17:11:32 cnx1 coffeenix: [1] PID=29168, PWD=/home/coffeenix, CMD=    7  ls -la
Sep 30 17:11:36 cnx1 coffeenix: [2] STAT=0
Sep 30 17:11:36 cnx1 coffeenix: [1] PID=29168, PWD=/home/coffeenix, CMD=    8  vi get_stat.sh
Sep 30 17:15:24 cnx1 coffeenix: [2] STAT=0
Sep 30 17:15:24 cnx1 coffeenix: [1] PID=29168, PWD=/home/coffeenix, CMD=    9  chmod 700 get_stat.sh 
Sep 30 17:15:28 cnx1 coffeenix: [2] STAT=0
Sep 30 17:15:28 cnx1 coffeenix: [1] PID=29168, PWD=/home/coffeenix, CMD=   10  ./get_stat.sh 
Sep 30 17:15:35 cnx1 coffeenix: [2] STAT=0
Sep 30 17:15:35 cnx1 coffeenix: [1] PID=29168, PWD=/home/coffeenix, CMD=   11  ls
Sep 30 17:16:31 cnx1 coffeenix: [2] STAT=0
Sep 30 17:16:31 cnx1 coffeenix: [1] PID=29168, PWD=/home/coffeenix, CMD=   12  cd /var/log
Sep 30 17:16:32 cnx1 coffeenix: [2] STAT=0
Sep 30 17:16:32 cnx1 coffeenix: [1] PID=29168, PWD=/var/log, CMD=   13  ls

시간표시를 자세히 보면 [2]가 먼저 저장되고, [1]이 그 다음에 저장된다. [2] 는 이전에 실행한 명령의 실행 결과 코드이며, [1]은 방금 실행한 명령이다. 방금 실행한 결과 코드는 다음 명령이 실행되어야 결과로 저장이 된다.

실행명령만 별도 로그로 저장하고 싶다면 /etc/syslog.conf 에 다음을 추가하고, syslogd 데몬을 재실행해주면 된다.

local1.notice                           /var/log/cmd.log

보다 자세한 것은 커피닉스에 써둔 '쉘에서 실행한 명령을 syslog로 자동 보내기'를 살펴보기 바란다.

http://truefeel.tistory.com/123 에서 발췌하였습니다.
Trackback 0 Comment 0
2008/08/19 13:41

iptables

Linux Firewalls Using iptables

= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =

In This Chapter

Chapter 11

Linux Firewalls Using iptables

What Is iptables?

Download And Install The Iptables Package

How To Get iptables Started

Packet Processing In iptables

Iptables Packet Flow Diagram

Processing For Packets Routed By The Firewall

Packet Processing For Data Received By The Firewall

Packet Processing For Data Sent By The Firewall

Targets And Jumps

Descriptions Of The Most Commonly Used Targets

Important Iptables Command Switch Operations

General Iptables Match Criteria

Common TCP and UDP Match Criteria

Common ICMP (Ping) Match Criteria

Common Match Extensions Criteria

Using User Defined Chains

Sample iptables Scripts

Basic Initialization

Allowing DNS Access To Your Firewall

Allowing WWW And SSH Access To Your Firewall

Allowing Your Firewall To Access The Internet

Allow Your Home Network To Access The Firewall

Masquerading (Many to One NAT)

Port Forwarding Type NAT

Static NAT

Logging & Troubleshooting

 

 

© Peter Harrison, www.linuxhomenetworking.com


= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =

You can convert your Linux box into a firewall using the IPtables package. This page shows how to convert your Linux box into:

·     A firewall while simultaneously being your home website's mail, web and DNS server.

·     A router that will use NAT and port forwarding to both protect your home network and have another web server on your home network while sharing the public IP address of your firewall

What Is iptables?

Originally, the most popular firewall / NAT package running on Linux was ipchains. It had a number of limitations, the primary one being that it ran as a separate program and not as part of the kernel. The Netfilter organization decided to create a new product called iptables in order to rectify this shortcoming. As a result of this, iptables is considered a faster and more secure alternative.  iptables has now become the default firewall package installed under RedHat Linux.  

Download And Install The Iptables Package

Most RedHat Linux software products are available in the RPM format. Downloading and installing RPMs isn’t hard. If you need a refresher, the chapter on RPMs covers how to do this in detail. The latest version of the RPM for RedHat 8.0 is iptables-ipv6-1.2.6a-2.i386.rpm. Install the package using the following command:


[root@bigboy tmp]# rpm -Uvh iptables-ipv6-1.2.6a-2.i386.rpm
Preparing...    ########################################### [100%]
1:iptables      ########################################### [100%]

[root@bigboy tmp]#  

How To Get iptables Started

You can start/stop/restart iptables after booting by using the following commands:


[root@bigboy tmp]# /etc/init.d/iptables start
[root@bigboy tmp]# /etc/init.d/iptables stop
[root@bigboy tmp]# /etc/init.d/iptables restart


To get iptables configured to start at boot:


[root@bigboy tmp]# chkconfig --level 345 iptables on  

Packet Processing In iptables

All packets inspected by iptables pass through a sequence of built-in tables (queues) for processing. Each of these queue is dedicated to a particular type of packet activity and is controlled by an associated packet transformation / filtering chain. Don’t worry if this all seems confusing, there’ll be tables and examples of how the concepts are all interlinked.

For example, the chart and graphic below describe the steps taken by iptables when a packet traverses the firewall.


Iptables Packet Flow Diagram





Processing For Packets Routed By The Firewall


Packet flow

Intercepted by iptables chain (Queue)

Packet transformation table associated with this queue

Description of possible modifications by iptables using this transformation table

Packet enters the NIC and is passed to iptables

Mangle

PREROUTING

Modification of the TCP packet quality of service bits.

(Rarely used)


Nat

PREROUTING

Destination network address translation (DNAT)

Packet passed to the Linux routing engine

N/A

N/A

N/A

Determines whether the packet is destined to a local application or should be sent out another NIC interface

Packet passed back to iptables

Filter

FORWARD

Packet filtering:

Packets destined for servers accessible by another NIC on the firewall.


Nat

POSTROUTING

Source network address translation (SNAT)

Packet transmitted out the other NIC

N/A

N/A

N/A




Packet Processing For Data Received By The Firewall


Packet flow

Actions by Operating System

Packet intercepted by iptables table (Queue)

Packet transformation chain associated with this queue

Description of possible modifications by iptables using this transformation table

Packet

destined for firewall


Packet enters the NIC from remote server.

The packet is intercepted by the iptables mangle, then nat queues

mangle

PREROUTING

Modification of the TCP packet quality of service bits.

(Rarely used)



nat

PREROUTING

Destination network address translation (DNAT)


The packet is then passed from iptables to the Linux routing engine.


The routing engine passes the packet to the target application via the iptables filter queue

filter

INPUT

Packet filtering:

Packets destined for the firewall.

The application receives the packet from iptables then processes it.





Packet Processing For Data Sent By The Firewall


Packet flow

Actions by Operating System

Packet intercepted by iptables table (Queue)

Packet transformation chain associated with this queue

Description of possible modifications by iptables using this transformation table

The application sends data to a remote server

Packet

originating from firewall


The packet is intercepted by iptables which then processes it in the mangle, nat and filter tables

mangle

OUTPUT

Modification of the TCP packet quality of service bits.

(Rarely used)



nat

OUTPUT

Source network address translation

(Rarely used)



filter

OUTPUT

Packet filtering:

Packets destined for other servers / devices.


The packet is then passed to the Linux routing engine which forwards the packet out the correct NIC


The packet is intercepted by the iptables nat table

nat

POSTROUTING

Source network address translation (SNAT)

Packet transmitted out a NIC




Targets And Jumps

You don't have to rely solely on the built-in chains provided by iptables, you can create your own chains. These can be accessed by making them the targets of "jumps" in the built-in chains. So in summary, the targets/jumps tell the rule what to do with a packet that matches the rule perfectly.

There are a number of built-in targets that most rules may use.


Descriptions Of The Most Commonly Used Targets

Target

Description

Most common options

ACCEPT

·    iptables stops further processing.

·    The packet is handed over to the end application or the operating system for processing

N/A

DROP

·    iptables stops further processing.

·    The packet is blocked

N/A


LOG

·    The packet information is sent to the syslog daemon for logging

·    iptables continues processing with the next rule in the table

·    As you can't LOG and DROP at the same time, it is common to have two similar rules in sequence. The first will LOG the packet, the second will DROP it.

--log-prefix "string"

Tells iptables to prefix all log messages with a user defined string. Frequently used to tell why the logged packet was dropped

REJECT

·    Works like the DROP target, but will also return an error message to the host sending the packet that was blocked

--reject-with qualifier


The qualifier tells what type of reject message is returned. These include:


icmp-port-unreachable (default)

icmp-net-unreachable

icmp-host-unreachable

icmp-proto-unreachable

icmp-net-prohibited

icmp-host-prohibited

tcp-reset

echo-reply

DNAT

·    Used to do Destination Network Address Translation. ie.rewriting the destination IP address of the packet

--to-destination ipaddress


Tells iptables what the destination IP address should be

SNAT

·    Used to do Source Network Address Translation. ie.rewriting the source IP address of the packet

·    The source IP address is user defined

--to-source <address>[-<address>][:<port>-<port>]

Specifies the source IP address and ports to be used by SNAT.

MASQUERADE


·    Used to do Source Network Address Translation. ie.rewriting the source IP address of the packet

·    By default the source IP address is the same as that used by the firewall's interface

[--to-ports <port>[-<port>]]

Specifies the range of source ports the original source port can be mapped to.







Important Iptables Command Switch Operations

We’ll now explore how to use iptables command switches used to create your firewall.

General Iptables Match Criteria

iptables

command

Switch

Description

-t <table>

If you don't specify a table, then the filter table is assumed. As discussed before, the possible built-in tables include: filter, nat, mangle

-A

Append rule to end of a chain

-F

Flush. Deletes all the rules in the selected table

-p <protocol-type>

Match protocol. Types include, icmp, tcp, udp, all

-s <ip-address>

Match source IP address

-d <ip-address>

Match destination IP address

-i <interface-name>

Match "input" interface on which the packet enters.

-o <interface-name>

Match "output" interface on which the packet exits


Example:


iptables -A INPUT -s 0/0 -i eth0 -d 192.168.1.1  -p TCP -j ACCEPT


In this example iptables is being configured to allow the firewall to accept TCP packets coming in on interface eth0 from any IP address destined for the firewall's IP address of 192.168.1.1



Common TCP and UDP Match Criteria

switches used with

 

-p tcp

Description

 

switches used with

 

-p udp

Description

 

--sport <port>

TCP source port

Can be a single value or a range in the format:

start-port-number:end-port-number


--sport <port>

TCP source port

Can be a single value or a range in the format:

starting-port:ending-port

--dport <port>

TCP destination port

Can be a single value or a range in the format:

starting-port:ending-port


--dport <port>

TCP destination port

Can be a single value or a range in the format:

starting-port:ending-port

--syn

Used to identify a new connection request


! --syn means, not a new connection request





Example:


iptables -A FORWARD -s 0/0 -i eth0 -d 192.168.1.58 -o eth1 -p TCP \

         -sport 1024:65535 -dport 80 -j ACCEPT


In this example iptables is being configured to allow the firewall to accept TCP packets to be routed when they enter on interface eth0 from any IP address destined for IP address of 192.168.1.58 that is reachable via interface eth1. The source port is in the range 1024 to 65535 and the destination port is port 80 (www/http)



Common ICMP (Ping) Match Criteria

Matches

used with

 

---icmp-type

Description

--icmp-type <type>

The most commonly used types are  

echo-reply and echo-request


Example:


iptables -A OUTPUT -p icmp --icmp-type echo-request -j ACCEPT
iptables -A INPUT  -p icmp --icmp-type echo-reply   -j ACCEPT


In this example iptables is being configured to allow the firewall send ICMP echo-requests (pings) and in turn, accept the expected ICMP echo-replies.



Common Match Extensions Criteria

TCP/UDP match

extensions used with

 

-m multiport

Description

--sport <port, port>

A variety of TCP/UDP source ports separated by commas

--dport <port, port>

A variety of TCP/UDP destination  ports separated by commas

--dport <port, port>

A variety of TCP/UDP ports separated by commas. Source and destination ports are assumed to be the same.






Match extensions

used with

 

-m state

Description

--state <state>

The most frequently tested states are:


ESTABLISHED

The packet is part of a connection which has seen packets in both directions


NEW

The packet is the start of a new connection


RELATED

The packet is starting a new secondary connection. This is a common feature of protocols such as an FTP data transfer, or an ICMP error.


Example:


iptables -A FORWARD -s 0/0 -i eth0 -d 192.168.1.58 -o eth1 -p TCP \

         -sport 1024:65535 -m multiport -dport 80,443 -j ACCEPT


iptables -A FORWARD -d 0/0 -o eth0 -s 192.168.1.58 -i eth1 -p TCP \

         -m state --state ESTABLISHED -j ACCEPT


This is an expansion on the previous example. Here iptables is being configured to allow the firewall to accept TCP packets to be routed when they enter on interface eth0 from any IP address destined for IP address of 192.168.1.58 that is reachable via interface eth1. The source port is in the range 1024 to 65535 and the destination ports are port 80 (www/http) and 443 (https).

We are also allowing the return packets from 192.168.1.58 to be accepted too. Instead of stating the source and destination ports, it is sufficient to allow packets related to established connections using the -m state and --state ESTABLISHED options.



Using User Defined Chains

As stated in the introduction, iptables can be configured to have user-defined chains. This feature is frequently used to help streamline the processing of packets. For example, instead of having a single chain for all protocols, it is possible to have a chain that determines the protocol type for the packet and then hands off the actual final processing to a protocol specific chain. In other words, you can replace a long chain with a main stubby chain pointing to multiple stubby chains thereby shortening the total length of all chains the packet has to pass through.


Example:


iptables -A INPUT -i eth0  -d 206.229.110.2 -j fast-input-queue
iptables -A OUTPUT -o eth0 -s 206.229.110.2 -j fast-output-queue

iptables -A fast-input-queue  -p icmp -j icmp-queue-in
iptables -A fast-output-queue -p icmp -j icmp-queue-out

iptables -A icmp-queue-out -p icmp --icmp-type echo-request \
         -m state --state NEW -j ACCEPT

iptables -A icmp-queue-in -p icmp --icmp-type echo-reply -j ACCEPT


In this example we have six queues with the following characteristics to help assist in processing speed:



Chain

Description

INPUT

The regular built-in INPUT chain in iptables

OUTPUT

The regular built-in OUTPUT chain in iptables

fast-input-queue

Input chain dedicated to specific protocols

fast-output-queue

Output chain dedicated to specific protocols

icmp-queue-out

Output queue dedicated to ICMP

icmp-queue-in

Intput queue dedicated to ICMP






Sample iptables Scripts

Here are some sample scripts you can use to get iptables working for you. It is best to invoke these from your /etc/rc.d/rc.local file so that the firewall script is run every time you boot up. Pay special attention to the logging example at the end.

The "basic initialization" script snippet should also be included in all your scripts to ensure the correct initialization of your chains should you decide to restart your script after startup. This chapter also includes other snippets that will help you get basic functionality. It should be a good guide to get you started.

You then can use the Appendix to find a detailed script once you feel more confident. It shows you how to allow your firewall to:

·     Be used as a  Linux Web / Mail / DNS server

·     Be the NAT router for your home network

·     Prevent various types of attacks using corrupted TCP, UDP and ICMP packets.

·     Outbound passive FTP access from the firewall

There are also simpler code snippets in the Appendix for:

·     Inbound and outbound FTP connections to / from your firewall

Basic Initialization

It is a good policy, in any iptables script you write, to initialize your chain and table settings with known values. The "filter" table's INPUT, FORWARD and OUTPUT chains should DROP packets by default for the best security. However, it is not good policy to make your "nat" and "mangle" tables DROP packets by default. This is because these tables are queried before the "filter" table, and if all packets that don't match the "nat" and "mangle" rules  are DROP-ped, then they will not reach the the INPUT, FORWARD and OUTPUT chains and won't be processed.


Additional ALLOW rules should be added to the end of this script snippet.


#!/bin/bash

#---------------------------------------------------------------
# Load modules for FTP connection tracking and NAT – You may need

# them later
#---------------------------------------------------------------

modprobe ip_conntrack_ftp

modprobe iptable_nat


#---------------------------------------------------------------
# Initialize all the chains by removing all the rules
# tied to them
#---------------------------------------------------------------

iptables --flush
iptables -t nat --flush
iptables -t mangle --flush

#---------------------------------------------------------------
# Now that the chains have been initialized, the user defined
# chains should be deleted. We'll recreate them in the next step
#---------------------------------------------------------------

iptables --delete-chain
iptables -t nat --delete-chain
iptables -t mangle --delete-chain
 

#---------------------------------------------------------------
# If a packet doesn't match one of the built in chains, then
# The policy should be to drop it
#---------------------------------------------------------------

iptables --policy INPUT DROP
iptables --policy OUTPUT DROP
iptables --policy FORWARD DROP


#---------------------------------------------------------------
# The loopback interface should accept all traffic

# Necessary for X-Windows and other socket based services
#---------------------------------------------------------------

iptables -A INPUT  -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT

Allowing DNS Access To Your Firewall 

You’ll almost certainly want your firewall to make DNS queries to the Internet. The following statements will apply not only for firewalls acting as DNS clients but also for firewalls working in a caching or regular DNS server role.


#---------------------------------------------------------------

# Allow outbound DNS queries from the FW and the replies too

#

# - Interface eth0 is the internet interface

#

# Zone transfers use TCP and not UDP. Most home networks

# / websites using a single DNS server won’t require TCP statements

#

#---------------------------------------------------------------


iptables -A OUTPUT -p udp -o eth0 --dport 53 --sport 1024:65535 \

         -j ACCEPT


iptables -A INPUT -p udp -i eth0 --sport 53 --dport 1024:65535 \

         -j ACCEPT





Allowing WWW And SSH Access To Your Firewall

This sample snippet is for a web server that is managed remotely by its system administrator via secure shell (SSH) sessions. Inbound packets destined for ports 80 and 22 are allowed thereby making the first steps in establishing a connection. It isn't necessary to specify these ports for the return leg as outbound packets for all established connections are allowed. Connections initiated by persons logged into the webserver will be denied as outbound NEW connection packets aren't allowed.


#---------------------------------------------------------------
# Allow previously established connections

# - Interface eth0 is the internet interface

#---------------------------------------------------------------
 

iptables -A OUTPUT -o eth0 -m state --state ESTABLISHED,RELATED \

  -j ACCEPT

#---------------------------------------------------------------
# Allow port 80 (www) and 22 (SSH) connections to the firewall

#---------------------------------------------------------------
 

iptables -A INPUT -p tcp -i eth0 --dport 22 –sport 1024:65535 \

  -m state –state NEW -j ACCEPT

iptables -A INPUT -p tcp -i eth0 --dport 80 –sport 1024:65535 \

  -m state –state NEW -j ACCEPT


Allowing Your Firewall To Access The Internet

The following iptables sample script allows a user on the firewall to use a web browser to surf the Internet. TCP port 80 is used for HTTP traffic and port 443 is used for HTTPS (secure HTTP frequently used for credit card transactions). HTTPS is also used by RedHat Linux servers using up2date.


#---------------------------------------------------------------
# Allow port 80 (www) and 443 (https) connections to the firewall

#---------------------------------------------------------------

iptables -A OUTPUT -j ACCEPT -m state --state NEW \

  -o eth0 –p tcp -m multiport --dport 80,443 --sport 1024:65535


#---------------------------------------------------------------
# Allow previously established connections

# - Interface eth0 is the internet interface

#---------------------------------------------------------------
iptables -A INPUT -j ACCEPT -m state --state ESTABLISHED,RELATED  \

-i eth0 –p tcp



If you want all TCP traffic originating from the firewall to be accepted then you can remove the following section from the snippet above:


-m multiport --dport 80,443 --sport 1024:65535


Allow Your Home Network To Access The Firewall

In this example, eth1 is directly connected to a home network using IP addresses from the 192.168.1.0 network. All traffic between this network and the firewall is simplistically assumed to be trusted and allowed.  

Further rules will be needed for the interface connected to the Internet to allow only specific ports, types of connections and possibly even remote servers to have access to your firewall and home network.


#---------------------------------------------------------------
# Allow all bidirectional traffic from your firewall to the

# protected network

# - Interface eth1 is the private network interface

#---------------------------------------------------------------


iptables -A INPUT   -j ACCEPT -p all -s 192.168.1.0/24 -i eth1
iptables -A OUTPUT  -j ACCEPT -p all -d 192.168.1.0/24 -o eth1


Masquerading (Many to One NAT)

As explained in the Introduction to Networking chapter, masquerading is another word for what many call "many to one" NAT. In other words, traffic from all devices on one or more protected networks will appear as if it originated from a single IP address on the Internet side of the firewall.  

iptables requires the iptables_nat module to be loaded with the "modprobe" command for the masquerade feature to work. Masquerading also depends on the Linux operating system being configured to support routing between the internet and private network interfaces of the firewall. This is done by enabling "IP forwarding" or routing by giving the file /proc/sys/net/ipv4/ip_forward the value "1" as opposed to the default disabled value of "0".

Once masquerading has been achieved using the POSTROUTING chain of the "nat" table, iptables will have to be configured to allow packets to flow between the two interfaces. This is done using the FORWARD chain of the "filter" table. More specifically, packets related to NEW and ESTABLISHED connections will be allowed outbound to the Internet, while only packets related to ESTABLISHED connections will be allowed inbound. This helps to protect the home network from persons trying to initiate connections from the Internet. An example follows:




#---------------------------------------------------------------
# Load the NAT module

#---------------------------------------------------------------


modprobe iptable_nat
 


#---------------------------------------------------------------
# Allow masquerading

# Enable routing by modifying the ip_forward /proc filesystem file

# - Interface eth0 is the internet interface

# - Interface eth1 is the private network interface

#---------------------------------------------------------------


iptables -A POSTROUTING -t nat -o eth0 -s 192.168.1.0/24 -d 0/0 \

         -j MASQUERADE


echo 1 > /proc/sys/net/ipv4/ip_forward
 

#---------------------------------------------------------------
# Prior to masquerading, the packets are routed via the filter

# table's FORWARD chain.

# Allowed outbound: New, established and related connections

# Allowed inbound : Established and related connections

#---------------------------------------------------------------


iptables -A FORWARD -t filter -i eth1 -m state \

         --state NEW,ESTABLISHED,RELATED -j ACCEPT

iptables -A FORWARD -t filter -i eth0 -m state \

         --state ESTABLISHED,RELATED     -j ACCEPT


Note: If you configure your firewall to do masquerading, then if should be the used as the default gateway for all your servers on the network.


Port Forwarding Type NAT (DHCP DSL)

In many cases home users may get a single DHCP public IP address from their ISP. If their Linux firewall is their interface to the Internet and they want to host a website on one of the NAT protected home servers then they will have to use the “port forwarding” technique.

Here the combination of the firewall's single IP address, the remote server’s IP address and the source/destination port of the traffic can be used to uniquely identify a traffic flow. All traffic that matches a particular combination of these factors may then be forwarded to a single server on the private network.

Port forwarding is handled by the PREROUTING chain of the "nat" table. As in masquerading, the iptables_nat module will have to be loaded and routing enabled for port forwarding to work.  Routing too will have to be allowed in iptables with the FORWARD chain, this would include all NEW inbound connections from the Internet matching the port forwarding port plus all future packets related to the ESTABLISHED connection in both directions. An example follows:




#---------------------------------------------------------------
# Load the NAT module

#---------------------------------------------------------------


modprobe iptable_nat
 

#---------------------------------------------------------------
# Get the IP address of the Internet interface eth0 (linux only)

#

# You'll have to use a different expression to get the IP address

# for other operating systems which have a different ifconfig output

# or enter the IP address manually in the PREROUTING statement

#

# This is best when your firewall gets its IP address using DHCP.

# The external IP address could just be hard coded (“typed in

# normally”)

#---------------------------------------------------------------


external_int="eth0"
external_ip="`ifconfig $external_int | grep 'inet addr' | \

                       awk '{print $2}' | sed -e 's/.*://'`"
 


#---------------------------------------------------------------
# Allow port forwarding for traffic destined to port 80 of the

# firewall’s IP address to be forwarded to port 8080 on server

# 192.168.1.200

#

# Enable routing by modifying the ip_forward /proc filesystem file

# - Interface eth0 is the internet interface

# - Interface eth1 is the private network interface

#---------------------------------------------------------------


iptables -t nat -A PREROUTING -p tcp -i eth0 -d $external_ip \

     --dport 80 --sport 1024:65535 -j DNAT --to 192.168.1.200:8080


echo 1 > /proc/sys/net/ipv4/ip_forward
 

#---------------------------------------------------------------
# After DNAT, the packets are routed via the filter table's

# FORWARD chain.

# Connections on port 80 to the target machine on the private

# network must be allowed.

#---------------------------------------------------------------


iptables -A FORWARD -p tcp -i eth0 -o eth1 -d 192.168.1.200 \

    --dport 8080 --sport 1024:65535 -m state --state NEW -j ACCEPT


iptables -A FORWARD -t filter -i eth1 -m state \

         --state NEW,ESTABLISHED,RELATED -j ACCEPT


iptables -A FORWARD -t filter -i eth0 -m state \

         --state ESTABLISHED,RELATED -j ACCEPT




Static NAT

In this example, all traffic to a particular public IP address, not just to a particular port, is NAT-ted to a single server on the protected subnet. As the firewall has more than one IP address, MASQUERADE isn't recommended to be used as it will force masquerading as the IP address of the primary interface and not any of the alias IP addresses it may have. SNAT is therefore used to specify the alias IP address to be used for connections initiated by all other servers in the protected net.

Note that though the "nat" table NATs all traffic to the target servers (192.168.1.100 to 102), only connections on ports 80,443 and 22 are allowed through by the FORWARD chain.


#---------------------------------------------------------------
# Load the NAT module

#---------------------------------------------------------------


modprobe iptable_nat
 


#---------------------------------------------------------------
# Enable routing by modifying the ip_forward /proc filesystem file

#---------------------------------------------------------------


echo 1 > /proc/sys/net/ipv4/ip_forward


#---------------------------------------------------------------
# NAT ALL traffic:

#

# TO:             FROM:        MAP TO SERVER:

# 97.158.253.26  Anywhere      192.168.1.100

# 97.158.253.27  Anywhere      192.168.1.101

# 97.158.253.28  Anywhere      192.168.1.102

#

# SNAT is used to NAT all other outbound connections initiated

# from the protected network to appear to come from

# IP address 97.158.253.29

#

# - Interface eth0 is the internet interface

# - Interface eth1 is the private network interface

#---------------------------------------------------------------


iptables -t nat -A PREROUTING -d 97.158.253.26 -i eth0 \
         -j DNAT --to-destination 192.168.1.100
iptables -t nat -A PREROUTING -d 97.158.253.27 -i eth0 \
         -j DNAT --to-destination 192.168.1.101
iptables -t nat -A PREROUTING -d 97.158.253.28 -i eth0 \
         -j DNAT --to-destination 192.168.1.102

iptables -A POSTROUTING -s 192.168.1.0/24 \
         -j SNAT -o eth1 --to-source 97.158.253.29

 

iptables -A FORWARD -p tcp -i eth0 -o eth1 -d 192.168.1.100 \

    -m multiport --dport 80,443,22 --sport 1024:65535 \

    -m state --state NEW -j ACCEPT


iptables -A FORWARD -p tcp -i eth0 -o eth1 -d 192.168.1.101 \

    -m multiport --dport 80,443,22 --sport 1024:65535 \

    -m state --state NEW -j ACCEPT


iptables -A FORWARD -p tcp -i eth0 -o eth1 -d 192.168.1.102 \

    -m multiport --dport 80,443,22 --sport 1024:65535 \

    -m state --state NEW -j ACCEPT


iptables -A FORWARD -t filter -i eth1 -m state \

         --state NEW,ESTABLISHED,RELATED -j ACCEPT


iptables -A FORWARD -t filter -i eth0 -m state \

         --state ESTABLISHED,RELATED -j ACCEPT


Logging & Troubleshooting

You track packets passing through the iptables list of rules using the LOG target. You should be aware that the LOG target:

o        will log all traffic that matches the iptables rule in which it is located.

o        automatically writes an entry to the /var/log/messages file and then executes the next rule.

Therefore if you want to log only unwanted traffic then you have to add a matching rule with a DROP target immediately after the LOG rule. If you don’t, you’ll find yourself logging both desired and unwanted traffic with no way of discerning between the two as by default iptables doesn’t state why the packet was logged in its log message.

This example logs a summary of failed packets to the file /var/log/messages. You can use the contents of this file to determine what TCP/UDP ports you need to open to provide access to specific traffic that is currently stopped.


#---------------------------------------------------------------

# Log and drop all other packets to file /var/log/messages

# Without this we could be crawling around in the dark

#---------------------------------------------------------------


iptables -A OUTPUT -j LOG

iptables -A INPUT -j LOG

iptables -A FORWARD -j LOG


iptables -A OUTPUT -j DROP

iptables -A INPUT -j DROP

iptables -A FORWARD -j DROP


Here are some examples of the output of this file:


o        Firewall denying replies to DNS queries (UDP port 53) destined to server 192.168.1.102 on the home network.


Feb 23 20:33:50 bigboy kernel: IN=wlan0 OUT= MAC=00:06:25:09:69:80:00:a0:c5:e1:3e:88:08:00 SRC=192.42.93.30 DST=192.168.1.102 LEN=220 TOS=0x00 PREC=0x00 TTL=54 ID=30485 PROTO=UDP SPT=53 DPT=32820 LEN=200


o        Firewall denying Windows NetBIOS traffic (UDP port 138)


Feb 23 20:43:08 bigboy kernel: IN=wlan0 OUT= MAC=ff:ff:ff:ff:ff:ff:00:06:25:09:6a:b5:08:00 SRC=192.168.1.100 DST=192.168.1.255 LEN=241 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=UDP SPT=138 DPT=138 LEN=221


o        Firewall denying Network Time Protocol (NTP UDP port 123)


Feb 23 20:58:48 bigboy kernel: IN= OUT=wlan0 SRC=192.168.1.102 DST=207.200.81.113 LEN=76 TOS=0x10 PREC=0x00 TTL=64 ID=0 DF PROTO=UDP SPT=123 DPT=123 LEN=56



Note: The traffic in all these examples isn’t destined for the firewall. Therefore you should check your INPUT, OUTPUT, FORWARD and NAT related statements. If the firewall’s IP address is involved, then you should focus on the INPUT, OUTPUT statements

If nothing shows up in the logs, then follow the steps in the Network Troubleshooting chapter to determine whether the data is reaching your firewall at all, and if it is not, the location your network that could be causing the problem.

Troubleshooting NAT: As a general rule, you won’t be able to access the public NAT IP addresses from servers on your home network. Basic NAT testing will require you to ask a friend to try to connect to your home network from the Internet.

You can then use the logging output in /var/log/messages to make sure that:

o        the translations are occurring correctly and

o        iptables isn’t dropping the packets after translation occurs

Trackback 0 Comment 0
2008/08/18 15:33

Tcpdump란?

1. Tcpdump란?
 tcpdump는 Lawrence Berkley Nation Lab의 Network Rearch Gruop에서 만든 것으로 네트워크의 패킷
을 출력해주는 프로그램이다. 주어진 조건식을 만족하는 네트워크 인터페이스를 거치는 패킷들의
헤더들을 출력해 주는 프로그램이다. 주로 쓰임은 지정된 상대방 호스트로부터 들어오는 패킷을 체크
하는 데 있다.

2. tcpdump의 사용법
 (1) 사용법
   tcpdump [options] [host]
 (2) tcpdump의 결과보기 
 [root@www root]# tcpdump 01:37:09.744959 203.xxx.xxx.10.4847 > linux.co.kr.ftp: S 2082495566:2082495566(0) win 16384 (DF)
=> (결과설명) 01:37:09.744959 : Timestamp로 보통 '시간.특정한숫자값'형태로 부여된다. 203.xxx.xxx.10.4847 : Source_address.source_port로 소스의 IP주소와 Port번호를 나타낸 다. > : Traffic direction으로 방향을 나타낸다. linux.co.kr.ftp : destination_address.destination_port로 도착지 IP주소와 Port번호를 나타낸다. S : TCP flag로 특정한 표시문자를 일컫는다. 2082495566:2082495566(0) : sequence number이다. win 16384 : window size이다. : various options 이다. (DF) : Don't fragment 3. tcpdump 플래그(flags)


TCP 플래그
TCPDUMP 플래그
플래그의 의미
SYN
S
SYN패킷, 접속요청을 할 때 보내는 패킷을 말한다.
TCP접속시에 가장먼저 보내는 패킷이다.
ACK
ack
ACK패킷, 상대방으로부터 패킷을 받은 뒤에 알려주는
패킷을 말한다. 다른 플래그와 같이 출력되는 경우도
있다.
FIN
F
접속종료를 위한 플래그로 이 패킷을 보내는 곳이
현재 접속하고 있는 곳과 접속을 끊고자 할 때 사용한다.
RESET
R
이 패킷을 보내는 곳이 현재 접속하고 있는 곳과 즉시
연결을끊고자 할 때 사용한다.
PUSH
P
데이터를 즉시 목적지로 보내라는 의미이다. 텔넷과
같이 상호작용이 중요한 프로그램의 경우 빠른 응답
이 중요한다. 이때 사용하는 플래그이다.
UGENT
URG
긴급한 데이터는 다른 데이터에 비해 우선순위가
높아야 한다. 예를 들어 ftp로 자료를 받고 있는 도중
[CTRL]+[C] 를 받으면 즉시 자료받기를 중단해야 하는
것처럼 이 때 사용하는 플래그이다.
Placeholder
.
패킷이 SYN, FINISH, RESET, PUSH등의 플래그가 없는
경우이 플래그가 세팅된다. 이 플래그는 ACK플래그와
함께 사용되는 경우도 있다.


4. tcpdump의 옵션
 -h: 버전 및 기본 사용법을 보여준다.
 -a : Network & Broadcast 주소들을 이름들로 바꾼다.
 -c Number : 제시된 수의 패킷을 받은 후 종료한다.
 -d : compile된 packet-matching code를 사람이 읽을 수 있도록 바꾸어 표준 출력으로 출력하고,
     종료한다.
 -dd : packet-matching code를 C program의 일부로 출력한다.
 -ddd : packet-matching code를 숫자로 출력한다.
 -e : 출력되는 각각의 행에 대해서 link-level 헤더를 출력한다.
 -f : 외부의 internet address를 가급적 심볼이 아닌 숫자로 출력한다.(Sun의 yp server와의 사용은
     가급적 피한다.)
 -F file : filter 표현의 입력으로 파일을 받아들인다. 커맨드라인에 주어진 추가의 표현들은 모두
          무시된다.
 -i device : 어느 인터페이스를 경유하는 패킷들을 잡을지 지정한다. 지저되지 않으면 시스템의
            인터페이스 리스트를 검색하여 가장 낮은 번호를 가진 인터페이스를 선택한다.(이 때
            loopback은 제외된다.) 예) tcpdump -i eth0
 -l : 표준 출력으로 나가는 데이터들을 line buffering한다. 다른 프로그램에서 tcpdump로부터 데이
     터를 받고자 할 때 유용하다. 보통 'tcpdump -l | tee dat' 나 'tcpdump -l < dat & tail -f
     dat' 명령으로 연계해서 사용하면 편리하다.
 -n : 모든 주소들을 번역하지 않는다(port,host address 등등)
 -N : 호스트 이름을 출력할 때, 도메인을 찍지 않는다.
 -O : packet-matching code optimizer를 실행하지 않는다. 이 옵션은 optimizer에 있는 버그를 찾을
     때나 쓰인다.
 -p : 인터페이스를 promiscuous mode로 두지 않는다.
 -q : 프로토콜에 대한 정보를 덜 출력한다. 따라서 출력되는 라인이 좀 더 짧아진다.
 -r file : 패킷들을 '-w'옵션으로 만들어진 파일로 부터 읽어 들인다. 파일에 "-" 가 사용되면 표준
          입력을 통해서 받아들인다.
 -s length: 패킷들로부터 추출하는 샘플을 default값인 68Byte외의 값으로 설정할 때 사용한다.(Sun
           OS의 NIT에서는 최소가 96Byte이다). 68Byte는 IP,ICMP, TCP, UDP등에 적절한 값이지만
           Name Server나 NFS 패킷들의 경우에는 프로토콜의 정보들을 Truncation할 우려가 있다.
           이 옵션을 수정할 때는 신중해야만 한다. 이유는 샘플 사이즈를 크게 잡으면 곧 패킷 하
           나하나를 처리하는데 시간이 더 걸릴 뿐만아니라 패킷 버퍼의 사이즈도 자연히 작아지게
           되어 손실되는 패킷들이 발생할 수 있기 때문이다. 또, 작게 잡으면 그만큼의 정보를 잃
           게되는 것이다. 따라서 가급적 캡춰하고자 하는 프로토콜의 헤더 사이즈에 가깝게 잡아
           주어야 한다.
 -T type : 조건식에 의해 선택된 패킷들을 명시된 형식으로 표시한다. type에는 다음과 같은 것들이
          올 수 있다. rpc(Remote Procedure Call), rtp(Real-Time Applications protocol), rtcp
          (Real-Time Application control protocal), vat(Visual Audio Tool), wb(distributed
           White Board)
 -S : TCP sequence번호를 상대적인 번호가 아닌 절대적인 번호로 출력한다.
 -t : 출력되는 각각의 라인에 시간을 출력하지 않는다.
 -tt : 출력되는 각각의 라인에 형식이 없는 시간들을 출력한다.
 -v : 좀 더 많은 정보들을 출력한다.
 -vv : '-v'보다 좀 더 많은 정보들을 출력한다.
 -vvv : 16진수값 형태로 정보를 보여준다. 보통 -X옵션과 사용되어
 -w : 캡춰한 패킷들을 분석해서 출력하는 대신에 그대로 파일에 저장한다.
 -x : 각각의 패킷을 헥사코드로 출력한다.
 -X : 헥사코드와 ascii형태 모두 출력해준다. 보통 -x 옵션과 같이 사용된다.
 -조건식(expression!)
  옵션의 제일 마지막인 조건식은 어떤 패킷들을 출력할 지를 선택하는 데 쓰인다. 조건식이 주어지지
 않는다면 모든 패킷들이 대상이 된다. 조건식들은 하나 또는 여러 개의 primitive들로 구성되어 있고
 primitive들은 다시 하나 또는 여러 개의 qualifier들 다음에 오는 하나의 값으로 이루어진다.
  *qualifier
   type : 주어진 값의 종류가 무엇인지를 나타낸다. 가능한 type들은 'host', 'net', 'port'가 있다.
         type이 없는 값들은 type을 host라 가정한다.
   dir : id로 부터의 어떤 특정한 전송 방향을 나타낸다. 가능한 방향은 'src', 'dst', 'src or
        dst', 'src and dst'이다. 만약 방향이 정해지지 않았다면, src or dst라 가정한다. "For
        `null' link layers (i.e. point to point protocols such as slip) the inb ound and out
        bound qualifiers can be used to specify a desired direction."
   proto : 매칭을 특정 프로토콜에 한해서 수행한다. 가능한 프로토콜들은 ether, fddi, ip, arp,
          rarp, decnet, lat, sca, moprc, mopdl, tcp, udp이다. 만약 프로토콜이 명시되지 않았다
          면, 해당하는 값의 type에 관련된 모든 프로토콜들이 그 대상이 된다.
  *위의 패턴을 따르지 않는 primitive : gateway, broadcast, less, greater, 산술식이 있으며 참고
                                   로 더 정교한 조건식을 사용하려면 'and(&&)','or(||)','not(!)'
                                   을 사용할 수 있다.
  *사용가능한 primitive들
   dst host HOST
    => packet의 IP destination 항목이 HOST일때 참이 된다.
   src host HOST
    => packet의 IP source 항목이 HOST일때 참이 된다.
   host HOST
    => IP source, IP destination 항목 중 어느 하나라도 HOST이면 참이다.
   ether dst ehost
    => ethernet destination 주소가 ehost일 때 참이다.
   ether src ehost
    => ethernet source 주소가 ehost일 때 참이다.
   ether host ehost
    => ethernet source, destination 항목들 중 어느 하나라도 ehost이면 참이다.
   gateway host
    => 패킷이 host를 게이트웨이로 사용하면 참이다. 이 말의 의미는 ethernet sour ce나 destina
      tion 항목은 host이지만, IP source와 destination은 host가 아닐 때를 말한다.
   dst net NET
    => 패킷의 IP destination 주소가 NET의 network number를 가지고 있을 때 참이다.
   src net NET
    => 패킷의 IP source 주소가 NET의 network number를 가지고 있을 때 참이다.
   net NET
    => 패킷의 IP source 주소 혹은 destination 주소가 NET의 network number를 가 지고 있을 때
      참이다.
   net netmask mask
    => IP 어드레스가 지정된 netmask를 통해서 net과 매칭되면 참이다.
   net net/len
    => IP 어드레스가 netmask와 len 비트만큼 매치되면 참이다.
   dst port PORT
    => 패킷이 ip/tcp, ip/udp 프로토콜의 패킷이고 destination port의 값이 PORT일 때 참이다.
      port는 /etc/services에 명시된 이름일 수도 있고 그냥 숫자일 수도 있다. 만약 이름이 사용
      됐다면 port 번호와 프로토콜이 같이 체크될 것이다. 만약 숫자나 불 확실한 이름이 사용됐을
      경우에는 port 번호만이 체크될 것이다.
   src port PORT
    => 패킷의 source port의 값으로 PORT를 가지면 참이다.
   port PORT
    => 패킷의 source, destination port 중에 하나라도 PORT이면 참이다.
   less length
    => 패킷이 length보다 짧거나 같으면 참이다.(len <= length)
   greater length
    => 패킷이 length보다 짧거나 같으면 참이다.(len >= length)
   ip proto protocol
    => 패킷이 지정된 종류의 프로토콜의 ip패킷이면 참이다. Protocol은 icmp, igrp, udp, nd, tcp 중의 하나 혹은 몇 개가 될 수 있다. 주의할 점은 tcp, udp, icmp들은 '\'로 escape되어야 한다.
   ehter broadcast
    => 패킷이 ethernet broadcast 패킷이라면 참이다. ehter는 생략 가능하다.
   ip broadcast
    => 패킷이 IP broadcast 패킷이라면 참이다.
   ether multicast 
    => 패킷이 IP multicast 패킷이라면 참이다.
   ether proto protocol
    => 패킷이 ether type의 protocol이라면 참이다. protocol은 ip, arp, rarp 중에 하나 혹은 몇 개가 될 수 있다. ip proto protocol에서와 마찬가지로 ip, arp, rarp는 escape 되어야 한다.
   decnet src host
    => 만약 DECNET의 source address가 host이면 참이다. 이 어드레스는 '10.123'이 나 DECNET의 host name일 수 있다. DECNET host name은 DECNET에서 돌아가도록 설정된 Ultrix 시스템에서 만 사용 가능하다.
   decnet dst host
    => DECNET destination address가 host이면 참이다.
   decnet host HOST
    => DECNET source, destination address중의 하나라도 HOST이면 참이다. ip, arp, rarp, decnet => ether proto [ip|arp|rarp|decnet]의 약어 lat, moprc, mopdl => ether proto [lat|moprc|mopdl]의 약어 tcp, udp, icmp => ip proto [tcp|udp|icmp]의 약어 expr relop expr => EXPR proto [expr:size]의 형식을 띤다. proto, expr, size에 올 수 있는 것들은 다음과 같다. proto : ether, fddi, ip, arp, rarp, tcp, udp, icmp expr : indicate Byte offset of packet of proto size : optional. indicate the size of bytes in field of interest default is one, and can be two or four => RELOP !=, =, <=, >=, etc. 이 조건식을 사용하기 위해서는 먼저 해당하는 Protocol(proto)의 헤더에 관련된 것들을 자세 히 알아야만 한다. proto에는 대상이 될 프로토콜을 지정한다. expr에는 프로토콜 헤더의 처음 부터의 Byte Offset을 지정하는 식이 들어가게 된다. Size는 Option이며 지정이 안 되어 있을 경우에는 자동으로 1byte를 지칭한다. 따라서 이 조건식을 사용하게 되면 헤더에 포함된 정보 를 Bitmask를 사용하여 직 접 원하는 패킷인지를 가려낼 수 있기 때문에, 보다 정밀한 사용이 가능하게 된다.

5. tcpdump 기본사용예
(1) [root@www root]# tcpdump => 현재 서버의 모든 패킷을 보여준다.

(2) [root@www root]# tcpdump port 21
tcpdump: listening on eth0 01:25:43.833276 203.xxx.xxx.100.4828 > xxx.com.ftp: S 1910472596:1910472596(0) win 16384 203.247.40.244.4828: S 4108025962:4108025962(0) ack 1910472597 )
=> 21번 포트로 들어온 패킷만 보여준다.

(3) [root@nanajjang /root]# tcpdump -c 2 host neuro.hannam.ac.kr Kernel filter, protocol ALL, datagram packet socket
tcpdump: listening on all devices 11:09:44.576419 eth0 B arp who-has 203.247.40.247 tell neuro.hannam.ac.kr 11:09:44.576507 eth0 > arp reply 203.247.40.247 (0:c0:26:1:11:77) is-at 0:c0:26)
=> neuro.hannam.ac.kr의 패킷 2개만 보여준다.

(4) tcpdump -v -e broadcast
=> broadcast 의 정보를 자세히 출력하고 출력되는 각각의 행에 대해서 link-level헤더를 출력 한다.

6. tcpdump로 패스워드 알아내기

(1) 설명: telnet을 이용하여 서버에 접속을 하면 패킷전송시에 암호화하지 않기 때문에 쉽게 내용 을 볼 수 있다. tcpdump를 이용하여 패스워드를 알아낼 수 있다.

(2) 사용예
  1) 실행명령 [root@www root]# tcpdump port telnet -l -vvv -x -X >dumpdata & tail -f dumpdata
 
  2) 패킷분석: 패킷의 양이 많으므로 잘 찾아야 한다. 먼저 연결된 포트를 확인한다.
 20:38:22.395281 xxx.com.telnet > 210.xxx.xxx.100.35383: P [tcp sum ok] 175:182(7) ack 81 win 5792 (DF) [tos 0x10] (ttl 64, id 59193, len 59) 0x0000 4510 003b e739 4000 4006 ca41 cbf7 28fc E..;.9@.@..A..(. 0x0010 d27b c1c2 0017 8a37 2992 16d8 2041 b972 .{.....7)....A.r 0x0020 8018 16a0 5fec 0000 0101 080a 04d1 f156 ...._..........V 0x0030 0223 7825 6c6f 6769 6e3a 20 .#x%login:.
=> 서버(xxx.com)에서 클라이언트(210.xxx.xxx.100에게 'login'이라는 것을 보여줌을 알 수 있다. 또한 연결된 클라이언트의 포트번호가 35383임을 알 수 있다. 이 포트번호를 확인해 야 패킷을 찾아갈 수 있다.
---중략---
20:38:23.979306 210.xxx.xxx.100.35383 > xxx.com.telnet: P [tcp sum ok] 81:82(1) ack 182 win 5840 (DF) [tos 0x10] (ttl 56, id 49475, len 53) 0x0000 4510 0035 c143 4000 3806 f83d d27b c1c2 E..5.C@.8..=.{.. 0x0010 cbf7 28fc 8a37 0017 2041 b972 2992 16df ..(..7...A.r)... 0x0020 8018 16d0 5130 0000 0101 080a 0223 78c3 ....Q0.......#x. 0x0030 04d1 f156 70 ...Vp => 클라이언트에서 서버로 전송하는 부분만을 확인하면 된다. P 다음에 존재하는 81:82와 ack 다음에 182라는 번호를 꼭 확인한다. 다음 패킷번호는 82:83이 되고 ack 183번이 되므로 ack 183이라는 부분을 찾아가면 된다. 여기서 클라이언트에서 서버로 전송한 글자는 맨 마지막에 표시된다. 즉 'p'이다.
---중략---
20:38:24.162490 210.xxx.xxx.100.35383 > xxx.com.telnet: P [tcp sum ok] 82:83(1) ack 183 win 5840 (DF) [tos 0x10] (ttl 56, id 49477, len 53) 0x0000 4510 0035 c145 4000 3806 f83b d27b c1c2 E..5.E@.8..;.{.. 0x0010 cbf7 28fc 8a37 0017 2041 b973 2992 16e0 ..(..7...A.s)... 0x0020 8018 16d0 4ef0 0000 0101 080a 0223 78d6 ....N........#x. 0x0030 04d1 f481 6f ....o
---중략---
20:38:24.322785 210.xxx.xxx.100.35383 > xxx.com.telnet: P [tcp sum ok] 83:84(1) ack 184 win 5840 (DF) [tos 0x10] (ttl 56, id 49479, len 53) 0x0000 4510 0035 c147 4000 3806 f839 d27b c1c2 E..5.G@.8..9.{.. 0x0010 cbf7 28fc 8a37 0017 2041 b974 2992 16e1 ..(..7...A.t)... 0x0020 8018 16d0 4a80 0000 0101 080a 0223 78e6 ....J........#x. 0x0030 04d1 f4df 73 ....s
---중략---
20:38:24.445142 210.xxx.xxx.100.35383 > xxx.com.telnet: P [tcp sum ok] 84:85(1) ack 185 win 5840 (DF) [tos 0x10] (ttl 56, id 49481, len 53) 0x0000 4510 0035 c149 4000 3806 f837 d27b c1c2 E..5.I@.8..7.{.. 0x0010 cbf7 28fc 8a37 0017 2041 b975 2992 16e2 ..(..7...A.u)... 0x0020 8018 16d0 5820 0000 0101 080a 0223 78f2 ....X........#x. 0x0030 04d1 f531 65 ...1e
---중략---
20:38:24.532360 210.xxx.xxx.100.35383 > xxx.com.telnet: P [tcp sum ok] 85:86(1) ack 186 win 5840 (DF) [tos 0x10] (ttl 56, id 49483, len 53) 0x0000 4510 0035 c14b 4000 3806 f835 d27b c1c2 E..5.K@.8..5.{.. 0x0010 cbf7 28fc 8a37 0017 2041 b976 2992 16e3 ..(..7...A.v)... 0x0020 8018 16d0 53d6 0000 0101 080a 0223 78fb ....S........#x. 0x0030 04d1 f570 69 ...pi
---중략---
20:38:24.624350 210.xxx.xxx.100.35383 > xxx.com.telnet: P [tcp sum ok] 86:87(1) ack 187 win 5840 (DF) [tos 0x10] (ttl 56, id 49485, len 53) 0x0000 4510 0035 c14d 4000 3806 f833 d27b c1c2 E..5.M@.8..3.{.. 0x0010 cbf7 28fc 8a37 0017 2041 b977 2992 16e4 ..(..7...A.w)... 0x0020 8018 16d0 4e9f 0000 0101 080a 0223 7904 ....N........#y. 0x0030 04d1 f59c 6e ....n
---중략---
=> posein이라는 글자를 알 수 있다. 즉 사용자 ID가 posein이다.
20:38:24.932380 xxx.com.telnet > 210.xxx.xxx.100.35383: P [tcp sum ok] 190:200(10) ack 89 win 5792 (DF) [tos 0x10] (ttl 64, id 59201, len 62) 0x0000 4510 003e e741 4000 4006 ca36 cbf7 28fc E..>.A@.@..6..(. 0x0010 d27b c1c2 0017 8a37 2992 16e7 2041 b97a .{.....7)....A.z 0x0020 8018 16a0 d40b 0000 0101 080a 04d1 f669 ...............i 0x0030 0223 7923 5061 7373 776f 7264 3a20 .#y#Password:.
=> 서버에서 클라이언트에서 Password라는 글을 보내어 출력시킨다.
---중략---
20:38:25.300524 210.xxx.xxx.100.35383 > xxx.com.telnet: P [tcp sum ok] 89:90(1) ack 200 win 5840 (DF) [tos 0x10] (ttl 56, id 49490, len 53) 0x0000 4510 0035 c152 4000 3806 f82e d27b c1c2 E..5.R@.8....{.. 0x0010 cbf7 28fc 8a37 0017 2041 b97a 2992 16f1 ..(..7...A.z)... 0x0020 8018 16d0 557f 0000 0101 080a 0223 7947 ....U........#yG 0x0030 04d1 f669 66 ...ip
---중략---
20:38:25.454778 210.xxx.xxx.100.35383 > xxx.com.telnet: P [tcp sum ok] 90:91(1) ack 200 win 5840 (DF) [tos 0x10] (ttl 56, id 49491, len 53) 0x0000 4510 0035 c153 4000 3806 f82d d27b c1c2 E..5.S@.8..-.{.. 0x0010 cbf7 28fc 8a37 0017 2041 b97b 2992 16f1 ..(..7...A.{)... 0x0020 8018 16d0 489e 0000 0101 080a 0223 7957 ....H........#yW 0x0030 04d1 f739 72 ...9a
---중략---
20:38:25.659340 210.xxx.xxx.100.35383 > xxx.com.telnet: P [tcp sum ok] 91:92(1) ack 200 win 5840 (DF) [tos 0x10] (ttl 56, id 49492, len 53) 0x0000 4510 0035 c154 4000 3806 f82c d27b c1c2 E..5.T@.8..,.{.. 0x0010 cbf7 28fc 8a37 0017 2041 b97c 2992 16f1 ..(..7...A.|)... 0x0020 8018 16d0 554e 0000 0101 080a 0223 796b ....UN.......#yk 0x0030 04d1 f774 65 ...ts
---중략---
20:38:25.777475 210.xxx.xxx.100.35383 > xxx.com.telnet: P [tcp sum ok] 92:93(1) ack 200 win 5840 (DF) [tos 0x10] (ttl 56, id 49493, len 53) 0x0000 4510 0035 c155 4000 3806 f82b d27b c1c2 E..5.U@.8..+.{.. 0x0010 cbf7 28fc 8a37 0017 2041 b97d 2992 16f1 ..(..7...A.})... 0x0020 8018 16d0 54d8 0000 0101 080a 0223 7977 ....T........#yw 0x0030 04d1 f7dd 65 ....s
---중략---
20:38:26.049208 210.xxx.xxx.100.35383 > xxx.com.telnet: P [tcp sum ok] 93:94(1) ack 200 win 5840 (DF) [tos 0x10] (ttl 56, id 49494, len 53) 0x0000 4510 0035 c156 4000 3806 f82a d27b c1c2 E..5.V@.8..*.{.. 0x0010 cbf7 28fc 8a37 0017 2041 b97e 2992 16f1 ..(..7...A.~)... 0x0020 8018 16d0 887f 0000 0101 080a 0223 7992 .............#y. 0x0030 04d1 f81a 31 ....w
---중략---
20:38:26.243634 210.xxx.xxx.100.35383 > xxx.com.telnet: P [tcp sum ok] 94:95(1) ack 200 win 5840 (DF) [tos 0x10] (ttl 56, id 49495, len 53) 0x0000 4510 0035 c157 4000 3806 f829 d27b c1c2 E..5.W@.8..).{.. 0x0010 cbf7 28fc 8a37 0017 2041 b97f 2992 16f1 ..(..7...A..)... 0x0020 8018 16d0 86df 0000 0101 080a 0223 79a6 .............#y. 0x0030 04d1 f8a5 32 ....o
---중략---
20:38:26.442302 210.xxx.xxx.100.35383 > xxx.com.telnet: P [tcp sum ok] 95:96(1) ack 200 win 5840 (DF) [tos 0x10] (ttl 56, id 49496, len 53) 0x0000 4510 0035 c158 4000 3806 f828 d27b c1c2 E..5.X@.8..(.{.. 0x0010 cbf7 28fc 8a37 0017 2041 b980 2992 16f1 ..(..7...A..)... 0x0020 8018 16d0 8768 0000 0101 080a 0223 79b9 .....h.......#y. 0x0030 04d1 f908 31 ....r
---중략---
20:38:26.540930 210.xxx.xxx.100.35383 > xxx.com.telnet: P [tcp sum ok] 96:97(1) ack 200 win 5840 (DF) [tos 0x10] (ttl 56, id 49497, len 53) 0x0000 4510 0035 c159 4000 3806 f827 d27b c1c2 E..5.Y@.8..'.{.. 0x0010 cbf7 28fc 8a37 0017 2041 b981 2992 16f1 ..(..7...A..)... 0x0020 8018 16d0 80f7 0000 0101 080a 0223 79c3 .............#y. 0x0030 04d1 f96e 37 ...nd
---이하생략---
=> 패스워드가 password라는 것을 알 수 있다.출처 : http://www.attikorea.com/secuutil/tcpdump.html

TCPDUMP User Guide

Date : January 1999


written by Kwon, YongChul

-. 이 문서의 저작권은 저자(권용철:godslord@sparcs.kaist.ac.kr)에게 있습니다. 본문의 무단 인용, 복사는 저자와의 협의 없이 절대 불가능합니다.


Table of Contents


이 문서를 보기 전에 알아야 할 사전 지식

Tcpdump란?

Tcpdump의 패키지 구하기

Tcpdump의 설치

Tcpdump Source의 간략한 설명

Tcpdump의 옵션들

조건식
Tcpdump의 사용 예제들

Tcpdump의 평가

References


이 문서를 보기 전에 알아야 할 사전 지식

이 문서는 네트워크의 패킷들을 잡아내는 Tcpdump라는 프로그램에 대해서 설명하고 있다. 프로그램의 특성상, 네트워크에 관련된 많은 용어들과 특히 TCP/IP에 대한 내용 이 많이 나온다. 따라서 보다 잘 이해하기 위해서는 네트워크 설비 자료나, 네트워크 프로그래밍 가이드, 혹은 네트워크 프로토콜(TCP/IP)에 관련된 책들을 참조하는 것이 좋을 것이다.



Tcpdump란?

Tcpdump는 주어진 조건식을 만족하는 네트워크 인터페이스를 거치는 패킷들의 헤더들 을 출력해 주는 프로그램이다. 프로그램의 특성상, 네트워크 인터페이스를 아주 심도 있게 사용하기 때문에, 실행하는 사람은 반드시 네트워크 인터페이스에 대한 읽기 권 한이 있어야만 한다.
OS dependent)
위에서 말하는 읽기 권한을 가지고 있어야 하는 파일, 혹은 Tcpdump의 퍼미션 이다.

SunOS : /dev/nit, /dev/bpf*

Solaris(SunOS 5.x) : /dev/le 등

HP-UX & IRIX & Linux : root에서 실행하거나, root로 setuid를 설정해야 함

Ultrix & Digital UNIX : root가 pfconfig를 이용하여, promiscuous-mode를 가능하게 설정하면 어떤 유저라도 사용할 수 있다.

BSD : /dev/bpf*


Tcpdump의 패키지 구하기

Tcpdump는 ftp://ftp.ee.lbl.gov/tcpdump.tar.Z에서 최신 버전을 구할 수 있다. 유명 한 프로그램이기 때문에, 시스템소프트웨어를 패키지형태로 제공해 주는 OS들의 경우 Vendor에서 패키징된(컴파일된) 버전으로도 구할 수 있을 것이다.



Tcpdump의 설치

Tcpdump는 libpcap(Protocol Capture Library)라는 것을 사용한다. 이 라이브러리는 Platform에 상관없이 동일한 방법으로 사용자 레벨에서 패킷들을 캡춰할 수 있게 해 준다. 따라서 이 라이브러리가 없다면, ftp://ftp.ee.lbl.gov/libpcap.tar.Z에서 구하 여 설치하도록 한다.

ANSI C 컴파일러는 아마 대부분의 시스템에서 구비하고 있을 것이다. 만약 없다면 ftp://prep.ai.mit.edu/pub/gnu/gcc.tar.gz를 받아서 설치하기 바란다.

libpcap라이브러리가 완벽하게 설치되었다는 가정하에서 다음의 절차에 따라 설치를 시작한다.


Makefile.in의 BINDEST와 MANDEST 항목에 각각, tcpdump 실행파일과 메뉴얼 페이 지가 설치될 디렉토리들을 입력해 준다.
Tcpdump 패키지와 함께 제공되는 ./configure 스크립트를 실행시킨다. 이 스크립트는 현재 시스템의 환경들을 검사하고 이에 맞추어서 Makefile을 생성해 준다.
make를 실행한다.
컴파일이 다 됐으면, make install을 수행하여 실행파일을 설치하고, make install-man을 실행하여 메뉴얼 페이지도 설치한다.
tcpdump의 퍼미션이 제대로 되었는지를 검사한다. setgid가 설정되어 있기 때문에, 원하지 않는 사람이 실행하게 된다면 위험하다. 위에서 설명한 절차를 그대로 옮겨 본다. # vi Makefile.in
# ./configure
# make
# make install
# make install-man
OS dependent)

DEC/OSF and BSD/386, etc : tcpdump가 OS와 함께 제공되는 경우가 있다. 이럴 경우 tcpdump를 업그레이드 하기 전에 반드시 기존의 tcpdump를 백업해 두도록 하자.

Linux : libpcap 라이브러리는 2.0.25 커널에서 테스트 됐다. 2.0.x 대 커널 에서 25이하의 버전에서는 실행이 아마 가능할 것이다. 그러나 1.x대의 커널에서는 동작 여부가 입증되지 않았으므로 주의해야 한다.

OSF 4 : OSF4에서는 stack C 컴파일러에 치명적인 버그가 있다. 이 버그를 피해가려면, ./configure를 실행한 후 컴파일 하기 전에 Makefile에서 다음의 문장을 삭제한 후 컴파일해 주면 된다.
            -DETHER_HEADER_HAS_EA=1 -DETHER_ARP_HAS_EA=1
 


Tcpdump Source의 간략한 설명



Tcpdump의 옵션들


-a : Network & Broadcast 주소들을 이름들로 바꾼다.

-c Number : 제시된 수의 패킷을 받은 후 종료한다.

-d : comile된 packet-matching code를 사람이 읽을 수 있도록 바꾸어 표준 출력으로 출력하고, 종료한다.

-dd : packet-matching code를 C program의 일부로 출력한다.

-ddd : packet-matching code를 숫자로 출력한다.

-e : 출력되는 각각의 행에 대해서 link-level 헤더를 출력한다.

-f : 외부의 internet address를 가급적 심볼로 출력한다(Sun의 yp server와의 사용은 가급적 피하자).

-F file : filter 표현의 입력으로 파일을 받아들인다. 커맨드라인에 주어진 추가의 표현들은 모두 무시된다.

-i device : 어느 인터페이스를 경유하는 패킷들을 잡을지 지정한다. 지저되지 않으면 시스템의 인터페이스 리스트를 뒤져서 가장 낮은 번호를 가진 인터페이스를 선택한다(이 때 loopback은 제외된다).

-l : 표준 출력으로 나가는 데이터들을 line buffering한다. 다른 프로그램에서 tcpdump로부터 데이터를 받고자 할 때, 유용하다.

-n : 모든 주소들을 번역하지 않는다(port,host address 등등)

-N : 호스트 이름을 출력할 때, 도메인을 찍지 않는다.

-O : packet-matching code optimizer를 실행하지 않는다. 이 옵션은 optimizer에 있는 버그를 찾을 때나 쓰인다.

-p : 인터페이스를 promiscuous mode로 두지 않는다.

-q : 프로토콜에 대한 정보를 덜 출력한다. 따라서 출력되는 라인이 좀 더 짧아진다.

-r file : 패킷들을 '-w'옵션으로 만들어진 파일로 부터 읽어 들인다. 파일에 "-" 가 사용되면 표준 입력을 통해서 받아들인다.

-s length: 패킷들로부터 추출하는 샘플을 default값인 68Byte외의 값으로 설정할 때 사용한다(SunOS의 NIT에서는 최소가 96Byte이다). 68Byte는 IP,ICMP, TCP, UDP등에 적절한 값이지만 Name Server나 NFS 패킷들의 경우에는 프로토콜의 정보들을 Truncation할 우려가 있다. 이 옵션을 수정할 때는 신중해야만 한다. 이유는 샘플 사이즈를 크게 잡으면 곧 패킷 하나하나를 처리하는데 시간이 더 걸릴 뿐만아니라 패킷 버퍼의 사이즈도 자연히 작아지게 되어 손실되는 패킷들이 발생할 수 있기 때문이다. 또, 작게 잡으면 그만큼의 정보를 잃게되는 것이다. 따라서 가급적 캡춰하고자 하는 프로토콜의 헤더 사이즈에 가깝게 잡아주어야 한다.

-T type : 조건식에 의해 선택된 패킷들을 명시된 형식으로 표시한다. type에는 다음과 같은 것들이 올 수 있다. rpc(Remote Procedure Call), rtp(Real-Time Applications protocol), rtcp(Real-Time Application control protocal), vat(Visual Audio Tool), wb(distributed White Board)

-S : TCP sequence번호를 상대적인 번호가 아닌 절대적인 번호로 출력한다.

-t : 출력되는 각각의 라인에 시간을 출력하지 않는다.

-tt : 출력되는 각각의 라인에 형식이 없는 시간들을 출력한다.

-v : 좀 더 많은 정보들을 출력한다.

-vv : '-v'보다 좀 더 많은 정보들을 출력한다.

-w : 캡춰한 패킷들을 분석해서 출력하는 대신에 그대로 파일에 저장한다.

-x : 각각의 패킷을 헥사코드로 출력한다.


조건식(expression!)

옵션의 제일 마지막인 조건식은 어떤 패킷들을 출력할지를 선택하는데 쓰인다. 조건식이 주어지지 않는 다면 모든 패킷들이 그 대상이 될 것이다. 일단 주어지면, 아무리 패킷들이 많아도 조 건식에 부합하는 패킷만을 출력한다.

조건식들은 하나 또는 몇 개의 primitive들로 구성되어 있다. primitive들은 보통 하나 혹은 몇개의 qualifier들 다음에 오는 하나의 값으로 이루어진다. Qualifier들은 모두 3 종류이며 다음과 같다.


type : 주어진 값의 종류가 무엇인지를 나타낸다. 가능한 type들은 'host', 'net', 'port'가 있다. type이 없는 값들은 type을 host라 가정한다.

dir : id로 부터의 어떤 특정한 전송 방향을 나타낸다. 가능한 방향은 'src', 'dst', 'src or dst', 'src and dst'이다. 만약 방향이 정해지지 않았다면, src or dst라 가정한다. "For `null' link layers (i.e. point to point protocols such as slip) the inb ound and out bound qualifiers can be used to specify a desired direction."

proto : 매칭을 특정 프로토콜에 한해서 수행한다. 가능한 프로토콜들은 ether, fddi, ip, arp, rarp, decnet, lat, sca, moprc, mopdl, tcp, udp이다. 만약 프로토콜이 명시되지 않았다면, 해당하는 값의 type에 관련된 모든 프로토콜들이 그 대상이 된다.


이 밖에도 위의 패턴을 따르지 않는 Primitive들이 존재한다(gateway, broadcst, less, greater, 산술식).

좀 더 정교한 조건식들을 사용하려면, 'and(&&)', 'or(||)', 'not(!)'들을 사용하여 여러 primitive들을 연결하면 된다. 같은 표현들은 생략될 수 있다.

사용 가능한 Primitive들


dst host HOST
packet의 IP destination 항목이 HOST일때 참이 된다.
src host HOST
packet의 IP source 항목이 HOST일때 참이 된다.
host HOST
IP source, IP destination 항목 중 어느 하나라도 HOST이면 참이다.
ether dst ehost
ethernet destination 주소가 ehost일 때 참이다.
ether src ehost
ethernet source 주소가 ehost일 때 참이다.
ether host ehost
ethernet source, destination 항목들 중 어느 하나라도 ehost이면 참이다.
gateway host
패킷이 host를 게이트웨이로 사용하면 참이다. 이 말의 의미는 ethernet sour ce나 destination 항목은 host이지만, IP source와 destination은 host가 아닐 때를 말한다.
dst net NET
패킷의 IP destination 주소가 NET의 network number를 가지고 있을 때 참이 다.
src net NET
패킷의 IP source 주소가 NET의 network number를 가지고 있을 때 참이다.
net NET
패킷의 IP source 주소 혹은 destination 주소가 NET의 network number를 가 지고 있을 때 참이다.
net netmask mask
IP 어드레스가 지정된 netmask를 통해서 net과 매칭되면 참이다.
net net/len
IP 어드레스가 netmask와 len 비트만큼 매치되면 참이다.
dst port PORT
패킷이 ip/tcp, ip/udp 프로토콜의 패킷이고 destination port의 값이 PORT일 때 참이다. port는 /etc/services에 명시된 이름일 수도 있고 그냥 숫자일 수도 있다. 만약 이름이 사용됐다면 port 번호와 프로토콜이 같이 체크될 것이다. 만약 숫자나 불 확실한 이름이 사용됐을 경우에는 port 번호만이 체크될 것이다.
src port PORT
패킷의 source port의 값으로 PORT를 가지면 참이다.
port PORT
패킷의 source, destination port 중에 하나라도 PORT이면 참이다.
less length
패킷이 length보다 짧거나 같으면 참이다.(len <= length)
greater length
패킷이 length보다 짧거나 같으면 참이다.(len >= length)
ip proto protocol
패킷이 지정된 종류의 프로토콜의 ip패킷이면 참이다. Protocol은 icmp, igrp, udp, nd, tcp 중의 하나 혹은 몇 개가 될 수 있다. 주의할 점은 tcp, udp, icmp들은 '\'로 escape되어야 한다.
ehter broadcast
패킷이 ethernet broadcast 패킷이라면 참이다. ehter는 생략 가능하다.
ip broadcast
패킷이 IP broadcast 패킷이라면 참이다.
ether multicast
패킷이 IP multicast 패킷이라면 참이다.
ether proto protocol
패킷이 ether type의 protocol이라면 참이다. protocol은 ip, arp, rarp 중에 하나 혹은 몇개가 될 수 있다. ip proto protocol에서와 마찬가지로 ip, arp, rarp는 escape 되어야 한다.
decnet src host
만약 DECNET의 source address가 host이면 참이다. 이 어드레스는 '10.123'이 나 DECNET의 host name일 수 있다. DECNET host name은 DECNET에서 돌아가도록 설정된 Ultrix 시스템에서만 사용 가능하다.
decnet dst host
DECNET destination address가 host이면 참이다.
decnet host HOST
DECNET source, destination address중의 하나라도 HOST이면 참이다.
ip, arp, rarp, decnet
ether proto [ip|arp|rarp|decnet]의 약어
lat, moprc, mopdl
ether proto [lat|moprc|mopdl]의 약어
tcp, udp, icmp
ip proto [tcp|udp|icmp]의 약어
expr relop expr

EXPR
proto [expr:size]의 형식을 띤다. proto, expr, size에 올 수 있는 것들은 다음과 같다.
proto : ether, fddi, ip, arp, rarp, tcp, udp, icmp
expr : indicate Byte offset of packet of proto
size : optional. indicate the size of bytes in field of interest
default is one, and can be two or four
RELOP
!=, =, <=, >=, etc.

이 조건식을 사용하기 위해서는 먼저 해당하는 Protocol(proto)의 헤더에 관련된 것들을 자세히 알아야만 한다. proto에는 대상이 될 프로토콜을 지정한다. expr에는 프로토콜 헤더의 처음부터의 Byte Offset을 지정하는 식이 들어가게 된다. Size는 Option이며 지정이 안 되어 있을 경우에는 자동으로 1byte를 지칭한다. 따라서 이 조건식을 사용하게 되면 헤더에 포함된 정보를 Bitmask를 사용하여 직 접 원하는 패킷인지를 가려낼 수 있기 때문에, 보다 정밀한 사용이 가능하게 된다.



Tcpdump의 사용 예제들


security라는 호스트로부터 날아오고, 날아가는 패킷들을 출력
# tcpdump host security
security와 mazinga, getarobo 사이에 날아다니고 있는 패킷들을 출력
# tcpdump host security and \( mazinga or getarobo \)
security에서 elgaim을 제외한 모든 호스트로 날아다니는 IP 패킷들을 출력
# tcpdump ip host security and not elgaim
gateway amurorei를 거치는 ftp에 관련된 패킷들을 출력
# tcpdump 'gateway amurorei and ( port ftp or ftp-data )'
local호스트가 아닌 호스트와 로컬호스트가 맺는 TCP 커넥션의 시작과 마지막 패 킷들을 출력한다(SYN, FIN 패킷).
# tcpdump 'tcp[13] & 3 != 0 and not src and dst net non-local'
gateway amurorei를 지나는 576Byte보다 큰 패킷들을 출력한다
# tcpdump 'gateway amurorei and ip[2:2] > 576'
Ethernet boradcast 혹은 multicast를 통해서 보내진 것이 아닌, IP broadcast 혹 은 multicast 패킷들을 출력한다.
# tcpdump 'ehter[0] & 1 = 0 and ip[16] >= 224'
Echo request/reply가 아닌 ICMP 패킷들을 모두 출력한다.
# tcpdump 'icmp[0] != 8 and icmp[0] != 0'


Tcpdump의 평가

TCPDUMP는 여러모로 좋은 툴이다. libpcap을 거의 100% 활용한 프로그램의 예이며, 실제로 많은 툴들이 TCPDUMP와 병행하여 돌아가거나, TCPDUMP를 기반으로 제작되었다. TCPDUMP의 막강한 packet filter는 현재 로컬 네트워크 상에서 날아다니고 있는 특정한 패킷들을 실시간으로 기록해 줄 수 있으며, 이를 이용하여 네트워크에서 벌어지는 일들을 네트워크 관리자가 원하는 대로 뽑아 볼 수 있게 해 준다. 또한, 시스템 관리자들에게는 로컬 유저의 외부로의 커넥션들을 감시하고, 또 특정 침입자가 침투 경로로 자주 이용하는 호스트, 혹은 원하지 않는 호스트로부터의 커넥션을 실시간으로 감시할 수 있게 해 준다. libpcap을 이용하여 비슷한 툴을 제작하고자 하는 사람들에게도 TCPDUMP는 가장 훌륭한 예제가 될 것이다.

Trackback 0 Comment 0
2008/08/16 22:39

grep으로 검색된 문자에 색 넣기(highlight)

  log나 text로 이루어진 문서를 grep으로 검색하다보면 가끔 내가 검색한 단어가
잘 보이지 않을때가 있다.

그럴때는 grep 옵션으로 중에 highlight를 넣는 기능을 이용하여 쉽게 단어를 찾을 수가 있다.

export GREP_OPTIONS='--color=auto' GREP_COLOR='타잎;글색;배경색'

GREP_OPTIONS)
--color= auto / always
auto와 always란 두 가지 기능이 있지만 별 차이는 없다.

GREP_COLOR)
'타잎;글색;배경색'
기본적으로 ANSI Escape Code의 색상을 따른다.

※색상코드


분명 편하고 찾고자 하는 문구를 쉽게 확인할 수 있는 장점이 있다.
하지만 주의해야할 점은 컴파일시 grep을 쓰는 경우가 상당히 많이 있다.
이럴경우 ANSI로 색이 덮혀 있는 글자는

^[[숫자m


라는 ANSI CODE가 들어가서 정상적으로 컴파일이 되지 않는 경우가 있다.
이점을 필히 주의 하기 바란다.
Trackback 0 Comment 0