I've build a Dovecot proxy that sends users to specific backends based on their domain. Domain A goes to server A and domain B goes to server B, etc. The list of domains is not static, but it isn't changing a lot. That works totally ok with a passdb driver sql and a simple SQL statement like:
password_query = SELECT
NULL as password,
'y' as nopassword,
'y' as proxy,
NULL as destuser,
'y' as proxy_nopipelining,
host,
'y' as nodelay,
'y' as nologin,
'any-cert' as 'starttls'
FROM proxy_domain WHERE domain = '%d';
The dovecot config contains:
passdb {
args = /etc/dovecot/sql.conf
driver = sql
}
userdb {
args = static uid=5000 gid=5000 home=/dev/null
driver = static
}
My "problem" is not really a problem - but... I need to install and run a Mysql/MariaDB server only for this job and I think, there must be an easier way to resolve the host for a specific domain. A parallel postfix installation uses a simple transport map for doing the same job. I don't need a SQL server for that simple lookup.
I thought about the Dovecot Lua passdb or static passdb but I can't find any useful example to match a domain against a host with Lua or how I return all the necessary parameters?
So I've installed the debian package dovecot-auth-lua
.
I tried with:
passdb {
driver = lua
args = file=/etc/dovecot/passdb.lua blocking=yes
default_fields = password=NULL nopassword=y proxy=y destuser=NULL proxy_nopipelining=y nodelay=y nologin=y starttls=any-cert
}
Is blocking here necessary? It's readonly operation, or?
The Lua script:
local database = "/etc/dovecot/backends"
function auth_passdb_lookup(req)
for line in io.lines(database) do
for domain, host in string.gmatch(line, "(.+)%s(.+)") do
if (domain == req.domain) then
return dovecot.auth.PASSDB_RESULT_OK, "host=" .. host
end
end
end
return dovecot.auth.PASSDB_RESULT_USER_UNKNOWN, ""
end
and of course the backends file with <domain> <host>
per line.
But I got an error on the proxy
pam_unix(dovecot:auth): check pass; user unknown
pam_unix(dovecot:auth): authentication failure; logname= uid=0 euid=0 tty=dovecot ruser=user@domain rhost=<my-ip>
pam(user@domain,ip,<id>): pam_authenticate() failed: Authentication failure (Password mismatch?)
What does it mean? I'm not sure - but is it, because I return "NULL" on some of it. When I remove the both attributes password
and destuser
it has the same effect.
pam_authenticate means it's trying a system user lookup, disable pam lookups by commenting out the include for auth-system.conf.ext in 10-auth.conf.
ps: did you get the LUA working? I am trying something similar.
edit - got mine working by adding these fields into the passdb lookup function return fields (NOT userdb lookup function fields):
return dovecot.auth.PASSDB_RESULT_OK, "password=pass proxy=y host=imap.domain.com [email protected] pass=anotherpass"