Coming from another server¶
Coming from Stalwart is a copy, because inbuxa reads its store as it is. From anything else it is a move, and it has four parts:
- Who people are. Accounts, passwords, aliases and groups.
- Their mail. Copied over IMAP, folder by folder.
- Everything else. Calendars, contacts, filters, forwarding.
- The cutover. DNS moves, and the old server stops receiving.
This page covers what those four parts have in common. The page for your server says what is different about it:
-
Including Dovecot signing in against Active Directory, LDAP, SQL or a password file.
-
Postfix and Dovecot, with an LDAP or SQL backend and optionally SOGo.
-
Its own LDAP, or Active Directory, plus calendars and contacts to export.
-
On-premises Exchange, signing in against Active Directory.
-
App Suite in front of an IMAP backend, with groupware data in its own database.
Not yet tested on a production system
So far, the only migration to inbuxa that has been run on production systems is coming from Stalwart. None of the procedures on these pages has been, yet.
There is also no migration tool for this yet. The planned inbuxa
migrate tool starts with Stalwart, and every system on these pages,
along with others, is planned to be added to it over time. Until then,
everything here is a procedure you run yourself, with standard tools. The inbuxa side of it is what
the server does, and the server's own tests cover it. The
source-side commands come from each product's own tools and
documentation, and we have not run every one of them against a live
install of every version. Try each step on one test mailbox first. If
something doesn't match what you see, tell us, so the page can be fixed.
The shape of it¶
Side by side, the same as coming from Stalwart. inbuxa goes in next to the old server, which keeps running and keeps receiving mail until the cutover. You read from the old server and never write to it. Rolling back means pointing DNS back at it.
- Install inbuxa as on the install pages, and add your domains in the console. Don't touch DNS yet.
- Decide where people sign in (below), and set that up.
- Copy the mail once, while the old server is still live. This takes the longest, and nobody notices it.
- Move everything else: aliases, lists, filters, calendars and contacts.
- Cut over: move MX and the client hostnames, then copy the mail again to catch what arrived in between.
- Verify, and keep the old server until you are sure.
Part 1: who people are¶
This is the decision that shapes the rest. There are three ways to do it.
A. Keep the directory you have¶
If people already sign in against Active Directory or an LDAP server that is staying, point inbuxa at it. Accounts and passwords stay where they are. Nobody is given a new password, and disabling someone in the directory stops them signing in to mail as well.
This is the usual choice for Active Directory, and for Exchange always.
B. Bring the passwords with you¶
If the old directory is going away with the old server, as Zimbra's and iRedMail's usually do, inbuxa can take each account's password hash across. People then sign in with the password they already have.
- Point inbuxa at the old directory with Use Bind Authentication off, so it reads the password hash from the directory.
- Copy the mail (part 2). Each account is created in inbuxa as it is copied, with its password hash, its display name and its aliases.
- When the copy is done, set the domain's directory back to the internal one. The accounts keep the passwords the directory last gave them.
These hash formats are recognized, with or without their {SCHEME} prefix
where they have one:
| Family | Formats |
|---|---|
| crypt | $1$ (MD5), $5$ (SHA-256), $6$ (SHA-512), $2a$/$2b$/$2y$ (bcrypt), classic DES, {CRYPT} around any of these |
| LDAP-style | {SSHA512}, {SHA512}, {SSHA256}, {SHA256}, {SSHA}, {SHA}, {MD5} |
| Modern | Argon2, PBKDF2, scrypt |
| Plain text | {PLAIN}, {CLEAR} |
Dovecot's {SHA512-CRYPT} and {BLF-CRYPT} prefixes
These aren't recognized as prefixes, but what follows them ($6$…,
$2y$…) is. Where you control the query, as with an SQL backend, strip
the prefix there. The source pages show how.
Two things to know before you choose this:
- Only accounts that are copied, receive mail, or sign in get created. An account with no mail to copy has to be copied (an empty copy is fine) or created by hand.
- Whoever is disabled in the old directory at the moment you switch stays signed out only if you disable them in inbuxa too. After the switch there is no directory to ask.
C. Start fresh¶
Create the accounts in the console and hand out new passwords. For a handful of people this is the least work, and it is the only choice when the old server's passwords can't be read.
How a directory behaves in inbuxa¶
These rules apply to choice A for good, and to choice B until you switch back:
- The directory is chosen by domain. Each domain can use its own directory, or the server default, or the internal one. People sign in with their full email address, because the domain part is what chooses the directory.
- The domain has to exist in inbuxa first. A directory never creates a domain.
- Accounts are created on first use: the first sign-in, the first message delivered to them, or the first copy of their mail.
- The directory decides who exists on its domains. An account's addresses and aliases come from the directory. Mail to an address the directory doesn't know is refused. Mailing lists and the catch-all are the exception: those are kept in inbuxa and still work.
- No fallback. If the directory can't be reached, sign-in fails and incoming mail gets a temporary failure, so the sender retries. It never falls back to another directory or a local password.
- Passwords are changed in the directory, not in inbuxa. App passwords still work, and are how people use clients that can't do anything better.
- Nothing is deleted. Removing someone from the directory stops them signing in, and stops their mail, but their account and mail stay in inbuxa until you remove them.
Setting one up¶
In the console:
- Settings › Security › Directories: create a directory. The type is LDAP Directory for Active Directory and any LDAP server.
- Management › Domains: open the domain and set Directory to it. Or, to use it for every domain that doesn't name its own, set it under Settings › Security › Sign-in › General.
The LDAP form's fields, and what they do:
| Field | What it is |
|---|---|
| Server URL | ldaps://dc1.corp.example.com:636 for TLS from the start, or ldap://…:389 |
| Enable TLS | STARTTLS on an ldap:// URL. Leave it off with ldaps:// |
| Base DN | Where searches start, such as dc=corp,dc=example,dc=com |
| Bind DN, Bind Secret | A read-only service account that can search the directory |
| Use Bind Authentication | On: a password is checked by signing in to the directory as that person. Off: the password hash is read and checked by inbuxa (choice B) |
| Login Filter | Finds the person signing in. ? is replaced by what they typed |
| Mailbox Filter | Finds the owner of an address when mail arrives. ? is the address |
| Member Of Filter | Finds the groups someone is in, when their entry doesn't list them. ? is their DN |
| Primary E-mail Attribute, E-mail Alias Attribute | Where the address and the aliases are. Values must be plain addresses |
| Member Of Attribute | Lists the DNs of someone's groups |
| Account Type Attribute, Group Object Class | How a group's entry is told apart from a person's |
| Password Attribute | Where the hash is, for choice B. Leave it empty for choice A |
| Description Attribute | The display name |
A group comes across only if it has an email address, and only if that address is on a domain the same directory serves.
Active Directory¶
This is the configuration for choice A against Active Directory. It is the same for a Postfix and Dovecot server that signs in against AD and for Exchange.
| Field | Value |
|---|---|
| Server URL | ldaps://dc1.corp.example.com:636 |
| Base DN | dc=corp,dc=example,dc=com |
| Bind DN | cn=svc-inbuxa,ou=Service Accounts,dc=corp,dc=example,dc=com |
| Use Bind Authentication | On |
| Login Filter | (&(objectCategory=person)(objectClass=user)(mail=?)(!(userAccountControl:1.2.840.113556.1.4.803:=2))) |
| Mailbox Filter | (&(objectCategory=person)(objectClass=user)(mail=?)(!(userAccountControl:1.2.840.113556.1.4.803:=2))) |
| Member Of Filter | (&(objectClass=group)(member=?)) |
| Primary E-mail Attribute | mail |
| E-mail Alias Attribute | empty, or an attribute of plain addresses (below) |
| Member Of Attribute | memberOf |
| Account Type Attribute | objectClass |
| Group Object Class | group |
| Password Attribute | empty |
| Description Attribute | displayName |
The userAccountControl clause leaves out disabled accounts. With it in the
mailbox filter too, mail to someone who has been disabled is refused. That
is usually what you want, and the source pages say where it isn't.
People sign in with their mail address. If that is the same as their
userPrincipalName, (userPrincipalName=?) works in the login filter
instead.
proxyAddresses can't be the alias attribute
Exchange keeps aliases in proxyAddresses, as smtp:[email protected].
inbuxa needs plain addresses, so those values are skipped. Recreate
aliases as described under aliases, or copy them without the
prefix into an attribute of their own.
Groups are resolved one level deep. Someone in a group that is itself in a group gets only the first.
Part 2: the mail¶
Mail is copied over IMAP with imapsync, which runs on any machine that can reach both servers. It copies every folder with its flags, and it is incremental: run it again and it copies only what's new. That is what makes the second pass at cutover quick.
Copy as an administrator¶
Nobody needs to hand over their password. On the inbuxa side, one account signs in on everyone's behalf:
- In the console, under Management › Directory › Roles, make a role with the permission Act on behalf of another user, and give it to an account you control. Put that account on a domain that uses the internal directory, so you know its password.
- Sign in as
[email protected]%[email protected], with the migrator's password. You are signed in as Alice.
If Alice's domain uses a directory, signing in on her behalf creates her account from the directory first. That is how the copy creates every account in choice B.
Two limits: an account in a tenant can't act on behalf of anyone, and an app password can't be used for it.
The source side has its own way of doing the same. Each source page gives it. A copy of one mailbox looks like this:
imapsync \
--host1 old.example.com --ssl1 \
--user1 '[email protected]' --authuser1 '[email protected]' \
--password1 "$SOURCE_ADMIN_PASSWORD" \
--host2 mail.example.net --ssl2 \
--user2 '[email protected]%[email protected]' \
--password2 "$MIGRATOR_PASSWORD" \
--automap
--automap puts Sent, Drafts, Trash and Junk in inbuxa's folders of the
same purpose, whatever the source called them. To copy everyone, run it once
per address from a list.
Set quotas before you copy
A mailbox bigger than its quota stops copying partway. Set quotas first, or copy first and set them after.
When the copy is done, take the role away from the migrator account.
Part 3: everything else¶
Aliases, lists and forwarding¶
- An alias is another address for one person. With a directory, it belongs in the directory's alias attribute. Otherwise, add it to the account in the console. Either way, a mailing list with one member also works, on any domain.
- A distribution list that fans mail out becomes a mailing list in inbuxa. Keep it out of the directory's mailbox filter, or the directory answers for the address first and the list is never reached.
- A catch-all is a setting on the domain.
- Forwarding to an outside address is a Sieve
redirectin the person's filters.
Filters and out-of-office¶
Filters are Sieve scripts, and most servers already keep them as Sieve.
Upload each one over ManageSieve (port 4190, if you
opened it) with a client such as
sieve-connect, or paste it into the webmail's
filter editor. Both refuse a script that won't
compile, so you find out straight away.
A script that uses another server's own extensions (vnd.dovecot.…, Zimbra's
extensions) won't compile. Take those parts out, or rebuild the rules in the
editor. Out-of-office is set again by the person, in the webmail.
Calendars and contacts¶
IMAP copies mail and nothing else. Calendars and contacts come across as
files: .ics for calendars, and .vcf or .ldif for contacts. Each person
imports them in the webmail. See importing a calendar
and importing contacts. Importing the
same file twice updates rather than duplicates, so a second, later export
is safe to import.
A CalDAV or CardDAV client that talks to both servers can also copy them across.
What doesn't come across¶
- Spam training. The filter learns again from what people mark.
- Sessions and app passwords. Everyone signs in again, and makes new app passwords.
- Server settings such as rate limits, transport rules and relay configuration. Set those up in the console.
Part 4: the cutover¶
- A day ahead, lower the TTL on the MX records and on the hostnames clients connect to, so the change takes effect quickly.
- Publish inbuxa's DKIM key and add its address to SPF, while the old server's entries are still there. Both servers can send validly during the overlap.
- Move MX to inbuxa. New mail starts arriving there.
- Move the client hostnames (the IMAP, SMTP and webmail names people's clients use). If they move to inbuxa unchanged, nobody has to reconfigure a client, but each client signs in once more.
- Copy the mail again. This pass picks up what reached the old server before the DNS change spread. Run it once more a day later for stragglers.
- Remove the old server's DKIM and SPF entries only once it has sent its last message.
Verification¶
Work down this list before you tell anyone it's done:
- an account signs in over IMAP, SMTP and in the webmail, with the password it already had (choices A and B);
- a message arrives from outside, and one leaves and passes DKIM, SPF and DMARC at the receiving end;
- aliases and mailing lists receive;
- a mailbox's folder and message counts match the old server's;
- filters run on new mail;
- someone disabled in the directory can't sign in (choice A).
Rolling back¶
Until the old server is gone, rolling back is moving MX and the client hostnames back. Mail that inbuxa received in the meantime is only on inbuxa. Copy it back with imapsync, the other way round, before you tell people it's over.
Keep the old server, read-only, until you have watched real mail flow through inbuxa for longer than you think you need to.