先日、Sysdig SecureのレジストリスキャンがGAになったので、さっそく試しみてみました。今回はJFrog Artifactory SaaS/Cloudに対するレジストリスキャンの手順をご紹介します。
JFrog Artifactoryのネーミングは業界の標準とは異なり、「レジストリ」の代わりに「リポジトリ」、「リポジトリ」の代わりに「パッケージ」と命名されています。
参照ドキュメント
前提条件
レジストリスキャンを実施するregistry-scannerはKubernetes上でコンテナとして動作します。そのため、Kubernetes環境が必要 です。
JFrog Artifactory環境の準備
JFrog Artifactoryにログインし、nginxイメージをプッシュします。
ubuntu@ip-172-31-33-129:~$ docker login -u <USER_NAME> bobo3977.jfrog.io
Password:
WARNING! Your password will be stored unencrypted in /home/ubuntu/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
ubuntu@ip-172-31-33-129:~$ docker pull nginx
ubuntu@ip-172-31-33-129:~$ docker tag nginx bobo3977.jfrog.io/docker/hello-world:1.1.0
ubuntu@ip-172-31-33-129:~$ docker push bobo3977.jfrog.io/docker/hello-world:1.1.0
Helmによるregistry-scannerのインストール
以下のコマンドでregistry-scannerをKubernetes環境にインストールします。
SYSDIG_SECURE_URLの値はご利用のSysdig SaaSリージョンにより異なります。下記ドキュメントをご参照ください。
https://docs.sysdig.com/en/docs/administration/saas-regions-and-ip-ranges/
helm repo add sysdig https://charts.sysdig.com
helm repo update
helm upgrade --install registry-scanner sysdig/registry-scanner --version=1 \
--set config.secureBaseURL=<SYSDIG_SECURE_URL> \
--set config.secureAPIToken=<SYSDIG_SECURE_API_TOKEN> \
--set config.registryType=artifactory \
--set config.registryURL=<JFROG_ARTIFACTORY_REGISTRY_URL> \
--set config.registryApiUrl=<JFROG_ARTIFACTORY_REGISTRY_API_DOCKER_URL> \
--set config.registryUser=<JFROG_ARTIFACTORY_USER> \
--set config.registryPassword=<JFROG_ARTIFACTORY_PASSWORD>
私の環境だと以下になります。
helm upgrade --install registry-scanner sysdig/registry-scanner --version=1 \
--set config.secureBaseURL=https://app.us4.sysdig.com \
--set config.secureAPIToken=XXXXXXXXXXXXXX \
--set config.registryType=artifactory \
--set config.registryURL=bobo3977.jfrog.io/docker \
--set config.registryApiUrl=bobo3977.jfrog.io/artifactory/api/docker/docker \
--set config.registryUser=XXXXXXXX@gmail.com \
--set config.registryPassword=XXXXXXXXXXXXXX
Release "registry-scanner" does not exist. Installing it now.
NAME: registry-scanner
LAST DEPLOYED: Tue Feb 14 14:07:18 2023
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
A cronjob 'registry-scanner' has been created. The cronjob will execute the registry scan on the following schedule:
Schedule: "0 6 * * 6"
For troubleshooting, check the status of the jobs and logs of the 'registry-scanner' pods that are created on every execution.
下記コマンドで、Cronjobとして登録されていることを確認します。
kubectl get cronjob
デフォルトでは毎週土曜日の午前6時にスキャンが実行される設定で登録されています。
NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE
registry-scanner 0 6 * * 6 False 0 <none> 88s
手動によるレジストリスキャン
レジストリスキャンを手動で実行する場合は、下記コマンドを実行します。
kubectl create job --from=cronjob/registry-scanner registry-scanner-manual-test
起動したregistry-scannerのPodを確認します。
kubectl get pod
NAME READY STATUS RESTARTS AGE
registry-scanner-manual-test-rb87p 0/1 Completed 0 41s
registry-scanner-worker-dd42x-1-mk8gj 0/1 Completed 0 33s
Podのログを確認します。
kubectl logs registry-scanner-manual-test-s2xhz
ubuntu@ip-172-31-33-129:~$ k logs registry-scanner-manual-test-rb87p
Reading config from: /config.yaml
["2023-02-14T14:25:39.143" MSG] Registry type: artifactory
["2023-02-14T14:25:39.144" MSG] Creating new vulnerability-management scanner
["2023-02-14T14:25:39.490" MSG] WARN: maxTagsPerRepository: 0 is higher than maximum allowed retention. Setting to 5
["2023-02-14T14:25:39.490" MSG] Using filter:
Include: []
Exclude: []
Max age days: 0
Max tags per repository: 5
["2023-02-14T14:25:39.490" MSG] Getting repositories...
["2023-02-14T14:25:39.686" MSG] Getting tags concurrently from repository (2/2) library/hello-world...
["2023-02-14T14:25:39.686" MSG] Getting tags concurrently from repository (1/2) hello-world...
["2023-02-14T14:25:39.830" MSG] Retrieving image information (4/4): hello-world:1.1.0...
["2023-02-14T14:25:39.830" MSG] Retrieving image information (2/4): library/hello-world:sha256__f54a58bc1aac5ea1a25d796ae155dc228b3f0e11d046ae276b39c4bf2f13d8c4...
["2023-02-14T14:25:39.830" MSG] Retrieving image information (3/4): hello-world:1.0.0...
["2023-02-14T14:25:39.830" MSG] Retrieving image information (1/4): library/hello-world:latest...
["2023-02-14T14:25:39.896" ERROR] {bobo3977.jfrog.io/docker library/hello-world latest} - Get image config error
Unexpected response code from RetrieveArtifact endpoint: 404
{
"errors" : [ {
"status" : 404,
"message" : "Could not find resource"
} ]
}
["2023-02-14T14:25:39.902" MSG] Image ID: sha256:feb5d9fea6a5e9606aa995e879d862b825965ba48de054caab5ef356dc6b3412 created 2021-09-23 23:47:57.442225064 +0000 UTC
["2023-02-14T14:25:39.929" MSG] Image ID: sha256:3f8a00f137a0d2c8a2163a09901e28e2471999fde4efc2f9570b91f1c30acf94 created 2023-02-09 04:36:22.393029904 +0000 UTC
["2023-02-14T14:25:39.942" MSG] Image ID: sha256:feb5d9fea6a5e9606aa995e879d862b825965ba48de054caab5ef356dc6b3412 created 2021-09-23 23:47:57.442225064 +0000 UTC
["2023-02-14T14:25:39.942" MSG] Creating registry report. Num. of workers: 1
["2023-02-14T14:25:39.942" MSG] Starting round 1. Pending images: 3
["2023-02-14T14:25:39.942" MSG] 0.00% completed. Completed images: 0/4 . Elapsed: 16.552µs ETA: ?
["2023-02-14T14:25:39.942" MSG] Round 1: Processed 0/3 images (0 errors)
["2023-02-14T14:25:39.943" MSG] Processing image bobo3977.jfrog.io/docker/hello-world:1.1.0. Retries: 0
["2023-02-14T14:25:39.943" MSG] bobo3977.jfrog.io/docker/hello-world:1.1.0 - Checking status...
["2023-02-14T14:25:39.943" MSG] bobo3977.jfrog.io/docker/hello-world:1.1.0 - Scanning...
{"level":"info","component":"image-scanner","time":"2023-02-14T14:25:39Z","message":"Getting image bobo3977.jfrog.io/docker/hello-world:1.1.0"}
{"level":"info","component":"vuln-db-downloader","time":"2023-02-14T14:25:44Z","message":"downloading vulnerability database"}
{"level":"info","component":"image-scanner","time":"2023-02-14T14:25:45Z","message":"Matching vulnerabilities"}
{"level":"info","component":"image-scanner","time":"2023-02-14T14:25:45Z","message":"image bobo3977.jfrog.io/docker/hello-world:1.1.0 scanned in 5.99078168s"}
["2023-02-14T14:25:46.398" MSG] bobo3977.jfrog.io/docker/hello-world:1.1.0 - Scan completed: noPolicy
["2023-02-14T14:25:46.398" MSG] 25.00% completed. Completed images: 1/4 . Elapsed: 6.455118293s ETA: 19.365s
["2023-02-14T14:25:46.398" MSG] Round 1: Processed 1/3 images (0 errors)
["2023-02-14T14:25:46.398" MSG] Processing image bobo3977.jfrog.io/docker/hello-world:1.0.0. Retries: 0
{"level":"info","component":"image-scanner","time":"2023-02-14T14:25:46Z","message":"Getting image bobo3977.jfrog.io/docker/hello-world:1.0.0"}
["2023-02-14T14:25:46.398" MSG] bobo3977.jfrog.io/docker/hello-world:1.0.0 - Checking status...
["2023-02-14T14:25:46.398" MSG] bobo3977.jfrog.io/docker/hello-world:1.0.0 - Scanning...
{"level":"info","component":"image-scanner","time":"2023-02-14T14:25:46Z","message":"Matching vulnerabilities"}
{"level":"info","component":"image-scanner","time":"2023-02-14T14:25:46Z","message":"image bobo3977.jfrog.io/docker/hello-world:1.0.0 scanned in 85.884142ms"}
["2023-02-14T14:25:46.587" MSG] bobo3977.jfrog.io/docker/hello-world:1.0.0 - Scan completed: noPolicy
["2023-02-14T14:25:46.587" MSG] 50.00% completed. Completed images: 2/4 . Elapsed: 6.644958633s ETA: 6.644s
["2023-02-14T14:25:46.587" MSG] Round 1: Processed 2/3 images (0 errors)
["2023-02-14T14:25:46.587" MSG] Processing image bobo3977.jfrog.io/docker/library/hello-world:sha256__f54a58bc1aac5ea1a25d796ae155dc228b3f0e11d046ae276b39c4bf2f13d8c4. Retries: 0
["2023-02-14T14:25:46.587" MSG] bobo3977.jfrog.io/docker/library/hello-world:sha256__f54a58bc1aac5ea1a25d796ae155dc228b3f0e11d046ae276b39c4bf2f13d8c4 - Checking status...
["2023-02-14T14:25:46.587" MSG] bobo3977.jfrog.io/docker/library/hello-world:sha256__f54a58bc1aac5ea1a25d796ae155dc228b3f0e11d046ae276b39c4bf2f13d8c4 - Scanning...
{"level":"info","component":"image-scanner","time":"2023-02-14T14:25:46Z","message":"Getting image bobo3977.jfrog.io/docker/library/hello-world:sha256__f54a58bc1aac5ea1a25d796ae155dc228b3f0e11d046ae276b39c4bf2f13d8c4"}
{"level":"info","component":"image-scanner","time":"2023-02-14T14:25:46Z","message":"Matching vulnerabilities"}
{"level":"info","component":"image-scanner","time":"2023-02-14T14:25:46Z","message":"image bobo3977.jfrog.io/docker/library/hello-world:sha256__f54a58bc1aac5ea1a25d796ae155dc228b3f0e11d046ae276b39c4bf2f13d8c4 scanned in 90.751024ms"}
["2023-02-14T14:25:46.780" MSG] bobo3977.jfrog.io/docker/library/hello-world:sha256__f54a58bc1aac5ea1a25d796ae155dc228b3f0e11d046ae276b39c4bf2f13d8c4 - Scan completed: noPolicy
["2023-02-14T14:25:46.780" MSG] 75.00% completed. Completed images: 3/4 . Elapsed: 6.837135235s ETA: 2.279s
["2023-02-14T14:25:46.780" MSG] Round 1: Processed 3/3 images (0 errors)
["2023-02-14T14:25:46.780" MSG] Finished round 1. Processed: 3. Failed: 0.
["2023-02-14T14:25:46.780" MSG] Scan report:
{
"Status": "finished",
"Error": "",
"Registry": "bobo3977.jfrog.io/docker",
"Started": "2023-02-14T14:25:39.490916221Z",
"LastUpdate": "2023-02-14T14:25:46.780105099Z",
"Finished": "2023-02-14T14:25:46.780105099Z",
"Images": {
"bobo3977.jfrog.io/docker/hello-world:1.0.0": {
"Registry": "bobo3977.jfrog.io/docker",
"Repository": "hello-world",
"Tag": "1.0.0",
"ImageID": "sha256:feb5d9fea6a5e9606aa995e879d862b825965ba48de054caab5ef356dc6b3412",
"Created": "2021-09-23T23:47:57.442225064Z",
"TagNumberInRepo": 1,
"FullTag": "bobo3977.jfrog.io/docker/hello-world:1.0.0",
"ScanStatus": "noPolicy",
"Policies": null,
"ReportURL": "https://app.us4.sysdig.com/secure/#/scanning/scan-results/bobo3977.jfrog.io%2Fdocker%2Fhello-world%3A1.0.0/id/feb5d9fea6a5e9606aa995e879d862b825965ba48de054caab5ef356dc6b3412/summaries",
"LastErrorMessage": "",
"NumberOfRetries": 0,
"StatusChecked": null,
"StatusRetrieved": null,
"ScanStarted": "2023-02-14T14:25:46.398076157Z",
"ScanFinished": "2023-02-14T14:25:46.587879649Z"
},
"bobo3977.jfrog.io/docker/hello-world:1.1.0": {
"Registry": "bobo3977.jfrog.io/docker",
"Repository": "hello-world",
"Tag": "1.1.0",
"ImageID": "sha256:3f8a00f137a0d2c8a2163a09901e28e2471999fde4efc2f9570b91f1c30acf94",
"Created": "2023-02-09T04:36:22.393029904Z",
"TagNumberInRepo": 0,
"FullTag": "bobo3977.jfrog.io/docker/hello-world:1.1.0",
"ScanStatus": "noPolicy",
"Policies": null,
"ReportURL": "https://app.us4.sysdig.com/secure/#/scanning/scan-results/bobo3977.jfrog.io%2Fdocker%2Fhello-world%3A1.1.0/id/3f8a00f137a0d2c8a2163a09901e28e2471999fde4efc2f9570b91f1c30acf94/summaries",
"LastErrorMessage": "",
"NumberOfRetries": 0,
"StatusChecked": null,
"StatusRetrieved": null,
"ScanStarted": "2023-02-14T14:25:39.943023777Z",
"ScanFinished": "2023-02-14T14:25:46.398036775Z"
},
"bobo3977.jfrog.io/docker/library/hello-world:latest": {
"Registry": "bobo3977.jfrog.io/docker",
"Repository": "library/hello-world",
"Tag": "latest",
"ImageID": "",
"Created": "0001-01-01T00:00:00Z",
"TagNumberInRepo": 1,
"FullTag": "bobo3977.jfrog.io/docker/library/hello-world:latest",
"ScanStatus": "",
"Policies": null,
"ReportURL": "",
"LastErrorMessage": "Unexpected response code from RetrieveArtifact endpoint: 404\n{\n \"errors\" : [ {\n \"status\" : 404,\n \"message\" : \"Could not find resource\"\n } ]\n}",
"NumberOfRetries": 0,
"StatusChecked": null,
"StatusRetrieved": null,
"ScanStarted": null,
"ScanFinished": null
},
"bobo3977.jfrog.io/docker/library/hello-world:sha256__f54a58bc1aac5ea1a25d796ae155dc228b3f0e11d046ae276b39c4bf2f13d8c4": {
"Registry": "bobo3977.jfrog.io/docker",
"Repository": "library/hello-world",
"Tag": "sha256__f54a58bc1aac5ea1a25d796ae155dc228b3f0e11d046ae276b39c4bf2f13d8c4",
"ImageID": "sha256:feb5d9fea6a5e9606aa995e879d862b825965ba48de054caab5ef356dc6b3412",
"Created": "2021-09-23T23:47:57.442225064Z",
"TagNumberInRepo": 0,
"FullTag": "bobo3977.jfrog.io/docker/library/hello-world:sha256__f54a58bc1aac5ea1a25d796ae155dc228b3f0e11d046ae276b39c4bf2f13d8c4",
"ScanStatus": "noPolicy",
"Policies": null,
"ReportURL": "https://app.us4.sysdig.com/secure/#/scanning/scan-results/bobo3977.jfrog.io%2Fdocker%2Flibrary%2Fhello-world%3Asha256__f54a58bc1aac5ea1a25d796ae155dc228b3f0e11d046ae276b39c4bf2f13d8c4/id/feb5d9fea6a5e9606aa995e879d862b825965ba48de054caab5ef356dc6b3412/summaries",
"LastErrorMessage": "",
"NumberOfRetries": 0,
"StatusChecked": null,
"StatusRetrieved": null,
"ScanStarted": "2023-02-14T14:25:46.587917743Z",
"ScanFinished": "2023-02-14T14:25:46.780064276Z"
}
}
}
{"level":"info","component":"image-scanner","time":"2023-02-14T14:25:46Z","message":"Closing image analyzer DB"}
スキャン結果のSysdig UIでの確認
Sysdig UIにログインし、Vulnerabilities > Registry に移動します。
レジストリ内のイメージのスキャン結果が表示されていることを確認します。
クリーンアップ
registry-scannerをアンインストールするには以下のコマンドを実行します。
kubectl delete job registry-scanner-manual-test
sudo helm uninstall registry-scanner
まとめ
registry-scannerを使って、JFrog Artifactory SaaS/Cloudのレジストリスキャンを簡単に実行できることが確認できました。