쿠버네티스 일반/Network

sniff - kubectl 환경 패킷 캡쳐 유틸리디

Jerry_이정훈 2022. 1. 18. 05:35
728x90

가시다님 스터디에서 ‘stewart’ 님이 공유해 주신 파드 패깃덤프 플러그인 sniff 사용 예제를 공유한다. sniff 사용하면 파드에 접속해서 tcpdump 명령어 실행하지 않아도 로컬PC에서 kubectl 명령어로 원격 파드의 패킷 덤프를 바로 실행할 수 있다. 패킷덤프는 그동안 귀찮아서 네트워크 엔지니어에게 미루었는데 내가 해보게 되고 여러모로 도움이 되는 스터디다.

 

sniff 참고

https://github.com/eldadru/ksniff 

 

GitHub - eldadru/ksniff: Kubectl plugin to ease sniffing on kubernetes pods using tcpdump and wireshark

Kubectl plugin to ease sniffing on kubernetes pods using tcpdump and wireshark - GitHub - eldadru/ksniff: Kubectl plugin to ease sniffing on kubernetes pods using tcpdump and wireshark

github.com

TL;DR

  • 파드 접속해서 tcpdump 뜨지 않고 원격에서 kubectl 명령어로 파드의 tcpdump 실행 가능
  • dump 뜬 파일이 로컬에 바로 저장되어 해당 파일을 wireshark 열어서 바로 볼 수 있다.
    (PATH에 wireshark 실행 가능하면 파일에 저장하지 않고도 자동으로 wireshark 실행해서 볼 수 있다. 하지만 난 wsl 환경이라 wireshark 자동 실행은 안되고 파일 경로를 지정하고 해당 파일을 다시 불러오는 방법을 사용한다.)
  • busybox 등 tcpdump 유틸없는 파드에서도 실행 가능하다. 

 설치는 krew 기반으로 너무 간단하다.

 

[Kubernetes] Kubernetes Plugin Manager - Krew

쿠버네티스 플러그인 관리자 Krew 쿠버네티스를 사용하다보면 다양한 정보를 확인하기 위해 kubectl 명령어를 잘 활용해야 합니다. 또, 특정 인자를 반복적으로 넘겨주어야 하는 때도 있습니다. 대

wookiist.dev

[spkr@erdia22 11.aws-front-git (ubun71:default)]$ k krew install sniff
Updated the local copy of plugin index.
  New plugins available:
    * directpv
    * explore
    * ktop
    * secretdata
  Upgrades available for installed plugins:
    * minio v4.3.8 -> v4.4.3
    * virt v0.48.1 -> v0.49.0
Installing plugin: sniff
Installed plugin: sniff
\
 | Use this plugin:
 |      kubectl sniff
 | Documentation:
 |      https://github.com/eldadru/ksniff
 | Caveats:
 | \
 |  | This plugin needs the following programs:
 |  | * wireshark (optional, used for live capture)
 | /
/
WARNING: You installed plugin "sniff" from the krew-index plugin repository.
   These plugins are not audited for security by the Krew maintainers.
   Run them at your own risk.

실행 예제

현재 2개의 파드가 실행 중이다. 테스트 시나리오는 busybox- 파드에서 myweb2 파드로 ping을 날리고 해당 패킷을 myweb2 파드에서 패킷 캡쳐한다. 해당 패킷 캡쳐한 파일을 로컬PC Wireshark에서 불러오면 원격 파드에서 tcpdump 실행한 것과 동일한 걸 내 PC에서 확인할 수 있다.
(물론 2개 파드 실행하지 않고 단일 파드에서 8.8.8.8 등으로 ping 하는 것도 패킷 캡쳐 가능하다.)

즉 원격 파드에 접속해서 tcpdump 실행 안하고(파드에 tcpdump 유틸 설치하지 않고) kubectl 명령어로 편하게 원격 파드 tcpdump 실행 할 수 있다. 

 

먼저 파드 현황.

[spkr@erdia22 ~ (ubun71:default)]$ kgp  #k get pod -o wide
NAME                       READY   STATUS    RESTARTS   AGE    IP             NODE        NOMINATED NODE   READINESS GATES
busybox-7fd54c485d-84wrd   1/1     Running   0          91m    10.233.64.11   ubun20-71   <none>           <none>
myweb2                     2/2     Running   0          5d2h   10.233.67.18   ubun20-74   <none>           <none>

창을 3개를 띄우고 아래와 같이 위에서 순서대로 1) myweb2에서 tcpdump 실행 2) 로컬 PC에서 sniff 실행 3) 원격 busybox 파드에서 ping을 실행 

 

 3개의 명령어는 아래와 같다.

# 1번째 창
myweb2  ~  tcpdump -i eth0 -nn icmp
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes

# 2번째 창
[spkr@erdia22 ~ (ubun71:default)]$ k sniff myweb2 -i eth0 -c myweb2-netshoot -f "icmp" -o ping.pcap

# 3번째 창
/ # ping -c 1 10.233.67.18

sniff 명령어 사용 예제는 다음과 같다.

[spkr@erdia22 ~ (ubun71:default)]$ k sniff myweb2 -i eth0 -c myweb2-netshoot -f "icmp" -o ping.pcap
  • -o output 옵션으로 로컬 디렉토리 선택하면 해당 파일에 패킷을 쓴다. 
  • -f filter 옵션에 tcpdump 옵션을 지정한다. 
    (왜 티스토리는 코드 블럭에 bold 강조가 안될까?)

 이제 명령어 실행한다. 

[spkr@erdia22 ~ (ubun71:default)]$ k sniff myweb2 -i eth0 -c myweb2-netshoot -f "icmp" -o ping.pcap
INFO[0000] using tcpdump path at: '/home/spkr/.krew/store/sniff/v1.6.1/static-tcpdump'
INFO[0000] sniffing method: upload static tcpdump
INFO[0000] sniffing on pod: 'myweb2' [namespace: 'default', container: 'myweb2-netshoot', filter: 'icmp', interface: 'eth0']
INFO[0000] uploading static tcpdump binary from: '/home/spkr/.krew/store/sniff/v1.6.1/static-tcpdump' to: '/tmp/static-tcpdump'
INFO[0000] uploading file: '/home/spkr/.krew/store/sniff/v1.6.1/static-tcpdump' to '/tmp/static-tcpdump' on container: 'myweb2-netshoot'
INFO[0000] executing command: '[/bin/sh -c test -f /tmp/static-tcpdump]' on container: 'myweb2-netshoot', pod: 'myweb2', namespace: 'default'
INFO[0000] command: '[/bin/sh -c test -f /tmp/static-tcpdump]' executing successfully exitCode: '0', stdErr :''
INFO[0000] file found: ''
INFO[0000] file was already found on remote pod
INFO[0000] tcpdump uploaded successfully
INFO[0000] output file option specified, storing output in: 'ping.pcap'
INFO[0000] start sniffing on remote container
INFO[0000] executing command: '[/tmp/static-tcpdump -i eth0 -U -w - icmp]' on container: 'myweb2-netshoot', pod: 'myweb2', namespace: 'default'

 그러면 패킷 덤프한 결과 파일이 원격 파드에 있는게 아니라 내 PC의 현재 디렉토리에 저장된다.

[spkr@erdia22 ~ (ubun71:default)]$ ls -lrt ping.pcap
-rw-r--r-- 1 spkr spkr 480 Jan 17 15:53 ping.pcap
[spkr@erdia22 ~ (ubun71:default)]$ pwd
/home/spkr
  • 윈도우 wsl 환경이라 홈디렉토리가 /home/spkr 이다. 

 해당 파일을 윈도우 wireshark로 열어보면 위 tcpdump로 실행한 화면과 동일하게 패킷 캡쳐 결과를 확인할 수 있다.  

  • 참고로 flannel이 사용하는 VxLAN 헤더를 확인할 수 있다. 

원하는 원격 파드의 패킷 덤프가 정상적으로 실행된 걸 알 수 있다. 편하다.

 

그리고 busybox 등 tcpdump 유틸 설치되어 있지 않는 파드도 사용할 수 있다. 

sniff 아키텍쳐는 아래 참조. 같은 노드에 파드를 하나 더 생성하고 기존 파드에 같은 네트워크 네임스페이스로 파드를 실행해서 우리가 원하는 파드의 패킷을 캡쳐하는 구조이다. (신기하다)

 

참조 https://kubesandclouds.com/index.php/2021/01/20/ksniff/

 

Ksniff: packet capture at pod level for k8s 🕵️‍♂️📦 - Kubes&Clouds

The answer is simple, the exact same way that we would do it in a computer or a virtual machine, a packet sniffer. In this article we will introduce Ksniff as

kubesandclouds.com

How does it work? 💻🤔
Ksniff is shipped as a kubectl plugin that allows using tcpdump and Wireshark to capture traffic on a specific pod within a cluster. Ksniff uses kubectl to upload a tcpdump binary (packet sniffer) to the target container, and redirects the output to the Wireshark instance running in your machine.

You may be thinking right now, how would this work in containers without explicit network capabilities or non-privileged users? Well, Ksniff has specific flag (p) for that. This approach can be also used to sniff traffic in distroless containers, where the binary cannot be executed by a shell.

By using the p flag, Ksniff will deploy a pod in the same node where the target pod/container is placed, with access to the docker daemon. The container within this ‘auxiliar’ pod is placed in the same network namespace as the target container, and traffic can then be captured.

sniff 실행하면 파드가 하나 더 생성된다.

 

이상 간단한 파드 패킷덤프 플러그인 sniff 사용 방법이다. 편하게 사용할 수 있을 것 같다. 가시다님 스터디 시간에 이것저것 유용한 걸 많이 배울 수 있다. 

반응형