Skip to content
This repository has been archived by the owner on Apr 2, 2024. It is now read-only.

tada apigee hybrid tcpdump

Yuriy Lesyuk edited this page Dec 30, 2020 · 3 revisions

TADA: Apigee Hybrid Container Traffic Analysis with tcpdump for Target Requests*

  • TADA -- Troubleshooting And Debugging for Apigee

#apigee-hybrid #1.3.x #tcpdump #kubernetes-networking

For troubleshooting connection between Target endpoint and the backend itself, most problems with Apigee Proxies are solved by using the TRACE tool of the Edge UI.

More complex problems require usage of a Debug logging

The most complex problems call for usage of tcpdump. For Apigee hybrid, the scenario is complicated by the fact that apigee-runtime container runs as an apigee:apigee user. Good for your security, not so for tcpdump, which require root's permissions.

The following walkthrough uses Brian O'Connell's tip to find a Kubernetes container's interface at a cluster node How to get tcpdump for containers inside Kubernetes pods.

Problem: A backend server required a Host header setup, because DNS is not configured, we have an IP address-based URL.

We can use either JavaScript policy or AssignMessage policy to set up a Host header value. But we cannot be sure for 100% it worked, because as it happens now, Get Curl button does not show the transformed request and response body is not shown under certain conditions, which might leave some space for speculation. One of those curtain conditions is when Apigee response parser is unable to parse a response body. In this case, we are not going to see it.

Let's use http:/httpbin.org for our troubleshooting session.

Sending Test Request Directly to Backend

?. The httpbin.org/get request conveniently returns sent headers

curl http://httpbin.org/get

{
  "args": {}, 
  "headers": {
    "Accept": "*/*", 
    "Host": "httpbin.org", 
    "User-Agent": "curl/7.64.1", 
    "X-Amzn-Trace-Id": "Root=1-5fec44cc-56672a2f419e9c67426910af"
  }, 
  "origin": "86.140.110.147", 
  "url": "http://httpbin.org/get"
}

?. Find out IP address for httpbin.org FQDN

ping httpbin.org

PING httpbin.org (3.211.1.78): 56 data bytes
...

?. Request to httpbin.org using IP address, returns expected host header containing IP address

curl http://3.211.1.78/get

{
  "args": {}, 
  "headers": {
    "Accept": "*/*", 
    "Host": "3.211.1.78", 
    "User-Agent": "curl/7.64.1", 
    "X-Amzn-Trace-Id": "Root=1-5fec4571-02fe421e52942a49105014c3"
  }, 
  "origin": "86.140.110.147", 
  "url": "http://3.211.1.78/get"
}

Passthrough Apigee Proxy

?. Using +PROXY/Reverse proxy master, create an httpbin proxy:

Name: httpbin
Target: http://3.211.1.78
Next
Pass through (no authorization)
Next
Select checkbox: Deployment: test
Create

Send a request to the Apigee API Proxy to apigee-runtime pod/container

In a general case, you will have multiple apigee-runtime pods in multiple regions. As we want to intercept traffic to a specific single container, we need to send the request to the specific pod that hosts this container.

See for details: https://github.com/apigee/ahr/wiki/Hybrid-Ingress-Walkthrough-1.3

?. Verify that you're authenticated into a correct cluster

kubectl config get-contexts

?. Pick a container to work with. We are selecting first one from the list of eligible pods

export POD=$(kubectl get pods  -n apigee |grep apigee-runtime |awk 'NR==1{print $1}'); echo $POD

apigee-runtime-emea-cs-hybrid-demo6-test-v110-2lsbg

?. Exec into a $POD

kubectl exec -it $POD --namespace apigee -c apigee-runtime -- sh

WARNING: There is no curl installed into an apigee-runtime pod prior to hybrid 1.3.x. Use

kubectl get pods -n apigee -o wide to get pod IP address

kubectl run -it busyboxplus --image=radial/busyboxplus --restart=Never to log into busyboxplus and run curl.

kubectl delete pod busyboxplus to delete a stopped pod.

?. Get Pod IP value

kubectl get pod $POD -n apigee -o jsonpath='{.status.podIP}'

10.44.5.57

?. In the pod at the prompt, execute a request

export RUNTIME_IP=10.44.5.57
export RUNTIME_HOST_ALIAS=emea-cs-hybrid-demo6-test-dc1.hybrid-apigee.net

curl -k https://$RUNTIME_HOST_ALIAS:8443/httpbin/get --resolve "$RUNTIME_HOST_ALIAS:8443:$RUNTIME_IP"

Output:

{
  "args": {}, 
  "headers": {
    "Accept": "*/*", 
    "Host": "3.211.1.78", 
    "User-Agent": "curl/7.35.0", 
    "X-Amzn-Trace-Id": "Root=1-5fec5cd8-4023c6b4521223404a5e5727"
  }, 
  "origin": "35.196.107.149", 
  "url": "http://3.211.1.78/get"
}

Setting up tcpdump session @ GKE/GCP

For details: How to get tcpdump for containers inside Kubernetes pods https://community.pivotal.io/s/article/How-to-get-tcpdump-for-containers-inside-Kubernetes-pods?language=en_US

?. Find the container name and node where your pod is deployed

kubectl describe pod $POD -n apigee|grep -E "Node:|Containers:|Container ID:|apigee-runtime:"

Node:               gke-dc1-cluster-apigee-runtime-f80b30bd-btxy/10.142.0.19
Init Containers:
    Container ID:  docker://f551fe5cf7c23b138966d656fe7891bd620a62c7181d8b0e7f56817f578f31fd
Containers:
  apigee-runtime:
    Container ID:   docker://95f76d7ffb881d19ff77117f3f9a657a91843c25ab49009cf5e9b71a3e1af97b
    Image:          google/apigee-runtime:1.1.0

?. Using Node: field value, find the node's region

gcloud compute instances list 

...
gke-dc1-cluster-apigee-runtime-f80b30bd-btxy  us-east1-b     n1-standard-4               10.142.0.19  35.196.107.149  RUNNING
...

?. Ssh into the node

gcloud compute ssh gke-dc1-cluster-apigee-runtime-f80b30bd-btxy --zone us-east1-b

yuriyl@gke-dc1-cluster-apigee-runtime-f80b30bd-btxy ~ $ 

?. Using container Id, find the pod's unique network interface index inside it's container.

export CID=95f76d7ffb881d19ff77117f3f9a657a91843c25ab49009cf5e9b71a3e1af97b


docker exec $CID /bin/bash -c 'cat /sys/class/net/eth0/iflink'

Output:

60

?. Take the result from that and locate that interface on the worker

for i in /sys/class/net/veth*/ifindex; do grep -l 60 $i; done

Output:

/sys/class/net/veth052c835c/ifindex

?. Install toolbox at the node

As GKE nodes use COS, install and run the toolbox. For details: https://cloud.google.com/container-optimized-os/docs/how-to/toolbox

/usr/bin/toolbox

?. After logging into the toolbox, install tcpdump

apt-get update && apt-get install -y tcpdump

tcpdump: Traffic Capture

We need two terminal sessions:

  • one to run tcpdump
  • one to execute curl requests.

Using interface id from the previous section, capture incoming and outgoing traffic for httpbin.org IP address we found earlier

?. Start tcpdump to capture output into a request.pcap file.

tcpdump -i veth052c835c host 3.211.1.78 -w request.pcap

?. Execute request using curl in a separate session

?. Press Ctrl+C to interrupt the tcp dump capture.

Output:

^C9 packets captured
9 packets received by filter
0 packets dropped by kernel

?. Copy capture file out of toolbox to the node See also: https://cloud.google.com/container-optimized-os/docs/how-to/toolbox#getting_files_into_and_out_of_toolbox

?. Exit from toolbox session. Notice the container name.

root@gke-dc1-cluster-apigee-runtime-f80b30bd-btxy:~# exit

logout
Container yuriyl-gcr.io_google-containers_toolbox-20180918-00 exited successfully.

?. At the node, execute sudo cp to copy request.pcap file from container to the node file system

sudo cp /var/lib/toolbox/yuriyl-gcr.io_google-containers_toolbox-20180918-00/root/request.pcap .

?. Exit the node and copy request.pcap file to your work machine

exit

?. Copy capture file to your work machine with installed wireshark.

gcloud compute scp gke-dc1-cluster-apigee-runtime-f80b30bd-btxy:~/request.pcap . --zone us-east1-b

?. Open the file in wireshark, select the GET line and right-click follow the HTTP stream.

tcpdump request with ip address

Add AssignMessage Policy to set the Host header

?. Using Edge UI, add the following Assign Message Policy to the Target Endpoint PreFlow event.

<AssignMessage async="false" continueOnError="false" enabled="true" name="AssignMessage-SetHost">
    <AssignVariable>
        <Name>target.header.host</Name>
        <Value>xxx.yyy.com</Value>
    </AssignVariable>
    <AssignTo createNew="false" transport="http" type="request"/>
</AssignMessage>

Edge UI Assign Message to Set Host

?. Save and Deploy a new version of the httpbin API proxy

?. Repeat tcpdump capture and analysis for a new curl request

tcpdump Host Header

Observe that the request now uses an overridden SNI-compliant host value.


Scenarios



Deep Dives

Archive

Ingress and TLS

DevPortal

Troubleshooting Flows

Clone this wiki locally