Adds guacd-exec ServiceAccount, ClusterRole (pods/exec), and ClusterRoleBinding for Kubernetes protocol support.
427 lines
9.8 KiB
YAML
427 lines
9.8 KiB
YAML
# Apache Guacamole - Blue Jay Remote Access
|
|
# FlowerCore Infrastructure Gateway
|
|
# MySQL 8 + guacd + guacamole web (Blue Jay branded)
|
|
# ArgoCD managed - BlueJay Lab
|
|
# ALL credentials sourced from 1Password via OnePasswordItem CRD (guacamole-credentials)
|
|
# Custom image: fc-guacamole:bluejay (Blue Jay branding + 1Password vault extension)
|
|
---
|
|
apiVersion: v1
|
|
kind: Namespace
|
|
metadata:
|
|
name: guacamole
|
|
labels:
|
|
app.kubernetes.io/part-of: bluejay-infra
|
|
---
|
|
# MySQL 8 StatefulSet
|
|
apiVersion: apps/v1
|
|
kind: StatefulSet
|
|
metadata:
|
|
name: guac-mysql
|
|
namespace: guacamole
|
|
labels:
|
|
app: guac-mysql
|
|
spec:
|
|
serviceName: guac-mysql
|
|
replicas: 1
|
|
selector:
|
|
matchLabels:
|
|
app: guac-mysql
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app: guac-mysql
|
|
spec:
|
|
containers:
|
|
- name: mysql
|
|
image: mysql:8.0
|
|
ports:
|
|
- containerPort: 3306
|
|
name: mysql
|
|
env:
|
|
- name: MYSQL_ROOT_PASSWORD
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: guacamole-credentials
|
|
key: DB-Root-Password
|
|
- name: MYSQL_DATABASE
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: guacamole-credentials
|
|
key: DB-Name
|
|
- name: MYSQL_USER
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: guacamole-credentials
|
|
key: DB-User
|
|
- name: MYSQL_PASSWORD
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: guacamole-credentials
|
|
key: DB-Password
|
|
volumeMounts:
|
|
- name: guac-mysql-data
|
|
mountPath: /var/lib/mysql
|
|
resources:
|
|
requests:
|
|
memory: 256Mi
|
|
cpu: 100m
|
|
limits:
|
|
memory: 1Gi
|
|
cpu: 500m
|
|
livenessProbe:
|
|
exec:
|
|
command:
|
|
- mysqladmin
|
|
- ping
|
|
- -h
|
|
- localhost
|
|
initialDelaySeconds: 60
|
|
periodSeconds: 10
|
|
readinessProbe:
|
|
exec:
|
|
command:
|
|
- mysqladmin
|
|
- ping
|
|
- -h
|
|
- localhost
|
|
initialDelaySeconds: 30
|
|
periodSeconds: 5
|
|
volumeClaimTemplates:
|
|
- metadata:
|
|
name: guac-mysql-data
|
|
spec:
|
|
accessModes: [ReadWriteOnce]
|
|
resources:
|
|
requests:
|
|
storage: 5Gi
|
|
---
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
name: guac-mysql
|
|
namespace: guacamole
|
|
spec:
|
|
selector:
|
|
app: guac-mysql
|
|
ports:
|
|
- port: 3306
|
|
targetPort: 3306
|
|
name: mysql
|
|
clusterIP: None
|
|
---
|
|
# DB schema init Job
|
|
apiVersion: batch/v1
|
|
kind: Job
|
|
metadata:
|
|
name: guacamole-initdb
|
|
namespace: guacamole
|
|
annotations:
|
|
argocd.argoproj.io/hook: PostSync
|
|
argocd.argoproj.io/hook-delete-policy: BeforeHookCreation
|
|
spec:
|
|
ttlSecondsAfterFinished: 300
|
|
template:
|
|
spec:
|
|
restartPolicy: OnFailure
|
|
initContainers:
|
|
- name: wait-for-mysql
|
|
image: mysql:8.0
|
|
command:
|
|
- sh
|
|
- -c
|
|
- |
|
|
until mysqladmin ping -h guac-mysql --silent; do
|
|
echo "Waiting for MySQL..."
|
|
sleep 5
|
|
done
|
|
containers:
|
|
- name: initdb
|
|
image: guacamole/guacamole:latest
|
|
command:
|
|
- sh
|
|
- -c
|
|
- |
|
|
/opt/guacamole/bin/initdb.sh --mysql > /tmp/initdb.sql
|
|
mysql -h guac-mysql -u root -p"$MYSQL_ROOT_PASSWORD" "$MYSQL_DATABASE" < /tmp/initdb.sql || true
|
|
env:
|
|
- name: MYSQL_ROOT_PASSWORD
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: guacamole-credentials
|
|
key: DB-Root-Password
|
|
- name: MYSQL_DATABASE
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: guacamole-credentials
|
|
key: DB-Name
|
|
---
|
|
# guacd (Guacamole daemon)
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: guacd
|
|
namespace: guacamole
|
|
labels:
|
|
app: guacd
|
|
spec:
|
|
replicas: 1
|
|
selector:
|
|
matchLabels:
|
|
app: guacd
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app: guacd
|
|
spec:
|
|
containers:
|
|
serviceAccountName: guacd-exec
|
|
- name: guacd
|
|
image: guacamole/guacd:latest
|
|
ports:
|
|
- containerPort: 4822
|
|
name: guacd
|
|
resources:
|
|
requests:
|
|
memory: 128Mi
|
|
cpu: 100m
|
|
limits:
|
|
memory: 512Mi
|
|
cpu: 500m
|
|
livenessProbe:
|
|
tcpSocket:
|
|
port: 4822
|
|
initialDelaySeconds: 15
|
|
periodSeconds: 10
|
|
---
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
name: guacd
|
|
namespace: guacamole
|
|
spec:
|
|
selector:
|
|
app: guacd
|
|
ports:
|
|
- port: 4822
|
|
targetPort: 4822
|
|
name: guacd
|
|
---
|
|
# Guacamole Properties ConfigMap
|
|
apiVersion: v1
|
|
kind: ConfigMap
|
|
metadata:
|
|
name: guacamole-properties
|
|
namespace: guacamole
|
|
labels:
|
|
app: guacamole
|
|
data:
|
|
guacamole.properties: |
|
|
# Blue Jay Remote Access — Guacamole Configuration
|
|
# MySQL/guacd settings provided via env vars — do NOT duplicate here
|
|
|
|
# 1Password Vault Integration
|
|
1password-connect-url: http://onepassword-connect.onepassword-system.svc.cluster.local:8080
|
|
1password-connect-token: placeholder-configure-via-secret
|
|
1password-vault-id: qaphopopkryhbg353ukzhhuqoq
|
|
|
|
# Extension Priority
|
|
extension-priority: mysql, ban, bluejay, 1password-vault, *
|
|
|
|
# Ban (brute force)
|
|
ban-max-invalid-attempts: 5
|
|
ban-address-duration: 300000
|
|
ban-max-addresses: 1000
|
|
|
|
# TOTP
|
|
totp-issuer: Blue Jay Remote Access
|
|
totp-digits: 6
|
|
totp-period: 30
|
|
totp-mode: sha256
|
|
|
|
# Session Recording
|
|
recording-search-path: /var/lib/guacamole/recordings
|
|
|
|
# Logging
|
|
log-level: info
|
|
|
|
# API Token Expiry
|
|
api-session-timeout: 60
|
|
---
|
|
# Guacamole Web Application — Blue Jay branded
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: guacamole
|
|
namespace: guacamole
|
|
labels:
|
|
app: guacamole
|
|
spec:
|
|
replicas: 1
|
|
selector:
|
|
matchLabels:
|
|
app: guacamole
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app: guacamole
|
|
spec:
|
|
containers:
|
|
- name: guacamole
|
|
image: localhost/fc-guacamole:bluejay
|
|
imagePullPolicy: Never
|
|
ports:
|
|
- containerPort: 8080
|
|
name: http
|
|
env:
|
|
- name: GUACD_HOSTNAME
|
|
value: guacd
|
|
- name: GUACD_PORT
|
|
value: "4822"
|
|
- name: MYSQL_HOSTNAME
|
|
value: guac-mysql
|
|
- name: MYSQL_PORT
|
|
value: "3306"
|
|
- name: MYSQL_DATABASE
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: guacamole-credentials
|
|
key: DB-Name
|
|
- name: MYSQL_USER
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: guacamole-credentials
|
|
key: DB-User
|
|
- name: MYSQL_PASSWORD
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: guacamole-credentials
|
|
key: DB-Password
|
|
volumeMounts:
|
|
- name: guac-properties
|
|
mountPath: /etc/guacamole/guacamole.properties
|
|
subPath: guacamole.properties
|
|
resources:
|
|
requests:
|
|
memory: 256Mi
|
|
cpu: 100m
|
|
limits:
|
|
memory: 1Gi
|
|
cpu: 500m
|
|
livenessProbe:
|
|
httpGet:
|
|
path: /guacamole/
|
|
port: 8080
|
|
initialDelaySeconds: 120
|
|
periodSeconds: 10
|
|
readinessProbe:
|
|
httpGet:
|
|
path: /guacamole/
|
|
port: 8080
|
|
initialDelaySeconds: 60
|
|
periodSeconds: 5
|
|
volumes:
|
|
- name: guac-properties
|
|
configMap:
|
|
name: guacamole-properties
|
|
---
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
name: guacamole
|
|
namespace: guacamole
|
|
spec:
|
|
selector:
|
|
app: guacamole
|
|
ports:
|
|
- port: 8080
|
|
targetPort: 8080
|
|
name: http
|
|
---
|
|
# Traefik addPrefix middleware
|
|
apiVersion: traefik.io/v1alpha1
|
|
kind: Middleware
|
|
metadata:
|
|
name: guac-add-prefix
|
|
namespace: guacamole
|
|
spec:
|
|
addPrefix:
|
|
prefix: /guacamole
|
|
---
|
|
# TLS Certificate via cert-manager
|
|
apiVersion: cert-manager.io/v1
|
|
kind: Certificate
|
|
metadata:
|
|
name: guacamole-tls
|
|
namespace: guacamole
|
|
spec:
|
|
secretName: guacamole-tls
|
|
issuerRef:
|
|
name: step-ca-acme
|
|
kind: ClusterIssuer
|
|
dnsNames:
|
|
- guac.iamworkin.lan
|
|
---
|
|
# Traefik IngressRoute
|
|
apiVersion: traefik.io/v1alpha1
|
|
kind: IngressRoute
|
|
metadata:
|
|
name: guacamole
|
|
namespace: guacamole
|
|
spec:
|
|
entryPoints:
|
|
- websecure
|
|
routes:
|
|
- match: Host(`guac.iamworkin.lan`)
|
|
kind: Rule
|
|
middlewares:
|
|
- name: guac-add-prefix
|
|
services:
|
|
- name: guacamole
|
|
port: 8080
|
|
tls:
|
|
secretName: guacamole-tls
|
|
---
|
|
# 1Password secret sync
|
|
apiVersion: onepassword.com/v1
|
|
kind: OnePasswordItem
|
|
metadata:
|
|
name: guacamole-credentials
|
|
namespace: guacamole
|
|
spec:
|
|
itemPath: vaults/IAmWorkin/items/Guacamole
|
|
---
|
|
# RBAC for guacd K8s exec protocol
|
|
apiVersion: v1
|
|
kind: ServiceAccount
|
|
metadata:
|
|
name: guacd-exec
|
|
namespace: guacamole
|
|
---
|
|
apiVersion: rbac.authorization.k8s.io/v1
|
|
kind: ClusterRole
|
|
metadata:
|
|
name: guacd-pod-exec
|
|
rules:
|
|
- apiGroups: [""]
|
|
resources: ["pods"]
|
|
verbs: ["get", "list"]
|
|
- apiGroups: [""]
|
|
resources: ["pods/exec"]
|
|
verbs: ["create"]
|
|
- apiGroups: [""]
|
|
resources: ["namespaces"]
|
|
verbs: ["list"]
|
|
---
|
|
apiVersion: rbac.authorization.k8s.io/v1
|
|
kind: ClusterRoleBinding
|
|
metadata:
|
|
name: guacd-pod-exec
|
|
subjects:
|
|
- kind: ServiceAccount
|
|
name: guacd-exec
|
|
namespace: guacamole
|
|
roleRef:
|
|
kind: ClusterRole
|
|
name: guacd-pod-exec
|
|
apiGroup: rbac.authorization.k8s.io
|