Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to load mod_rewrite as a dynamic module due to incomplete/missing library linker flags #1590

Closed
pghmcfc opened this issue Feb 2, 2023 · 16 comments
Assignees
Milestone

Comments

@pghmcfc
Copy link
Contributor

pghmcfc commented Feb 2, 2023

What I Did

Added LoadModule mod_rewrite.c to existing working configuration. After doing this, proftpd no longer starts.

Originally reported for Alma Linux 9 (clone of Red Hat Enterprise Linux 9):
https://bugzilla.redhat.com/show_bug.cgi?id=2166454

I can reproduce this on Fedora 37.

# /usr/sbin/proftpd -td10 -c /etc/proftpd.conf
Checking syntax of configuration file
2023-02-02 09:37:43,073 goalkeeper.city-fan.org proftpd[454172]: using PCRE2 10.40
2023-02-02 09:37:43,075 goalkeeper.city-fan.org proftpd[454172]: using TCP receive buffer size of 131072 bytes
2023-02-02 09:37:43,075 goalkeeper.city-fan.org proftpd[454172]: using TCP send buffer size of 16384 bytes
2023-02-02 09:37:43,076 goalkeeper.city-fan.org proftpd[454172]: using 'en_GB.UTF-8' locale based on LANG=en_GB.UTF-8 environment variable
2023-02-02 09:37:43,076 goalkeeper.city-fan.org proftpd[454172]: using 'UTF-8' as local charset for UTF-8 conversion
2023-02-02 09:37:43,076 goalkeeper.city-fan.org proftpd[454172]: mod_tls/2.9.2: using OpenSSL 3.0.5 5 Jul 2022
2023-02-02 09:37:43,076 goalkeeper.city-fan.org proftpd[454172]: mod_memcache/0.1: using libmemcached-1.1.3
2023-02-02 09:37:43,076 goalkeeper.city-fan.org proftpd[454172]: ROOT PRIVS at mod_core.c:384
2023-02-02 09:37:43,076 goalkeeper.city-fan.org proftpd[454172]: RELINQUISH PRIVS at mod_core.c:386
2023-02-02 09:37:43,076 goalkeeper.city-fan.org proftpd[454172]: ROOT PRIVS at mod_core.c:393
2023-02-02 09:37:43,076 goalkeeper.city-fan.org proftpd[454172]: ROOT PRIVS at parser.c:1207
2023-02-02 09:37:43,076 goalkeeper.city-fan.org proftpd[454172]: mod_dso/0.5: loading 'mod_ctrls_admin.c'
2023-02-02 09:37:43,076 goalkeeper.city-fan.org proftpd[454172]: mod_dso/0.5: loaded module 'mod_ctrls_admin' (from '/usr/libexec/proftpd/mod_ctrls_admin.so', last modified on Wed Jan 25 12:44:16 2023)
2023-02-02 09:37:43,077 goalkeeper.city-fan.org proftpd[454172]: mod_dso/0.5: loading 'mod_rewrite.c'
2023-02-02 09:37:43,077 goalkeeper.city-fan.org proftpd[454172]: mod_dso/0.5: unable to dlopen 'mod_rewrite.c': file not found (No such file or directory)
2023-02-02 09:37:43,077 goalkeeper.city-fan.org proftpd[454172]: mod_dso/0.5: unable to load 'mod_rewrite.c'; check to see if '/usr/libexec/proftpd/mod_rewrite.la' exists
2023-02-02 09:37:43,077 goalkeeper.city-fan.org proftpd[454172]: mod_dso/0.5: defaulting to 'self' for symbol resolution
2023-02-02 09:37:43,077 goalkeeper.city-fan.org proftpd[454172]: mod_dso/0.5: unable to find module symbol 'rewrite_module' in 'self'
2023-02-02 09:37:43,077 goalkeeper.city-fan.org proftpd[454172]: fatal: LoadModule: error loading module 'mod_rewrite.c': No such file or directory on line 101 of '/etc/proftpd/modules.conf'
2023-02-02 09:37:43,077 goalkeeper.city-fan.org proftpd[454172]: RELINQUISH PRIVS at parser.c:1210
2023-02-02 09:37:43,077 goalkeeper.city-fan.org proftpd[454172]: RELINQUISH PRIVS at mod_core.c:396
2023-02-02 09:37:43,077 goalkeeper.city-fan.org proftpd[454172]: warning: unable to include '/etc/proftpd/modules.conf': Operation not permitted
2023-02-02 09:37:43,077 goalkeeper.city-fan.org proftpd[454172]: mod_dso/0.5: loading 'mod_vroot.c'
2023-02-02 09:37:43,077 goalkeeper.city-fan.org proftpd[454172]: mod_dso/0.5: loaded module 'mod_vroot' (from '/usr/libexec/proftpd/mod_vroot.so', last modified on Wed Jan 25 12:44:16 2023)
2023-02-02 09:37:43,077 goalkeeper.city-fan.org proftpd[454172]: <IfDefine>: skipping 'DYNAMIC_BAN_LISTS' section at line 154
2023-02-02 09:37:43,077 goalkeeper.city-fan.org proftpd[454172]: <IfDefine>: skipping 'QOS' section at line 160
2023-02-02 09:37:43,078 goalkeeper.city-fan.org proftpd[454172] goalkeeper.city-fan.org: 
2023-02-02 09:37:43,078 goalkeeper.city-fan.org proftpd[454172] goalkeeper.city-fan.org: Config for ProFTPD:
2023-02-02 09:37:43,078 goalkeeper.city-fan.org proftpd[454172] goalkeeper.city-fan.org: mod_lang/1.1: binding to text domain 'proftpd' using locale path '/usr/share/locale'
2023-02-02 09:37:43,078 goalkeeper.city-fan.org proftpd[454172] goalkeeper.city-fan.org: mod_lang/1.1: using locale files in '/usr/share/locale'
2023-02-02 09:37:43,079 goalkeeper.city-fan.org proftpd[454172] goalkeeper.city-fan.org: mod_lang/1.1: skipping possible language 'zh_CN': not supported by setlocale(3); see `locale -a'
2023-02-02 09:37:43,079 goalkeeper.city-fan.org proftpd[454172] goalkeeper.city-fan.org: mod_lang/1.1: skipping possible language 'ru_RU': not supported by setlocale(3); see `locale -a'
2023-02-02 09:37:43,079 goalkeeper.city-fan.org proftpd[454172] goalkeeper.city-fan.org: mod_lang/1.1: skipping possible language 'ja_JP': not supported by setlocale(3); see `locale -a'
2023-02-02 09:37:43,079 goalkeeper.city-fan.org proftpd[454172] goalkeeper.city-fan.org: mod_lang/1.1: skipping possible language 'zh_TW': not supported by setlocale(3); see `locale -a'
2023-02-02 09:37:43,079 goalkeeper.city-fan.org proftpd[454172] goalkeeper.city-fan.org: mod_lang/1.1: skipping possible language 'fr_FR': not supported by setlocale(3); see `locale -a'
2023-02-02 09:37:43,080 goalkeeper.city-fan.org proftpd[454172] goalkeeper.city-fan.org: mod_lang/1.1: skipping possible language 'ko_KR': not supported by setlocale(3); see `locale -a'
2023-02-02 09:37:43,080 goalkeeper.city-fan.org proftpd[454172] goalkeeper.city-fan.org: mod_lang/1.1: skipping possible language 'it_IT': not supported by setlocale(3); see `locale -a'
2023-02-02 09:37:43,080 goalkeeper.city-fan.org proftpd[454172] goalkeeper.city-fan.org: mod_lang/1.1: skipping possible language 'es_ES': not supported by setlocale(3); see `locale -a'
2023-02-02 09:37:43,081 goalkeeper.city-fan.org proftpd[454172] goalkeeper.city-fan.org: mod_lang/1.1: skipping possible language 'bg_BG': not supported by setlocale(3); see `locale -a'
2023-02-02 09:37:43,081 goalkeeper.city-fan.org proftpd[454172] goalkeeper.city-fan.org: mod_lang/1.1: added the following supported languages: en_US
2023-02-02 09:37:43,081 goalkeeper.city-fan.org proftpd[454172] goalkeeper.city-fan.org: ROOT PRIVS at mod_ctrls.c:1233
2023-02-02 09:37:43,081 goalkeeper.city-fan.org proftpd[454172] goalkeeper.city-fan.org: RELINQUISH PRIVS at mod_ctrls.c:1235
2023-02-02 09:37:43,082 goalkeeper.city-fan.org proftpd[454172] goalkeeper.city-fan.org: mod_tls/2.9.2: generating initial TLS session ticket key
2023-02-02 09:37:43,082 goalkeeper.city-fan.org proftpd[454172] goalkeeper.city-fan.org: ROOT PRIVS at mod_tls.c:6548
2023-02-02 09:37:43,082 goalkeeper.city-fan.org proftpd[454172] goalkeeper.city-fan.org: RELINQUISH PRIVS at mod_tls.c:6551
2023-02-02 09:37:43,082 goalkeeper.city-fan.org proftpd[454172] goalkeeper.city-fan.org: mod_tls/2.9.2: scheduling new TLS session ticket key every 3600 secs
2023-02-02 09:37:43,082 goalkeeper.city-fan.org proftpd[454172] goalkeeper.city-fan.org: ROOT PRIVS at mod_delay.c:583
2023-02-02 09:37:43,082 goalkeeper.city-fan.org proftpd[454172] goalkeeper.city-fan.org: RELINQUISH PRIVS at mod_delay.c:586
2023-02-02 09:37:43,082 goalkeeper.city-fan.org proftpd[454172] goalkeeper.city-fan.org: ROOT PRIVS at mod_rlimit.c:554
2023-02-02 09:37:43,082 goalkeeper.city-fan.org proftpd[454172] goalkeeper.city-fan.org: RELINQUISH PRIVS at mod_rlimit.c:557
2023-02-02 09:37:43,082 goalkeeper.city-fan.org proftpd[454172] goalkeeper.city-fan.org: set core resource limits for daemon
Syntax check complete.

It's not a general module loading issue as I tried loading mod_load instead of mod_rewrite and that worked OK.
The modules are present as ".so" files but not ".la" files:

# ls -l /usr/libexec/proftpd/
total 1596
-rwxr-xr-x. 1 root root  65784 Jan 25 12:44 mod_ban.so
-rwxr-xr-x. 1 root root  28304 Jan 25 12:44 mod_copy.so
-rwxr-xr-x. 1 root root  40768 Jan 25 12:44 mod_ctrls_admin.so
-rwxr-xr-x. 1 root root  32216 Jan 25 12:44 mod_deflate.so
-rwxr-xr-x. 1 root root  44976 Jan 25 12:44 mod_exec.so
-rwxr-xr-x. 1 root root  15504 Jan 25 12:44 mod_facl.so
-rwxr-xr-x. 1 root root  28272 Jan 25 12:44 mod_ifsession.so
-rwxr-xr-x. 1 root root  15528 Jan 25 12:44 mod_ifversion.so
-rwxr-xr-x. 1 root root  15464 Jan 25 12:44 mod_load.so
-rwxr-xr-x. 1 root root  15552 Jan 25 12:44 mod_qos.so
-rwxr-xr-x. 1 root root  15488 Jan 25 12:44 mod_quotatab_file.so
-rwxr-xr-x. 1 root root  15448 Jan 25 12:44 mod_quotatab_radius.so
-rwxr-xr-x. 1 root root  71472 Jan 25 12:44 mod_quotatab.so
-rwxr-xr-x. 1 root root  19608 Jan 25 12:44 mod_quotatab_sql.so
-rwxr-xr-x. 1 root root  66304 Jan 25 12:44 mod_radius.so
-rwxr-xr-x. 1 root root  28968 Jan 25 12:44 mod_ratio.so
-rwxr-xr-x. 1 root root  53280 Jan 25 12:44 mod_rewrite.so
-rwxr-xr-x. 1 root root  28032 Jan 25 12:44 mod_sftp_pam.so
-rwxr-xr-x. 1 root root 552840 Jan 25 12:44 mod_sftp.so
-rwxr-xr-x. 1 root root  19632 Jan 25 12:44 mod_sftp_sql.so
-rwxr-xr-x. 1 root root  44976 Jan 25 12:44 mod_shaper.so
-rwxr-xr-x. 1 root root  36400 Jan 25 12:44 mod_site_misc.so
-rwxr-xr-x. 1 root root  36656 Jan 25 12:44 mod_sql_passwd.so
-rwxr-xr-x. 1 root root  96832 Jan 25 12:44 mod_sql.so
-rwxr-xr-x. 1 root root  36176 Jan 25 12:44 mod_tls_memcache.so
-rwxr-xr-x. 1 root root  44408 Jan 25 12:44 mod_tls_shmcache.so
-rwxr-xr-x. 1 root root  15512 Jan 25 12:44 mod_unique_id.so
-rwxr-xr-x. 1 root root  46032 Jan 25 12:44 mod_vroot.so
-rwxr-xr-x. 1 root root  15488 Jan 25 12:44 mod_wrap2_file.so
-rwxr-xr-x. 1 root root  36816 Jan 25 12:44 mod_wrap2.so
-rwxr-xr-x. 1 root root  15496 Jan 25 12:44 mod_wrap2_sql.so

ProFTPD Version and Configuration

Please help us reproduce the problem/issue you are encountering. To do this,
we need to know which version of ProFTPD you are using, how it was built,
etc. The following command is an easy way to get all of this information:

[root@goalkeeper ~]# proftpd -V
Compile-time Settings:
  Version: 1.3.8 (stable)
  Platform: LINUX [Linux 6.0.12-300.fc37.x86_64 x86_64]
  OS/Release:
    NAME="Fedora Linux"
    VERSION="37 (Server Edition)"
    ID=fedora
    VERSION_ID=37
    VERSION_CODENAME=""
    PLATFORM_ID="platform:f37"
    PRETTY_NAME="Fedora Linux 37 (Server Edition)"
    CPE_NAME="cpe:/o:fedoraproject:fedora:37"
    REDHAT_BUGZILLA_PRODUCT="Fedora"
    REDHAT_BUGZILLA_PRODUCT_VERSION=37
    REDHAT_SUPPORT_PRODUCT="Fedora"
    REDHAT_SUPPORT_PRODUCT_VERSION=37
    SUPPORT_END=2023-11-14
    VARIANT="Server Edition"
    VARIANT_ID=server
  Built: Sat Jan 21 2023 00:00:00 UTC
  Built With:
    configure  '--build=x86_64-redhat-linux-gnu' '--host=x86_64-redhat-linux-gnu' '--program-prefix=' '--disable-dependency-tracking' '--prefix=/usr' '--exec-prefix=/usr' '--bindir=/usr/bin' '--sbindir=/usr/sbin' '--sysconfdir=/etc' '--datadir=/usr/share' '--includedir=/usr/include' '--libdir=/usr/lib64' '--libexecdir=/usr/libexec' '--localstatedir=/var' '--sharedstatedir=/var/lib' '--mandir=/usr/share/man' '--infodir=/usr/share/info' '--libexecdir=/usr/libexec/proftpd' '--localstatedir=/run/proftpd' '--disable-strip' '--enable-ctrls' '--enable-dso' '--enable-facl' '--enable-ipv6' '--enable-memcache' '--enable-nls' '--enable-openssl' '--disable-pcre' '--enable-pcre2' '--disable-redis' '--enable-shadow' '--enable-tests' '--with-libraries=/usr/lib64/mariadb' '--with-includes=/usr/include/mysql' '--with-modules=mod_readme:mod_auth_pam:mod_tls' '--with-shared=mod_sql:mod_sql_passwd:mod_sql_mysql:mod_sql_postgres:mod_sql_sqlite:mod_quotatab:mod_quotatab_file:mod_quotatab_ldap:mod_quotatab_radius:mod_quotatab_sql:mod_ldap:mod_ban:mod_ctrls_admin:mod_facl:mod_load:mod_vroot:mod_radius:mod_ratio:mod_rewrite:mod_site_misc:mod_exec:mod_shaper:mod_wrap2:mod_wrap2_file:mod_wrap2_sql:mod_copy:mod_deflate:mod_ifversion:mod_qos:mod_sftp:mod_sftp_pam:mod_sftp_sql:mod_tls_shmcache:mod_tls_memcache:mod_unique_id:mod_ifsession' 'build_alias=x86_64-redhat-linux-gnu' 'host_alias=x86_64-redhat-linux-gnu' 'CC=gcc' 'CFLAGS=-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1  -m64  -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection' 'LDFLAGS=-Wl,-z,relro -Wl,--as-needed  -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1  -Wl,--build-id=sha1 -specs=/usr/lib/rpm/redhat/redhat-package-notes' 'CXX=g++' 'CXXFLAGS=-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1  -m64  -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection'

  CFLAGS: -g2 -O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1  -m64  -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -Wall -fno-omit-frame-pointer -fno-strict-aliasing -Werror=implicit-function-declaration
  LDFLAGS: -Wl,-L$(top_srcdir)/lib,-L$(top_builddir)/lib -Wl,-z,relro -Wl,--as-needed  -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1  -Wl,--build-id=sha1 -specs=/usr/lib/rpm/redhat/redhat-package-notes -rdynamic -L/usr/lib64/mariadb -L/usr/lib64/ -L/usr/lib64
  LIBS:  -lpcre2-posix -lpcre2-8 -lssl -lcrypto -lcap  -lssl -lcrypto  -lpam -lattr -lresolv -lresolv -lcrypt -lmemcachedutil -lmemcached 

  Files:
    Configuration File:
      /etc/proftpd.conf
    Pid File:
      /run/proftpd/proftpd.pid
    Scoreboard File:
      /run/proftpd/proftpd.scoreboard
    Header Directory:
      /usr/include/proftpd
    Shared Module Directory:
      /usr/libexec/proftpd

  Info:
    + Max supported UID: 4294967295
    + Max supported GID: 4294967295

  Features:
    - Autoshadow support
    + Controls support
    + curses support
    - Developer support
    + DSO support
    + IPv6 support
    + Largefile support
    - Lastlog support
    + Memcache support
    + ncursesw support
    + NLS support
    + OpenSSL support (OpenSSL 3.0.5 5 Jul 2022)
    - PCRE support
    + PCRE2 support
    + POSIX ACL support
    - Redis support
    + Sendfile support
    + Shadow file support
    - Sodium support
    + Trace support
    + xattr support

  Tunable Options:
    PR_TUNABLE_BUFFER_SIZE = 1024
    PR_TUNABLE_DEFAULT_RCVBUFSZ = 8192
    PR_TUNABLE_DEFAULT_SNDBUFSZ = 8192
    PR_TUNABLE_ENV_MAX = 2048
    PR_TUNABLE_GLOBBING_MAX_MATCHES = 100000
    PR_TUNABLE_GLOBBING_MAX_RECURSION = 8
    PR_TUNABLE_HASH_TABLE_SIZE = 40
    PR_TUNABLE_LOGIN_MAX = 256
    PR_TUNABLE_NEW_POOL_SIZE = 512
    PR_TUNABLE_PATH_MAX = 4096
    PR_TUNABLE_SCOREBOARD_BUFFER_SIZE = 80
    PR_TUNABLE_SCOREBOARD_SCRUB_TIMER = 30
    PR_TUNABLE_SELECT_TIMEOUT = 30
    PR_TUNABLE_TIMEOUTIDENT = 10
    PR_TUNABLE_TIMEOUTIDLE = 600
    PR_TUNABLE_TIMEOUTLINGER = 10
    PR_TUNABLE_TIMEOUTLOGIN = 300
    PR_TUNABLE_TIMEOUTNOXFER = 300
    PR_TUNABLE_TIMEOUTSTALLED = 3600
    PR_TUNABLE_XFER_SCOREBOARD_UPDATES = 10

In addition, we need to see all of the ProFTPD configuration files you are
using (minus any sensitive information like passwords, of course). Armed
with the version and configuration data, then, we can set up ProFTPD locally
using the same configuration, and see what happens.

/etc/sysconfig/proftpd

# Set PROFTPD_OPTIONS to add command-line options for proftpd.
# See proftpd(8) for a comprehensive list of what can be used.
#
# The following "Defines" can be used with the default configuration file:
# -DANONYMOUS_FTP	: Enable anonymous FTP
# -DDYNAMIC_BAN_LISTS	: Enable dynamic ban lists (mod_ban)
# -DQOS			: Enable QoS bits on server traffic (mod_qos)
# -DTLS			: Enable TLS (mod_tls)
#
# For example, for anonymous FTP and dynamic ban list support:
# PROFTPD_OPTIONS="-DANONYMOUS_FTP -DDYNAMIC_BAN_LISTS"
PROFTPD_OPTIONS="-DANONYMOUS_FTP -DDYNAMIC_BAN_LISTS -DTLS"

/etc/proftpd.conf

# ProFTPD Configuration for ftp.city-fan.org
#
# See: http://www.proftpd.org/docs/directives/linked/by-name.html

# Security-Enhanced Linux (SELinux) Notes:
#
# In Fedora and Red Hat Enterprise Linux, ProFTPD runs confined by SELinux
# in order to mitigate the effects of an attacker taking advantage of an
# unpatched vulnerability and getting control of the ftp server. By default,
# ProFTPD cannot read or write most files on a system nor connect to many
# external network services, but these restrictions can be relaxed by
# setting SELinux booleans as follows:
#
# setsebool -P ftpd_anon_write=1
#   This allows the ftp daemon to write to files and directories labelled
#   with the public_content_rw_t context type; the daemon would only have
#   read access to these files normally. Files to be made available by ftp
#   but not writeable should be labelled public_content_t.
#   On older systems this boolean was called allow_ftpd_anon_write.
#
# setsebool -P ftpd_full_access=1
#   This allows the ftp daemon to read and write all files on the system.
#   On older systems this boolean was called allow_ftpd_full_access, and there
#   was a separate boolean ftp_home_dir to allow the ftp daemon access to
#   files in users' home directories.
#
# setsebool -P ftpd_use_cifs=1
#   This allows the ftp daemon to read and write files on CIFS-mounted
#   filesystems.
#   On older systems this boolean was called allow_ftpd_use_cifs.
#
# setsebool -P ftpd_use_fusefs=1
#   This allows the ftp daemon to read and write files on ntfs/fusefs-mounted
#   filesystems.
#
# setsebool -P ftpd_use_nfs=1
#   This allows the ftp daemon to read and write files on NFS-mounted
#   filesystems.
#   On older systems this boolean was called allow_ftpd_use_nfs.
#
# setsebool -P ftpd_connect_all_unreserved=1
#   This setting is only available from Fedora 16/RHEL-7 onwards, and is
#   necessary for active-mode ftp transfers to work reliably with non-Linux
#   clients (see http://bugzilla.redhat.com/782177), which may choose to
#   use port numbers outside the "ephemeral port" range of 32768-61000.
#
# setsebool -P ftpd_connect_db=1
#   This setting allows the ftp daemon to connect to commonly-used database
#   ports over the network, which is necessary if you are using a database
#   back-end for user authentication, etc.
#
# setsebool -P ftpd_use_passive_mode=1
#   This setting allows the ftp daemon to bind to all unreserved ports for
#   passive mode.
#
# All of these booleans are unset by default.
#
# See also the "ftpd_selinux" manpage.
#
# Note that the "-P" option to setsebool makes the setting permanent, i.e.
# it will still be in effect after a reboot; without the "-P" option, the
# effect only lasts until the next reboot.
#
# Restrictions imposed by SELinux are on top of those imposed by ordinary
# file ownership and access permissions; in normal operation, the ftp daemon
# will not be able to read and/or write a file unless *all* of the ownership,
# permission and SELinux restrictions allow it.

# Load DSO modules as required
Include /etc/proftpd/modules.conf

# Server Config - config used for anything outside a <VirtualHost> or <Global> context
# See: http://www.proftpd.org/docs/howto/Vhost.html

# Trace logging, disabled by default for performance reasons
# (http://www.proftpd.org/docs/howto/Tracing.html)
#TraceLog			/var/log/proftpd/trace.log
#Trace				ctrls:3

ServerName			"ProFTPD server"
ServerIdent			on "Welcome to ftp.city-fan.org."
ServerAdmin			ftpadmin@city-fan.org
DefaultServer			on

# Copious debugging output
#DebugLevel			5
#SystemLog			/var/log/proftpd/debug.log

# Cause every FTP user except paul to be chrooted into their home directory
DefaultRoot			~ !paul

# Use pam to authenticate (default) and be authoritative
AuthPAMConfig			proftpd
AuthOrder			mod_auth_pam.c* mod_auth_unix.c
# If you use NIS/YP/LDAP you may need to disable PersistentPasswd
#PersistentPasswd		off

# Don't do reverse DNS lookups (hangs on DNS problems)
#UseReverseDNS			off

# Set the user and group that the server runs as
User				nobody
Group				nobody

# To prevent DoS attacks, set the maximum number of child processes
# to 20.  If you need to allow more than 20 concurrent connections
# at once, simply increase this value.  Note that this ONLY works
# in standalone mode; in inetd mode you should use an inetd server
# that allows you to limit maximum number of processes per service
# (such as xinetd)
MaxInstances			20

# Disable sendfile by default since it breaks displaying the download speeds in
# ftptop and ftpwho
#UseSendfile			off

# Define the log formats
LogFormat			default	"%h %l %u %t \"%r\" %s %b"
LogFormat			auth	"%v [%P] %h %t \"%r\" %s"

# Don't log hostname or timestamps because systemd will do that for us
LogOptions			-Timestamp -Hostname +RoleBasedProcessLabels

# Login delays to slow down clients using multiple logins
<IfModule mod_delay.c>
  # This gets cleared on reboot
  DelayTable			/run/proftpd/proftpd.delay

  # Allow root to use "ftpdctl delay ..."
  DelayControlsACLS		all allow user root

  # Configure successful logins to be delayed by 2 secs
  DelayOnEvent			PASS 2000ms

  # Configure failed logins to be delayed by 5 secs
  DelayOnEvent			FailedLogin 5s
</IfModule>

# Enable basic controls via ftpdctl
# (http://www.proftpd.org/docs/modules/mod_ctrls.html)
ControlsEngine			on
ControlsACLs			all allow user root
ControlsSocketACL		allow user *
ControlsLog			/var/log/proftpd/controls.log

# Enable admin controls via ftpdctl
# (http://www.proftpd.org/docs/contrib/mod_ctrls_admin.html)
<IfModule mod_ctrls_admin.c>
  AdminControlsEngine		on
  AdminControlsACLs		all allow user root
</IfModule>

# Enable mod_vroot by default for better compatibility with PAM
# (http://bugzilla.redhat.com/506735)
<IfModule mod_vroot.c>
  VRootEngine			on
</IfModule>

# TLS (http://www.castaglia.org/proftpd/modules/mod_tls.html)
# Enable this with PROFTPD_OPTIONS=-DTLS in /etc/sysconfig/proftpd
<IfDefine TLS>
Include /etc/proftpd/mod_tls.conf
</IfDefine>

# Dynamic ban lists (http://www.proftpd.org/docs/contrib/mod_ban.html)
# Enable this with PROFTPD_OPTIONS=-DDYNAMIC_BAN_LISTS in /etc/sysconfig/proftpd
<IfModule mod_ban.c>
Include /etc/proftpd/mod_ban.conf
</IfModule>

# Set networking-specific "Quality of Service" (QoS) bits on the packets used
# by the server (http://www.proftpd.org/docs/contrib/mod_qos.html)
<IfModule mod_qos.c>
Include /etc/proftpd/mod_qos.conf
</IfModule>

# Global Config - config common to Server Config and all virtual hosts
# See: http://www.proftpd.org/docs/howto/Vhost.html
<Global>

  # Umask 022 is a good standard umask to prevent new dirs and files
  # from being group and world writable
  Umask				022

  # Allow users to overwrite files and change permissions
  AllowOverwrite		yes
  <Limit ALL SITE_CHMOD>
    AllowAll
  </Limit>

</Global>

# A basic anonymous configuration, with an upload directory
# Enable this with PROFTPD_OPTIONS=-DANONYMOUS_FTP in /etc/sysconfig/proftpd
<IfDefine ANONYMOUS_FTP>
Include /etc/proftpd/anonftp.conf
</IfDefine>

# Include other custom configuration files
Include /etc/proftpd/conf.d/*.conf

/etc/proftpd/anonftp.conf

# A basic anonymous configuration, with an upload directory
# Enable this with PROFTPD_OPTIONS=-DANONYMOUS_FTP in /etc/sysconfig/proftpd
<Anonymous ~ftp>
  User			ftp
  Group			ftp
  AccessGrantMsg	"Anonymous login ok, restrictions apply."

  # We want clients to be able to login with "anonymous" as well as "ftp"
  UserAlias		anonymous ftp

  # Limit the maximum number of anonymous logins
  MaxClients		10 "Sorry, max %m users -- try again later"

  # Put the user into /pub right after login
  #DefaultChdir		/pub

  # We want 'welcome.msg' displayed at login, '.message' displayed in
  # each newly chdired directory and tell users to read README* files.
  DisplayLogin		/welcome.msg
  DisplayChdir		.message
  DisplayReadme		README*

  # Don't want google indexing the FTP site when they can access it via HTTP
  AnonRejectPasswords	googlebot@google\.com

  # Cosmetic option to make all files appear to be owned by user "ftp"
  DirFakeUser		on ftp
  DirFakeGroup		on ftp

  # Limit WRITE everywhere in the anonymous chroot
  <Limit WRITE SITE_CHMOD>
    DenyAll
  </Limit>

  # An upload directory that allows storing files but not retrieving
  # or creating directories.
  #
  # Directory specification is slightly different if mod_vroot is in
  # use: see http://sourceforge.net/p/proftp/mailman/message/31728570/
  #          https://bugzilla.redhat.com/show_bug.cgi?id=1045922
  <IfModule mod_vroot.c>
    <Directory /uploads/*>
      AllowOverwrite		no
      <Limit READ>
        DenyAll
      </Limit>

      <Limit STOR>
        AllowAll
      </Limit>
    </Directory>
  </IfModule>
  <IfModule !mod_vroot.c>
    <Directory uploads/*>
      AllowOverwrite		no
      <Limit READ>
        DenyAll
      </Limit>

      <Limit STOR>
        AllowAll
      </Limit>
    </Directory>
  </IfModule>

  # Don't write anonymous accesses to the system wtmp file (good idea!)
  WtmpLog			off

  # Logging for the anonymous transfers
  ExtendedLog			/var/log/proftpd/access.log WRITE,READ default
  ExtendedLog			/var/log/proftpd/auth.log AUTH auth

</Anonymous>

/etc/proftpd/mod_ban.conf

# Dynamic ban lists (http://www.proftpd.org/docs/contrib/mod_ban.html)
<IfModule mod_ban.c>
  BanEngine			on
  BanLog			/var/log/proftpd/ban.log
  BanTable			/run/proftpd/ban.tab

  # If the same client reaches the MaxLoginAttempts limit 2 times
  # within 10 minutes, automatically add a ban for that client that
  # will expire after 24 hours.
  BanOnEvent			MaxLoginAttempts 2/00:10:00 24:00:00

  # Inform the user that it's not worth persisting
  BanMessage			"Host %a has been banned"

  # Allow root to manually add/remove bans
  BanControlsACLs		all allow user root
</IfModule>

/etc/proftpd/mod_qos.conf

# Set networking-specific "Quality of Service" (QoS) bits on the packets used
# by the server (http://www.proftpd.org/docs/contrib/mod_qos.html)
<IfModule mod_qos.c>
  # RFC791 TOS parameter compatibility
  QoSOptions			dataqos throughput ctrlqos lowdelay
  # For a DSCP environment (may require tweaking)
  #QoSOptions			dataqos CS2 ctrlqos AF41
</IfModule>

/etc/proftpd/mod_tls.conf

# TLS (http://www.castaglia.org/proftpd/modules/mod_tls.html)
<IfModule mod_tls.c>
  TLSEngine			on
  TLSRequired			off
  TLSCertificateChainFile	/etc/pki/tls/certs/ftpserver-chain.pem
  TLSRSACertificateFile		/etc/pki/tls/certs/ftpserver-cert.pem
  TLSRSACertificateKeyFile	/etc/pki/tls/private/ftpserver.pem
  TLSCipherSuite		PROFILE=SYSTEM
  # Relax the requirement that the SSL session be re-used for data transfers
  TLSOptions			NoSessionReuseRequired
  TLSLog			/var/log/proftpd/tls.log
  <IfModule mod_tls_shmcache.c>
    TLSSessionCache		shm:/file=/run/proftpd/sesscache
  </IfModule>
</IfModule>

/etc/proftpd/modules.conf

# Dynamic Shared Object (DSO) loading
# See README.DSO and howto/DSO.html for more details


# Allow only user root to load and unload modules, but allow everyone
# to see which modules have been loaded
# (http://www.proftpd.org/docs/modules/mod_dso.html#ModuleControlsACLs)
ModuleControlsACLs              insmod,rmmod allow user root
ModuleControlsACLs              lsmod allow user *

#
# General database support (http://www.proftpd.org/docs/contrib/mod_sql.html)
# Note that this module is required if you use any of the other mod_sql_*
# modules
#   LoadModule mod_sql.c
#
# Support for base-64 or hex encoded MD5 and SHA1 passwords from SQL tables
# (contrib/mod_sql_passwd.html)
#   LoadModule mod_sql_passwd.c
#
# Mysql support (requires proftpd-mysql package)
# (http://www.proftpd.org/docs/contrib/mod_sql.html)
#   LoadModule mod_sql_mysql.c
#
# Postgresql support (requires proftpd-postgresql package)
# (http://www.proftpd.org/docs/contrib/mod_sql.html)
#   LoadModule mod_sql_postgres.c
#
# SQLite support (requires proftpd-sqlite package)
# (http://www.proftpd.org/docs/contrib/mod_sql.html,
#  http://www.proftpd.org/docs/contrib/mod_sql_sqlite.html)
#   LoadModule mod_sql_sqlite.c
#
# Quota support (http://www.proftpd.org/docs/contrib/mod_quotatab.html)
#   LoadModule mod_quotatab.c
#
# File-specific "driver" for storing quota table information in files
# (http://www.proftpd.org/docs/contrib/mod_quotatab_file.html)
#   LoadModule mod_quotatab_file.c
#
# SQL database "driver" for storing quota table information in SQL tables
# (http://www.proftpd.org/docs/contrib/mod_quotatab_sql.html)
#   LoadModule mod_quotatab_sql.c
#
# LDAP support (requires proftpd-ldap package)
# (http://www.proftpd.org/docs/directives/linked/config_ref_mod_ldap.html)
#   LoadModule mod_ldap.c
#
# LDAP quota support (requires proftpd-ldap package)
# (http://www.proftpd.org/docs/contrib/mod_quotatab_ldap.html)
#   LoadModule mod_quotatab_ldap.c
#
# Support for authenticating users using the RADIUS protocol
# (http://www.proftpd.org/docs/contrib/mod_radius.html)
#   LoadModule mod_radius.c
#
# Retrieve quota limit table information from a RADIUS server
# (http://www.proftpd.org/docs/contrib/mod_quotatab_radius.html)
#   LoadModule mod_quotatab_radius.c
#
# SITE CPFR and SITE CPTO commands (analogous to RNFR and RNTO), which can be
# used to copy files/directories from one place to another on the server
# without having to transfer the data to the client and back
# (http://www.castaglia.org/proftpd/modules/mod_copy.html)
#   LoadModule mod_copy.c
#
# Administrative control actions for the ftpdctl program
# (http://www.proftpd.org/docs/contrib/mod_ctrls_admin.html)
LoadModule mod_ctrls_admin.c
#
# Support for MODE Z commands, which allows FTP clients and servers to
# compress data for transfer
# (http://www.castaglia.org/proftpd/modules/mod_deflate.html)
#   LoadModule mod_deflate.c
#
# Execute external programs or scripts at various points in the process
# of handling FTP commands
# (http://www.castaglia.org/proftpd/modules/mod_exec.html)
#   LoadModule mod_exec.c
#
# Support for POSIX ACLs
# (http://www.proftpd.org/docs/modules/mod_facl.html)
#   LoadModule mod_facl.c
#
# Allow for version-specific configuration sections of the proftpd config file,
# useful for using the same proftpd config across multiple servers where
# different proftpd versions may be in use
# (http://www.castaglia.org/proftpd/modules/mod_ifversion.html)
#   LoadModule mod_ifversion.c
#
# Configure server availability based on system load
# (http://www.proftpd.org/docs/contrib/mod_load.html)
#   LoadModule mod_load.c
#
# Limit downloads to a multiple of upload volume (see README.ratio)
#   LoadModule mod_ratio.c
#
# Rewrite FTP commands sent by clients on-the-fly,
# using regular expression matching and substitution 
# (http://www.proftpd.org/docs/contrib/mod_rewrite.html)
LoadModule mod_rewrite.c
#
# Support for the SSH2, SFTP, and SCP protocols, for secure file transfer over
# an SSH2 connection (http://www.castaglia.org/proftpd/modules/mod_sftp.html)
#   LoadModule mod_sftp.c
#
# Use PAM to provide a 'keyboard-interactive' SSH2 authentication method for
# mod_sftp (http://www.castaglia.org/proftpd/modules/mod_sftp_pam.html)
#   LoadModule mod_sftp_pam.c
#
# Use SQL (via mod_sql) for looking up authorized SSH2 public keys for user
# and host based authentication
# (http://www.castaglia.org/proftpd/modules/mod_sftp_sql.html)
#   LoadModule mod_sftp_sql.c
#
# Provide data transfer rate "shaping" across the entire server
# (http://www.castaglia.org/proftpd/modules/mod_shaper.html)
#   LoadModule mod_shaper.c
#
# Support for miscellaneous SITE commands such as SITE MKDIR, SITE SYMLINK,
# and SITE UTIME (http://www.proftpd.org/docs/contrib/mod_site_misc.html)
#   LoadModule mod_site_misc.c
#
# Provide an external SSL session cache using shared memory
# (contrib/mod_tls_shmcache.html)
#   LoadModule mod_tls_shmcache.c
#
# Provide a memcached-based implementation of an external SSL session cache
# (contrib/mod_tls_memcache.html)
#   LoadModule mod_tls_memcache.c
#
# Use the /etc/hosts.allow and /etc/hosts.deny files, or other allow/deny
# files, as well as SQL-based access rules, for IP-based access control
# (http://www.proftpd.org/docs/contrib/mod_wrap2.html)
#   LoadModule mod_wrap2.c
#
# Support module for mod_wrap2 that handles access rules stored in specially
# formatted files on disk
# (http://www.proftpd.org/docs/contrib/mod_wrap2_file.html)
#   LoadModule mod_wrap2_file.c
#
# Support module for mod_wrap2 that handles access rules stored in SQL
# database tables (http://www.proftpd.org/docs/contrib/mod_wrap2_sql.html)
#   LoadModule mod_wrap2_sql.c
#
# Implement a virtual chroot capability that does not require root privileges
# (http://www.castaglia.org/proftpd/modules/mod_vroot.html)
# Using this module rather than the kernel's chroot() system call works
# around issues with PAM and chroot (http://bugzilla.redhat.com/506735)
LoadModule mod_vroot.c

# Dynamic ban lists (http://www.proftpd.org/docs/contrib/mod_ban.html)
# Enable this with PROFTPD_OPTIONS=-DDYNAMIC_BAN_LISTS in /etc/sysconfig/proftpd
<IfDefine DYNAMIC_BAN_LISTS>
  LoadModule                    mod_ban.c
</IfDefine>

# Set networking-specific "Quality of Service" (QoS) bits on the packets used
# by the server (contrib/mod_qos.html)
<IfDefine QOS>
  LoadModule                    mod_qos.c
</IfDefine>

# Attempt to generate a unique ID for every FTP session
# (http://www.proftpd.org/docs/contrib/mod_unique_id.html)
#   LoadModule mod_unique_id.c
#
# Provide a flexible way of specifying that certain configuration directives
# only apply to certain sessions, based on credentials such as connection
# class, user, or group membership
# (http://www.proftpd.org/docs/contrib/mod_ifsession.html)
# Note that mod_ifsession must be the last loaded module, otherwise the
# per-user/group/class functionality will not work as you expect
#   LoadModule mod_ifsession.c
@Castaglia
Copy link
Member

I'll see about reproducing this locally. In the meantime, would it be possible for you to attach/provide the generated config.h (and maybe config.log) files as well? I'm wondering if something in the configure script's detection of various regex libraries is amiss somehow.

@Castaglia
Copy link
Member

Using a local Docker almalinux:9 container, I'm not able to reproduce this behavior. I wonder if it is something during build/install process, rather than at runtime. Here's what I did:

$ tar zxvf proftpd-1.3.8.tar.gz
$ cd proftpd-1.3.8
$ ./configure --enable-dso --disable-pcre --enable-pcre2 --with-shared=mod_rewrite
$ make
$ make install

$ ls -al /usr/local/libexec/
total 352
drwxr-xr-x 1 root root   4096 Feb  3 01:24 .
drwxr-xr-x 1 root root   4096 Feb  3 01:24 ..
-rw-r--r-- 1 root root 207768 Feb  3 01:24 mod_rewrite.a
-rwxr-xr-x 1 root root    965 Feb  3 01:24 mod_rewrite.la
-rwxr-xr-x 1 root root 137496 Feb  3 01:24 mod_rewrite.so

$ /usr/local/sbin/proftpd -td10
...
2023-02-03 01:28:20,991 12ee4a816677 proftpd[16661]: <IfModule>: using 'mod_dso.c' section at line 23
2023-02-03 01:28:20,991 12ee4a816677 proftpd[16661]: mod_dso/0.5: loading 'mod_rewrite.c'
2023-02-03 01:28:20,991 12ee4a816677 proftpd[16661]: mod_dso/0.5: loaded module 'mod_rewrite' (from '/usr/local/libexec/mod_rewrite.so', last modified on Fri Feb 03 01:24:40 2023)
...
Syntax check complete.

Now, that's building from the 1.3.8 source.

Next, I'll try just installing the packages, as mentioned in that Bugzilla ticket:

dnf install -qy --enablerepo crb proftpd

to see what might be different.

@Castaglia
Copy link
Member

Castaglia commented Feb 3, 2023

Looks like that package is missing the .la files; I don't know why:

$ dnf install -qy --enablerepo crb proftpd
Importing GPG key 0x3228467C:
 Userid     : "Fedora (epel9) <epel@fedoraproject.org>"
 Fingerprint: FF8A D134 4597 106E CE81 3B91 8A38 72BF 3228 467C
 From       : /etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-9

Installed:
  libmemcached-awesome-1.1.0-12.el9.x86_64     logrotate-3.18.0-7.el9.x86_64    
  proftpd-1.3.8-1.el9.x86_64                  

$ rpm -qa | grep proftpd
proftpd-1.3.8-1.el9.x86_64

$ rpm -ql proftpd-1.3.8-1.el9.x86_64
...
/usr/libexec/proftpd
/usr/libexec/proftpd/mod_ban.so
/usr/libexec/proftpd/mod_copy.so
/usr/libexec/proftpd/mod_ctrls_admin.so
/usr/libexec/proftpd/mod_deflate.so
/usr/libexec/proftpd/mod_exec.so
/usr/libexec/proftpd/mod_facl.so
/usr/libexec/proftpd/mod_ifsession.so
/usr/libexec/proftpd/mod_ifversion.so
/usr/libexec/proftpd/mod_load.so
/usr/libexec/proftpd/mod_qos.so
/usr/libexec/proftpd/mod_quotatab.so
/usr/libexec/proftpd/mod_quotatab_file.so
/usr/libexec/proftpd/mod_quotatab_radius.so
/usr/libexec/proftpd/mod_quotatab_sql.so
/usr/libexec/proftpd/mod_radius.so
/usr/libexec/proftpd/mod_ratio.so
/usr/libexec/proftpd/mod_rewrite.so
/usr/libexec/proftpd/mod_sftp.so
/usr/libexec/proftpd/mod_sftp_pam.so
/usr/libexec/proftpd/mod_sftp_sql.so
/usr/libexec/proftpd/mod_shaper.so
/usr/libexec/proftpd/mod_site_misc.so
/usr/libexec/proftpd/mod_sql.so
/usr/libexec/proftpd/mod_sql_passwd.so
/usr/libexec/proftpd/mod_tls_memcache.so
/usr/libexec/proftpd/mod_tls_shmcache.so
/usr/libexec/proftpd/mod_unique_id.so
/usr/libexec/proftpd/mod_vroot.so
/usr/libexec/proftpd/mod_wrap2.so
/usr/libexec/proftpd/mod_wrap2_file.so
/usr/libexec/proftpd/mod_wrap2_sql.so
...

And without the .la files, the libltdl library wouldn't be able to locate the .so files to load, which would explain the behavior reported.

I suspect that your example of mod_load worked because the mod_load module, on Linux, probably doesn't require any additional libraries. But mod_rewrite would, and those additional libraries (instructions to the dynamic loader) would be in the .la file, to be loaded prior to loading the .so file, so that all of the symbols could be properly resolved by the dynamic linker. Maybe? It is curious that mod_load would work, though, without an .la file.

@Castaglia Castaglia added the build label Feb 3, 2023
@pghmcfc
Copy link
Contributor Author

pghmcfc commented Feb 3, 2023

Regarding the .la (libtool archive) files, the removal of them in the packaging is intentional. Apparently they're only consumed by libtool itself these days as the ELF library format includes the information needed to find dependent libraries. In fact, rpm has been explicitly removing them from builds by default since rpm 4.17 (see also https://fedoraproject.org/wiki/Changes/RemoveLaFiles). Furthermore, the proftpd packaging in Fedora/EPEL has been explicitly removing these files since 2006 and it doesn't seem to have been a problem up to now.

Nevertheless, I created a new build that included the .la files just to be on the safe side. It doesn't appear to have made any difference:

# /usr/sbin/proftpd -td10 -c /etc/proftpd.conf
Checking syntax of configuration file
2023-02-03 09:38:46,438 goalkeeper.city-fan.org proftpd[512203]: using PCRE2 10.40
2023-02-03 09:38:46,446 goalkeeper.city-fan.org proftpd[512203]: using TCP receive buffer size of 131072 bytes
2023-02-03 09:38:46,446 goalkeeper.city-fan.org proftpd[512203]: using TCP send buffer size of 16384 bytes
2023-02-03 09:38:46,447 goalkeeper.city-fan.org proftpd[512203]: using 'en_GB.UTF-8' locale based on LANG=en_GB.UTF-8 environment variable
2023-02-03 09:38:46,447 goalkeeper.city-fan.org proftpd[512203]: using 'UTF-8' as local charset for UTF-8 conversion
2023-02-03 09:38:46,448 goalkeeper.city-fan.org proftpd[512203]: mod_tls/2.9.2: using OpenSSL 3.0.5 5 Jul 2022
2023-02-03 09:38:46,448 goalkeeper.city-fan.org proftpd[512203]: mod_memcache/0.1: using libmemcached-1.1.3
2023-02-03 09:38:46,449 goalkeeper.city-fan.org proftpd[512203]: ROOT PRIVS at mod_core.c:384
2023-02-03 09:38:46,449 goalkeeper.city-fan.org proftpd[512203]: RELINQUISH PRIVS at mod_core.c:386
2023-02-03 09:38:46,449 goalkeeper.city-fan.org proftpd[512203]: ROOT PRIVS at mod_core.c:393
2023-02-03 09:38:46,449 goalkeeper.city-fan.org proftpd[512203]: ROOT PRIVS at parser.c:1207
2023-02-03 09:38:46,449 goalkeeper.city-fan.org proftpd[512203]: mod_dso/0.5: loading 'mod_ctrls_admin.c'
2023-02-03 09:38:46,450 goalkeeper.city-fan.org proftpd[512203]: mod_dso/0.5: loaded module 'mod_ctrls_admin' (from '/usr/libexec/proftpd/mod_ctrls_admin.so', last modified on Fri Feb 03 09:32:28 2023)
2023-02-03 09:38:46,450 goalkeeper.city-fan.org proftpd[512203]: mod_dso/0.5: loading 'mod_rewrite.c'
2023-02-03 09:38:46,451 goalkeeper.city-fan.org proftpd[512203]: mod_dso/0.5: unable to dlopen 'mod_rewrite.c': file not found (No such file or directory)
2023-02-03 09:38:46,451 goalkeeper.city-fan.org proftpd[512203]: mod_dso/0.5: unable to load 'mod_rewrite.c'; check to see if '/usr/libexec/proftpd/mod_rewrite.la' exists
2023-02-03 09:38:46,451 goalkeeper.city-fan.org proftpd[512203]: mod_dso/0.5: defaulting to 'self' for symbol resolution
2023-02-03 09:38:46,451 goalkeeper.city-fan.org proftpd[512203]: mod_dso/0.5: unable to find module symbol 'rewrite_module' in 'self'
2023-02-03 09:38:46,451 goalkeeper.city-fan.org proftpd[512203]: fatal: LoadModule: error loading module 'mod_rewrite.c': No such file or directory on line 101 of '/etc/proftpd/modules.conf'
2023-02-03 09:38:46,451 goalkeeper.city-fan.org proftpd[512203]: RELINQUISH PRIVS at parser.c:1210
2023-02-03 09:38:46,451 goalkeeper.city-fan.org proftpd[512203]: RELINQUISH PRIVS at mod_core.c:396
2023-02-03 09:38:46,451 goalkeeper.city-fan.org proftpd[512203]: warning: unable to include '/etc/proftpd/modules.conf': Operation not permitted
2023-02-03 09:38:46,451 goalkeeper.city-fan.org proftpd[512203]: mod_dso/0.5: loading 'mod_vroot.c'
2023-02-03 09:38:46,451 goalkeeper.city-fan.org proftpd[512203]: mod_dso/0.5: loaded module 'mod_vroot' (from '/usr/libexec/proftpd/mod_vroot.so', last modified on Fri Feb 03 09:32:28 2023)
2023-02-03 09:38:46,452 goalkeeper.city-fan.org proftpd[512203]: <IfDefine>: skipping 'DYNAMIC_BAN_LISTS' section at line 154
2023-02-03 09:38:46,452 goalkeeper.city-fan.org proftpd[512203]: <IfDefine>: skipping 'QOS' section at line 160
2023-02-03 09:38:46,455 goalkeeper.city-fan.org proftpd[512203] goalkeeper.city-fan.org: 
2023-02-03 09:38:46,455 goalkeeper.city-fan.org proftpd[512203] goalkeeper.city-fan.org: Config for ProFTPD:
2023-02-03 09:38:46,455 goalkeeper.city-fan.org proftpd[512203] goalkeeper.city-fan.org: mod_lang/1.1: binding to text domain 'proftpd' using locale path '/usr/share/locale'
2023-02-03 09:38:46,455 goalkeeper.city-fan.org proftpd[512203] goalkeeper.city-fan.org: mod_lang/1.1: using locale files in '/usr/share/locale'
2023-02-03 09:38:46,456 goalkeeper.city-fan.org proftpd[512203] goalkeeper.city-fan.org: mod_lang/1.1: skipping possible language 'zh_CN': not supported by setlocale(3); see `locale -a'
2023-02-03 09:38:46,457 goalkeeper.city-fan.org proftpd[512203] goalkeeper.city-fan.org: mod_lang/1.1: skipping possible language 'ru_RU': not supported by setlocale(3); see `locale -a'
2023-02-03 09:38:46,457 goalkeeper.city-fan.org proftpd[512203] goalkeeper.city-fan.org: mod_lang/1.1: skipping possible language 'ja_JP': not supported by setlocale(3); see `locale -a'
2023-02-03 09:38:46,457 goalkeeper.city-fan.org proftpd[512203] goalkeeper.city-fan.org: mod_lang/1.1: skipping possible language 'zh_TW': not supported by setlocale(3); see `locale -a'
2023-02-03 09:38:46,458 goalkeeper.city-fan.org proftpd[512203] goalkeeper.city-fan.org: mod_lang/1.1: skipping possible language 'fr_FR': not supported by setlocale(3); see `locale -a'
2023-02-03 09:38:46,458 goalkeeper.city-fan.org proftpd[512203] goalkeeper.city-fan.org: mod_lang/1.1: skipping possible language 'ko_KR': not supported by setlocale(3); see `locale -a'
2023-02-03 09:38:46,459 goalkeeper.city-fan.org proftpd[512203] goalkeeper.city-fan.org: mod_lang/1.1: skipping possible language 'it_IT': not supported by setlocale(3); see `locale -a'
2023-02-03 09:38:46,459 goalkeeper.city-fan.org proftpd[512203] goalkeeper.city-fan.org: mod_lang/1.1: skipping possible language 'es_ES': not supported by setlocale(3); see `locale -a'
2023-02-03 09:38:46,461 goalkeeper.city-fan.org proftpd[512203] goalkeeper.city-fan.org: mod_lang/1.1: skipping possible language 'bg_BG': not supported by setlocale(3); see `locale -a'
2023-02-03 09:38:46,461 goalkeeper.city-fan.org proftpd[512203] goalkeeper.city-fan.org: mod_lang/1.1: added the following supported languages: en_US
2023-02-03 09:38:46,461 goalkeeper.city-fan.org proftpd[512203] goalkeeper.city-fan.org: ROOT PRIVS at mod_ctrls.c:1233
2023-02-03 09:38:46,461 goalkeeper.city-fan.org proftpd[512203] goalkeeper.city-fan.org: RELINQUISH PRIVS at mod_ctrls.c:1235
2023-02-03 09:38:46,462 goalkeeper.city-fan.org proftpd[512203] goalkeeper.city-fan.org: mod_tls/2.9.2: generating initial TLS session ticket key
2023-02-03 09:38:46,462 goalkeeper.city-fan.org proftpd[512203] goalkeeper.city-fan.org: ROOT PRIVS at mod_tls.c:6548
2023-02-03 09:38:46,462 goalkeeper.city-fan.org proftpd[512203] goalkeeper.city-fan.org: RELINQUISH PRIVS at mod_tls.c:6551
2023-02-03 09:38:46,462 goalkeeper.city-fan.org proftpd[512203] goalkeeper.city-fan.org: mod_tls/2.9.2: scheduling new TLS session ticket key every 3600 secs
2023-02-03 09:38:46,462 goalkeeper.city-fan.org proftpd[512203] goalkeeper.city-fan.org: ROOT PRIVS at mod_delay.c:583
2023-02-03 09:38:46,462 goalkeeper.city-fan.org proftpd[512203] goalkeeper.city-fan.org: RELINQUISH PRIVS at mod_delay.c:586
2023-02-03 09:38:46,462 goalkeeper.city-fan.org proftpd[512203] goalkeeper.city-fan.org: ROOT PRIVS at mod_rlimit.c:554
2023-02-03 09:38:46,462 goalkeeper.city-fan.org proftpd[512203] goalkeeper.city-fan.org: RELINQUISH PRIVS at mod_rlimit.c:557
2023-02-03 09:38:46,462 goalkeeper.city-fan.org proftpd[512203] goalkeeper.city-fan.org: set core resource limits for daemon
Syntax check complete.
# ls -l /usr/libexec/proftpd/mod_rewrite.la
-rw-r--r--. 1 root root 1015 Feb  3 09:32 /usr/libexec/proftpd/mod_rewrite.la

@pghmcfc
Copy link
Contributor Author

pghmcfc commented Feb 3, 2023

Attached config.h and config.log files from build:
proftpd-config.tar.gz

I suspect it might be something to do with compiler/linker flags, maybe for link-time-optimization.

@pghmcfc
Copy link
Contributor Author

pghmcfc commented Feb 3, 2023

It is a flags issue. I got rid of a bunch of them and it now works. Now time to figure out which set of flags is breaking it. Definitely nothing to do with the missing .la files anyway.

@pghmcfc
Copy link
Contributor Author

pghmcfc commented Feb 3, 2023

Seems to be the hardened build option (see https://fedoraproject.org/wiki/Changes/Harden_All_Packages).
This has been enabled for a long time so I don't know if it's recently stopped working or nobody ever used mod_rewrite with the packaged builds.

If I undefine the _hardened build macro, the resulting build loads mod_rewrite successfully.

@Castaglia
Copy link
Member

Interesting! I'll experiment with some of those hardening flags on my end, see what I can find.

One test would be to enable the _hardened build macro, using e.g. the ProFTPD 1.3.7 code, to see if the same behavior occurs. That is, is this issue caused by the hardening by itself somehow, or is it something about the hardening in combination with something in ProFTPD 1.3.8?

@pghmcfc
Copy link
Contributor Author

pghmcfc commented Feb 3, 2023

It's underlinking. mod_rewrite uses functions from libidn2 (or libidn) but isn't linked against it. As a hack to try out this theory, I made this change:

--- Make.rules.in
+++ Make.rules.in
@@ -93,7 +93,7 @@
   src/error.o
 
 SHARED_MODULE_DIRS=@SHARED_MODULE_DIRS@
-SHARED_MODULE_LIBS=@SHARED_MODULE_LIBS@
+SHARED_MODULE_LIBS=@SHARED_MODULE_LIBS@ -lidn2
 SHARED_MODULE_OBJS=@SHARED_MODULE_OBJS@
 SHARED_MODULE_SRCS=@SHARED_MODULE_SRCS@

With that change, mod_rewrite loaded successfully after building with hardening flags enabled.

@Castaglia
Copy link
Member

Ah, thanks! That does remind of something I noticed while debugging some other issue. I suspect it's from the use of AC_TRY_COMPILE here, rather than AC_TRY_LINK -- or something similar. I should have time later today to dig into this, and to examine the provided config.log (which, I think, will show more details on the issues with Autoconf detection of all the libidn2 related bits and settings).

@pghmcfc
Copy link
Contributor Author

pghmcfc commented Feb 3, 2023

It's not a problem with library detection:

checking idn2.h usability... yes
checking idn2.h presence... yes 
checking for idn2.h... yes

The problem is that neither proftpd itself (since it uses no idn2 functions) nor mod_rewrite.so are linked with libidn2 in the resulting package. The configure script adds -lidn2 to MAIN_LIBS which I think ends up in the proftpd main binary linker flags, but since (with hardening enabled) the link is done with the "as-needed" linker flag, that idn2 reference is discarded since proftpd itself does not need it. On the other hand, mod_rewrite does need it but the MAIN_LIBS value isn't used when linking the dynamic modules. This is why adding -lidn2 to SHARED_MODULE_LIBS fixes the problem.

@Castaglia
Copy link
Member

At least this shows that this issue is new to ProFTPD 1.3.8, via #1286. I think I see a way to fix this; just a sec.

@Castaglia Castaglia self-assigned this Feb 3, 2023
@Castaglia Castaglia added this to the 1.3.9 milestone Feb 3, 2023
Castaglia added a commit that referenced this issue Feb 3, 2023
…ary, make sure that the proper linker flags are set, especially for linking dynamic modules.
@Castaglia
Copy link
Member

#1592 seems to work better in my local tests, if you'd care to try it out in your setup with the hardening flags?

@pghmcfc
Copy link
Contributor Author

pghmcfc commented Feb 3, 2023

Works for me too. Though it does end up trying to link all of the dynamic modules with the IDN library rather than just mod_rewrite, which I think is the only one that needs it. Having potentially different library lists for each module would be a lot more work though.

@Castaglia
Copy link
Member

Yeah, that's a general issue -- you see it with the SQL libraries (MySQL, Postgres, SQLite) as well.

Once a module reaches a certain level of complexity (e.g. being built from multiple source files, or need more complex Autoconf support), that's when it tends to be redone with its own Autoconf script, Makefiles, etc -- such as mod_sftp has.

@Castaglia Castaglia changed the title Unable to load mod_rewrite Unable to load mod_rewrite as a dynamic module due to incomplete/missing library linker flags Feb 4, 2023
Castaglia added a commit that referenced this issue Feb 4, 2023
Issue #1590: When we properly detect (via linking) the `libidn2` libr…
Castaglia added a commit that referenced this issue Feb 4, 2023
…ary, make sure that the proper linker flags are set, especially for linking dynamic modules.
@Castaglia
Copy link
Member

@pghmcfc This should now be fixed in master, and backported to the 1.3.8 branch. Thanks!

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

No branches or pull requests

2 participants