{"id":18837313,"url":"https://github.com/clarenceb/osm-mtls-check","last_synced_at":"2026-03-19T06:40:31.825Z","repository":{"id":142072069,"uuid":"445405591","full_name":"clarenceb/osm-mtls-check","owner":"clarenceb","description":"Open Service Mesh mTLS check","archived":false,"fork":false,"pushed_at":"2022-01-07T05:41:12.000Z","size":2212,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-05-29T19:39:24.207Z","etag":null,"topics":["aks","ksniff","osm","tls","wireshark"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/clarenceb.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-01-07T05:13:07.000Z","updated_at":"2022-04-03T12:01:25.000Z","dependencies_parsed_at":"2023-07-09T05:32:07.215Z","dependency_job_id":null,"html_url":"https://github.com/clarenceb/osm-mtls-check","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/clarenceb/osm-mtls-check","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clarenceb%2Fosm-mtls-check","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clarenceb%2Fosm-mtls-check/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clarenceb%2Fosm-mtls-check/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clarenceb%2Fosm-mtls-check/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/clarenceb","download_url":"https://codeload.github.com/clarenceb/osm-mtls-check/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clarenceb%2Fosm-mtls-check/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28803642,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-27T03:44:14.111Z","status":"ssl_error","status_checked_at":"2026-01-27T03:43:33.507Z","response_time":168,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aks","ksniff","osm","tls","wireshark"],"created_at":"2024-11-08T02:34:44.089Z","updated_at":"2026-01-27T05:02:16.940Z","avatar_url":"https://github.com/clarenceb.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"Open Service Mesh mTLS check\n============================\n\nOpen Service Mesh enables automatic mTLS between services that are part of the service mesh.  However, how can you be sure mTLS is configured and actually working?\n\nIn this example we will use tcpdump and wireshark via the [ksniff](https://github.com/eldadru/ksniff) [krew](https://krew.sigs.k8s.io/) plugin for kubectl.\n\nPrerequisities\n--------------\n\n* AKS cluster with [OSM add-on enabled](https://docs.microsoft.com/en-us/azure/aks/open-service-mesh-deploy-addon-az-cli#install-the-osm-aks-add-on-on-your-cluster) -- technically, you can use any Kubernetes cluster with self-install OSM\n* [OSM CLI configured](https://docs.microsoft.com/en-us/azure/aks/open-service-mesh-binary?pivots=client-operating-system-linux#configure-osm-cli-variables-with-an-osm_config-file)\n* Admin user access to the AKS cluster\n* Wireshark in your path (e.g. on Ubuntu `sudo apt install wireshark`) -- install latest via PPA\n\n```sh\nsudo add-apt-repository ppa:wireshark-dev/stable\nsudo apt update\nsudo apt install wireshark\nsudo dpkg-reconfigure wireshark-common\n# Select 'Yes'\nsudo dpkg-reconfigure wireshark-common\n# Restart wsl2/ubuntu\nwireshark --version\n# Wireshark 3.4.8 (Git v3.4.8 packaged as 3.4.8-1~ubuntu20.04.0+wiresharkdevstable1)\nwireshark\n```\n\n![wireshark](img/wireshark.png \"Wireshark\")\n\nNotes\n-----\n\n* The local environment used for this demo is Windows 11 + WSL2 with Ubuntu 20.04 LTS -- but any similar setup should work with minor changes\n* Wireshark will only detect HTTP protocol traffic on well-known ports like 80, 443 -- if you have HTTP services on other ports then [configure Wireshark HTTP preferences](https://wiki.wireshark.org/HTTP_Preferences) or enable Heuristic sub-dissectors (from the menu: **Edit** / **Preferences** / **Protocols** / **TCP** / **Try heuristic sub-dissectors first**)\n\n![TCP settings](img/try-heuristic-sub-dissectors-first-2.png \"Try heuristic sub-dissectors first\")\n\n* `tcmpdump` cannot be run in non-privileged or distroless/scratch containers: use [ksniff workaround](https://github.com/eldadru/ksniff#non-privileged-and-scratch-pods) with the `-p` flag\n    * This would be the case with the `curl` and `envoy` containers but not the `httpbin` container\n* We'll focus on the `httpbin` container (the server) but you can also check the `curl` container (the client) to examine traffic on the client side\n* Attaching to either httpbin or envoy containers will work since they share the same network interface and we can sniff any traffic in the same pod\n\nDemo app\n--------\n\nCredit: This demo app is taken from: https://github.com/openservicemesh/osm/tree/main/docs/example/manifests/samples\n\nDeploy the app with and without envoy sidecars:\n\n```sh\nkubectl create namespace encrypted\nkubectl label namespace encrypted openservicemesh.io/monitored-by=osm\nkubectl create namespace unencrypted\n\nkubectl apply -f httpbin/httpbin-sidecar.yaml -n encrypted\nkubectl apply -f httpbin/httpbin.yaml -n unencrypted\n\nkubectl apply -f curl/curl-sidecar.yaml -n encrypted\nkubectl apply -f curl/curl.yaml -n unencrypted\n\nkubectl get pod -n encrypted\nkubectl get pod -n unencrypted\n\n# Get references to the pods (these can change if you restart the pods)\nCURL_POD=\"$(kubectl get pod -n unencrypted -l app=curl -o name | cut -f 2,2 -d '/')\"\nHTTPBIN_POD=\"$(kubectl get pod -n unencrypted -l app=httpbin -o name | cut -f 2,2 -d '/')\"\nCURL_ENC_POD=\"$(kubectl get pod -n encrypted -l app=curl -o name | cut -f 2,2 -d '/')\"\nHTTPBIN_ENC_POD=\"$(kubectl get pod -n encrypted -l app=httpbin -o name | cut -f 2,2 -d '/')\"\n\n# Check the pod IPs in the unencrypted namespace\nkubectl get pod -n unencrypted -o wide\n\n#NAME                       READY   STATUS    RESTARTS   AGE   IP            NODE                                NOMINATED NODE   READINESS GATES\n#curl-548c575854-tlj4b      1/1     Running   0          26h   10.240.0.52   aks-nodepool1-38579899-vmss000001   \u003cnone\u003e           \u003cnone\u003e\n#httpbin-8688f865cf-4k4gl   1/1     Running   0          26h   10.240.0.36   aks-nodepool1-38579899-vmss000001   \u003cnone\u003e           \u003cnone\u003e\n```\n\nHere we can see the `curl` pod IP is `10.240.0.52` and `httpbin` pod IP is `10.240.0.36`.  This will be useful later when using Wireshark to identify the source and dest pod.\n\n```sh\n# Check the pod IPs in the encrypted namespace\nkubectl get pod -n encrypted -o wide\n#NAME                       READY   STATUS    RESTARTS   AGE   IP            NODE                                NOMINATED NODE   READINESS GATES\n#curl-74c4b77794-7n5cp      2/2     Running   0          28h   10.240.0.77   aks-nodepool1-38579899-vmss000002   \u003cnone\u003e           \u003cnone\u003e\n#httpbin-869b78c659-fzhsv   2/2     Running   0          28h   10.240.0.49   aks-nodepool1-38579899-vmss000001   \u003cnone\u003e           \u003cnone\u003e\n```\n\nHere we can see the `curl` pod IP is `10.240.0.77` and `httpbin` pod IP is `10.240.0.49`.  This will be useful later when using Wireshark to identify the source and dest pod.\n\n\nTracing HTTP traffic in the unencrypted namespace\n-------------------------------------------------\n\nStart packet sniffing on `httpbin` service in the `unencrypted` namespace:\n\n```sh\nkubectl sniff $HTTPBIN_POD -c httpbin -n unencrypted\n```\n\nMake a HTTP request to `httpbin`:\n\n```sh\nkubectl exec -ti $CURL_POD -c curl -n unencrypted -- curl http://httpbin/\n```\n\nPress the \"Stop\" button to pause packet capture.\n\nIn Wireshark we can see the TCP handshake, HTTP request, response and TCP connection close.\n\nIf we follow the HTTP stream we can see the HTTP request and reponse:\n\n![HTTP stream follow](img/http-stream-follow.png \"Follow HTTP stream\")\n\n![HTTP stream follow details](img/http-stream-follow-2.png \"Follow HTTP stream details\")\n\nHere we can see the request and responses are directly between the `curl` (`10.240.0.52`) and `httpbin` (`10.240.0.36`) pods with no sidecar proxies involved.  Traffic is in plaintext (HTTP) and is not encrypted.\n\nClose the Wireshark window to exit ksniff.\n\nTracing HTTP traffic in the encrypted namespace\n-----------------------------------------------\n\nStart packet sniffing on `httpbin` service in the `encrypted` namespace:\n\n```sh\nkubectl sniff $HTTPBIN_ENC_POD -c httpbin -n encrypted\n```\n\nMake a request to httpbin:\n\n```sh\nkubectl exec -ti $CURL_ENC_POD -c curl -n encrypted -- curl http://httpbin/\n```\n\nPress the \"Stop\" button to pause packet capture.\n\nIn Wireshark we can see the TCP handshake, TLS client hello, server hello, change cipherspec, etc., encrypted request and response, and TCP connection close.\n\nHere is the TLS handshake Client Hello message:\n\n![TLS Handshake Client Hello](img/client-hello.png \"Client Hello\")\n\nAnd the corresponding TLS handshake Server Hello message:\n\n![TLS Handshake Server Hello](img/server-hello.png \"Server Hello\")\n\nThe selected chipher suite was `TLS_AES_128_GCM_SHA256 (0x1301)`.\n\nFollow the TCP stream and you will see that the messages exchnaged are encrypted:\n\n![Follow TLS TCP stream](img/follow-tcp-stream-tls-1.png \"Follow TLS TCP stream\")\n\n![Follow TLS TCP stream encrypted](img/follow-tcp-stream-tls-2.png \"Follow TLS TCP stream encrypted\")\n\nSince the protocol used is TLSv1.3, it is not straight-forward to decrypt the messages as TLSv1.3 mandates [Perfect Forward Secrecy](https://en.wikipedia.org/wiki/Forward_secrecy) (PFS).  Previously, you could extract the RSA private keys (for the client and server envoy proxies).  With PFS, a unique session key is generated for each individual session.  This means that even if you have the private key you cannot decrypt conversations.  You would also need the individual session key (out of scope for this demo) but that will not allow you to decrypt previous converations.\n\nFor our purposes in this demo, we can be assured that the communications are encrypted between the services.\n\nIf we remove any applied filter in Wireshark, we can first see the comms using the pod IP addresses and then we have a number of calls with source and destination IPs of `localhost`.  These `localhost` calls are from/to the `envoy` proxy.  Traffic from/to the `envoy` proxy is within the same pod and is unencrypted.\n\nSee the unencrypted HTTP calls between the `envoy` proxy and the `httpbin` container:\n\n![Sidecar comms](img/sidecar-comms.png \"Sidecar comms\")\n\nCleanup\n-------\n\n```sh\nkubectl delete ns encrypted\nkubectl delete ns unencrypted\n```\n\nReferences\n----------\n\n* [Verifying Service Mesh TLS in Kubernetes, Using ksniff and Wireshark](https://blog.getambassador.io/verifying-service-mesh-tls-in-kubernetes-using-ksniff-and-wireshark-454b1e3f4dc9)\n* [OSM ports](https://release-v0-11.docs.openservicemesh.io/docs/guides/app_onboarding/prereqs/#ports)\n* [Decoding TLS v1.2 Protocol Handshake With Wireshark](https://www.thesecmaster.com/decoding-tls-v1-2-protocol-handshake-with-wireshark/)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclarenceb%2Fosm-mtls-check","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fclarenceb%2Fosm-mtls-check","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclarenceb%2Fosm-mtls-check/lists"}