-
-
Notifications
You must be signed in to change notification settings - Fork 465
Description
Disclaimer: This is "kind of" a feature request, but more a concept on how it could be done. Because when talking on Discord, we figured out some roadblocks (or "what if"s), and I gave it a deep thought. And I think I was able to come up with a doable approach?
So this issue would be a possibility to discuss, I'd suggest.
The current problem:
We can add "FTP" users with a path, which is used as the home path. This "FTP" user is also usable for SSH and with that, also SCP.
However, we cannot limit access to the specified folder (and its children). And here is a concept for a possible solution.
I think we can agree that we need a jail to achieve this. And here's how it could be done.
So I would suggest we need a folder /froxlorjails which is going to be where the jails are located, obviously.
And the idea is that we make heavy use of mount --bind so we can offer a full userland to the user via ssh.
Let's say we have a user joe who has two domains, catvideos.org and dogphotos.net. So his customer folder would be
/var/customers/webs/joe/. And inside this, we have catvideos.org and dogphotos.net.
And to have some good examples, let's say joe also has another user that points only to catvideos.org. Let's call this user joeftp1, as froxlor would currently do.
To achieve a true jail, we would have to do two things. We would have to populate the jail and tell the ssh daemon about it.
SSH would be rather easy. Froxlor manages /etc/ssh/sshd_config.d/99-froxlor.conf and puts the "FTP" users in there, like so
Match User joe
ChrootDirectory /froxlorjails/joe
Match User joeftp1
ChrootDirectory /froxlorjails/joeftp1
Whenever a customer or an "FTP" user is added or removed (not changed), froxlor rewrites this file and fires a systemctl reload sshd.
Now for the jails. Froxlor's cron would have to populate those folders. It can mount --bind just about everything a standard Linux setup has, like /bin, /etc, /usr. But /home and not /root (and not /froxlorjails, obviously).
For /var, we have to get a little picky. It shall not mount /var/customers. But it should mount /var/run lock files, sockets, so the user can perform a mysqldump or such.
Now the cron would create and mount --bind /var/customers/webs/joe.
That, we would do inside /froxlorjails/joe/.
Same with joeftp1, except it mounts /var/customers/webs/joe/catvideos.org and it works inside /froxlorjails/joeftp1.
Now we have some edge cases.
What if joe decides to change joeftp1's home to dogphotos.net?
In that case, the cron would have to kill all processes for joeftp1 with pkill -u joeftp1 to unbusy the mounts. This also quits any SSH connections that might be active (which is required as we change the home folder). It will also kill tools like tmux that the user might have had running (to prevent the session from being lost when ssh disconnects). Because next step is to umount -R /froxlorjails/joeftp1 (for which we need the ressources to be not busy) and re-populate the jail, see above. We don't have to reload sshd because the jail itself has not changed (for all sshd cares).
However, processes that run under the user joeftp1 are exclusively started by the user in front of the display, and not needed for the server. It is a pure login user without any services. Which is why it's somewhat safe to just nuke it.
Here we see something crucial. We would have to declare "joe" sacred. It should point to the customer's folder, so it can be used as an administrative account, but after that, it cannot be changed (by the customer). Because if we wanted to point "joe" to another home directory (such as catvideos.org), we would also have to pkill -u joe (for the same reason as above), however, this would also kill any running PHP-FPM processes for joe, and thus disrupting his websites. So joe is the admin, all-access, and that is sacred. He's free to set the shell to /bin/false, but other than that, it shall not be changed (unless by an admin).
When we delete a customer, we would have to pkill their processes as well, but in that case, we'd want to get rid of them anyway, so that should be fine.
It might be important to know that the associated cronjob should be a little smarter than average. It can and should check if every jail that should exist, exists (checking for the folders, grepping in /proc/mounts). If not, it's free to create the structure, mount everything necessary and maybe remove leftovers from gone users (but that's just housekeeping). But if anything changes, it shall only touch the users that changed. Because if joeftp1 changes the home folder, it should only change this jail (with killing all spawned processes associated with joeftp1). It should not affect janeftp6 who may also be logged in doing stuff.
What happens after a reboot?
After a reboot, the mounts are gone obviously. But since cron runs every few minutes, it would find out that the jails are not populated...and populate them, as stated above.
Are we in dependency hell?
One would think maybe we have to juggle depedencies and could render the server unusable, like when we have to make sure all directories mentioned in /etc/ssh/sshd_config.d/99-froxlor.conf have to exist. In which case, we would have to wait for froxlor, which itself needs MySQL and when we managed to kill MySQL to a point where it would not even start, we are locked out of ssh.
This is NOT the case. sshd doesn't care about the folders as long as the syntax is correct. It starts caring when one of the rules applies to the current connection. But that would not be the case for a root or a "real" system user (that is not created by froxlor)
Bottom line
Looking at current froxlor, the "only" thing new for this idea would be the jails thing and the associated cronjob (and the sshd config file). Everything else should already exist. Like FTP users would be renamed to, I don't know, "Users" or something with a little line that it is FTP (if enabled) and SSH, and they are taken care of by extrausers.
Mounting an "FTP" user's home to /froxlorjails/joe/var/customers/webs/joe has the advantage that the absolute paths, inside the jail and outside are identical. So if you were mad enough to work with absolute paths in your scripts, they would work either way. That was the rational.
So what do you think?