chore(immich): hardening of security according to audit report by Polaris

This commit is contained in:
Tommy 2024-11-11 21:11:58 +01:00
parent 556acce1b2
commit d3dca67841
Signed by: tommy
SSH key fingerprint: SHA256:1LWgQT3QPHIT29plS8jjXc3S1FcE/4oGvsx3Efxs6Uc
6 changed files with 204 additions and 24 deletions

View file

@ -2,10 +2,11 @@ apiVersion: v2
name: immich
description: |
High-performance self-hosted photo and video management
# renovate: image=ghcr.io/immich-app/immich-server
appVersion: 1.105.1
type: application
icon: https://avatars.githubusercontent.com/u/109746326?s=200&v=4
version: 0.1.16
version: 1.0.0
maintainers:
- name: Tommy Skaug
email: tommy@skaug.me

View file

@ -0,0 +1,78 @@
config:
externalUrl: https://photos.example.com/
machineLearningUrl: http://immich-machine-learning.home.svc.cluster.local:3003
image:
repository: ghcr.io/immich-app/immich-server
envSecretName: immich-secret
library:
persistence:
existingClaim: immich
configuration:
trash:
enabled: false
days: 30
storageTemplate:
enabled: true
template: "{{y}}/{{y}}-{{MM}}-{{dd}}/{{filename}}"
microservices:
securityContext: {}
resources:
limits:
memory: "3Gi"
cpu: "1000m"
requests:
cpu: 100m
memory: 100Mi
server:
securityContext: {}
resources:
limits:
memory: "3Gi"
cpu: "1000m"
requests:
cpu: 100m
memory: 100Mi
machineLearning:
persistence:
accessMode: ReadWriteOnce
size: 5Gi
image:
repository: ghcr.io/immich-app/immich-machine-learning
tag: v1.120.1
securityContext: {}
resources:
limits:
memory: "3Gi"
cpu: "1000m"
requests:
cpu: 100m
memory: 100Mi
initContainers:
dbInit:
image:
repository: ghcr.io/onedr0p/postgres-init
tag: "16"
existingSecretName: immich-postgres-init-secret
pgvecto:
image:
repository: tensorchord/pgvecto-rs
tag: "pg16-v0.2.1-rootless"
existingSecretName: immich-postgres-init-secret
metrics:
enabled: true
port: 9001
redis:
host: dragonfly.databases.svc.cluster.local
port: 6397
postgres:
host: postgres-pgvectors-rw.databases.svc.cluster.local

View file

@ -1,4 +1,3 @@
---
apiVersion: batch/v1
kind: Job
metadata:
@ -9,22 +8,37 @@ spec:
template:
spec:
restartPolicy: Never
automountServiceAccountToken: false
priorityClassName: "high-priority"
containers:
- name: general-db-init
image: "{{ .Values.initContainers.dbInit.image.repository }}:{{ .Values.initContainers.dbInit.image.tag }}"
imagePullPolicy: IfNotPresent
env:
- name: INIT_POSTGRES_HOST
value: {{ .Values.postgres.host }}
- name: INIT_POSTGRES_HOST
value: {{ .Values.postgres.host }}
envFrom:
- secretRef:
name: {{ .Values.initContainers.dbInit.existingSecretName }}
securityContext:
runAsUser: 1000
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
resources:
requests:
memory: "512Mi"
cpu: "250m"
limits:
memory: "1Gi"
cpu: "500m"
- name: pgvecto-db-init
command: [ "bin/sh", "-c", "psql -a -f /initdb/create-extensions.sql" ]
image: "{{ .Values.initContainers.pgvecto.image.repository }}:{{ .Values.initContainers.pgvecto.image.tag }}"
imagePullPolicy: IfNotPresent
volumeMounts:
- name: pgvector-initdb
mountPath: /initdb
readOnly: false
readOnly: true
env:
- name: PGPASSWORD
valueFrom:
@ -40,8 +54,19 @@ spec:
key: INIT_POSTGRES_DBNAME
- name: PGHOST
value: {{ .Values.postgres.host }}
securityContext:
runAsUser: 1000
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
resources:
requests:
memory: "512Mi"
cpu: "250m"
limits:
memory: "1Gi"
cpu: "500m"
volumes:
- name: pgvector-initdb
configMap:
name: {{ include "immich.fullname" . }}-pgvector-initdb
backoffLimit: 3
backoffLimit: 3

View file

@ -1,4 +1,3 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
@ -17,14 +16,30 @@ spec:
labels:
app: {{ include "immich.fullname" . }}-machine-learning
spec:
priorityClassName: "high-priority"
automountServiceAccountToken: false
topologySpreadConstraints:
- maxSkew: 1
topologyKey: "topology.kubernetes.io/zone"
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
app: {{ include "immich.fullname" . }}-machine-learning
securityContext:
{{- toYaml .Values.machineLearning.securityContext | nindent 8 }}
runAsUser: 1000
runAsNonRoot: true
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
containers:
- name: immich-machine-learning
env:
{{- include "immich.envs" . | nindent 10 }}
image: {{ .Values.machineLearning.image.repository }}:{{ .Values.machineLearning.image.tag }}
imagePullPolicy: IfNotPresent
imagePullPolicy: Always
securityContext:
runAsUser: 1000
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
livenessProbe:
failureThreshold: 3
httpGet:
@ -35,9 +50,9 @@ spec:
successThreshold: 1
timeoutSeconds: 1
ports:
- containerPort: 3003
name: http
protocol: TCP
- containerPort: 3003
name: http
protocol: TCP
readinessProbe:
failureThreshold: 3
httpGet:
@ -52,10 +67,20 @@ spec:
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /cache
name: cache
- mountPath: /cache
name: cache
serviceAccountName: {{ include "immich.fullname" . }}
volumes:
- name: cache
persistentVolumeClaim:
claimName: {{ include "immich.fullname" . }}-machine-learning-cache
- name: cache
persistentVolumeClaim:
claimName: {{ include "immich.fullname" . }}-machine-learning-cache
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: {{ include "immich.fullname" . }}-machine-learning-pdb
spec:
minAvailable: 1
selector:
matchLabels:
app: {{ include "immich.fullname" . }}-machine-learning

View file

@ -1,4 +1,3 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
@ -15,9 +14,20 @@ spec:
labels:
app: {{ include "immich.fullname" . }}-microservices
spec:
priorityClassName: "high-priority"
automountServiceAccountToken: false
topologySpreadConstraints:
- maxSkew: 1
topologyKey: "topology.kubernetes.io/zone"
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
app: {{ include "immich.fullname" . }}-microservices
securityContext:
{{- toYaml .Values.microservices.securityContext | nindent 8 }}
automountServiceAccountToken: true
runAsUser: 1000
runAsNonRoot: true
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
containers:
- name: immich-microservices
args:
@ -27,7 +37,11 @@ spec:
env:
{{- include "immich.envs" . | nindent 10 }}
image: {{ .Values.image.repository }}:v{{ .Chart.AppVersion }}
imagePullPolicy: IfNotPresent
imagePullPolicy: Always
securityContext:
runAsUser: 1000
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
livenessProbe:
failureThreshold: 3
periodSeconds: 10
@ -65,3 +79,13 @@ spec:
- name: library
persistentVolumeClaim:
claimName: {{ .Values.library.persistence.existingClaim }}
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: {{ include "immich.fullname" . }}-microservices-pdb
spec:
minAvailable: 1
selector:
matchLabels:
app: {{ include "immich.fullname" . }}-microservices

View file

@ -1,4 +1,3 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
@ -15,8 +14,22 @@ spec:
labels:
app: {{ include "immich.fullname" . }}-server
spec:
priorityClassName: "high-priority"
automountServiceAccountToken: false
topologySpreadConstraints:
- maxSkew: 1
topologyKey: "topology.kubernetes.io/zone"
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
app: {{ include "immich.fullname" . }}-server
securityContext:
{{- toYaml .Values.server.securityContext | nindent 8 }}
runAsUser: 1000
runAsNonRoot: true
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]
containers:
- name: immich-server
args:
@ -26,7 +39,11 @@ spec:
env:
{{- include "immich.envs" . | nindent 10 }}
image: {{ .Values.image.repository }}:v{{ .Chart.AppVersion }}
imagePullPolicy: IfNotPresent
imagePullPolicy: Always
securityContext:
runAsUser: 1000
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
livenessProbe:
failureThreshold: 3
httpGet:
@ -64,3 +81,13 @@ spec:
- name: library
persistentVolumeClaim:
claimName: {{ .Values.library.persistence.existingClaim }}
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: {{ include "immich.fullname" . }}-server-pdb
spec:
minAvailable: 1
selector:
matchLabels:
app: {{ include "immich.fullname" . }}-server