Running jailkit from non-root process - linux

I have a webserver which will frequently spawn a latex interpreter (written in python). This interpreter lives inside a chroot jail made using jailkit so it has to be started as root.
I don't want the server to run as root and I can't setuid the bash script. I could write a setuid c program that calls the script but I'm pretty sure that leads to big security holes.
The best I have come up with so far is running a separate webserver as root whose sole job is spawning interpreter processes.
What is the right way to do this?

Your best bet is to create a very small script which simply set the environment and calls the latex interpreter and make that script SUID root.
This is best because:
The least amount of time is spent as root
Just a single script needs to be SUID
Small script == smaller chance to do something wrong
BASH is pretty safe to use as root while running a whole web server is not.

Related

How to execute a script at the start and end of every application in Linux?

I am trying to log the applications that a user opens/closes in the Linux (any distro) OS. Is there a way to execute a script (Java,Python,etc) everytime an application (like firefox,etc) is opened and closed?
As a general feature -- no.
The execution of a script to log the execution, would in itself be a program execution which would require logging, and hence you would have a recursive problem.
However, if you want to log specific programs, you can implement a shell script which replaces the executable for those specific programs (firefox, python etc), and then within that shell script you could log the execution before calling the actual program.
However
The user would still be able to call the original program without the logging if they know the path.
The new scripts would be a security issue (making the system less secure) and hence would not be recommended.
So in short, a bad idea.
This is not a programming question, but still.
You can actually do this. See https://superuser.com/questions/222912/how-can-i-log-all-process-launches-in-linux
There are many answers. For example, you could use auditd.

Intricacies of Launching a complex shell script from CGI

Ok, so over the past year I have built some rather complex automation scripts (mostly bash, but with some perl here and there) for some of the more common work we do at my place of business. They rely heavily on ImageMagick, Ghostscript, and PhantomJS to name just a few. They also traverse a huge number of directories across the network and several different file systems and host OSs... Frankly the fact that they work is a bit of a miracle and perhaps a testament to my willingness to keep beating my head against the wall... Also, trust me, this is easier and more effective than trying to corral my resources. Our archives are... organic... and certain high-ranking individuals in the company think of them as belonging to them and do not look out for the interests of the company in their management. They are, at least, relatively well backed-up these days.
In any case these scripts automate the production of a number of image-based print-ready products of varying degrees of complexity up to multi-hundred page image-heavy books, and as such some of them accept absurdly complex argument structures to do all the things they do. (P.S. embedded Javascript in SVGS is a MAGICAL thing!) These systems have been in "working beta" for a while now, which basically means I've been hand entering the commands at a terminal to run them, and I want to move them up to production and offer them as a webservice so that those in production who are not friends with the command line can use them, and to also potentially integrate them with our new custom-developed order management system.
TL;DR below
so that's the background, the problem is this:
I'm running everything on a headless CentOS 6.4 virtual machine with SELINUX disabled.
Apache2 serves up my interface.sh CGI just fine, and the internet has already helped me make the POST data into shell variables. Now I need to launch the worker scripts that actually direct the heavy lifting and coordinate the binaries... from the CGI:
#get post data from form and make it into variables...
/bin/bash /path/to/script/worker.sh $arg1 $arg2 $arg3 $arg5 $arg6 $opt1 $arg7
Nothing.
httpd log shows permission denied, fair enough!
Ok, googling suggests that the script being called by the CGI must also be owned by the apache user and group, or by root with 755 permissions. Done!
now httpd log show permission denied for things worker.sh is trying to do :/
Google has lead me to believe that for security reasons fcgi requires that everything interacted with by the CGI process chain must have correctly controlled permissions, all the way down to the binaries and source files... Sure, this is smart for security and damage control, but almost impossible in my case. We have very dynamic data and terabytes of resources... :/
the script worker.sh exports its own environment and runs all it's commands as root. This is largely to overcome the minefield of permissions disasters that I have to contend with and CentOS's own paranoia about allowing stuff to happen. I had hoped this might be a work around, but no.
One suggestion I have seen is to simply write out the composed command to a text file and have cron or incron do something with the text file. Seems like that would work... BUT, I'd love to be able to get STDIO back into my web page as there are verbose errors and notifications (though no interaction) in many of these worker scripts, and I would like to provide notification of completion as well. Is there any way to do this that doesn't require a permissions war to be waged?
To run certain commands as another user, you can use sudo.
Set up sudo to allow passwordless access to run your command by the apache user. Then you can have the CGI script call sudo /path/to/script args to run it as root (or -u for another user of your choice).
It's very hard to make this secure, so you should make sure your CGI script is only accessible by trustworthy individuals.

Script killing too long process

I'm a webhosting owner, I don't know why currently, but I have some php scripts that are launched for many hours (as personnaly known customers), so I think there is a bug somewhere.
These scripts are eating the RAM AND the swap... So I'm looking for a way to list processes, find the execution time, kill them 1 by 1 if the execution exceed 10 or 20 minutes.
I'm not a bash master, but I know bash and pipes. The only thing I don't know, is how to list the processes (with execution time AND complete command line with arguments). Actually, even in top (then c) there is no arguments in php :/
Thanks for your help.
If you are running Apache with mod_php, you will not see a separate PHP process since the script is actually running inside an Apache process. If you are running as FastCGI, you also might not see a distinguishable PHP process for the actual script execution, though I have no experience with PHP/FastCGI and might be wrong on this.
You can set the max_execution_time option, but it is overridable at run time by calling set_time_limit() unless you run in Safe Mode. Safe mode, however, has been deprecated in PHP 5.3 and removed in 5.4, so you cannot rely on it if you are on 5.4 or plan to upgrade.
If you can manage it with your existing customers (since in some cases it requires non-trivial changes to PHP code), running PHP as CGI should allow you to monitor the actual script execution, as each CGI request will spawn a separate PHP interpreter process and you should be able to distinguish between the scripts they are executing. Note, however, that CGI is the least effective setup (the others being mod_php and FastCGI).
You can use the ps -aux command to list the processes with some detailed information.
You can also check out the ps man page.
This might also be of some help.

mount without sudo using sticky bit?

I am trying to write a shell script to mount loop device, and I am assigning this script with a sticky bit to execute as uid(root).(this is for other users on server) The problem is I can't seem to run 'mount' command without using sudo in front of it. When I am in root account, I can run 'mount' command without any issue, so I thought by setting script with rws-r_x-r_x would do it.
Am I misunderstanding the concept of using sticky bit? or is there any other way?
The server is running under Ubuntu 10.04
You mean the setuid bit, not the sticky one. The kernel doesn't honor the setuid bit on scripts. See this post for a thorough description, here's a summary: the gist is that suid on a script is insecure.* The kernel starts reading the script to execute it, but it sees the #!/path/to/interpreter and figures out that it needs to be interpreted. It then cancels "executing" the script directly and calls the specified interpreter, passing the script name as the first argument (and all subsequent arguments in order after that). The reason setting UID is insecure in this instance is that an attacker could potentially change the script to be executed between the kernel setting the new UID and the interpreter reading the file.
*: The other post mentioned that perl handles its scripts in such a way that they can be suid.
As for the actual mounting problem at hand, add a line to /etc/fstab/ and include the user option.

Running a program as non root from a script

I have a question closely related to this thread:
Best practice to run Linux service as a different user
but I need the solution to work in "every" Linux distribution.
I would like to run a program as a non root user from a script. This way, when init.d starts up the services at boot time as root, the script launches the process as the non-root user I specify. Of course the solution shouldn't prompt for a password.
I think this is the normal/correct procedure when deploying applications.
How could I do that?
Thanks a lot
A good way would be to drop privileges from your actual program. Then just pass that user as a parameter. Inside you can handle it in a very standard way (setuid())
Otherwise su -c 'your command' different_user will work just fine on any linux. (as long as different_user exists)
There are two ways:
sudo command - you need to add the original user to /etc/sudoers with such entry that the program can be run without (NOPASSWD)
seteuid() system call (if you can modify the program)
If you are root, you can also use su (see #cnicutar's answer for details)

Resources