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:
Andrew Stoltz
2026-03-09 20:55:45 -05:00
parent 3199c509c0
commit 2be7bf1279
3 changed files with 232 additions and 142 deletions

View File

@@ -1,5 +1,6 @@
# UnrealIRCd + Anope IRC Services
# ArgoCD managed - BlueJay Lab
# Credentials: 1Password → OnePasswordItem → K8s Secret → initContainer sed injection
---
apiVersion: v1
kind: Namespace
@@ -8,6 +9,15 @@ metadata:
labels:
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
apiVersion: cert-manager.io/v1
kind: Certificate
@@ -22,17 +32,17 @@ spec:
dnsNames:
- irc.iamworkin.lan
---
# UnrealIRCd configuration
# UnrealIRCd configuration template (passwords replaced by placeholders)
apiVersion: v1
kind: Secret
kind: ConfigMap
metadata:
name: unrealircd-config
name: unrealircd-config-template
namespace: irc
type: Opaque
stringData:
data:
unrealircd.conf: |
/* BlueJay Lab IRC - UnrealIRCd 6.x config */
/* Managed by ArgoCD */
/* Credentials injected from 1Password at pod startup */
include "modules.default.conf";
include "help/help.conf";
@@ -101,21 +111,21 @@ stringData:
oper bluejay {
mask *;
password "BlueJay-IRC-Oper-2026";
password "__OPER_PASSWORD__";
operclass netadmin-with-override;
class opers;
}
drpass {
restart "BlueJay-IRC-Oper-2026";
die "BlueJay-IRC-Oper-2026";
restart "__OPER_PASSWORD__";
die "__OPER_PASSWORD__";
}
link services.iamworkin.lan {
incoming {
mask *;
}
password "BlueJay-Services-Link-2026";
password "__LINK_PASSWORD__";
class servers;
}
@@ -126,7 +136,7 @@ stringData:
log {
source {
all;
\!debug;
\\!debug;
}
destination {
channel "#ops";
@@ -169,14 +179,13 @@ stringData:
}
}
---
# Anope configuration
# Anope configuration template (passwords replaced by placeholders)
apiVersion: v1
kind: Secret
kind: ConfigMap
metadata:
name: anope-config
name: anope-config-template
namespace: irc
type: Opaque
stringData:
data:
services.conf: |
define
{
@@ -188,7 +197,7 @@ stringData:
{
host = "unrealircd.irc.svc.cluster.local"
port = 8067
password = "BlueJay-Services-Link-2026"
password = "__LINK_PASSWORD__"
}
serverinfo
@@ -386,6 +395,26 @@ spec:
app: unrealircd
spec:
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
image: busybox:1.36
command: ["sh", "-c"]
@@ -416,7 +445,7 @@ spec:
- containerPort: 8067
name: services-link
volumeMounts:
- name: unrealircd-config
- name: injected-config
mountPath: /app/conf/unrealircd.conf
subPath: unrealircd.conf
- name: unrealircd-data
@@ -431,9 +460,14 @@ spec:
memory: 256Mi
cpu: 250m
volumes:
- name: unrealircd-config
- name: irc-credentials
secret:
secretName: unrealircd-config
secretName: irc-credentials
- name: unrealircd-config-template
configMap:
name: unrealircd-config-template
- name: injected-config
emptyDir: {}
- name: unrealircd-data
persistentVolumeClaim:
claimName: unrealircd-data
@@ -462,6 +496,24 @@ spec:
app: anope
spec:
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
image: busybox:1.36
command: ["sh", "-c"]
@@ -476,7 +528,7 @@ spec:
- name: anope
image: anope/anope:latest
volumeMounts:
- name: anope-config
- name: injected-config
mountPath: /anope/conf/services.conf
subPath: services.conf
- name: anope-data
@@ -489,9 +541,14 @@ spec:
memory: 128Mi
cpu: 100m
volumes:
- name: anope-config
- name: irc-credentials
secret:
secretName: anope-config
secretName: irc-credentials
- name: anope-config-template
configMap:
name: anope-config-template
- name: injected-config
emptyDir: {}
- name: anope-data
persistentVolumeClaim:
claimName: anope-data

View File

@@ -1,5 +1,6 @@
# docker-mailserver - Postfix + Dovecot + rspamd
# ArgoCD managed - BlueJay Lab
# Credentials: 1Password → OnePasswordItem CRD → K8s Secret
---
apiVersion: v1
kind: Namespace
@@ -8,17 +9,14 @@ metadata:
labels:
app.kubernetes.io/part-of: bluejay-infra
---
# Mail accounts Secret (postfix-accounts.cf format: user@domain|{SHA512-CRYPT}hash)
apiVersion: v1
kind: Secret
# 1Password → K8s Secret sync for mail credentials
apiVersion: onepassword.com/v1
kind: OnePasswordItem
metadata:
name: mail-accounts
name: mail-credentials
namespace: mail
type: Opaque
stringData:
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/
spec:
itemPath: "vaults/IAmWorkin/items/Mail Postmaster"
---
# Mail data PVC
apiVersion: v1
@@ -65,6 +63,25 @@ spec:
app: mailserver
spec:
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:
- name: mailserver
image: docker.io/mailserver/docker-mailserver:latest
@@ -116,7 +133,7 @@ spec:
- name: mail-tls
mountPath: /etc/ssl/mail
readOnly: true
- name: mail-accounts
- name: mail-accounts-generated
mountPath: /tmp/docker-mailserver/postfix-accounts.cf
subPath: postfix-accounts.cf
readOnly: true
@@ -142,9 +159,11 @@ spec:
- name: mail-tls
secret:
secretName: mail-tls
- name: mail-accounts
- name: mail-credentials
secret:
secretName: mail-accounts
secretName: mail-credentials
- name: mail-accounts-generated
emptyDir: {}
---
# SMTP LoadBalancer Service (external)
apiVersion: v1

View File

@@ -8,6 +8,15 @@ metadata:
labels:
app.kubernetes.io/part-of: bluejay-infra
---
# 1Password secret sync - TeamSpeak credentials
apiVersion: onepassword.com/v1
kind: OnePasswordItem
metadata:
name: teamspeak-credentials
namespace: teamspeak
spec:
itemPath: "vaults/IAmWorkin/items/TeamSpeak 3"
---
# TeamSpeak data PVC
apiVersion: v1
kind: PersistentVolumeClaim
@@ -56,6 +65,11 @@ spec:
env:
- name: TS3SERVER_LICENSE
value: accept
- name: TS3SERVER_SERVERADMIN_PASSWORD
valueFrom:
secretKeyRef:
name: teamspeak-credentials
key: ServerQuery Password
volumeMounts:
- name: teamspeak-data
mountPath: /var/ts3server