Skip to content

Commit

Permalink
Adding support for Kubectl 1.12+, adding more verifications to improv…
Browse files Browse the repository at this point in the history
…e UX
  • Loading branch information
eldadru committed Oct 25, 2018
1 parent 9d81588 commit 1078863
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 15 deletions.
36 changes: 30 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,21 +1,45 @@
PLUGIN_FOLDER=~/.kube/plugins/sniff

TCPDUMP_VERSION=4.9.2
NEW_PLUGIN_SYSTEM_MINIMUM_KUBECTL_VERSION=12
KUBECTL_MINOR_VERSION=$(shell kubectl version --client=true --short=true -o json | jq .clientVersion.minor)
IS_NEW_PLUGIN_SUBSYSTEM := $(shell [ $(KUBECTL_MINOR_VERSION) -ge $(NEW_PLUGIN_SYSTEM_MINIMUM_KUBECTL_VERSION) ] && echo true)
STATIC_TCPDUMP_NAME=static-tcpdump

ifeq ($(IS_NEW_PLUGIN_SUBSYSTEM),true)
PLUGIN_FOLDER=/usr/local/bin
PLUGIN_NAME=kubectl-sniff
else
PLUGIN_FOLDER=~/.kube/plugins/sniff
PLUGIN_NAME=ksniff.sh
endif

install: install-static-tcpdump install-plugin

plugin-folder:
mkdir -p ~/.kube/plugins/sniff
mkdir -p ${PLUGIN_FOLDER}

install-plugin: plugin-folder
cp ksniff.sh plugin.yaml ${PLUGIN_FOLDER}
chmod +x ${PLUGIN_FOLDER}/ksniff.sh
if [ "${IS_NEW_PLUGIN_SUBSYSTEM}" != "true" ]; then \
cp plugin.yaml ${PLUGIN_FOLDER};\
fi

cp ksniff.sh ${PLUGIN_FOLDER}/${PLUGIN_NAME}
chmod +x ${PLUGIN_FOLDER}/${PLUGIN_NAME}

install-static-tcpdump: plugin-folder static-tcpdump
mv static-tcpdump ${PLUGIN_FOLDER}
mv ${STATIC_TCPDUMP_NAME} ${PLUGIN_FOLDER}

static-tcpdump:
wget http://www.tcpdump.org/release/tcpdump-${TCPDUMP_VERSION}.tar.gz
tar -xvf tcpdump-${TCPDUMP_VERSION}.tar.gz
cd tcpdump-${TCPDUMP_VERSION} && CFLAGS=-static ./configure --without-crypto && make
mv tcpdump-${TCPDUMP_VERSION}/tcpdump ./static-tcpdump
mv tcpdump-${TCPDUMP_VERSION}/tcpdump ./${STATIC_TCPDUMP_NAME}
rm -rf tcpdump-${TCPDUMP_VERSION} tcpdump-${TCPDUMP_VERSION}.tar.gz

uninstall:
if [ "${IS_NEW_PLUGIN_SUBSYSTEM}" != "true" ]; then \
rm -f ${PLUGIN_FOLDER}/plugin.yaml;\
fi

rm -f ${PLUGIN_FOLDER}/${STATIC_TCPDUMP_NAME}
rm -f ${PLUGIN_FOLDER}/${PLUGIN_NAME}
16 changes: 13 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,26 +17,36 @@ output to your local Wireshark for smooth network debugging experience.
![Demo!](https://i.imgur.com/hWtF9r2.gif)

## Installation

Requirements:
1. libpcap-dev: for tcpdump compilation (Ubuntu: sudo apt-get install libpcap-dev)
2. jq: for parsing kubectl version

You can easily install the plugin using the Makefile:

1. make install

'make install' will compile a static tcpdump binary and will copy all the required files to your
~/.kube/plugins folder.
'make install' will compile a static tcpdump binary and will copy all the required files to your plugin folder

if you only want to install the plugin files without compiling tcpdump use:
if you only want to install the plugin files without compiling tcpdump use:

1. make install-plugin


### Usage

kubectl < 1.12:
kubectl plugin sniff <POD_NAME> [-n <NAMESPACE_NAME>] [-c <CONTAINER_NAME>] [-f <CAPTURE_FILTER>]

kubectl >= 1.12:
kubectl sniff <POD_NAME> [-n <NAMESPACE_NAME>] [-c <CONTAINER_NAME>] [-f <CAPTURE_FILTER>]

POD_NAME: Required. the name of the kubernetes pod to start capture it's traffic.
NAMESPACE_NAME: Optional. Namespace name. used to specify the target namespace to operate on.
CONTIANER_NAME: Optional. If omitted, the first container in the pod will be chosen.
CAPTURE_FILTER: Optional. specify a specific tcpdump capture filter. If omitted no filter will be used.



### Future Work
1. Instead of uploading static tcpdump, use the future support of "kubectl debug" feature
Expand Down
47 changes: 41 additions & 6 deletions ksniff.sh
Original file line number Diff line number Diff line change
@@ -1,21 +1,46 @@
#!/usr/bin/env bash

KUBECTL_MINOR_VERSION=$(kubectl version --client=true --short=true -o json | jq .clientVersion.minor)
KUBECTL_MINOR_VERSION="${KUBECTL_MINOR_VERSION%\"}"
KUBECTL_MINOR_VERSION="${KUBECTL_MINOR_VERSION#\"}"
NEW_PLUGIN_SYSTEM_MINIMUM_KUBECTL_VERSION=12

POD_NAME=${KUBECTL_PLUGINS_LOCAL_FLAG_POD:-$1}
CONTAINER_NAME=${KUBECTL_PLUGINS_LOCAL_FLAG_CONTAINER}
NAMESPACE_NAME=${KUBECTL_PLUGINS_CURRENT_NAMESPACE}
FILTER=${KUBECTL_PLUGINS_LOCAL_FLAG_FILTER}
STATIC_TCPDUMP_NAME=static-tcpdump
STATIC_TCPDUMP_LOCAL_PATH="./"
CONTAINER_FLAG=""
NAMESPACE_FLAG=""


function usage() {
echo "[+] Usage: ./ksniff.sh <POD_NAME> [-n <NAMESPACE_NAME>] [-c <CONTAINER_NAME>] [-f <CAPTURE FILTER>]"
exit 1
}

if [ -z ${POD_NAME} ]; then
usage
usage
fi

shift

while getopts ":n:c:f:" opt; do
case ${opt} in
n )
NAMESPACE_NAME=${OPTARG}
;;
c )
CONTAINER_NAME=${OPTARG}
;;
f )
FILTER=${OPTARG}
;;
esac
done


if [ -n "$CONTAINER_NAME" ]; then
CONTAINER_FLAG="-c ${CONTAINER_NAME}"
fi
Expand All @@ -24,7 +49,11 @@ if [ -n "$NAMESPACE_NAME" ]; then
NAMESPACE_FLAG="-n ${NAMESPACE_NAME}"
fi

echo "[+] Sniffing on pod: ${POD_NAME} container: ${CONTAINER_NAME} namespace: ${NAMESPACE_NAME}"
if [ ${KUBECTL_MINOR_VERSION} -ge ${NEW_PLUGIN_SYSTEM_MINIMUM_KUBECTL_VERSION} ]; then
STATIC_TCPDUMP_LOCAL_PATH=/usr/local/bin/
fi

echo "[+] Sniffing on pod: '${POD_NAME}' [container: '${CONTAINER_NAME}', namespace: '${NAMESPACE_NAME}', filter: '${FILTER}']"

echo "[+] Verifying pod status"
kubectl get pod ${POD_NAME} ${NAMESPACE_FLAG}
Expand All @@ -34,14 +63,20 @@ if [[ $? -ne 0 ]]; then
fi

echo "[+] checking if tcpdump already exist"
kubectl exec ${POD_NAME} ${CONTAINER_FLAG} ${NAMESPACE_FLAG} -- ls -alt /static-tcpdump
kubectl exec ${POD_NAME} ${CONTAINER_FLAG} ${NAMESPACE_FLAG} -- ls -alt /${STATIC_TCPDUMP_NAME}
if [[ $? -ne 0 ]]; then
echo "[+] couldn't find static tcpdump binary, uploading static tcpdump to container"
kubectl cp ./static-tcpdump ${POD_NAME}:/static-tcpdump ${CONTAINER_FLAG} ${NAMESPACE_FLAG}
kubectl exec ${POD_NAME} ${CONTAINER_FLAG} ${NAMESPACE_FLAG} -- chmod +x /static-tcpdump

if [ ! -f ${STATIC_TCPDUMP_LOCAL_PATH}${STATIC_TCPDUMP_NAME} ]; then
echo "[-] static tcpdump was not found in path! please install it and make sure it's located on the same directory as ksniff"
exit 1
fi

kubectl cp ${STATIC_TCPDUMP_LOCAL_PATH}${STATIC_TCPDUMP_NAME} ${POD_NAME}:/${STATIC_TCPDUMP_NAME} ${CONTAINER_FLAG} ${NAMESPACE_FLAG}
kubectl exec ${POD_NAME} ${CONTAINER_FLAG} ${NAMESPACE_FLAG} -- chmod +x /${STATIC_TCPDUMP_NAME}
else
echo "[+] static tcpdump is already installed on container!"
fi

echo "[+] Starting remote sniffing!"
kubectl exec ${POD_NAME} ${CONTAINER_FLAG} ${NAMESPACE_FLAG} -- /static-tcpdump -U -w - ${FILTER} | wireshark -k -i -
kubectl exec ${POD_NAME} ${CONTAINER_FLAG} ${NAMESPACE_FLAG} -- /${STATIC_TCPDUMP_NAME} -U -w - ${FILTER} | wireshark -k -i -

0 comments on commit 1078863

Please sign in to comment.