Fix the "nobody" replication problem
authorAlex Dehnert <alex@dehnerts.com>
Sat, 24 Oct 2020 03:30:31 +0000 (23:30 -0400)
committerAlex Dehnert <alex@dehnerts.com>
Sat, 24 Oct 2020 04:02:06 +0000 (00:02 -0400)
commit116f196c37e70e98c99c844e87358e474c96b909
tree6cdf7162aeee953d73e304151067fc9944dac106
parent421069361b9bf8111cae27e83fbda3375cf40aa8
Fix the "nobody" replication problem

dovecot by default only considers users with UIDs over 500. For normal mail
serving, this is a supplement to the "can you actually log in?" check, so it's
okay if it's a little too broad. For replication, though, dovecot enumerates
all the users and tries to replicate them all. If a user doesn't *really* exist
(nonexistent homedir, say), this produces annoying errors. Sadly, "nobody" is
treated as a real user by this default dovecot config, and mildly breaks some
stuff. I've been using "doveadm replicator remove nobody" to skip "nobody", but
this needs to be run every boot.

I've poked at various other solutions:
- I discovered a while ago the username_filter setting, which became available
  in Dovecot 2.2.30+. I'm finally running that, but it appears to be only for
  passdb's, and can't be set on userdb's. Since userdb's are responsible for
  the enumeration, this doesn't help.
- I found the result_success setting, and tried adding a userdb driven off of
  /etc/dovecot/deny-users with result_sucess = return-fail. After some
  confusing failures due to having initially used return_sucess instead, I got
  the config to parse, but it seems this doesn't exclude the user from the user
  list.
- The replication wiki page (https://wiki2.dovecot.org/Replication) notes that
  you can disable a user by providing the noreplicate database field.
  Unfortunately, that's not available until 2.3.1, which I still don't have.

Finally, I started wondering "so why is this only a problem with 'nobody', and
not, say, 'postfix'? Can I get that filtering to exclude 'nobody' as well?" I
pretty quickly found first_valid_uid and its friend last_valid_uid, which
worked.

Ubuntu seems to start UIDs at 1000, so I increased first_valid_uid accordingly.
last_valid_uid is pretty flexible ("alex" is the only user I care much
about[1], so really anything above 1000 and below 65534 would be fine), so I
picked 2000 to give plenty of room for additional users.

(As an additional note: it appears that once the replication engine learns
about a user, it may continue to store replication state for that user, even if
the user is removed from the userdb, and even across reboots, which makes it a
little hard to diagnose whether a user is being successfully excluded. It's
possible one of my other fixes did work, since I didn't discover this failure
mode until late. However, removing the user from the userdb, then manually
removing the user from replication, and finally rebooting, seems to keep it
gone.  In any case, the first/last UID technique seems better than the other
three I listed, at least for "nobody", so I'm not trying the other ones again.)

[1] There's a couple other users that it's marginally useful to replicate too
conf.d/10-mail.conf
conf.d/auth-system.conf.ext