newServer
This commit is contained in:
+41
@@ -0,0 +1,41 @@
|
|||||||
|
name: Release Charts
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
release:
|
||||||
|
runs-on: [self-hosted, Linux, X64]
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Configure Git
|
||||||
|
run: |
|
||||||
|
git config user.name "$GITHUB_ACTOR"
|
||||||
|
git config user.email "$GITHUB_ACTOR@users.noreply.github.com"
|
||||||
|
|
||||||
|
- name: Install Helm
|
||||||
|
uses: azure/setup-helm@v3
|
||||||
|
with:
|
||||||
|
version: v3.14.0
|
||||||
|
|
||||||
|
# https://github.com/helm/chart-releaser-action/issues/74
|
||||||
|
- name: Add repositories
|
||||||
|
run: |
|
||||||
|
for dir in $(ls -d charts/*/); do
|
||||||
|
helm dependency list $dir 2> /dev/null | tail +2 | head -n -1 | awk '{ print "helm repo add " $1 " " $3 }' | while read cmd; do $cmd; done
|
||||||
|
done
|
||||||
|
|
||||||
|
- name: Run chart-releaser
|
||||||
|
uses: helm/chart-releaser-action@v1.6.0
|
||||||
|
env:
|
||||||
|
CR_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
|
||||||
|
with:
|
||||||
|
charts_dir: charts
|
||||||
|
skip_existing: true
|
||||||
+46
@@ -0,0 +1,46 @@
|
|||||||
|
name: Test setup script
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
paths:
|
||||||
|
- 'docker-compose/**'
|
||||||
|
- '.github/workflows/test.yml'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
name: Test setup script
|
||||||
|
runs-on: [self-hosted, Linux]
|
||||||
|
steps:
|
||||||
|
- name: Login to GitHub container registry
|
||||||
|
uses: docker/login-action@v2
|
||||||
|
with:
|
||||||
|
registry: ghcr.io
|
||||||
|
username: ${{ github.actor }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
- name: Create working directory
|
||||||
|
run: mkdir temp
|
||||||
|
- name: Run setup script
|
||||||
|
env:
|
||||||
|
DEFGUARD_DOMAIN: "id.localhost"
|
||||||
|
DEFGUARD_ENROLLMENT_DOMAIN: "enrollment.localhost"
|
||||||
|
DEFGUARD_VPN_NAME: "test_location"
|
||||||
|
DEFGUARD_VPN_IP: "10.0.60.1/24"
|
||||||
|
DEFGUARD_VPN_GATEWAY_IP: "10.20.20.40"
|
||||||
|
DEFGUARD_VPN_GATEWAY_PORT: "50050"
|
||||||
|
CORE_IMAGE_TAG: latest
|
||||||
|
PROXY_IMAGE_TAG: latest
|
||||||
|
GATEWAY_IMAGE_TAG: latest
|
||||||
|
working-directory: temp
|
||||||
|
run: curl --proto '=https' --tlsv1.2 -sSf -L https://raw.githubusercontent.com/DefGuard/deployment/main/docker-compose/setup.sh | bash -s - --non-interactive
|
||||||
|
- name: Sleep for 10 seconds
|
||||||
|
working-directory: temp
|
||||||
|
run: sleep 10s
|
||||||
|
- name: Test defguard is available
|
||||||
|
working-directory: temp
|
||||||
|
run: curl -f http://id.localhost/api/v1/health
|
||||||
|
- name: Stop compose stack
|
||||||
|
if: always()
|
||||||
|
working-directory: temp
|
||||||
|
run: docker-compose down
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
docker-compose/.env
|
||||||
|
docker-compose/.volumes
|
||||||
|
.idea
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
Copyright 2023 teonite ventures sp. z o.o. (teonite)
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
<p align="center">
|
||||||
|
<img src="docs/header.png" alt="defguard">
|
||||||
|
</p>
|
||||||
|
|
||||||
|
# Defguard deployment
|
||||||
|
|
||||||
|
Check our [documentation](https://defguard.gitbook.io/defguard/features/setting-up-your-instance) for deployment
|
||||||
|
instructions.
|
||||||
|
|
||||||
|
## Community and Support
|
||||||
|
|
||||||
|
Find us on Matrix: [#defguard:teonite.com](https://matrix.to/#/#defguard:teonite.com)
|
||||||
|
|
||||||
|
## Contribution
|
||||||
|
|
||||||
|
Please review the [Contributing guide](https://defguard.gitbook.io/defguard/for-developers/contributing) for information on how to get started contributing to the project. You might also find our [environment setup guide](https://defguard.gitbook.io/defguard/for-developers/dev-env-setup) handy.
|
||||||
@@ -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/
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
apiVersion: v2
|
||||||
|
name: defguard-proxy
|
||||||
|
description: Defguard proxy is a public-facing proxy for core defguard service
|
||||||
|
|
||||||
|
type: application
|
||||||
|
version: 0.3.5
|
||||||
|
appVersion: 0.5.0
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
1. Get the application URL by running these commands:
|
||||||
|
{{- if .Values.ingress.enabled }}
|
||||||
|
{{- range $host := .Values.ingress.hosts }}
|
||||||
|
http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host }}/
|
||||||
|
{{- end }}
|
||||||
|
{{- else if contains "NodePort" .Values.service.type }}
|
||||||
|
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "defguard-proxy.fullname" . }})
|
||||||
|
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
|
||||||
|
echo http://$NODE_IP:$NODE_PORT
|
||||||
|
{{- else if contains "LoadBalancer" .Values.service.type }}
|
||||||
|
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
|
||||||
|
You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "defguard-proxy.fullname" . }}'
|
||||||
|
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "defguard-proxy.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
|
||||||
|
echo http://$SERVICE_IP:{{ .Values.service.port }}
|
||||||
|
{{- else if contains "ClusterIP" .Values.service.type }}
|
||||||
|
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "defguard-proxy.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
|
||||||
|
export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
|
||||||
|
echo "Visit http://127.0.0.1:8080 to use your application"
|
||||||
|
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT
|
||||||
|
{{- end }}
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
{{/*
|
||||||
|
Expand the name of the chart.
|
||||||
|
*/}}
|
||||||
|
{{- define "defguard-proxy.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 "defguard-proxy.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 "defguard-proxy.chart" -}}
|
||||||
|
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Common labels
|
||||||
|
*/}}
|
||||||
|
{{- define "defguard-proxy.labels" -}}
|
||||||
|
helm.sh/chart: {{ include "defguard-proxy.chart" . }}
|
||||||
|
{{ include "defguard-proxy.selectorLabels" . }}
|
||||||
|
{{- if .Chart.AppVersion }}
|
||||||
|
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||||
|
{{- end }}
|
||||||
|
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Selector labels
|
||||||
|
*/}}
|
||||||
|
{{- define "defguard-proxy.selectorLabels" -}}
|
||||||
|
app.kubernetes.io/name: {{ include "defguard-proxy.name" . }}
|
||||||
|
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Create the name of the service account to use
|
||||||
|
*/}}
|
||||||
|
{{- define "defguard-proxy.serviceAccountName" -}}
|
||||||
|
{{- if .Values.serviceAccount.create }}
|
||||||
|
{{- default (include "defguard-proxy.fullname" .) .Values.serviceAccount.name }}
|
||||||
|
{{- else }}
|
||||||
|
{{- default "default" .Values.serviceAccount.name }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: {{ include "defguard-proxy.fullname" . }}-config
|
||||||
|
labels:
|
||||||
|
{{- include "defguard-proxy.labels" . | nindent 4 }}
|
||||||
|
data:
|
||||||
|
DEFGUARD_PROXY_HTTP_PORT: {{ .Values.service.ports.http | quote }}
|
||||||
|
DEFGUARD_PROXY_GRPC_PORT: {{ .Values.service.ports.grpc | quote }}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: {{ include "defguard-proxy.fullname" . }}
|
||||||
|
labels:
|
||||||
|
{{- include "defguard-proxy.labels" . | nindent 4 }}
|
||||||
|
spec:
|
||||||
|
{{- if not .Values.autoscaling.enabled }}
|
||||||
|
replicas: {{ .Values.replicaCount }}
|
||||||
|
{{- end }}
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
{{- include "defguard-proxy.selectorLabels" . | nindent 6 }}
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
{{- with .Values.podAnnotations }}
|
||||||
|
annotations:
|
||||||
|
{{- toYaml . | nindent 8 }}
|
||||||
|
{{- end }}
|
||||||
|
labels:
|
||||||
|
{{- include "defguard-proxy.selectorLabels" . | nindent 8 }}
|
||||||
|
spec:
|
||||||
|
{{- with .Values.imagePullSecrets }}
|
||||||
|
imagePullSecrets:
|
||||||
|
{{- toYaml . | nindent 8 }}
|
||||||
|
{{- end }}
|
||||||
|
serviceAccountName: {{ include "defguard-proxy.serviceAccountName" . }}
|
||||||
|
securityContext:
|
||||||
|
{{- toYaml .Values.podSecurityContext | nindent 8 }}
|
||||||
|
containers:
|
||||||
|
- name: {{ .Chart.Name }}
|
||||||
|
envFrom:
|
||||||
|
- configMapRef:
|
||||||
|
name: {{ include "defguard-proxy.fullname" . }}-config
|
||||||
|
securityContext:
|
||||||
|
{{- toYaml .Values.securityContext | nindent 12 }}
|
||||||
|
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
|
||||||
|
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
containerPort: {{ .Values.service.ports.http }}
|
||||||
|
protocol: TCP
|
||||||
|
- name: grpc
|
||||||
|
containerPort: {{ .Values.service.ports.grpc }}
|
||||||
|
protocol: TCP
|
||||||
|
livenessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /api/v1/health
|
||||||
|
port: http
|
||||||
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /api/v1/health
|
||||||
|
port: http
|
||||||
|
resources:
|
||||||
|
{{- toYaml .Values.resources | nindent 12 }}
|
||||||
|
{{- with .Values.nodeSelector }}
|
||||||
|
nodeSelector:
|
||||||
|
{{- toYaml . | nindent 8 }}
|
||||||
|
{{- end }}
|
||||||
|
{{- with .Values.affinity }}
|
||||||
|
affinity:
|
||||||
|
{{- toYaml . | nindent 8 }}
|
||||||
|
{{- end }}
|
||||||
|
{{- with .Values.tolerations }}
|
||||||
|
tolerations:
|
||||||
|
{{- toYaml . | nindent 8 }}
|
||||||
|
{{- end }}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
annotations:
|
||||||
|
traefik.ingress.kubernetes.io/service.serversscheme: h2c
|
||||||
|
name: {{ include "defguard-proxy.fullname" . }}-grpc
|
||||||
|
labels:
|
||||||
|
{{- include "defguard-proxy.labels" . | nindent 4 }}
|
||||||
|
spec:
|
||||||
|
type: {{ .Values.service.type }}
|
||||||
|
ports:
|
||||||
|
- port: {{ .Values.service.ports.grpc }}
|
||||||
|
targetPort: grpc
|
||||||
|
protocol: TCP
|
||||||
|
name: grpc
|
||||||
|
selector:
|
||||||
|
{{- include "defguard-proxy.selectorLabels" . | nindent 4 }}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
{{- if .Values.ingress.grpc.enabled -}}
|
||||||
|
{{- $fullName := include "defguard-proxy.fullname" . -}}
|
||||||
|
{{- if and .Values.ingress.grpc.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }}
|
||||||
|
{{- if not (hasKey .Values.ingress.grpc.annotations "kubernetes.io/ingress.class") }}
|
||||||
|
{{- $_ := set .Values.ingress.grpc.annotations "kubernetes.io/ingress.class" .Values.ingress.grpc.className}}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}}
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
|
||||||
|
apiVersion: networking.k8s.io/v1beta1
|
||||||
|
{{- else -}}
|
||||||
|
apiVersion: extensions/v1beta1
|
||||||
|
{{- end }}
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
name: {{ $fullName }}-grpc
|
||||||
|
labels:
|
||||||
|
{{- include "defguard-proxy.labels" . | nindent 4 }}
|
||||||
|
{{- with .Values.ingress.grpc.annotations }}
|
||||||
|
annotations:
|
||||||
|
{{- toYaml . | nindent 4 }}
|
||||||
|
{{- end }}
|
||||||
|
spec:
|
||||||
|
{{- if and .Values.ingress.grpc.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }}
|
||||||
|
ingressClassName: {{ .Values.ingress.grpc.className }}
|
||||||
|
{{- end }}
|
||||||
|
{{- if .Values.ingress.grpc.tls }}
|
||||||
|
tls:
|
||||||
|
- hosts:
|
||||||
|
- {{ .Values.ingress.grpc.host | quote }}
|
||||||
|
secretName: {{ printf "%s-grpc-tls" .Values.ingress.grpc.host }}
|
||||||
|
{{- end }}
|
||||||
|
rules:
|
||||||
|
- host: {{ .Values.ingress.grpc.host | quote }}
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
{{- if semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion }}
|
||||||
|
pathType: ImplementationSpecific
|
||||||
|
{{- end }}
|
||||||
|
backend:
|
||||||
|
{{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }}
|
||||||
|
service:
|
||||||
|
name: {{ $fullName }}-grpc
|
||||||
|
port:
|
||||||
|
number: {{ .Values.service.ports.grpc }}
|
||||||
|
{{- else }}
|
||||||
|
serviceName: {{ $fullName }}-grpc
|
||||||
|
servicePort: {{ .Values.service.ports.grpc }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
{{- if .Values.ingress.web.enabled -}}
|
||||||
|
{{- $fullName := include "defguard-proxy.fullname" . -}}
|
||||||
|
{{- if and .Values.ingress.web.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }}
|
||||||
|
{{- if not (hasKey .Values.ingress.web.annotations "kubernetes.io/ingress.class") }}
|
||||||
|
{{- $_ := set .Values.ingress.web.annotations "kubernetes.io/ingress.class" .Values.ingress.web.className}}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}}
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
|
||||||
|
apiVersion: networking.k8s.io/v1beta1
|
||||||
|
{{- else -}}
|
||||||
|
apiVersion: extensions/v1beta1
|
||||||
|
{{- end }}
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
name: {{ $fullName }}-web
|
||||||
|
labels:
|
||||||
|
{{- include "defguard-proxy.labels" . | nindent 4 }}
|
||||||
|
{{- with .Values.ingress.web.annotations }}
|
||||||
|
annotations:
|
||||||
|
{{- toYaml . | nindent 4 }}
|
||||||
|
{{- end }}
|
||||||
|
spec:
|
||||||
|
{{- if and .Values.ingress.web.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }}
|
||||||
|
ingressClassName: {{ .Values.ingress.web.className }}
|
||||||
|
{{- end }}
|
||||||
|
{{- if .Values.ingress.web.tls }}
|
||||||
|
tls:
|
||||||
|
- hosts:
|
||||||
|
- {{ .Values.ingress.web.host | quote }}
|
||||||
|
secretName: {{ printf "%s-web-tls" .Values.ingress.web.host }}
|
||||||
|
{{- end }}
|
||||||
|
rules:
|
||||||
|
- host: {{ .Values.ingress.web.host | quote }}
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
{{- if semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion }}
|
||||||
|
pathType: ImplementationSpecific
|
||||||
|
{{- end }}
|
||||||
|
backend:
|
||||||
|
{{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }}
|
||||||
|
service:
|
||||||
|
name: {{ $fullName }}-web
|
||||||
|
port:
|
||||||
|
number: {{ .Values.service.ports.http }}
|
||||||
|
{{- else }}
|
||||||
|
serviceName: {{ $fullName }}-web
|
||||||
|
servicePort: {{ .Values.service.ports.http }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: {{ include "defguard-proxy.fullname" . }}-web
|
||||||
|
labels:
|
||||||
|
{{- include "defguard-proxy.labels" . | nindent 4 }}
|
||||||
|
spec:
|
||||||
|
type: {{ .Values.service.type }}
|
||||||
|
ports:
|
||||||
|
- port: {{ .Values.service.ports.http }}
|
||||||
|
targetPort: http
|
||||||
|
protocol: TCP
|
||||||
|
name: http
|
||||||
|
selector:
|
||||||
|
{{- include "defguard-proxy.selectorLabels" . | nindent 4 }}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
{{- if .Values.serviceAccount.create -}}
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ServiceAccount
|
||||||
|
metadata:
|
||||||
|
name: {{ include "defguard-proxy.serviceAccountName" . }}
|
||||||
|
labels:
|
||||||
|
{{- include "defguard-proxy.labels" . | nindent 4 }}
|
||||||
|
{{- with .Values.serviceAccount.annotations }}
|
||||||
|
annotations:
|
||||||
|
{{- toYaml . | nindent 4 }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
affinity: {}
|
||||||
|
autoscaling:
|
||||||
|
enabled: false
|
||||||
|
minReplicas: 1
|
||||||
|
maxReplicas: 10
|
||||||
|
fullnameOverride: ""
|
||||||
|
image:
|
||||||
|
pullPolicy: IfNotPresent
|
||||||
|
repository: ghcr.io/defguard/defguard-proxy
|
||||||
|
tag: ""
|
||||||
|
imagePullSecrets: []
|
||||||
|
ingress:
|
||||||
|
grpc:
|
||||||
|
annotations: {}
|
||||||
|
className: ""
|
||||||
|
enabled: true
|
||||||
|
host: enrollment-grpc.local
|
||||||
|
tls: false
|
||||||
|
web:
|
||||||
|
annotations: {}
|
||||||
|
className: ""
|
||||||
|
enabled: true
|
||||||
|
host: enrollment.local
|
||||||
|
tls: false
|
||||||
|
nameOverride: ""
|
||||||
|
nodeSelector: {}
|
||||||
|
podAnnotations: {}
|
||||||
|
podLabels: {}
|
||||||
|
podSecurityContext: {}
|
||||||
|
publicUrl: "http://enrollment.local"
|
||||||
|
replicaCount: 1
|
||||||
|
resources: {}
|
||||||
|
securityContext: {}
|
||||||
|
service:
|
||||||
|
ports:
|
||||||
|
http: 8080
|
||||||
|
grpc: 50051
|
||||||
|
type: ClusterIP
|
||||||
|
serviceAccount:
|
||||||
|
annotations: {}
|
||||||
|
create: true
|
||||||
|
tolerations: []
|
||||||
@@ -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/
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
dependencies:
|
||||||
|
- name: postgresql
|
||||||
|
repository: https://charts.bitnami.com/bitnami
|
||||||
|
version: 12.12.10
|
||||||
|
- name: defguard-proxy
|
||||||
|
repository: https://defguard.github.io/deployment
|
||||||
|
version: 0.3.5
|
||||||
|
digest: sha256:de930b480616cfa369caf7b1447c5b3e729fce3e17994717ab0f64aa02c027e7
|
||||||
|
generated: "2024-07-26T09:00:54.309522115+02:00"
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
apiVersion: v2
|
||||||
|
name: defguard
|
||||||
|
description: Defguard is an open-source enterprise wireGuard VPN with MFA and SSO
|
||||||
|
|
||||||
|
type: application
|
||||||
|
version: 0.7.6
|
||||||
|
appVersion: 0.11.0
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
- name: postgresql
|
||||||
|
condition: postgresql.enabled
|
||||||
|
version: 12.12.10
|
||||||
|
repository: https://charts.bitnami.com/bitnami
|
||||||
|
- name: defguard-proxy
|
||||||
|
condition: defguard-proxy.enabled
|
||||||
|
version: 0.3.5
|
||||||
|
repository: https://defguard.github.io/deployment
|
||||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,20 @@
|
|||||||
|
1. Get the application URL by running these commands:
|
||||||
|
{{- if .Values.ingress.enabled }}
|
||||||
|
{{- range $host := .Values.ingress.hosts }}
|
||||||
|
http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host }}/
|
||||||
|
{{- end }}
|
||||||
|
{{- else if contains "NodePort" .Values.service.type }}
|
||||||
|
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "defguard.fullname" . }})
|
||||||
|
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
|
||||||
|
echo http://$NODE_IP:$NODE_PORT
|
||||||
|
{{- else if contains "LoadBalancer" .Values.service.type }}
|
||||||
|
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
|
||||||
|
You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "defguard.fullname" . }}'
|
||||||
|
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "defguard.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
|
||||||
|
echo http://$SERVICE_IP:{{ .Values.service.port }}
|
||||||
|
{{- else if contains "ClusterIP" .Values.service.type }}
|
||||||
|
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "defguard.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
|
||||||
|
export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
|
||||||
|
echo "Visit http://127.0.0.1:8080 to use your application"
|
||||||
|
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT
|
||||||
|
{{- end }}
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
{{/*
|
||||||
|
Expand the name of the chart.
|
||||||
|
*/}}
|
||||||
|
{{- define "defguard.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 "defguard.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 "defguard.chart" -}}
|
||||||
|
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Common labels
|
||||||
|
*/}}
|
||||||
|
{{- define "defguard.labels" -}}
|
||||||
|
helm.sh/chart: {{ include "defguard.chart" . }}
|
||||||
|
{{ include "defguard.selectorLabels" . }}
|
||||||
|
{{- if .Chart.AppVersion }}
|
||||||
|
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||||
|
{{- end }}
|
||||||
|
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Selector labels
|
||||||
|
*/}}
|
||||||
|
{{- define "defguard.selectorLabels" -}}
|
||||||
|
app.kubernetes.io/name: {{ include "defguard.name" . }}
|
||||||
|
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Create the name of the service account to use
|
||||||
|
*/}}
|
||||||
|
{{- define "defguard.serviceAccountName" -}}
|
||||||
|
{{- if .Values.serviceAccount.create }}
|
||||||
|
{{- default (include "defguard.fullname" .) .Values.serviceAccount.name }}
|
||||||
|
{{- else }}
|
||||||
|
{{- default "default" .Values.serviceAccount.name }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Define OpenID secret name
|
||||||
|
*/}}
|
||||||
|
{{- define "defguard.openidSecretName" -}}
|
||||||
|
{{- $name := "openid-key" }}
|
||||||
|
{{- $name }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Define JWT secret name
|
||||||
|
*/}}
|
||||||
|
{{- define "defguard.jwtSecretName" -}}
|
||||||
|
{{- $name := "jwt-secrets" }}
|
||||||
|
{{- $name }}
|
||||||
|
{{- end }}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: {{ include "defguard.fullname" . }}-config
|
||||||
|
labels:
|
||||||
|
{{- include "defguard.labels" . | nindent 4 }}
|
||||||
|
data:
|
||||||
|
{{- if .Values.cookie.domain }}
|
||||||
|
DEFGUARD_COOKIE_DOMAIN: {{ .Values.cookie.domain }}
|
||||||
|
{{- end }}
|
||||||
|
DEFGUARD_COOKIE_INSECURE: {{ .Values.cookie.insecure | quote }}
|
||||||
|
DEFGUARD_DB_HOST: {{ .Values.postgresql.host | default (printf "%s-postgresql" (include "defguard.fullname" .)) }}
|
||||||
|
DEFGUARD_DB_PORT: {{ .Values.postgresql.port | quote}}
|
||||||
|
DEFGUARD_DB_NAME: {{ .Values.postgresql.auth.database }}
|
||||||
|
DEFGUARD_DB_USER: {{ .Values.postgresql.auth.username }}
|
||||||
|
DEFGUARD_GRPC_PORT: {{ .Values.service.ports.grpc | quote }}
|
||||||
|
DEFGUARD_ENROLLMENT_URL: {{ index .Values "defguard-proxy" "publicUrl" }}
|
||||||
|
{{- if .Values.proxyUrl }}
|
||||||
|
DEFGUARD_PROXY_URL: {{ .Values.proxyUrl }}
|
||||||
|
{{- end }}
|
||||||
|
DEFGUARD_URL: {{ .Values.publicUrl }}
|
||||||
|
DEFGUARD_WEBAUTHN_RP_ID: {{ .Values.ingress.web.host }}
|
||||||
|
{{- if .Values.ldap.enabled }}
|
||||||
|
DEFGUARD_LDAP_ADMIN_GROUP: {{ .Values.ldap.admin_group | quote }}
|
||||||
|
DEFGUARD_LDAP_BIND_PASSWORD: {{ .Values.ldap.bind_password | quote }}
|
||||||
|
DEFGUARD_LDAP_BIND_USERNAME: {{ .Values.ldap.bind_username | quote }}
|
||||||
|
DEFGUARD_LDAP_GROUP_SEARCH_BASE: {{ .Values.ldap.group_search_base | quote }}
|
||||||
|
DEFGUARD_LDAP_USER_SEARCH_BASE: {{ .Values.ldap.user_search_base | quote }}
|
||||||
|
DEFGUARD_LDAP_URL: {{ .Values.ldap.url | quote }}
|
||||||
|
{{- end }}
|
||||||
@@ -0,0 +1,105 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: {{ include "defguard.fullname" . }}
|
||||||
|
labels:
|
||||||
|
{{- include "defguard.labels" . | nindent 4 }}
|
||||||
|
spec:
|
||||||
|
{{- if not .Values.autoscaling.enabled }}
|
||||||
|
replicas: {{ .Values.replicaCount }}
|
||||||
|
{{- end }}
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
{{- include "defguard.selectorLabels" . | nindent 6 }}
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
{{- with .Values.podAnnotations }}
|
||||||
|
annotations:
|
||||||
|
{{- toYaml . | nindent 8 }}
|
||||||
|
{{- end }}
|
||||||
|
labels:
|
||||||
|
{{- include "defguard.selectorLabels" . | nindent 8 }}
|
||||||
|
spec:
|
||||||
|
{{- with .Values.imagePullSecrets }}
|
||||||
|
imagePullSecrets:
|
||||||
|
{{- toYaml . | nindent 8 }}
|
||||||
|
{{- end }}
|
||||||
|
serviceAccountName: {{ include "defguard.serviceAccountName" . }}
|
||||||
|
securityContext:
|
||||||
|
{{- toYaml .Values.podSecurityContext | nindent 8 }}
|
||||||
|
containers:
|
||||||
|
- name: {{ .Chart.Name }}
|
||||||
|
env:
|
||||||
|
- name: DEFGUARD_DB_PASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: {{ .Values.postgresql.auth.existingSecret }}
|
||||||
|
key: {{ .Values.postgresql.auth.existingSecretPasswordKey | default "password" }}
|
||||||
|
- name: DEFGUARD_AUTH_SECRET
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: {{ .Values.existingJwtSecret | default (include "defguard.jwtSecretName" .) }}
|
||||||
|
key: auth
|
||||||
|
- name: DEFGUARD_GATEWAY_SECRET
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: {{ .Values.existingJwtSecret | default (include "defguard.jwtSecretName" .) }}
|
||||||
|
key: gateway
|
||||||
|
- name: DEFGUARD_YUBIBRIDGE_SECRET
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: {{ .Values.existingJwtSecret | default (include "defguard.jwtSecretName" .) }}
|
||||||
|
key: yubi-bridge
|
||||||
|
- name: DEFGUARD_SECRET_KEY
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: {{ .Values.existingJwtSecret | default (include "defguard.jwtSecretName" .) }}
|
||||||
|
key: secret-key
|
||||||
|
- name: DEFGUARD_OPENID_KEY
|
||||||
|
value: "/etc/defguard-openid-key.pem"
|
||||||
|
envFrom:
|
||||||
|
- configMapRef:
|
||||||
|
name: {{ include "defguard.fullname" . }}-config
|
||||||
|
securityContext:
|
||||||
|
{{- toYaml .Values.securityContext | nindent 12 }}
|
||||||
|
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
|
||||||
|
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
containerPort: 8000
|
||||||
|
protocol: TCP
|
||||||
|
- name: grpc
|
||||||
|
containerPort: 50055
|
||||||
|
protocol: TCP
|
||||||
|
livenessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /api/v1/health
|
||||||
|
port: http
|
||||||
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /api/v1/health
|
||||||
|
port: http
|
||||||
|
resources:
|
||||||
|
{{- toYaml .Values.resources | nindent 12 }}
|
||||||
|
volumeMounts:
|
||||||
|
- name: openid-key
|
||||||
|
mountPath: "/etc/defguard-openid-key.pem"
|
||||||
|
readOnly: true
|
||||||
|
subPath: openid-key
|
||||||
|
{{- with .Values.nodeSelector }}
|
||||||
|
nodeSelector:
|
||||||
|
{{- toYaml . | nindent 8 }}
|
||||||
|
{{- end }}
|
||||||
|
{{- with .Values.affinity }}
|
||||||
|
affinity:
|
||||||
|
{{- toYaml . | nindent 8 }}
|
||||||
|
{{- end }}
|
||||||
|
{{- with .Values.tolerations }}
|
||||||
|
tolerations:
|
||||||
|
{{- toYaml . | nindent 8 }}
|
||||||
|
{{- end }}
|
||||||
|
volumes:
|
||||||
|
- name: openid-key
|
||||||
|
secret:
|
||||||
|
secretName: {{ .Values.existingOpenIdSecret | default (include "defguard.openidSecretName" .) }}
|
||||||
|
optional: false
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
{{ if not .Values.existingJwtSecret }}
|
||||||
|
{{- $auth := (randAlpha 16) | b64enc | quote }}
|
||||||
|
{{- $gateway := (randAlpha 16) | b64enc | quote }}
|
||||||
|
{{- $yubiBridge := (randAlpha 16) | b64enc | quote }}
|
||||||
|
{{- $secretKey := (randAlpha 64) | b64enc | quote }}
|
||||||
|
{{- $secret := (lookup "v1" "Secret" .Release.Namespace (include "defguard.jwtSecretName" .)) }}
|
||||||
|
{{- if $secret }}
|
||||||
|
{{- $auth = index $secret.data "auth" }}
|
||||||
|
{{- $gateway = index $secret.data "gateway" }}
|
||||||
|
{{- $yubiBridge = index $secret.data "yubi-bridge" }}
|
||||||
|
{{- $secretKey = index $secret.data "secret-key" }}
|
||||||
|
{{- end }}
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: {{ include "defguard.jwtSecretName" . }}
|
||||||
|
labels:
|
||||||
|
{{- include "defguard.labels" . | nindent 4 }}
|
||||||
|
type: Opaque
|
||||||
|
data:
|
||||||
|
auth: {{ $auth }}
|
||||||
|
gateway: {{ $gateway }}
|
||||||
|
yubi-bridge: {{ $yubiBridge }}
|
||||||
|
secret-key: {{ $secretKey }}
|
||||||
|
{{- end }}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: {{ include "defguard.fullname" . }}-web
|
||||||
|
labels:
|
||||||
|
{{- include "defguard.labels" . | nindent 4 }}
|
||||||
|
spec:
|
||||||
|
type: {{ .Values.service.type }}
|
||||||
|
ports:
|
||||||
|
- port: {{ .Values.service.ports.http }}
|
||||||
|
targetPort: http
|
||||||
|
protocol: TCP
|
||||||
|
name: http
|
||||||
|
selector:
|
||||||
|
{{- include "defguard.selectorLabels" . | nindent 4 }}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
annotations:
|
||||||
|
traefik.ingress.kubernetes.io/service.serversscheme: h2c
|
||||||
|
name: {{ include "defguard.fullname" . }}-grpc
|
||||||
|
labels:
|
||||||
|
{{- include "defguard.labels" . | nindent 4 }}
|
||||||
|
spec:
|
||||||
|
type: {{ .Values.service.type }}
|
||||||
|
ports:
|
||||||
|
- port: {{ .Values.service.ports.grpc }}
|
||||||
|
targetPort: grpc
|
||||||
|
protocol: TCP
|
||||||
|
name: grpc
|
||||||
|
selector:
|
||||||
|
{{- include "defguard.selectorLabels" . | nindent 4 }}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
{{- if .Values.ingress.grpc.enabled -}}
|
||||||
|
{{- $fullName := include "defguard.fullname" . -}}
|
||||||
|
{{- if and .Values.ingress.grpc.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }}
|
||||||
|
{{- if not (hasKey .Values.ingress.grpc.annotations "kubernetes.io/ingress.class") }}
|
||||||
|
{{- $_ := set .Values.ingress.grpc.annotations "kubernetes.io/ingress.class" .Values.ingress.grpc.className}}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}}
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
|
||||||
|
apiVersion: networking.k8s.io/v1beta1
|
||||||
|
{{- else -}}
|
||||||
|
apiVersion: extensions/v1beta1
|
||||||
|
{{- end }}
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
name: {{ $fullName }}-grpc
|
||||||
|
labels:
|
||||||
|
{{- include "defguard.labels" . | nindent 4 }}
|
||||||
|
{{- with .Values.ingress.grpc.annotations }}
|
||||||
|
annotations:
|
||||||
|
{{- toYaml . | nindent 4 }}
|
||||||
|
{{- end }}
|
||||||
|
spec:
|
||||||
|
{{- if and .Values.ingress.grpc.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }}
|
||||||
|
ingressClassName: {{ .Values.ingress.grpc.className }}
|
||||||
|
{{- end }}
|
||||||
|
{{- if .Values.ingress.grpc.tls }}
|
||||||
|
tls:
|
||||||
|
- hosts:
|
||||||
|
- {{ .Values.ingress.grpc.host | quote }}
|
||||||
|
secretName: {{ printf "%s-grpc-tls" .Values.ingress.grpc.host }}
|
||||||
|
{{- end }}
|
||||||
|
rules:
|
||||||
|
- host: {{ .Values.ingress.grpc.host | quote }}
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
{{- if semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion }}
|
||||||
|
pathType: ImplementationSpecific
|
||||||
|
{{- end }}
|
||||||
|
backend:
|
||||||
|
{{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }}
|
||||||
|
service:
|
||||||
|
name: {{ $fullName }}-grpc
|
||||||
|
port:
|
||||||
|
number: {{ .Values.service.ports.grpc }}
|
||||||
|
{{- else }}
|
||||||
|
serviceName: {{ $fullName }}-grpc
|
||||||
|
servicePort: {{ .Values.service.ports.grpc }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
{{- if .Values.ingress.web.enabled -}}
|
||||||
|
{{- $fullName := include "defguard.fullname" . -}}
|
||||||
|
{{- if and .Values.ingress.web.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }}
|
||||||
|
{{- if not (hasKey .Values.ingress.web.annotations "kubernetes.io/ingress.class") }}
|
||||||
|
{{- $_ := set .Values.ingress.web.annotations "kubernetes.io/ingress.class" .Values.ingress.web.className}}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}}
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
|
||||||
|
apiVersion: networking.k8s.io/v1beta1
|
||||||
|
{{- else -}}
|
||||||
|
apiVersion: extensions/v1beta1
|
||||||
|
{{- end }}
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
name: {{ $fullName }}-web
|
||||||
|
labels:
|
||||||
|
{{- include "defguard.labels" . | nindent 4 }}
|
||||||
|
{{- with .Values.ingress.web.annotations }}
|
||||||
|
annotations:
|
||||||
|
{{- toYaml . | nindent 4 }}
|
||||||
|
{{- end }}
|
||||||
|
spec:
|
||||||
|
{{- if and .Values.ingress.web.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }}
|
||||||
|
ingressClassName: {{ .Values.ingress.web.className }}
|
||||||
|
{{- end }}
|
||||||
|
{{- if .Values.ingress.web.tls }}
|
||||||
|
tls:
|
||||||
|
- hosts:
|
||||||
|
- {{ .Values.ingress.web.host | quote }}
|
||||||
|
secretName: {{ printf "%s-web-tls" .Values.ingress.web.host }}
|
||||||
|
{{- end }}
|
||||||
|
rules:
|
||||||
|
- host: {{ .Values.ingress.web.host | quote }}
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
{{- if semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion }}
|
||||||
|
pathType: ImplementationSpecific
|
||||||
|
{{- end }}
|
||||||
|
backend:
|
||||||
|
{{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }}
|
||||||
|
service:
|
||||||
|
name: {{ $fullName }}-web
|
||||||
|
port:
|
||||||
|
number: {{ .Values.service.ports.http }}
|
||||||
|
{{- else }}
|
||||||
|
serviceName: {{ $fullName }}-web
|
||||||
|
servicePort: {{ .Values.service.ports.http }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
{{ if not .Values.existingOpenIdSecret }}
|
||||||
|
{{- $openIdKey := (genPrivateKey "rsa") | b64enc | quote }}
|
||||||
|
{{- $secret := (lookup "v1" "Secret" .Release.Namespace (include "defguard.openidSecretName" .)) }}
|
||||||
|
{{- if $secret }}
|
||||||
|
{{- $openIdKey = index $secret.data "openid-key" }}
|
||||||
|
{{- end }}
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: {{ include "defguard.openidSecretName" . }}
|
||||||
|
labels:
|
||||||
|
{{- include "defguard.labels" . | nindent 4 }}
|
||||||
|
type: Opaque
|
||||||
|
data:
|
||||||
|
openid-key: {{ $openIdKey }}
|
||||||
|
{{- end }}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
{{ if .Values.postgresql.enabled }}
|
||||||
|
{{- $password := (randAlpha 16) | b64enc | quote }}
|
||||||
|
{{- $postgresPassword := (randAlpha 16) | b64enc | quote }}
|
||||||
|
{{- $secret := (lookup "v1" "Secret" .Release.Namespace .Values.postgresql.auth.existingSecret) }}
|
||||||
|
{{- if $secret }}
|
||||||
|
{{- $password = index $secret.data "password" }}
|
||||||
|
{{- $postgresPassword = index $secret.data "postgres-password" }}
|
||||||
|
{{- end }}
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: {{ .Values.postgresql.auth.existingSecret }}
|
||||||
|
labels:
|
||||||
|
{{- include "defguard.labels" . | nindent 4 }}
|
||||||
|
type: Opaque
|
||||||
|
data:
|
||||||
|
password: {{ $password }}
|
||||||
|
postgres-password: {{ $postgresPassword }}
|
||||||
|
{{- end }}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
{{- if .Values.serviceAccount.create -}}
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ServiceAccount
|
||||||
|
metadata:
|
||||||
|
name: {{ include "defguard.serviceAccountName" . }}
|
||||||
|
labels:
|
||||||
|
{{- include "defguard.labels" . | nindent 4 }}
|
||||||
|
{{- with .Values.serviceAccount.annotations }}
|
||||||
|
annotations:
|
||||||
|
{{- toYaml . | nindent 4 }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
affinity: {}
|
||||||
|
autoscaling:
|
||||||
|
enabled: false
|
||||||
|
minReplicas: 1
|
||||||
|
maxReplicas: 10
|
||||||
|
cookie:
|
||||||
|
domain: ""
|
||||||
|
insecure: false
|
||||||
|
fullnameOverride: ""
|
||||||
|
image:
|
||||||
|
pullPolicy: IfNotPresent
|
||||||
|
repository: ghcr.io/defguard/defguard
|
||||||
|
tag: ""
|
||||||
|
imagePullSecrets: []
|
||||||
|
ingress:
|
||||||
|
grpc:
|
||||||
|
annotations: {}
|
||||||
|
className: ""
|
||||||
|
enabled: true
|
||||||
|
host: defguard-grpc.local
|
||||||
|
tls: false
|
||||||
|
web:
|
||||||
|
annotations: {}
|
||||||
|
className: ""
|
||||||
|
enabled: true
|
||||||
|
host: defguard.local
|
||||||
|
tls: false
|
||||||
|
existingJwtSecret: ""
|
||||||
|
ldap:
|
||||||
|
admin_group: ""
|
||||||
|
bind_password: ""
|
||||||
|
bind_username: ""
|
||||||
|
enabled: false
|
||||||
|
group_search_base: ""
|
||||||
|
url: ""
|
||||||
|
user_search_base: ""
|
||||||
|
nameOverride: ""
|
||||||
|
nodeSelector: {}
|
||||||
|
existingOpenIdSecret: ""
|
||||||
|
podAnnotations: {}
|
||||||
|
podLabels: {}
|
||||||
|
podSecurityContext: {}
|
||||||
|
# sub-chart bitnami/postgresql
|
||||||
|
postgresql:
|
||||||
|
enabled: true
|
||||||
|
host: "" # set if using external postgresql ~ enabled: false
|
||||||
|
port: 5432
|
||||||
|
auth:
|
||||||
|
database: defguard
|
||||||
|
existingSecret: postgres-password
|
||||||
|
existingSecretPasswordKey: "" # set if using external postgresql ~ enabled: false
|
||||||
|
username: defguard
|
||||||
|
proxyUrl: ""
|
||||||
|
publicUrl: "http://defguard.local"
|
||||||
|
replicaCount: 1
|
||||||
|
resources: {}
|
||||||
|
securityContext: {}
|
||||||
|
service:
|
||||||
|
ports:
|
||||||
|
grpc: 50055
|
||||||
|
http: 80
|
||||||
|
type: ClusterIP
|
||||||
|
serviceAccount:
|
||||||
|
annotations: {}
|
||||||
|
create: true
|
||||||
|
tolerations: []
|
||||||
|
# sub-chart defguard-proxy
|
||||||
|
defguard-proxy:
|
||||||
|
enabled: false
|
||||||
|
publicUrl: "http://enrollment.local"
|
||||||
|
ingress:
|
||||||
|
grpc:
|
||||||
|
host: defguard-proxy-grpc.local
|
||||||
|
web:
|
||||||
|
host: enrollment.local
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
# The best way to define each secret is to generate random strings with e.g.:
|
||||||
|
#
|
||||||
|
# openssl rand -base64 48 #this will generate a 48chars random string
|
||||||
|
#
|
||||||
|
# Please provide secret strings (do not share them) for:
|
||||||
|
#
|
||||||
|
# Secret used for JWT cryptography
|
||||||
|
DEFGUARD_AUTH_SECRET=<YOUR_AUTH_SECRET>
|
||||||
|
# Secret used for JWT cryptography in YubiBridge GRPC communication
|
||||||
|
DEFGUARD_YUBIBRIDGE_SECRET=<DEFGUARD_YUBIBRIDGE_SECRET>
|
||||||
|
# Secret used for JWT cryptography in gateway GRPC communication
|
||||||
|
DEFGUARD_GATEWAY_SECRET=<DEFGUARD_GATEWAY_SECRET>
|
||||||
|
# Secret used for private cookies cryptography; must be at least 64 characters long
|
||||||
|
DEFGUARD_SECRET_KEY=<DEFGUARD_SECRET_KEY>
|
||||||
|
# Database password
|
||||||
|
DEFGUARD_DB_PASSWORD=<YOUR_DB_PASSWORD>
|
||||||
|
# Public URL of your Defguard instance
|
||||||
|
# E.g.: https://defguard.mycompany.com
|
||||||
|
DEFGUARD_URL=<YOUR_DEFGUARD_URL>
|
||||||
|
# Webauthn RP ID (https://w3c.github.io/webauthn/#rp-id)
|
||||||
|
# E.g.: defguard.mycompany.com (without http/https)
|
||||||
|
DEFGUARD_WEBAUTHN_RP_ID=<YOUR_DEFGUARD_WEBAUTHN_RP_ID>
|
||||||
|
# Public URL of your defguard proxy gRPC server
|
||||||
|
# DEFGUARD_PROXY_URL=<YOUR_PROXY_GRPC_URL>
|
||||||
|
# Public URL of your enrollment service
|
||||||
|
# E.g.: https://enrollment.mycompany.com
|
||||||
|
# DEFGUARD_ENROLLMENT_URL=<YOUR_PROXY_URL> # [ENROLLMENT]
|
||||||
|
# Token used for VPN gateway authorization
|
||||||
|
# DEFGUARD_TOKEN=<GATEWAY_TOKEN> # [VPN]
|
||||||
|
# Enable insecure cookies when not using HTTPS
|
||||||
|
# DEFGUARD_COOKIE_INSECURE=true # [HTTP]
|
||||||
@@ -0,0 +1,98 @@
|
|||||||
|
services:
|
||||||
|
db:
|
||||||
|
image: postgres:15-alpine
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
POSTGRES_DB: defguard
|
||||||
|
POSTGRES_USER: defguard
|
||||||
|
POSTGRES_PASSWORD: ${DEFGUARD_DB_PASSWORD}
|
||||||
|
volumes:
|
||||||
|
- ${VOLUME_DIR:-./.volumes}/db:/var/lib/postgresql/data
|
||||||
|
# ports:
|
||||||
|
# - "5432:5432"
|
||||||
|
|
||||||
|
# caddy: # [PROXY]
|
||||||
|
# image: caddy:2.7-alpine # [PROXY]
|
||||||
|
# restart: unless-stopped # [PROXY]
|
||||||
|
# volumes: # [PROXY]
|
||||||
|
# - ${VOLUME_DIR:-./.volumes}/caddy/data:/data # [PROXY]
|
||||||
|
# - ${VOLUME_DIR:-./.volumes}/caddy/config:/config # [PROXY]
|
||||||
|
# - ${VOLUME_DIR:-./.volumes}/caddy/Caddyfile:/etc/caddy/Caddyfile # [PROXY]
|
||||||
|
# ports: # [PROXY]
|
||||||
|
# # http # [PROXY]
|
||||||
|
# - "80:80" # [PROXY]
|
||||||
|
# # https # [PROXY]
|
||||||
|
# - "443:443" # [PROXY]
|
||||||
|
|
||||||
|
core:
|
||||||
|
image: ghcr.io/defguard/defguard:${CORE_IMAGE_TAG:-latest}
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
DEFGUARD_AUTH_SECRET: ${DEFGUARD_AUTH_SECRET}
|
||||||
|
DEFGUARD_GATEWAY_SECRET: ${DEFGUARD_GATEWAY_SECRET}
|
||||||
|
DEFGUARD_YUBIBRIDGE_SECRET: ${DEFGUARD_YUBIBRIDGE_SECRET}
|
||||||
|
DEFGUARD_SECRET_KEY: ${DEFGUARD_SECRET_KEY}
|
||||||
|
DEFGUARD_DEFAULT_ADMIN_PASSWORD: ${DEFGUARD_DEFAULT_ADMIN_PASSWORD}
|
||||||
|
DEFGUARD_DB_HOST: db
|
||||||
|
DEFGUARD_DB_PORT: 5432
|
||||||
|
DEFGUARD_DB_USER: defguard
|
||||||
|
DEFGUARD_DB_PASSWORD: ${DEFGUARD_DB_PASSWORD}
|
||||||
|
DEFGUARD_DB_NAME: defguard
|
||||||
|
DEFGUARD_URL: ${DEFGUARD_URL}
|
||||||
|
DEFGUARD_LOG_LEVEL: info
|
||||||
|
# DEFGUARD_WEBAUTHN_RP_ID: ${DEFGUARD_WEBAUTHN_RP_ID}
|
||||||
|
DEFGUARD_COOKIE_INSECURE: ${DEFGUARD_COOKIE_INSECURE:-false}
|
||||||
|
DEFGUARD_ENROLLMENT_URL: ${DEFGUARD_ENROLLMENT_URL} # [ENROLLMENT]
|
||||||
|
# DEFGUARD_PROXY_URL: https://proxy:50052 # [ENROLLMENT]
|
||||||
|
# DEFGUARD_PROXY_GRPC_CA: /ssl/defguard-ca.pem # [ENROLLMENT]
|
||||||
|
#DEFGUARD_GRPC_CERT: /ssl/defguard-grpc.crt
|
||||||
|
#DEFGUARD_GRPC_KEY: /ssl/defguard-grpc.key
|
||||||
|
## RSA setup guide: https://defguard.gitbook.io/defguard/community-features/setting-up-your-instance/docker-compose#openid-rsa-setup
|
||||||
|
DEFGUARD_OPENID_KEY: /keys/rsakey.pem
|
||||||
|
## LDAP setup guide: https://defguard.gitbook.io/defguard/features/ldap-synchronization-setup
|
||||||
|
# DEFGUARD_LDAP_URL: ldap://localhost:389 # [LDAP]
|
||||||
|
# DEFGUARD_LDAP_BIND_USERNAME: cn=admin,dc=example,dc=org # [LDAP]
|
||||||
|
# DEFGUARD_LDAP_BIND_PASSWORD: password # [LDAP]
|
||||||
|
ports:
|
||||||
|
# web
|
||||||
|
- "8850:8000"
|
||||||
|
# grpc
|
||||||
|
- "50055:50055"
|
||||||
|
depends_on:
|
||||||
|
- db
|
||||||
|
volumes:
|
||||||
|
# SSL setup guide: https://defguard.gitbook.io/defguard/features/setting-up-your-instance/docker-compose#ssl-setup
|
||||||
|
- ${VOLUME_DIR:-./.volumes}/ssl:/ssl
|
||||||
|
## RSA setup guide: https://defguard.gitbook.io/defguard/community-features/setting-up-your-instance/docker-compose#openid-rsa-setup
|
||||||
|
- ${VOLUME_DIR:-./.volumes}/core/rsakey.pem:/keys/rsakey.pem
|
||||||
|
|
||||||
|
# proxy: # [ENROLLMENT]
|
||||||
|
# image: ghcr.io/defguard/defguard-proxy:${PROXY_IMAGE_TAG:-latest} # [ENROLLMENT]
|
||||||
|
# restart: unless-stopped # [ENROLLMENT]
|
||||||
|
# environment: # [ENROLLMENT]
|
||||||
|
# DEFGUARD_PROXY_GRPC_PORT: 50052 # [ENROLLMENT]
|
||||||
|
# DEFGUARD_PROXY_GRPC_CERT: /ssl/defguard-proxy-grpc.crt # [ENROLLMENT]
|
||||||
|
# DEFGUARD_PROXY_GRPC_KEY: /ssl/defguard-proxy-grpc.key # [ENROLLMENT]
|
||||||
|
# volumes: # [ENROLLMENT]
|
||||||
|
# SSL setup guide: https://defguard.gitbook.io/defguard/features/setting-up-your-instance/docker-compose#ssl-setup
|
||||||
|
# - ${VOLUME_DIR:-./.volumes}/ssl:/ssl # [ENROLLMENT]
|
||||||
|
# ports:
|
||||||
|
# # web
|
||||||
|
# - "8080:8080"
|
||||||
|
# depends_on: # [ENROLLMENT]
|
||||||
|
# - core # [ENROLLMENT]
|
||||||
|
|
||||||
|
# gateway: # [VPN]
|
||||||
|
# image: ghcr.io/defguard/gateway:${GATEWAY_IMAGE_TAG:-latest} # [VPN]
|
||||||
|
# restart: unless-stopped # [VPN]
|
||||||
|
# network_mode: "host" # [VPN]
|
||||||
|
# environment: # [VPN]
|
||||||
|
# DEFGUARD_GRPC_URL: https://localhost:50055 # [VPN]
|
||||||
|
# DEFGUARD_GRPC_CA: /ssl/defguard-ca.pem # [VPN]
|
||||||
|
# DEFGUARD_STATS_PERIOD: 30 # [VPN]
|
||||||
|
# DEFGUARD_TOKEN: ${DEFGUARD_TOKEN} # [VPN]
|
||||||
|
# volumes: # [VPN]
|
||||||
|
# SSL setup guide: https://defguard.gitbook.io/defguard/features/setting-up-your-instance/docker-compose#ssl-setup
|
||||||
|
# - ${VOLUME_DIR:-./.volumes}/ssl:/ssl # [VPN]
|
||||||
|
# cap_add: # [VPN]
|
||||||
|
# - NET_ADMIN # [VPN]
|
||||||
Executable
+890
@@ -0,0 +1,890 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# shellcheck shell=bash
|
||||||
|
|
||||||
|
# This is a script that sets up an entire defguard instance (including core,
|
||||||
|
# gateway, enrollment proxy and reverse proxy). It's goal is to prepare
|
||||||
|
# a working instance by running a single command.
|
||||||
|
|
||||||
|
set -o errexit # abort on nonzero exitstatus
|
||||||
|
set -o pipefail # don't hide errors within pipes
|
||||||
|
|
||||||
|
# Global variables
|
||||||
|
VERSION="1.0.2"
|
||||||
|
SECRET_LENGTH=64
|
||||||
|
PASSWORD_LENGTH=16
|
||||||
|
|
||||||
|
VOLUME_DIR=".volumes"
|
||||||
|
SSL_DIR="${VOLUME_DIR}/ssl"
|
||||||
|
RSA_DIR="${VOLUME_DIR}/core"
|
||||||
|
|
||||||
|
COMPOSE_FILE="docker-compose.yaml"
|
||||||
|
ENV_FILE=".env"
|
||||||
|
LOG_FILE=$(mktemp setup.log.XXXXXX)
|
||||||
|
|
||||||
|
BASE_COMPOSE_FILE_URL="https://raw.githubusercontent.com/DefGuard/deployment/main/docker-compose/docker-compose.yaml"
|
||||||
|
BASE_ENV_FILE_URL="https://raw.githubusercontent.com/DefGuard/deployment/main/docker-compose/.env.template"
|
||||||
|
|
||||||
|
CORE_IMAGE_TAG="${CORE_IMAGE_TAG:-latest}"
|
||||||
|
GATEWAY_IMAGE_TAG="${GATEWAY_IMAGE_TAG:-latest}"
|
||||||
|
PROXY_IMAGE_TAG="${PROXY_IMAGE_TAG:-latest}"
|
||||||
|
|
||||||
|
|
||||||
|
#####################
|
||||||
|
### MAIN FUNCTION ###
|
||||||
|
#####################
|
||||||
|
|
||||||
|
main() {
|
||||||
|
is_utf_term
|
||||||
|
is_term_color
|
||||||
|
tput reset
|
||||||
|
print_header
|
||||||
|
|
||||||
|
# display help `--help` argument is found
|
||||||
|
for i in $*; do
|
||||||
|
test "$i" == "--help" && print_usage && exit 0
|
||||||
|
|
||||||
|
# run non interactive
|
||||||
|
if [[ "$i" == "--non-interactive" ]]; then
|
||||||
|
CFG_NON_INTERACTIVE=1
|
||||||
|
# we need to remove this element from $* or getopt will return an error
|
||||||
|
set -- $(remove_element "$i" $*)
|
||||||
|
fi
|
||||||
|
|
||||||
|
# configure https
|
||||||
|
if [[ "$i" == "--use-https" ]]; then
|
||||||
|
CFG_USE_HTTPS=1
|
||||||
|
# we need to remove this element from $* or getopt will return an error
|
||||||
|
set -- $(remove_element "$i" $*)
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
#
|
||||||
|
# First let's gather the ENV/command line variables
|
||||||
|
#
|
||||||
|
|
||||||
|
# load configuration from env variables
|
||||||
|
load_configuration_from_env
|
||||||
|
|
||||||
|
# load configuration from CLI options
|
||||||
|
load_configuration_from_cli "$@"
|
||||||
|
|
||||||
|
# load configuration from user inputs
|
||||||
|
if [ X$CFG_VOLUME_DIR != X ]; then
|
||||||
|
VOLUME_DIR=${CFG_VOLUME_DIR}
|
||||||
|
SSL_DIR="${VOLUME_DIR}/ssl"
|
||||||
|
RSA_DIR="${VOLUME_DIR}/core"
|
||||||
|
fi
|
||||||
|
|
||||||
|
export VOLUME_DIR
|
||||||
|
|
||||||
|
# We have enough to check the enviromnent
|
||||||
|
# so check if necessary tools are available
|
||||||
|
check_environment
|
||||||
|
|
||||||
|
# load configuration from user inputs
|
||||||
|
if ! [ $CFG_NON_INTERACTIVE ]; then
|
||||||
|
load_configuration_from_input
|
||||||
|
fi
|
||||||
|
|
||||||
|
# check that all required configuration options are set
|
||||||
|
validate_required_variables
|
||||||
|
|
||||||
|
# generate external service URLs based on config
|
||||||
|
generate_external_urls
|
||||||
|
|
||||||
|
# print out config
|
||||||
|
print_config
|
||||||
|
|
||||||
|
# set current working directory
|
||||||
|
WORK_DIR_PATH=$(pwd)
|
||||||
|
|
||||||
|
# setup RSA & SSL keys
|
||||||
|
setup_keys
|
||||||
|
|
||||||
|
# generate caddyfile
|
||||||
|
create_caddyfile
|
||||||
|
|
||||||
|
# generate `.env` file
|
||||||
|
generate_env_file
|
||||||
|
|
||||||
|
# enable insecure cookies if not using HTTPS
|
||||||
|
if ! [ "$CFG_USE_HTTPS" ]; then
|
||||||
|
uncomment_feature "HTTP" "${PROD_ENV_FILE}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# generate base docker-compose file
|
||||||
|
PROD_COMPOSE_FILE="${WORK_DIR_PATH}/${COMPOSE_FILE}"
|
||||||
|
if [ -f "$PROD_COMPOSE_FILE" ]; then
|
||||||
|
echo -n " ${TXT_BEGIN} Using existing docker-compose file at ${PROD_COMPOSE_FILE}... "
|
||||||
|
print_confirmation
|
||||||
|
else
|
||||||
|
fetch_base_compose_file
|
||||||
|
fi
|
||||||
|
|
||||||
|
# enable reverse proxy in compose file
|
||||||
|
uncomment_feature "PROXY" "${PROD_COMPOSE_FILE}"
|
||||||
|
|
||||||
|
# enable enrollment service in compose file
|
||||||
|
if [ "$CFG_ENABLE_ENROLLMENT" ]; then
|
||||||
|
enable_enrollment
|
||||||
|
fi
|
||||||
|
|
||||||
|
# fetch latest images
|
||||||
|
echo " ${TXT_BEGIN} Fetching latest Docker images: "
|
||||||
|
$COMPOSE_CMD -f "${PROD_COMPOSE_FILE}" --env-file "${PROD_ENV_FILE}" pull
|
||||||
|
|
||||||
|
# enable and setup VPN gateway
|
||||||
|
if [ "$CFG_ENABLE_VPN" ]; then
|
||||||
|
enable_vpn_gateway
|
||||||
|
fi
|
||||||
|
|
||||||
|
# start docker-compose stack
|
||||||
|
echo " ${TXT_BEGIN} Starting docker-compose stack"
|
||||||
|
$COMPOSE_CMD -f "${PROD_COMPOSE_FILE}" --env-file "${PROD_ENV_FILE}" up -d
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo >&2 "ERROR: failed to start docker-compose stack"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
print_instance_summary
|
||||||
|
}
|
||||||
|
|
||||||
|
########################
|
||||||
|
### HELPER FUNCTIONS ###
|
||||||
|
########################
|
||||||
|
|
||||||
|
check_character_support() {
|
||||||
|
local char="$1"
|
||||||
|
echo -e "$char" | grep -q "$char"
|
||||||
|
}
|
||||||
|
|
||||||
|
is_utf_term() {
|
||||||
|
if check_character_support "√"; then
|
||||||
|
TXT_CHECK="✓"
|
||||||
|
TXT_BEGIN="▶"
|
||||||
|
TXT_SUB="▷"
|
||||||
|
TXT_STAR="★"
|
||||||
|
TXT_X="✗"
|
||||||
|
TXT_INPUT="✍"
|
||||||
|
else
|
||||||
|
TXT_CHECK="+"
|
||||||
|
TXT_BEGIN=">>"
|
||||||
|
TXT_SUB=">"
|
||||||
|
TXT_STAR="*"
|
||||||
|
TXT_X="x"
|
||||||
|
TXT_INPUT=" ::"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
is_term_color() {
|
||||||
|
|
||||||
|
if [[ $TERM == *"256"* ]]; then
|
||||||
|
C_RED="\033[31m"
|
||||||
|
C_GREEN="\033[32m"
|
||||||
|
C_YELLOW="\033[33m"
|
||||||
|
C_BLUE="\033[34m"
|
||||||
|
C_WHITE="\033[37m"
|
||||||
|
C_GREY="\033[90m"
|
||||||
|
|
||||||
|
C_LRED="\033[91m"
|
||||||
|
C_LGREEN="\033[92m"
|
||||||
|
C_LYELLOW="\033[93m"
|
||||||
|
C_LBLUE="\033[94m"
|
||||||
|
|
||||||
|
C_BOLD="\033[1m"
|
||||||
|
C_ITALICS="\033[3m"
|
||||||
|
C_BG_GREY="\033[100m"
|
||||||
|
C_END="\033[0m"
|
||||||
|
else
|
||||||
|
C_RED=""
|
||||||
|
C_GREEN=""
|
||||||
|
C_YELLOW=""
|
||||||
|
C_BLUE=""
|
||||||
|
C_WHITE=""
|
||||||
|
C_GREY=""
|
||||||
|
|
||||||
|
C_LRED=""
|
||||||
|
C_LGREEN=""
|
||||||
|
C_LYELLOW=""
|
||||||
|
C_LBLUE=""
|
||||||
|
|
||||||
|
C_BOLD=""
|
||||||
|
C_ITALICS=""
|
||||||
|
C_BG_GREY=""
|
||||||
|
C_END=""
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# remove array element
|
||||||
|
remove_element() {
|
||||||
|
local remove=$1
|
||||||
|
local result=()
|
||||||
|
for element in "$@"; do
|
||||||
|
if [[ "$element" != "$remove" ]]; then
|
||||||
|
result+=("$element")
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
echo "${result[@]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to convert relative path to absolute path
|
||||||
|
to_absolute_path() {
|
||||||
|
local path="$1"
|
||||||
|
if [[ "${path:0:1}" != "/" ]]; then
|
||||||
|
path="$(cd "$(dirname "$path")" && pwd)/$(basename "$path")"
|
||||||
|
fi
|
||||||
|
echo ${path}
|
||||||
|
}
|
||||||
|
|
||||||
|
print_header() {
|
||||||
|
echo -e "${C_LBLUE}"
|
||||||
|
cat << _EOF_
|
||||||
|
#
|
||||||
|
## #
|
||||||
|
## ## # # ## #
|
||||||
|
## ## # # # #
|
||||||
|
# ## # #### # #### ##### #### # # #### ### #### #
|
||||||
|
# ## ## # ## # ## # # # # # # # # # ##
|
||||||
|
## ## # # ######## # # # # # # # # #
|
||||||
|
# ## ## # # # ## # ##### # # ###### # # #
|
||||||
|
# ## # # ## # # # # # # # # # # ##
|
||||||
|
## ## #### # ##### # ####### #### # #### # # #### #
|
||||||
|
## ## # # #
|
||||||
|
## # #######
|
||||||
|
#
|
||||||
|
_EOF_
|
||||||
|
echo -e "${C_END}"
|
||||||
|
echo
|
||||||
|
echo "defguard docker-compose deployment setup script v${VERSION}"
|
||||||
|
echo -e "Copyright (C) 2023-2024 ${C_BOLD}teonite${C_END} <${C_BG_GREY}${C_YELLOW}https://teonite.com${C_END}>"
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
print_confirmation() {
|
||||||
|
echo -e " ${C_LGREEN}${TXT_CHECK}${C_END} "
|
||||||
|
}
|
||||||
|
|
||||||
|
print_usage() {
|
||||||
|
|
||||||
|
echo "Usage: ${BASENAME} [options]"
|
||||||
|
echo
|
||||||
|
echo 'Available options:'
|
||||||
|
echo
|
||||||
|
echo -e "\t--help this help message"
|
||||||
|
echo -e "\t--non-interactive run in non-interactive mode - !REQUIRES SETTING all options/env vars"
|
||||||
|
echo -e "\t--domain <domain> domain where defguard web UI will be available"
|
||||||
|
echo -e "\t--enrollment-domain <domain> domain where enrollment service will be available"
|
||||||
|
echo -e "\t--use-https configure reverse proxy to use HTTPS"
|
||||||
|
echo -e "\t--volume <directory> Docker volumes directory - default: ${VOLUME_DIR}"
|
||||||
|
echo -e "\t--vpn-name <name> VPN location name"
|
||||||
|
echo -e "\t--vpn-ip <address> VPN server address & netmask (e.g. 10.0.50.1/24)"
|
||||||
|
echo -e "\t--vpn-gateway-ip <ip> VPN gateway external IP (! NOT DOMAIN - IP)"
|
||||||
|
echo -e "\t--vpn-gateway-port <port> VPN gateway external port (your clients connect here)"
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
command_exists() {
|
||||||
|
local command="$1"
|
||||||
|
command -v "$command" >/dev/null 2>&1
|
||||||
|
}
|
||||||
|
|
||||||
|
command_exists_check() {
|
||||||
|
local command="$1"
|
||||||
|
if ! command_exists "$command"; then
|
||||||
|
echo >&2 "ERROR: $command command not found"
|
||||||
|
echo >&2 "ERROR: dependency failed, exiting..."
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
check_environment() {
|
||||||
|
echo -n " ${TXT_BEGIN} Checking if all required tools are available..."
|
||||||
|
# compose can be provided by newer docker versions or a separate docker-compose
|
||||||
|
docker compose version >/dev/null 2>&1
|
||||||
|
if [ $? = 0 ]; then
|
||||||
|
COMPOSE_CMD="docker compose"
|
||||||
|
else
|
||||||
|
if command_exists docker-compose; then
|
||||||
|
COMPOSE_CMD="docker-compose"
|
||||||
|
else
|
||||||
|
echo
|
||||||
|
echo >&2 "ERROR: docker-compose or docker compose command not found"
|
||||||
|
echo >&2 "ERROR: dependency failed, exiting..."
|
||||||
|
exit 3
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
command_exists_check openssl
|
||||||
|
command_exists_check curl
|
||||||
|
command_exists_check grep
|
||||||
|
|
||||||
|
# Check if the volume dir is an absolute path since docker requires it
|
||||||
|
VOLUME_DIR=$(to_absolute_path "${VOLUME_DIR}")
|
||||||
|
|
||||||
|
if [ -d ${VOLUME_DIR} ]; then
|
||||||
|
echo
|
||||||
|
echo >&2 "ERROR: volume directory: ${VOLUME_DIR} exists."
|
||||||
|
echo >&2 "ERROR: this means, I would overwrite the configuration, database and certificates."
|
||||||
|
echo >&2 "ERROR: please backup or remove the volume directory."
|
||||||
|
exit 3
|
||||||
|
fi
|
||||||
|
|
||||||
|
# create all necessary directories
|
||||||
|
for dir in ${VOLUME_DIR} ${SSL_DIR} ${RSA_DIR}; do
|
||||||
|
mkdir ${dir}
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo >&2 "ERROR: cloud not create volume directory: ${dir}"
|
||||||
|
exit 3
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
print_confirmation
|
||||||
|
}
|
||||||
|
|
||||||
|
load_configuration_from_env() {
|
||||||
|
echo -n " ${TXT_BEGIN} Loading configuration from environment variables... "
|
||||||
|
# required variables
|
||||||
|
CFG_DOMAIN="$DEFGUARD_DOMAIN"
|
||||||
|
|
||||||
|
# optional variables
|
||||||
|
CFG_VOLUME_DIR="$DEFGUARD_VOLUME_DIR"
|
||||||
|
CFG_VPN_NAME="$DEFGUARD_VPN_NAME"
|
||||||
|
CFG_VPN_IP="$DEFGUARD_VPN_IP"
|
||||||
|
CFG_VPN_GATEWAY_IP="$DEFGUARD_VPN_GATEWAY_IP"
|
||||||
|
CFG_VPN_GATEWAY_PORT="$DEFGUARD_VPN_GATEWAY_PORT"
|
||||||
|
CFG_ENROLLMENT_DOMAIN="$DEFGUARD_ENROLLMENT_DOMAIN"
|
||||||
|
if ! [ $CFG_USE_HTTPS ]; then
|
||||||
|
CFG_USE_HTTPS="$DEFGUARD_USE_HTTPS"
|
||||||
|
fi
|
||||||
|
|
||||||
|
print_confirmation
|
||||||
|
}
|
||||||
|
|
||||||
|
load_configuration_from_cli() {
|
||||||
|
echo -n " ${TXT_BEGIN} Loading configuration from CLI arguments... "
|
||||||
|
|
||||||
|
ARGUMENT_LIST=(
|
||||||
|
"domain"
|
||||||
|
"enrollment-domain"
|
||||||
|
"volume"
|
||||||
|
"vpn-name"
|
||||||
|
"vpn-ip"
|
||||||
|
"vpn-gateway-ip"
|
||||||
|
"vpn-gateway-port"
|
||||||
|
)
|
||||||
|
|
||||||
|
# read arguments
|
||||||
|
opts=$(
|
||||||
|
getopt \
|
||||||
|
--longoptions "$(printf "%s:," "${ARGUMENT_LIST[@]}")" \
|
||||||
|
--name "$(basename "$0")" \
|
||||||
|
--options "" \
|
||||||
|
-- "$@"
|
||||||
|
)
|
||||||
|
|
||||||
|
eval set --$opts
|
||||||
|
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case "$1" in
|
||||||
|
--domain)
|
||||||
|
CFG_DOMAIN=$2
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
|
||||||
|
--enrollment-domain)
|
||||||
|
CFG_ENROLLMENT_DOMAIN=$2
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
|
||||||
|
--volume)
|
||||||
|
CFG_VOLUME_DIR=$2
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
|
||||||
|
--vpn-name)
|
||||||
|
CFG_VPN_NAME=$2
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
|
||||||
|
--vpn-ip)
|
||||||
|
CFG_VPN_IP=$2
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
|
||||||
|
--vpn-gateway-ip)
|
||||||
|
CFG_VPN_GATEWAY_IP=$2
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
|
||||||
|
--vpn-gateway-port)
|
||||||
|
CFG_VPN_GATEWAY_PORT=$2
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
|
||||||
|
*)
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
print_confirmation
|
||||||
|
}
|
||||||
|
|
||||||
|
load_configuration_from_input() {
|
||||||
|
echo -ne "${C_ITALICS}${C_LBLUE}"
|
||||||
|
cat << _EOF_
|
||||||
|
|
||||||
|
Please provide the values to configure your defguard instance. If you've
|
||||||
|
already configured some options by setting environment variables or through
|
||||||
|
CLI options, those will be used as defaults.
|
||||||
|
|
||||||
|
If you prefer to disable this user input section, please restart the script
|
||||||
|
with --non-interactive CLI flag.
|
||||||
|
|
||||||
|
_EOF_
|
||||||
|
|
||||||
|
echo -ne "${C_GREY}"
|
||||||
|
cat << _EOF_
|
||||||
|
|
||||||
|
Choose domains that will be used to expose your instance through Caddy
|
||||||
|
reverse proxy. defguard uses a separate domain for the Web UI, and for
|
||||||
|
the optional enrollment/desktop client configuration/password reset
|
||||||
|
service.
|
||||||
|
|
||||||
|
If you don't provide any domain for the enrollment service, the service
|
||||||
|
itself will not be deployed.
|
||||||
|
|
||||||
|
You can also enable HTTPS here (highly recommended), which will configure
|
||||||
|
Caddy to automatically provision SSL certificates.
|
||||||
|
_EOF_
|
||||||
|
|
||||||
|
echo -ne "${C_BOLD}"
|
||||||
|
cat << _EOF_
|
||||||
|
|
||||||
|
Please note that this requires your server to have a public IP address
|
||||||
|
and public DNS records for your chosen domains to be configured
|
||||||
|
correctly (pointing to your server's IP address).
|
||||||
|
|
||||||
|
_EOF_
|
||||||
|
|
||||||
|
echo -ne "${C_END}"
|
||||||
|
|
||||||
|
echo -e " ${C_BOLD}${C_GREEN}${TXT_STAR} General config ${TXT_STAR}${C_END}\n"
|
||||||
|
|
||||||
|
while [ X${domain} = "X" ]; do
|
||||||
|
echo -ne "${C_YELLOW}${TXT_INPUT}${C_END} "
|
||||||
|
read -p "Enter defguard domain [default: ${CFG_DOMAIN}]: " domain
|
||||||
|
if [ "$domain" ]; then
|
||||||
|
CFG_DOMAIN="$domain"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo -ne "${C_YELLOW}${TXT_INPUT}${C_END} "
|
||||||
|
read -p "Enter enrollment domain [default: ${CFG_ENROLLMENT_DOMAIN}]: " enroll
|
||||||
|
if [ "$enroll" ]; then
|
||||||
|
CFG_ENROLLMENT_DOMAIN="$enroll"
|
||||||
|
fi
|
||||||
|
|
||||||
|
use_https_bool_value="false"
|
||||||
|
if [ $CFG_USE_HTTPS ]; then use_https_bool_value="true"; fi
|
||||||
|
echo -ne "${C_YELLOW}${TXT_INPUT}${C_END} "
|
||||||
|
read -p "Use HTTPS [default: ${use_https_bool_value}]: " https
|
||||||
|
if [ "$https" ]; then
|
||||||
|
CFG_USE_HTTPS=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo -e " ${C_BOLD}${C_GREEN}${TXT_STAR} WireGuard VPN${TXT_STAR}${C_END}\n"
|
||||||
|
|
||||||
|
echo -ne "${C_ITALICS}${C_GREY}"
|
||||||
|
cat << _EOF_
|
||||||
|
|
||||||
|
If you wish to configure and deploy WireGuard VPN gateway, please
|
||||||
|
provide your VPN location name. To skip, just press enter and VPN will
|
||||||
|
not be configured.
|
||||||
|
_EOF_
|
||||||
|
|
||||||
|
echo -ne "${C_END}\n"
|
||||||
|
|
||||||
|
echo -ne "${C_YELLOW}${TXT_INPUT}${C_END} "
|
||||||
|
read -p "Enter VPN location name [default: ${CFG_VPN_NAME}]: " vpn_name
|
||||||
|
if [ "$vpn_name" ]; then
|
||||||
|
CFG_VPN_NAME="$vpn_name"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$CFG_VPN_NAME" ]; then
|
||||||
|
while [ X${vpn_ip} = "X" ]; do
|
||||||
|
echo -ne "${C_YELLOW}${TXT_INPUT}${C_END} "
|
||||||
|
read -p "Enter VPN server address and subnet (e.g. 10.0.60.1/24) [default: ${CFG_VPN_IP}]: " vpn_ip
|
||||||
|
if [ "$vpn_ip" ]; then
|
||||||
|
CFG_VPN_IP="$vpn_ip"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo -ne "${C_ITALICS}${C_GREY}"
|
||||||
|
cat << _EOF_
|
||||||
|
|
||||||
|
Now we'll configure a public endpoint (IP + port) that your WireGuard
|
||||||
|
client devices will use to safely connect to your gateway from the
|
||||||
|
public internet.
|
||||||
|
|
||||||
|
Since we'll be starting the gateway on this server the IP address should
|
||||||
|
be the same as your server's public IP address.
|
||||||
|
_EOF_
|
||||||
|
echo -ne "${C_BOLD}"
|
||||||
|
cat << _EOF_
|
||||||
|
Please also remember that your firewall should be configured
|
||||||
|
to allow incoming UDP traffic on the chosen WireGuard port.
|
||||||
|
_EOF_
|
||||||
|
|
||||||
|
echo -ne "${C_END}"
|
||||||
|
|
||||||
|
while [ X${public_ip} = "X" ]; do
|
||||||
|
echo -ne "${C_YELLOW}${TXT_INPUT}${C_END} "
|
||||||
|
read -p "Enter VPN gateway public IP (no domains!) [default: ${CFG_VPN_GATEWAY_IP}]: " public_ip
|
||||||
|
if [ "$public_ip" ]; then
|
||||||
|
CFG_VPN_GATEWAY_IP="$public_ip"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
while [ X${public_port} = "X" ]; do
|
||||||
|
echo -ne "${C_YELLOW}${TXT_INPUT}${C_END} "
|
||||||
|
read -p "Enter VPN gateway public port [default: ${CFG_VPN_GATEWAY_PORT}]: " public_port
|
||||||
|
if [ "$public_port" ]; then
|
||||||
|
CFG_VPN_GATEWAY_PORT="$public_port"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
else
|
||||||
|
echo -e " ${C_BOLD}${C_RED}${TXT_X} ${C_GREY} WireGuard VPN skipped${C_END}\n"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo -e "${C_BOLD}${C_GREEN}Thank you. We'll now proceed with the deployment using provided values.${C_END}"
|
||||||
|
}
|
||||||
|
|
||||||
|
check_required_variable() {
|
||||||
|
local var_name="$1"
|
||||||
|
if [ -z "${!var_name}" ]; then
|
||||||
|
echo >&2 "ERROR: ${var_name} configuration option not set"
|
||||||
|
exit 4
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
validate_required_variables() {
|
||||||
|
echo -n " ${TXT_BEGIN} Validating configuration options..."
|
||||||
|
check_required_variable "CFG_DOMAIN"
|
||||||
|
|
||||||
|
# if VPN name is given validate other VPN configurations are present
|
||||||
|
if [ "$CFG_VPN_NAME" ]; then
|
||||||
|
CFG_ENABLE_VPN=1
|
||||||
|
check_required_variable "CFG_VPN_IP"
|
||||||
|
check_required_variable "CFG_VPN_GATEWAY_IP"
|
||||||
|
check_required_variable "CFG_VPN_GATEWAY_PORT"
|
||||||
|
fi
|
||||||
|
|
||||||
|
print_confirmation
|
||||||
|
}
|
||||||
|
|
||||||
|
generate_external_urls() {
|
||||||
|
# prepare full defguard URL
|
||||||
|
if [ $CFG_USE_HTTPS ]; then
|
||||||
|
CFG_DEFGUARD_URL="https://${CFG_DOMAIN}"
|
||||||
|
else
|
||||||
|
CFG_DEFGUARD_URL="http://${CFG_DOMAIN}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# prepare full enrollment URL
|
||||||
|
if [ "$CFG_ENROLLMENT_DOMAIN" ]; then
|
||||||
|
CFG_ENABLE_ENROLLMENT=1
|
||||||
|
if [ "$CFG_USE_HTTPS" ]; then
|
||||||
|
CFG_ENROLLMENT_URL="https://${CFG_ENROLLMENT_DOMAIN}"
|
||||||
|
else
|
||||||
|
CFG_ENROLLMENT_URL="http://${CFG_ENROLLMENT_DOMAIN}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
print_config() {
|
||||||
|
echo
|
||||||
|
echo " ${TXT_BEGIN} Setting up your defguard instance with following config:"
|
||||||
|
echo
|
||||||
|
echo -e " ${TXT_SUB} data volume: ${C_BOLD}${VOLUME_DIR}${C_END}"
|
||||||
|
echo
|
||||||
|
echo -e " ${TXT_SUB} domain: ${C_BOLD}${CFG_DOMAIN}${C_END}"
|
||||||
|
echo -e " ${TXT_SUB} web UI URL: ${C_BOLD}${CFG_DEFGUARD_URL}${C_END}"
|
||||||
|
|
||||||
|
if [ "$CFG_VPN_NAME" ]; then
|
||||||
|
echo -e " ${TXT_SUB} VPN location name: ${C_BOLD}${CFG_VPN_NAME}${C_END}"
|
||||||
|
echo -e " ${TXT_SUB} VPN address: ${C_BOLD}${CFG_VPN_IP}${C_END}"
|
||||||
|
echo -e " ${TXT_SUB} VPN gateway IP: ${C_BOLD}${CFG_VPN_GATEWAY_IP}${C_END}"
|
||||||
|
echo -e " ${TXT_SUB} VPN gateway port: ${C_BOLD}${CFG_VPN_GATEWAY_PORT}${C_END}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$CFG_ENROLLMENT_DOMAIN" ]; then
|
||||||
|
echo -e " ${TXT_SUB} Enrollment service domain: ${C_BOLD}${CFG_ENROLLMENT_DOMAIN}${C_END}"
|
||||||
|
echo -e " ${TXT_SUB} Enrollment service URL: ${C_BOLD}${CFG_ENROLLMENT_URL}${C_END}"
|
||||||
|
fi
|
||||||
|
echo
|
||||||
|
echo -e " ${TXT_BEGIN} All executed command's results are in log file: ${C_BOLD}${LOG_FILE}${C_END}"
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
setup_keys() {
|
||||||
|
echo " ${TXT_BEGIN} Setting up SSL certificates and RSA keys..."
|
||||||
|
if [ -d ${SSL_DIR} -a "$(ls -A ${SSL_DIR})" ]; then
|
||||||
|
echo " ${TXT_SUB} Using existing SSL certificates from ${SSL_DIR}"
|
||||||
|
else
|
||||||
|
generate_certs
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -d ${RSA_DIR} -a "$(ls -A ${RSA_DIR})" ]; then
|
||||||
|
echo " ${TXT_SUB} Using existing RSA keys from ${RSA_DIR}."
|
||||||
|
else
|
||||||
|
generate_rsa
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
generate_certs() {
|
||||||
|
echo " ${TXT_BEGIN} Creating new SSL certificates in ${SSL_DIR}..."
|
||||||
|
mkdir -p ${SSL_DIR}
|
||||||
|
|
||||||
|
PASSPHRASE=$(generate_secret)
|
||||||
|
|
||||||
|
echo "PEM passphrase for SSL certificates set to '${PASSPHRASE}'."
|
||||||
|
|
||||||
|
# generate private key for CA
|
||||||
|
openssl genrsa -des3 -out ${SSL_DIR}/defguard-ca.key -passout pass:"${PASSPHRASE}" 2048 2>&1 >> ${LOG_FILE}
|
||||||
|
# generate Root Certificate
|
||||||
|
# TODO: allow configuring CA parameters
|
||||||
|
openssl req -x509 -new -nodes -key ${SSL_DIR}/defguard-ca.key -sha256 -days 1825 -out ${SSL_DIR}/defguard-ca.pem -passin pass:"${PASSPHRASE}" -subj "/C=PL/ST=Zachodniopomorskie/L=Szczecin/O=Example/OU=IT Department/CN=${CFG_DOMAIN}" 2>&1 >> ${LOG_FILE}
|
||||||
|
|
||||||
|
# generate CA-signed certificate for defguard gRPC
|
||||||
|
openssl genrsa -out ${SSL_DIR}/defguard-grpc.key 2048 2>&1 >> ${LOG_FILE}
|
||||||
|
|
||||||
|
openssl req -new -key ${SSL_DIR}/defguard-grpc.key -out ${SSL_DIR}/defguard-grpc.csr -subj "/C=PL/ST=Zachodniopomorskie/L=Szczecin/O=Example/OU=IT Department/CN=${CFG_DOMAIN}" 2>&1 >> ${LOG_FILE}
|
||||||
|
cat >${SSL_DIR}/defguard-grpc.ext <<EOF
|
||||||
|
authorityKeyIdentifier=keyid,issuer
|
||||||
|
basicConstraints=CA:FALSE
|
||||||
|
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
|
||||||
|
subjectAltName = @alt_names
|
||||||
|
[alt_names]
|
||||||
|
DNS.1 = ${CFG_DOMAIN}
|
||||||
|
DNS.2 = core
|
||||||
|
DNS.3 = localhost
|
||||||
|
EOF
|
||||||
|
openssl x509 -req -in ${SSL_DIR}/defguard-grpc.csr -CA ${SSL_DIR}/defguard-ca.pem -CAkey ${SSL_DIR}/defguard-ca.key -passin pass:"${PASSPHRASE}" -CAcreateserial \
|
||||||
|
-out ${SSL_DIR}/defguard-grpc.crt -days 1000 -sha256 -extfile ${SSL_DIR}/defguard-grpc.ext 2>&1 >> ${LOG_FILE}
|
||||||
|
|
||||||
|
# generate CA-signed certificate for defguard proxy gRPC
|
||||||
|
openssl genrsa -out ${SSL_DIR}/defguard-proxy-grpc.key 2048 2>&1 >> ${LOG_FILE}
|
||||||
|
|
||||||
|
openssl req -new -key ${SSL_DIR}/defguard-proxy-grpc.key -out ${SSL_DIR}/defguard-proxy-grpc.csr -subj "/C=PL/ST=Zachodniopomorskie/L=Szczecin/O=Example/OU=IT Department/CN=${CFG_DOMAIN}" 2>&1 >> ${LOG_FILE}
|
||||||
|
cat >${SSL_DIR}/defguard-proxy-grpc.ext <<EOF
|
||||||
|
authorityKeyIdentifier=keyid,issuer
|
||||||
|
basicConstraints=CA:FALSE
|
||||||
|
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
|
||||||
|
subjectAltName = @alt_names
|
||||||
|
[alt_names]
|
||||||
|
DNS.1 = proxy
|
||||||
|
DNS.2 = localhost
|
||||||
|
EOF
|
||||||
|
openssl x509 -req -in ${SSL_DIR}/defguard-proxy-grpc.csr -CA ${SSL_DIR}/defguard-ca.pem -CAkey ${SSL_DIR}/defguard-ca.key -passin pass:"${PASSPHRASE}" -CAcreateserial \
|
||||||
|
-out ${SSL_DIR}/defguard-proxy-grpc.crt -days 1000 -sha256 -extfile ${SSL_DIR}/defguard-proxy-grpc.ext 2>&1 >> ${LOG_FILE}
|
||||||
|
}
|
||||||
|
|
||||||
|
generate_rsa() {
|
||||||
|
echo "Generating RSA keys in ${RSA_DIR}..."
|
||||||
|
mkdir -p ${RSA_DIR}
|
||||||
|
openssl genpkey -out ${RSA_DIR}/rsakey.pem -algorithm RSA -pkeyopt rsa_keygen_bits:2048 2>&1 >> ${LOG_FILE}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
generate_secret() {
|
||||||
|
generate_secret_inner "${SECRET_LENGTH}"
|
||||||
|
}
|
||||||
|
|
||||||
|
generate_password() {
|
||||||
|
generate_secret_inner "${PASSWORD_LENGTH}"
|
||||||
|
}
|
||||||
|
|
||||||
|
generate_secret_inner() {
|
||||||
|
local length="$1"
|
||||||
|
openssl rand -base64 ${length} | tr -d "=+/" | tr -d '\n' | cut -c1-${length-1}
|
||||||
|
}
|
||||||
|
|
||||||
|
create_caddyfile() {
|
||||||
|
caddy_volume_path="${VOLUME_DIR}/caddy"
|
||||||
|
caddyfile_path="${caddy_volume_path}/Caddyfile"
|
||||||
|
mkdir -p ${caddy_volume_path}
|
||||||
|
|
||||||
|
cat >${caddyfile_path} <<EOF
|
||||||
|
${CFG_DEFGUARD_URL} {
|
||||||
|
reverse_proxy core:8000
|
||||||
|
}
|
||||||
|
|
||||||
|
EOF
|
||||||
|
|
||||||
|
if [ "$CFG_ENABLE_ENROLLMENT" ]; then
|
||||||
|
cat >>${caddyfile_path} <<EOF
|
||||||
|
${CFG_ENROLLMENT_URL} {
|
||||||
|
reverse_proxy proxy:8080
|
||||||
|
}
|
||||||
|
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat >>${caddyfile_path} <<EOF
|
||||||
|
:80 {
|
||||||
|
respond 404
|
||||||
|
}
|
||||||
|
:443 {
|
||||||
|
respond 404
|
||||||
|
}
|
||||||
|
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
fetch_base_compose_file() {
|
||||||
|
echo -n " ${TXT_BEGIN} Fetching base compose file to ${PROD_COMPOSE_FILE}... "
|
||||||
|
|
||||||
|
curl --proto '=https' --tlsv1.2 -sSf "${BASE_COMPOSE_FILE_URL}" -o "${PROD_COMPOSE_FILE}" 2>&1 >> ${LOG_FILE}
|
||||||
|
|
||||||
|
print_confirmation
|
||||||
|
}
|
||||||
|
|
||||||
|
generate_env_file() {
|
||||||
|
PROD_ENV_FILE="${WORK_DIR_PATH}/${ENV_FILE}"
|
||||||
|
fetch_base_env_file
|
||||||
|
update_env_file
|
||||||
|
|
||||||
|
print_confirmation
|
||||||
|
}
|
||||||
|
|
||||||
|
fetch_base_env_file() {
|
||||||
|
echo -e " ${TXT_BEGIN} Fetching base ${ENV_FILE} file for compose stack..."
|
||||||
|
|
||||||
|
curl --proto '=https' --tlsv1.2 -sSf "${BASE_ENV_FILE_URL}" -o "${PROD_ENV_FILE}" 2>&1 >> ${LOG_FILE}
|
||||||
|
print_confirmation
|
||||||
|
}
|
||||||
|
|
||||||
|
update_env_file() {
|
||||||
|
echo -n " ${TXT_BEGIN} Setting environment variables in ${ENV_FILE} file for compose stack..."
|
||||||
|
|
||||||
|
# set image versions
|
||||||
|
set_env_file_value "CORE_IMAGE_TAG" "${CORE_IMAGE_TAG}"
|
||||||
|
set_env_file_value "PROXY_IMAGE_TAG" "${PROXY_IMAGE_TAG}"
|
||||||
|
set_env_file_value "GATEWAY_IMAGE_TAG" "${GATEWAY_IMAGE_TAG}"
|
||||||
|
|
||||||
|
# fill in values
|
||||||
|
set_env_file_secret "DEFGUARD_AUTH_SECRET"
|
||||||
|
set_env_file_secret "DEFGUARD_YUBIBRIDGE_SECRET"
|
||||||
|
set_env_file_secret "DEFGUARD_GATEWAY_SECRET"
|
||||||
|
set_env_file_secret "DEFGUARD_SECRET_KEY"
|
||||||
|
|
||||||
|
# use existing password if set in env variable
|
||||||
|
if [ "$DEFGUARD_DB_PASSWORD" ]; then
|
||||||
|
set_env_file_value "DEFGUARD_DB_PASSWORD" "${DEFGUARD_DB_PASSWORD}"
|
||||||
|
else
|
||||||
|
set_env_file_password "DEFGUARD_DB_PASSWORD"
|
||||||
|
fi
|
||||||
|
|
||||||
|
DEFGUARD_DEFAULT_ADMIN_PASSWORD="$(generate_password)"
|
||||||
|
set_env_file_value "DEFGUARD_DEFAULT_ADMIN_PASSWORD" "${DEFGUARD_DEFAULT_ADMIN_PASSWORD}"
|
||||||
|
|
||||||
|
set_env_file_value "DEFGUARD_URL" "${CFG_DEFGUARD_URL}"
|
||||||
|
set_env_file_value "DEFGUARD_WEBAUTHN_RP_ID" "${CFG_DOMAIN}"
|
||||||
|
print_confirmation
|
||||||
|
}
|
||||||
|
|
||||||
|
set_env_file_value() {
|
||||||
|
# make sure variable exists in file
|
||||||
|
grep -qF "${1}=" "${PROD_ENV_FILE}" || echo "${1}=" >>"${PROD_ENV_FILE}"
|
||||||
|
sed -i "s@\(${1}\)=.*@\1=${2}@" "${PROD_ENV_FILE}"
|
||||||
|
}
|
||||||
|
|
||||||
|
set_env_file_secret() {
|
||||||
|
set_env_file_value "${1}" "$(generate_secret)" "${PROD_ENV_FILE}"
|
||||||
|
}
|
||||||
|
|
||||||
|
set_env_file_password() {
|
||||||
|
set_env_file_value "${1}" "$(generate_password)" "${PROD_ENV_FILE}"
|
||||||
|
}
|
||||||
|
|
||||||
|
uncomment_feature() {
|
||||||
|
sed -i "s@# \(.*\) # \[${1}\]@\1@" "${2}"
|
||||||
|
}
|
||||||
|
|
||||||
|
enable_enrollment() {
|
||||||
|
echo -n " ${TXT_BEGIN} Enabling enrollment proxy service in compose file..."
|
||||||
|
|
||||||
|
# update .env file
|
||||||
|
uncomment_feature "ENROLLMENT" "${PROD_ENV_FILE}"
|
||||||
|
set_env_file_value "DEFGUARD_ENROLLMENT_URL" "${CFG_ENROLLMENT_URL}"
|
||||||
|
|
||||||
|
# update compose file
|
||||||
|
uncomment_feature "ENROLLMENT" "${PROD_COMPOSE_FILE}"
|
||||||
|
|
||||||
|
print_confirmation
|
||||||
|
}
|
||||||
|
|
||||||
|
enable_vpn_gateway() {
|
||||||
|
echo " ${TXT_BEGIN} Enabling VPN gateway service..."
|
||||||
|
|
||||||
|
uncomment_feature "VPN" "${PROD_COMPOSE_FILE}"
|
||||||
|
uncomment_feature "VPN" "${PROD_ENV_FILE}"
|
||||||
|
|
||||||
|
# fetch latest image
|
||||||
|
echo " ${TXT_SUB} Fetching latest gateway image..."
|
||||||
|
$COMPOSE_CMD -f "${PROD_COMPOSE_FILE}" --env-file "${PROD_ENV_FILE}" pull gateway
|
||||||
|
|
||||||
|
# create VPN location
|
||||||
|
echo " ${TXT_BEGIN} Adding VPN to core & generating gateway token..."
|
||||||
|
VPN_NETWORK=`echo ${CFG_VPN_IP} | awk -F'[./]' '{print $1"."$2"."$3".0/"$5}'`
|
||||||
|
token=$($COMPOSE_CMD -f "${PROD_COMPOSE_FILE}" --env-file "${PROD_ENV_FILE}" run core init-vpn-location --name "${CFG_VPN_NAME}" --address "${CFG_VPN_IP}" --endpoint "${CFG_VPN_GATEWAY_IP}" --port "${CFG_VPN_GATEWAY_PORT}" --allowed-ips "${VPN_NETWORK}" | tail -n 1)
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo >&2 "ERROR: failed to create VPN network"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# add gateway token to .env file
|
||||||
|
set_env_file_value "DEFGUARD_TOKEN" "${token}"
|
||||||
|
}
|
||||||
|
|
||||||
|
print_instance_summary() {
|
||||||
|
echo
|
||||||
|
echo -e "${C_LGREEN} ${TXT_CHECK} defguard setup finished successfully${C_END}"
|
||||||
|
echo
|
||||||
|
echo "If your DNS configuration is correct your defguard instance should be available at:"
|
||||||
|
echo
|
||||||
|
echo -e "\t${TXT_SUB} Web UI: ${C_BOLD}${CFG_DEFGUARD_URL}${C_END}"
|
||||||
|
if [ "$CFG_ENABLE_ENROLLMENT" ]; then
|
||||||
|
echo -e "\t${TXT_SUB} Enrollment service: ${C_BOLD}${CFG_ENROLLMENT_URL}${C_END}"
|
||||||
|
fi
|
||||||
|
echo
|
||||||
|
echo -e " ${TXT_BEGIN} You can log into the UI using the default admin user:"
|
||||||
|
echo
|
||||||
|
echo -e "\t${TXT_SUB} username: ${C_BOLD}admin${C_END}"
|
||||||
|
echo -e "\t${TXT_SUB} password: ${C_BOLD}${DEFGUARD_DEFAULT_ADMIN_PASSWORD}${C_END}"
|
||||||
|
echo
|
||||||
|
if [ "$CFG_ENABLE_VPN" ]; then
|
||||||
|
echo -e "\t\tVPN server public endpoint is ${C_BOLD}${CFG_VPN_GATEWAY_IP}:${CFG_VPN_GATEWAY_PORT}${C_END}"
|
||||||
|
echo -e "\t\tVPN network is ${C_BOLD}${VPN_NETWORK}${C_END}"
|
||||||
|
echo -e "\t\t! Make sure your firewall allows external UDP traffic to port ${C_BOLD}${CFG_VPN_GATEWAY_PORT}${C_END} !"
|
||||||
|
echo
|
||||||
|
echo -e "\t\tTo test if the VPN is working: ping ${CFG_VPN_IP} (after connecting to VPN)"
|
||||||
|
fi
|
||||||
|
echo
|
||||||
|
echo -e "Files used to deploy your instance are stored in:"
|
||||||
|
echo -e "\t docker compose file: ${C_BOLD}${PROD_COMPOSE_FILE}${C_END}"
|
||||||
|
echo -e "\t docker compose environment: ${C_BOLD}${PROD_ENV_FILE}${C_END}"
|
||||||
|
echo
|
||||||
|
echo -e "Persistent data (docker volumes) is stored in ${C_BOLD}${VOLUME_DIR}${C_END}"
|
||||||
|
echo
|
||||||
|
echo -e " ${C_YELLOW}${TXT_STAR} To support our work, please star us on GitHub! ${TXT_STAR}${C_END}"
|
||||||
|
echo -e " ${C_YELLOW}${TXT_STAR} https://github.com/defguard/defguard ${TXT_STAR}${C_END}"
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
# run main function
|
||||||
|
main "$@" || exit 1
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 24 KiB |
@@ -0,0 +1,10 @@
|
|||||||
|
# Use userspace wireguard implementation, useful on systems without native wireguard support
|
||||||
|
|
||||||
|
# Set to 0/1
|
||||||
|
DEFGUARD_USERSPACE=0
|
||||||
|
# Defguard GRPC URL, e.g.: defguard-grpc.mycompany.com
|
||||||
|
DEFGUARD_GRPC_URL=http://192.168.1.197:50055/
|
||||||
|
# Token from Defguard app to secure gRPC connection, available on network page.
|
||||||
|
DEFGUARD_TOKEN=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJEZWZHdWFyZCIsInN1YiI6IkRFRkdVQVJELU5FVFdPUkstMiIsImNsaWVudF9pZCI6IjIiLCJleHAiOjYwMTg2NjMyMjYsIm5iZiI6MTcyMzY5NTkzMX0.cmQTo1ZIflFAW-STanDi3rgb9lqE55Hf50yetX1BSUE
|
||||||
|
# Defines how often (in seconds) should interface statistics be sent to Defguard server
|
||||||
|
DEFGUARD_STATS_PERIOD=30
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
# Use userspace wireguard implementation, useful on systems without native wireguard support
|
||||||
|
# Set to 0/1
|
||||||
|
DEFGUARD_USERSPACE=0
|
||||||
|
# Defguard GRPC URL, e.g.: defguard-grpc.mycompany.com
|
||||||
|
DEFGUARD_GRPC_URL=<DEFGUARD_GRPC_URL>
|
||||||
|
# Token from Defguard app to secure gRPC connection, available on network page.
|
||||||
|
DEFGUARD_TOKEN=<DEFGUARD_TOKEN>
|
||||||
|
# Defines how often (in seconds) should interface statistics be sent to Defguard server
|
||||||
|
DEFGUARD_STATS_PERIOD=30
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
-----BEGIN PRIVATE KEY-----
|
||||||
|
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCbzBOckyI+yISZ
|
||||||
|
8+K+wkacfAR/NJsqJ1pyq7mKa+fbWMeINharP3G0qBmL56sromxl2zgC/9VU5lnR
|
||||||
|
UwSjvA5UtwOtfAxwhtRf9gmWYA6qUC8csSLev/nwTi/BiHzeJvEJFB5y4JCMPfs/
|
||||||
|
grRVWIW79to3zIUY2PKLcY9xvQwGwn9w9nYasnESdv2931ZTWR0ibYkrhMfqt1eW
|
||||||
|
njB63ZISWWoIVirO/WfcoAMtihuGt1IK/tlARk1nT1SFAhNncG59tzMa7uz2jJIq
|
||||||
|
c3JEoAhMeClH08Yv0+rRIB3dXExEKg5/6wr8eE7hGBpBEfpaeMPQocQYwLBEH82f
|
||||||
|
vR9hioTNAgMBAAECggEABsjeWcU2ipFk5OdwCmqfdJUaBQgfcbiBAdlknRiR4kV9
|
||||||
|
evsQBakfpIRliGgwVhgerFjdmZPWkHnvk2QQIalA3oORz25FhGj6uqsWQ8wvF0+i
|
||||||
|
nZdBM34cvlBJWB4/gdUkTgboRIxu/wx78ooYnFbcjBD189QeP7TC6zuoyYU4Dts8
|
||||||
|
FaJ4FcGa+tKFWhCh2wqtGxisHOxUmgaMmkOljLcpLmEA7DpUfRew7dIHptkGylox
|
||||||
|
8ahyVVTPq8H5R1lsshvDw0MFLsS12hHtTn1yicTFQNOg8JGX9lV67fCyC3pFxLiR
|
||||||
|
ZtGcUe0MiiCVltHOqwPQEBsIcweN0SRk2JZA0FnAAQKBgQDPKveaqNuU9rY7R0QF
|
||||||
|
8mjVnbPbobrmi5k9XqvuoPOuDA/86e0BYlv7BDST8Y8hOyK9aBScg+4vCKvEptoR
|
||||||
|
AGDIjdd2GueGW/HjwZa2kjunXQk0Rn1C9OsQpwNLTR3XLwmPyWvMZLVMEx/bGuLg
|
||||||
|
lNgxj+qetmSq2jwpYLkpZqiYAQKBgQDAhUXsd5uXuDtzp8NToxaoO+juKFYIRNKF
|
||||||
|
EP6m/7Pmwb2PGAT+a7erI9wktKdpN/AL8uQjder0hOHmN/ik+nwEB04HHDQxyoXt
|
||||||
|
VzayzBuhjfEKg+QwWuRu79eTlFd2Ed4bYbsPod1XMfj9XSI64wFZZCNF2XqfRiuU
|
||||||
|
uuFkE2jMzQKBgQCVjdAnj0TNWfkd/AmIPYIey/T+VdfF/PsICaMW5oxjlgOosfrN
|
||||||
|
qAL8yAFo19ZayAUBNPTENJ2qyJivo0ADTAGSZosnkK6ZGSEbKTKy5Ag6fvhZC5X7
|
||||||
|
0zEq2VaQcsBbCnLdoSu35u/WVmwF0Xf9ZpZX2SwnnUY47MjHmjKxR5HoAQKBgQCD
|
||||||
|
FjwWVxrKo9dXWNPXDyVOR/zCrRRnbPUrRfcfHt0QMrsvw9sioZXeIfyzwY58Rmpc
|
||||||
|
uHY+7vucox5t846KR0RKOe8XSE0B2jR29vt3oyLtTgjicAvgIQOJxiWzhz5GVsQ1
|
||||||
|
QMZuTni39n7jhZbZIdi5VUXvObYU3WKvUtBFpDGnwQKBgA3GtNzxQ8vzUkciUfue
|
||||||
|
uHaStFZEASM8m+Fz6J5JDTVzeHzJA6vFQCm2YPFqWlYHZLTZsuXWknm0iCntPCMN
|
||||||
|
Bbn0J5Ap8IUg3mzm4IHVGUNkGKrLm3Go77E4ZZrYOq7O2dGdtJPQppMaJ10FXdUr
|
||||||
|
pHiQmASJ88fBasr1sQ12/2vQ
|
||||||
|
-----END PRIVATE KEY-----
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDdzCCAl+gAwIBAgIUFAaYomt0LdhGk7d3r7/cojUSpYowDQYJKoZIhvcNAQEL
|
||||||
|
BQAwSzELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk5ZMQwwCgYDVQQHDANOWUMxITAf
|
||||||
|
BgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yNDA4MTUwNzA1MDRa
|
||||||
|
Fw0zNDA4MTMwNzA1MDRaMEsxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOWTEMMAoG
|
||||||
|
A1UEBwwDTllDMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggEi
|
||||||
|
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCbzBOckyI+yISZ8+K+wkacfAR/
|
||||||
|
NJsqJ1pyq7mKa+fbWMeINharP3G0qBmL56sromxl2zgC/9VU5lnRUwSjvA5UtwOt
|
||||||
|
fAxwhtRf9gmWYA6qUC8csSLev/nwTi/BiHzeJvEJFB5y4JCMPfs/grRVWIW79to3
|
||||||
|
zIUY2PKLcY9xvQwGwn9w9nYasnESdv2931ZTWR0ibYkrhMfqt1eWnjB63ZISWWoI
|
||||||
|
VirO/WfcoAMtihuGt1IK/tlARk1nT1SFAhNncG59tzMa7uz2jJIqc3JEoAhMeClH
|
||||||
|
08Yv0+rRIB3dXExEKg5/6wr8eE7hGBpBEfpaeMPQocQYwLBEH82fvR9hioTNAgMB
|
||||||
|
AAGjUzBRMB0GA1UdDgQWBBSuVx6w1tDFOr/nxkhH5zUCoKQjnjAfBgNVHSMEGDAW
|
||||||
|
gBSuVx6w1tDFOr/nxkhH5zUCoKQjnjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3
|
||||||
|
DQEBCwUAA4IBAQATnuDVzsiLdg1D7KIWvavEv4l0aj1TzMAnev7ASoCeDumVKxrv
|
||||||
|
1F8B8gKiYtA0r1GXInq0x9o4/u7nZK00hqyPBvHmTDCwimV0KMD+XEcg28rwTfn8
|
||||||
|
0RbVcUIEMNVRs1eEV3wSUHoJMxhEf7kSGJ7X8C+zu0CEQ9loBqAAbO7unhJZuoT6
|
||||||
|
TixM0nqV5ss3hkk8RFhe3902mRT8Fit5wotNHRYquvi8yku4EZyArudjkQoalCBV
|
||||||
|
CNnhWxTug+Sc1XY6jMWdfFnU4bVK+hjuSnYwIM6VRDXmYRGuxCFf8lEfQNIRUOdF
|
||||||
|
N9Xp6iJcj0Lg3lW4i9lLS2z/jW+ICgtPYTcK
|
||||||
|
-----END CERTIFICATE-----
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
21E9338B4AD12CCAF2F29C30B8DA6E8C7D993090
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDHTCCAgUCFCHpM4tK0SzK8vKcMLjabox9mTCQMA0GCSqGSIb3DQEBCwUAMEsx
|
||||||
|
CzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOWTEMMAoGA1UEBwwDTllDMSEwHwYDVQQK
|
||||||
|
DBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwHhcNMjQwODE1MDcwNTQ5WhcNMjUw
|
||||||
|
ODE1MDcwNTQ5WjBLMQswCQYDVQQGEwJVUzELMAkGA1UECAwCTlkxDDAKBgNVBAcM
|
||||||
|
A05ZQzEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkq
|
||||||
|
hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu9RdFYdklQ94lioWaFDEOb/1KeQ8BQ1X
|
||||||
|
b0YjYvgJ+rWobMNRls7A12g+gJ8EAPVDP7p9YaC06ovievSfaueC9byo9lfWsUrW
|
||||||
|
mwNA4/lH82j+/qKl8Yi8doBnQ6UAlSmt/g0PYE+/PQvRahld1K0LvqOpZIVa5imv
|
||||||
|
NY0h9Bt9J9gYKSZPvTh4MapsWGdVurkLUvQglfU4DpHKGvRoGT1nMYKX7BlFgtkM
|
||||||
|
hzD4jRoyOFyXwyyL9UFqHFYUozscPmm5deX0nNcfOs0NUOBHp11u+MG8R9mThct2
|
||||||
|
JzEmu9lXxshBVk1Yrf7kHpZuW0YrvqNCSRYu9MiBiPSTZGdt1TrsoQIDAQABMA0G
|
||||||
|
CSqGSIb3DQEBCwUAA4IBAQAW17f+yj2IJis7SmrKFho1+bQapQac0err61g7jGYS
|
||||||
|
5Jo7f0Qvk7K5FUwwAbqF6zr8C31+PZrZmou1n8ht6y4rf/mmZV3ujuSf8cRuX9Jr
|
||||||
|
RpBpwDhBQU51/iZaQm+eDwuw8KJDGnHRQE7EzP6CNO5G9M7YblI3nJdcbXIog1Y7
|
||||||
|
JgOOf5UZmerVhQm9wUNvVJ19p4qWW5u1AGXSaXTu2tcj6NSMITT2lLL321AdL4Vs
|
||||||
|
Zl7vpUV6ZbyDd7rYwqXnWEFLIWWTi9CKk8nSe130oag8PPhNCOFUY39M/1u1ZfeC
|
||||||
|
LypC2FNYJseA+xZnZXxAXkDOBLt8rIxTykVxAR8idElN
|
||||||
|
-----END CERTIFICATE-----
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
-----BEGIN CERTIFICATE REQUEST-----
|
||||||
|
MIICrzCCAZcCAQAwSzELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk5ZMQwwCgYDVQQH
|
||||||
|
DANOWUMxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDCCASIwDQYJ
|
||||||
|
KoZIhvcNAQEBBQADggEPADCCAQoCggEBALvUXRWHZJUPeJYqFmhQxDm/9SnkPAUN
|
||||||
|
V29GI2L4Cfq1qGzDUZbOwNdoPoCfBAD1Qz+6fWGgtOqL4nr0n2rngvW8qPZX1rFK
|
||||||
|
1psDQOP5R/No/v6ipfGIvHaAZ0OlAJUprf4ND2BPvz0L0WoZXdStC76jqWSFWuYp
|
||||||
|
rzWNIfQbfSfYGCkmT704eDGqbFhnVbq5C1L0IJX1OA6Ryhr0aBk9ZzGCl+wZRYLZ
|
||||||
|
DIcw+I0aMjhcl8Msi/VBahxWFKM7HD5puXXl9JzXHzrNDVDgR6ddbvjBvEfZk4XL
|
||||||
|
dicxJrvZV8bIQVZNWK3+5B6WbltGK76jQkkWLvTIgYj0k2RnbdU67KECAwEAAaAf
|
||||||
|
MB0GCSqGSIb3DQEJBzEQDA5aYWthcmlhMTk4NiEhITANBgkqhkiG9w0BAQsFAAOC
|
||||||
|
AQEAUae4G2/G01LzT4MyTRhXja8uU1AKbxx7KztIN9WxWsRgQJjLte9gcANcsku+
|
||||||
|
e+yrMlfm+LjTRH6bG3yNyyxFWncS8IyG3a+N2rvXoEO4lMIwQfyanYPyOB0ONoR3
|
||||||
|
fzB+Ssgw8txiXwOSIG7KsQkebJ30aSqUe6FuUd9kY02bx1NYGvctf9mtBv+d9Q5Y
|
||||||
|
xYv1S0S6TtjB9PnUMWdfLm0Xmj9X0XzPjKrtxwamJ/AF3uTsQseuqcKQpbLCd32r
|
||||||
|
w0mjeZHtVrDgrxVgqxt1c86eAHwnhmD4jy9Vl2tJLcPNIXvTQNxoi5h/tYi1TlD3
|
||||||
|
Mj6K46g29ee1HiLaL7ZbJb7Geg==
|
||||||
|
-----END CERTIFICATE REQUEST-----
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
-----BEGIN PRIVATE KEY-----
|
||||||
|
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC71F0Vh2SVD3iW
|
||||||
|
KhZoUMQ5v/Up5DwFDVdvRiNi+An6tahsw1GWzsDXaD6AnwQA9UM/un1hoLTqi+J6
|
||||||
|
9J9q54L1vKj2V9axStabA0Dj+UfzaP7+oqXxiLx2gGdDpQCVKa3+DQ9gT789C9Fq
|
||||||
|
GV3UrQu+o6lkhVrmKa81jSH0G30n2BgpJk+9OHgxqmxYZ1W6uQtS9CCV9TgOkcoa
|
||||||
|
9GgZPWcxgpfsGUWC2QyHMPiNGjI4XJfDLIv1QWocVhSjOxw+abl15fSc1x86zQ1Q
|
||||||
|
4EenXW74wbxH2ZOFy3YnMSa72VfGyEFWTVit/uQelm5bRiu+o0JJFi70yIGI9JNk
|
||||||
|
Z23VOuyhAgMBAAECggEAKwwkuUZqeu8sx92lfQrlrgacfZldWBsSquH8QjZusxLn
|
||||||
|
IuYw0MtZzwSJLplDJaUQYI6xJarbS9X7dgqSbsHYddFjN/IxtjhcrvIz8Qu0vciW
|
||||||
|
iG1mctDPwKj1Ab/TPlxrEAqWN5CPV8JZoGNn6dIvGuYPcIZPquhqy28pFPUn3fV3
|
||||||
|
cSS2dR3D6OU6yxEImZGffDwrZdXTTM+N1QMLHl4ivPzIjzrbwlVMVVODKracNvUE
|
||||||
|
79wYcieiEgbAM3DzlHnaW4BINw2ugoWFTAKMtHiVV8U3wQhDKvwljgFMTjB9O6PQ
|
||||||
|
nXRzoVwW5KX9gwpo9CBNVWn8/D+S04KHObC4cIKeQQKBgQD3ugq2sU1zXnBh/n7P
|
||||||
|
4Ac0Fv8Xwd/Ai3gRraJ3fFHKdwWKIL0m5DWDvALhoM+I/joLgUy0SV05R+iQzSu3
|
||||||
|
3hLrp9GqWn/drNOvUhnPeO1MwvHATpDRCEkza5I1uRn6wZf95eclvDgocqnutWGv
|
||||||
|
t43sccm38iivIzs2YYmPdgQ75QKBgQDCGjnxXwU/wHV+uOFNSs5R/LIpCpqGzoW7
|
||||||
|
5PQguJQOQY2Gq3aoPwnSGycgkOfkg2cibv04lDuoCnooYAc6SZy0N0wy9FDAsuzB
|
||||||
|
+6RNHGrr3jsqKJkRPwDal4Hb9AIMkhcIt9RIzEjO4nMKb7GxkhKD5glFVxWlNmMT
|
||||||
|
CWmXuIo6DQKBgQDM1epx8d1m3dnzTWoyHL4YFkPLsyV+olQf2gES55sB3LSZ6EQ/
|
||||||
|
Wkfdq6J+SmgQkJYSWVHBaUBKUuk8gkn5+QiQDu3Q/I/qDjPjLfHlmcotxKv9JXmd
|
||||||
|
Pkq41+PHxEx1CYrSCD2++Ak/eMCGfzhNAWu67MOs8/EsD+ewKaqDE0Sg+QKBgAVx
|
||||||
|
ktpwHceR8Dmjmb3/MRYfjieUgozxUdLZMveP9acIs51pRaSmT/IyjMBfEAHapZPT
|
||||||
|
pQpnLd0inhZvywQZeGmde2eaboFZA0bVdeArwdvnmaUvCkvvhmibAytWBpCvsDGw
|
||||||
|
ZiW8hPY4Z52NUGB4hkhotS3aqWK+ybyI8QsuQ8IpAoGBAIsY6ARakykXZueMGLQN
|
||||||
|
B7n5cyoWlQNr3iD0UCUMDHqjUe8IUIfw1ZMaHun+aI3UaY/chHBkaxfy+0IQatNd
|
||||||
|
1F9wmCNmHrjjoBLPEqPvh7TeAEfzexi4fnadLukXWb9KyZLA9YEdos4CK9EE0+Nx
|
||||||
|
6r076e6gFIRQr09qR7pGz9TQ
|
||||||
|
-----END PRIVATE KEY-----
|
||||||
BIN
Binary file not shown.
@@ -0,0 +1,22 @@
|
|||||||
|
|
||||||
|
services:
|
||||||
|
gateway:
|
||||||
|
image: ghcr.io/defguard/gateway:latest
|
||||||
|
restart: unless-stopped
|
||||||
|
network_mode: "host"
|
||||||
|
environment:
|
||||||
|
# load variables from .env file
|
||||||
|
- DEFGUARD_GRPC_URL
|
||||||
|
- DEFGUARD_TOKEN
|
||||||
|
- DEFGUARD_STATS_PERIOD
|
||||||
|
- RUST_LOG=debug
|
||||||
|
# SSL setup guide: https://defguard.gitbook.io/defguard/features/setting-up-your-instance/docker-compose#ssl-setup
|
||||||
|
- DEFGUARD_GRPC_CA=/ssl/defguard-ca.pem
|
||||||
|
#ports:
|
||||||
|
# wireguard endpoint
|
||||||
|
#- "51820:50051/udp"
|
||||||
|
volumes:
|
||||||
|
# SSL setup guide: https://defguard.gitbook.io/defguard/features/setting-up-your-instance/docker-compose#ssl-setup
|
||||||
|
- ./.volumes/ssl:/ssl
|
||||||
|
cap_add:
|
||||||
|
- NET_ADMIN
|
||||||
Reference in New Issue
Block a user