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: wildduck 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: 25 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 volumes: - name: config configMap: name: "${var.instance}-haraka" EOF } resource "kubectl_manifest" "haraka_config" { yaml_body = <<-EOF apiVersion: v1 kind: ConfigMap metadata: name: "${var.instance}-haraka" namespace: "${var.namespace}" labels: ${jsonencode(local.haraka-labels)} data: 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 = /' wildduck.yaml: |- ## Connect to a master instance or Redis redis: port: 6379 host: "${var.instance}-${var.component}-redis.${var.namespace}.svc" db: 3 mongo: # connection string for main messages database url: 'mongodb://${var.component}:${local.mongo-password}@${var.instance}-${var.component}-mongo-svc.${var.namespace}.svc:27017/wildduck' ## database name or connection string for the users db #users: "users" ## database name or connection string for the attachments db #gridfs: "attachments" ## database name or connection string for the outbound queue sender: 'mongodb://${var.component}:${local.mongo-password}@${var.instance}-${var.component}-mongo-svc.${var.namespace}.svc:27017/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: 'secret value' 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 }