Sysdig SecureによるGitLab CI/CDパイプラインでのイメージスキャン


今回は下記Sysdigブログのガイドに沿って、Sysdig Secureを使ったGitLab CI/CDパイプライン上でのイメージスキャンを実行してみました。詳細は下記ブログをご参照ください。
https://sysdig.jp/blog/gitlab-ci-cd-image-scanning/

# GitLabにSysdig Secure API Tokenをマスク変数として登録する
1. GitLabのUIにログインします。
2. <b>Settings > CI/CD > Variables</b>に移動します。
3. __SYSDIG_SECURE_TOKEN__ をマスク変数として登録します。値にはSysdig Secure API Tokenの値を入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2802821/69085422-4cd8-61f0-1d86-50ff43841817.png)



# Dockerfileをリポジトリに配置する
今回は単純なAlpineイメージを使用しています。
```:Dockerfile
FROM alpine
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2802821/ded3181d-9f6d-12a2-6a68-e1c309c1ba38.png)

# GitLab runnerを自身のDockerインストール済みのLinuxインスタンスにインストールする
今回は共有runnerではなく自分自身のrunnerを使用したいので、このプロジェクト用のGitLab runnerを準備します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2802821/0c8b3e49-5c59-5ad9-8437-6c24b37f593d.png)

https://docs.gitlab.com/runner/install/linux-repository.html#installing-gitlab-runner

1. 自身のDockerインストール済みのLinuxインスタンスにログインします。
1. 下記コマンドでGitLab runnerをインストールします。

```
curl -L "https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh" | sudo bash
```
```
sudo apt-get install gitlab-runner
```
# GitLab runnerを登録する
```
sudo gitlab-runner register
```
下記で入力する`registration token` はGitLabの<b>Settings > CI/CD > Project runners</b>で確認できます。
```
ubuntu@ip-172-31-33-239:~$

Enter the GitLab instance URL (for example, https://gitlab.com/):
https://gitlab.com/

Enter the registration token:
<registration token>

Enter a description for the runner:
testprj

Enter tags for the runner (comma-separated):

Enter optional maintenance note for the runner:

Enter an executor: virtualbox, docker-ssh+machine, instance, kubernetes, docker-ssh, shell, parallels, ssh, docker+machine, custom, docker:
docker

Enter the default Docker image (for example, ruby:2.7):
ruby:2.7
Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!

Configuration (with the authentication token) was saved in "/etc/gitlab-runner/config.toml"
```

# パイプラインを編集する
1. GitLabのUIで、<b>CI/CD > Editor</b>に移動します。
2. 下記パイプラインを記述します。内容としては、イメージのビルド・スキャン・プッシュの３段階のステージがあり、スキャンステージでsysdig-cli-scannerを使ってイメージスキャンを実行します。スキャン結果がPASSED（合格）だった場合だけ、イメージをリポジトリにプッシュします。

:::note
**SYSDIG_SECURE_ENDPOINT**の値は利用しているSysdig SaaSリージョンにより異なります。下記ドキュメントをご参照ください。
https://docs.sysdig.com/en/docs/administration/saas-regions-and-ip-ranges/
:::

```:.gitlab-ci.yml
# This file is a template, and might need editing before it works on your project.
# This is a sample GitLab CI/CD configuration file that should run without any modifications.
# It demonstrates a basic 3 stage CI/CD pipeline. Instead of real tests or scripts,
# it uses echo commands to simulate the pipeline execution.
#
# A pipeline is composed of independent jobs that run scripts, grouped into stages.
# Stages run in sequential order, but jobs within stages run in parallel.
#
# For more information, see: https://docs.gitlab.com/ee/ci/yaml/index.html#stages
#
# You can copy and paste this template into a new `.gitlab-ci.yml` file.
# You should not add this template to an existing `.gitlab-ci.yml` file by using the `include:` keyword.
#
# To contribute improvements to CI/CD templates, please follow the Development guide at:
# https://docs.gitlab.com/ee/development/cicd/templates.html
# This specific template is located at:
# https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Getting-Started.gitlab-ci.yml


variables:
 SYSDIG_SECURE_ENDPOINT: "https://app.us4.sysdig.com"
 CI_IMAGE_TAG: "my-tag"
 stages:          # List of stages for jobs, and their order of execution
 - build
 - scan
 - push


image:build:
 stage: build
 image:
   name: gcr.io/kaniko-project/executor:debug
   entrypoint: [""]
 script:
   - /kaniko/executor --dockerfile Dockerfile --destination $CI_REGISTRY_IMAGE:$CI_IMAGE_TAG --no-push --oci-layout-path $(pwd)/build/ --tarPath $(pwd)/build/$CI_IMAGE_TAG.tar
 artifacts:
   paths:
     - build/
   expire_in: 1 days


image:scan:
 stage: scan
 before_script:
   - export SECURE_API_TOKEN=$SYSDIG_SECURE_TOKEN
 script:
   - curl -LO https://download.sysdig.com/scanning/bin/sysdig-cli-scanner/$(curl -L -s https://download.sysdig.com/scanning/sysdig-cli-scanner/latest_version.txt)/linux/amd64/sysdig-cli-scanner
   - chmod +x ./sysdig-cli-scanner
   - ./sysdig-cli-scanner --console-log  --apiurl $SYSDIG_SECURE_ENDPOINT file://$(pwd)/build/$CI_IMAGE_TAG.tar
 artifacts:
   paths:
     - build/
   expire_in: 1 days
   when: always
 needs:
   - image:build


image:push:
 stage: push
 image:
   name: gcr.io/go-containerregistry/crane:debug
   entrypoint: [""]
 script:
   - crane auth login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
   - crane push build/$CI_IMAGE_TAG.tar $CI_REGISTRY_IMAGE:$CI_IMAGE_TAG
 needs:
   - image:scan
```

# コミットしてパイプラインを実行する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2802821/ded6c279-07d3-3870-4c66-8c2f2efd2369.png)

```:Log
Running with gitlab-runner 15.9.1 (d540b510)
 on testprj tkWiZT3Z, system ID: s_293d4a2b5dbb
Preparing the "docker" executor
00:13
Using Docker executor with image ruby:2.7 ...
Pulling docker image ruby:2.7 ...
Using docker image sha256:1f734a36075fd0f4625e5d416a9174f99ad3855b579ffe0f3e8f5ac9a4b1751c for ruby:2.7 with digest ruby@sha256:aaff8189c708ce0b2862994b422641e63a85771ce046cc592002f20dd67b0fce ...
Preparing environment
00:06
Running on runner-tkwizt3z-project-40344221-concurrent-0 via ip-172-31-33-239...
Getting source from Git repository
00:03
Fetching changes with git depth set to 20...
Reinitialized existing Git repository in /builds/yotakegrp/testprj/.git/
Checking out 00206fe5 as detached HEAD (ref is main)...
Removing build/
Skipping Git submodules setup
Downloading artifacts
00:03
Downloading artifacts for image:build (3916954739)...
Downloading artifacts from coordinator... ok        host=cdn.artifacts.gitlab-static.net id=3916954739 responseStatus=200 OK token=64_uDnjz
Executing "step_script" stage of the job script
00:05
Using docker image sha256:1f734a36075fd0f4625e5d416a9174f99ad3855b579ffe0f3e8f5ac9a4b1751c for ruby:2.7 with digest ruby@sha256:aaff8189c708ce0b2862994b422641e63a85771ce046cc592002f20dd67b0fce ...
$ export SECURE_API_TOKEN=$SYSDIG_SECURE_TOKEN
$ curl -LO https://download.sysdig.com/scanning/bin/sysdig-cli-scanner/$(curl -L -s https://download.sysdig.com/scanning/sysdig-cli-scanner/latest_version.txt)/linux/amd64/sysdig-cli-scanner
 % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                Dload  Upload   Total   Spent    Left  Speed
100 30.6M  100 30.6M    0     0  39.5M      0 --:--:-- --:--:-- --:--:-- 39.5M
$ chmod +x ./sysdig-cli-scanner
$ ./sysdig-cli-scanner --console-log  --apiurl $SYSDIG_SECURE_ENDPOINT file://$(pwd)/build/$CI_IMAGE_TAG.tar
2023-03-12T01:17:15Z Starting analysis with Sysdig scanner version 1.3.4
2023-03-12T01:17:15Z INF Starting analysis with Sysdig scanner commit=1c575fe version=1.3.4
2023-03-12T01:17:15Z INF Using path for the cache: /root/.cache/inlineScannerCache.db
2023-03-12T01:17:15Z INF Retrieving MainDB
2023-03-12T01:17:15Z Retrieving MainDB...
2023-03-12T01:17:15Z WRN error, overwrite current MainDB error="stat /builds/yotakegrp/testprj/main.db.meta.json: no such file or directory"
2023-03-12T01:17:15Z INF Downloading a new MainDB to /builds/yotakegrp/testprj/main.db/sysdig-db-data
2023-03-12T01:17:17Z INF DB correctly downloaded dbTimestamp=2023-03-11T17:23:52Z dbVersion=V1
2023-03-12T01:17:17Z INF Got updated DB file on path /builds/yotakegrp/testprj/main.db/sysdig-db-data: 146347046 bytes downloaded
2023-03-12T01:17:17Z INF Loading MainDB from: /builds/yotakegrp/testprj/main.db/sysdig-db-data
2023-03-12T01:17:17Z Done 146.3 MB
2023-03-12T01:17:17Z Loading MainDB...
2023-03-12T01:17:17Z Done
2023-03-12T01:17:17Z INF Done: MainDB loaded
2023-03-12T01:17:18Z INF GET pkgMeta indexedAt on index changed from 0001-01-01 00:00:00 +0000 UTC to 2023-03-02 17:08:52.46 +0000 UTC on GetPkgMetaIndexedAt
2023-03-12T01:17:18Z INF Retrieving image imgName=file:///builds/yotakegrp/testprj/build/my-tag.tar
2023-03-12T01:17:18Z Retrieving image...
2023-03-12T01:17:18Z WRN failed to create containers-storage loader, will continue without this image loader error="error creating default store object: mount /var/lib/containers/storage/aufs:/var/lib/containers/storage/aufs, flags: 0x1000: operation not permitted"
2023-03-12T01:17:18Z Done
2023-03-12T01:17:18Z Scan started...
2023-03-12T01:17:18Z INF Done: image retrieved imgName=file:///builds/yotakegrp/testprj/build/my-tag.tar
2023-03-12T01:17:18Z INF Start analyzing image
2023-03-12T01:17:18Z INF Start matching vulnerabilities
2023-03-12T01:17:18Z INF Matched 15 OS packages and 0 nonOS packages
2023-03-12T01:17:18Z INF Start policies evaluation
2023-03-12T01:17:18Z INF End policies evaluation result=passed
2023-03-12T01:17:18Z INF Start risks acceptance evaluation
2023-03-12T01:17:18Z INF evaluation of accepted risks completed
2023-03-12T01:17:18Z Uploading result to backend...
2023-03-12T01:17:18Z INF Scan Result uploaded scan-result-id=174b871b98053b79a3fad0fae1269a20 scan-result-url=https://app.us4.sysdig.com/secure/#/scanning/assets/results/174b871b98053b79a3fad0fae1269a20/overview
2023-03-12T01:17:18Z INF Done duration=2.819386617s
2023-03-12T01:17:18Z Done
2023-03-12T01:17:18Z Total execution time 2.819400432s
Type: dockerImage
ImageID: sha256:7ff52767cf0ee4bd0b2ddf81df033cc0c1b837f1434aa7af3928250aa7a7fbe3
Digest:
BaseOS: alpine 3.17.2
PullString: /builds/yotakegrp/testprj/build/my-tag.tar
0 vulnerabilities found
                           POLICIES EVALUATION
   Policy: Sysdig Best Practices PASSED (0 failures - 0 risks accepted)
Policies evaluation PASSED at 2023-03-12T01:17:18Z
Full image results here: https://app.us4.sysdig.com/secure/#/scanning/assets/results/174b871b98053b79a3fad0fae1269a20/overview (id 174b871b98053b79a3fad0fae1269a20)
Execution logs written to: /builds/yotakegrp/testprj/scan-logs
Uploading artifacts for successful job
00:03
Uploading artifacts...
build/: found 9 matching artifact files and directories
Uploading artifacts as "archive" to coordinator... 201 Created  id=3916954740 responseStatus=201 Created token=64_uDnjz
Cleaning up project directory and file based variables
00:01
Job succeeded
```

# イメージがプッシュされたことを確認する
1. 上記のログのスキャン結果が __PASSED__ になっているので、実際にイメージがリポジトリにプッシュされていることを確認します。
1.  <b>Packages and registries > Container Registry</b>に移動します。
1. イメージがプッシュされていることを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2802821/8d99cb69-c116-41d9-e3e7-b113a267048a.png)

# Sysdig UIでイメージスキャン結果を確認する
1. Sysdig UIにログインします。
1. <b>Vulnerabilities > Pipeline</b>に移動します。
1. イメージのスキャン結果が一覧に表示されていることを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2802821/7669b9d1-6084-7be9-df35-93eb40a09bb9.png)

# まとめ
Sysdig Secureを使って、GitLab CI/CDパイプライン上でのイメージスキャンを簡単に実行できることが確認できました。