Compare commits

...

8 Commits
main ... helm

Author SHA1 Message Date
René Zubcevic
386ebfe142 added modsec chart for webgoat behind modsecurity crs 2022-01-07 16:06:20 +01:00
René Zubcevic
ee31633822 paramterized additional things and tested on developer sandbox 2021-12-23 17:07:23 +01:00
René Zubcevic
4018212304 tested and verified version on CRC 2021-12-23 12:18:44 +01:00
René Zubcevic
833e09fced link to remote host hsqldb 2021-12-23 09:10:43 +01:00
René Zubcevic
f1f5c352df seperate apps 2021-12-23 09:09:21 +01:00
René Zubcevic
e58373ffff config added 2021-12-20 16:55:25 +01:00
René Zubcevic
ae02d98d37 template for openshift developer sandbox 2021-12-20 14:27:32 +01:00
René Zubcevic
3b55ef5ffe initial helm chart 2021-12-20 14:27:32 +01:00
21 changed files with 530 additions and 1 deletions

View File

@ -0,0 +1,54 @@
# Helm chart deployment on OpenShift K8S clusters
This helm chart can be used on a OpenShift Code Ready Container environment or an OpenShift Cloud Container environment.
With the OpenShift CRC (Code Ready Container) cluster you run an entire environment on your local machine. (> 4 vCPU, >8GB mem)
See the Red Hat documentation for general understanding of OpenShift. Make sure helm is installed as well.
https://developers.redhat.com/developer-sandbox
## CRC commands
crc config set cpus 6
crc config set memory 12288
crc setup
crc start
eval $(crc oc-env)
oc login -u developer https://api.crc.testing:6443
oc new-project demo-project
The example without modification uses *demo-project* as the project/namespace for installing WebGoat and WebWolf.
## Helm install this example on your local Code Ready Container environment
helm install goat1 ./webgoat
## Helm install on single node Developer Sandbox (cloud)
oc login --token=sha256~phDWy6Wm_oJQW6kmOHEbLkRdDIXU6b70hRVmdSYWolM --server=https://api.sandbox-m2.rz9k.p1.openshiftapps.com:6443
helm install --set namespace=renezubcevic-dev --set accessMode=ReadWriteOnce --set urlpostfix=.apps.sandbox-m2.rz9k.p1.openshiftapps.com goat1 ./webgoat
A code ready container looks the same for all developers on their local machine, but a developer sandbox requires other credentials from your account in the cloud and different namespace and urlpostfix and also a different access mode for the persistent storage.
Of course the token here is a fake.
## uninstall
helm uninstall goat1
The URL on a Code Ready Container is build from router name + namespace + default extension .apps-crc.testing:
+ [https://webgoat-1-goat-demo-project.apps-crc.testing/WebGoat](https://webgoat-1-goat-demo-project.apps-crc.testing/WebGoat)
+ [http://webwolf-1-wolf-demo-project.apps-crc.testing/WebWolf](http://webwolf-1-wolf-demo-project.apps-crc.testing/WebWolf)
## Explanation
deployment.yaml contains two K8S deployment elements. Both use the same Persistent Volume Claim and use the same Volume mapping.
They both use the same image but with other entrypoint and command arguments. The java.io.dir is also mapped to this persistent volume mapping. The number of pods is 1 for both WebGoat and WebWolf. WebGoat uses the WEBWOLF_HOST parameter to know where the external address of WebWolf is defined. WebWolf uses WEBGOAT_HOST to define the internal service address to WebGoat for connecting to the HSQL database
persistent-storage-claim.yaml contains the OpenShift K8S extension for requestig a volume with Read-Write access that will survive any pod replacements.
service.yaml defines the service ports for both WebGoat and WebWolf
route-goat defines an https endpoint toward the 8080 port. route-wolf defines an http port towards the 9090 port.

View File

@ -0,0 +1,23 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*.orig
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/

View File

@ -0,0 +1,9 @@
apiVersion: v2
name: modsec
description: ModSecurity Core Rule Set
type: application
version: 0.1.0
appVersion: "latest"

View File

@ -0,0 +1,18 @@
kind: ConfigMap
apiVersion: v1
metadata:
name: {{ .Values.modsec_server.name }}-configmap-modsec
namespace: {{ .Values.namespace }}
labels:
app.kubernetes.io/part-of: {{ .Values.modsec_server.name }}
data:
PARANOIA: '1'
EXECUTING_PARANOIA: '2'
ANOMALYIN: '5'
ANOMALYOUT: '5'
ALLOWED_METHODS: 'GET POST'
ALLOWED_REQUEST_CONTENT_TYPE: "text/xml|application/xml|text/plain"
MAX_FILE_SIZE: '5242880'
PORT: '8001'
RESTRICTED_EXTENSIONS: '.conf/'
BACKEND: 'http://{{ .Values.webgoat_server.name }}-service:8080'

View File

@ -0,0 +1,45 @@
kind: Deployment
apiVersion: apps/v1
metadata:
name: {{ .Values.modsec_server.name }}
namespace: {{ .Values.namespace }}
spec:
replicas: 1
selector:
matchLabels:
app: {{ .Values.modsec_server.name }}
template:
metadata:
labels:
app: {{ .Values.modsec_server.name }}
spec:
containers:
- resources:
limits:
memory: "2Gi"
cpu: "1"
requests:
memory: "1Gi"
cpu: "0.5"
name: modsec
ports:
- containerPort: 8001
protocol: TCP
image: {{ .Values.modsec_server.image }}
imagePullPolicy: Always
terminationMessagePolicy: File
envFrom:
- configMapRef:
name: {{ .Values.modsec_server.name }}-configmap-modsec
restartPolicy: Always
terminationGracePeriodSeconds: 30
dnsPolicy: ClusterFirst
securityContext: {}
schedulerName: default-scheduler
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 25%
maxSurge: 25%
revisionHistoryLimit: 10
progressDeadlineSeconds: 600

View File

@ -0,0 +1,16 @@
apiVersion: route.openshift.io/v1
kind: Route
metadata:
labels:
app: {{ .Values.modsec_server.name }}
name: {{ .Values.modsec_server.name }}-modsec
namespace: {{ .Values.namespace }}
spec:
path: /
port:
targetPort: 8001
to:
kind: Service
name: {{ .Values.modsec_server.name }}-service
weight: 100
wildcardPolicy: None

View File

@ -0,0 +1,16 @@
apiVersion: v1
kind: Service
metadata:
labels:
app: {{ .Values.modsec_server.name }}
name: {{ .Values.modsec_server.name }}-service
namespace: {{ .Values.namespace }}
spec:
ports:
- name: 8001-tcp
port: 8001
protocol: TCP
targetPort: 8001
selector:
app: {{ .Values.modsec_server.name }}
sessionAffinity: None

View File

@ -0,0 +1,13 @@
namespace: demo-project
urlpostfix: .apps-crc.testing
accessMode: ReadWriteMany
modsec_server:
name: modsec-1
#image: docker.io/franbuehler/modsecurity-crs-rp
#image: docker.io/owasp/modsecurity-crs
image: docker.io/chrira/modsecurity-crs-rp:openshift
webgoat_server:
name: webgoat-1

View File

@ -0,0 +1,23 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*.orig
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/

View File

@ -0,0 +1,9 @@
apiVersion: v2
name: webgoat
description: WebGoat Learning Environment
type: application
version: 0.1.0
appVersion: "8.2.3-SNAPSHOT"

View File

@ -0,0 +1,11 @@
kind: ConfigMap
apiVersion: v1
metadata:
name: {{ .Values.webwolf_server.name }}-configmap
namespace: {{ .Values.namespace }}
labels:
app.kubernetes.io/part-of: {{ .Values.webgoat_server.name }}
data:
TZ: 'Europe/Amsterdam'
WEBGOAT_HOST: {{ .Values.webgoat_server.name }}-service

View File

@ -0,0 +1,13 @@
kind: ConfigMap
apiVersion: v1
metadata:
name: {{ .Values.webgoat_server.name }}-configmap
namespace: {{ .Values.namespace }}
labels:
app.kubernetes.io/part-of: {{ .Values.webgoat_server.name }}
data:
TZ: 'Europe/Amsterdam'
EXCLUDE_CATEGORIES: 'CLIENT_SIDE'
EXCLUDE_LESSONS: 'SqlInjectionAdvanced'
WEBWOLF_HOST: '{{ .Values.webwolf_server.name }}-wolf-{{ .Values.namespace }}{{ .Values.urlpostfix }}'
WEBWOLF_PORT: '80'

View File

@ -0,0 +1,159 @@
kind: Deployment
apiVersion: apps/v1
metadata:
labels:
app.kubernetes.io/part-of: {{ .Values.webgoat_server.name }}
name: {{ .Values.webgoat_server.name }}
namespace: {{ .Values.namespace }}
spec:
replicas: 1
selector:
matchLabels:
app: {{ .Values.webgoat_server.name }}
template:
metadata:
labels:
app: {{ .Values.webgoat_server.name }}
spec:
volumes:
- name: webgoat-volume-1
persistentVolumeClaim:
claimName: {{ .Values.webgoat_server.name }}-pvc
containers:
- resources:
limits:
memory: "2Gi"
cpu: "1"
requests:
memory: "1Gi"
cpu: "0.5"
name: webgoat
ports:
- containerPort: 8080
protocol: TCP
#livenessProbe:
# failureThreshold: 3
# periodSeconds: 10
# httpGet:
# path: /WebGoat
# port: 8080
#readinessProbe:
# failureThreshold: 3
# periodSeconds: 10
# initialDelaySeconds: 60
## httpGet:
# path: /WebGoat
# port: 8080
image: {{ .Values.webgoat_server.image }}
command:
- 'java'
args: ["-Duser.home=/home/webgoat",
"--add-opens","java.base/java.lang=ALL-UNNAMED",
"--add-opens","java.base/java.util=ALL-UNNAMED",
"--add-opens","java.base/java.lang.reflect=ALL-UNNAMED",
"--add-opens","java.base/java.text=ALL-UNNAMED",
"--add-opens","java.desktop/java.beans=ALL-UNNAMED",
"--add-opens","java.desktop/java.awt.font=ALL-UNNAMED",
"--add-opens","java.base/sun.nio.ch=ALL-UNNAMED",
"--add-opens","java.base/java.io=ALL-UNNAMED",
"-Djava.io.tmpdir=/home/webgoat/.webgoat-{{ .Chart.AppVersion }}",
"-Dfile.encoding=UTF-8",
"-jar","/home/webgoat/webgoat.jar",
"--server.address=0.0.0.0"]
imagePullPolicy: Always
volumeMounts:
- name: webgoat-volume-1
mountPath: /home/webgoat/.webgoat-{{ .Chart.AppVersion }}
terminationMessagePolicy: File
envFrom:
- configMapRef:
name: {{ .Values.webgoat_server.name }}-configmap
- secretRef:
name: {{ .Values.webgoat_server.name }}-secret
restartPolicy: Always
terminationGracePeriodSeconds: 30
dnsPolicy: ClusterFirst
securityContext: {}
schedulerName: default-scheduler
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 25%
maxSurge: 25%
revisionHistoryLimit: 10
progressDeadlineSeconds: 600
---
kind: Deployment
apiVersion: apps/v1
metadata:
labels:
app.kubernetes.io/part-of: {{ .Values.webgoat_server.name }}
name: {{ .Values.webwolf_server.name }}
namespace: {{ .Values.namespace }}
spec:
replicas: 1
selector:
matchLabels:
app: {{ .Values.webwolf_server.name }}
template:
metadata:
labels:
app: {{ .Values.webwolf_server.name }}
spec:
volumes:
- name: webgoat-volume-1
persistentVolumeClaim:
claimName: {{ .Values.webgoat_server.name }}-pvc
containers:
- resources:
limits:
memory: "2Gi"
cpu: "1"
requests:
memory: "1Gi"
cpu: "0.5"
name: webwolf
ports:
- containerPort: 9090
protocol: TCP
#livenessProbe:
# failureThreshold: 3
# periodSeconds: 10
# httpGet:
# path: /WebWolf
# port: 9090
#readinessProbe:
#failureThreshold: 3
#periodSeconds: 10
#initialDelaySeconds: 100
#httpGet:
# path: /WebWolf
# port: 9090
image: {{ .Values.webwolf_server.image }}
command:
- 'java'
args: ["-Duser.home=/home/webgoat",
"-Djava.io.tmpdir=/home/webgoat/.webgoat-{{ .Chart.AppVersion }}",
"-Dfile.encoding=UTF-8",
"-jar","/home/webgoat/webwolf.jar",
"--server.address=0.0.0.0"]
imagePullPolicy: Always
volumeMounts:
- name: webgoat-volume-1
mountPath: /home/webgoat/.webgoat-{{ .Chart.AppVersion }}
terminationMessagePolicy: File
envFrom:
- configMapRef:
name: {{ .Values.webwolf_server.name }}-configmap
restartPolicy: Always
terminationGracePeriodSeconds: 30
dnsPolicy: ClusterFirst
securityContext: {}
schedulerName: default-scheduler
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 25%
maxSurge: 25%
revisionHistoryLimit: 10
progressDeadlineSeconds: 600

View File

@ -0,0 +1,13 @@
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: '{{ .Values.webgoat_server.name }}-pvc'
namespace: '{{ .Values.namespace }}'
spec:
accessModes:
- '{{ .Values.accessMode }}'
resources:
requests:
storage: 1Gi
#volumeName: pv0028
volumeMode: Filesystem

View File

@ -0,0 +1,19 @@
apiVersion: route.openshift.io/v1
kind: Route
metadata:
labels:
app: {{ .Values.webgoat_server.name }}
name: {{ .Values.webgoat_server.name }}-goat
namespace: {{ .Values.namespace }}
spec:
tls:
termination: edge
insecureEdgeTerminationPolicy: Redirect
path: /WebGoat
port:
targetPort: 8080
to:
kind: Service
name: {{ .Values.webgoat_server.name }}-service
weight: 100
wildcardPolicy: None

View File

@ -0,0 +1,16 @@
apiVersion: route.openshift.io/v1
kind: Route
metadata:
labels:
app: {{ .Values.webwolf_server.name }}
name: {{ .Values.webwolf_server.name }}-wolf
namespace: {{ .Values.namespace }}
spec:
path: /
port:
targetPort: 9090
to:
kind: Service
name: {{ .Values.webwolf_server.name }}-service
weight: 100
wildcardPolicy: None

View File

@ -0,0 +1,7 @@
apiVersion: v1
kind: Secret
metadata:
name: {{ .Values.webgoat_server.name }}-secret
namespace: {{ .Values.namespace }}
stringData:
ADMIN_PASSWORD: admin

View File

@ -0,0 +1,39 @@
apiVersion: v1
kind: Service
metadata:
labels:
app: {{ .Values.webgoat_server.name }}
app.kubernetes.io/part-of: {{ .Values.webgoat_server.name }}
name: {{ .Values.webgoat_server.name }}-service
namespace: {{ .Values.namespace }}
spec:
ports:
- name: 8080-tcp
port: 8080
protocol: TCP
targetPort: 8080
- name: 9001-tcp
port: 9001
protocol: TCP
targetPort: 9001
selector:
app: {{ .Values.webgoat_server.name }}
sessionAffinity: None
---
apiVersion: v1
kind: Service
metadata:
labels:
app: {{ .Values.webwolf_server.name }}
app.kubernetes.io/part-of: {{ .Values.webgoat_server.name }}
name: {{ .Values.webwolf_server.name }}-service
namespace: {{ .Values.namespace }}
spec:
ports:
- name: 9090-tcp
port: 9090
protocol: TCP
targetPort: 9090
selector:
app: {{ .Values.webwolf_server.name }}
sessionAffinity: None

View File

@ -0,0 +1,14 @@
namespace: demo-project
urlpostfix: .apps-crc.testing
accessMode: ReadWriteMany
webgoat_server:
name: webgoat-1
image: docker.io/webgoat/goatandwolf:openshift
webwolf_server:
name: webwolf-1
image: docker.io/webgoat/goatandwolf:openshift

View File

@ -65,13 +65,24 @@ public class DataSourceResolver {
@Value("${webgoat.actuator.configprops.path:/configprops}")
private String configPropsPath;
@Value("${hsqldb.address}")
private String hsqlHost;
@Autowired
ApplicationContext ctx;
@Bean
@DependsOn("dsConfigDiscovery")
public DataSource dataSource(DataSourceProperties dataSourceProperties) {
DriverManagerDataSource driverManagerDataSource = new DriverManagerDataSource(dataSourceProperties.getUrl());
String connectString = dataSourceProperties.getUrl();
/**
* Replace the server address as reported by webgoat by the one that is given
* to WebWolf as the address of WebGoat. In case it doesn't run locally.
*/
if (connectString!=null) {
connectString = connectString.replace("0.0.0.0", hsqlHost);
}
DriverManagerDataSource driverManagerDataSource = new DriverManagerDataSource(connectString);
driverManagerDataSource.setDriverClassName(dataSourceProperties.getDriverClassName());
return driverManagerDataSource;
}

View File

@ -6,6 +6,7 @@ server.port=${WEBWOLF_PORT:9090}
server.address=${WEBWOLF_HOST:127.0.0.1}
server.servlet.session.cookie.name=WEBWOLFSESSION
server.servlet.session.timeout=6000
hsqldb.address=${WEBGOAT_HOST:127.0.0.1}
spring.jpa.properties.hibernate.default_schema=CONTAINER
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.HSQLDialect