1

Current State

Given is a host with a couple of IPv4 addresses and HTTP & FTP access for each address; each vhost has access to a PostgreSQL database. Web- and ftp-authentication is done against the respective database; for proftpd I use this setup for each IP-Address/vhost ($VALUES are no variables but hide real values):

SQLConnectInfo $VHOST@localhost $SQLUSER $SQLPASS
SQLUserInfo login Login Password 33 33 "CONCAT('/var/www/$VHOST/upload/', id)" "'/bin/bash'"

So basically every web user has an ftp account at the same host with the same credentials; internally they work as www-data.www-data and each account on each vhost has an individual folder. Works fine.

Task & Idea

Not needing more IPv4 addresses for additional vhosts (and preferably getting rid of most of the existing ones). Take as given that customers demand ftp(s) access and IPv4 for at least the next couple of years - otherwise things would be easy.

Ftp has no concept of vhosts, so the best approach I could think of so far is to use account names like $VHOST.$LOGIN (should be acceptable for customers). I could then split the login name at the dot, use the first part as the database name and the second part as the login name. Nothing else would need to be changed.

Problem

I can't find any piece of software supporting it. Neither do I see a way to integrate such a setup into the proftpd-configuration nor did I find another ftp daemon being more flexible.

Digression: There is such a thing as SQLNamedConnectInfo/SQLNamedQuery and I can get the desired format of the login name plus the usage of a specific database with that:

SQLNamedConnectInfo $VHOST postgres $VHOST@localhost $SQLUSER $SQLPASS
SQLNamedQuery $VHOST SELECT "Login, Password, 33, 33, CONCAT('/var/www/$VHOST.epaxios.com/upload/', id), '/bin/bash' FROM login WHERE Login=substr('%U', strpos('%U', '.')+1) AND substr('%U', 1, strpos('%U', '.')-1)='$VHOST'" $VHOST
SQLUserInfo custom:/$VHOST

But unfortunately this can only be included once (in the main section, there is only 1 IP-Address) - with such an approach I'd need to iterate through all the vhosts/databases however...

Next thing I have been looking at was PAM - there is pam_pgsql, but no such thing as supporting different databases (whether depending on parts of the user name or not).

Last thing I could think of was libnss. There is libnss-pgsql, but again it supports only a single connection to a dedicated table - of course the most typical use case, but not enough for me.

Is there anything I have not thought of? Or some way to insert a tiny script into one of these solutions? After all, I am just a few string operations away from my goal.

SlowFox
  • 11
  • 2
  • Newer FTP clients support the `HOST` command (see [RFC 7151](https://datatracker.ietf.org/doc/html/rfc7151)), which implements name-based vhosting for FTP. In addition to supporting `HOST`, for FTPS, ProFTPD also supports [TLS SNI](https://en.wikipedia.org/wiki/Server_Name_Indication) for name-based FTPS vhosts. – Castaglia Oct 17 '21 at 16:27
  • @Castaglia sadly this is as good as switching to IPv6: perfect, but not going to work. I changed the test environment and contacted the ~10 most technically aware customers: Two reactions like "uh?", silence otherwise and not a single successful connection yet. If I don't find a solution which does not require any (technical) changes at the client, I have not found any solution at all :( – SlowFox Oct 21 '21 at 10:32
  • I understand. Another possibility might be to use a proxy like [`pgpool`](https://www.pgpool.net/), where the proxy maps the client username to the backend database to be used? – Castaglia Oct 24 '21 at 21:22

0 Answers0