Unix Groups

From DreamHost

Jump to: navigation, search
The instructions provided in this article or section require shell access unless otherwise stated.

You can use the PuTTY client on Windows, or SSH on UNIX and UNIX-like systems such as Linux or Mac OS X.
Your account must be configured for shell access in the Control Panel.
More information may be available on the article's talk page.

Unix groups are used for file sharing, and that is it. They are not normally used for anything else.

Contents

Creating Groups

To create a group, go to Users > Unix Groups in the Web Panel. Everything there should be self-explanatory. Please note that when adding users, they will be assigned to a default group (in the form of pg######).

Sharing Files between Groups

To share files or to share website access, first create a group (or use the default one if you don't mind all of your users having access). Next, sign in to SSH/shell. Go to the directory you want to share, and do:

chgrp -R new_group /home/user/directory

to change the group of that folder. To access the folder from other users, they will need to sign in to the shell and then CD to the shared folder. That's it! For more control over group permissions, just change the permissions of the group of the file. See Unix File Permissions.

Caveat: if you have any .cgi files, the above command will make them fail to run and generate HTTP 500 errors. Be sure that you leave the group for the .cgi and its parent directory as the default group. That is, if your .cgi file is in /home/joe/example.com/cgi/fun.cgi then the following directories/files must be joe's default group: /home/joe/example.com/cgi, /home/joe/example.com/cgi/fun.cgi.

DreamHost Security Defaults

When you add a user, it is automatically added to your default pg###### group. Another thing to note is that by default, all of your files are of the same default pg###### group unless you changed it yourself. This means that any other users that you have in the Web Panel have (read) access to all of your files. If you do not trust your users, follow the instructions below.

Protecting your files from other members of your group

Option 1: chgrp

To keep other members of your group out of your stuff, you can create a new group in the panel, and add only yourself to the group. Then change the group of all of your files that you want to protect:

chgrp -R my_group /home/user/directory

The down side to this is that you have to chgrp any new files when they are created in order to continue protecting them.

Option 2: chmod g-x

To keep everyone from your group out, you can also use this method. Simply remove execute permissions from the directory you want to protect:

chmod g-x /home/user/directory

The down side to this is that you have to remember to do this for every folder that you create, and have to remember not to do it to any of your web folders

Option 3: SetGID bit

Set the GID bit on your root folder and any already existing folders:

chgrp -R <my_group> ~/
find ~/ -xdev -user <username> -group <my_group> -type d -print -exec chmod +s {} \;

Line one of this changes the group ownership of all 'files' and 'folders' (within your home folder ~/) to the specified <my_group>.

Line two 'sets the GID bit' for all the 'folders' within your home folder and it's sub-folders. (In particular, it modifies all that are owned by the specified <my_group> which should be all of them if the command from line one was executed successfully.) Setting the GID bit on a folder changes it such that subsequently any folders or files created within it will be owned by the specified <my_group>.

The down side to this is that if the group of a folder is ever changed, it loses the GID flag and anything under that folder will now be created with your default (pg#######) group again. (When is this likely to happen?)

Option 4: Cron job

To effectively change your default group and make sure that anything new created is in that group, create a cron job that runs the setperms.sh script every hour or so.

Create your new group in the DreamHost Control Panel. Once your group has been created, SSH into your account and verify that you are a member of the group by typing

groups

and seeing if your new group is listed in the results.


Protect your webfolder appropriately

chmod 751 <webfolder>


Create the setperms.sh file in your home folder

setperms.sh

#!/bin/bash

LOCKFILE=$HOME"/.set-permissions.lock"
ABORT=0
NEEDSHELP=0

Usage()
{
        echo "Usage: $0 -g <group> -p <group> -u <user>"
        echo "          -w <folder> [[-w <folder>] ...]"
        echo " -g|--group <group>       The group to chgroup your files to"
        echo " -p|--primary <group>     The group that files must have to be chgrouped"
        echo " -u|--user <user> The user you are running as. The user must"
        echo "                  be a member of both groups specified."
        echo " -w|--web <folder>        The foldername of your web directory that must be"
        echo "                  world readable. You must specify at least one folder,"
        echo "                  but may specify any number of folders to be"
        echo "                  accessable from the web"
        ABORT=1
}

ParseCommandLine()
{
        echo "Parsing..."
        # Parse the command line
        if [ $# -eq 0 ]; then
                NEEDSHELP=1
        fi

        i=0
        while [ -n "$1" ]; do
                case $1 in
                        "-g" | "--group")
                                [ -n "$2" ] || Usage
                                GROUP=$2
                                shift
                                ;;
                        "-h" | "--help")
                                NEEDSHELP=1
                                shift
                                ;;
                        "-p" | "--primary")
                                [ -n "$2" ] || Usage
                                PRIMARYGROUP=$2
                                shift
                                ;;
                        "-u" | "--user")
                                [ -n "$2" ] || Usage
                                USERNAME=$2
                                shift
                                ;;
                        "-w" | "--web")
                                [ -n "$2" ] || Usage
                                WEBFOLDER[$i]=$2
                                i=$i+1
                                shift
                                ;;
                        *)
                                Usage;;
                esac
                shift
                if [ $ABORT -eq 1 ]; then
                        return
                fi
        done

        if [ ${NEEDSHELP} -lt 1 ]; then
                if [ -z $GROUP ]; then
                        echo "You must specify a group (-g)"
                        NEEDSHELP=1
                fi

                if [ -z $PRIMARYGROUP ]; then
                        echo "You must specify a primary group (-p)"
                        NEEDSHELP=1
                fi

                if [ -z $USERNAME ]; then
                        echo "You must specify a user (-u)"
                        NEEDSHELP=1
                fi

                if [ -z $WEBFOLDER ]; then
                        echo "You must specify at least one webfolder (-w)"
                        NEEDSHELP=1
                fi
        fi
}

ValidateGroups()
{
        echo "Validating group memberships"
        # Check the primary group
        groups ${USERNAME} | grep "${PRIMARYGROUP}" 2>&1 > /dev/null
        if [ $? -gt 0 ]; then
                echo "User ${USERNAME} is not a member of ${PRIMARYGROUP}"
                ABORT=1
        fi

        # Check the target group
        groups ${USERNAME} | grep "${GROUP}" 2>&1 > /dev/null
        if [ $? -gt 0 ]; then
                echo "User ${USERNAME} is not a member of ${PRIMARYGROUP}"
                ABORT=1
        fi
}

RunCommands()
{
        # Deal with stuff in the webfolders first
        for W in $WEBFOLDER
        do
                echo "Setting file permissions in web folder ${W}"
                find ~/$W -xdev -user ${USERNAME} -group ${PRIMARYGROUP} -not -type d -print -exec chmod o+r,o-w {} \; -exec chgrp ${GROUP} {} \;
                echo "Setting folder permissions in web folder ${W}"
                find ~/$W -xdev -user ${USERNAME} -group ${PRIMARYGROUP} -type d -print -exec chmod o+x,o-wr {} \; -exec chgrp ${GROUP} {} \;
        done

        # Change anything in the primary group to the new group
        echo "Setting group membership on items currently in group ${PRIMARYGROUP}"
        find ~/ -xdev -user ${USERNAME} -group ${PRIMARYGROUP} -not -type l -not -print -exec chmod o-rwx {} \; -exec chgrp ${GROUP} {} \;

        # Cleanup any messes we may have made
        chmod o+x .
        chmod u+x,g-wx,o-wx $0
        for W in $WEBFOLDER
        do
                chmod o+x $W
        done
}

Main()
{
        # Make sure that we're the only instance of the script running
        if [ -e $LOCKFILE ]
        then
                echo "Either another instance of this script is running or you need to remove the $LOCKFILE file"
                exit 0
        fi
        touch $LOCKFILE

        ParseCommandLine "$@"

        if [ ${NEEDSHELP} -eq 0 ]; then
                # All the parameters were there, now make sure they're valid
                ValidateGroups
        fi

        if [ ${NEEDSHELP} -eq 0 ]; then
                # Run the commands
                echo "Running the commands"

                RunCommands $0
        elif [ ${ABORT} -lt 1 ]; then
                Usage
        fi

        # Remove the temporary lockfile
        rm $LOCKFILE
}

Main "$@"

Make sure that the file is in Unix mode (rather than DOS mode) so that weird things don't happen

dos2unix setperms.sh


Chmod the setperms.sh script so that you can execute it and no one else can

chmod 700 setperms.sh


Chgrp the setperms.sh script to something other than your default (pg#######) group

chgrp <newgroup> setperms.sh


Run the script for the first time to get everything set up properly and make sure it's working. This will probably take a long while to run the first time as it will touch just about, and will print out all of the files and folders that it is making changes to.

./setperms.sh -g <newgroup> -p <primary group, pg#######> -u <username> -w <webfolder>

For example

./setperms.sh -g fred -p pg1234567 -u fred -w fred.com

If you have multiple web folders, you can put additional -w <webfolder> statements on the end

Setup the cron job

crontab -e


Install the script to run every hour or so, and to dump all of the output to the garbage

0 * * * * /home/fred/setperms.sh -g fred -p pg1234567 -u fred -w fred.com >/dev/null 2>&1

If you want the results to be emailed to you every time the script runs:

MAILTO=<your@email.address>
0 * * * * /home/fred/setperms.sh -g fred -p pg1234567 -u fred -w fred.com

If you want the results to be emailed to you once a day:

MAILTO=<your@email.address>
0 * * * * /home/fred/setperms.sh -g fred -p pg1234567 -u fred -w fred.com >> /home/fred/setperms.log 2>&1
1 1 * * * cat /home/fred/setperms.log
2 1 * * * rm -rf /home/fred/setperms.log

Timings

I've run this in a few different sites, and the CPU time is not too bad, as long as it's not being run more than every 30-45 minutes. Sample timings:

#files |    743   |   1961   |    6709   |   19878   |   31302   |   31477   |
-------|----------|----------|-----------|-----------|-----------|-----------|
  real | 0m2.600s | 0m6.427s | 0m48.321s | 1m48.668s | 4m39.025s | 4m41.896s |
  user | 0m0.050s | 0m0.120s |  0m0.090s |  0m0.170s |  0m0.460s |  0m0.570s |
   sys | 0m0.130s | 0m0.060s |  0m1.230s |  0m0.950s |  0m3.630s |  0m3.710s |
-----------------------------------------------------------------------------/

This is for runs with no files/folders that needed changing. As the number of files/folders that have to be modified increases, so will the timings.

Details

This script traverses your entire structure looking for and doing the following things:

Order | Looking for               | Action if found
------|---------------------------------------------------------------
  1   | In each webfolder, a      | Remove world write, add world
      | file, your username,      | read, make group the new group
      | primary group (pg####),   | 
------|---------------------------------------------------------------
  2   | In each webfolder, a      | Remove world read and write, add
      | folder, your username,    | world execute, make group the
      | primary group (pg####),   | new group.
------|---------------------------------------------------------------
  3   | From your home, a file    | Remove world read, write, execute,
      | or folder, your username, | world execute, make group the
      | primary group (pg####),   | new group.
------|---------------------------------------------------------------
  4   | On your home folder       | Add world execute
------|---------------------------------------------------------------
  5   | On the script             | Add owner execute, remove group
      |                           | and world write and execute
------|---------------------------------------------------------------
  6   | On each webfolder         | Add world execute
------|---------------------------------------------------------------

Pros & Cons

Pros

  • Anything that is created by your user from anywhere (ssh, sftp, ftp, etc.) is treated as "new" by the script and processed. Anything that has a group membership other than your primary (pg#######) group is treated as "old" and left alone. This means that you know that anything new you create will within the hour be assigned the correct group and permissions to be secure, but that if you want one particular item (file or folder) to have a non-default group or permissions it won't be messed with.
  • Doesn't care what your umask is set at, it sets the permissions to properly protect the private files and properly serve the web-accessable ones.

Cons

  • This script has 3 find commands in it, two of which are executed once for each web folder that you have. If you've got lots of web folders, this could potentially add up and might not be a viable way to go.
  • The initial run takes quite a long time, even with under 800 files it still took close to a minute.
  • Ignores your umask. (Well, it fits on both sides, what do you want?)
  • Requires shell access for each account
Personal tools