Skip to content

Commit a24e84c

Browse files
authored
Feature/trivy scanner (#445)
* Updating CI to use trivy scanner * Removing apk add curl command * Removing mv command * More ci updates * More ci updates * Proper trivy CLI * Trivy proper formatting * Trivy proper formatting * Adding base image scan * Adding anchore * Adding anchore * Persist base image to workspace * Increasing timeout * Adding custom policy file * Omitting failure condition * Adding grype * Increasing idle timeout for grype * Adding more options to grype * Changing grype again * Removing grype
1 parent 8f20c2c commit a24e84c

File tree

2 files changed

+71
-142
lines changed

2 files changed

+71
-142
lines changed

.circleci/anchore-policy.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"name": "IgnoreUnfixablePkgs",
3+
"version": "1_0",
4+
"comment": "Policy for basic checks",
5+
"id": "ba6daa06-da3b-46d3-9e22-f01f07b0489a",
6+
"rules": [
7+
{
8+
"action": "STOP",
9+
"gate": "vulnerabilities",
10+
"id": "80569900-d6b3-4391-b2a0-bf34cf6d813d",
11+
"params": [
12+
{ "name": "package_type", "value": "all" },
13+
{ "name": "severity_comparison", "value": ">" },
14+
{ "name": "severity", "value": "medium" },
15+
{ "name": "fix_available", "value": "true"}
16+
],
17+
"trigger": "package"
18+
}
19+
]
20+
}

.circleci/config.yml

Lines changed: 51 additions & 142 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ executors:
1414
resource_class: xlarge
1515

1616
orbs:
17-
clair: ovotech/clair-scanner@1.6.0
17+
anchore: anchore/anchore-engine@1.8.2
1818

1919
jobs:
2020

@@ -33,11 +33,13 @@ jobs:
3333
command: |
3434
docker save -o workspace_cache/splunk-debian-10.tar splunk-debian-10:latest
3535
docker save -o workspace_cache/uf-debian-10.tar uf-debian-10:latest
36+
docker save -o workspace_cache/base-debian-10.tar base-debian-10:latest
3637
- persist_to_workspace:
3738
root: workspace_cache
3839
paths:
3940
- splunk-debian-10.tar
4041
- uf-debian-10.tar
42+
- base-debian-10.tar
4143

4244
build_redhat_8:
4345
executor: py3
@@ -54,22 +56,60 @@ jobs:
5456
command: |
5557
docker save -o workspace_cache/splunk-redhat-8.tar splunk-redhat-8:latest
5658
docker save -o workspace_cache/uf-redhat-8.tar uf-redhat-8:latest
59+
docker save -o workspace_cache/base-redhat-8.tar base-redhat-8:latest
5760
- persist_to_workspace:
5861
root: workspace_cache
5962
paths:
6063
- splunk-redhat-8.tar
6164
- uf-redhat-8.tar
65+
- base-redhat-8.tar
6266

63-
scan_images:
64-
executor: clair/default
67+
scan_images_trivy:
68+
executor: py3
6569
steps:
6670
- checkout
6771
- setup_remote_docker
6872
- attach_workspace:
6973
at: workspace_cache
70-
- modified-clair-scan:
71-
docker_tar_dir: /root/project/workspace_cache/
72-
whitelist: /root/project/clair-whitelist.yml
74+
- run:
75+
name: Install trivy
76+
command: |
77+
VERSION=$(
78+
curl --silent "https://api.github.com/repos/aquasecurity/trivy/releases/latest" | \
79+
grep '"tag_name":' | \
80+
sed -E 's/.*"v([^"]+)".*/\1/'
81+
)
82+
wget https://github.com/aquasecurity/trivy/releases/download/v${VERSION}/trivy_${VERSION}_Linux-64bit.tar.gz
83+
tar zxvf trivy_${VERSION}_Linux-64bit.tar.gz
84+
- run:
85+
name: Scan images
86+
command: |
87+
for image in ./workspace_cache/*.tar; do
88+
[ -e "$image" ] || continue
89+
./trivy image --exit-code 0 --ignore-unfixed --severity "HIGH,CRITICAL" --no-progress -i "$image"
90+
done
91+
92+
scan_images_anchore:
93+
executor: anchore/anchore_engine
94+
steps:
95+
- checkout
96+
- setup_remote_docker
97+
- attach_workspace:
98+
at: workspace_cache
99+
- run:
100+
name: Load images
101+
command: |
102+
for image in ./workspace_cache/*.tar; do
103+
[ -e "$image" ] || continue
104+
docker load --input "$image"
105+
done
106+
- anchore/analyze_local_image:
107+
image_name: 'splunk-redhat-8 uf-redhat-8 base-redhat-8 splunk-debian-10 uf-debian-10 base-debian-10'
108+
policy_bundle_file_path: .circleci/anchore-policy.json
109+
timeout: '600'
110+
- anchore/parse_reports
111+
- store_artifacts:
112+
path: anchore-reports
73113

74114
test_redhat_8_small:
75115
executor: circleci_large
@@ -208,7 +248,11 @@ workflows:
208248
jobs:
209249
- build_debian_10
210250
- build_redhat_8
211-
- scan_images:
251+
- scan_images_trivy:
252+
requires:
253+
- build_debian_10
254+
- build_redhat_8
255+
- scan_images_anchore:
212256
requires:
213257
- build_debian_10
214258
- build_redhat_8
@@ -228,138 +272,3 @@ workflows:
228272
requires:
229273
- build_debian_10
230274
- build_redhat_8
231-
232-
commands:
233-
modified-clair-scan:
234-
description: "Scan an image for vulnerabilities"
235-
parameters:
236-
image:
237-
type: "string"
238-
description: "Name of the image to scan"
239-
default: ""
240-
image_file:
241-
type: "string"
242-
description: "Path to a file of images to scan"
243-
default: ""
244-
whitelist:
245-
type: "string"
246-
description: "Path to a CVE whitelist"
247-
default: ""
248-
severity_threshold:
249-
type: "string"
250-
description: "The threshold (equal and above) at which discovered vulnerabilities are reported. May be 'Defcon1', 'Critical', 'High', 'Medium', 'Low', 'Negligible' or 'Unknown'"
251-
default: "High"
252-
fail_on_discovered_vulnerabilities:
253-
type: "boolean"
254-
description: "Fail command when vulnerabilities at severity equal to or above the threshold are discovered"
255-
default: true
256-
fail_on_unsupported_images:
257-
type: "boolean"
258-
description: "Fail command when image cannot be scanned for vulnerabilities"
259-
default: true
260-
disable_verbose_console_output:
261-
type: "boolean"
262-
description: "Disable verbose console output"
263-
default: false
264-
docker_tar_dir:
265-
type: "string"
266-
description: "Path of directory that Docker tarballs are stored"
267-
default: "/docker-tars"
268-
steps:
269-
- run:
270-
name: "Vulnerability scan"
271-
command: |
272-
#!/usr/bin/env bash
273-
274-
set -xe
275-
276-
DOCKER_TAR_DIR="<< parameters.docker_tar_dir >>"
277-
278-
if [ -z "<< parameters.image_file >><< parameters.image >>" ] && [ -z "$(ls -A "$DOCKER_TAR_DIR" 2>/dev/null)" ]; then
279-
echo "image_file or image parameters or docker tarballs must be present"
280-
exit 255
281-
fi
282-
283-
REPORT_DIR=/clair-reports
284-
mkdir $REPORT_DIR
285-
286-
DB=$(docker run -p 5432:5432 -d arminc/clair-db:latest)
287-
CLAIR=$(docker run -p 6060:6060 --link "$DB":postgres -d arminc/clair-local-scan:latest)
288-
CLAIR_SCANNER=$(docker run -v /var/run/docker.sock:/var/run/docker.sock -d ovotech/clair-scanner@sha256:8a4f920b4e7e40dbcec4a6168263d45d3385f2970ee33e5135dd0e3b75d39c75 tail -f /dev/null)
289-
290-
clair_ip=$(docker exec -it "$CLAIR" hostname -i | grep -oE '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+')
291-
scanner_ip=$(docker exec -it "$CLAIR_SCANNER" hostname -i | grep -oE '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+')
292-
293-
if [ -n "<< parameters.whitelist >>" ]; then
294-
cat "<< parameters.whitelist >>"
295-
docker cp "<< parameters.whitelist >>" "$CLAIR_SCANNER:/whitelist.yml"
296-
297-
WHITELIST="-w /whitelist.yml"
298-
fi
299-
300-
function scan() {
301-
local image=$1
302-
# replace forward-slashes and colons with underscores
303-
munged_image=$(echo "$image" | sed 's/\//_/g' | sed 's/:/_/g')
304-
sanitised_image_filename="${munged_image}.json"
305-
local ret=0
306-
local docker_cmd=(docker exec -it "$CLAIR_SCANNER" clair-scanner \
307-
--ip "$scanner_ip" \
308-
--clair=http://"$clair_ip":6060 \
309-
-t "<< parameters.severity_threshold >>" \
310-
--report "/$sanitised_image_filename" \
311-
--log "/log.json" $WHITELIST \
312-
--reportAll=true \
313-
--exit-when-no-features=false \
314-
"$image")
315-
316-
# if verbose output is disabled, analyse status code for more fine-grained output
317-
if [ "<< parameters.disable_verbose_console_output >>" == "true" ];then
318-
"${docker_cmd[@]}" > /dev/null 2>&1 || ret=$?
319-
else
320-
"${docker_cmd[@]}" 2>&1 || ret=$?
321-
fi
322-
if [ $ret -eq 0 ]; then
323-
echo "No unapproved vulnerabilities"
324-
elif [ $ret -eq 1 ]; then
325-
echo "Unapproved vulnerabilities found"
326-
if [ "<< parameters.fail_on_discovered_vulnerabilities >>" == "true" ];then
327-
EXIT_STATUS=1
328-
fi
329-
elif [ $ret -eq 5 ]; then
330-
echo "Image was not scanned, not supported."
331-
if [ "<< parameters.fail_on_unsupported_images >>" == "true" ];then
332-
EXIT_STATUS=1
333-
fi
334-
else
335-
echo "Unknown clair-scanner return code $ret."
336-
EXIT_STATUS=1
337-
fi
338-
339-
docker cp "$CLAIR_SCANNER:/$sanitised_image_filename" "$REPORT_DIR/$sanitised_image_filename" || true
340-
}
341-
342-
EXIT_STATUS=0
343-
344-
for entry in "$DOCKER_TAR_DIR"/*.tar; do
345-
[ -e "$entry" ] || continue
346-
images=$(docker load -i "$entry" | sed -e 's/Loaded image: //g')
347-
for image in $images; do
348-
scan "$image"
349-
done
350-
done
351-
352-
if [ -n "<< parameters.image_file >>" ]; then
353-
images=$(cat "<< parameters.image_file >>")
354-
for image in $images; do
355-
scan "$image"
356-
done
357-
fi
358-
if [ -n "<< parameters.image >>" ]; then
359-
image="<< parameters.image >>"
360-
scan "$image"
361-
fi
362-
363-
exit $EXIT_STATUS
364-
- store_artifacts:
365-
path: /clair-reports

0 commit comments

Comments
 (0)