Froxlor icon indicating copy to clipboard operation
Froxlor copied to clipboard

Add Option to set OpenBaseDir manually for domain/subdomain

Open dirkey opened this issue 6 years ago • 43 comments

The OpenBaseDir can only be set to the "Home Directory" or the "Document Root". It would be nice to have a third option to set it manually. For example: Magento needs only it's pub directory to be accessible via Apache (DocumentRoot), but PHP needs access to all files in the "Mangento Root" (OpenBaseDir). Currently I must give it access to all files under the home directory of the user.

dirkey avatar Feb 13 '18 13:02 dirkey

So, domain-documentroot is e.g. /[user]/magento/pub and your chice would be either /[user]/ or /[user]/magento/pub but you need /[user]/magento - correct?

d00p avatar Feb 13 '18 13:02 d00p

One of the "minor" problems here is that we try to avoid letting the customer enter paths manually as it might void the openbasedir functionality which the admin might wanted intentionally..that's why it's only these two choices

d00p avatar Feb 13 '18 13:02 d00p

I see! Maybe, we let users only allow to add relative paths to there home directory. But then, we need to take care of relative paths pointing to a parent directory. A solution is also to show the directory tree instead of a textbox. Then he is only allowed to choose these. Or populate the combobox with the tree related to the document root?

dirkey avatar Feb 13 '18 18:02 dirkey

My two cents: I'd love this. I've been creating separate users and using their home directories for it and that's become quite tedious to manage. Allow the following three options:

  • document root
  • parent of document root (must be inside home directory)
  • home directory

If the parent of the document root is not inside the home directory, automatically set the home directory. (It's an absolute path string, so something like

$home_path = realpath($home_directory);
$open_basedir_path = realpath($open_basedir);
if ($home_path === $open_basedir_path || substr($open_basedir_path, 0, strlen($home_path) + 1) === $home_path.DIRECTORY_SEPARATOR)
{
    // everything is fine
}
else
{
    $open_basedir_path = $home_path;
}

should suffice to make this safe.

This would help greatly with properly setting up Drupal, Magento, Tyop3 and custom built applications, such that only one small index.php and static files remain in the document root of the web server's virtual host, and all application files, view templates (typically not with php extension, would be served as text), configuration, and possibly databases (e.g. SQLite ones) can safely remain outside of it and out of the reach of a FastCGI or rewrite engine failure of some sort from a package upgrade mishap.

dori4n avatar Aug 06 '18 18:08 dori4n

Sounds good to me @NightmareJoker2

d00p avatar Aug 07 '18 05:08 d00p

Hi, please review and merge my pull request https://github.com/Froxlor/Froxlor/pull/587, tested with v0.9.40.

florianschroen avatar Nov 18 '18 02:11 florianschroen

All Laravel projects need this too, and currently running with open_basedir disabled

negrusti avatar Feb 26 '19 17:02 negrusti

Why don't we just decouple the open_basedir from the documentroot? I'd suggest the following solution:

Let the user choose between three settings per Domain:

  1. Use the customer home directory as open_basedir (and recommend against choosing this, it may have valid use-cases, tho)
  2. Use the domain root as open_basedir (which would default to $HOME/$DOMAIN, and should be the default choice)
  3. Use the document root as open_basedir (and that can only be located somewhere below the domain root)

This would need Froxlor to track another setting, i.e. what currently is DocumentRoot would become the domain root, and DocumentRoot would become a new setting.

Froxlor now just has to ensure that this new setting is:

  1. a relative path (thus not starting with /, or just hint that it will be appended as-is to $domainroot)
  2. ensure that realpath($docroot) starts with realpath($domainroot) (so that you can't escape $domainroot with symlinks)

kakra avatar Oct 15 '19 16:10 kakra

chosing between customer-homedir and domain-docroot should be fair enough don't you think? that would be a simple select box. Starting with custom-values to be entered manually really complicates things

d00p avatar Oct 16 '19 07:10 d00p

Customer homedir as an option is better than nothing but will expose other sites of that customer.

negrusti avatar Oct 16 '19 13:10 negrusti

"expose" is a bit hard. Yes, a script can read/access the whole homedir of the customer. But require the customer to set a value there manually is imho not a good way. Depending what kind of customers you have but most of the "common webhosting customers" dont know what openbasedir is and don't care. Won't the solution suggested by @NightmareJoker2 in https://github.com/Froxlor/Froxlor/issues/515#issuecomment-410812127 be sufficient?

d00p avatar Oct 16 '19 15:10 d00p

By exposed I mean if one site is compromised, it will be trivial for attacker to compromise other sites on that account. I have a few Froxlor servers where clients host several Laravel apps under one account.

On Wed, Oct 16, 2019, 12:11 Michael Kaufmann [email protected] wrote:

"expose" is a bit hard. Yes, a script can read/access the whole homedir of the customer. But require the customer to set a value there manually is imho not a good way. Depending what kind of customers you have but most of the "common webhosting customers" dont know what openbasedir is and don't care. Won't the solution suggested by @NightmareJoker2 https://github.com/NightmareJoker2 in #515 (comment) https://github.com/Froxlor/Froxlor/issues/515#issuecomment-410812127 be sufficient?

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/Froxlor/Froxlor/issues/515?email_source=notifications&email_token=AENTJY5O4DB5KZ4VD74VTTLQO4VKFA5CNFSM4EQO4WP2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEBM3IYQ#issuecomment-542749794, or unsubscribe https://github.com/notifications/unsubscribe-auth/AENTJYZMXXHWGWCVSJNG6OLQO4VKFANCNFSM4EQO4WPQ .

negrusti avatar Oct 16 '19 16:10 negrusti

I understand fully, and I can relate why this improvement is needed. Still, like said in https://github.com/Froxlor/Froxlor/issues/515#issuecomment-365264373 I try to avoid entering custom paths by customers as extensivly as possible

d00p avatar Oct 16 '19 16:10 d00p

We were installing a copy of the very popular open-source learning platform Moodle for a non-profit the other day. The Moodle installation wizard wanted a path to store files which couldn't be accessed via the web.

This could be solved by having it outside of the DocumentRoot (I'll use Apache terminology in this comment), but that'd mean modifying the open_basedir to accommodate. With Froxlor this unfortunately means an entirely new and separate PHP configuration would need creating & managing for just for this one single domain (as that extra path should only be for this specific copy of Moodle, a 2nd copy of Moodle on the same server would need its own!). This is a pain when you want to tweak the base PHP config for all customer domains... you'll now have extra separate PHP configurations to keep in sync.

Unfortunately the way the Moodle installation wizard works at the moment... it won't proceed until that "Data directory" is outside of the DocumentRoot (even if it is properly secured with .htaccess). I feel this is a bit crazy, so I logged a bug (Frolxor is mentioned a fair bit) about their docs being confusing and/or the security check being broken... this bug here. Ultimately I can see (on their forums and tracker) people on either side of the argument.

It strikes me... that we're likely to see more "off the shelf" content management platforms (e.g. Moodle, Magento, WordPress, Joomla, Drupal etc...) or extensions (installed within those sites)... that'll get more paranoid about where to store non-web accessible data. Typically the only non-public sensitive data of much concern had been passwords (usually kept safely in a database)... but with more functionality (which traditionally needed a back end) being put into these CMS systems, they'll deal with more (and different kinds of) sensitive information. They'll also likely get less concerned about offering up solutions for specific HTTP daemons (such as automatically creating Apache-specific .htaccess files for you) as the HTTP daemon space continues to diversify.

For this reason I'd love to see a way of appending to the open_basedir on a per-domain basis within the Froxlor panel.

I completely hear the point that @d00p made though about this shouldn't be a path that just anyone can arbitrarily state.

So how about for every DocumentRoot there is a same-named alternate private path...

Here are a few examples of how that might work...

DocumentRoot Private path appended to open_basedir
/var/customers/webs/username/moodle.example.com/ /var/customers/webs/private/username/moodle.example.com/
/var/customers/webs/username/ /var/customers/webs/username/private/
/var/customers/webs/username/my-dir/something/moo/ /var/customers/webs/username/private/my-dir/something/moo/

You'd have an option which can be enabled on a per-domain basis to enable / disable the "private path". If you enable it and save... then it will automatically mkdir -p the same location used for DocumentRoot (minus the path for the username /var/customers/webs/username/ part) within the 'private' subdirectory.

That way people can still get at the data via FTP/SFTP if required.

Thoughts?

Lantizia avatar Jul 28 '20 16:07 Lantizia

Oh also (just out of interest) is there any reason why the setting "Paths to append to OpenBasedir" is under... Settings | Webserver settings and not in Settings | PHP-FPM, where one might expect it to be (since it's a php.ini directive)?

Or is it just because if you weren't using FPM (and instead used mod_php), you wouldn't actually have a PHP-named section under Settings to find PHP-related options?

Lantizia avatar Jul 28 '20 16:07 Lantizia

Basically a good idea, but there will always be someone saying "but I need the folder to be named xyz" or whatever. So appending a folder within the customers home directory should be fair enough. I still think it's complicating things as other customers might need a folder within the domain docroot and so on and so forth. There's always another case that needs something else. Also, 90% of customers (end users!!) don't even know what open_basedir is...

So, if you know what you are doing, and not what you are installing, why not just deactivate open_basedir for the domain needing this?

d00p avatar Jul 28 '20 16:07 d00p

Oh also (just out of interest) is there any reason why the setting "Paths to append to OpenBasedir" is under... Settings | Webserver settings and not in Settings | PHP-FPM, where one might expect it to be (since it's a php.ini directive)?

Or is it just because if you weren't using FPM (and instead used mod_php), you wouldn't actually have a PHP-named section under Settings to find PHP-related options?

  1. because it was there way before fcgid/fpm and never switched section but:
  2. also yes, because you would not have the php-related setting-sections if you'd use mod_php

d00p avatar Jul 28 '20 17:07 d00p

I don't think it's a good idea to do it this way. Many sites are deployed from git, and document root is a subdirectory of the whole project. Can't be restructured to fit this un-natural Froxlor quirk.

negrusti avatar Jul 28 '20 17:07 negrusti

@negrusti you're welcome to provide a better solution and a pull-request :)

d00p avatar Jul 28 '20 17:07 d00p

So appending a folder within the customers home directory should be fair enough.

Yeah that'd be much simpler :) So assuming that was an option which became available on a per-domain basis...

Since we also use this setting...

image

The DocumentRoot is automatically set (if it isn't overridden) as a sub-directory in their "home directory" with the same name as the websites domain.

So for us... something equally as simple... like a _private suffix on the same formula would work quite well...

DocumentRoot: /var/customers/webs/username/moodle.example.com Private per-website "Data directory" area: /var/customers/webs/username/moodle.example.com_private

Also since many of these "installation wizards" that come with common PHP-written CMS's can detect and then display the absolute path they're running in (the DocumentRoot)... which if left untouched looks like this...

image

It should then be really easy to explain to the user that they can just set that "Data directory" (or similar such name) to the same as the path their website detected it's running from (the DocumentRoot) if it's displayed. They'll just need to add a _private (or whatever suffix is nominated in Froxlor) and it'll work without them getting any open_basedir errors (they wouldn't need to know what open_basedir even is!).

Visually explaining it would be as easy as...

image

I can see this working for many situations, not just Moodle. I just happen to have Moodle to hand for screenshot purposes... perhaps @dirkey knows what this looks like on a Magento installation?

The reason I'm saying all this, is because I'm dreaming up a new setting (to go alongside the first one I mentioned... in Settings | System settings) to make this even easier for everyone...

image

Also, I like fake screenshots :)

Lantizia avatar Jul 28 '20 19:07 Lantizia

I think that would be the best solution for both sides, nothing manually entered but works. Just has to be communicated with the customer (e.g. good setting description)

PS: yeah fake screenshots are great ;p

d00p avatar Jul 28 '20 21:07 d00p

But remember, if it's in system-settings the customer cannot change it. It should be a customer option to enable a domain-based dara-dir (or whatever you wanna call it)

d00p avatar Jul 28 '20 21:07 d00p

Yeah, so on the domain settings you'd have...

  1. A checkbox to enable the "private area". A nice friendly name for this function... but the actual checkbox's description can state that its actually to append to open_basedir a single path... creating it if non-existant and with a predetermined name if not overridden with...
  2. A text box for the user to optionally enter a directory name (relative to the users "home" dir) to use with this function... if they enter something, then it overrides using domain name + suffix (suffix being set in the admin settings). Obviously the string in this text box can be ignored if they didn't check the checkbox.

That way you could leave a default suffix like '_private' in system-settings without it affecting anyone.

Lantizia avatar Jul 29 '20 12:07 Lantizia

then you would have customer input again which totally makes the checkbox unnecessary if you could just enter a path which still is something i'm trying to avoid (from a customers point of view). Thought we agreed on the checkbox so nothing needs to be entered manually, see https://github.com/Froxlor/Froxlor/issues/515#issuecomment-665281732

d00p avatar Jul 29 '20 12:07 d00p

I'm (personally speaking) happy with just a checkbox (and then it'd always be a extra path comprised of "domain + suffix")... but I was trying to accommodate anyone else who might want to specifically state which path (relative to the "home" dir) they want if they're not wanting that.

In a way it's no different to how this setting works...

image

As setting that, doesn't mean you can't override the DocumentRoot on a per-domain basis anyway... it just presumes an answer if that text input box isn't filled in.

Lantizia avatar Jul 29 '20 12:07 Lantizia

keep in mind that many things you are refering to are admin-settings - customer cannot change or set these! there's a big difference what an admin can and should do and what a customer is allowed to do and should be able to

d00p avatar Jul 29 '20 12:07 d00p

OK so looking at this from the perspective of a logged in customer...

In these fake screenshots I've used non-technical language to describe the settings and tried to keep any terminology similar to language already used on that page...

image

Which since (in this particular case) our Path: (not Private path) is the name of the domain (which was automatically set), then leaving the private area path completely blank... would do exactly the same job...

image

But if someone doesn't like the "domain + suffix" path, they can override it...

image

If someone doesn't want to append an extra path to open_basedir at all... they just want the normal open_basedir which is to include the Path: (i.e. the DocumentRoot)... then they can just turn this off (which should be the default)...

image

However if someone wants the "private area" to actually just be the entirety of the users "home" directory... (setting '/' is different to blank)

image

Which incidentally means that the following section... which is already in Froxlor (it's just been missing from all the screenshots above)... can now be completely removed...

image

As we already have ways of achieving both options which it had in it's drop down box. It's also better explained and is less "scary" sounding than the way it is presented now.

Lantizia avatar Jul 29 '20 13:07 Lantizia

my initial answer still is valid though, an admin might not want that so you would again have additional options (on a per customer base, or even domain based) whether or not to allow adding custom openbasedir-values

But these paths are relative to their own home directory!! What admin would care if they add one single open_basedir path per domain - when it's a path inside of their own user space?!

Lantizia avatar Jul 29 '20 13:07 Lantizia

Yeah yeah, got you. You were talking about your "private path field". And yes, most admins wont care - other might. I'm just saying what I think out of experience with new options from the last 10 years.

As said, I'll gladly merge any pull-request provided if tested thoroughly

d00p avatar Jul 29 '20 13:07 d00p

I think the solution that will cover 99% of use cases is 3 options for open_basedir:

  1. document_root
  2. 1 level above document_root
  3. off

negrusti avatar Jul 29 '20 14:07 negrusti