Linux - SecurityThis forum is for all security related questions.
Questions, tips, system compromises, firewalls, etc. are all included here.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Not sure if umask would be covered under security section, but anyway, here is my situation:-
In my environment, we have two servers A and B running RHEL 5.2.
Server B will transmit file to server A via rcp (and I know about scp/ssh etc. but for our project, we are limited to rcp/rsh). The trick now is that whatever that is rcp over from B to A, it should only be readable by the owner i.e. read-only.
Given the setup as follow:-
User = system
User Home Directory = /DATASTORE/DATA/
User Backup Directory = /DATASTORE/DATA/BACKUP
User Working Directory = /DATASTORE/DATA/ACTIVE
I've read about umask and to get what I want, I read that I should set the umask for all xinetd services in /etc/xinetd.conf to my desired value, which would be 0377 i.e. read-only by owner.
There's one problem I see here. What happen if I rcp over a directory with files? From my observation, I noticed that the directory is created and umask applied, BUT the files can't be copied over due to permission denied. Is there something I can do to overcome this?
Another problem is that the user system should be able remote login from Server B to A and perform some copy/move/edit operation ONLY in /DATASTORE/DATA/ACTIVE folder. Bascially, I want the umask for this folder to be 077. Is this possible?
umask doesn't provide separate ones for directories and files.
Quote:
Originally Posted by Chaosbreaker
Bascially, I want the umask for this folder to be 077. Is this possible?
Setting directories, or at least the top level one, to have octal 1700 would mean only the user can access and modify files it owns. But maintaining these disparate umask settings, confusing kludge it is due to conflicting requirements, will be a nightmare and as far as I know there's no way to propagate or keep the sticky bit on subdirectory creation, not even with 'setfacl'. The only way out I can see to control it would be to script something triggered by inotify or audit watches.
umask doesn't provide separate ones for directories and files.
Setting directories, or at least the top level one, to have octal 1700 would mean only the user can access and modify files it owns. But maintaining these disparate umask settings, confusing kludge it is due to conflicting requirements, will be a nightmare and as far as I know there's no way to propagate or keep the sticky bit on subdirectory creation, not even with 'setfacl'. The only way out I can see to control it would be to script something triggered by inotify or audit watches.
Thanks for the tip on inotify. I read up, set it up and got it to work the way I want to. I do have another question about inotify though. Is it possible for me to use the event DELETE to stop an actual file/folder from getting deleted? I haven't tried it yet and now looking into it, so hoping any additional guidance would speed up my resolution.
The reason I asked is that now a similar situation with two folders - one folder I allow rm and rmdir to be run, but the other folder, I want to disallow it. My initial setup removes the use of these commands for a user A totally, so the command is not available for use by the user period. However, if I allow the use of these commands, then the user can remove files/folders as they pleases anywhere, which is undesirable. So I just wondered about using the inotify DELETE event and if it is able to help me stop the delete event or perhaps do a file restoration? If not, is there any other way?
I love my conflicting requirements.... really cracking my brain.
Thanks for the tip on inotify. I read up, set it up and got it to work the way I want to.
Could you please outline your solution? It would complete this thread perfectly and others who find this thread may benefit from it. TIA!
Quote:
Originally Posted by Chaosbreaker
now a similar situation with two folders - one folder I allow rm and rmdir to be run, but the other folder, I want to disallow it (..) Is it possible for me to use the event DELETE to stop an actual file/folder from getting deleted?
This is about DAC permissions and system calls. Creating and deleting entities require write rights on the parent directory (modify meta data) so for instance a 0500 directory won't allow creation but no deletion either so that's no solution. Syscalls (create, unlink) drive creation and deletion but Inotify only "intercepts" syscalls for logging purposes. In Linux 2.4 we had syscalltrack to intercept and stop syscalls but we don't have that kind of mechanism for Linux 2.6 AFAIK. Another way would be intercepting syscalls by preloading a library but that needs to be attached to the process and it doesn't allow for granular control. Another way could be a path-based MAC like TOMOYO (or maybe Apparmor?) but that needs configuration and I don't know yet how TOMOYO would handle recursion wrt configuration entities. Even wilder may be versioning or overlay file systems but I don't have enough experience with those. In short I can't think of a way that isn't cumbersome, contrived or convoluted.
Quote:
Originally Posted by Chaosbreaker
(..) or perhaps do a file restoration?
Restoration is a completely different topic IMO. See libtrash or (rsync-based?) backup solutions?
Could you please outline your solution? It would complete this thread perfectly and others who find this thread may benefit from it. TIA!
There's good news and bad news. The good news that it worked well as I mentioned...initially. After setting it up, I issued commands locally to verify that the permissions were changed as desired, and it did. For the benefit of others, this is what I did:-
1) Ran two inotifywait to capture CREATE and CLOSE_WRITE events.
Code:
inotifywait -mrq -e CREATE --format %w%f /DATASTORE/DATA/BACKUP | while IFS= read -r FILE; do chmod 770 "$FILE"; done &
-> Upon file or folder creation in /DATASTORE/DATA/BACKUP, set the permission to 550 i.e. read-write-execute for owner and group
Code:
inotifywait -mrq -e CLOSE_WRITE --format %w%f /DATASTORE/DATA/BACKUP | while IFS= read -r FILE; do chmod 440 "$FILE"; done &
-> This would be applicable for files only. When a file is closed after it was opened for writing, set the permission to 440 i.e. read-only for owner and group
Works well when commands issued locally. The two commands can even be scripted and set up as boot-up scripts, and what I found out further is that instead of using the -m option (monitor), using -d (daemon) will automatically run the command in the background, and an additional parameter --outfile need to be specified to determine where the runtime logs will be saved to. Very nice!
2) When I issued a remote copy (rcp) command to transfer a folder with multiple files, the result was inconsistent. On few occasion it would be successful to set the permissions correctly, but most of the time, there would be at least be one file that did not get its permission updated. I read several sources, and found something in the man (man inotifywait).
"There are race conditions in the recursive directory watching code which can cause events to be missed if they occur in a directory immediately after that directory is created. This is probably not fixable."
This is exactly is what happening in my case, and WILL be a very common scenario. In short, inotify is great but for my implementation, it is not viable.
I'm at this juncture looking back at my very first most primitive and simplest approach - cron job a script that would regularly (say every 2 seconds) alter the permission for the directory and files accordingly. My only concern is whether when a file is currently opened for writing and the script fired, would the file permission gets changed? I don't feel it would since the file is currently opened for writing. If it does however, it may be a problem since the file is no longer writable before even it is transferred completely over.
Quote:
Originally Posted by unSpawn
This is about DAC permissions and system calls. Creating and deleting entities require write rights on the parent directory (modify meta data) so for instance a 0500 directory won't allow creation but no deletion either so that's no solution. Syscalls (create, unlink) drive creation and deletion but Inotify only "intercepts" syscalls for logging purposes. In Linux 2.4 we had syscalltrack to intercept and stop syscalls but we don't have that kind of mechanism for Linux 2.6 AFAIK. Another way would be intercepting syscalls by preloading a library but that needs to be attached to the process and it doesn't allow for granular control. Another way could be a path-based MAC like TOMOYO (or maybe Apparmor?) but that needs configuration and I don't know yet how TOMOYO would handle recursion wrt configuration entities. Even wilder may be versioning or overlay file systems but I don't have enough experience with those. In short I can't think of a way that isn't cumbersome, contrived or convoluted.
I actually thought of one thing. Not sure if there would be any issue until I tried it out. My idea is to script a new rm specifically for use by the user. The new rm script would check if the command is issued to a file in the /DATASTORE/DATA/BACKUP folder. If yes, script would exit. Otherwise, it would call the original rm command to remove.
I drafted a simple one first:
Code:
#! /bin/bash
# version 0.1
# Limitation:-
# 1) Only works for one file at the moment
# 2) When * (or *.xxx, xxx.* etc.) is supplied, first file seen is used
# 3) Currently does not filter options (not sure if this will be needed or can be omitted)
# This is the directory where rm command is not allowed
CTRL_DIR="/DATASTORE/DATA/BACKUP"
FILE_DIR=`dirname $(readlink -f $1)` # This need to be updated once multiple file
# handling is done
echo "Parameters = $@"
echo "The file $1 resides in $FILE_DIR"
if [ $FILE_DIR == $CTRL_DIR ]; then
echo "You are NOT allowed to issue removal commands in $FILE_DIR;
echo "This incident will be reported";
echo "`date +%b' '%d' '%T` localhost `id -un` attempted to execute rm command in $FILE_DIR at `date`" >> /var/log/secure;
exit 1;
fi
/bin/rm $@
As I wrote this, I realized that the user would only be using the rm command in /DATASTORE/DATA/ACTIVE so instead of blocking the command in an if statement, I should just allow it in one if statement for the specific directory, and block the command for all other locations. As can be seen from the comments, I do have some work left to handle multiple files for wildcard options. If anyone has any contribution, do feel free to drop a post. I will share the completed script once is done, tested and stabilized.
Quote:
Originally Posted by unSpawn
Restoration is a completely different topic IMO. See libtrash or (rsync-based?) backup solutions?
This would work if it wasn't for the fact that the files in this situation are the 'local source' before even an internal backup occurs, so there isn't anything to rsync to except to the 'remote source', which unfortunately, does not allow incoming remote connections.
Last edited by Chaosbreaker; 12-09-2010 at 10:02 PM.
rm script - Block execution for files/folders not in allowed directory
Completed the script to control rm by blocking execution on all directories except the one listed in the variable ALLOWED_DIR.
Basically my setup is as follow:-
1. Created a folder /bin/system for user system. In this folder, I placed the script below.
2. I altered the PATH variable for user system to point only to /bin/system. Basically whatever commands I allow the user to run will be symbolic linked in this folder.
3. I set my ALLOWED_DIR in the script below to /DATASTORE/DATA/ACTIVE and created the folder with 770 permission, system:users ownership.
Works good so far but on top of the bugs mentioned in the script, I also noted a security flaw that I have not gotten down to think about on the resolution. Since the script below will invoke /bin/rm, it means that the user system would be able to directly access the command by typing /bin/rm and wreak havoc. I've set the script to executable-only to others and ownership set to root:root. Still, someone who dabbles in Unix/Linux would know where to try to find the original rm file and invoke it directly.
The first thing came to mind is to move the rm file elsewhere to a different folder. I just feel this isn't really the best solution but currently, I don't know how else to resolve this security issue. Hopefully someone can shed some ideas.
Code:
#! /bin/bash
# #########################################################################
# Filename : rm #
# Version : 0.2 #
# #
# Description #
# =========== #
# This script, when invoked, will supercede the rm command. It will block #
# the rm command execution unless the file(s) reside in the specified #
# allowed directory i.e. ALLOWED_DIR. #
# #
# Known Issue #
# =========== #
# 1. If recursive option is specified AFTER a folder argument, the #
# contents of the folder will NOT be removed. #
# e.g. rm.sh <folder-name> -r #
# 2. The logging to /var/log/secure does not work due to permission. #
# Changing permission to allow write for non-root users is not #
# advisable as the logs can be tampered with. Pending resolution. #
# #
# Changelog #
# ========= #
# Ver Date (DDMMYYYY) Author Remarks #
# --- --------------- ------ ----------------------------------------- #
# 0.1 09122010 Yusoff Created base script #
# 0.2 09122010 Yusoff Added rm option support for -r, -f and -v #
# Enhance initial design #
# ----------------------- END - OF - CHANGELOG -------------------------- #
# #########################################################################
# -----------------------------------------------------------------
# Start of script
if [ "$#" -lt 1 ] # No arguments supplied
then
printf "Usage: rm [OPTION]... FILE...\n"
printf "Remove (unlink) the FILE(s).\n\n"
printf " -f, --force ignore nonexistent files, never prompt\n"
printf " -r, -R, --recursive remove directories and their contents recursively\n"
printf " -v, --verbose explain what is being done\n"
exit 2
fi
# -----------------------------------------------------------------
# This is the directory where rm command is allowed
ALLOWED_DIR="/DATASTORE/DATA/ACTIVE"
OPTION_STR=
# Extract the non-option arguments, which would be the file(s) or folder
for arg in "$@"
do
if [[ $arg =~ '\-[fvr]' ]]
then
# do nothing
OPTION_STR=$OPTION_STR$arg" ";
else
# Perform removal if allowed
FILE_DIR=`dirname $(/usr/bin/sudo readlink -f $arg)`;
if [ $FILE_DIR == $ALLOWED_DIR ]; then
/bin/rm $OPTION_STR $arg;
else
# If we got here, it means the command was issued where it is not
# allowed to run by the user
echo "You are NOT allowed to issue removal commands in $FILE_DIR!";
echo "This incident will be logged.";
echo "`date +%b' '%d' '%T` localhost `id -un` attempted to execute rm command in $FILE_DIR at `date`" >> /var/log/secure;
fi
fi
done
# End of script
# -----------------------------------------------------------------
I'll probably try to work on inotify again and if I can get it to give consistent results, I'll work on the next script to alter the file/folder permission to be scheduled via cron before returning back to the above script. Will post updates tomorrow.
Last edited by Chaosbreaker; 12-09-2010 at 04:15 AM.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.