File Permission Security on Shared Web Hosting

Some web hosts allows you to create multiple users per account. Each user can have domain assigned to its home home directory accessible via FTP or SSH/SCP. The problem with multiple users on the same account is that they share the same default unix group, and default permissions allow their files to be easily modified by the members of this group. Usually this doesn’t pose a problem as each user is probably trusted by account owner to not to mess with others files, but if one of the users have their web application hacked then all other users on the same account will be in danger.

By default (on DreamHost) all files in your account are created with 644 privileges and directories are with 775. That means any user can read your files and any user from the same account can move and add files in your freshly made directories. Your home directory is different, though. By default it carries 751 attribute meaning that only members of your group can see your files, but can’t add any new. These group access schemes are possible, because every user in your account has its primary/default group set to “pgxxxxxx”, which is assigned to every new file you create by default. The normal way to secure users from web-intrusion is to assign a separate group to the web-server user, removing it from default group. This way, exploited scripts will not be able to traverse into home directories of other users on your account. To allow account users to update centralized web-site they could be added to web-site group explicitly. But this “normal way” doesn’t work with DreamHost, because you can’t delete web-user from the default group and unless you set access for every new file explicitly, it will be possible for an intruder to read it.

To make managing privileges easier in interactive sessions “umask 007″ command can be specified in your .bash_profile – this makes all new files carry xx0 mask. You also need to control your scripts (web based or cron/shell) so that they set mask for critical files explicitly. To secure account users from access by means of hacked user script you would also like to define another group for every user in your account and change group ownership of the user’s home directory to that group with “set gid” bit set (and optional umask 007 in .bash_profile).

  1. Add a separate user and group for every domain where apache will be running
  2. Add a separate group for other user accounts
  3. Change the default group for new files created by your users by changing the group of their home directory and setting set gid bit for it (it is impossible to do this with FTP accounts, therefore you will need to login in each account via SSH)
  4. Add users who need access to web-site into the web-user group
  5. Optionally set umask 007 in .bash_profile for every user to tweak default DreamHost 775/664 permissions to something like 770/660 for directories and files that are not meant to be read by Apache (660 could also be used for all web scripts including .php as they are not read by dhapache CGI, but merely executed)

Apache Security

All your web files that need to be read by Apache should be readable by everyone as Apache itself is run under dhapache user. However, executable scripts like .php are executed under your own user and do not have to be world readable as they are not actually read by Apache, but executed via suEXEC. Quite the opposite – to prevent your code or database settings from being messed by any third-parties you SHOULD set permissions to these files explicitly to something like 640 or even 600 depending on who do you trust.

Multiuser security setup example

For our example, we will create a example_www user and a new_webroot group for serving web files with apache and setup a example user with a ‘rfrc group to manage mail and keep other files on DH privately. Since these records already exist, you will need to subsitute your own names.

  • Login to DreamHost panel and create the users example_www and example with shell access.
  • From groups tab create two groups – new_webroot and rfrc. Note that users created in previous step are still members of the same default pgxxxxxx group.
  • Add example_www to ‘the ‘new_webroot group and example to both the new_webroot and rfrc groups
  • Move your domain to example_www account (mine is example.org)
  • Now login to SSH with your example_www user and change the default group for your home directory with “sgid” bit set to make all current and new files/directories created in this directory have the same new_webroot group.
 $ chgrp -R new_webroot .
 $ chmod 2751 .
 $ chmod 2771 example.org

By setting 2771 the directory will be writable by the owner, the group and will be only executable by others. The contents of an executable only directory cannot be listed, but the files inside it can be read (if the permissions of the file allow it). It is important that the directory can be executable in order to allow static content (e.g. .html files) inside it to be read. Remember that directories you don’t want anyone to have web access to, should be 0770 (writable by the owner and group, or 0750 writable by the owner and readable by group). Such strict permissions should by applied to password files, php include files or databases files (such as SQLite, BDB, etc).

  • Do the same for example user, but specify rfrc group instead.

chgrp -R rfrc .
chmod 2751 .

  • Optionally modify umask in .bash_profile in user’s home to 007 to make all files created by this user have 660 permissions set by default. If you want that newly created files by accessible by the web, you need to manually setup it’s permissions to 664.

Now I can login as the user “example” and update the web-site in the ../example_www/example.org directory. There is one more setup needed. Because files copied from other accounts can have 644 permissions set instead of 664, you need a script which will update permissions to 664 or 660 to allow other group members modify such files.

Blocking Abuse by IP Address

IP Abuse Detection Script

This shell script checks the access and error logs generated by apache for a particular domain, looking for the IP addresses that have connected to your site the most. It checks for IP addresses that trigger a Concurrent Connection Limit Exceeded error, which is a good sign they are an automated bot of some kind, making over 20 requests to your site at the same time. This script also checks for Internal Recursion Errors which can have very negative effects on your speed and resources, and are basically internal looping problems generally caused by improperly configured Htaccess setups.

Once the script finishes scanning your logs for those events, it automatically generates .htaccess code that you may add to your sites root .htaccess file to block those IP addresses the script identified as abusive. The only IP addresses included in the generated .htaccess file are those that have no reverse dns.

alt text

Installation

  1. Log in to your account using SSH
  2. Save this code in your $HOME directory as ip-abuse-lookup.sh
    1. Run pico $HOME/ip-abuse-lookup.sh
    2. Copy the code to the screen by clicking the right-mouse-button
    3. Hold down the Ctrl button and then press x to save
  3. Run the command dos2unix -dv $HOME/ip-abuse-lookup.sh to fix line break issues
  4. Run the command chmod -v 744 $HOME/ip-abuse-lookup.sh to make executable

Running the Script

From your $HOME directory (cd $HOME), run ./ip-abuse-lookup.sh to execute the program.

Example Generated .htaccess

This script will also generate code that you can place in your .htaccess file to block specific abusers.

## IP-ABUSE-LOOKUP
Order Allow,Deny
Allow from All
Deny from 6.132.177.129 27.67.117.178 6.135.166.102 8.93.225.133
Deny from 21.194.136.15 22.120.61.3 6.252.139.246 9.64.50.83
Deny from 8.123.144.98 21.249.83.87 29.85.238.28 25.214.237.62
Deny from 22.115.130.23 13.57.156.241 14.121.4.82 6.208.172.177

ip-abuse-lookup.sh

#!/bin/sh
# Version 0.2, 2008-04-20

# User-contributed script. Not sponsored by DreamHost.
# Script created 2008-01-16 by AskApache 

### SHELL OPTIONS
set +o noclobber  # allowed to clobber files
set +o noglob     # globbing on
set +o xtrace     # change to - to enable tracing
set +o verbose    # change to - to enable verbose debugging
set -e            # abort on first error

The full script is here, but the authors has an updated Ip Abuse Blocking with .htaccess page.