Wire IRC, mail, teamspeak to 1Password secrets
- IRC: OnePasswordItem CRD, ConfigMap templates with inject-credentials initContainers - Mail: OnePasswordItem CRD, inject-accounts initContainer builds postfix-accounts.cf - TeamSpeak: OnePasswordItem CRD, TS3SERVER_SERVERADMIN_PASSWORD from secret - Zero hardcoded passwords remain in these manifests
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
# UnrealIRCd + Anope IRC Services
|
# UnrealIRCd + Anope IRC Services
|
||||||
# ArgoCD managed - BlueJay Lab
|
# ArgoCD managed - BlueJay Lab
|
||||||
|
# Credentials: 1Password → OnePasswordItem → K8s Secret → initContainer sed injection
|
||||||
---
|
---
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: Namespace
|
kind: Namespace
|
||||||
@@ -8,6 +9,15 @@ metadata:
|
|||||||
labels:
|
labels:
|
||||||
app.kubernetes.io/part-of: bluejay-infra
|
app.kubernetes.io/part-of: bluejay-infra
|
||||||
---
|
---
|
||||||
|
# 1Password → K8s Secret sync
|
||||||
|
apiVersion: onepassword.com/v1
|
||||||
|
kind: OnePasswordItem
|
||||||
|
metadata:
|
||||||
|
name: irc-credentials
|
||||||
|
namespace: irc
|
||||||
|
spec:
|
||||||
|
itemPath: "vaults/IAmWorkin/items/IRC UnrealIRCd"
|
||||||
|
---
|
||||||
# TLS Certificate for IRC
|
# TLS Certificate for IRC
|
||||||
apiVersion: cert-manager.io/v1
|
apiVersion: cert-manager.io/v1
|
||||||
kind: Certificate
|
kind: Certificate
|
||||||
@@ -22,17 +32,17 @@ spec:
|
|||||||
dnsNames:
|
dnsNames:
|
||||||
- irc.iamworkin.lan
|
- irc.iamworkin.lan
|
||||||
---
|
---
|
||||||
# UnrealIRCd configuration
|
# UnrealIRCd configuration template (passwords replaced by placeholders)
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: Secret
|
kind: ConfigMap
|
||||||
metadata:
|
metadata:
|
||||||
name: unrealircd-config
|
name: unrealircd-config-template
|
||||||
namespace: irc
|
namespace: irc
|
||||||
type: Opaque
|
data:
|
||||||
stringData:
|
|
||||||
unrealircd.conf: |
|
unrealircd.conf: |
|
||||||
/* BlueJay Lab IRC - UnrealIRCd 6.x config */
|
/* BlueJay Lab IRC - UnrealIRCd 6.x config */
|
||||||
/* Managed by ArgoCD */
|
/* Managed by ArgoCD */
|
||||||
|
/* Credentials injected from 1Password at pod startup */
|
||||||
|
|
||||||
include "modules.default.conf";
|
include "modules.default.conf";
|
||||||
include "help/help.conf";
|
include "help/help.conf";
|
||||||
@@ -101,21 +111,21 @@ stringData:
|
|||||||
|
|
||||||
oper bluejay {
|
oper bluejay {
|
||||||
mask *;
|
mask *;
|
||||||
password "BlueJay-IRC-Oper-2026";
|
password "__OPER_PASSWORD__";
|
||||||
operclass netadmin-with-override;
|
operclass netadmin-with-override;
|
||||||
class opers;
|
class opers;
|
||||||
}
|
}
|
||||||
|
|
||||||
drpass {
|
drpass {
|
||||||
restart "BlueJay-IRC-Oper-2026";
|
restart "__OPER_PASSWORD__";
|
||||||
die "BlueJay-IRC-Oper-2026";
|
die "__OPER_PASSWORD__";
|
||||||
}
|
}
|
||||||
|
|
||||||
link services.iamworkin.lan {
|
link services.iamworkin.lan {
|
||||||
incoming {
|
incoming {
|
||||||
mask *;
|
mask *;
|
||||||
}
|
}
|
||||||
password "BlueJay-Services-Link-2026";
|
password "__LINK_PASSWORD__";
|
||||||
class servers;
|
class servers;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,7 +136,7 @@ stringData:
|
|||||||
log {
|
log {
|
||||||
source {
|
source {
|
||||||
all;
|
all;
|
||||||
\!debug;
|
\\!debug;
|
||||||
}
|
}
|
||||||
destination {
|
destination {
|
||||||
channel "#ops";
|
channel "#ops";
|
||||||
@@ -169,14 +179,13 @@ stringData:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
---
|
---
|
||||||
# Anope configuration
|
# Anope configuration template (passwords replaced by placeholders)
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: Secret
|
kind: ConfigMap
|
||||||
metadata:
|
metadata:
|
||||||
name: anope-config
|
name: anope-config-template
|
||||||
namespace: irc
|
namespace: irc
|
||||||
type: Opaque
|
data:
|
||||||
stringData:
|
|
||||||
services.conf: |
|
services.conf: |
|
||||||
define
|
define
|
||||||
{
|
{
|
||||||
@@ -188,7 +197,7 @@ stringData:
|
|||||||
{
|
{
|
||||||
host = "unrealircd.irc.svc.cluster.local"
|
host = "unrealircd.irc.svc.cluster.local"
|
||||||
port = 8067
|
port = 8067
|
||||||
password = "BlueJay-Services-Link-2026"
|
password = "__LINK_PASSWORD__"
|
||||||
}
|
}
|
||||||
|
|
||||||
serverinfo
|
serverinfo
|
||||||
@@ -386,6 +395,26 @@ spec:
|
|||||||
app: unrealircd
|
app: unrealircd
|
||||||
spec:
|
spec:
|
||||||
initContainers:
|
initContainers:
|
||||||
|
- name: inject-credentials
|
||||||
|
image: busybox:1.36
|
||||||
|
command: ["sh", "-c"]
|
||||||
|
args:
|
||||||
|
- |
|
||||||
|
OPER_PW=$(cat /secrets/password)
|
||||||
|
LINK_PW=$(cat /secrets/Link-Password)
|
||||||
|
sed -e "s|__OPER_PASSWORD__|${OPER_PW}|g" \
|
||||||
|
-e "s|__LINK_PASSWORD__|${LINK_PW}|g" \
|
||||||
|
/config-template/unrealircd.conf > /injected-config/unrealircd.conf
|
||||||
|
echo "Credentials injected into unrealircd.conf"
|
||||||
|
volumeMounts:
|
||||||
|
- name: irc-credentials
|
||||||
|
mountPath: /secrets
|
||||||
|
readOnly: true
|
||||||
|
- name: unrealircd-config-template
|
||||||
|
mountPath: /config-template
|
||||||
|
readOnly: true
|
||||||
|
- name: injected-config
|
||||||
|
mountPath: /injected-config
|
||||||
- name: copy-tls
|
- name: copy-tls
|
||||||
image: busybox:1.36
|
image: busybox:1.36
|
||||||
command: ["sh", "-c"]
|
command: ["sh", "-c"]
|
||||||
@@ -416,7 +445,7 @@ spec:
|
|||||||
- containerPort: 8067
|
- containerPort: 8067
|
||||||
name: services-link
|
name: services-link
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- name: unrealircd-config
|
- name: injected-config
|
||||||
mountPath: /app/conf/unrealircd.conf
|
mountPath: /app/conf/unrealircd.conf
|
||||||
subPath: unrealircd.conf
|
subPath: unrealircd.conf
|
||||||
- name: unrealircd-data
|
- name: unrealircd-data
|
||||||
@@ -431,9 +460,14 @@ spec:
|
|||||||
memory: 256Mi
|
memory: 256Mi
|
||||||
cpu: 250m
|
cpu: 250m
|
||||||
volumes:
|
volumes:
|
||||||
- name: unrealircd-config
|
- name: irc-credentials
|
||||||
secret:
|
secret:
|
||||||
secretName: unrealircd-config
|
secretName: irc-credentials
|
||||||
|
- name: unrealircd-config-template
|
||||||
|
configMap:
|
||||||
|
name: unrealircd-config-template
|
||||||
|
- name: injected-config
|
||||||
|
emptyDir: {}
|
||||||
- name: unrealircd-data
|
- name: unrealircd-data
|
||||||
persistentVolumeClaim:
|
persistentVolumeClaim:
|
||||||
claimName: unrealircd-data
|
claimName: unrealircd-data
|
||||||
@@ -462,6 +496,24 @@ spec:
|
|||||||
app: anope
|
app: anope
|
||||||
spec:
|
spec:
|
||||||
initContainers:
|
initContainers:
|
||||||
|
- name: inject-credentials
|
||||||
|
image: busybox:1.36
|
||||||
|
command: ["sh", "-c"]
|
||||||
|
args:
|
||||||
|
- |
|
||||||
|
LINK_PW=$(cat /secrets/Link-Password)
|
||||||
|
sed -e "s|__LINK_PASSWORD__|${LINK_PW}|g" \
|
||||||
|
/config-template/services.conf > /injected-config/services.conf
|
||||||
|
echo "Credentials injected into services.conf"
|
||||||
|
volumeMounts:
|
||||||
|
- name: irc-credentials
|
||||||
|
mountPath: /secrets
|
||||||
|
readOnly: true
|
||||||
|
- name: anope-config-template
|
||||||
|
mountPath: /config-template
|
||||||
|
readOnly: true
|
||||||
|
- name: injected-config
|
||||||
|
mountPath: /injected-config
|
||||||
- name: fix-perms
|
- name: fix-perms
|
||||||
image: busybox:1.36
|
image: busybox:1.36
|
||||||
command: ["sh", "-c"]
|
command: ["sh", "-c"]
|
||||||
@@ -476,7 +528,7 @@ spec:
|
|||||||
- name: anope
|
- name: anope
|
||||||
image: anope/anope:latest
|
image: anope/anope:latest
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- name: anope-config
|
- name: injected-config
|
||||||
mountPath: /anope/conf/services.conf
|
mountPath: /anope/conf/services.conf
|
||||||
subPath: services.conf
|
subPath: services.conf
|
||||||
- name: anope-data
|
- name: anope-data
|
||||||
@@ -489,9 +541,14 @@ spec:
|
|||||||
memory: 128Mi
|
memory: 128Mi
|
||||||
cpu: 100m
|
cpu: 100m
|
||||||
volumes:
|
volumes:
|
||||||
- name: anope-config
|
- name: irc-credentials
|
||||||
secret:
|
secret:
|
||||||
secretName: anope-config
|
secretName: irc-credentials
|
||||||
|
- name: anope-config-template
|
||||||
|
configMap:
|
||||||
|
name: anope-config-template
|
||||||
|
- name: injected-config
|
||||||
|
emptyDir: {}
|
||||||
- name: anope-data
|
- name: anope-data
|
||||||
persistentVolumeClaim:
|
persistentVolumeClaim:
|
||||||
claimName: anope-data
|
claimName: anope-data
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
# docker-mailserver - Postfix + Dovecot + rspamd
|
# docker-mailserver - Postfix + Dovecot + rspamd
|
||||||
# ArgoCD managed - BlueJay Lab
|
# ArgoCD managed - BlueJay Lab
|
||||||
|
# Credentials: 1Password → OnePasswordItem CRD → K8s Secret
|
||||||
---
|
---
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: Namespace
|
kind: Namespace
|
||||||
@@ -8,17 +9,14 @@ metadata:
|
|||||||
labels:
|
labels:
|
||||||
app.kubernetes.io/part-of: bluejay-infra
|
app.kubernetes.io/part-of: bluejay-infra
|
||||||
---
|
---
|
||||||
# Mail accounts Secret (postfix-accounts.cf format: user@domain|{SHA512-CRYPT}hash)
|
# 1Password → K8s Secret sync for mail credentials
|
||||||
apiVersion: v1
|
apiVersion: onepassword.com/v1
|
||||||
kind: Secret
|
kind: OnePasswordItem
|
||||||
metadata:
|
metadata:
|
||||||
name: mail-accounts
|
name: mail-credentials
|
||||||
namespace: mail
|
namespace: mail
|
||||||
type: Opaque
|
spec:
|
||||||
stringData:
|
itemPath: "vaults/IAmWorkin/items/Mail Postmaster"
|
||||||
postfix-accounts.cf: |
|
|
||||||
admin@iamwork.in|{SHA512-CRYPT}$6$1355214084ba403a$LPA.qkZLpv9RqMu8OenCrgYgyHbMwMIAYOuLrbNX/eeiaOj.8rtj9IlMeLDxSc6FdWK9N/PcNmBzV5fJL7IRn/
|
|
||||||
noreply@iamwork.in|{SHA512-CRYPT}$6$1355214084ba403a$LPA.qkZLpv9RqMu8OenCrgYgyHbMwMIAYOuLrbNX/eeiaOj.8rtj9IlMeLDxSc6FdWK9N/PcNmBzV5fJL7IRn/
|
|
||||||
---
|
---
|
||||||
# Mail data PVC
|
# Mail data PVC
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
@@ -65,6 +63,25 @@ spec:
|
|||||||
app: mailserver
|
app: mailserver
|
||||||
spec:
|
spec:
|
||||||
hostname: mail
|
hostname: mail
|
||||||
|
initContainers:
|
||||||
|
- name: inject-accounts
|
||||||
|
image: busybox:1.36
|
||||||
|
command:
|
||||||
|
- sh
|
||||||
|
- -c
|
||||||
|
- |
|
||||||
|
ADMIN_EMAIL=$(cat /credentials/Admin-Email)
|
||||||
|
ADMIN_HASH=$(cat /credentials/Admin-Hash)
|
||||||
|
NOREPLY_EMAIL=$(cat /credentials/Noreply-Email)
|
||||||
|
NOREPLY_HASH=$(cat /credentials/Noreply-Hash)
|
||||||
|
echo "${ADMIN_EMAIL}|${ADMIN_HASH}" > /accounts/postfix-accounts.cf
|
||||||
|
echo "${NOREPLY_EMAIL}|${NOREPLY_HASH}" >> /accounts/postfix-accounts.cf
|
||||||
|
volumeMounts:
|
||||||
|
- name: mail-credentials
|
||||||
|
mountPath: /credentials
|
||||||
|
readOnly: true
|
||||||
|
- name: mail-accounts-generated
|
||||||
|
mountPath: /accounts
|
||||||
containers:
|
containers:
|
||||||
- name: mailserver
|
- name: mailserver
|
||||||
image: docker.io/mailserver/docker-mailserver:latest
|
image: docker.io/mailserver/docker-mailserver:latest
|
||||||
@@ -116,7 +133,7 @@ spec:
|
|||||||
- name: mail-tls
|
- name: mail-tls
|
||||||
mountPath: /etc/ssl/mail
|
mountPath: /etc/ssl/mail
|
||||||
readOnly: true
|
readOnly: true
|
||||||
- name: mail-accounts
|
- name: mail-accounts-generated
|
||||||
mountPath: /tmp/docker-mailserver/postfix-accounts.cf
|
mountPath: /tmp/docker-mailserver/postfix-accounts.cf
|
||||||
subPath: postfix-accounts.cf
|
subPath: postfix-accounts.cf
|
||||||
readOnly: true
|
readOnly: true
|
||||||
@@ -142,9 +159,11 @@ spec:
|
|||||||
- name: mail-tls
|
- name: mail-tls
|
||||||
secret:
|
secret:
|
||||||
secretName: mail-tls
|
secretName: mail-tls
|
||||||
- name: mail-accounts
|
- name: mail-credentials
|
||||||
secret:
|
secret:
|
||||||
secretName: mail-accounts
|
secretName: mail-credentials
|
||||||
|
- name: mail-accounts-generated
|
||||||
|
emptyDir: {}
|
||||||
---
|
---
|
||||||
# SMTP LoadBalancer Service (external)
|
# SMTP LoadBalancer Service (external)
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
|
|||||||
@@ -1,108 +1,122 @@
|
|||||||
# TeamSpeak 3 Server
|
# TeamSpeak 3 Server
|
||||||
# ArgoCD managed - BlueJay Lab
|
# ArgoCD managed - BlueJay Lab
|
||||||
---
|
---
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: Namespace
|
kind: Namespace
|
||||||
metadata:
|
metadata:
|
||||||
name: teamspeak
|
name: teamspeak
|
||||||
labels:
|
labels:
|
||||||
app.kubernetes.io/part-of: bluejay-infra
|
app.kubernetes.io/part-of: bluejay-infra
|
||||||
---
|
---
|
||||||
# TeamSpeak data PVC
|
# 1Password secret sync - TeamSpeak credentials
|
||||||
apiVersion: v1
|
apiVersion: onepassword.com/v1
|
||||||
kind: PersistentVolumeClaim
|
kind: OnePasswordItem
|
||||||
metadata:
|
metadata:
|
||||||
name: teamspeak-data
|
name: teamspeak-credentials
|
||||||
namespace: teamspeak
|
namespace: teamspeak
|
||||||
spec:
|
spec:
|
||||||
accessModes: [ReadWriteOnce]
|
itemPath: "vaults/IAmWorkin/items/TeamSpeak 3"
|
||||||
resources:
|
---
|
||||||
requests:
|
# TeamSpeak data PVC
|
||||||
storage: 1Gi
|
apiVersion: v1
|
||||||
---
|
kind: PersistentVolumeClaim
|
||||||
# TeamSpeak 3 Deployment
|
metadata:
|
||||||
apiVersion: apps/v1
|
name: teamspeak-data
|
||||||
kind: Deployment
|
namespace: teamspeak
|
||||||
metadata:
|
spec:
|
||||||
name: teamspeak
|
accessModes: [ReadWriteOnce]
|
||||||
namespace: teamspeak
|
resources:
|
||||||
labels:
|
requests:
|
||||||
app: teamspeak
|
storage: 1Gi
|
||||||
spec:
|
---
|
||||||
replicas: 1
|
# TeamSpeak 3 Deployment
|
||||||
strategy:
|
apiVersion: apps/v1
|
||||||
type: Recreate
|
kind: Deployment
|
||||||
selector:
|
metadata:
|
||||||
matchLabels:
|
name: teamspeak
|
||||||
app: teamspeak
|
namespace: teamspeak
|
||||||
template:
|
labels:
|
||||||
metadata:
|
app: teamspeak
|
||||||
labels:
|
spec:
|
||||||
app: teamspeak
|
replicas: 1
|
||||||
spec:
|
strategy:
|
||||||
containers:
|
type: Recreate
|
||||||
- name: teamspeak
|
selector:
|
||||||
image: teamspeak:latest
|
matchLabels:
|
||||||
ports:
|
app: teamspeak
|
||||||
- containerPort: 9987
|
template:
|
||||||
name: voice
|
metadata:
|
||||||
protocol: UDP
|
labels:
|
||||||
- containerPort: 30033
|
app: teamspeak
|
||||||
name: filetransfer
|
spec:
|
||||||
protocol: TCP
|
containers:
|
||||||
- containerPort: 10011
|
- name: teamspeak
|
||||||
name: serverquery
|
image: teamspeak:latest
|
||||||
protocol: TCP
|
ports:
|
||||||
env:
|
- containerPort: 9987
|
||||||
- name: TS3SERVER_LICENSE
|
name: voice
|
||||||
value: accept
|
protocol: UDP
|
||||||
volumeMounts:
|
- containerPort: 30033
|
||||||
- name: teamspeak-data
|
name: filetransfer
|
||||||
mountPath: /var/ts3server
|
protocol: TCP
|
||||||
resources:
|
- containerPort: 10011
|
||||||
requests:
|
name: serverquery
|
||||||
memory: 128Mi
|
protocol: TCP
|
||||||
cpu: 50m
|
env:
|
||||||
limits:
|
- name: TS3SERVER_LICENSE
|
||||||
memory: 512Mi
|
value: accept
|
||||||
cpu: 500m
|
- name: TS3SERVER_SERVERADMIN_PASSWORD
|
||||||
readinessProbe:
|
valueFrom:
|
||||||
tcpSocket:
|
secretKeyRef:
|
||||||
port: 10011
|
name: teamspeak-credentials
|
||||||
initialDelaySeconds: 30
|
key: ServerQuery Password
|
||||||
periodSeconds: 10
|
volumeMounts:
|
||||||
livenessProbe:
|
- name: teamspeak-data
|
||||||
tcpSocket:
|
mountPath: /var/ts3server
|
||||||
port: 10011
|
resources:
|
||||||
initialDelaySeconds: 60
|
requests:
|
||||||
periodSeconds: 15
|
memory: 128Mi
|
||||||
volumes:
|
cpu: 50m
|
||||||
- name: teamspeak-data
|
limits:
|
||||||
persistentVolumeClaim:
|
memory: 512Mi
|
||||||
claimName: teamspeak-data
|
cpu: 500m
|
||||||
---
|
readinessProbe:
|
||||||
# TeamSpeak LoadBalancer Service
|
tcpSocket:
|
||||||
apiVersion: v1
|
port: 10011
|
||||||
kind: Service
|
initialDelaySeconds: 30
|
||||||
metadata:
|
periodSeconds: 10
|
||||||
name: teamspeak
|
livenessProbe:
|
||||||
namespace: teamspeak
|
tcpSocket:
|
||||||
annotations:
|
port: 10011
|
||||||
metallb.universe.tf/loadBalancerIPs: 10.0.56.205
|
initialDelaySeconds: 60
|
||||||
spec:
|
periodSeconds: 15
|
||||||
type: LoadBalancer
|
volumes:
|
||||||
selector:
|
- name: teamspeak-data
|
||||||
app: teamspeak
|
persistentVolumeClaim:
|
||||||
ports:
|
claimName: teamspeak-data
|
||||||
- port: 9987
|
---
|
||||||
targetPort: 9987
|
# TeamSpeak LoadBalancer Service
|
||||||
name: voice
|
apiVersion: v1
|
||||||
protocol: UDP
|
kind: Service
|
||||||
- port: 30033
|
metadata:
|
||||||
targetPort: 30033
|
name: teamspeak
|
||||||
name: filetransfer
|
namespace: teamspeak
|
||||||
protocol: TCP
|
annotations:
|
||||||
- port: 10011
|
metallb.universe.tf/loadBalancerIPs: 10.0.56.205
|
||||||
targetPort: 10011
|
spec:
|
||||||
name: serverquery
|
type: LoadBalancer
|
||||||
protocol: TCP
|
selector:
|
||||||
|
app: teamspeak
|
||||||
|
ports:
|
||||||
|
- port: 9987
|
||||||
|
targetPort: 9987
|
||||||
|
name: voice
|
||||||
|
protocol: UDP
|
||||||
|
- port: 30033
|
||||||
|
targetPort: 30033
|
||||||
|
name: filetransfer
|
||||||
|
protocol: TCP
|
||||||
|
- port: 10011
|
||||||
|
targetPort: 10011
|
||||||
|
name: serverquery
|
||||||
|
protocol: TCP
|
||||||
|
|||||||
Reference in New Issue
Block a user