I use PHP in DSO mode, which is (woefully) insecure because it lives to save files as ‘nobody.’ Now, previously I found a ‘fix’ to this with WordPress, by tweaking some file permissions and a define in my wp-config.php file, and all was well. But if you know me, you know I’m polyamorus with my CMS, and WordPress ain’t the only game in town.
I love, love, love Zenphoto for a gallery that is larger than my thumbdrive. But I’ve been having an annoyance that acrylian and sbillard have been really patient with me ranting about for a while now. See, when you upgrade Zenphoto, it narked at me that I had bad permissions:
Oh how I cried. My work-around became to make those 777, upgrade, and change ’em back to 755, because that did work for nobody, but when Zenphoto moved the config file and had it be writable by the upgrader, I had to make that owned by nobody and the slippery slope was happening. This was not good. I brought it up again, but we all agreed this was very much a me-problem.
A new PHP
Now my choices were to deal with it, or change to a new PHP. Well there are problems with that, and neither suPHP nor FastCGI met my needs for speed and memory consumption. Also I tend to get error 500s when I try any of them on this server, which means I would have to do a total overhaul which I don’t have time for. Instead, I decided to look into why mod_php (aka DSO) likes to have nobody own this stuff. In my research, I stumbled across mod_ruid2, which is included in EasyApache.
In reading up on cPanel’s notes on mod_ruid2, I hit the incompatibilities list and winced. Right there near the top was MemCache. When I switched over to ZendOptimizer, I also switched to MemCache, and I really was not ready to give it up and go to XCache. Worse? It’s not compatible with
mod_security
. Epic fail. I absolutely cannot use this. Back to the drawing board until cPanel figures out a way to force it to work with those.
More searching introduced me to MPM-itk. This was something categorically not supported by cPanel (they backed mod_ruid2), but they still had some directions on how to do this in their forums: Using MPM ITK as a Custom Opt Module
I need to stress two very important things here:
1) This is NOT supported by cPanel.
They do include it in their Custom Mods, but they don’t support it’s use, and won’t include it by default because of issue number 2 (see below). Mind you, I’m no stranger to unsupported installs. I have ImageMagick in a higher version than they do, I installed wp-cli, and I have Pagespeed. So I pretty much run around always upgrading what I need. I am smarter than I used to be, and I have all this documented in a Word Doc called “Custom Installs on my server” which lives on Dropbox, for emergencies. Everything is written with code examples and as much copy/pasta as I can.
2) There is a security risk with mpm-itk because it runs as root.
I will quote the author:
Since mpm-itk has to be able to setuid(), it runs as root (although restricted with POSIX capabilities and seccomp v2 where possible) until the request is parsed and the vhost determined. This means that any code execution hole before the request is parsed will be a potential root security hole. (The most likely place is probably in mod_ssl.) This is not likely to change in the near future, as socket passing, the most likely alternative solution, is very hard to get to work properly in a number of common use cases (e.g. SSL).
Obviously this is a choice you need to make yourself. Perhaps ironically, by using setuid(), you’re protected from users cross-contaminating but this is not really a perfect fix for everyone. And frankly, this is not my preferred long term fix. My long term fix is this: Build a brand new server, from scratch, with FastCGI, and move sites over one at a time, testing as I go. That’s not today. Instead, it took me about an hour to figure this stuff out and install. And it worked out of the box. Well, except for one thing which I’ll get to.
Installing mpm-itk
These directions are pretty easy for cPanel/WHM. You install:
cd ~/tmp wget http://docs.cpanel.net/twiki/pub/EasyApache3/CustomMods/MPMitk.tar.gz tar -C /var/cpanel/easy/apache/custom_opt_mods -xzf MPMitk.tar.gz
Then you run EasyApache (/scripts/easyapache
) and select mpm-itk from the Exhaustive Options list for PHP (it will give you a warning about the dangers, Will Robinson). Once the update is done, make sure all your normal settings are back in place, if you have anything special, and now you have to actually tell every virtual host what ID to use.
mkdir -p /usr/local/apache/conf/userdata/std/2/username echo "AssignUserID username username" >> /usr/local/apache/conf/userdata/std/2/username/mpm.conf /scripts/ensure_vhost_includes --user=username
Replace ‘username’ with your user name (you saw that coming, right?) and off you go. Of course, I had 10 users, so instead I scripted it:
#!/bin/bash for user in `ls /var/cpanel/users`; do mkdir -p /usr/local/apache/conf/userdata/std/2/${user} echo "AssignUserID ${user} ${user}" >> /usr/local/apache/conf/userdata/std/2/${user}/mpm.conf /scripts/ensure_vhost_includes --user=${user} done
Huzzah!
Cleanup, Aisle PHP
Once I had it installed, and it really was painless, I tested uploads on WordPress and everything worked. But I remembered what I had done back in 2011:
The last step I had was chowning the folder for uploads and 2011 to nobody:nobody.
This time I did it in reverse and chowned everything back to my user IDs. I did this for all sites, for all users, and all cache folders. Then I decided to look for all files and folders that were 777 (which I do at work when scanning for hacks) just in case I’d been stupid. I try to not be, but…
find . -type d -perm 0777
That listed all directories, and I was appalled to find some! That’s right. Up until recently, there were folders permission’d as 777 on my server. I bow my head in shame and embarrassment. Please forgive me, as I run this command to fix that:
find . -type d -perm 777 -print -exec chmod 755 {} \;
I also ran find . -group nobody
to see if I had anything left over, and it happily came up empty. Then I went to double check everything worked. When I’d tested before, I did it on my single install of WP, my wiki, my gallery, another blog, and it worked. So I came here to post and I couldn’t upload images. Horror! Shock! I decided to scan my error log, and right away got a warning on cPanel: Out of disk quota.
Well that was an easy fix!
Now everything’s owned by the user it runs for, and nobody owns anything. Everything is secure (except for that ‘running setuid as root for a millisecond’ issue, and yes I’m keeping tabs on that), and everyone is happy. Especially me.
Bonus Internet points if you get the joke with the title.
Comments
4 responses to “Polyphemus Problem Pans Out”
Without knowing the full context, my inclination would have been to set a +w ACL for the apache user on the directory tree Zenphoto writes to:
setfacl -R -m 'u:apache:w'
(write on existing content)setfacl -d -R -m 'u:apache:w'
(set the above rule on future files and directories)That’s assuming that the web server filesystem is mounted with ACL support.
The problem is that instead of running as the user apache, it literally ran as ‘nobody’ – This is intentional, so it drove me up a wall :/ Has to do with how DSO/Mod_PHP is set up. Supposedly you can make it run as the apache user, but everyone shouted how that was more dangerous than doing this.
Thanks for calling us “patient” π
You’re certainly far more understanding than many people have been with me π