Skip to content

Instantly share code, notes, and snippets.

@digitalresistor
Last active November 4, 2015 22:25
Show Gist options
  • Save digitalresistor/11055147 to your computer and use it in GitHub Desktop.
Save digitalresistor/11055147 to your computer and use it in GitHub Desktop.
Being able to have full alias domains with ViMbAdmin is fairly handy, in that it allows people to have multiple domains forward to a single domain. This isn't supported out of the box with ViMbAdmin, and thus needs to be kind of hacked in... I am using Postfix + with Dovecot for virtual mail delivery

After updating your main.cf and your Dovecot configuration you can now add alias domains to ViMbAdmin:

  1. Create new domain example.net which we want to alias to example.com
  2. Create new alias on example.net named *@example.net that forwards to *@example.com
  3. Test send an email to user@example.com and user@example.net and verify both messages are delivered successfully to user@example.com

Users can log in to Dovecot (IMAP/POP3/SMTP AUTH) using either example.net or example.com. If login fails to find the username/password combo on the first try, it will attempt to look it up in the alias table, and allow login if that succeeds. This way users can configure their mail clients however they please.

# Try this first ...
passdb {
driver = sql
args = /usr/local/etc/dovecot/dovecot-sql.conf.ext
}
# Well that failed, so let's try and see if the user is trying to login using an alias
passdb {
driver = sql
args = /usr/local/etc/dovecot/dovecot-alias-sql.conf.ext
}
userdb {
driver = prefetch
}
# Try this first
userdb {
driver = sql
args = /usr/local/etc/dovecot/dovecot-sql.conf.ext
}
# Maybe user tried an alias?
userdb {
driver = sql
args = /usr/local/etc/dovecot/dovecot-alias-sql.conf.ext
}
driver = mysql
connect = host=127.0.0.1 user=vimbadmin password=yourpasshere dbname=vimbadmin
default_pass_scheme = MD5-CRYPT
password_query = SELECT username AS user, password AS password, \
homedir AS userdb_home, maildir AS userbd_mail, \
concat('*:bytes=', quota) as quota_rule, uid AS userdb_uid, gid AS userdb_gid \
FROM mailbox \
WHERE username = (SELECT CONCAT('%n', SUBSTRING(goto, LOCATE('@', goto))) AS addr FROM alias WHERE address = '*@%d') AND active = '1' \
AND ( access_restriction = 'ALL' OR LOCATE( access_restriction, '%Us' ) > 0 )
user_query = SELECT homedir AS home, maildir AS mail, \
concat('*:bytes=', quota) as quota_rule, uid, gid \
FROM mailbox WHERE username = (SELECT CONCAT('%u', SUBSTRING(goto, LOCATE('@', goto))) AS addr FROM alias WHERE address = '*@%d')
driver = mysql
connect = host=127.0.0.1 user=vimbadmin password=yourpasshere dbname=vimbadmin
default_pass_scheme = MD5-CRYPT
password_query = SELECT username AS user, password AS password, \
homedir AS userdb_home, maildir AS userbd_mail, \
concat('*:bytes=', quota) as quota_rule, uid AS userdb_uid, gid AS userdb_gid \
FROM mailbox \
WHERE username = '%u' AND active = '1' \
AND ( access_restriction = 'ALL' OR LOCATE( access_restriction, '%Us' ) > 0 )
user_query = SELECT homedir AS home, maildir AS mail, \
concat('*:bytes=', quota) as quota_rule, uid, gid \
FROM mailbox WHERE username = '%u'
virtual_transport = lmtp:unix:private/dovecot-lmtp
virtual_alias_maps = mysql:$config_directory/virtual_domain_forwarding,mysql:$config_directory/virtual_alias
virtual_mailbox_domains = mysql:$config_directory/virtual_domains
virtual_mailbox_maps = mysql:$config_directory/virtual
user = vimbadmin
password = yourpasshere
hosts = 127.0.0.1
dbname = vimbadmin
table = mailbox
select_field = username
where_field = username
user = vimbadmin
password = yourpasshere
hosts = 127.0.0.1
dbname = vimbadmin
query = SELECT goto FROM alias WHERE address = '%s' AND active = '1' and substring(address, 1, 1) <> '*'
user = vimbadmin
password = yourpasshere
hosts = 127.0.0.1
dbname = vimbadmin
query = SELECT SUBSTRING(goto,LOCATE('@',goto)) AS goto FROM alias WHERE address='*@%d' AND 1 = ( (SELECT count(Domain_id) FROM mailbox WHERE username = CONCAT('%u', (SELECT SUBSTRING(goto, LOCATE('@', goto)) AS goto FROM alias WHERE address='*@%d'))) OR (SELECT count(Domain_id) FROM alias WHERE address = CONCAT('%u', (SELECT SUBSTRING(goto, LOCATE('@', goto)) AS goto FROM alias WHERE address='*@%d'))) );
user = vimbadmin
password = yourpasshere
hosts = 127.0.0.1
dbname = vimbadmin
query = SELECT domain FROM domain WHERE domain = '%s' AND backupmx = '0' AND active = '1'
@PhrozenByte
Copy link

Your virtual_domain_forwarding seems to be more complex than necessary. Assume you want to forward *@example.com to *@example.net. A e-mail to foo@example.com arrives and should be forwarded to foo@example.net. Why do you care about the existance of foo@example.net? Postfix changes the To: header and starts over with an completely new delivery process. According to the domains managed by Postfix, the mail will be handeled internally (and rejected if the destination doesn't exist) or forwarded to another mail server.

Besides the unnecessary complexity, you MUST NOT care about the destination. Assume a setup where example.net isn't hosted on the same mail system.

user = vimbadmin
password = yourpasshere
hosts = 127.0.0.1
dbname = vimbadmin
query =
    SELECT CONCAT('%u', SUBSTRING(goto, 2)) AS goto
    FROM alias
    WHERE address='*@%d' AND goto LIKE '*@%%'

By the way: It's not necessary to exclude * aliases in virtual_alias: When somebody sends an email to *@example.com, the mail will be forwarded to *@example.net - what is exactly what you want.

Big thanks for your how to anyway!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment