Implementing DevSecOps in AWS using CI/CD Pipeline

DevOps has completely changed the IT structure by applying the  combination of cultural philosophies, practices, and tools that increases an organization’s ability to deliver applications and services at high speed and updating and improving software products at a faster pace than organizations using traditional software development and deployment processes. It brings a collaborative approach to software development, testing and deployment. It also reduces the barriers between the developer and operation teams and bind them with one objective to deploy application quickly and through automation.

DevSecOps Primer / 101
image source :- https://www.linkedin.com/pulse/devsecops-primer-101-dhaval-shrimankar

However there is still one area that is lagging behind with all these rapid changes happening around it. Most of the organizations are neglecting security in DevOps design and as such these environments end up with an less agile and uncoordinated approach to incident management and mitigation.  To address this, we need to build in security continuously across the Software Development Life Cycle so that DevOps teams can deliver secure applications with speed and quality. The earlier you can introduce security into the workflow, the sooner you can identify and remedy security weaknesses and vulnerabilities. DevSecOps is about practices and tools that we use to setup built-in security practices across the software lifecycle. Some commonly used Application security tools are:

  • Static application security testing (SAST) like SonarQube, AWS CodeGuru
  • Software composition analysis (SCA) like Sentinel SCA, Checkmarx
  • Interactive application security testing (IAST) like Veracode
  • Dynamic application security testing (DAST) like OWASP Zap

AWS DevSecOps CI/CD pipeline with open source SCA, SAST and DAST tools

In this blog series, I will show you how to implement DevSecOps throughout application deployment cycle using AWS services like Code Commit, Code build , Code Pipeline code pipelines and integrate with service like AWS lambda, AWS Config. I will run many Open sources Security tools like SCA (Software Composite Analysis), SAST (Static Application Security Testing), DAST (Dynamic Application Security Testing), and aggregation of vulnerability findings into a single pane of glass using AWS Security Hub. We will be following all the best practices through security perspective along the pipelines and its integrated services.

AWS DevSecOps CICD pipeline architecture
Image Source:- AWS Documentation

Demo– Part 1 :- Deploying a SonarQube SAST server on EC2 Instance

Open the AWS Console, and navigate to the EC2 Service (under the Compute layer). Launch a new instance, and select the Amazon Linux 2 as AMI  Select  t2.medium or higher as Instance Type .Leave the default configuration as is, and click on Review and Launch. Create a new key pair as this key pair will be used to connect to your EC2 Instance through ssh. One your EC2 instance is ready , Connect to it through a terminal is using SSH and keypair you downloaded earlier.

There are three main prerequisites that should be satisfied before installing a SonarQube instance in a Linux-production environment. There an up and running supported SQL database, a non-root system user and JDK installed in the local environment. After they are satisfied, SonarQube software can be download and installed. Then SonarQube server should be configured to use the setup database and system user

Setup a PostgreSQL Database

Install PostgreSQL 9.6
sudo yum install postgresql96 postgresql96-server

Create a new PostgreSQL database cluster
sudo service postgresql96 initdb
Start PostgreSQL service
sudo service postgresql96 start
Change password of default PostgreSQL user
sudo passwd postgres
Login as Postgres user using the new password
su — postgres
Login to psql shell
psql
Create a user and database for sonar
CREATE USER sonar WITH ENCRYPTED PASSWORD ‘sonar_password’;
CREATE DATABASE sonarqube;
GRANT ALL PRIVILEGES ON DATABASE sonarqube to sonar;
#Don’t exit from psql shell

Edit authentication methods of PostgreSQL
locate pg_hba.conf file and copy the path into clipboard
SHOW hba_file; #inside psql shell /var/lib/pgsql96/data/pg_hba.conf #$HBA_FILE_PATH
open hba file in an editor
sudo nano $HBA_FILE_PATH
edit authentication methods of local and host connections as follows:-


#TYPE DATABASE USER ADDRESS METHOD #
#“local” is for Unix domain socket connections only #
local all sonar md5
local all all peer
#IPv4 local connections:#
host all all 127.0.0.1/32 md5
#IPv6 local connections: #
host all all ::1/128 md5

Create Sonar System User

3.1 Create a user group for sonar users
sudo groupadd sonar
3.2 Create a user named sonar without sign in options
sudo useradd -c “Sonar System User” -d /opt/sonarqube -g sonar -s /bin/bash sonar
3.3 Activate sonar user by setting a password to it
sudo passwd sonar
3.4 Add sonar group to ec2-user
sudo usermod -a -G sonar ec2-user

Install OpenJDK 11

4.1 Download zip file
curl -O https://download.java.net/java/GA/jdk11/13/GPL/openjdk-11.0.1_linux-x64_bin.tar.gz
4.2 Unzip and move files into an appropriate path
tar zxvf openjdk-11.0.1_linux-x64_bin.tar.gz
sudo mv jdk-11.0.1 /usr/local/
4.3 Change access to JDK folder
sudo chmod -R 755 /usr/local/jdk-11.0.1
4.4 Add Java to the path
4.4.1 Open /etc/profile in an editor
sudo nano /etc/profile
4.4.2 Add following lines add the end of the file
export JAVA_HOME=/usr/local/jdk-11.0.1
export PATH=$JAVA_HOME/bin:$PATH

4.4.3 Load new configurations
source /etc/profile


4.4.4 Check java is installed properly for each user

java -version

# Expected Output
openjdk version “11.0.1” 2018–10–16
OpenJDK Runtime Environment 18.9 (build 11.0.1+13)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.1+13, mixed mode)

Install SonarQube Server

Download SonarQube 7.9.1 Developer Edition
wget https://binaries.sonarsource.com/CommercialDistribution/sonarqube-developer/sonarqube-developer-7.9.1.zip
5.2 Unzip the downloaded zip file
unzip sonarqube-developer-7.9.1.zip
5.3 Move SonarQube to a file path of choosing (normally /opt/sonarqube)
sudo mv -v sonarqube-7.9.1/* /opt/sonarqube
5.4 Change ownership of all the sonarqube files to user sonar
sudo chown -R sonar:sonar /opt/sonarqube
5.5 Change file access privileges
sudo chmod -R 775 /opt/sonarqube
5.6 Set SONAR_HOME environment variable for future use (optional)
5.6.1 Open .bashrc file in an editor
nano ~/.bashrc
5.6.2 Enter the following line to the end of the file
export SONAR_HOME=/opt/sonarqube
5.6.3 Load new configurations
source ~/.bashrc #you can check whether variable is added by running echo $SONAR_HOME

Configure SonarQube

Set run as user
Open sonar.sh in an editor
sudo nano $SONAR_HOME/bin/linux-x86–64/sonar.sh
Find the line RUN_AS_USER, uncomment it by removing the pound sign and enter sonar user as the value
RUN_AS_USER=sonar

Other configurations
Open sonar.properties in an editor
sudo nano $SONAR_HOME/conf/sonar.properties
Add jdbc user name and password
sonar.jdbc.username=sonar
sonar.jdbc.password=sonar_password

Find and uncomment Postgres driver property and remove current schema param if you are not using a custom schema for SonarQube database
sonar.jdbc.url=jdbc:postgresql://localhost/sonarqube

Note:- Add a custom TCP security rule for EC2 instance to allow inbound traffic to the selected SonarQube port (default: 9000)

Start sonar server

$SONAR_HOME/bin/linux-x86–64/sonar.sh console #enter sonar system user password once prompted


6.5 Connect to SonarQube instance for the local machine
http://<host_ip>:<sonar_web_port>

6.6 Login to SonarQube server using default username & password
username : admin
password : admin


In the next part of this blog series , We will be creating a sample app by uploading code to code commit repository. We will then create a buildspec file with steps to integrate application with SonarQube server. Then we will use the AWS Code Build service to create a build job for the application. Once the Build process is completed we should see the code analysis report in the SonarQube dashboard.