Skip to content

Commit

Permalink
feat!: allow configurability of SSH and harden application settings (#…
Browse files Browse the repository at this point in the history
…196)

## Description

This PR disables SSH more fully by default but adds an option to
reconfigure it later - it also adds a way to harden specific settings in
GitLab declaratively.

> [!IMPORTANT]
> ⚠️ BREAKING CHANGE - this is a breaking change as it will force
hardened settings on the end user unless the settingsJob is disabled or
reconfigured.

## Related Issue

Fixes #189 
Fixes #190 

## Type of change

- [ ] Bug fix (non-breaking change which fixes an issue)
- [X] New feature (non-breaking change which adds functionality)
- [ ] Other (security config, docs update, etc)

## Checklist before merging

- [X] Test, docs, adr added or updated as needed
- [X] [Contributor Guide
Steps](https://github.com/defenseunicorns/uds-package-gitlab/blob/main/CONTRIBUTING.md#developer-workflow)
followed

Release-As: v17.2.7-uds.1
  • Loading branch information
Racer159 authored Sep 24, 2024
1 parent 6ea19d2 commit bcd34c6
Show file tree
Hide file tree
Showing 38 changed files with 454 additions and 73 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/commitlint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ on:
jobs:
validate:
name: Validate
uses: defenseunicorns/uds-common/.github/workflows/commitlint.yaml@76287d41ec5f06ecbdd0a6453877a78675aceffe # v0.11.2
uses: defenseunicorns/uds-common/.github/workflows/commitlint.yaml@e3008473beab00b12a94f9fcc7340124338d5c08 # v0.13.1
2 changes: 1 addition & 1 deletion .github/workflows/lint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
fetch-depth: 0

- name: Environment setup
uses: defenseunicorns/uds-common/.github/actions/setup@76287d41ec5f06ecbdd0a6453877a78675aceffe # v0.11.2
uses: defenseunicorns/uds-common/.github/actions/setup@e3008473beab00b12a94f9fcc7340124338d5c08 # v0.13.1
with:
registry1Username: ${{ secrets.IRON_BANK_ROBOT_USERNAME }}
registry1Password: ${{ secrets.IRON_BANK_ROBOT_PASSWORD }}
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/tag-and-release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ jobs:
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7

- name: Environment setup
uses: defenseunicorns/uds-common/.github/actions/setup@76287d41ec5f06ecbdd0a6453877a78675aceffe # v0.11.2
uses: defenseunicorns/uds-common/.github/actions/setup@e3008473beab00b12a94f9fcc7340124338d5c08 # v0.13.1
with:
registry1Username: ${{ secrets.IRON_BANK_ROBOT_USERNAME }}
registry1Password: ${{ secrets.IRON_BANK_ROBOT_PASSWORD }}
Expand All @@ -67,10 +67,10 @@ jobs:

- name: Debug Output
if: ${{ always() }}
uses: defenseunicorns/uds-common/.github/actions/debug-output@76287d41ec5f06ecbdd0a6453877a78675aceffe # v0.11.2
uses: defenseunicorns/uds-common/.github/actions/debug-output@e3008473beab00b12a94f9fcc7340124338d5c08 # v0.13.1

- name: Save logs
if: always()
uses: defenseunicorns/uds-common/.github/actions/save-logs@76287d41ec5f06ecbdd0a6453877a78675aceffe # v0.11.2
uses: defenseunicorns/uds-common/.github/actions/save-logs@e3008473beab00b12a94f9fcc7340124338d5c08 # v0.13.1
with:
suffix: '${{ matrix.flavor }}-${{ matrix.architecture }}-${{ github.run_id }}-${{ github.run_attempt }}'
8 changes: 4 additions & 4 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -46,25 +46,25 @@ jobs:
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7

- name: Environment setup
uses: defenseunicorns/uds-common/.github/actions/setup@76287d41ec5f06ecbdd0a6453877a78675aceffe # v0.11.2
uses: defenseunicorns/uds-common/.github/actions/setup@e3008473beab00b12a94f9fcc7340124338d5c08 # v0.13.1
with:
registry1Username: ${{ secrets.IRON_BANK_ROBOT_USERNAME }}
registry1Password: ${{ secrets.IRON_BANK_ROBOT_PASSWORD }}
ghToken: ${{ secrets.GITHUB_TOKEN }}

- name: Test
uses: defenseunicorns/uds-common/.github/actions/test@76287d41ec5f06ecbdd0a6453877a78675aceffe # v0.11.2
uses: defenseunicorns/uds-common/.github/actions/test-deploy@e3008473beab00b12a94f9fcc7340124338d5c08 # v0.13.1
with:
flavor: ${{ matrix.flavor }}
type: ${{ matrix.type }}

- name: Debug Output
if: ${{ always() }}
uses: defenseunicorns/uds-common/.github/actions/debug-output@76287d41ec5f06ecbdd0a6453877a78675aceffe # v0.11.2
uses: defenseunicorns/uds-common/.github/actions/debug-output@e3008473beab00b12a94f9fcc7340124338d5c08 # v0.13.1

- name: Save logs
if: always()
uses: defenseunicorns/uds-common/.github/actions/save-logs@76287d41ec5f06ecbdd0a6453877a78675aceffe # v0.11.2
uses: defenseunicorns/uds-common/.github/actions/save-logs@e3008473beab00b12a94f9fcc7340124338d5c08 # v0.13.1
with:
suffix: ${{ matrix.type }}-${{ matrix.flavor }}-${{ github.run_id }}-${{ github.run_attempt }}

Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,6 @@ overlay-values-*
# Tests
node_modules/
.playwright/
tests/data/gitlab-test-ssh-key
tests/data/gitlab-test-ssh-key.pub
tests/data/uds-package-test-*
2 changes: 1 addition & 1 deletion .yamllint
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ yaml-files:
- '.yamllint'

ignore:
- '**/chart/templates**'
- '**/charts/**/templates**'

rules:
anchors: enable
Expand Down
13 changes: 13 additions & 0 deletions bundle/uds-bundle.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@ packages:
overrides:
gitlab:
uds-gitlab-config:
values:
- path: ssh.enabled
value: true
- path: ssh.port
value: 2223
variables:
- name: GITLAB_SSO_ENABLED
description: "Boolean to enable or disable sso things"
Expand All @@ -90,6 +95,10 @@ packages:
path: "sso.requiredGroups"
gitlab:
values:
- path: gitlab.gitlab-shell.enabled
value: true
- path: global.shell.port
value: 2223
- path: global.psql.host
value: pg-cluster.postgres.svc.cluster.local
- path: "global.psql.username"
Expand Down Expand Up @@ -132,3 +141,7 @@ packages:
- name: SHELL_REPLICAS
description: "Gitlab Shell Min Replicas"
path: "gitlab.gitlab-shell.minReplicas"
uds-gitlab-settings:
values:
- path: settingsJob.application.enabled_git_access_protocol
value: all
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
17 changes: 17 additions & 0 deletions charts/config/templates/ssh-gateway.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{{- if .Values.ssh.enabled }}
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
name: gitlab-ssh-gateway
namespace: istio-tenant-gateway
spec:
selector:
app: tenant-ingressgateway
servers:
- hosts:
- gitlab.{{ .Values.domain }}
port:
name: tcp-ssh
number: {{ .Values.ssh.port }}
protocol: TCP
{{- end }}
20 changes: 20 additions & 0 deletions charts/config/templates/ssh-virtual-service.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{{- if .Values.ssh.enabled }}
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: gitlab-ssh
namespace: {{ .Release.Namespace }}
spec:
gateways:
- istio-tenant-gateway/gitlab-ssh-gateway
hosts:
- gitlab.{{ .Values.domain }}
tcp:
- match:
- port: {{ .Values.ssh.port }}
route:
- destination:
host: gitlab-gitlab-shell.gitlab.svc.cluster.local
port:
number: {{ .Values.ssh.port }}
{{- end }}
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,17 @@ spec:
- direction: Ingress
remoteGenerated: IntraNamespace

{{- if .Values.ssh.enabled }}
- direction: Ingress
selector:
app: gitlab-shell
remoteNamespace: istio-tenant-gateway
remoteSelector:
app: tenant-ingressgateway
port: 2222
description: "SSH Ingress"
{{- end }}

# ingress from runner only if runner lives in cluster. Otherwise, it goes through the gateway
{{- if .Values.runner.internal }}
- direction: Ingress
Expand Down
5 changes: 5 additions & 0 deletions chart/values.yaml → charts/config/values.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
domain: "###ZARF_VAR_DOMAIN###"

ssh:
enabled: false
port: 2222

sso:
enabled: true
protocol: saml
Expand Down
23 changes: 23 additions & 0 deletions charts/settings/.helmignore
Original file line number Diff line number Diff line change
@@ -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/
18 changes: 18 additions & 0 deletions charts/settings/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
apiVersion: v2
name: uds-gitlab-settings
description: uds-gitlab-settings

# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application

# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 0.1.0
43 changes: 43 additions & 0 deletions charts/settings/templates/_settings-pod.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Reusable Pod spec for settings jobs
{{- define "uds-gitlab-settings.settings-pod" }}
metadata:
labels:
app: gitlab
spec:
serviceAccountName: gitlab-settings-sa
containers:
- name: gitlab-settings
image: "{{ .Values.global.kubectl.image.repository }}:{{ .Values.global.kubectl.image.tag }}"
command: ["/bin/sh", "-c"]
args:
- |
# Read the JSON file from the mounted application settings secret
SETTINGS=$(cat /etc/gitlab-settings/application.json)

# Dynamically parse each key-value pair in the JSON using yq and construct query parameters
QUERY_PARAMS=$(echo $SETTINGS | yq e 'to_entries | map("\(.key)=\(.value)") | join("&")' -)

# Generate and capture a GitLab token from the GitLab Toolbox Rails Console
TOKEN=$(kubectl exec -n gitlab deployment/gitlab-toolbox -- \
gitlab-rails runner -e production \
"random_token = SecureRandom.hex(32); token = User.find_by_username('root').personal_access_tokens.create(scopes: ['api', 'admin_mode'], name: 'Application Settings Token', expires_at: 1.days.from_now); token.set_token(random_token); token.save!; puts random_token" | tail -n 1)

# Use the generated token to set GitLab settings
kubectl exec -n gitlab deployment/gitlab-toolbox -- \
curl --request PUT --header "PRIVATE-TOKEN: $TOKEN" \
"http://gitlab-webservice-default.gitlab.svc.cluster.local:8181/api/v4/application/settings?$QUERY_PARAMS"

# Revoke the token after use
kubectl exec -n gitlab deployment/gitlab-toolbox -- \
gitlab-rails runner -e production \
"token = PersonalAccessToken.find_by_token('$TOKEN'); token.revoke!"
volumeMounts:
- name: gitlab-settings-volume
mountPath: /etc/gitlab-settings
readOnly: true
restartPolicy: OnFailure
volumes:
- name: gitlab-settings-volume
secret:
secretName: gitlab-settings-secret
{{- end }}
40 changes: 40 additions & 0 deletions charts/settings/templates/service-account-role.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{{- if .Values.settingsJob.enabled }}
apiVersion: v1
kind: ServiceAccount
metadata:
name: gitlab-settings-sa
namespace: {{ .Release.Namespace }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: gitlab-settings-role
namespace: {{ .Release.Namespace }}
rules:
# Only allow exec into the toolbox pod
- apiGroups: [""]
resources: ["pods/exec"]
verbs: ["create"]
- apiGroups: [""]
resources: ["pods"]
verbs: ["list"]
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get"]
resourceNames:
- gitlab-toolbox
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: gitlab-settings-rolebinding
namespace: {{ .Release.Namespace }}
subjects:
- kind: ServiceAccount
name: gitlab-settings-sa
namespace: {{ .Release.Namespace }}
roleRef:
kind: Role
name: gitlab-settings-role
apiGroup: rbac.authorization.k8s.io
{{- end }}
17 changes: 17 additions & 0 deletions charts/settings/templates/settings-cron-job.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{{- if .Values.settingsJob.enabled }}
# CronJob to reapply settings on schedule
apiVersion: batch/v1
kind: CronJob
metadata:
name: gitlab-settings-cronjob
namespace: {{ .Release.Namespace }}
spec:
schedule: "{{ .Values.settingsJob.schedule }}"
successfulJobsHistoryLimit: 1
failedJobsHistoryLimit: 1
jobTemplate:
spec:
ttlSecondsAfterFinished: 30
template:
{{ include "uds-gitlab-settings.settings-pod" . | indent 8 }}
{{- end }}
12 changes: 12 additions & 0 deletions charts/settings/templates/settings-job.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{{- if .Values.settingsJob.enabled }}
# Job to apply settings immediately on deployment
apiVersion: batch/v1
kind: Job
metadata:
name: gitlab-settings-job
namespace: {{ .Release.Namespace }}
spec:
ttlSecondsAfterFinished: 30
template:
{{ include "uds-gitlab-settings.settings-pod" . | indent 4 }}
{{- end }}
10 changes: 10 additions & 0 deletions charts/settings/templates/settings-secret.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{{- if .Values.settingsJob.enabled }}
apiVersion: v1
kind: Secret
metadata:
name: gitlab-settings-secret
namespace: gitlab
type: Opaque
stringData:
application.json: {{ .Values.settingsJob.application | toJson | quote }}
{{- end }}
Loading

0 comments on commit bcd34c6

Please sign in to comment.