Commit f22a8edf authored by Alan (Maciej) Paruszewski's avatar Alan (Maciej) Paruszewski Committed by Shinya Maeda

Add Running Container Scanning CI Template

This change adds new template to pefrom Running Container Scanning
scans.

Changelog: added
EE: true
parent 7edc61c2
......@@ -29,7 +29,13 @@ in the [CI documentation](../../ci/yaml/index.md#image).
For consistency, scanning jobs should be named after the scanner, in lower case.
The job name is suffixed after the type of scanning:
`_dependency_scanning`, `_container_scanning`, `_dast`, and `_sast`.
- `_dependency_scanning`
- `_cluster_image_scanning`
- `_container_scanning`
- `_dast`
- `_sast`
For instance, the dependency scanning job based on the "MySec" scanner would be named `mysec_dependency_scanning`.
### Image
......@@ -69,7 +75,15 @@ so the [`allow_failure`](../../ci/yaml/index.md#allow_failure) parameter should
Scanning jobs must declare a report that corresponds to the type of scanning they perform,
using the [`artifacts:reports`](../../ci/yaml/index.md#artifactsreports) keyword.
Valid reports are: `dependency_scanning`, `container_scanning`, `dast`, `api_fuzzing`, `coverage_fuzzing`, and `sast`.
Valid reports are:
- `dependency_scanning`
- `container_scanning`
- `cluster_image_scanning`
- `dast`
- `api_fuzzing`
- `coverage_fuzzing`
- `sast`
For example, here is the definition of a SAST job that generates a file named `gl-sast-report.json`,
and uploads it as a SAST report:
......@@ -90,9 +104,15 @@ it's declared under the `reports:sast` key in the job definition, not because of
Certain GitLab workflows, such as [AutoDevOps](../../topics/autodevops/customize.md#disable-jobs),
define CI/CD variables to indicate that given scans should be disabled. You can check for this by looking
for variables such as `DEPENDENCY_SCANNING_DISABLED`, `CONTAINER_SCANNING_DISABLED`,
`SAST_DISABLED`, and `DAST_DISABLED`. If appropriate based on the scanner type, you should then
disable running the custom scanner.
for variables such as:
- `DEPENDENCY_SCANNING_DISABLED`
- `CONTAINER_SCANNING_DISABLED`
- `CLUSTER_IMAGE_SCANNING_DISABLED`
- `SAST_DISABLED`
- `DAST_DISABLED`
If appropriate based on the scanner type, you should then disable running the custom scanner.
GitLab also defines a `CI_PROJECT_REPOSITORY_LANGUAGES` variable, which provides the list of
languages in the repository. Depending on this value, your scanner may or may not do something different.
......@@ -194,6 +214,19 @@ using the variables `DOCKER_USER` and `DOCKER_PASSWORD`.
If these are not defined, then the scanner should use
`CI_REGISTRY_USER` and `CI_REGISTRY_PASSWORD` as default values.
#### Cluster Image Scanning
To be consistent with the official `cluster_image_scanning` for GitLab, scanners must scan the
Kubernetes cluster whose configuration is given by `KUBECONFIG`.
If you use the `CIS_KUBECONFIG` CI/CD variable, then the
`KUBECONFIG` variable is ignored and the cluster specified in the
`CIS_KUBECONFIG` variable is scanned instead. If you don't provide
the `CIS_KUBECONFIG` CI/CD variable, the value defaults to the value of
`$KUBECONFIG`. `$KUBECONFIG` is a predefined CI/CD variable configured when the project is assigned to a
Kubernetes cluster. When multiple contexts are provided in the `KUBECONFIG` variable, the context
selected as `current-context` will be used to fetch vulnerabilities.
#### Configuration files
While scanners may use `CI_PROJECT_DIR` to load specific configuration files,
......@@ -282,7 +315,8 @@ The format is extensively described in the documentation of
[SAST](../../user/application_security/sast/index.md#reports-json-format),
[DAST](../../user/application_security/dast/#reports),
[Dependency Scanning](../../user/application_security/dependency_scanning/index.md#reports-json-format),
and [Container Scanning](../../user/application_security/container_scanning/index.md#reports-json-format).
[Container Scanning](../../user/application_security/container_scanning/index.md#reports-json-format),
and [Cluster Image Scanning](../../user/application_security/cluster_image_scanning/index.md#reports-json-format).
You can find the schemas for these scanners here:
......@@ -310,7 +344,12 @@ We recommend that you generate a UUID and use it as the `id` field's value.
#### Category
The value of the `category` field matches the report type:
`dependency_scanning`, `container_scanning`, `sast`, and `dast`.
- `dependency_scanning`
- `cluster_image_scanning`
- `container_scanning`
- `sast`
- `dast`
#### Scanner
......@@ -480,6 +519,31 @@ so these attributes are mandatory.
The `image` is also mandatory.
All other attributes are optional.
#### Cluster Image Scanning
The `location` of a `cluster_image_scanning` vulnerability has a `dependency` field. It also has
an `operating_system` field. For example, here is the `location` object for a vulnerability
affecting version `2.50.3-2+deb9u1` of Debian package `glib2.0`:
```json
{
"dependency": {
"package": {
"name": "glib2.0"
},
},
"version": "2.50.3-2+deb9u1",
"operating_system": "debian:9",
"image": "index.docker.io/library/nginx:1.18"
}
```
The affected package is found when scanning the image of the pod `index.docker.io/library/nginx:1.18`.
The location fingerprint of a Cluster Image Scanning vulnerability combines the
`operating_system` and the package `name`, so these attributes are mandatory. The `image` is also
mandatory. All other attributes are optional.
#### SAST
The `location` of a SAST vulnerability must have a `file` and a `start_line` field,
......
......@@ -90,6 +90,7 @@ and complete an integration with the Secure stage.
- Documentation for [SAST reports](../../user/application_security/sast/index.md#reports-json-format).
- Documentation for [Dependency Scanning reports](../../user/application_security/dependency_scanning/index.md#reports-json-format).
- Documentation for [Container Scanning reports](../../user/application_security/container_scanning/index.md#reports-json-format).
- Documentation for [`cluster_image_scanning` reports](../../user/application_security/cluster_image_scanning/index.md#reports-json-format).
- See this [example secure job definition that also defines the artifact created](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Security/Container-Scanning.gitlab-ci.yml).
- If you need a new kind of scan or report, [create an issue](https://gitlab.com/gitlab-org/gitlab/-/issues/new#)
and add the label `devops::secure`.
......
---
type: reference, howto
stage: Protect
group: Container Security
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
# Cluster Image Scanning **(ULTIMATE)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 14.1.
WARNING:
This analyzer is in [Alpha](https://about.gitlab.com/handbook/product/gitlab-the-product/#alpha)
and is unstable. The JSON report and CI/CD configuration may be subject to change or breakage
across GitLab releases.
Your Kubernetes cluster may run workloads based on images that the Container Security analyzer
didn't scan. These images may therefore contain known vulnerabilities. By including an extra job in
your pipeline that scans for those security risks and displays them in the vulnerability report, you
can use GitLab to audit your Kubernetes workloads and environments.
GitLab provides integration with open-source tools for vulnerability analysis in Kubernetes clusters:
- [Starboard](https://github.com/aquasecurity/starboard)
To integrate GitLab with security scanners other than those listed here, see
[Security scanner integration](../../../development/integrations/secure.md).
You can enable cluster image scanning by [including the CI job](#configuration)
in your existing `.gitlab-ci.yml` file.
## Prerequisites
To enable cluster image scanning in your pipeline, you need the following:
- [GitLab Runner](https://docs.gitlab.com/runner/)
with the [`docker`](https://docs.gitlab.com/runner/executors/docker.html)
or [`kubernetes`](https://docs.gitlab.com/runner/install/kubernetes.html)
executor.
- Docker `18.09.03` or later installed on the same computer as the runner. If you're using the
shared runners on GitLab.com, then this is already the case.
- [Starboard Operator](https://aquasecurity.github.io/starboard/v0.10.3/operator/installation/kubectl/)
installed and configured in your cluster.
- The configuration for accessing your Kubernetes cluster stored in the `CIS_KUBECONFIG`
[configuration variable](#cicd-variables-for-cluster-image-scanning)
with the type set to `File` (see [Configuring the cluster](#configuring-the-cluster)).
## Configuring the cluster
1. Create a new service account.
To properly fetch vulnerabilities from the cluster and to limit analyzer access to the workload,
you must create a new service account with the cluster role limited to `get`, `list`, and `watch`
`vulnerabilityreports` in the Kubernetes cluster:
```shell
kubectl apply -f https://gitlab.com/gitlab-org/security-products/analyzers/cluster-image-scanning/-/raw/main/gitlab-vulnerability-viewer-service-account.yaml
```
1. Obtain the Kubernetes API URL.
Get the API URL by running this command:
```shell
API_URL=$(kubectl cluster-info | grep -E 'Kubernetes master|Kubernetes control plane' | awk '/http/ {print $NF}')
```
1. Obtain the CA certificate:
1. List the secrets with `kubectl get secrets`. One should have a name similar to
`default-token-xxxxx`. Copy that token name for use below.
1. Run this command to get the certificate:
```shell
CA_CERTIFICATE=$(kubectl get secret <secret name> -o jsonpath="{['data']['ca\.crt']}")
```
1. Obtain the service account token:
```shell
TOKEN=$(kubectl -n kube-system get secret $(kubectl -n kube-system get secret | grep gitlab-vulnerability-viewer | awk '{print $1}') -o jsonpath="{.data.token}" | base64 --decode)
```
1. Generate the value for the `CIS_KUBECONFIG` variable. Copy the printed value from the output:
```shell
echo "
---
apiVersion: v1
kind: Config
clusters:
- name: gitlab-vulnerabilities-viewer
cluster:
server: $API_URL
certificate-authority-data: $CA_CERTIFICATE
contexts:
- name: gitlab-vulnerabilities-viewer
context:
cluster: gitlab-vulnerabilities-viewer
namespace: default
user: gitlab-vulnerabilities-viewer
current-context: gitlab-vulnerabilities-viewer
users:
- name: gitlab-vulnerabilities-viewer
user:
token: $TOKEN
"
```
1. Set the CI/CD variable:
1. Navigate to your project's **Settings > CI/CD**.
1. Expand the **Variables** section.
1. Select **Add variable** and fill in the details:
- **Key**: `CIS_KUBECONFIG`.
- **Value**: `generated value`
- **Type**: `File`
WARNING:
The `CIS_KUBECONFIG` variable is accessible by all jobs executed for your project. Mark the
`Protect variable` flag to export this variable to pipelines running on protected branches and tags
only. You can apply additional protection to your cluster by
[restricting service account access to a single namespace](https://kubernetes.io/docs/reference/access-authn-authz/rbac/),
and [configuring Starboard Operator](https://aquasecurity.github.io/starboard/v0.10.3/operator/configuration/#install-modes)
to install in restricted mode.
## Configuration
To include the `Cluster-Image-Scanning.gitlab-ci.yml` template (GitLab 14.1 and later), add the
following to your `.gitlab-ci.yml` file:
```yaml
include:
- template: Security/Cluster-Image-Scanning.gitlab-ci.yml
```
The included template:
- Creates a `cluster_image_scanning` job in your CI/CD pipeline.
- Connects to your Kubernetes cluster with credentials provided in the `CIS_KUBECONFIG` variable and
fetches vulnerabilities found by [Starboard Operator](https://aquasecurity.github.io/starboard/v0.10.3/operator/).
GitLab saves the results as a
[Cluster Image Scanning report artifact](../../../ci/yaml/index.md#artifactsreportscluster_image_scanning)
that you can download and analyze later. When downloading, you always receive the most recent
artifact.
### Customize the cluster image scanning settings
You can customize how GitLab scans your cluster. For example, to restrict the analyzer to get
results for only a certain workload, use the [`variables`](../../../ci/yaml/index.md#variables)
parameter in your `.gitlab-ci.yml` to set [CI/CD variables](#cicd-variables-for-cluster-image-scanning).
The variables you set in your `.gitlab-ci.yml` overwrite those in
`Cluster-Image-Scanning.gitlab-ci.yml`.
#### CI/CD variables for cluster image scanning
You can [configure](#customize-the-cluster-image-scanning-settings) analyzers by using the following CI/CD variables:
| CI/CD Variable | Default | Description |
| ------------------------------ | ------------- | ----------- |
| `CIS_KUBECONFIG` | `""` | File used to configure access to the Kubernetes cluster. See the [Kubernetes documentation](https://kubernetes.io/docs/tasks/access-application-cluster/configure-access-multiple-clusters/) for more details. |
| `CIS_CONTAINER_NAME` | `""` | Name of the container used in the Kubernetes resource you want to filter vulnerabilities for. For example, `alpine`. |
| `CIS_RESOURCE_NAME` | `""` | Name of the Kubernetes resource you want to filter vulnerabilities for. For example, `nginx`. |
| `CIS_RESOURCE_NAMESPACE` | `""` | Namespace of the Kubernetes resource you want to filter vulnerabilities for. For example, `production`. |
| `CIS_RESOURCE_KIND` | `""` | Kind of the Kubernetes resource you want to filter vulnerabilities for. For example, `deployment`. |
### Override the cluster image scanning template
If you want to override the job definition (for example, to change properties like `variables`), you
must declare and override a job after the template inclusion, and then
specify any additional keys.
This example sets `CIS_RESOURCE_NAME` to `nginx`:
```yaml
include:
- template: Security/Cluster-Image-Scanning.gitlab-ci.yml
cluster_image_scanning:
variables:
CIS_RESOURCE_NAME: nginx
```
### Connect with Kubernetes cluster associated to the project
If you want to connect to the Kubernetes cluster associated with the project and run Cluster Image Scanning jobs without
configuring the `CIS_KUBECONFIG` variable, you must extend `cluster_image_scanning` and specify the environment you want to scan.
This example configures the `cluster_image_scanning` job to scan the Kubernetes cluster connected with the `staging` environment:
```yaml
cluster_image_scanning:
environment:
name: staging
action: prepare
```
## Reports JSON format
The cluster image scanning tool emits a JSON report file. For more information, see the
[schema for this report](https://gitlab.com/gitlab-org/security-products/security-report-schemas/-/blob/master/dist/container-scanning-report-format.json).
Here's an example cluster image scanning report:
```json-doc
{{
"version": "14.0.2",
"scan": {
"scanner": {
"id": "starboard_trivy",
"name": "Trivy (using Starboard Operator)",
"url": "https://github.com/aquasecurity/starboard",
"vendor": {
"name": "GitLab"
},
"version": "0.16.0"
},
"start_time": "2021-04-28T12:47:00Z",
"end_time": "2021-04-28T12:47:00Z",
"type": "cluster_image_scanning",
"status": "success"
},
"vulnerabilities": [
{
"id": "c15f22205ee842184c2d55f1a207b3708283353f85083d66c34379c709b0ac9d",
"category": "cluster_image_scanning",
"message": "CVE-2011-3374 in apt",
"description": "",
"cve": "library/nginx:1.18:apt:CVE-2011-3374",
"severity": "Low",
"confidence": "Unknown",
"solution": "Upgrade apt from 1.8.2.2",
"scanner": {
"id": "starboard_trivy",
"name": "Trivy (using Starboard Operator)"
},
"location": {
"dependency": {
"package": {
"name": "apt"
},
"version": "1.8.2.2"
},
"operating_system": "library/nginx:1.18",
"image": "index.docker.io/library/nginx:1.18"
},
"identifiers": [
{
"type": "cve",
"name": "CVE-2011-3374",
"value": "CVE-2011-3374",
"url": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2011-3374"
}
],
"links": [
"https://avd.aquasec.com/nvd/cve-2011-3374"
]
}
]
}
```
## Security Dashboard
The [Security Dashboard](../security_dashboard/index.md) shows you an overview of all
the security vulnerabilities in your groups, projects, and pipelines.
## Interacting with the vulnerabilities
After a vulnerability is found, you can [address it](../vulnerabilities/index.md).
## Troubleshooting
### Getting warning message `gl-cluster-image-scanning-report.json: no matching files`
For information on this error, see the [general Application Security troubleshooting section](../../../ci/pipelines/job_artifacts.md#error-message-no-files-to-upload).
......@@ -189,11 +189,6 @@ container_scanning:
GIT_STRATEGY: fetch
```
WARNING:
GitLab 13.0 and later doesn't support [`only` and `except`](../../../ci/yaml/index.md#only--except).
When overriding the template, you must use [`rules`](../../../ci/yaml/index.md#rules)
instead.
### Change scanners
The container-scanning analyzer can use different scanners, depending on the value of the
......
......@@ -43,6 +43,7 @@ GitLab uses the following tools to scan and report known vulnerabilities found i
| [Security Dashboard](security_dashboard/index.md) **(ULTIMATE)** | View vulnerabilities in all your projects and groups. |
| [Static Application Security Testing (SAST)](sast/index.md) | Analyze source code for known vulnerabilities. |
| [Coverage fuzzing](coverage_fuzzing/index.md) **(ULTIMATE)** | Find unknown bugs and vulnerabilities with coverage-guided fuzzing. |
| [Cluster Image Scanning](cluster_image_scanning/index.md) **(ULTIMATE)** | Scan Kubernetes clusters for known vulnerabilities. |
## Security scanning with Auto DevOps
......
......@@ -33,6 +33,7 @@ The security dashboard and vulnerability report displays information about vulne
- [Dynamic Application Security Testing](../dast/index.md)
- [Dependency Scanning](../dependency_scanning/index.md)
- [Static Application Security Testing](../sast/index.md)
- [Cluster Image Scanning](../cluster_image_scanning/index.md)
- And [others](../index.md#security-scanning-tools)!
## Prerequisites
......
......@@ -118,6 +118,7 @@ The type of scan. This must be one of the following:
- `dependency_scanning`
- `dast`
- `sast`
- `cluster_image_scanning`
### Scanner
......
......@@ -8,6 +8,7 @@ RSpec.describe Gitlab::Template::GitlabCiYmlTemplate do
it 'finds the Security Products templates' do
expect(templates).to include('Container-Scanning')
expect(templates).to include('Cluster-Image-Scanning')
expect(templates).to include('DAST')
expect(templates).to include('Dependency-Scanning')
expect(templates).to include('License-Scanning')
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe 'Cluster-Image-Scanning.gitlab-ci.yml' do
subject(:template) { Gitlab::Template::GitlabCiYmlTemplate.find('Cluster-Image-Scanning') }
describe 'the created pipeline' do
let_it_be(:project) { create(:project, :custom_repo, files: { 'README.txt' => '' }) }
let(:default_branch) { 'master' }
let(:user) { project.owner }
let(:service) { Ci::CreatePipelineService.new(project, user, ref: 'master' ) }
let(:pipeline) { service.execute!(:push) }
let(:build_names) { pipeline.builds.pluck(:name) }
before do
stub_ci_pipeline_yaml_file(template.content)
allow_next_instance_of(Ci::BuildScheduleWorker) do |worker|
allow(worker).to receive(:perform).and_return(true)
end
allow(project).to receive(:default_branch).and_return(default_branch)
create(:ci_variable, project: project, key: 'CIS_KUBECONFIG', value: '*')
end
context 'when project has no license' do
it 'includes no jobs' do
expect { pipeline }.to raise_error(Ci::CreatePipelineService::CreateError)
end
end
context 'when project has Ultimate license' do
let(:license) { build(:license, plan: License::ULTIMATE_PLAN) }
before do
allow(License).to receive(:current).and_return(license)
end
context 'by default' do
it 'includes job' do
expect(build_names).to match_array(%w[cluster_image_scanning])
end
end
context 'with CIS_MAJOR_VERSION greater than 3' do
before do
create(:ci_variable, project: project, key: 'CIS_MAJOR_VERSION', value: '4')
end
it 'includes job' do
expect(build_names).to match_array(%w[cluster_image_scanning])
end
end
context 'when CLUSTER_IMAGE_SCANNING_DISABLED=1' do
before do
create(:ci_variable, project: project, key: 'CLUSTER_IMAGE_SCANNING_DISABLED', value: '1')
end
it 'includes no jobs' do
expect { pipeline }.to raise_error(Ci::CreatePipelineService::CreateError)
end
end
end
end
end
# Use this template to enable cluster image scanning in your project.
# You should add this template to an existing `.gitlab-ci.yml` file by using the `include:`
# keyword.
# The template should work without modifications but you can customize the template settings if
# needed: https://docs.gitlab.com/ee/user/application_security/cluster_image_scanning/#customize-the-container-scanning-settings
#
# Requirements:
# - A `test` stage to be present in the pipeline.
# - You must define the `CIS_KUBECONFIG` variable to allow analyzer to connect to your Kubernetes cluster and fetch found vulnerabilities.
#
# Configure container scanning with CI/CD variables (https://docs.gitlab.com/ee/ci/variables/README.html).
# List of available variables: https://docs.gitlab.com/ee/user/application_security/cluster_image_scanning/#available-variables
variables:
CIS_ANALYZER_IMAGE: registry.gitlab.com/gitlab-org/security-products/analyzers/cluster-image-scanning:0
cluster_image_scanning:
image: "$CIS_ANALYZER_IMAGE"
stage: test
allow_failure: true
artifacts:
reports:
cluster_image_scanning: gl-cluster-image-scanning-report.json
paths: [gl-cluster-image-scanning-report.json]
dependencies: []
script:
- /analyzer run
rules:
- if: $CLUSTER_IMAGE_SCANNING_DISABLED
when: never
- if: '($KUBECONFIG == null || $KUBECONFIG == "") && ($CIS_KUBECONFIG == null || $CIS_KUBECONFIG == "")'
when: never
- if: $CI_COMMIT_BRANCH &&
$GITLAB_FEATURES =~ /\bcluster_image_scanning\b/
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment