Most of the issues I see that block tasks from running successfully are caused by permissions problems. More often than not, these are files written by Drupal (or CiviCRM) with mode 0600
, owned by the web user. 'aegir
', despite being a member of the web group (i.e. www-data
) is not in a position to operate on such files. The resolution is usually to chown
and chmod
these files as root
.
In other issues, we've discussed adding a script that could be called under sudo to perform such fixes securely. Of course this is the tricky part. We'd need to ensure that the command was only ever run against site directories, and wouldn't permit arbitrary chmod()
ing and chown()
ing.
I think we could accomplish this with a Drush command (or three), which would have the added benefit of making it reasonably simple to wrap it in an Aegir task. If we're running the script under sudo
, then it will be executed as root
, so we'll need to point it to our aliases/contexts. We could try using the --include
option (and maybe also --local
) to make all and only aliases in /var/aegir/.drush
available.
I think this might look like:
- A sudo entry is manually created upon installing this command and would look like:
aegir ALL=NOPASSWD: /usr/local/bin/drush fix-permissions /var/aegir/.drush /var/aegir/platforms
Which hardcodes both the alias include path and a 'jail' dir as arguments. - Aegir calls
drush @example.com provision-fix-permissions
. provision-fix-permissions
invokessudo drush fix-permissions /var/aegir/.drush /var/aegir/platforms @example.com
.drush fix-permissions
then callsdrush --include=/var/aegir/.drush --jail=/var/aegir/platforms @example fix-permissions-real
.drush fix-permissions-real
looks for a--site-path
option, validates that the path is under/var/aegir/platforms
, and only then operate itschown()
s andchmod()
s.
We might want to include such commands under hosting_tasks_extra or hosting_dev.
Comment | File | Size | Author |
---|---|---|---|
#6 | add_fix_permissions-2616426-5.patch | 3.31 KB | helmo |
Comments
Comment #2
ergonlogicComment #3
gboudrias CreditAttribution: gboudrias at Praxis Labs Coop commentedSolid plan. I was planning on making this a separate module but it seems that this is more or less what tasks_extra is for.
Comment #4
helmo CreditAttribution: helmo at Initfour websolutions commented+1 for creating such a script/task.
One downside of using drush for this is the risk of priviledge escalation.
If the fix-permissions drush command is called as root, can we be sure that no other code where the aegir user can write to is used?
In most current installations the aegir user can modify the drush code ... or add a drush module with e.g. a pre hook.
So any code called via sudo should be only writable by root. My vote would be for a compact standalone script php of shell without any includes.
What about the script from #1737266: The directory sites/drupal7.d7.local/files is not writable.
Comment #5
helmo CreditAttribution: helmo at Initfour websolutions commentedI've taken the script example from https://www.drupal.org/node/244924, and opened a pull request in one of the git repo's tracking it.
Instructions:
Copy the fix-permissions.sh script from this patch to /usr/local/bin/fix-permissions.sh (especially a place where the aegir user should have NO write access).
Add to sudo with `visudo -f /etc/sudoers.d/aegir`
Usage:
sudo /usr/local/bin/fix-permissions.sh --drupal_path=/var/aegir/platforms/drupal-8.0.x --drupal_user=aegir
About adding a task ... this script works on a platform ... so a platform task would make the most sense.
We could eventually include this in the Debian package install but only after thorough review.
Comment #6
helmo CreditAttribution: helmo at Initfour websolutions commentedComment #7
helmo CreditAttribution: helmo at Initfour websolutions commentedA slightly more specific sudo line:
aegir ALL = (root) NOPASSWD: /usr/local/bin/fix-drupal-file-permissions.sh --drupal_path=/var/aegir/platforms/*/ --drupal_user=aegir
And I suggest to name the script fix-drupal-file-permissions.sh to make it's purpose even more explicit.
Comment #8
clemens.tolboomI assumed the verify task was for fixing permissions too. What is wrong with that?
If we need a script (jikes) for that I agree with @helmo to name it fix-drupal-file-permissions
(a hostmaster user)
Comment #9
clemens.tolboomI was talking about site file permissions. My site was broken as site verify seemed to fix top level files dir(s) but forgot it's children
Why not ask the site for it's private:// public:// and temp:// and fix those recursive?
Comment #10
helmo CreditAttribution: helmo at Initfour websolutions commentedprivate/temp needs to be handled.
And I think we can simplify it to only work on sites ... not the platform.
Comment #11
helmo CreditAttribution: helmo at Initfour websolutions commentedtargeting for the next release
Comment #12
gboudrias CreditAttribution: gboudrias at Praxis Labs Coop commentedComment #13
Jon PughMarking major. This is a sleeping dragon of a problem, one that most people aren't aware of, and one that causes aegir to "look bad".
Comment #14
helmo CreditAttribution: helmo at Initfour websolutions commentedComment #15
Jon PughAfter a comment from omega8cc, I think this needs to be a part of aegir core's Verify task.
We already are setting permissions on files as much as aegir user is allowed. In fact this is one of the big selling points of aegir: "You don't have to mess with file permissions." ...
I would almost call this a bug. When the system claims to "set permissions, configuration, and ensure the site is in order" but it actually can't properly reset permissions on uploaded files, wouldn't that be a bug?
Let's make this happen...
Comment #16
memtkmcc CreditAttribution: memtkmcc at Omega8.cc commentedIn BOA we are running global permissions fix daily, for all sites (but also for custom platforms, to make sure people don't try to make their codebases writable in some dangerous way). It helps a bit, but is still not ideal, since once you clone a site, you can't wait until the next day to have all permissions fixed for you. It should be fixed on the fly. Here is the script we run daily. It does many more than permissions fix, and already turned into spaghetti code, so we need to make it modular, but maybe parts of it could offer some hints.
The procedure where the global fix happens, can be seen here: fix_permissions()
Comment #17
memtkmcc CreditAttribution: memtkmcc at Omega8.cc commentedPlease note that the fix should be run (available as an extra task?) both for sites and platforms.
It is otherwise possible that people create codebase which is not writable by the Aegir user, and it will instead log warnings like:
Comment #18
ergonlogicI agree that we need to be able to fix both sites and platforms, but I'd prefer that we do it under separate scripts and tasks. That is, have both a
fix-drupal-platform-permissions.sh
and afix-drupal-site-permissions.sh
, called by the respective "verify" tasks.This could be added as a feature to tasks_extra, so that it remains optional, and could be implemented in a pre-verify hook.
Comment #19
ergonlogicI've added a prototype implementation in the
dev/fix-permissions
branch ofhosting_tasks_extra
: http://cgit.drupalcode.org/hosting_tasks_extra/tree/fix_permissions?h=de...There's an
install.sh
script to deploy thefix-permissions.sh
script (copied from https://www.drupal.org/node/244924), setting up sudoers, etc. Then we have the Hosting Feature scaffolding that allows the functionality to bel enabled from the front-end. Finally, there's a basicdrush_hook_pre_provision_verify()
, where we call the script, passing in the relevant arguments, and log the results. It will currently only run on platform verify tasks.Next steps should probably include:
fix-permissions.sh
into platform- and site-specific scripts;We may also need to add a Drush command, which would more easily allow for remote execution. We'd then also need to ensure that we're deploying the scripts, sudoers entry, etc. to web nodes. It'd also just be a nice convenience feature to be able to run:
drush @example.com fix-permissions
Comment #20
colanIn case anyone's interested in looking at the code, I worked on a Drush command for fixing permissions a while ago which never got committed. The issue is #990812: Add a "permissions" subcommand to fix/set all file permissions.
Edit: The most recent patch is probably the most useful: https://www.drupal.org/node/990812#comment-7013970.
Comment #21
ergonlogicThanks for sharing that, @colan. That's a long issue thread, so I only skimmed it. Feel free to point out any specifics that you might think are relevant here.
FWIW, we started out looking at doing this in Drush, but @helmo's concerns in comment #4 shifted the focus to a stand-alone shell script. Also, Aegir already attempts to fix ownership and permissions in _provision_drupal_create_directories(). It's in-ability to
chown
andchgrp
effectively is the main motivation for this script, as it'll need to be run undersudo
.It occurs to me, having just re-stated it above, that the permissions changes in the script are redundant with those in Aegir core, and don't actually match, in some cases. I wonder if this script could be trimmed down to just the
chown
andchgrp
, as that should allow Aegir's native permissions handling to work.Comment #22
ergonlogicI've now split out fixing ownership from permissions, as well as site operations from platform ones, to allow for more granular testing and experimentation. I also added better error-checking and logging, as well as switching to the native Aegir option names (i.e., "root", "script-user", etc.)
I think these additions are ready for review and testing, so long as sites are hosted locally. I suspect that support for remote servers will require a separate Drush wrapper in order to work smoothly. While our hub & spoke model ought to sync these changes out to remotes, in some cases the remote is authoritative, and so this might not apply.
Comment #23
ergonlogicI've implemented a couple hooks in these new extensions to disable Aegir core's chgrp and chmod, since it was ending up flipping some perms back and forth.
Comment #24
helmo CreditAttribution: helmo at Initfour websolutions commentedWhat about the 'sites/example.com/private' I assume that needs the same commands as used for files.
Comment #25
ergonlogicAdded fixes to private/ perms in 87cf4fd (dev/fix-permissions branch of hosting_tasks_extra)
This results in .htaccess files under private being chmod'd 660. Should www-data be able to write to .htaccess? I guess since we don't use them anyway, it's a moot point...
Comment #26
ergonlogicRunning this in a pre-verify hook can be insufficient to leave a properly working site. For example, CiviCRM will delete and recreate some directories during its cache-clear, that occurs late in a post-verify hook. So, moving to a post-hook, and renaming the Drush files and hook implementations to add a "zz_" prefix, are sufficient to ensure our script is run last. Kind of ugly though, so I haven't committed it yet.
I had experimented with mechanisms to re-order Drush hooks, but I don't think they were ever merged. Does anyone know a better way to achieve this?
Comment #27
helmo CreditAttribution: helmo at Initfour websolutions for Aegir Cooperative commentedHook re-ordering would be nice here ... but would also make it even more complex. The zz_ prefix seems like an easy solution. Otherwise we might have to look for another hook... a post_post hook :) ?
Comment #28
colanModule weights?
Comment #29
ergonlogicI've pushed the change to prepend "zz_".
Unfortunately, Drush doesn't have a concept of module weights, unless that's changes in the last year or so. It relies only on the alphabetical order of the extensions/commandfiles.
We might want to add a couple hooks within our hook implementations, to avoid other contrib having to be named "zzz_...". In fact, we could split out the "zz_" implementations into a stand-alone extension (still within hosting_tasks_extra), that simply provides a convenient way to provide something like "post_post" hooks (maybe "post_final"). Anyway, we can table that discussion, unless and until someone cares enough to start a new issue about it.
Comment #30
colanI just found Allow modules to control the order of hook invocations which you worked on a while ago, but it looks like it may require the listed follow-up? It would be good to get that in.
Comment #31
ergonlogicRight, this failing PR is probably a good start: https://github.com/drush-ops/drush/pull/462. That said, it's really outside the scope of this issue, since the "zz_" solution works, and should be pretty easily re-factored in a hook invocation order altering hook is merged into Drush.
As far as fixing file ownership and permissions, I think we're in pretty good shape. The only remaining item, as far as I can tell, is the concern I raised in #19. That is, execution of these scripts on platforms and sites that live on remote servers.
Assuming we're otherwise good here, I'd like to merge the
dev/fix-permissions
branch, and work on any fixes required for remote execution in a new issue. Any objections?Comment #32
Jon PughThat's a really good point, update hooks or drupal cache clearing might do things to files too.
But I'm thinking we might actually need to run this both pre and post verify.
I run into the situation where Aegir verify cannot run because some file is unwritable, so the fixperms would need to be fixed before that.
Comment #33
helmo CreditAttribution: helmo at Initfour websolutions for Aegir Cooperative commentedThis needs a good hint to the user that the install script needs to be executed ... for both permission and ownership modules.
If you currently fail do to do this you get a warning in the task log which is not directly obvious.
Comment #34
helmo CreditAttribution: helmo at Initfour websolutions for Aegir Cooperative commentedI've added a drupal_set_message when the modules are enabled...
Bonus points lets it link to the actual docs... but rtbc otherwise
Comment #35
Jon PughPerhaps implementing a "hook_requirements()" would be helpful, not just for this but other things Aegir needs?
Comment #36
helmo CreditAttribution: helmo at Initfour websolutions for Aegir Cooperative commentedComment #37
helmo CreditAttribution: helmo at Initfour websolutions for Aegir Cooperative commentedhttp://cgit.drupalcode.org/hosting_tasks_extra/commit/?id=402925b
Comment #39
inteja CreditAttribution: inteja commentedI'm running Aegir 3.9 and have enabled the Fix Permissions and Fix Ownership modules and run the bash install scripts but verify is now throwing warning for sites that previously verified.
EDIT:
I see in the Aegir log for one verify task:
Comment #40
inteja CreditAttribution: inteja commentedWorked it out. For whatever reason, running the
sudo bash scripts/install.sh
in each of these submodules resulted in copying the scripts to/usr/local/bin/
and setting the correct file ownership and permissions, but did not add the corresponding entries to sudoers. So I manually added the following to my sudoers file and now it works as advertised.Comment #41
ToRum CreditAttribution: ToRum commentedWe ran into this issue while trying to install Aegir 3.9 manually. Since
drush hostmaster-install
needs to be run as the aegir user, this user is not allowed to run thehostmaster-7.x-3.9/profiles/hostmaster/modules/aegir/hosting_tasks_extra/fix_ownership/scripts/install.sh
andhostmaster-7.x-3.9/profiles/hostmaster/modules/aegir/hosting_tasks_extra/fix_permissions/scripts/install.sh
scripts.As a workaround, we first executed the following commands as root user:
Afterwards, you can continue installation:
Comment #42
inteja CreditAttribution: inteja commentedHave just updated 3.9 to 3.10 and now it looks like verify task fix permissions is changing ownership to www-data instead of aegir, so verify and backup tasks fail.
Suggestions on how to fix?
Comment #43
pmunch CreditAttribution: pmunch commentedI have a fresh Aegir 3.10 install using deb packages on Ubuntu 16.04, and I confirm that "Fix Permissions" and "Fix Ownership" make verify hosmaster task fail immediately with:
Comment #44
NWOM CreditAttribution: NWOM commentedI can confirm #43 happening to me as well.
Comment #45
helmo CreditAttribution: helmo at Initfour websolutions for Aegir Cooperative commentedPlease don't ask questions in a closed issue ... it doesn't show up normally, and thus doesn't get attention.
The first thing to check here is if the sudo settings have been setup correctly by the install.sh scripts. You should have files like /etc/sudoers.d/fix-drupal-platform-ownership
Please open a new issue if you have those and still see this problem.
Comment #46
NWOM CreditAttribution: NWOM commented@helmo: Thanks for the information.
@pmunch: I created an additional issue for this here: #2961009: Sudo Settings not setup correctly in regards to Fix Drupal Platform Ownership