Migration from PMTA to Kumomta

[source.“ip-1”]
source_address = “81.28.97.239”
ehlo_domain = ‘mta-mx-239.oneworkspace.xyz’

[source.“ip-2”]
source_address = “81.28.97.240”
ehlo_domain = ‘mta-mx-240.oneworkspace.xyz’

[source.“ip-3”]
source_address = “81.28.97.241”
ehlo_domain = ‘mta-mx-241.oneworkspace.xyz’

[pool.“pool-1”]
[pool.“pool-1”.“ip-1” ]

[pool.“pool-1”]
[pool.“pool-1”.“ip-2” ]

[pool.“pool-1”]
[pool.“pool-1”.“ip-3” ]

queues.toml configuration -

The tenant to use if no tenant_header is present

default_tenant = “default-tenant”

[tenant.‘default-tenant’]
egress_pool = ‘pool-1’

It’s not enough to just fill out the toml files, show your latest init.lua pls.

Also read https://gist.github.com/

########################################################
KumoMTA minimal Send Policy
(Save this as /opt/kumomta/etc/policy/init.lua for systemd automation)
This config policy defines KumoMTA with a minimal
set of modifications from default.
Please read the docs at https://docs.kumomta.com/
For detailed configuration instructions.
########################################################
]]

local kumo = require ‘kumo’
–[[ Start of INIT section ]]

local listener_domains = require ‘policy-extras.listener_domains’
local utils = require ‘policy-extras.policy_utils’

kumo.on(
‘get_listener_domain’,
listener_domains:setup { ‘/opt/kumomta/etc/listener_domains.toml’ }
)

local shaping = require ‘policy-extras.shaping’
kumo.on(‘get_egress_path_config’, shaping:setup())

– Configure source IPs.
local sources = require ‘policy-extras.sources’
sources:setup { ‘/opt/kumomta/etc/sources.toml’ }

local queue_module = require ‘policy-extras.queue’
local queue_helper =
queue_module:setup { ‘/opt/kumomta/etc/queues.toml’ }

kumo.on(‘init’, function()
kumo.start_esmtp_listener {
listen = ‘0.0.0.0:5890’,
hostname = ‘mail.oneworkspace.xyz’,
relay_hosts = { ‘198.27.80.228’ },

}

kumo.start_esmtp_listener {
listen = ‘81.28.96.182:2591’,
}
kumo.start_esmtp_listener {
listen = ‘127.0.0.1:2591’,
hostname = ‘mail.oneworkspace.xyz’,
relay_hosts = { ‘127.0.0.1’ },
}

kumo.start_http_listener {
listen = ‘127.0.0.1:8000’,
}

kumo.define_spool {
name = ‘data’,
path = ‘/var/spool/kumomta/data’,
}

kumo.define_spool {
name = ‘meta’,
path = ‘/var/spool/kumomta/meta’,
}

kumo.configure_local_logs {
log_dir = ‘/var/log/kumomta’,
}
end)
–[[ End of INIT Section ]]

–[[ Start of Non-INIT level config ]]

– PLEASE read https://docs.kumomta.com/ for extensive documentation on customizing this config.
–[[ End of Non-INIT level config ]]

See Configuring Queue Management - KumoMTA Docs - you don’t have a call to queue_helper:apply(msg)

I’d use Example Server Policy - KumoMTA Docs as a reference as your build your init.lua

You mean below code -

local queue_module = require ‘policy-extras.queue’
local queue_helper =
queue_module:setup { ‘/opt/kumomta/etc/queues.toml’ }

No.

The code is on the page I linked.

I seem to be able to connect to your server…

Trying 81.28.96.182...
Connected to 81.28.96.182.
Escape character is '^]'.
220 ns1025.imingo.net KumoMTA

and it is behaving properly…

Connected to 81.28.96.182.
Escape character is '^]'.
220 ns1025.imingo.net KumoMTA
ehlo moto
250-ns1025.imingo.net Aloha moto
250-PIPELINING
250-ENHANCEDSTATUSCODES
250 STARTTLS
mail from:tom@kumomta.com
250 OK EnvelopeAddress("tom@kumomta.com")
rcpt to:tom@kumomta.com
550 5.7.1 relaying not permitted for 54.188.107.73:47964
quit
221 So long, and thanks for all the fish!
Connection closed by foreign host.
```

In your sources, you should not be defining a pool more than once. you have defined pool-1 3 times.

[pool."pool-1"."ip-1" ]

[pool."pool-1"]
[pool."pool-1"."ip-2" ]


[pool."pool-1"]
[pool."pool-1"."ip-3" ]```

This should be :

[pool."pool-1"."ip-1" ]
[pool."pool-1"."ip-2" ]
[pool."pool-1"."ip-3" ]```

finally IP rotation working fine. thanks @faithful-ostrich

Getting following error while setting up DKIM -

stack traceback:
[C]: in local ‘poll’
[string “?”]:5: in main chunk
(…tail calls…)
/opt/kumomta/share/policy-extras/dkim_sign.lua:207: in upvalue ‘do_dkim_sign’
/opt/kumomta/share/policy-extras/dkim_sign.lua:271: in upvalue ‘dkim_signer’
[string “/opt/kumomta/etc/policy/init.lua”]:176: in function <[string “/opt/kumomta/etc/policy/init.lua”]:162>
caused by: Vault { vault_address: None, vault_token: None, vault_mount: “secret”, vault_path: “/opt/kumomta/etc/dkim/dkim2024.key” }: vault_address was not specified and $VAULT_ADDR is not set/usable: Vault { vault_address: None, vault_token: None, vault_mount: “secret”, vault_path: “/opt/kumomta/etc/dkim/dkim2024.key” } environment variable not found

Here is the configuration of dkim_data.toml file

[base]

If these are present, we’ll use hashicorp vault instead

of reading from disk

vault_mount = “secret”
vault_path_prefix = “dkim/”

To do double or triple signing, add each additional

signature name to this list and see the signature."MyESPName"

block below

additional_signatures = [“171mails”]

Default selector to assume if the domain/signature block

doesn’t specify one

selector = “dkim1024”

The default set of headers to sign if otherwise unspecified

This reccommended set comes from section 5.4.1 of RFC 6376

See https://datatracker.ietf.org/doc/html/rfc6376#section-5.4

headers = [
“From”, “Reply-To”, “Subject”, “Date”, “To”, “Cc”,
“Resent-Date”, “Resent-From”, “Resent-To”, “Resent-Cc”,
“In-Reply-To”, “References”, “List-Id”, “List-Help”,
“List-Unsubscribe”, “List-Subscribe”, “List-Post”,
“List-Owner”, “List-Archive”
]

Automatic oversigning can help prevent certain DKIM replay attacks by asserting

absence of any additional copies of a given header.

over_sign = true

Domain blocks match based on the sender domain of the

incoming message

[domain.“clothingdeals2023.info”]
selector = ‘dkim2024’
headers = [“From”, “To”, “Subject”, “Date”, “Sender”]
algo = “sha256” # or “ed25519”. Omit to use the default of “sha256”

optional overridden filename.

Default is “/opt/kumomta/etc/dkim/DOMAIN/SELECTOR.key”

#filename = “/full/path/to/key.”
filename = “/opt/kumomta/etc/dkim/dkim2024.key”

TODO: reception-time policy for signing based on DNS.

policy = “TempFailIfNotInDNS” # Reject
#policy = “SignAlways” # Sign and relay
#policy = “SignOnlyIfInDNS” # Don’t sign. Allow fallback to additional_signatures

The signature block is independent of the sender domain.

They are consulted based on the value of base.additional_signatures

above.

In addition to the same values that are found in the domain block,

the following keys are supported

[signature.“171mails”]

Policy is interpreted differently for these

policy = “Always” # Always add this signature
#policy = “OnlyIfMissingDomainBlock” # Use this as a fallback

specifies the signing domain for this signature block

domain = “clothingdeals2023.info”

Unless you mean to use a vault, comment out to two lines referring to vault_ if your config.

When posting code and configs in Discord, please use triple backticks. Otherwise it will be interpreters as markup and is hard to read.