So, for Jailkit support, we need the following things in Virtualmin:
Domain creation form
When creating a domain, there needs to be an option to jail the user. If a domain is jailed, it needs to force all users within to be jailed, as well.
There needs to be a dropdown to select which jail configuration to initialize for the user. This can be determined by the sections of /etc/jailkit/jk_init.ini
You can get the list of jails using the jailkit-lib.pl. Example of that in delete_jail.cgi. e.g.:
# Load the jk_init.ini into a Config::IniFiles object
my $jk_init_ini = get_jk_init_ini();
# Get an array of the sections (jail definitions)
my @sections = $jk_init_ini->Sections();
Each section in the config file applies to a jail configuration (the files to include in the jail). The object also provides access to the parameters for each option within the sections...so, if you needed to be able to display the comment (which usually describes the jail), that'd be available via a function like this: "$jk_init_ini->val( $section, 'comment' );"
During the creation
Once a user has been created, they need to have their jail initialized, and their shell in /etc/passwd switched to include the jail magic bits.
To initialize their jail, run jk_init:
# jk_init -j jail section
Where "jail" is the path to the jail. This should be something like /home/chroot/domainname or /home/jail/domainname (probably should be configurable). jk_init will create the directory and populate it.
And, "section" is the section from the jk_init.ini file to use (the jail configuration ID, like "perl" or "limitedshell". Users can define their own jail configurations in the Jailkit Webmin module which I'll roll into the repos at the same time (could also include in Webmin, though it depends on Config::IniFiles).
Set the user home path and shell
The following must be done manually (well, by Virtualmin). The jk_jailuser command which normally sets up the user to be jailed does so by moving the home directory into the jail. We want to bind mount the home, rather than move the home into the jail, as we need the rest of the system to be able to find the home in /home/domainname...for web services, for mail delivery, etc.
The user entry in /etc/passwd needs two changes from the usual:
The shell needs to be set to jk_chrootsh
And the home directory needs to be set to a weird format, which includes both the chroot path and the home directory path within the chroot. e.g.:
This is a magic format which the jk_chrootsh knows what to do with. The /home/chroot/domainname is the jail created in the previous step, and the /home/domainname is the actual home directory (which will be bind-mounted inside the chroot).
Add a bind mount for the users home
The jail will not contain the user home directory, which kinda defeats the purpose of having a shell login. So, we need to use a bind mount to make it available for the user.
The simplest form of this is adding this to fstab:
/home/domainname /home/chroot/domainname/home/domainname none bind 0 0
On a system with a lot of users, this will lead to a lot of bind mounts, but I can't find any reason for this to be a problem. There are no hard limits imposed by Linux on bind mounts. Docker and some other container systems use bind mounts heavily and with hundreds or thousands of them, so I think we're safe. It might be worth thinking about a way to avoid filling up the fstab with these bind mounts, but I can't think of a good way to do it (the fstab.d feature we talked about in the past never made it to widespread usage and development stopped).
I believe we should put the domain email boxes into the same bind mounted home, so we only need a bind mount per domain, rather than per-user. This means mailbox users with a shell will not be jailed into their home but into the home of their domain, but mailbox users don't need a shell if they aren't trusted. So no big deal, there.
If the server is going to use jails, it has to call procmail via the jk_procmailwrapper rather than our wrapper. I think this has to be system-wide? So, it'll make it impossible for any domain-level spam/AV configuration for any domain if jails are turned on for any user (right?). I guess we could also modify the jk_procmail_wrapper to do what ours does for users that aren't jailed...but, I've never been very comfortable with it, anyway, and I think it's probably fine to give up per-domain settings.
So, that needs to be in the install wizard. Something along the lines of "Do you want to use chroot jail features for some or all of your users? Enabling this feature for any user will disable per-domain spam/AV features for all users. Per-user spam/AV configuration will still function normally."
You understand the procmail stuff in Virtualmin far better than I do, so you may see a way to not make this all or nothing.
Docs for that are here: https://olivier.sessink.nl/jailkit/jk_procmailwrapper.8.html
We probably need UI support for updating files in all configured jails after package updates and such. My module only handles configuration of jail sections in jk_init.ini right now. But, I can add some additional support for keeping up with what jails exist, updating them, etc. We'll need to call chroot support beta for the next couple of months, until we've sorted out all of the intricacies of this.
Also, we need to sort out running cgi and php within a chroot. For the short term, I think PHP-FPM supports chroot out of the box, so we just need to configure it. For CGI, we probably just need to make it possible to disable CGI, and possibly disable by default for chrooted users. It'll all Just Work, if we leave it as-is, but it will provide an easy vector for breaking chroot, since a user could trivially install a web shell which would be unjailed.
Oh, yeah, my Jailkit Webmin module is here: https://github.com/swelljoe/webmin-jailkit
Let me know if you need additional functionality from it for Virtualmin. I'll poke at adding some of the other stuff I mentioned, but may wait until we release V6 and then work on new features based on user feedback and requests. Just getting auto-jailing out the door is probably the minimum viable product, and then we'll refine from there.
The jailkit package is available in our bleed repo here, as well: http://software.virtualmin.com/bleed/centos/7/x86_64/jailkit-2.19-1.el7....
I may need to add a more functional jail configuration to jk_init.ini, as all of them look pretty anemic by default, and I don't want users to feel compelled to put a shell together before they can even use this feature. I tried getting some feedback in the forums, but nobody has poked at it.