반응형

OS: Ubuntu 14.04.1 LTS, Raspbian Jessie

tcpdump: Version 4.6.2 (libpcap 1.6.2)



리눅스에서 네트워크(e.g. 메쉬 네트워크)에 참여하는 각각의 기기가 자신을 거쳐 가는 모든 트래픽 사용량을 네트워크 인터페이스별로 구분해서 통계를 낼 필요가 생겼다.


Tcpdump에서는 "-i any" 옵션을 써서 한꺼번에 모든 인터페이스를 모니터링할 수는 있다. 하지만 아쉽게도 화면에 표시되는 로그 한 줄이 어느 네트워크 인터페이스에 연관된 것인지 알 수 없다. 특히 멀티라디오 멀티채널 라우팅 프로토콜을 돌리는 메쉬 라우터의 입장에서는 지나가는 트래픽 플로우 하나가 어느 네트워크 인터페이스를 거쳐서 지나가고, 소비하는 대역폭의 양이 어느 정도인지 반드시 확인해야 한다.


결국 두 가지 방법 중 하나를 써야 한다.

  1. Tcpdump 인스턴스 하나를 모든 네트워크 인터페이스에 대해서 검사하도록 실행하고, tcpdump에 찍히는 source, destination IP 주소를 검사해서 어느 네트워크 인터페이스에 해당되는지 확인(예측)하는 방법
  2. 각 네트워크 인터페이스별로 tcpdump 인스턴스를 별도로 실행하고, 각 인터페이스별로 구분되는 로그를 활용하기


처음에는 내가 1번 방식을 써서 라우팅 프로토콜에서 tcpdump 로그를 파싱하고 source, destination IP주소를 가지고 네트워크 인터페이스 이름을 알아내는 함수를 코딩해서 썼는데, 예상치 못한 문제가 발생했다. 로그에 찍히는 source와 destination IP 주소가 현재 로깅을 하는 기기와 상관없는 원격지의 IP주소일 경우에는 어느 인터페이스를 통해서 패킷이 들어오고 나가는지 알 수가 없었다. 아주 불가능한 것은 아니지만, 라우팅 테이블에 접근해서 source, destination 양쪽으로 가는 경로와 네트워크 인터페이스를 확인해야 했다. 그리고 외부에서 현재 기기로 들어오는 패킷인지, 패킷이 현재 기기를 통해서 다른 노드(next hop)로 빠져나가는 것인지를 tcpdump 로그에서는 알 길이 없었다. 라우터 입장에서는 똑같은 로그가 두 줄이 찍히는 것처럼 표시가 되었다.


결국 2번 방법을 쓰기로 하고 인터넷을 찾아보니 나와 비슷한 목적으로 tcpdump를 응용하는 사례가 이미 있었다. [1]

핵심은, 동시에 여러 개의 tcpdump 인스턴스를 실행하고, 그 대신 각 인스턴스에서 로그가 한 줄 찍힐 때마다 앞에 네트워크 인터페이스 이름을 추가해서 한 화면에 모두 출력하는 것이고, 이것을 bash script로 만든 것이 첫 번째 답변이다. ([2]에도 있음)


다만 [1]과 [2]에 소개된 스크립트가 라즈베리파이에서는 에러가 나서, 그냥 옵션들 빼고 여러 인터페이스를 동시에 쓰도록 간단하게 만들었다.


[anydump2.sh]

#!/bin/sh


# Get a list of interface names from a user by an argument. (e.g. 'eth0 wlan0')

# Note that the list of interfaces separated by a space should be inside '' or "".

IFLIST=$1


# When this exits, exit all background processes:

trap 'kill $(jobs -p) &> /dev/null && sleep 0.2 &&  echo ' EXIT


# Create one tcpdump output per interface and add the interface name in front of each line:

for interface in $IFLIST

do

        tcpdump -l -i $interface -Nn -b ip -tttt | sed 's/^/'"$interface"' /' 2>/dev/null &

done


# Wait until Ctrl+C

wait



사용 예시:


무선 인터페이스 3개(wlan0, wlan1, wlan2)를 모니터링할 경우,

$ sudo ./anydump2.sh 'wlan0 wlan1 wlan2'



출력 예시:

(listening 이후부터 출력되는 로그의 맨 앞에 인터페이스 이름이 다르게 찍히는 것을 볼 수 있다)


cdsn@cdsn-HP-EliteBook-2740p:~/exp/tcpdm-monitor$ sudo ./anydump2.sh 'wlan0 wlan1 wlan2'

[sudo] password for cdsn: 

tcpdump: verbose output suppressed, use -v or -vv for full protocol decode

listening on wlan0, link-type EN10MB (Ethernet), capture size 65535 bytes

tcpdump: verbose output suppressed, use -v or -vv for full protocol decode

listening on wlan2, link-type EN10MB (Ethernet), capture size 65535 bytes

tcpdump: verbose output suppressed, use -v or -vv for full protocol decode

listening on wlan1, link-type EN10MB (Ethernet), capture size 65535 bytes

wlan0 2016-09-05 17:42:41.671768 IP 192.168.4.6 > 192.168.4.5: ICMP echo request, id 2210, seq 1, length 64

wlan0 2016-09-05 17:42:41.671861 IP 192.168.4.5 > 192.168.4.6: ICMP echo reply, id 2210, seq 1, length 64

wlan0 2016-09-05 17:42:42.650726 IP 192.168.4.6 > 192.168.4.5: ICMP echo request, id 2210, seq 2, length 64

wlan0 2016-09-05 17:42:42.650783 IP 192.168.4.5 > 192.168.4.6: ICMP echo reply, id 2210, seq 2, length 64

wlan0 2016-09-05 17:42:43.650913 IP 192.168.4.6 > 192.168.4.5: ICMP echo request, id 2210, seq 3, length 64

wlan0 2016-09-05 17:42:43.650952 IP 192.168.4.5 > 192.168.4.6: ICMP echo reply, id 2210, seq 3, length 64

wlan1 2016-09-05 17:42:47.740037 IP 192.168.3.6 > 192.168.3.5: ICMP echo request, id 2211, seq 2, length 64

wlan1 2016-09-05 17:42:47.740121 IP 192.168.3.5 > 192.168.3.6: ICMP echo reply, id 2211, seq 2, length 64

wlan1 2016-09-05 17:42:48.752034 IP 192.168.3.6 > 192.168.3.5: ICMP echo request, id 2211, seq 3, length 64

wlan1 2016-09-05 17:42:48.752080 IP 192.168.3.5 > 192.168.3.6: ICMP echo reply, id 2211, seq 3, length 64

wlan1 2016-09-05 17:42:49.747415 IP 192.168.3.6 > 192.168.3.5: ICMP echo request, id 2211, seq 4, length 64

wlan1 2016-09-05 17:42:49.747452 IP 192.168.3.5 > 192.168.3.6: ICMP echo reply, id 2211, seq 4, length 64

^C6 packets captured6 packets captured


6 packets received by filter6 packets received by filter


0 packets dropped by kernel0 packets dropped by kernel


0 packets captured

0 packets received by filter

0 packets dropped by kernel

wlan1 

wlan0 

wlan2 

cdsn@cdsn-HP-EliteBook-2740p:~/exp/tcpdm-monitor$ 





<참고자료>

[1] StackOverflow, "How to display interface in tcpdump output flow?," http://serverfault.com/questions/224698/how-to-display-interface-in-tcpdump-output-flow

[2] Sebastian Haas, "Anydump 1.3," http://sebastianhaas.de/anydump-release/



반응형
블로그 이미지

Bryan_

,
반응형

OS: Ubuntu 14.04 Desktop



scp 명령으로 IP주소를 알고 있는 원격 리눅스 머신에 파일을 전송할 수 있는데, 이 때 콘솔 창 마지막에 실시간으로 전송 현황이 갱신되어 출력된다. 보통은 지금 전송하고 있는 파일명, 전송률(%), 전송 속도(KB/s, MB/s 등), 남은 시간 등의 정보가 출력된다.


ping의 경우에는 RTT 측정 결과가 새로운 라인으로 찍히기 때문에 콘솔 화면에 이전의 기록을 모두 볼 수 있는 반면, scp는 그런 것 없이 마지막으로 갱신된 정보가 이전 라인에 계속 덮어써지는 구조라서 이전 기록을 확인할 수 없다.


scp를 통해 전송중인 정보를 ping과 유사하게 line-by-line으로 기록으로 남기기 위해서는 다른 도구와 조합해서 써야 하는데, script가 유용하다고 한다 [1]. Script는 콘솔 창에서 변화가 생기는 것(?? 적당한 표현을 찾지 못함...)을 모두 기록하는 도구이다.


인용한 StackOverflow에 달린 두 번째 답변에 의하면, 아래와 같이 할 수 있다:


$ script -c "아웃풋을 기록하고자 하는 명령어" [아웃풋을_저장할_파일]


예를 들어,

$ script -c "scp [sending_file_location] [receiving_host_and_location]" scplog.txt


맨 끝에 아웃풋을 저장할 파일을 지정하지 않으면, 

콘솔의 현재 위치에 typescript라는 파일을 자동으로 생성해서 저장한다.



123.yuv라는 20MB짜리 파일을 Remote host에 전달했을 때, 

예제로 생성된 로그파일(scplog.txt)은 아래와 같다:


Script started on 2016년 05월 13일 (금) 오전 03시 30분 26초


123.yuv                                         0%    0     0.0KB/s   --:-- ETA

123.yuv                                        34% 7072KB   6.9MB/s   00:01 ETA

123.yuv                                        59%   12MB   6.7MB/s   00:01 ETA

123.yuv                                        84%   17MB   6.6MB/s   00:00 ETA

123.yuv                                       100%   20MB   6.7MB/s   00:03    


Script done on 2016년 05월 13일 (금) 오전 03시 30분 30초



Script로 ping 명령을 테스트해 보면 그냥 콘솔에서 보는 것과 똑같이 찍힌다. 자세한 원리는 모르겠지만 실제로 변화가 생긴 라인을 기록하는 것 같은데, 여러 라인에 변화가 생기면 여러 라인이 동시에 기록되는지는 아직 모르겠다.


어쨌든 SCP도 그때그때 눈으로 보고 속도를 메모하던 안습한 짓을 하지 않아도 돼서 다행이다. (=_=)



<참고자료>

[1] How to best capture and log scp output? http://stackoverflow.com/questions/202432/how-to-best-capture-and-log-scp-output



반응형
블로그 이미지

Bryan_

,