Skip to content

Commit 6fefd20

Browse files
author
Amir Moualem
authored
Merge pull request #178 from snyk/feat/force-static-analysis
feat: force static analysis
2 parents 3e78de7 + ecd6dad commit 6fefd20

22 files changed

+30
-195
lines changed

Dockerfile

-9
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,6 @@ LABEL maintainer="Snyk Ltd"
2929

3030
ENV NODE_ENV production
3131

32-
# INSTALLING DOCKER, CAN BE REMOVED WHEN WE DON'T TRY TO `DOCKER PULL`
33-
ENV DOCKERVERSION=18.06.3-ce
34-
RUN apk --no-cache add --virtual curl-dep curl \
35-
&& curl -fsSLO https://download.docker.com/linux/static/stable/x86_64/docker-${DOCKERVERSION}.tgz \
36-
&& tar xzvf docker-${DOCKERVERSION}.tgz --strip 1 \
37-
-C /usr/local/bin docker/docker \
38-
&& rm docker-${DOCKERVERSION}.tgz \
39-
&& apk del curl-dep
40-
4132
COPY --from=skopeo-build /usr/bin/skopeo /usr/bin/skopeo
4233
COPY --from=skopeo-build /etc/containers/registries.d/default.yaml /etc/containers/registries.d/default.yaml
4334
COPY --from=skopeo-build /etc/containers/policy.json /etc/containers/policy.json

README.md

+5-9
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
# snyk/kubernetes-monitor #
22

33
## Summary ##
4+
45
Container to monitor Kubernetes clusters' security
56

67
## Prerequisites ##
78

8-
*Note that by default the monitor uses Docker to scan your cluster and requires Docker to be your container runtime.*
9-
*Alternatively, you can enable static analysis, which allows the use of any container runtime.*
9+
* 50 GB of storage in the form of [emptyDir](https://kubernetes.io/docs/concepts/storage/volumes/#emptydir).
10+
* External internet access from the Kubernetes cluster.
11+
12+
## Installing ##
1013

1114
The Snyk monitor (`kubernetes-monitor`) requires some minimal configuration items in order to work correctly.
1215

@@ -75,10 +78,3 @@ Finally, to launch the Snyk monitor in your cluster, run the following:
7578
```shell
7679
kubectl apply -f snyk-monitor-deployment.yaml
7780
```
78-
79-
## Enabling static analysis ##
80-
81-
Static analysis works with any container runtime and does not rely on Docker to scan the images in your cluster.
82-
It works by pulling the image, unpacking it and inspecting the files directly. For this process it needs temporary storage, so the Snyk monitor uses 50 GB of storage in the form of [emptyDir](https://kubernetes.io/docs/concepts/storage/volumes/#emptydir).
83-
84-
To enable static analysis, modify one of the permissions files (`snyk-monitor-namespaced-permissions.yaml` for the Namespaced deployment or `snyk-monitor-cluster-permissions.yaml` for the Cluster-scoped deployment) and set the string value of `staticAnalysis` to `"true"`.

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"pretest": "./scripts/build-image.sh",
77
"test": "npm run lint && npm run build && npm run test:unit && npm run test:integration",
88
"test:unit": "./tap test/unit -R spec",
9-
"test:integration": "./tap test/integration -Rdot --timeout=600 && STATIC_ANALYSIS=true ./tap test/integration -Rdot --timeout=1200",
9+
"test:integration": "./tap test/integration -Rdot --timeout=1200",
1010
"test:coverage": "npm run test:unit -- --coverage",
1111
"test:watch": "tsc-watch --onSuccess 'npm run test:unit'",
1212
"test:apk": "./scripts/build-image.sh && PACKAGE_MANAGER=apk ./tap test/package-manager/regression.test.ts -Rdot --timeout=7200",

snyk-monitor-cluster-permissions.yaml

-1
Original file line numberDiff line numberDiff line change
@@ -83,5 +83,4 @@ data:
8383
namespace: ""
8484
integrationApi: ""
8585
clusterName: ""
86-
staticAnalysis: "false"
8786
---

snyk-monitor-deployment.yaml

-11
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@ spec:
2121
terminationMessagePath: /dev/termination-log
2222
terminationMessagePolicy: File
2323
volumeMounts:
24-
- name: docker-socket-mount
25-
mountPath: /var/run/docker.sock
2624
- name: docker-config
2725
readOnly: true
2826
mountPath: "/root/.docker"
@@ -52,12 +50,6 @@ spec:
5250
name: snyk-monitor
5351
key: clusterName
5452
optional: true
55-
- name: SNYK_STATIC_ANALYSIS
56-
valueFrom:
57-
configMapKeyRef:
58-
name: snyk-monitor
59-
key: staticAnalysis
60-
optional: true
6153
resources:
6254
requests:
6355
cpu: '250m'
@@ -67,9 +59,6 @@ spec:
6759
memory: '2Gi'
6860
securityContext: {}
6961
volumes:
70-
- name: docker-socket-mount
71-
hostPath:
72-
path: /var/run/docker.sock
7362
- name: docker-config
7463
secret:
7564
secretName: snyk-monitor

snyk-monitor-namespaced-permissions.yaml

-1
Original file line numberDiff line numberDiff line change
@@ -75,5 +75,4 @@ data:
7575
namespace: snyk-monitor
7676
integrationApi: ""
7777
clusterName: ""
78-
staticAnalysis: "false"
7978
---

snyk-monitor/README.md

+2-15
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
# snyk/kubernetes-monitor-chart #
22

33
## Summary ##
4-
A Helm chart for the Snyk monitor
54

6-
## Prerequisites ##
5+
A Helm chart for the Snyk monitor
76

8-
*Note that by default the monitor uses Docker to scan your cluster and requires Docker to be your container runtime.*
9-
*Alternatively, you can enable static analysis, which removes the reliance on Docker completely and works with any container runtime.*
7+
## Installing ##
108

119
The Snyk monitor (`kubernetes-monitor`) requires some minimal configuration items in order to work correctly.
1210

@@ -70,14 +68,3 @@ For Helm 3, you may run the following:
7068
```shell
7169
helm upgrade --generate-name --install snyk-monitor snyk-charts/snyk-monitor --namespace snyk-monitor --set clusterName="Production cluster"
7270
```
73-
74-
## Enabling static analysis ##
75-
76-
Static analysis works with any container runtime and does not rely on Docker to scan the images in your cluster.
77-
It works by pulling the image, unpacking it and inspecting the files directly. For this process it needs temporary storage, so the Snyk monitor uses 50 GB of storage in the form of [emptyDir](https://kubernetes.io/docs/concepts/storage/volumes/#emptydir).
78-
The Docker socket is _not_ mounted when static analysis is enabled.
79-
80-
To enable static analysis, set the `featureFlags.staticAnalysis` value to `true`:
81-
```shell
82-
helm upgrade --install snyk-monitor snyk-charts/snyk-monitor --namespace snyk-monitor --set clusterName="Production cluster" --set featureFlags.staticAnalysis=true
83-
```

snyk-monitor/templates/deployment.yaml

-15
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,11 @@ spec:
2727
terminationMessagePath: /dev/termination-log
2828
terminationMessagePolicy: File
2929
volumeMounts:
30-
{{- if ne .Values.featureFlags.staticAnalysis true }}
31-
- name: docker-socket-mount
32-
mountPath: /var/run/docker.sock
33-
{{- end }}
3430
- name: docker-config
3531
readOnly: true
3632
mountPath: "/root/.docker"
37-
{{- if eq .Values.featureFlags.staticAnalysis true }}
3833
- name: temporary-storage
3934
mountPath: "/snyk-monitor"
40-
{{- end }}
4135
env:
4236
- name: SNYK_INTEGRATION_ID
4337
valueFrom:
@@ -50,8 +44,6 @@ spec:
5044
value: {{ .Values.integrationApi }}
5145
- name: SNYK_CLUSTER_NAME
5246
value: {{ .Values.clusterName }}
53-
- name: SNYK_STATIC_ANALYSIS
54-
value: {{ quote .Values.featureFlags.staticAnalysis }}
5547
resources:
5648
requests:
5749
cpu: '250m'
@@ -60,19 +52,12 @@ spec:
6052
cpu: '1'
6153
memory: '2Gi'
6254
volumes:
63-
{{- if ne .Values.featureFlags.staticAnalysis true }}
64-
- name: docker-socket-mount
65-
hostPath:
66-
path: {{ .Values.dockerSocketHostPath }}
67-
{{- end }}
6855
- name: docker-config
6956
secret:
7057
secretName: {{ .Values.monitorSecrets }}
7158
items:
7259
- key: dockercfg.json
7360
path: config.json
74-
{{- if eq .Values.featureFlags.staticAnalysis true }}
7561
- name: temporary-storage
7662
emptyDir:
7763
sizeLimit: {{ .Values.temporaryStorageSize }}
78-
{{- end }}

snyk-monitor/values.yaml

-3
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,6 @@ clusterName: ""
2828
# The path of the docker socket on the node. For PKS: /var/vcap/data/sys/run/docker/docker.sock
2929
dockerSocketHostPath: "/var/run/docker.sock"
3030

31-
featureFlags:
32-
staticAnalysis: false
33-
3431
# The snyk-monitor requires disk storage to temporarily pull container images and to scan them for vulnerabilities.
3532
# This value controls how much disk storage _at most_ may be allocated for the snyk-monitor. The snyk-monitor mounts an emptyDir for storage.
3633
temporaryStorageSize: 50Gi

src/common/config.ts

-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,5 @@ config.AGENT_ID = uuidv4();
88
config.INTEGRATION_ID = config.INTEGRATION_ID.trim();
99
config.CLUSTER_NAME = config.CLUSTER_NAME || 'Default cluster';
1010
config.IMAGE_STORAGE_ROOT = '/snyk-monitor';
11-
config.STATIC_ANALYSIS = config.STATIC_ANALYSIS || false;
1211

1312
export = config;

src/common/features.ts

-5
This file was deleted.

src/images/docker.ts

-11
This file was deleted.

src/images/index.ts

+2-26
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
import logger = require('../common/logger');
2-
import { pull as dockerPull } from './docker';
32
import { pull as skopeoCopy, getDestinationForImage } from './skopeo';
43
import { unlink } from 'fs';
5-
import { isStaticAnalysisEnabled } from '../common/features';
64
import { IPullableImage } from './types';
75

86
export async function pullImages(images: IPullableImage[]): Promise<IPullableImage[]> {
@@ -11,14 +9,7 @@ export async function pullImages(images: IPullableImage[]): Promise<IPullableIma
119
for (const image of images) {
1210
const {imageName, fileSystemPath} = image;
1311
try {
14-
if (isStaticAnalysisEnabled()) {
15-
if (!fileSystemPath) {
16-
throw new Error('Missing required parameter fileSystemPath for static analysis');
17-
}
18-
await skopeoCopy(imageName, fileSystemPath);
19-
} else {
20-
await dockerPull(imageName);
21-
}
12+
await skopeoCopy(imageName, fileSystemPath);
2213
pulledImages.push(image);
2314
} catch (error) {
2415
logger.error({error, image: imageName}, 'failed to pull image');
@@ -28,28 +19,13 @@ export async function pullImages(images: IPullableImage[]): Promise<IPullableIma
2819
return pulledImages;
2920
}
3021

31-
/**
32-
* TODO: For Docker (dynamic scanning) it returns the image but with an empty file system path
33-
* (because Docker does not pull images to a temporary directory). This will no longer be true
34-
* when static analysis becomes the only option, but worth nothing it here to avoid confusion!
35-
* @param images a list of images for which to generate a file system path
36-
*/
3722
export function getImagesWithFileSystemPath(images: string[]): IPullableImage[] {
38-
return isStaticAnalysisEnabled()
39-
? images.map((image) => ({ imageName: image, fileSystemPath: getDestinationForImage(image) }))
40-
: images.map((image) => ({ imageName: image }));
23+
return images.map((image) => ({ imageName: image, fileSystemPath: getDestinationForImage(image) }));
4124
}
4225

4326
export async function removePulledImages(images: IPullableImage[]) {
44-
if (!isStaticAnalysisEnabled()) {
45-
return;
46-
}
47-
4827
for (const {imageName, fileSystemPath} of images) {
4928
try {
50-
if (!fileSystemPath) {
51-
throw new Error('Missing required parameter fileSystemPath for static analysis');
52-
}
5329
await new Promise((resolve) => unlink(fileSystemPath, resolve));
5430
} catch (error) {
5531
logger.warn({error, image: imageName}, 'failed to delete pulled image');

src/images/types.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
export interface IPullableImage {
22
imageName: string;
3-
fileSystemPath?: string;
3+
fileSystemPath: string;
44
}

src/kube-scanner/image-scanner.ts

+1-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import * as plugin from 'snyk-docker-plugin';
22
import logger = require('../common/logger');
33
import { IStaticAnalysisOptions, StaticAnalysisImageType } from './types';
4-
import { isStaticAnalysisEnabled } from '../common/features';
54
import { IPullableImage } from '../images/types';
65

76
export interface IScanResult {
@@ -45,9 +44,7 @@ export async function scanImages(images: IPullableImage[]): Promise<IScanResult[
4544

4645
for (const {imageName, fileSystemPath} of images) {
4746
try {
48-
const options = isStaticAnalysisEnabled()
49-
? constructStaticAnalysisOptions(fileSystemPath)
50-
: undefined;
47+
const options = constructStaticAnalysisOptions(fileSystemPath);
5148

5249
const result = await plugin.inspect(imageName, dockerfile, options);
5350

src/kube-scanner/watchers/namespaces.ts

-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { makeInformer, ADD } from '@kubernetes/client-node';
22
import { V1Namespace } from '@kubernetes/client-node';
33
import config = require('../../common/config');
4-
import { isStaticAnalysisEnabled } from '../../common/features';
54
import logger = require('../../common/logger');
65
import { WorkloadKind } from '../types';
76
import { setupInformer } from './handlers';
@@ -57,9 +56,6 @@ function setupWatchesForCluster() {
5756
}
5857

5958
export function beginWatchingWorkloads() {
60-
logger.info({isStaticAnalysisEnabled: isStaticAnalysisEnabled()},
61-
'static analysis check');
62-
6359
if (config.NAMESPACE) {
6460
logger.info({namespace: config.NAMESPACE}, 'kubernetes-monitor restricted to specific namespace');
6561
setupWatchesForNamespace(config.NAMESPACE);

test/fixtures/cluster-config.yaml

-7
This file was deleted.

test/fixtures/pod-spec.json

-4
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,6 @@
2020
{
2121
"name": "SNYK_CLUSTER_NAME",
2222
"value": "Production cluster"
23-
},
24-
{
25-
"name": "SNYK_STATIC_ANALYSIS",
26-
"value": "true"
2723
}
2824
],
2925
"image": "snyk/kubernetes-monitor:1.8.5",

test/integration/kubernetes.test.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,7 @@ tap.tearDown(tearDown);
2424
tap.test('deploy snyk-monitor', async (t) => {
2525
t.plan(1);
2626

27-
const isStaticAnalysis = process.env.STATIC_ANALYSIS === 'true';
28-
integrationId = await setup.deployMonitor(isStaticAnalysis);
27+
integrationId = await setup.deployMonitor();
2928

3029
t.pass('successfully deployed the snyk-monitor');
3130
});

test/package-manager/regression.test.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,7 @@ tap.tearDown(tearDown);
2626
tap.test('deploy snyk-monitor', async (t) => {
2727
t.plan(1);
2828

29-
const isStaticAnalysis = true;
30-
integrationId = await deployMonitor(isStaticAnalysis);
29+
integrationId = await deployMonitor();
3130

3231
t.pass('successfully deployed the snyk-monitor');
3332
});

0 commit comments

Comments
 (0)