Server Security

A Script for Fixing File Permissions

suPHP and FastCGI require files and folders to have a specific set of permissions/ownership different from other handlers. Without these permissions set correctly you will see a lot of errors such as: “403 Forbidden”, “500 Internal Server Error”, or simply generic errors that commonly have the word ‘permission’ in them.

It can be very time consuming to track down and check file permissions across a whole server. Luckily, fixing permissions and ownership on a server running  cPanel can be scripted. One of the members of our MST, Colin Roche-Dutch, created a simple script for ServInt called ‘fixperms’ that you can wget to any cPanel server. Simply run the fixperms script, specifying the user (or all users), and the errors disappear.  It is a good generic fix if you cannot find your permission problem, or if you have just switched your handler and need a quick way to change every user account on the server.

The following script is intended for suPHP or FastCGI ONLY! If you are not running either of these two handlers, do not run fixperms. The script will cause problems if you are running another handler such as DSO.
Furthermore, it is highly recommended that you run a full backup of your server before running fixperms or any other script that makes changes to multiple files.

The fixperms script is intended for cPanel servers only. It is dependent on cPanel’s internal scripts and file structure. If you’re on anything else (such as Plesk), it will simply fail to run. It won’t be able to do anything.

Steps to run fixperms on your VPS

1. wget fixperms and run for a single user

To use the fixperms script, simply log into your server as root, wget the file from our server, then run it. Type in the cPanel username and it will run only for that particular account.

It does not matter which directory you are in when you run fixperms. You can be in the user’s home directory, the server root, etc. The script will not affect anything outside of the particular user’s folder.


2. Running fixperms for all of the users

If you would like to fix the permissions for every user on your cPanel server, simply use the ‘–all’ option:

sh --all

3. Verbosity of fixperms

By default, the script runs in a ‘quiet’ mode with minimal display. However, if you’re like me, you may want to see everything that is happening. You can turn on verbosity using the ‘-v’ flag and have the script print to the screen everything that is being changed.

This is extremely useful when fixing large accounts that have many files. You can watch the changes as a sort of ‘progress bar’ of completion. The ‘-v’ flag can be used per account or with all accounts.

For one single account:

sh -v -a USER-NAME

For all accounts:

sh -v --all

 4. The code itself, what’s in it?

If you’re curious about just how fixperms works and want to poke around under the hood before uploading, here is the code.

001 #! /bin/bash
002 #
003 # Date: Jan 26th 2012
004 # Author: Colin Roche-Dutch
005 # Fixperms script for ServInt
006 #
007 # Fixperms script for cPanel servers running suPHP or FastCGI.
008 # Written for
009 # Copyright 2012 ServInt Corporation
010 #
011 # This program is free software: you can redistribute it and/or modify
012 # it under the terms of the GNU General Public License as published by
013 # the Free Software Foundation, either version 3 of the License, or
014 # (at your option) any later version.
015 #
016 # This program is distributed in the hope that it will be useful,
017 # but WITHOUT ANY WARRANTY; without even the implied warranty of
019 # GNU General Public License for more details.
021 # Set verbose to null
022 verbose=""
024 #Print the help text
025 helptext () {
026 tput bold
027 tput setaf 2
028 echo "Fix perms script help:"
029 echo "Sets file/directory permissions to match suPHP and FastCGI schemes"
030 echo "USAGE: fixperms [options] -a account_name"
031 echo "-------"
032 echo "Options:"
033 echo "-h or --help: print this screen and exit"
034 echo "-v: verbose output"
035 echo "--all: run on all cPanel accounts"
036 echo "--account or -a: specify a cPanel account"
037 tput sgr0
038 exit 0
039 }
041 # Main workhorse, fix perms per account passed to it
042 fixperms () {
044 #Get account from what is passed to the function
045 account=$1
047 #Check account against cPanel users file
048 if ! grep $account /var/cpanel/users/*
049 then
050 tput bold
051 tput setaf 1
052 echo "Invalid cPanel account"
053 tput sgr0
054 exit 0
055 fi
057 #Make sure account isn't blank
058 if [ -z $account ]
059 then
060 tput bold
061 tput setaf 1
062 echo "Need an account name!"
063 tput sgr0
064 helptext
065 #Else, start doing work
066 else
067 tput bold
068 tput setaf 4
069 echo "Fixing perms for $account:"
070 tput setaf 3
071 echo "------------------------"
072 tput setaf 4
073 echo "Fixing website files...."
074 tput sgr0
075 #Fix individual files in public_html
076 find /home/$account/public_html -type d -exec chmod $verbose 755 {} \;
077 find /home/$account/public_html -type f | xargs -r chmod $verbose 644
078 find /home/$account/public_html -name '*.cgi' -o -name '*.pl' | xargs -r chmod$verbose 755
079 chown $verbose -R $account:$account /home/$account/public_html/*
081 tput bold
082 tput setaf 4
083 echo "Fixing public_html...."
084 tput sgr0
085 #Fix perms of public_html itself
086 chown $verbose $account:nobody /home/$account/public_html
087 chmod $verbose 750 /home/$account/public_html
089 tput bold
090 tput setaf 4
091 echo "Fixing mail perms...."
092 tput sgr0
093 #Pass to cPanel's scripts to fix mail permissions
094 if [ -z $verbose ]
095 then
096 /scripts/mailperm --skiplocaldomains --skipmxcheck --skipserverperm $account > /dev/null
097 else
098 /scripts/mailperm --verbose --skiplocaldomains --skipmxcheck --skipserverperm $account
099 fi
100 tput bold
101 tput setaf 3
102 printf "Finished!\n\n"
103 tput sgr0
104 fi
106 return 0
107 }
109 #Parses all users through cPanel's users file
110 all () {
111 cd /var/cpanel/users
112 for user in *
113 do
114 fixperms $user
115 done
116 }
118 #Main function, switches options passed to it
119 case "$1" in
121 -h) helptext
122 ;;
123 --help) helptext
124 ;;
125 -v) verbose="-v"
127 case "$2" in
128 --all) all
129 ;;
130 --account) fixperms "$3"
131 ;;
132 -a) fixperms "$3"
133 ;;
134 *) tput bold
135 tput setaf 1
136 echo "Invalid Option!"
137 helptext
138 ;;
139 esac
140 ;;
141 --all) all
142 ;;
143 --account) fixperms "$2"
144 ;;
145 -a) fixperms "$2"
146 ;;
147 *)
148 tput bold
149 tput setaf 1
150 echo "Invalid Option!"
151 helptext
152 ;;
153 esac

Finally, as you’ve no doubt noted from the directions above, fixperms is a script run from the command line. If you’re a ServInt customer and think you’d benefit from this script but are unfamiliar with command line server administration, just open up a ticket in your customer portal and we’ll be happy to help.

Photo by orkomedix

Find out more about ServInt solutions

Starting at $25

  • Hosting Advice
  • The New York Times
  • The Hill
  • Bloomberg
  • The Seattle Times
  • Computer World
  • Ars Technica

To engage with the ServInt Sales Team use the following chat icon. Normal sales hours are Monday-Friday 9am-5pm EST but feel free to leave a message and we will follow up as soon as possible.

Sales Chat

To engage with the ServInt Support Team you must be logged into our Customer Portal for identity verification and have a ticket opened about your request or there will only be limited support offered.

Support Chat