diff --git a/apache-mod-mellon/.helmignore b/apache-mod-mellon/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/apache-mod-mellon/.helmignore @@ -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/ diff --git a/apache-mod-mellon/Chart.yaml b/apache-mod-mellon/Chart.yaml new file mode 100644 index 0000000..44027f1 --- /dev/null +++ b/apache-mod-mellon/Chart.yaml @@ -0,0 +1,6 @@ +apiVersion: v2 +name: apache-mod-mellon +description: A Helm chart for deploying an Apache HTTPd configured with the mod_mellon +type: application +version: 0.2.0 +appVersion: "1.16.0" diff --git a/apache-mod-mellon/templates/_helpers.tpl b/apache-mod-mellon/templates/_helpers.tpl new file mode 100644 index 0000000..1962bc8 --- /dev/null +++ b/apache-mod-mellon/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "apache-mod-mellon.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "apache-mod-mellon.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "apache-mod-mellon.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "apache-mod-mellon.labels" -}} +helm.sh/chart: {{ include "apache-mod-mellon.chart" . }} +{{ include "apache-mod-mellon.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "apache-mod-mellon.selectorLabels" -}} +app.kubernetes.io/name: {{ include "apache-mod-mellon.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "apache-mod-mellon.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "apache-mod-mellon.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/apache-mod-mellon/templates/apache-config-mod-mellon.yaml b/apache-mod-mellon/templates/apache-config-mod-mellon.yaml new file mode 100644 index 0000000..e23a574 --- /dev/null +++ b/apache-mod-mellon/templates/apache-config-mod-mellon.yaml @@ -0,0 +1,20 @@ +apiVersion: v1 +kind: Secret +type: Opaque +metadata: + annotations: + labels: + {{- include "apache-mod-mellon.labels" . | nindent 4 }}-apache + name: {{ include "apache-mod-mellon.fullname" . }}-mod-mellon +data: + mellon.key: | + {{ .Values.mellon_config.private_key | b64enc | quote }} + + mellon.cert: | + {{ .Values.mellon_config.certificate | b64enc | quote }} + + metadata-signing-cert.pem: | + {{ .Values.mellon_config.metadata_signing_cert | b64enc | quote }} + + metadata-idps.xml: | + {{ .Values.mellon_config.idps_metadata | b64enc | quote }} \ No newline at end of file diff --git a/apache-mod-mellon/templates/apache-config-virtualhost.yaml b/apache-mod-mellon/templates/apache-config-virtualhost.yaml new file mode 100644 index 0000000..f68f0fa --- /dev/null +++ b/apache-mod-mellon/templates/apache-config-virtualhost.yaml @@ -0,0 +1,104 @@ +apiVersion: v1 +kind: Secret +metadata: + annotations: + labels: + {{- include "apache-mod-mellon.labels" . | nindent 4 }}-apache + name: {{ include "apache-mod-mellon.fullname" . }}-virtualhost +data: + 000-default.conf: | + + ServerName {{ .Values.hostname }} + UseCanonicalName On + ProxyTimeout 300 + ServerAdmin webmaster@localhost + DocumentRoot /var/www/html + + ErrorLog /dev/stderr + CustomLog /dev/stdout combined + + + Options -Indexes + + MellonEnable "info" + MellonSecureCookie On + MellonUser eppn + MellonMergeEnvVars On + MellonSubjectConfirmationDataAddressCheck Off + MellonSPPrivateKeyFile /etc/mod-mellon-config/mellon.key + MellonSPCertFile /etc/mod-mellon-config/mellon.cert + MellonSPentityId {{ .Values.mellon_config.entity_id }} + MellonOrganizationName "{{ .Values.mellon_config.organization_url }}" + MellonOrganizationURL "{{ .Values.mellon_config.organization_url }}" + MellonIdPMetadataFile /etc/mod-mellon-config/metadata-idps.xml + MellonDiscoveryURL "{{ .Values.mellon_config.discovery_url }}" + MellonIdPCAFile /etc/mod-mellon-config/metadata-signing-cert.pem + MellonIdPPublicKeyFile /etc/mod-mellon-config/metadata-signing-cert.pem + MellonProbeDiscoveryTimeout 1 + MellonSetEnv "MAIL" "{{ .Values.mellon_config.set_env.mail }}" + MellonSetEnv "EPPN" "{{ .Values.mellon_config.set_env.eppn }}" + MellonSetEnv "CN" "{{ .Values.mellon_config.set_env.cn }}" + MellonSetEnv "O" "{{ .Values.mellon_config.set_env.o }}" + MellonSetEnv "SN" "{{ .Values.mellon_config.set_env.sn }}" + MellonSetEnv "GIVEN_NAME" "{{ .Values.mellon_config.set_env.given_name }}" + + MellonEndpointPath /mellon + + # it is this proxy's responsability to make sure the value of these headers are legit + # See a list of headers used by geOrchestra here: + # https://github.com/georchestra/georchestra/blob/master/commons/src/main/java/org/georchestra/commons/security/SecurityHeaders.java#L41-L67 + RequestHeader unset sec-georchestra-preauthenticated + RequestHeader unset sec-mellon-name-id + RequestHeader unset sec-username + RequestHeader unset sec-name + RequestHeader unset sec-givenname + RequestHeader unset sec-email + RequestHeader unset sec-org + RequestHeader unset sec-proxy + RequestHeader unset sec-user + RequestHeader unset sec-organization + RequestHeader unset sec-userid + RequestHeader unset sec-lastupdated + RequestHeader unset sec-roles + RequestHeader unset sec-firstname + RequestHeader unset sec-lastname + RequestHeader unset sec-tel + RequestHeader unset sec-orgid + RequestHeader unset sec-orgname + RequestHeader unset sec-org-lastupdated + RequestHeader unset imp-roles + RequestHeader unset imp-username + + {{ .Values.apache_auth_headers_type }} set sec-georchestra-preauthenticated true "expr=-n env('MELLON_NAME_ID')" + {{ .Values.apache_auth_headers_type }} set sec-mellon-name-id "expr={base64}%{base64:%{env:MELLON_NAME_ID}}" "expr=-n env('MELLON_NAME_ID')" + {{ .Values.apache_auth_headers_type }} set preauth-username "expr={base64}%{base64:%{env:MELLON_EPPN}}" "expr=-n env('MELLON_EPPN')" + {{ .Values.apache_auth_headers_type }} set preauth-email "expr={base64}%{base64:%{env:MELLON_MAIL}}" "expr=-n env('MELLON_MAIL')" + {{ .Values.apache_auth_headers_type }} set preauth-org "expr={base64}%{base64:%{env:MELLON_O}}" "expr=-n env('MELLON_O')" + {{ .Values.apache_auth_headers_type }} set preauth-firstname "expr={base64}%{base64:%{env:MELLON_GIVEN_NAME}}" "expr=-n env('MELLON_GIVEN_NAME')" + {{ .Values.apache_auth_headers_type }} set preauth-lastname "expr={base64}%{base64:%{env:MELLON_SN}}" "expr=-n env('MELLON_SN')" + + {{- if .Values.georchestra_proxypass_endpoint -}} + ProxyPass "{{ .Values.georchestra_proxypass_endpoint }}" + ProxyPassReverse "{{ .Values.georchestra_proxypass_endpoint }}" + ProxyPreserveHost On + {{- end }} + + RewriteEngine on + RewriteCond %{QUERY_STRING} ^$ + RewriteCond %{REQUEST_METHOD} =GET + RewriteCond %{REQUEST_URI} ^/login$ + RewriteRule /login /login/mellon [R,L] + RewriteCond %{ENV:MELLON_NAME_ID} !^$ + RewriteRule /logout /mellon/logout?ReturnTo={{ .Values.hostname }} + + + + + AuthType Mellon + MellonEnable auth + Require valid-user + RewriteEngine on + RewriteRule (.*) / [R] + + + \ No newline at end of file diff --git a/apache-mod-mellon/templates/apache-depl.yaml b/apache-mod-mellon/templates/apache-depl.yaml new file mode 100644 index 0000000..535e6cf --- /dev/null +++ b/apache-mod-mellon/templates/apache-depl.yaml @@ -0,0 +1,33 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "apache-mod-mellon.fullname" . }}-apache-depl + labels: + {{- include "apache-mod-mellon.labels" . | nindent 4 }}-apache-depl +spec: + selector: + matchLabels: + {{- include "apache-mod-mellon.selectorLabels" . | nindent 6 }}-apache-depl + template: + metadata: + labels: + {{- include "apache-mod-mellon.selectorLabels" . | nindent 8 }}-apache-depl + spec: + containers: + - name: apache + image: ghcr.io/camptocamp/inrae-docker-images/apache-mod-mellon:2.4 + imagePullPolicy: Always + volumeMounts: + - name: virtualhost-config + mountPath: /etc/apache2/sites-available/000-default.conf + subPath: 000-default.conf + - name: mod-mellon-config + mountPath: /etc/mod-mellon-config + volumes: + - name: mod-mellon-config + configMap: + name: {{ include "apache-mod-mellon.fullname" . }}-mod-mellon + - name: virtualhost-config + configMap: + name: {{ include "apache-mod-mellon.fullname" . }}-virtualhost + diff --git a/apache-mod-mellon/templates/apache-svc.yaml b/apache-mod-mellon/templates/apache-svc.yaml new file mode 100644 index 0000000..ab74339 --- /dev/null +++ b/apache-mod-mellon/templates/apache-svc.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "apache-mod-mellon.fullname" . }}-apache-svc + labels: + {{- include "apache-mod-mellon.labels" . | nindent 4 }}-apache-svc +spec: + ports: + - port: 80 + targetPort: 80 + protocol: TCP + selector: + {{- include "apache-mod-mellon.selectorLabels" . | nindent 4 }}-apache-depl diff --git a/apache-mod-mellon/values.yaml b/apache-mod-mellon/values.yaml new file mode 100644 index 0000000..ad45cb4 --- /dev/null +++ b/apache-mod-mellon/values.yaml @@ -0,0 +1,37 @@ +hostname: https://inrae.sandbox.apps.gs-fr-prod.camptocamp.com:443 +# Enable for ProxyPass mode +#georchestra_proxypass_endpoint: http://georchestra-gateway-svc:8080/ +# Can be RequestHeader when in ProxyPass mode +apache_auth_headers_type: "Header" +mellon_config: + entity_id: https://poc-renater.inrae.sandbox.apps.gs-fr-prod.camptocamp.com/ + certificate: | + -----BEGIN CERTIFICATE----- + .... + -----END CERTIFICATE----- + + private_key: | + -----BEGIN PRIVATE KEY----- + .... + -----END PRIVATE KEY----- + metadata_signing_cert: | + -----BEGIN CERTIFICATE----- + .... + -----END CERTIFICATE----- + idps_metadata: | + + .... + + + # * https://discovery.renater.fr/test/WAYF?cru=yes for test + # * https://discovery.renater.fr/renater/WAYF?cru=yes for prod + discovery_url: https://discovery.renater.fr/test/WAYF?cru=yes + organization_url: https://www.inrae.fr + organization_name: INRAE + set_env: + mail: urn:oid:0.9.2342.19200300.100.1.3 + eppn: urn:oid:1.3.6.1.4.1.5923.1.1.1.6 + cn: urn:oid:2.5.4.3 + o: urn:oid:2.5.4.10 + sn: urn:oid:2.5.4.4 + given_name: urn:oid:2.5.4.42