Files
domain/share/wildduck/haraka.tf
2024-01-25 18:35:22 +01:00

273 lines
8.8 KiB
HCL

locals {
haraka-labels = merge(local.common-labels, {
"app.kubernetes.io/component" = "haraka"
})
}
resource "kubectl_manifest" "haraka_deploy" {
yaml_body = <<-EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: "${var.instance}-haraka"
namespace: "${var.namespace}"
labels: ${jsonencode(local.haraka-labels)}
spec:
replicas: 1
selector:
matchLabels: ${jsonencode(local.haraka-labels)}
template:
metadata:
labels: ${jsonencode(local.haraka-labels)}
spec:
securityContext:
fsGroup: 1000
containers:
- name: haraka
securityContext:
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 1000
image: "${var.images.haraka.registry}/${var.images.haraka.repository}:${var.images.haraka.tag}"
imagePullPolicy: "${var.images.haraka.pullPolicy}"
ports:
- name: smtp
containerPort: 2500
protocol: TCP
livenessProbe:
tcpSocket:
port: smtp
initialDelaySeconds: 20
periodSeconds: 30
readinessProbe:
tcpSocket:
port: smtp
initialDelaySeconds: 20
periodSeconds: 30
resources:
{}
volumeMounts:
- name: config
mountPath: /app/config/me
subPath: me
- name: config
mountPath: /app/config/host_list
subPath: host_list
- name: config
mountPath: /app/config/rspamd.ini
subPath: rspamd.ini
- name: config
mountPath: /app/config/wildduck.yaml
subPath: wildduck.yaml
- name: config
mountPath: /app/config/smtp.ini
subPath: smtp.ini
- name: config
mountPath: /app/config/dkim_sign.ini
subPath: dkim_sign.ini
- name: tls
mountPath: /app/config/tls_key.pem
subPath: tls.key
- name: tls
mountPath: /app/config/tls_cert.pem
subPath: tls.crt
- mountPath: /app/queue
name: queue
volumes:
- name: queue
emptyDir: {}
- name: config
configMap:
name: "${var.instance}-haraka"
- name: tls
secret:
secretName: "${var.instance}-cert"
EOF
}
resource "kubernetes_config_map_v1" "haraka_config" {
metadata {
name = "${var.instance}-haraka"
namespace = "${var.namespace}"
labels = local.haraka-labels
}
data = yamldecode(<<-EOF
me: |-
${var.sub_domain}.${var.domain_name}
host_list: |-
# add hosts in here we want to accept mail for
${var.sub_domain}.${var.domain_name}
${var.domain_name}
${join("\n ",var.additional-domains)}
rspamd.ini: |-
host = ${var.instance}-rspamd.${var.namespace}.svc.cluster.local
port = 11333
add_headers = always
[dkim]
enabled = true
[header]
bar = X-Rspamd-Bar
report = X-Rspamd-Report
score = X-Rspamd-Score
spam = X-Rspamd-Spam
[check]
authenticated=true
private_ip=true
[reject]
spam = false
[soft_reject]
enabled = true
[rmilter_headers]
enabled = true
[spambar]
positive = +
negative = -
neutral = /'
smtp.ini: |-
listen=[::0]:2500
; public IP address (default: none)
; If your machine is behind a NAT, some plugins (SPF, GeoIP) gain features
; if they know the servers public IP. If 'stun' is installed, Haraka will
; try to figure it out. If that doesn't work, set it here.
;public_ip=N.N.N.N
; Time in seconds to let sockets be idle with no activity
;inactivity_timeout=300
; Drop privileges to this user/group
;user=smtp
;group=smtp
; Don't stop Haraka if plugins fail to compile
;ignore_bad_plugins=0
; Run using cluster to fork multiple backend processes
;nodes=cpus
; Daemonize
;daemonize=true
;daemon_log_file=/var/log/haraka.log
;daemon_pid_file=/var/run/haraka.pid
; Spooling
; Save memory by spooling large messages to disk
;spool_dir=/var/spool/haraka
; Specify -1 to never spool to disk
; Specify 0 to always spool to disk
; Otherwise specify a size in bytes, once reached the
; message will be spooled to disk to save memory.
;spool_after=
; Force Shutdown Timeout
; - Haraka tries to close down gracefully, but if everything is shut down
; after this time it will hard close. 30s is usually long enough to
; wait for outbound connections to finish.
;force_shutdown_timeout=30
; SMTP service extensions: https://tools.ietf.org/html/rfc1869
; strict_rfc1869 = false
; Advertise support for SMTPTUF8 (RFC-6531)
;smtputf8=true
[headers]
;add_received=true
;clean_auth_results=true
; replace header_hide_version
;show_version=true
; replace max_header_lines
max_lines=1000
; replace max_received_count
max_received=100
dkim_sign.ini: |-
disabled = true
selector = mail
domain = ${var.domain_name}
headers_to_sign = From, Sender, Reply-To, Subject, Date, Message-ID, To, Cc, MIME-Version
wildduck.yaml: |-
redis:
port: 6379
host: "${var.instance}-${var.component}-redis.${var.namespace}.svc"
db: 3
mongo:
url: 'mongodb://${var.component}:${local.mongo-password}@${var.instance}-${var.component}-mongo-svc.${var.namespace}.svc:27017/wildduck'
sender: 'zone-mta'
sender:
# Push messages to ZoneMTA queue for delivery
# if `false` then no messages are sent
enabled: true
# which ZoneMTA queue to use by default. This mostly affects forwarded messages
zone: 'default'
# Collection name for GridFS storage
gfs: 'mail'
# Collection name for the queue
# see [dbs].sender option for choosing correct database to use for ZoneMTA queues
# by default the main wildduck database is used
collection: 'zone-queue'
# Hashing secret for loop detection
# Must be shared with wildduck
# If not set then looping is not tracked
loopSecret: '${local.secrets.srs}'
srs:
# must be shared with ZoneMTA SRS config, otherwise messages sent from ZoneMTA are not recognized by Haraka
secret: '${local.secrets.srs}'
attachments:
type: 'gridstore'
bucket: 'attachments'
decodeBase64: true
log:
authlogExpireDays: 30
limits:
windowSize: 3600 # 1 hour
rcptIp: 100 # allowed messages for the same recipient from same IP during window size
rcptWindowSize: 60 # 1 minute
rcpt: 60 # allowed messages for the same recipient during window size
gelf:
enabled: false
component: 'mx'
options:
graylogPort: 12201
graylogHostname: '127.0.0.1'
connection: 'lan'
rspamd:
# do not process forwarding addresses for messages with the following spam score
forwardSkip: 10
# if a message has one of the tags listed here with positive score, the message will be rejected
blacklist:
- DMARC_POLICY_REJECT
# if a message has one of the tags listed here with positive score, the message will be soft rejected
softlist:
- RBL_ZONE
# define special responses
responses:
DMARC_POLICY_REJECT: "Unauthenticated email from {host} is not accepted due to domain's DMARC policy"
RBL_ZONE: '[{host}] was found from Zone RBL'
EOF
)
}
resource "kubectl_manifest" "haraka_service" {
yaml_body = <<-EOF
apiVersion: v1
kind: Service
metadata:
name: "${var.instance}-haraka"
namespace: "${var.namespace}"
labels: ${jsonencode(local.haraka-labels)}
spec:
type: LoadBalancer
ports:
- port: 25
targetPort: smtp
protocol: TCP
name: smtp
selector: ${jsonencode(local.haraka-labels)}
EOF
}