Hello internet, I made an experiment with a simple DevSecOps CI (Continuous Integration) pipeline based on some of the guidelines from OWASP and documented the steps that I made in this README file. It uses Gitlab, SonarQube and Jenkins docker images to automate a CI pipeline for a NodeJs App.
This project contains a docker compose yaml file which setup the following containers:
- Gitlab
- jenkins-blueocean (custom jenkins image with blueocean plugin)
- sonarQube
I'm still learning. So feel free to give any feedback! 👋
More details on using open-source devops tools can be found at https://owasp.org/www-project-devsecops-guideline/latest/
Requirements
- Docker Compose V2
- Internet
- Lots of RAM (at least 16GB)
-
Use the available scripts to start the docker-compose:
- use the docker-compose-up.sh file to start docker compose
- command:
sh docker-compose-up.sh
- command:
- use the docker-compose-up.sh file to down docker compose (if containers need to be removed)
- command:
sh docker-compose-down.sh
- command:
*Note that it will take some time for the containers to startup (especially Gitlab container 😞)
- use the docker-compose-up.sh file to start docker compose
-
Setup the passwords for the following:
- Jenkins:
- url: http://localhost:8080
- find the initial password @ /var/jenkins_home/secrets/initialAdminPassword
- goto the jenkins container > terminal
- enter
cat var/jenkins_home/secrets/initialAdminPassword
to get the initial password - note: to select the pipeline and git plugins to download at startup
- Sonarqube:
- url: http://localhost:9000
- both initial username and password is "admin"
- Gitlab
- url: http://localhost:80
- find the initial password @ etc/gitlab/initial_root_password
- enter
cat etc/gitlab/initial_root_password
to get the initial password - username is "root"
- Jenkins:
-
Download the necessary plugins for the pipeline @ Jenkins.
- Goto Manage Jenkins > Manage Plugins
- Download the following plugins and refresh the container after that
- NodeJs Plugin
- OWASP Dependency-Check Plugin
- SonarQube Scanner for Jenkins
- Git (if not downloaded yet)
- Pipeline (if not downloaded yet)
-
Setup the credentials for Jenkins to connect to SonarQube and Gitlab
- Goto Manage Jenkins > Manage Credentials
- Click on the arrow button beside (global) > Add credentials
- Create the following credentials
- Id: gitlab-creds
- kind: username with password
- enter the username (root for admin) and password created at gitlab
- description: gitlab credentials
- Id: sonarqube-creds
- Id: gitlab-creds
-
Configure Jenkins
- To setup connection to sonarqube
- Goto Configure Jenkins > Configure System
- Under SonarQube servers, Click on "Add sonarqube" and add the following
- Name: sonarqube
- Server URL: http://sonarQube:9000 (sonarQube is the name of the sonarqube container)
- Server authentication token: choose authentication token for sonarqube
- Setup tools according to the following settings
- Goto Configure Jenkins > Global Tools Configuration
- NodeJS
- Click on Add NodeJS
- Name: NodeJS
- Install Automatically
- Choose the version to install
- DependencyCheck
- Click on Add Dependency Check
- Name: dependencyCheck
- Install Automatically
- Choose the version to install
- SonarQube Scanner
- Click on Add SonarQube Scanner
- Name: sonar-scanner
- Install automatically
- Choose the version to install
- NodeJS
- Goto Configure Jenkins > Global Tools Configuration
- To setup connection to sonarqube
-
Push your NodeJs code into Gitlab container
- note that git remote url will look something like this if you are using localhost
http://host.docker.internal:80/gitlab-instance-****/repo-name.git
- note that git remote url will look something like this if you are using localhost
-
Add the Jenkinsfile and sonar-project.properties files from the pipeline_AddOns folder to the repo
- modify the sonar-project.properties file to suit the NodeJS project
-
Create a pipeline item in Jenkins
- Definition: Pipeline script from SCM
- Repository url: http://gitlab/gitlab-instance-****/repo-name.git
- Credentials: (choose the one with the gitlab credentials description)
- Script Path (path to the jenkins file): Jenkins *Jenkins file can be renamed with .Jenkinsfile extension e.g. pipeline.Jenkinsfile
-
Click on " > Build Now " to start the pipeline
*note that it will take some time for the tools to be installed in the Jenkins container initially
After the build job is completed, the dependency check results can be displayed in the job results. The sonarqube results can be viewed at http://localhost:9000. The Gitleaks results can be viewed in the console output (Use blueocean to view it).
- Adjust the time zone for the timestamp in the console output
- Adjust the time displayed in the console output
- Under Configure System > Timestamper
- use the format
'<b>'HH:mm:ss a'</b> '
forhour:min:sec AM/PM
The pipeline first goes through the usual basic stages and starts scanning for vulnerabilties after that.
-
git checkout
-
install node modules
-
build the app
-
run tests
-
Sonarqube for SAST/Static Application Security Testing
- test for vulnerabilities within code
-
Dependency Check for SCA/Software Composition Analysis
- scans for vulnerabilities in open source libraries that are used
(Missing container and gitlaks scanning stages. I didn't have enough resources to run them.) 😭
- Containers in a network should be reachable in the same network. So under the Jenkins settings, it is possible to use
http://<sonarqube container name>:9000
- Declare the name of the tools. The tool names are used in the Jenkins pipeline file
- Inital usernames and passwords could have been added in the docker files.