Merge pull request #651 from sharmapulkit04/security-validator-manifests

Added kubectl manifests to deploy webhook
This commit is contained in:
SylwiaBrant 2021-09-01 11:43:38 +02:00 committed by GitHub
commit 2e8fed4e59
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 201 additions and 681 deletions

View File

@ -96,8 +96,8 @@ e2e: deepcopy-gen manifests ## Runs e2e tests, you can use EXTRA_ARGS
.PHONY: helm-e2e
IMAGE_NAME := $(DOCKER_REGISTRY):$(GITCOMMIT)
#TODO: install cert-manager before running helm charts
helm-e2e: helm container-runtime-build ## Runs helm e2e tests, you can use EXTRA_ARGS
helm-e2e: helm container-runtime-build ## Runs helm e2e tests, you can use EXTRA_ARGS
@echo "+ $@"
RUNNING_TESTS=1 go test -parallel=1 "./test/helm/" -ginkgo.v -tags "$(BUILDTAGS) cgo" -v -timeout 60m -run "$(E2E_TEST_SELECTOR)" -image-name=$(IMAGE_NAME) $(E2E_TEST_ARGS)
@ -519,25 +519,14 @@ kubebuilder:
test -f ${ENVTEST_ASSETS_DIR}/setup-envtest.sh || curl -sSLo ${ENVTEST_ASSETS_DIR}/setup-envtest.sh https://raw.githubusercontent.com/kubernetes-sigs/controller-runtime/v0.7.0/hack/setup-envtest.sh
source ${ENVTEST_ASSETS_DIR}/setup-envtest.sh; fetch_envtest_tools $(ENVTEST_ASSETS_DIR); setup_envtest_env $(ENVTEST_ASSETS_DIR);
#TODO Integrate with master Makefile.
MANIFESTS := webhook/all_in_one_$(API_VERSION).yaml
all-in-one-build-webhook: ## Re-generate all-in-one yaml
@echo "+ $@"
> $(MANIFESTS)
cat webhook/rbac.yaml >> $(MANIFESTS)
cat webhook/operator.yaml >> $(MANIFESTS)
cat webhook/cert-manager.yaml >> $(MANIFESTS)
cat webhook/webhook.yaml >> $(MANIFESTS)
sed -i "s~{DOCKER_REGISTRY}:{GITCOMMIT}~${DOCKER_REGISTRY}:${GITCOMMIT}~;" ${MANIFESTS}
# start the cluster locally and set it to use the docker daemon from minikube
# install cert-manager v1.5.1
install-cert-manager: minikube-start
kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.5.1/cert-manager.yaml
uninstall-cert-manager: minikube-start
kubectl delete -f https://github.com/jetstack/cert-manager/releases/download/v1.5.1/cert-manager.yaml
#Launch cert-manager and deploy the operator locally along with webhook
deploy-webhook: install-cert-manager install-crds container-runtime-build all-in-one-build-webhook
# Deploy the operator locally along with webhook using helm charts
deploy-webhook: container-runtime-build
@echo "+ $@"
kubectl apply -f ${MANIFESTS}
bin/helm upgrade jenkins chart/jenkins-operator --install --set-string operator.image=${IMAGE_NAME} --set webhook.enabled=true --set jenkins.enabled=false

View File

@ -0,0 +1,67 @@
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: jenkins-webhook-certificate
namespace: default
spec:
duration: 2160h
renewBefore: 360h
secretName: jenkins-webhook-certificate
dnsNames:
- jenkins-webhook-service.default.svc
- jenkins-webhook-service.default.svc.cluster.local
issuerRef:
kind: Issuer
name: selfsigned
---
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: selfsigned
namespace: default
spec:
selfSigned: {}
---
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
name: jenkins-webhook
annotations:
cert-manager.io/inject-ca-from: default/jenkins-webhook-certificate
webhooks:
- admissionReviewVersions:
- v1
- v1beta1
clientConfig:
service:
name: jenkins-webhook-service
namespace: default
path: /validate-jenkins-io-v1alpha2-jenkins
failurePolicy: Fail
name: vjenkins.kb.io
timeoutSeconds: 30
rules:
- apiGroups:
- jenkins.io
apiVersions:
- v1alpha2
operations:
- CREATE
- UPDATE
resources:
- jenkins
scope: "Namespaced"
sideEffects: None
---
apiVersion: v1
kind: Service
metadata:
name: jenkins-webhook-service
namespace: default
spec:
ports:
- port: 443
targetPort: 9443
selector:
control-plane: controller-manager
---

View File

@ -1,15 +1,15 @@
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: webhook-certificate
name: jenkins-webhook-certificate
namespace: default
spec:
duration: 2160h
renewBefore: 360h
secretName: webhook-server-cert
secretName: jenkins-webhook-certificate
dnsNames:
- webhook-service.default.svc
- webhook-service.default.svc.cluster.local
- jenkins-webhook-service.default.svc
- jenkins-webhook-service.default.svc.cluster.local
issuerRef:
kind: Issuer
name: selfsigned
@ -21,6 +21,4 @@ metadata:
name: selfsigned
namespace: default
spec:
selfSigned: {}
---
selfSigned: {}

View File

@ -1,16 +1,17 @@
---
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
name: validating-webhook-configuration
name: jenkins-webhook
annotations:
cert-manager.io/inject-ca-from: default/webhook-certificate
cert-manager.io/inject-ca-from: default/jenkins-webhook-certificate
webhooks:
- admissionReviewVersions:
- v1
- v1beta1
clientConfig:
service:
name: webhook-service
name: jenkins-webhook-service
namespace: default
path: /validate-jenkins-io-v1alpha2-jenkins
failurePolicy: Fail
@ -26,18 +27,19 @@ webhooks:
- UPDATE
resources:
- jenkins
scope: "Namespaced"
sideEffects: None
---
apiVersion: v1
kind: Service
metadata:
name: webhook-service
name: jenkins-webhook-service
namespace: default
spec:
ports:
- port: 443
targetPort: 9443
selector:
control-plane: controller-manager
name: jenkins-operator
---

View File

@ -1,357 +0,0 @@
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: jenkins-operator
---
# permissions to do leader election.
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: leader-election-role
rules:
- apiGroups:
- ""
- coordination.k8s.io
resources:
- configmaps
- leases
verbs:
- get
- list
- watch
- create
- update
- patch
- delete
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: leader-election-rolebinding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: leader-election-role
subjects:
- kind: ServiceAccount
name: jenkins-operator
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: jenkins-operator
rules:
- apiGroups:
- apps
resources:
- daemonsets
- deployments
- replicasets
- statefulsets
verbs:
- '*'
- apiGroups:
- apps
- jenkins-operator
resources:
- deployments/finalizers
verbs:
- update
- apiGroups:
- build.openshift.io
resources:
- buildconfigs
- builds
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- configmaps
- secrets
- services
verbs:
- create
- get
- list
- update
- watch
- apiGroups:
- ""
resources:
- events
verbs:
- create
- get
- list
- patch
- watch
- apiGroups:
- ""
resources:
- persistentvolumeclaims
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- pods
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- ""
resources:
- pods
- pods/exec
verbs:
- '*'
- apiGroups:
- ""
resources:
- pods/log
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- pods/portforward
verbs:
- create
- apiGroups:
- ""
resources:
- serviceaccounts
verbs:
- create
- get
- list
- update
- watch
- apiGroups:
- image.openshift.io
resources:
- imagestreams
verbs:
- get
- list
- watch
- apiGroups:
- jenkins.io
resources:
- '*'
verbs:
- '*'
- apiGroups:
- jenkins.io
resources:
- jenkins
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- jenkins.io
resources:
- jenkins/finalizers
verbs:
- update
- apiGroups:
- jenkins.io
resources:
- jenkins/status
verbs:
- get
- patch
- update
- apiGroups:
- rbac.authorization.k8s.io
resources:
- rolebindings
- roles
verbs:
- create
- get
- list
- update
- watch
- apiGroups:
- route.openshift.io
resources:
- routes
verbs:
- create
- get
- list
- update
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: manager-rolebinding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: jenkins-operator
subjects:
- kind: ServiceAccount
name: jenkins-operator
---
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: jenkins-operator
labels:
control-plane: controller-manager
spec:
selector:
matchLabels:
control-plane: controller-manager
replicas: 1
template:
metadata:
labels:
control-plane: controller-manager
spec:
serviceAccountName: jenkins-operator
securityContext:
runAsUser: 65532
containers:
- command:
- /manager
args:
- --leader-elect
image: jenkins-operator:37d0eac4-dirty
name: jenkins-operator
imagePullPolicy: IfNotPresent
securityContext:
allowPrivilegeEscalation: false
livenessProbe:
httpGet:
path: /healthz
port: 8081
initialDelaySeconds: 15
periodSeconds: 20
readinessProbe:
httpGet:
path: /readyz
port: 8081
initialDelaySeconds: 5
periodSeconds: 10
resources:
limits:
cpu: 200m
memory: 200Mi
requests:
cpu: 100m
memory: 80Mi
env:
- name: WATCH_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
volumeMounts:
- mountPath: /tmp/k8s-webhook-server/serving-certs
name: cert
volumes:
- name: cert
secret:
defaultMode: 420
secretName: webhook-server-cert
terminationGracePeriodSeconds: 10
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: webhook-certificate
namespace: default
spec:
duration: 2160h
renewBefore: 360h
secretName: webhook-server-cert
dnsNames:
- webhook-service.default.svc
- webhook-service.default.svc.cluster.local
issuerRef:
kind: Issuer
name: selfsigned
---
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: selfsigned
namespace: default
spec:
selfSigned: {}
---
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
name: validating-webhook-configuration
annotations:
cert-manager.io/inject-ca-from: default/webhook-certificate
webhooks:
- admissionReviewVersions:
- v1
- v1beta1
clientConfig:
service:
name: webhook-service
namespace: default
path: /validate-jenkins-io-v1alpha2-jenkins
failurePolicy: Fail
name: vjenkins.kb.io
timeoutSeconds: 30
rules:
- apiGroups:
- jenkins.io
apiVersions:
- v1alpha2
operations:
- CREATE
- UPDATE
resources:
- jenkins
sideEffects: None
---
apiVersion: v1
kind: Service
metadata:
name: webhook-service
namespace: default
spec:
ports:
- port: 443
targetPort: 9443
selector:
control-plane: controller-manager
---

View File

@ -1,65 +0,0 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: jenkins-operator
labels:
control-plane: controller-manager
spec:
selector:
matchLabels:
control-plane: controller-manager
replicas: 1
template:
metadata:
labels:
control-plane: controller-manager
spec:
serviceAccountName: jenkins-operator
securityContext:
runAsUser: 65532
containers:
- command:
- /manager
args:
- --leader-elect
- --validate-security-warnings
image: {DOCKER_REGISTRY}:{GITCOMMIT}
name: jenkins-operator
imagePullPolicy: IfNotPresent
securityContext:
allowPrivilegeEscalation: false
livenessProbe:
httpGet:
path: /healthz
port: 8081
initialDelaySeconds: 15
periodSeconds: 20
readinessProbe:
httpGet:
path: /readyz
port: 8081
initialDelaySeconds: 5
periodSeconds: 10
resources:
limits:
cpu: 200m
memory: 200Mi
requests:
cpu: 100m
memory: 80Mi
env:
- name: WATCH_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
volumeMounts:
- mountPath: /tmp/k8s-webhook-server/serving-certs
name: cert
volumes:
- name: cert
secret:
defaultMode: 420
secretName: webhook-server-cert
terminationGracePeriodSeconds: 10
---

View File

@ -1,224 +0,0 @@
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: jenkins-operator
---
# permissions to do leader election.
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: leader-election-role
rules:
- apiGroups:
- ""
- coordination.k8s.io
resources:
- configmaps
- leases
verbs:
- get
- list
- watch
- create
- update
- patch
- delete
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: leader-election-rolebinding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: leader-election-role
subjects:
- kind: ServiceAccount
name: jenkins-operator
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: jenkins-operator
rules:
- apiGroups:
- apps
resources:
- daemonsets
- deployments
- replicasets
- statefulsets
verbs:
- '*'
- apiGroups:
- apps
- jenkins-operator
resources:
- deployments/finalizers
verbs:
- update
- apiGroups:
- build.openshift.io
resources:
- buildconfigs
- builds
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- configmaps
- secrets
- services
verbs:
- create
- get
- list
- update
- watch
- apiGroups:
- ""
resources:
- events
verbs:
- create
- get
- list
- patch
- watch
- apiGroups:
- ""
resources:
- persistentvolumeclaims
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- pods
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- ""
resources:
- pods
- pods/exec
verbs:
- '*'
- apiGroups:
- ""
resources:
- pods/log
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- pods/portforward
verbs:
- create
- apiGroups:
- ""
resources:
- serviceaccounts
verbs:
- create
- get
- list
- update
- watch
- apiGroups:
- image.openshift.io
resources:
- imagestreams
verbs:
- get
- list
- watch
- apiGroups:
- jenkins.io
resources:
- '*'
verbs:
- '*'
- apiGroups:
- jenkins.io
resources:
- jenkins
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- jenkins.io
resources:
- jenkins/finalizers
verbs:
- update
- apiGroups:
- jenkins.io
resources:
- jenkins/status
verbs:
- get
- patch
- update
- apiGroups:
- rbac.authorization.k8s.io
resources:
- rolebindings
- roles
verbs:
- create
- get
- list
- update
- watch
- apiGroups:
- route.openshift.io
resources:
- routes
verbs:
- create
- get
- list
- update
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: manager-rolebinding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: jenkins-operator
subjects:
- kind: ServiceAccount
name: jenkins-operator
---

View File

@ -241,7 +241,7 @@ kubectl --context remote-k8s --namespace default get po
Tests are written using [Ginkgo](https://onsi.github.io/ginkgo/) with [Gomega](https://onsi.github.io/gomega/).
Run unit tests with go fmt, lint, statickcheck, vet:
Run unit tests with go fmt, lint, staticcheck, vet:
```bash
make verify
@ -262,6 +262,12 @@ make minikube-start
make e2e
```
Run Helm e2e tests:
```bash
eval $(bin/minikube docker-env)
make helm-e2e
```
Run the specific e2e test:
```bash
@ -292,8 +298,13 @@ kubectl get secret jenkins-operator-credentials-<cr_name> -o 'jsonpath={.data.us
kubectl get secret jenkins-operator-credentials-<cr_name> -o 'jsonpath={.data.password}' | base64 -d
```
### Webhook
To deploy the operator along with webhook, run :
```bash
eval $(minikube docker-env)
make deploy-webhook
```
It uses [cert-manager](https://cert-manager.io/) as an external dependency.
## Self-learning
@ -304,6 +315,8 @@ kubectl get secret jenkins-operator-credentials-<cr_name> -o 'jsonpath={.data.pa
* [Operator SDK Tutorial for Go](https://sdk.operatorframework.io/docs/building-operators/golang/tutorial/)
* [Kubebuilder Validating Webhook Implementation](https://book.kubebuilder.io/cronjob-tutorial/webhook-implementation.html)
[dep_tool]:https://golang.github.io/dep/docs/installation.html
[git_tool]:https://git-scm.com/downloads
[go_tool]:https://golang.org/dl/
@ -314,4 +327,3 @@ kubectl get secret jenkins-operator-credentials-<cr_name> -o 'jsonpath={.data.pa
[minikube]:https://kubernetes.io/docs/tasks/tools/install-minikube/
[virtualbox]:https://www.virtualbox.org/wiki/Downloads
[install_dev_tools]:https://jenkinsci.github.io/kubernetes-operator/docs/developer-guide/tools/

View File

@ -892,4 +892,98 @@ below is the full list of those volumeMounts:
* jenkins-home
* scripts
* init-configuration
* operator-credentials
* operator-credentials
## Validating Webhook
Validating webhook can be used in order to increase the Operator's capabilities to monitor security issues. It will look for security vulnerabilities in the base and requested plugins. It can be easily installed via Helm charts by setting webhook.enabled in values.yaml.
**Note**: The webhook takes some time to get up and running. It's recommended to first deploy the Operator and later Jenkins Custom Resource by using toggles in `values.yaml`.
For the installation with yaml manifests (without using Helm chart), first, install cert-manager:
```bash
kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.5.1/cert-manager.yaml
```
It takes some time to get cert-manager up and running.
Then, install the webhook and other required resources:
```bash
kubectl apply -f https://raw.githubusercontent.com/jenkinsci/kubernetes-operator/master/deploy/all-in-one-webhook.yaml
```
Now, download the manifests for the operator and other resources from [here](https://raw.githubusercontent.com/jenkinsci/kubernetes-operator/master/deploy/all-in-one-v1alpha2.yaml) and please provide these additional fields in the operator manifest:
<pre>
<code>
apiVersion: apps/v1
kind: Deployment
metadata:
name: jenkins-operator
labels:
control-plane: controller-manager
spec:
selector:
matchLabels:
control-plane: controller-manager
replicas: 1
template:
metadata:
labels:
control-plane: controller-manager
spec:
serviceAccountName: jenkins-operator
securityContext:
runAsUser: 65532
containers:
- command:
- /manager
args:
- --leader-elect
<b>- --validate-security-warnings</b>
image: jenkins-operator:54231733-dirty
name: jenkins-operator
imagePullPolicy: IfNotPresent
securityContext:
allowPrivilegeEscalation: false
livenessProbe:
httpGet:
path: /healthz
port: 8081
initialDelaySeconds: 15
periodSeconds: 20
readinessProbe:
httpGet:
path: /readyz
port: 8081
initialDelaySeconds: 5
periodSeconds: 10
resources:
limits:
cpu: 200m
memory: 100Mi
requests:
cpu: 100m
memory: 20Mi
env:
- name: WATCH_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
<b>volumeMounts:
- mountPath: /tmp/k8s-webhook-server/serving-certs
name: webhook-certs
readOnly: true
volumes:
- name: webhook-certs
secret:
defaultMode: 420
secretName: jenkins-webhook-certificate
terminationGracePeriodSeconds: 10</b>
</code>
</pre>
To enable security validation in the jenkins custom resource,set
>jenkins.ValidateSecurityWarnings=true

View File

@ -35,3 +35,7 @@ The **Jenkins Operator** design incorporates the following concepts:
Operator state is kept in the custom resource status section, which is used for storing any configuration events or job statuses managed by the operator.
It helps to maintain or recover the desired state even after the operator or Jenkins restarts.
## Webhook
It rejects/accepts admission requests based on potential security warnings in plugins present in the Jenkins Custom Resource.