Kubernetes Sidecar Security Pattern with NGINX+ for Reverse Proxy + TLS + Jwt

Security is everyone’s responsibility but it does not have to be super complex and super costly. Today, we are going to cover a most shout after security design pattern that many architect struggle to get it right. Forget about App Mesh or Service Mesh, they are complex and costly and, more importantly, they may not meet your basic security requirement! I am talking about AWS App Mesh, it does not support Jwt token based authentication and authorization! You can secure your Kubernetes container application with much simpler security design pattern- you’re regulatory compliant and your apps are secure- with NGINX Plus as Reverse Proxy. NGINX Plus comes with many security controls including TLS Offloading and Jwt token validation.

Kubernetes Sidecar Security Pattern

Lately, I was playing with AWS stuff including EKS w/Fargate which is a cousin of Azure AKS and Google GKE- all are Kubernetes managed service providers. I started my Kubernetes journey with Azure AKS and it’s been a while since I resharpen my pencil. It’s time to revisit AKS to test a design pattern that you can use to secure your business applications deployed in Kubernetes cluster.

Why NGINX+? Nginx, pronounced like “engine-ex”, most popular web server among high-traffic websites. When you break down usage rates by traffic, Nginx powers 60.9% of the 100,000 most popular sites (up from 56.1% in 2018). While NGINX is free, NGINX Plus is not free but it delivers the features in it’s belt and they come with support. You can try NGINX+ for 30 days for free and that’s what I did to implement Kubernetes Sidecar Security Pattern with NGINX+ using Reverse Proxy, TLS Termination and Jwt token validation. All those are done with no coding, just configurations.

We will do a walk through of the parts and pieces needed to put the design in action.

  • Build NGINX Plus sidecar docker image. All dependent files can be found in the same github repo. All the certs and keys are truncated and you will need to generate your own certs/keys. You will get nginx repo cert/key when you signup for free trial.
  • Push the nginx sidecar docker image to your choice of repo, I am using Azure ACR.
  • Build the docker image of your business application. You can find an example docker file here. No source code is added, this is just to give your a sample.
  • Push the business app docker image to your repository.
  • I assume your already have a Kubernetes cluster running and you are familiar with kubectl commands.
  • Create a Kubernetes deployment yaml file and run with kubectl apply -f <file name>. You can use aspnet4youapidemo.yaml as your sample.
  • POD’s should be deployed in the cluster. Check and verify everything is working. You can even shell into one of the pod: kubectl exec -it aspnet4you-apidemo-7c5f4cc7d5-d522c — /bin/bash.
  • Create a Kubernetes service configuration file and run with kubectl apply -f <file name>. You can find a sample here, aspnet4youapidemo-service.yaml.
  • Find the services External IP address: kubectl get services -o wide. This External IP is private and you will use this as your backend at Azure Application Gateway.
  • For TLS termination, I am using Azure Private DNS and added this External IP as A Record for api.aspnet4you.aks. You can use self-signed or internally signed certificate. No need to buy trust signed certificate for internal usages like this.
  • Configure your application gateway, mine is Azure Application Gateway which is already setup and running, to add IP/FQDN to backend pool. In my case, I added api.aspnet4you.aks which is mapped to 172.240.0.5 (external ip of the service).
K8 Service exposed with internal LB

Some of the issues that you may encounter and I am going to highlight them here-

  • CORS- be sure to add cors headers in nginx sidecar for Angular app and Swagger to run correctly.
  • Preflight OPTIONS request handling is needed for Angular app. It was not needed for Swagger.
  • Azure application comes to http and https health probe. I had to keep a static server with port 80 listner in nginx sidecar. Gateway was broken otherwise.
  • I am using this API app for many other purpose and I didn’t want to add Jwt requirement for all paths. So, special path is added in nginx to test jwt functions. I used jwt.io site to create a jwt token with symmetric string based key- for simplicity.
  • Default dotnetcore image runs on port 80 by default! I had to modify my api app to listen on port 8080. This was needed since nginx sidecar exposes port 80 and 443.

Okay, we got the pod’s running and ingress with kubernetes service and Azure application gateway. It’s time to show the magic (do some test)! I used Swagger for api documentation and it’s a natural place to try! Open this url, https://api.aspnet4you.com/swagger in you choice of browser. TLS is terminated at App Gateway with a trust signed cert. You will never see the internal cert, by design, but the connection between App Gateway and NGINX sidecar is encrypted with internal cert. We komply with data security in transit.

API documented by Swagger

API application does not have static contents and, previously, you would not get anything in the response when you try the default path ( https://api.aspnet4you.com/ ). Well, you will get the see content served by nginx. This is cool!

Static contents served from nginx sidecar

I know you are waiting for the interesting part which is JWT token validation. Try this path, https://api.aspnet4you.com/api/jwt and you will get to see 401 Authorization Required. Nice, it’s working. :)-

401 Authorization Required

We are doing this as PoC and it’s okay to reveal the secret! Add this jwt token to the above url or just link the link with jwt token.

apijwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjAwMDEifQ.eyJzdWIiOiJwcm9kaXAua3VtYXJAYXNwbmV0NHlvdS5jb20iLCJlbWFpbCI6InByb2RpcC5rdW1hckBhc3BuZXQ0eW91LmNvbSIsIm5hbWUiOiJQcm9kaXAgU2FoYSIsInJvbGUiOiJMaW9uIEtpbmciLCJpc3MiOiJNeSBOR0lOWCBQbHVzIEdhdGV3YXkiLCJpYXQiOjE2MTYyMzkwMjJ9.hZHpr8RDQcVqyqd2mQTxhwmywhX4UGuUGMpVD6Er_eI
https://api.aspnet4you.com/api/jwt?apijwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjAwMDEifQ.eyJzdWIiOiJwcm9kaXAua3VtYXJAYXNwbmV0NHlvdS5jb20iLCJlbWFpbCI6InByb2RpcC5rdW1hckBhc3BuZXQ0eW91LmNvbSIsIm5hbWUiOiJQcm9kaXAgU2FoYSIsInJvbGUiOiJMaW9uIEtpbmciLCJpc3MiOiJNeSBOR0lOWCBQbHVzIEdhdGV3YXkiLCJpYXQiOjE2MTYyMzkwMjJ9.hZHpr8RDQcVqyqd2mQTxhwmywhX4UGuUGMpVD6Er_eI 

Bingo! You passed the test.

Jwt token validation passed

NGINX Plus can do the job to satisfy your top most enterprise application security requirements. It’s simple and it’s can get the job done quickly with less buck out of your pocket. Are you still thinking of App/Service Mesh? May be not until they provide required security features.

I am passionate about Information/Cloud Security and Cloud Compliance, always looking for opportunities to minimize security risks and to comply with regulations. For questions and comments, you can reach me over LinkedIn.

Leave a Reply