Science and technology

Security scanning your DevOps pipeline

Security is among the most necessary concerns for operating in any setting, and utilizing open supply software program is an effective way to deal with safety with out going over finances in your company setting or on your house setup. It is straightforward to speak in regards to the ideas of safety, however it’s one other factor to know the instruments that may get you there. This tutorial explains tips on how to arrange safety utilizing Jenkins with Anchore.

There are some ways to run Kubernetes. Using Minikube, a prepackaged digital machine (VM) setting designed for native testing, reduces the complexity of operating an setting.

Technology What is it?
Jenkins An open supply automation server
Anchore A centralized service for inspection, evaluation, and certification of container photographs
Minikube A single-node Kubernetes cluster inside a VM

In this tutorial, you will discover ways to add Jenkins and Anchore to Kubernetes and configure a scanning pipeline for brand new container photographs and registries.

Note: For finest efficiency on this tutorial, Minikube requires no less than 4 CPUs.

Basic necessities

Knowledge

  • Docker (together with a Docker Hub account)
  • Minikube
  • Jenkins
  • Helm
  • Kubectl

Software

  • Minikube
  • Helm
  • Kubectl consumer
  • Anchore CLI put in domestically

Set up the setting

Install Minikube in no matter approach that is smart on your setting. If you might have sufficient assets, I like to recommend giving a bit greater than the default reminiscence and CPU energy to your VM:

$ minikube config set reminiscence 8192
⚠️  These modifications will take impact upon a minikube delete and then a minikube begin
$ minikube config set cpus four
⚠️  These modifications will take impact upon a minikube delete and then a minikube begin

If you might be already operating a Minikube occasion, it’s essential to delete it utilizing minikube delete earlier than persevering with.

Next, install Helm, the usual Kubernetes bundle supervisor, in no matter approach is smart on your working system.

Now you are prepared to put in the purposes.

Install and configure Anchore and Jenkins

To start, begin Minikube and its dashboard.

$ minikube begin
?  minikube v1.1.zero on darwin (amd64)
?  Tip: Use 'minikube begin -p <title>' to create a brand new cluster, or 'minikube delete' to delete this one.
?  Restarting present virtualbox VM for "minikube" ...
⌛  Waiting for SSH entry ...
?  Configuring setting for Kubernetes v1.14.2 on Docker 18.09.6
?  Relaunching Kubernetes v1.14.2 utilizing kubeadm ...
⌛  Verifying: apiserver proxy etcd scheduler controller dns
?  Done! kubectl is now configured to make use of "minikube"

$ minikube dashboard
?  Enabling dashboard ...
?  Verifying dashboard well being ...
?  Launching proxy ...
?  Verifying proxy well being ...
?  Opening http://127.zero.zero.1:52646/api/v1/namespaces/kube-system/companies/http:kubernetes-dashboard:/proxy/ in your default browser...

As lengthy as you keep linked to this terminal session, you should have entry to a visible dashboard for Minikube at 127.zero.zero.1:52646.

 

Create namespace and set up Jenkins

The subsequent step is to get the Jenkins construct setting up and operating. To begin, guarantee your storage is configured for persistence so you’ll be able to reuse it later. Set the storage class for Persistent Volumes prior to installing Helm, so its set up can be persistent throughout reboots.

Either exit the dashboard utilizing CTRL+C or open a brand new terminal to run:

$ minikube addons allow default-storageclass
✅  default-storageclass was efficiently enabled

Using namespaces

I check fairly a couple of completely different purposes, and I discover it extremely useful to make use of namespaces in Kubernetes. Leaving all the pieces within the default namespace can overcrowd it and make it difficult to uninstall a Helm-installed utility. If you stick with this for Jenkins, you’ll be able to take away it by operating helm del –purge jenkins –namespace jenkins then kubectl delete ns jenkins. This is way simpler than manually searching and pecking by an extended listing of containers.

Install Helm

To use Helm, Kubernetes’ default bundle supervisor, initialize an setting and set up Jenkins.

$ kubectl create ns jenkins
namespace "jenkins" created
$ helm init
helm init
Creating /Users/alleycat/.helm
Creating /Users/alleycat/.helm/repository
Creating /Users/alleycat/.helm/repository/cache
Creating /Users/alleycat/.helm/repository/native
Creating /Users/alleycat/.helm/plugins
Creating /Users/alleycat/.helm/starters
Creating /Users/alleycat/.helm/cache/archive
Creating /Users/alleycat/.helm/repository/repositories.yaml
Adding secure repo with URL: https://kubernetes-charts.storage.googleapis.com
Adding native repo with URL: http://127.zero.zero.1:8879/charts
$HELM_HOME has been configured at /Users/alleycat/.helm.

Tiller (the Helm server-side element) has been put in into your Kubernetes Cluster.

Please be aware: by default, Tiller is deployed with an insecure 'enable unauthenticated customers' coverage.
To forestall this, run `helm init` with the --tiller-tls-verify flag.
For extra info on securing your set up see: https://docs.helm.sh/using_helm/#securing-your-helm-installation
$ helm set up --name jenkins secure/jenkins --namespace jenkins
NAME:   jenkins
LAST DEPLOYED: Tue May 28 11:12:39 2019
NAMESPACE: jenkins
STATUS: DEPLOYED

RESOURCES:
==> v1/ConfigMap
NAME           DATA  AGE
jenkins        5     0s
jenkins-tests  1     0s

==> v1/Deployment
NAME     READY  UP-TO-DATE  AVAILABLE  AGE
jenkins  zero/1    1           zero          0s

==> v1/PersistentVolumeClaim
NAME     STATUS   VOLUME    CAPACITY  ACCESS MODES  STORAGECLASS  AGE
jenkins  Pending  customary  0s

==> v1/Pod(associated)
NAME                      READY  STATUS   RESTARTS  AGE
jenkins-7565554b8f-cvhbd  zero/1    Pending  zero         0s

==> v1/Role
NAME                     AGE
jenkins-schedule-agents  0s

==> v1/RoleBinding
NAME                     AGE
jenkins-schedule-agents  0s

==> v1/Secret
NAME     TYPE    DATA  AGE
jenkins  Opaque  2     0s

==> v1/Service
NAME           TYPE          CLUSTER-IP    EXTERNAL-IP  PORT(S)         AGE
jenkins        LoadBalancer  10.96.90.zero    <pending>    8080:32015/TCP  0s
jenkins-agent  ClusterIP     10.103.85.49  <none>       50000/TCP       0s

==> v1/ServiceAccount
NAME     SECRETS  AGE
jenkins  1        0s

NOTES:
1. Get your 'admin' consumer password by operating:
  printf $(kubectl get secret --namespace jenkins jenkins -o jsonpath="" | base64 --decode);echo
2. Get the Jenkins URL to go to by operating these instructions in the identical shell:
  NOTE: It might take a couple of minutes for the LoadBalancer IP to be out there.
        You can watch the standing of by operating 'kubectl get svc --namespace jenkins -w jenkins'
  export SERVICE_IP=$(kubectl get svc --namespace jenkins jenkins --template " . ")
  echo http://$SERVICE_IP:8080/login

three. Login with the password from step 1 and the username: admin

For extra info on operating Jenkins on Kubernetes, go to:
https://cloud.google.com/options/jenkins-on-container-engine

Note the Bash one-liner above that begins with printf; it lets you question for the Jenkins password and it may be difficult to search out your default Jenkins password with out it. Take be aware of it and reserve it for later.

Set up port forwarding to log into the UI

Now that you have put in Minikube and Jenkins, log in to configure Jenkins. You’ll want the Pod title for port forwarding:

$ kubectl get pods --namespace jenkins
NAME                       READY     STATUS    RESTARTS   AGE
jenkins-7565554b8f-cvhbd   1/1       Running   zero          9m

Run the next to arrange port forwarding (utilizing your Jenkins pod title, which can be completely different from mine beneath):

# confirm your pod title from the namespace named jenkins
kubectl get pods --namespace jenkins
NAME                       READY     STATUS    RESTARTS   AGE
jenkins-7565554b8f-cvhbd   1/1       Running   zero          37m
# then ahead it
$ kubectl port-forward jenkins-7565554b8f-cvhbd 8088:8080 -n jenkins
Forwarding from 127.zero.zero.1:8088 -> 8080
Forwarding from [::1]:8088 -> 8080

Note that you’ll want a number of tabs in your terminal when you run the port-forwarding command.

Leave this tab open going ahead to take care of your port-forwarding session.

Navigate to Jenkins in your most popular browser by going to localhost:8088. The default username is admin and the password is saved in Kubernetes Secrets. Use the command on the finish of the helm set up jenkins step:

$ printf $(kubectl get secret --namespace jenkins jenkins -o jsonpath="" | base64 --decode);echo
Jfstacz2vy

After logging in, the UI will show Welcome to Jenkins!

From right here we’ll have to put in some plugins to Jenkins for our pipeline to work correctly. From the principle web page select Manage Jenkins on the left-hand facet.

 

Then select Manage Plugins

Then select Available 

Then select the checkboxes beside these plugins proven beneath

Once you might have checked the containers scroll to the underside of the web page and select Install with out Restart.
 

 

 

Deploy Anchore

Anchore Engine “is an open source project that provides a centralized service for inspection, analysis, and certification of container images.” Deploy it inside Minikube to do some safety inspection in your Jenkins pipeline. Add a safety namespace for the Helm set up, then run an set up:

$ kubectl create ns safety
namespace "security" created
$ helm set up --name anchore-engine secure/anchore-engine --namespace safety
NAME:   anchore-engine
LAST DEPLOYED: Wed May 29 12:22:25 2019
NAMESPACE: safety
STATUS: DEPLOYED
## And much more output

Confirm that the service is up and operating with this command:

kubectl run -i --tty anchore-cli --restart=Always --image anchore/engine-cli --env ANCHORE_CLI_USER=admin --env ANCHORE_CLI_PASS=$ANCHORE_CLI_PASS --env ANCHORE_CLI_URL=http://anchore-engine-anchore-engine-api.safety.svc.cluster.native:8228/v1/
If you don't see a command immediate, attempt urgent enter.
[anchore@anchore-cli-86d7fd9568-rmknw anchore-cli]$

If you might be logged into an Anchore container (just like above), then the system is on-line. The default password for Anchore is admin/foobar. Type exit to go away the terminal.

Use port forwarding once more to entry the Anchore Engine API out of your host system:

$ kubectl get pods --namespace safety
NAME                                                         READY     STATUS    RESTARTS   AGE
anchore-engine-anchore-engine-analyzer-7cf5958795-wtw69      1/1       Running   zero          3m
anchore-engine-anchore-engine-api-5c4cdb5587-mxkd7           1/1       Running   zero          3m
anchore-engine-anchore-engine-catalog-648fcf54fd-b8thl       1/1       Running   zero          3m
anchore-engine-anchore-engine-policy-7b78dd57f4-5dwsx        1/1       Running   zero          3m
anchore-engine-anchore-engine-simplequeue-859c989f99-5dwgf   1/1       Running   zero          3m
anchore-engine-postgresql-844dfcc468-s92c5                   1/1       Running   zero          3m
# Find the API pod title above and add it to the command beneath
$ kubectl port-forward anchore-engine-anchore-engine-api-5c4cdb5587-mxkd7 8228:8228 --namespace safety

Join Anchore and Jenkins

Go again to the Jenkins UI at http://127.0.0.1:8088/. On the principle menu, click on Manage Jenkins > Manage Plugins. Choose the Available tab, then scroll down or seek for the Anchore Container Image Scanner Plugin. Check the field subsequent to the plugin and select Install with out restart.

Once the set up completes, return to the principle menu in Jenkins and select Manage Jenkins, then Configure System. Scroll all the way down to Anchore Configuration. Confirm Engine Mode is chosen and a URL is entered, which is output from the Helm set up. Add the username and password (default admin/foobar). For debugging functions, test Enable DEBUG logging.

Now that the plugin is configured, you’ll be able to arrange a Jenkins pipeline to scan your container builds.

Jenkins pipeline and Anchore scanning

The objective of this setup is to have the ability to examine container photographs on the fly to make sure they meet safety necessities. To accomplish that, use Anchore Engine and provides it permission to entry your photographs. In this instance, they’re on Docker Hub, however they may be on Quay or another container registry supported by Anchore

In order to run the required instructions on the command line, we have to discover our Anchore pod title, then SSH into it utilizing kubectl exec:

$ kubectl get all
NAME                               READY     STATUS    RESTARTS   AGE
pod/anchore-cli-86d7fd9568-rmknw   1/1       Running   2          second

NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.96.zero.1    <none>        443/TCP   7d

NAME                          DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/anchore-cli   1         1         1            1           second

NAME                                     DESIRED   CURRENT   READY     AGE
replicaset.apps/anchore-cli-86d7fd9568   1         1         1         second
# Let’s hook up with our anchore-cli pod
$ kubectl exec -it anchore-cli-86d7fd9568-rmknw -i -t -- bash
[anchore@anchore-cli-86d7fd9568-rmknw anchore-cli]$ anchore-cli --u admin  --p foobar  registry add index.docker.io <username> <password>
Registry: index.docker.io
User: jrepka
Type: docker_v2
Verify TLS: True
Created: 2019-05-14T22:37:59Z
Updated: 2019-05-14T22:37:59Z

Anchore Engine is now able to work along with your registry. There are several ways it could accomplish that, together with:

  • Analyzing photographs
  • Inspecting picture content material
  • Scanning repositories
  • Viewing safety vulnerabilities

Point Anchore Engine towards a picture to research it in opposition to your coverage. For our testing, we’ll use the publicly out there Cassandra picture:

[anchore@anchore-cli-86d7fd9568-rmknw anchore-cli]$ anchore-cli --u admin  --p foobar   picture add
docker.io/library/cassandra:newest

Image Digest: sha256:7f7afff84384e36593b085d62e087674029de9aced4482c7780f155d8ee55fad
Parent Digest: sha256:800084987d58c2a62daeea4662ecdd79fd4928d449279bd410ef7690ef482469
Analysis Status: not_analyzed
Image Type: docker
Analyzed At: None
Image ID: a34c036183d18527684cdb613fbb1c806c7e1bc26f6911dcc25e918aa7b093fc
Dockerfile Mode: None
Distro: None
Distro Version: None
Size: None
Architecture: None
Layer Count: None

Full Tag: docker.io/library/cassandra:newest
Tag Detected At: 2019-07-09T17:44:45Z

You may also must seize a default coverage ID to check in opposition to on your pipeline. (In a future article, I’ll go into customizing coverage and whitelist guidelines.)

Run the next command to get the coverage ID:

[anchore@anchore-cli-86d7fd9568-rmknw anchore-cli]$ anchore-cli --u admin  --p foobar coverage listing

Policy ID                                   Active        Created                     Updated                    
2c53a13c-1765-11e8-82ef-23527761d060        True          2019-05-14T22:12:05Z        2019-05-14T22:12:05Z

Now that you’ve got added a registry and the picture you need, you’ll be able to construct a pipeline to scan it repeatedly.

Scanning works on this order: Build, push, scan. To forestall photographs that don’t meet safety necessities from making it into manufacturing, I like to recommend a tiered method to safety scanning: promote a container picture to a separate improvement setting and advertise to manufacturing solely as soon as it passes the Anchore Engine’s scan.

We cannot do something too thrilling till we configure our customized coverage, so we are going to be certain a scan completes efficiently by operating a Hello World model of it. Below is an instance workflow written in Groovy:

node

To run this code, log again into the Jenkins UI at localhost:8088, select New Item, Pipeline, then place this code block into the Pipeline Script space.

It will take a while to finish since we’re constructing the complete Cassandra picture added above. You will see a blinking crimson icon within the meantime. 

And it would ultimately end and cross. That means we now have set all the pieces up appropriately.

That’s a wrap

If you made it this far, you might have a operating Minikube configuration with Jenkins and Anchore Engine. You even have a number of photographs hosted on a container registry service and a approach for Jenkins to point out errors when photographs do not meet the default coverage. In the following article, we are going to construct a customized pipeline that verifies safety insurance policies set by Anchore Engine.

Anchore can be used to scan large-scale Amazon Elastic Container Registries (ECRs), so long as the credentials are configured correctly in Jenkins.

Other assets

This is quite a lot of info for one article. If you need extra particulars, the next hyperlinks (which embrace my GitHub for all of the examples on this tutorial) might assist:

Are there any particular pipelines you need me to construct within the subsequent tutorial? Let me know within the feedback.

Most Popular

To Top