Hello Folks I came up with a New Project in Devsecops. This Project is Inspired by this ProjectDiscovery blog — https://blog.projectdiscovery.io/implementing-nuclei-into-your-github-ci-cd-for-scanning-live-web-applications/
Our Main goal is to run Nuclei In Infrastructure to Dectect Vulnerabilities in early development and in Internal Apps.
I tried this above Project from projectdiscovery In Our Github CI/CD and Noticed Some Limitations.
Now Days Everyone Switching to Kubernestes and Microservices. So we are
How Devops Team Can Use this As DAST in CI/CD -> Microservices has service endpoints like this http://api-backend.default.svc.cluster.local:9000 collect all these service endpoints in file called urls.txt and give this file as a input to nuclei. Now how nuclei will access this urls? deploy nuclei in K8s cluster as Cronjob and trigger the job after Push commit in master branch
I am Using GKE Cluster and hosted some Microservices over there.
You can use any Service EKS , AKS , GKE ..etc
gcloud container clusters create clustername --num-nodes=3.# command to create Cluster In google Cloud
Demo of Internal app Microservice.
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
replicas: 2
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: Yourname/Yourapp
ports:
- containerPort: 3000---
apiVersion: v1
kind: Service
metadata:
name: myapp
spec:
type: ClusterIP
selector:
app: myapp
ports:
- port: 8080
targetPort: 3000
As you Can see i am Using ClusterIP and not Loadbalancer so No One Can Access this Publically.
For demo Purpose I hosted 4 Services in my Cluster.
So how Nuclei Works in K8s? I made a CronJob to Run Nuclei on these Services urls { FQDN URLS }. CronJob will Run on Every Midnight. Also we can trigger the Job By kubectl Command so After Successful Build we can scan apps for Vulnerabilities.
urls.txt
# FQDN URLS
http://juiceapp.default.svc.cluster.local:9000
http://myapp.default.svc.cluster.local:8080
http://myapi.default.svc.cluster.local:5000
http://djangoboy.default.svc.cluster.local:8086# This is how we can Access Internal apps in K8s
Main Script Where Nuclei Run — nuclei-scan.sh
#!/bin/bashnuclei -update-templates. # Update to install New Templates
# delte Unwanted Templates
rm -rf /root/nuclei-templates/iot /root/nuclei-templates/token-spray /root/nuclei-templates/network /root/nuclei-templates/miscellaneous /root/nuclei-templates/technologies /root/nuclei-templates/dns /root/nuclei-templates/osint /root/nuclei-templates/misconfiguration/http-missing-security-headers.yaml /root/nuclei-templates/cves/2016/CVE-2016-6210.yaml /root/nuclei-templates/cves/2018/CVE-2018-15473.yaml /root/nuclei-templates/cves/2017/CVE-2017-5487.yaml /root/nuclei-templates/ssl
rm -rf /root/nuclei-templates/http/iot /root/nuclei-templates/http/token-spray /root/nuclei-templates/http/network /root/nuclei-templates/http/miscellaneous /root/nuclei-templates/http/technologies /root/nuclei-templates/http/dns /root/nuclei-templates/http/osint
echo "scan started" | notify -silent
# Nuclei Run Command
nuclei -t /root/nuclei-templates -l ./urls.txt --severity low,high,medium,critical -o nucleiop.txt
# get Output in Discord Or Slack Channel. Also you can create Jira ticket read Docs.
cat nucleiop.txt | notify -silent
echo "scan completed" | notify -silent
Dockerfile to create Image for Above Script
FROM golang:1.20-bullseyeRUN go install -v github.com/projectdiscovery/nuclei/v2/cmd/nuclei@latest
RUN go install -v github.com/tomnomnom/anew@latest && \
go install -v github.com/projectdiscovery/notify/cmd/notify@latest
WORKDIR /app
COPY ./nuclei_scan . # above bash script
COPY ./urls.txt . # list of FQDN urls
COPY ./provider-config.yaml /root/.config/notify/provider-config.yaml # config file for notify
RUN chmod +x nuclei_scan
CMD ["sh" ,"nuclei_scan"]
docker build -t yourreponame/imagename:latestdocker push yourreponame/imagename:latest
Cronjob manifest file
apiVersion: batch/v1
kind: CronJob
metadata:
name: nuclei-scan-cronjob
spec:
schedule: "0 0 * * *"
jobTemplate:
spec:
template:
spec:
dnsPolicy: ClusterFirst
dnsConfig:
nameservers:
- 8.8.8.8
containers:
- name: nuclei-scan-container
image: yourreponame/imagename:latest
restartPolicy: OnFailure
kubectl apply -f cronjob.yaml
You can trigger this job manually by Kubectl command
kubectl create job --from=cronjob/nuclei-scan-cronjob nuclei-scan-manual
Now how to use this in CI/CD. I am using github-action workflows for this
name: CI/CD
on:
push:
branches:
- main
- master
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2 - name: Configure Google Cloud SDK
uses: google-github-actions/[email protected]
with:
project_id: yourProjectName
service_account_key: ${{ secrets.GCP_SA_KEY }}
- name: Trigger the Job
run: |
gcloud container clusters get-credentials YourClusterName --region=RegionName
kubectl create job --from=cronjob/nuclei-scan-cronjob nuclei-scan-manual
this is basic workflow there are multiple jobs in CI/CD process i am just showing how to configure GKE cluster in github-action and trigger the Job
service_account_key: ${{ secrets.GCP_SA_KEY }}.
Go the google Cloud console -> IAM -> Service Account -> keys - JSON KEYS
store that JSON key in Github Secrets.
After Successful Build we can trigger the Job to Scan the Apps.
I used Notify tool from Projectdiscovery to send the nuclei output to my Discord Server.
Follow me on Linkdein
https://www.linkedin.com/in/ajay-magar/
Happy Hacking :))