Why ProFTPD isn't loading your config (for example PassivePorts)

Recently I had an issue where I migrated ProFTPD from one server to another, but the PassivePorts was being ignored (as was AllowOverwrite). Connections were timing out and tcpdump showed the client was connecting to the wrong port range for passive mode.

Nothing in the logs, but dumping the config showed the PassivePorts wasn't being loaded:

# proftpd -t -d 10 |& grep -i port
server.host.name proftpd[1888019] server.host.name: mod_lang/1.1: skipping possible language 'ko_KR': not supported by setlocale(3); see `locale -a'
server.host.name proftpd[1888019] server.host.name: mod_lang/1.1: skipping possible language 'ru_RU': not supported by setlocale(3); see `locale -a'
server.host.name proftpd[1888019] server.host.name: mod_lang/1.1: skipping possible language 'it_IT': not supported by setlocale(3); see `locale -a'
server.host.name proftpd[1888019] server.host.name: mod_lang/1.1: skipping possible language 'en_US': not supported by setlocale(3); see `locale -a'
server.host.name proftpd[1888019] server.host.name: mod_lang/1.1: skipping possible language 'zh_CN': not supported by setlocale(3); see `locale -a'
server.host.name proftpd[1888019] server.host.name: mod_lang/1.1: skipping possible language 'es_ES': not supported by setlocale(3); see `locale -a'
server.host.name proftpd[1888019] server.host.name: mod_lang/1.1: skipping possible language 'ja_JP': not supported by setlocale(3); see `locale -a'
server.host.name proftpd[1888019] server.host.name: mod_lang/1.1: skipping possible language 'zh_TW': not supported by setlocale(3); see `locale -a'
server.host.name proftpd[1888019] server.host.name: mod_lang/1.1: skipping possible language 'fr_FR': not supported by setlocale(3); see `locale -a'
server.host.name proftpd[1888019] server.host.name: mod_lang/1.1: skipping possible language 'bg_BG': not supported by setlocale(3); see `locale -a'

Strace shows it getting stuck at modules.conf:

# strace -f proftpd -t -d 10 |& grep open | grep conf
openat(AT_FDCWD, "/etc/nsswitch.conf", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/etc/proftpd/proftpd.conf", O_RDONLY) = 3
openat(AT_FDCWD, "/etc/proftpd/modules.conf", O_RDONLY) = 4
openat(AT_FDCWD, "/etc/host.conf", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/etc/resolv.conf", O_RDONLY|O_CLOEXEC) = 3

Back inproftpd -t -d 10:

proftpd[1888558]: fatal: LoadModule: error loading module 'mod_wrap.c': No such file or directory on line 64 of '/etc/proftpd/modules.conf'
proftpd[1888558]: RELINQUISH PRIVS at parser.c:1210
RELINQUISH PRIVS at mod_core.c:396
proftpd[1888558]: warning: unable to include '/etc/proftpd/modules.conf': Operation not permitted

So after one error it drops privileges, but continues 'loading' modules and presumably loads a default configuration.

Installing the missing module fixed the problem:

# apt-get install proftpd-mod-wrap
# proftpd -t -d 10 |& grep -i port
server.host.name proftpd[1889516] server.host.name: Port
server.host.name proftpd[1889516] server.host.name: PassivePorts

Restart ProFTPD and passive works again.