273 lines
8.8 KiB
HCL
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
|
|
}
|