I'm very inexperienced when it comes to UNIX privileges. I have a Python script that starts some other Python scripts and also other programs like tcpdump. All those processes are started via subprocess.Popen, some of the programs are opened in terminals (via the x-terminal-emulator -e option).
Some of the scripts/programs need to be started as root, however. I have tried to split up the whole functionality in smaller scripts and only use sudo when it's necessary. Now my problem is that my setup requires me to enter my root password like 3 or 4 times everytime I start up the whole thing.
What I am looking for is a way to enter my password once when I start the original script, but only grant actual root permissions at specified places in my scripts. Can anyone help me out? :)
One way of doing this is to start as root, fork all sub-processes and then drop your privileges in the (sub-)processes that don't need the privileges.
For an example, see here
There are some other suggestions as well in the same post.
Related
I am writing a python administrative daemon on linux that needs to start/stop other services. Following the principle of least privilege, I want to run this normally with regular user privileges but when it needs to start/stop other services, I want it to become root. Essentially I want to do what sudo would do from the command line. I cannot directly exec sudo from the daemon because it has no tty. I want to avoid running the daemon as root when it does not need to run as root. Is there any way to do this from python without needing to use sudo?
Thank you in advance.
Ranga.
In this case I have a flask back end that needed to do something privileged. I broke it up into two back ends - one unprivileged and another small privileged piece rather than use sudo.
It is also possible to run sudo in a pty but I decided against this approach as it does indeed have a security flaw.
I wrote a simple script that parses some stuff off the web and emails it to me. Very simple. But I'm starting to realize that implementing this is going to be far more difficult that it really should be.
All I really want to do is run this script once a day.
I have explored using Google App Engine, but it doesn't like smtplib using ssl to login to my gmail to send an email.
I am considering using Heroku, but that just seems like a lot of work for something so simple.
I tried using my raspberry pi, but I'm not sure the script is still running when I exit ssh. I looked into running the scrip on a cron job, but I'm not sure thats an elegant solution.
I looked into running an applescript from my calendar, but I'm not sure what happens if my computer is closed and/or offline.
My question is: Is there a simple, elegant, easy solution here?
When you start the script from your session (./script.py or python script.py) than it stops running when you disconnect. If you want to run the script this way for whatever reason, I would recommend using tmux .
If you're using Raspian or another Debian based distro for your Pi:
$ apt-get install tmux
$ tmux
# disconnect from your tmux session with pressing CTRL+B and (after that) D
# to reattach to your session later, use
$ tmux attach
I would recommend using cron. Just add a file like this in /etc/cron.d/, if you want to run it at a specific time (e.g. every day at 1am), like so:
$ echo "0 1 * * * python /path/to/your/script.py > /dev/null 2>&1" > /etc/cron.d/script-runner
# and don't forget to make it executable
$ chmod +x /etc/cron.d/script-runner
Wikipedia has a nice explanation of the format (and also of shortcuts like #hourly and #daily).
If you don't care when exactly it runs, you can just put your script into /etc/cron.daily/. Don't forget a chmod +x to make it executable.
If you don't want to run it on one of your machines, you can also get a shell on one of uberspaces servers. You can pay whatever you wan't (minimum 1 Eur/month) and you get a shell on a linux box with 10GB storage (the first month is free for testing, cancelation happens automatically when you don't pay, no strings attached). I'm sure there are a lot of other services like that, I just mention it, because it's a cheap one with nice support. Also you get a domain (..uberspace.de) and can send mail from the server (e.g. with mail). So no need to use a gmail account.
Edit: Overread the "python" part. Changed everything to .py. Either use #!/usr/bin/env python3 (or 2.7) in your script or start the script via python scriptname.py.
I have a small problem running a python script as a specific user account in my CentOS 6 box.
My cron.d/cronfile looks like this:
5 17 * * * reports /usr/local/bin/report.py > /var/log/report.log 2>&1
The account reports exists and all the files that are to be accessed by that script are chowned and chgrped to reports. The python script is chmod a+r. The python script starts with a #!/usr/bin/env python.
But this is not the problem. The problem is that I see nothing in the logfile. The python script doesn't even start to run! Any ideas why this might be?
If I change the user to root instead of reports in the cronfile, it runs fine. However I cannot run it as root in production servers.
If you have any questions please ask :)
/e:
If I do sudo -u reports python report.py it works fine.
Cron jobs run with the permissions of the user that the cron job was setup under.
I.E. Whatever is in the cron table of the reports user, will be run as the reports user.
If you're having to so sudo to get the script to run when logged in as reports, then the script likely won't run as a cron job either. Can you run this script when logged in as reports without sudo? If not, then the cron job can't either. Make sense?
Check your logs - are you getting permissions errors?
There are a myriad of reasons why your script would need certain privs, but an easy way to fix this is to set the cron job up under root instead of reports. The longer way is to see what exactly is requiring elevated permissions and fix that. Is it file permissions? A protected command? Maybe adding reports to certain groups would allow you to run it under reports instead of root.
*be ULTRA careful if/when you setup cron jobs as root
I have a python script which is performing some nagios configuration. The script is running as a user which has full sudo rights (the user can run any command with sudo, without password prompt). The final step in the configuration is this:
open(NAGIOS_COMMAND_FILE, 'a').write(cmdline)
The NAGIOS_COMMAND_FILE is only writable by root, so this command should be run by root. I can think of two ways of achieving this (both unsatisfactory):
Run the whole script as root. I do not like doing this, since any error in my script will be executed with full root rights.
Put the open(NAGIOS_COMMAND_FILE, 'a').write(cmdline) command in a separate script, and use the subprocess library to call that script, with sudo. I do not like creating an extra script just to run a single command.
I suppose there is no way of changing the running user just for a single command, in my current script, or am I wrong?
Why don't you give write permission on NAGIOS_COMMAND_FILE to your user who have all sudo rights?
Never, ever run a web server as root or as a user with full sudo privileges. This isn't a pythonic thing, it is a "keep my server from being pwned" thing.
Look at os.seteuid, the "principle of least privilege", and man sudoers and run your server as regular "httpd-server" where "httpd-server" has sudoer permission to write to NAGIOS_COMMAND_FILE. And then be sure that what you write to the command file is as clean as you can make it.
It is actually possible to change user for a single command.
Fabric provides a way to log in as any user to a server. It relies on ssh connections I believe. So you could connect to localhost with a different user in your python script and execute the desired command.
http://docs.fabfile.org/en/1.4.3/api/core/decorators.html
Anyway, as others have already precised, it is best to allow the user running the script permission to execute this one command and avoid relying on root for execution.
I would agree with the post above, either give your user write perms to the NAGIOS_COMMAND_FILE or add that use to a group that has those permissions, like nagcmd.
Part of my python program needs administrator access. How can I gain root privileges using a GUI popup similar to the gksudo command?
I only need root privileges for a small part of my program so it would be preferable to only have the privileges for a particular function.
I'm hoping to be able to do something like:
gksudo(my_func, 'description of why password is needed')
gksudo can be used to launch programs running with administrator privileges. The part of your application that needs to run as root, must be able to be invoked as a separate process from the command line. If you need some form of communication between the two, you could use sockets or watch for a file, etc.
You have two options here:
You will need to make the part of the program that requires root privileges a separate file and then execute the file like this:
>>> import subprocess
>>> subprocess.call(['gksudo','python that_file.py'])
which will bring up the password prompt and run that_file.py as root
You could also require that a program be run as root from the start and just have the program user type "gksudo python your_program.py" in the command-line from the start which is obviously not the best idea if your program is normally launched from a menu.