Linux permissions are quite simple once told whats going on. You have a few ways of managing things on a Linux system:
UNIX style permissions
- Traditional permissions affecting the User that owns the file, Group, and Others.
- These are represented either as the letter abbreviation ,U, G, O, or a number such as 770.
- These are normally sufficient for taking care of basic logisitics, but in advanced situations, other methods have been created to deal with complexities.
- Created by the US NSA for hardening the US government's infrastructure.
- Sadly, not much adoption outside of Red Hat products and their derivatives.
- When used properly, will stop anything you don't want dead in its tracks.
- Fairly complicated at times, and a bit of a learning curve to use effectively.
- Easier than you may think to use on Red Hat family OS's thanks to very good defaults and a suite of tools to manage, audit, and diagnose things.
- Access Control Lists for Linux
- On most distributions
- Not that difficult to learn
- Not as comprehensive as SELinux, but works wonders in conjunction with the other methods to fine tune things that work %99 the way you want, but need an augmentation on said rules for isolated cases.
UNIX STYLE PERMISSIONS
These are the oldest and simplest to wrap ones' head around. You have a file owner and group membership and then everyone else. A user can be a member of any group, and is not limited to one membership, but has a default one.
Now for the permissions, for each of the three identifications (User whom owns the file, Group membership, Others), you can set Read, Write, and eXecute flags. So if you want a file to have full on access by the owner and group and zero access rights to others, the permissions would look like this:
| Identifier | Access | Numerical Abbreviation | |:---|:---:|:---:| User|rwx|7 Group|rwx|7 Others|---|0
Directories are files too in Linux. So one might question executing a directory? In this case it means entry into and the ability to delve into subdirectories. Read and Write are pretty much self explanatory. Although a trick that can be put to use, for better or worse mind you, is a directory that cannot be read, but written to. That can work. And can be used against you by allowing overwriting of files if the permissions allow it (ownerships primarily).
The numerical representation is basic binary to decimal.
So we add up what we have, and voila, the number. Do this for all three identifications. Aboce we had 770, which means that User (7), Group (7) and Others (0) become 770.
A read only area and only writable and executable by root would be 444. Remember that root can do whatever you want, which is why its frowned upon to be working as root, mistakes can happen.
SEEING THE PERMISSIONS AND OWNERSHIPS
To see the permissions and ownerships, any GUI file manager will show this somewhere in the file/folder properties. But the terminal command ls will do this too:
$ ls -l /home/ total 24 drwx--x---+ 203 andrew andrew 12288 Feb 13 19:49 andrew drwxr-xr-x. 20 makerpm makerpm 4096 Sep 22 2015 makerpm drwxr-xr-x. 15 makerpm makerpm 4096 May 4 2018 rpmbuid $
So we can see Red Hat has default permissions on home directories of 755, meaning one can enter and see things, but not modify to anyone other than the User (note the missing w's in the group and other fields?) Also note that andrew is locked down a bit more. As this is a workstation, some defaults will differ, and on an internet facing server, those would not be a good setup in my opinion. 770 or 700 would be better on the home directory itself.
CHANGING THE PERMISSIONS
So ether of the following commands will assign the permissions as described above:
$ chmod ug=rwx,o=rwx /path/to/file $ chmod 770 /path/to/file
chmod using the first example above sets things to equal. But you can add or remove them by the doing the following
# Block all access to file from others $ chmod o-rwx /path/to/file # Add read access to file from others $ chmod o+r /path/to/file # Doing both the above will allow reading on a file (second command) and prohibits write and execute (first command's leftovers)
To change the file's ownership, you must be able to read and write to the file first, but a sudo (linux) or doas(OpenBSD) can be used to elevate permissions if need be. But once that is achieved
$ chown user:group /path/to/file
A umask is the user mask, or in non-UNIX speak, the defaults that a directory will have. So if you follow my advice and decide to opt into paranoia, Others should have zero access to that which they do not NEED. So a 660 is a sane start. To set that permission as a default, you can umask the directory.
So, as in networking the mask is going to be the opposite of what we want. We are blocking bits out by force here, similar to how a network mask is defining the network bits versus the node bits.
So if we want a default permission of 700, for example. That boils down to add things up to 7. So if we have a desired default permission on a directory of 775, the mask would be 002.
On Red Hat, the default configuration of Apache web server is to point at /var/www/html/ and be owned apache:apache. So since the system really only needs the owner to write to it normally (php can modify this behavior, and why I hate php with a passion), group same, and others nothing (read would be fine if you want a regular user to see whats there, but not muck around), you could use a permissions of 660 or 770 (for php to allow scripting, remember that that difference is the execute flag). So a 117 or 007 umask would be needed. To set this:
$ sudo umask 117 /var/www/html $ sudo umask 007 /var/www/html
Note, this is an example. On a real webserver, SELinux would be put to use too, to further lock things down. But this is a good start. /home, /etc/, and /var have rather nice SELinux rules to aid in keeping things sane. But in reality, slacking too much in any area, will cause headaches.
Linux (and UNIX, and BSD) are great examples of tools that really work great, if you take your time and do it right. Spending 5 minutes pondering on groups and permissions will save more time fixing things than that 5 minutes that you may have skipped.
USER GROUP ASSIGNMENTS
To check a user's goups (or even yourself)
$ groups USERNAME $ groups
To add a user to a group that exists
$ sudo usermod -a -G GROUP USERNAME
To change a user's primary group
$ sudo usermod -g GROUP USERNAME
To create a new group and add a user to it
$ sudo usermod -G GROUP USERNAME
To remove user from secondary group
$ sudo gpasswd -d USER GROUP
To change a file's group assignment
$ chgrp GROUP FILENAME
To force a folder to only use a particular group for new files
$ chgrp -R GROUP /path/to/folder $ chmod g+s /path/to/folder # All files now in that folder are owned by GROUP and new ones will be too.
Be paranoid. If you dont need to allow access, don't. If you are unsure you can use 660 as your default.
If you need to share files with others, but not all others, create a group and set the group sticky bit (g+s). Add yourself and the others to the new group.
Groups can be created, and should be for group tasks. If you are interested in sharing media files over the network, or via a USB HDD, set them to be owned as yourself:new_media_group and 2750 (group sticky bit). For example, this can be done to lock out young children from watching violent films. Set the restricted movies in one group, the children's ones in another and only give the youngins group access to the youngins' group, others get both (come on, Princess Bride is awesome and made for youngins, and most appreciated by adults). For example the following is a simple way of having a set of parents and two kids have a split media library that is secured based off of group membership and basic Linux permissions:
$ mkdir /media/children $ groupadd childrensmovies $ chgrp -R childrensmovies /media/children $ chmod g+s /movies/children $ mkdir /media/movies $ groupadd movies $ chgrp -R movies /media/movies $ chgrp g+s /media/movies $ chown -R PARENT /media/ # Set to rwx on the owner, rx for group, nada for others $ chmod -R 750 /media/ $ usermod -a -G movies PARENT_1 $ usermod -a -G movies PARENT_2 $ usermod -a -G childrensmovies PARENT_1 $ usermod -a -G childrensmovies PARENT_2 $ usermod -a -G childrensmovies CHILD_1 $ usermod -a -G childrensmovies CHILD_2 # Child gets grounded gpasswd -d CHILD_1 childrensmovies
Stay tuned. This one is a fun one to write sofar ...