Deploying a Web App with Kubernetes in Kali Linux - blackgem

W E L C O M E

https://i.imgur.com/fEamA3G.png

Saturday, April 1, 2023

Deploying a Web App with Kubernetes in Kali Linux


Let me show you how easy it is to install k8s and deploy a web app in kali linux. My original idea was to jump to pentesting kubernetes right away. However when I wrote this tutorial to deploy the lab, seemed to me that it was going to be super long. So, expect pentesting kubernetes in a later post.


Kubernetes is an open source container orchestration engine for automating deployment, scaling, and management of containerized applications. The open source project is hosted by the Cloud Native Computing Foundation. Google open-sourced the Kubernetes project in 2014.

For full information about kubernetes please go to their website. I am doing this in Kali Linux however you can find the installers in the site. 

Installing Kubernetes and Kubectl

sudo apt-get update && sudo apt-get upgrade

sudo apt-get install -y apt-transport-https ca-certificates curl

Now we download the google cloud public signing key by executing:

sudo curl -fsSLo/usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg

Let's add the kubernetes repository and install kubernetes:

echo "deb https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee -a /etc/apt/sources.list.d/kubernetes.list
curl -Ls "https://sbom.k8s.io/$(curl -Ls https://dl.k8s.io/release/latest.txt)/release"  | awk '/Package: registry.k8s.io\// {print $3}'

This will add a .list file (repository) in your /etc/apt/sources.list.d

Update the OS to take the changes:
sudo apt-get update
And now we are ready to install kubectl:
sudo apt-get install -y kubectl
To check the installation:
kubctl version --client --output=yaml


Installing Minikube

For testing purposes we are also going to install minikube so we can have a kubernetes pod running in our environment. 

Please note that docker runs inside minikube so it runs as a docker container. This means that you should have docker installed already in your machine. If you have Kali running as a virtual machine probably this step can be missed.
sudo curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube_latest_amd64.deb 
sudo dpkg -i minikube_latest_amd64.deb
minikube start

Interacting with our cluster

Now we are able to list all the nodes in the cluster we have in our environment using kubectl:






Deploying the WebApp


Since we are setting up a realistic environment for pentesting, we are going to deploy a mongo-db database and a web application. 

The web application will connect to the database using external configuration data with Secret and Config Map so we can access the app from the browser.

For the web application we can use one from dockerhub. This applications is courtesy by TechWorld with Nana you can follow her youtube channel to learn more about kubernetes. 

Creating the configuration files

Using Visual Studio we are going to create 4 configuration files:



1. Create mongo-config.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: mongo-config
data:
  mongo-url: mongo-service



2. Create mongo-secret

apiVersion: v1

kind: Secret
metadata:
  name: mongo-secret
type: Opaque
data:
  mongo-user: bW9uZ291c2Vy
  mongo-password: bW9uZ29wYXNzd29yZA==

You need to encode the values for username and password:
echo -n mongouser | base64
echo -n mongopassword | base64

and paste the encoded values in our file.


Big disclosure here: There are more secure ways to deploy secrets but for the sake of the pentest we are going to keep the by-default b64 encoded password. Please refer to kubernetes site for authentication configuration.

3. Mongo Deployment and Service File (in one file as they belong together)

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mongo-deployment
  labels:
    app: mongo
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mongo
  template:
    metadata:
      labels:
        app: mongo
    spec:
      containers:
      - name: mongodb
        image: mongo:latest
        ports:
        - containerPort: 27017
---
apiVersion: v1
kind: Service
metadata:
  name: mongo-service
spec:
  selector:
    app: mongo
  ports:
    - protocol: TCP
      port: 27017
      targetPort: 27017



Replicas = how many pods you want to create using this blueprint.
Port attribute = sets the port of the service
Target port = tells the service to which port you should forward the request to the pods (container pod)

4. Web App Deployment and Service 

apiVersion: apps/v1
kind: Deployment
metadata:
  name: webapp-deployment
  labels:
    app: webapp
spec:
  replicas: 1
  selector:
    matchLabels:
      app: webapp
  template:
    metadata:
      labels:
        app: webapp
    spec:
      containers:
      - name: webapp
        image: nanajanashia/k8s-demo-app:v1.0
        ports:
        - containerPort: 3000

---

apiVersion: v1
kind: Service
metadata:
  name: mongo-service
spec:
  selector:
    app: mongo
  ports:
    - protocol: TCP
      port: 3000
      targetPort: 3000




Now, we can pass the secret data to Mongo Deployment

          env:
        - name: MONGO_INITDB_ROOT_USERNAME
          valueFrom: 
            secretKeyRef:
              name: mongo-secret
              key: mongo-user
        - name: MONGO_INITDB_ROOT_PASSWORD
          valueFrom:
             secretKeyRef:
               name: mongo-secret
               key: mongo-password



In mongo environment documentation we can see the environment variables that we have set in our mongo.yaml

When our webApp starts, it needs to know what database we need to connect to, what user and password.

So we pass these 3 pieces of data as environment variables to our web application:

                   env:
        - name: USER_NAME
          valueFrom:
            secretKeyRef:
              name: mongo-secret
              key: mongo-user
        - name: USER_PWD
          valueFrom:
            secretKeyRef:
              name: mongo-secret
              key: mongo-password
        - name: DB_URL
          valueFrom:
            configMapKeyRef:
              name: mongo-config
              key: mongo-url



And finally we make the web app accessible from a browser:

So far we have been configuring internal services, and now we have to make them external.

We add a type NodePort which is an external service type and it requires a third port called precisely nodePort. This exposes the service on each Node's IP at a static port. Please note that these ports ranges are between 30000 and 32767.


Deploying all resources in Minikube cluster 

We can do this from the terminal in Visual Studio. We start by creating the external configuration:

kubectl apply -f mongo-config.yaml
kubectl apply -f mongo-secret.yaml
kubectl apply -f mongo.yaml
kubectl apply -f webapp.yaml

Note: -f stands for file.


Interacting with our newly created cluster


To list all the components we just created in the cluster: deployments, pods, mongo, web apps and services.

kubectl get all


To get configmap, secret and pods:

kubectl get configmap
kubectl get secret
kubectl get pod


To check the logs, we specify the name of the pod running:

kubectl logs webapp-deployment-9fccd564d-k6smk


Accessing the Web App from the Browser

As a final step, we validate that we can see our app from the browser.

kubectl get svc


We can see the port we are going to connect to is port 30100 but to know the IP we have to find the one from the minikube.

minikube ip


And that's it, we have an application deployed ready to be tested in our next post.

Thank you for reading, I hope you learnt something new today and this is useful for you. See you next time.






No comments:

Post a Comment