Saturday, December 19, 2015

Adblock Plus does it again

I noticed recently a number of publishers adding refined versions of the adblocker detected message suggesting that their ads are not intrusive. It's a fine argument, the companies providing articles online do so for advertising revenue, but given the abominable behavior of the advertisers it's a reasonable action to block these. I tracked down this amazing feature, it's at easylist here: Anti-Adblock Warning List. I'm very excited to see this progress on the part of the blocker.

Wednesday, March 18, 2015

Django and cPanel

In my day job I work on cpanel systems with Centos 5 and 6. I have installed django on my system using a manual installation process.

The following describes hopefully enough to get you close to the following setup:

  • Centos 6
  • Current cPanel installation
  • mod_wsgi for apache
  • Python 3.4.3
  • django 1.7
  • a working django install on one subdomain

For Centos 6 and cPanel, you'll need these installed already, operating systems updates on your host are outside the scope of this guide.

Install Python 3.4

You'll need a current Python version to run the latest django. Get it from Python.org. You should build this with the following options, the prefix /usr won't hurt anything the way it would for python 2.7, since the redhat tools in centos use python 2.6. It's possible to install to /usr/local/ or alternate locations by later either adding this to the ldconfig information, or to the build instructions for mod_wsgi. Putting this in /usr, though bad discipline, appears the path of least resistance. Note here make install will require root privileges.: ./configure --enable-shared --prefix=/usr make && make install

After this, executing "/usr/bin/python3.4 --version" should show 3.4.3, and all is well (you should install the latest available python from the download link, 3.4.3 was current as I wrote.)

Install mod_wsgi

There exists a mod_wsgi EasyApache Custom Opt Module that will make wsgi a menu option at build time. This is preferable to other manual installation methods for a few reasons, the principal being that all others are likely to break on easyapache rebuilds. If you have managed hosting, that may have been initiated by your host rather than directly by you, and you might not like waking up to broken sites. So we'll play the cpanel way. EasyApache documentation has a link to a google code project to build this, it's a little dated, but we'll start from there. Get the module from this comment, then wonder why code is being linked from comments. Mind the date (Feb 2013, right now about 24 months old, and a few versions back). This has earlier instructions for installation, specifically, after download, extract to the easy apache directory: tar -C /var/cpanel/easy/apache/custom_opt_mods -xzf ModWSGI.tar.gz

This however, bundles version 3.4 of mod_wsgi, and nobody seems to be repackaging it. Let's get a current version (check the source for the current version): wget -O ModWSGI.pm.tar.gz \ https://github.com/GrahamDumpleton/mod_wsgi/archive/4.4.13.tar.gz mv -v /var/cpanel/easy/apache/custom_opt_mods/Cpanel/Easy/ModWSGI.pm.tar.gz{,-3.4} cp -av ModWSGI.pm.tar.gz /var/cpanel/easy/apache/custom_opt_mods/Cpanel/Easy/

This will give us a current version of mod_wsgi, we'll need to tell easy apache to use that. If you're curious, run your editor on the /var/cpanel/easy/apache/custom_opt_mods/ModWSGI.pm perl source for this module, and look for the src_cd2 line, update that to mod_wsgi-4.4.9 from mod_wsgi-3.4 (what came in the module bundle earlier). If you're not interested in how easy apache modules are built, just run the following, which backs up the file, then replaces the old version with the one we made (this is in fact the name of the directory created when you extract the tar archive): cp -av /var/cpanel/easy/apache/custom_opt_mods/Cpanel/Easy/ModWSGI.pm{,.save} sed -i 's/mod_wsgi-3.4/mod_wsgi-4.4.9/' /var/cpanel/easy/apache/custom_opt_mods/Cpanel/Easy/ModWSGI.pm

One final thing, this will default to using the system python version. We're cutting edge, we'll use the latest python 3 version we installed above, so we'll need to modify the call to configure to include that. If you still have your editor in the perl file, you'll see the configure command options in the qw quote call, and it's easy to add the needed --with-python argument, otherwise, sed does this for us: sed -i \ 's;bin/apxs;bin/apxs --with-python=/usr/bin/python3.4;'\ /var/cpanel/easy/apache/custom_opt_mods/Cpanel/Easy/ModWSGI.pm

Now run EasyApache (/usr/local/cpanel/scripts/easyapache) and check mod_wsgi. If you get any errors, either you or I did something wrong. I'd love to hear if that happens, and might be able to help. Fortunately, failed builds default to restoring the previous setup, so there's little danger in getting it wrong, and if apache won't compile, you won't break everything else. I would recommend using the least changes possible, so do this with the last working build, and only change adding mod_wsgi from the options menu.

Install Django

Since this will be a system wide feature, and I'm not going to delve into virtualenv + virtualhosts, let's just install django, at this time, the target was 1.7.6, but version numbers get bigger every day: pip3.4 install django==1.7

Install a Django site

You should really consult either a basic django book, or the official tutorial (make the polls app). However, assuming you know what you're doing, at this point, you should be ready to run django-admin as one of the users. Let's pretend we're starting the polls app: django-admin startproject polls

This isn't 100% ready to run, let's spiff it up a little. cd polls cp -av polls/wsgi.py ./wsgi.py EDITOR wsgi.py

You'll need to add the following to your wsgi.py to get python able to find any custom modules in your current site (which is not in the path):

import sys
sys.path.append("/path/to/django/site/")
Let's define a STATIC_ROOT for django in settings.py as well:
STATIC_ROOT = os.path.abspath(os.path.join(BASE_DIR, '../static'))
Now let's let apache know about this. Let's add this to a custom user include (in /usr/local/apache/conf/userdata/std/2_4/USERNAME/DOMAINNAME/django.conf, or whichever include directory is listed in your virtual host definition in httpd.conf, which you'll also need to uncomment to get this to load):
WSGIDaemonProcess USERNAME-django display-name=USERNAME-django user=site processes=2 threads=15
WSGIScriptAlias / /home/USERNAME/polls/wsgi.py

Alias /static /home/USERNAME/static

<Directory /home/USERNAME/static>
    Require all granted
</Directory>

Finally, we'll set django to collect the static elements (you know, so admin isn't ugly, and things work correctly): python3.4 manage.py collectstatic

Make it run? If this does not say ok, and emits any syntax errors, then restarting apache is a BAD idea: httpd -t If you're in the clear, restart: httpd -k restart

Sunday, March 08, 2015

Disable PHP execution in a directory

For a while it has bothered me that code was able to be loaded to wp-content/uploads on a wordpress site, then executed (for example, loading php code in a gif image is a common tactic). I've decided to enable a no-execute line, but wasn't' sure how to do it. My first attempt follows.

Add to the htaccess file in the directory to block the following directive (basically disabling execution of php files):

AddType text/plain php
The idea may need refinement, basically, no code will run. If you have other code extensions calling handlers (like .php5 or .pl or similar), then the line would change. I'm not sure this is 100% desired, but does change my test program from executing to returning the code, I used echo("running") as my example. Since there's no code handler for text/plain, the server sends it to the client directly, maybe with compression, but with no backend processing. This seems adequate to default a large chunk of malicious upload exploits.