Hi I have a python script which modifies an application configuration file. To applied this, I need to restart the application. To do that I call a init.d file. But I need to be root when I do this action otherwise the application cannot bind her on the port. Also I dont want execute all my python script with the root's privileges. How can I execute the restart with the root privileges and then remove them.
I set the user permission at the beginning with:
if __name__ == "__main__":
uid = pwd.getpwnam('ubuntu')[2]
os.setuid(uid)
app.run(host='0.0.0.0', port=5001, debug=True)
and at the end of my script I need to execute:
commands.getoutput('/etc/init.d/webapplication restart')
webapplication binds on the port 80.
If I execute my script with this configuration, webapplication cant start and return a message, "cannot bind socket on the 80".
Any idea? to have a clean solution to execute only one external command with the root privileges on a Debian server under a python script?
Thansk in advance.
P.S: I have tried to use the same method like in my main function and I have replaced the user "ubuntu" by "root" but it's not work.
You can use either of two approaches:
Create a program whose only job is to run the init.d script, and make it setuid root. (Make sure to write it securely!). The main script runs with ordinary user permissions and calls the runner.
There's no way for a program to escalate its own privileges (except by running sudo, which is at least as expensive as approach 1), but a program running as root can de-escalate itself. So you can do some steps as root and then continue as the normal user by setting your uid down to the real uid. This won't be any help if you need root privileges for the last thing the program does, though.
Finaly to reach my goal, I have use the sudo solution. To do that on a debian server:
apt-get install sudo
Edit: /etc/sudoers
Add line: my_user(uses for the setuid) ALL = NOPASSWD : /etc/init.d/webapplication
And in my python script:
commands.getoutput('sudo /etc/init.d/webapplication restart')
And that works.
Related
I have written a python script that downloads deb files from launchpad, and then calls out to a shell script to use alien to convert the debs to rpms.
The shell script uses alien, and so it needs to be run as root.
The program uses a thread pool to download the deb files asynchronously, using threadpool.apply_async, and then uses a processing pool to call the shell script asynchronously, so the whole thing happens reasonably quickly.
It all works well, but the shell script that calls alien needs to be root otherwise packages don't get built properly. When I first finished the script, I would use pkexec to call alien, after using sudo. In both cases, I had a couple of problems.
The first was that in starting in root, I lost the environment of the user, and so lost the pip installed python libraries. I could, perhaps, have used sudo -s or similar, but the second problem was that I had to enter my root password for every package that was built.
What I want to do, is to run the python script, qt gui and all, as a normal user, select which files to convert, and then hit the install button and only enter my superuser password once.
I decided to filter out the install parts of the python, which include the threaded download, and threaded call to the shell script, and then try and run those parts as root/superuser.
I created a dbus service, for this install part, and, after a steep dbus learning curve, managed to get the service working. However, I had no joy getting the script authenticated, and raising its privileges.
I have been able to use polkit to show the password dialog and authorise the super user, but I do not know how to use the return value from polkit
`authority.CheckAuthorization(subject, action_id, details, flags, cancellation_id)`
which shows the password dialog, for authorisation, but does not handle elevating the scripts privileges.
I have set the python install service as 0500 perms, so that hopefully, once I have figured out how to elevate privileges, the root user has the ability to read and execute the service, which is currently created on the session bus.
How can I elevate permissions, and, at the same time, keep the environment variables of the user, so that I don't have to install python modules into the root account?
Many thanks for your help in advance...
ps. I have written a polkit action file, and a polkit rule, but in each case I am not sure how the action id relates to the elevation of privileges.
pps. Can I/should I use pam?
I eventually ran the process as root, using pkexec to obtain a password dialog.
I'm looking to create a script in python that initiates an SSH session with a server. I know it has to be a simple process i'm just not sure where to start. My ultimate plan is to automate this script to run on startup. i am not even sure python is the best way to go i just know it comes preloaded on raspbain for the pi.
A simple bash script would be better suited to the task. It is possible with python, but there's no obvious reason to make it harder than necessary.
From
write a shell script to ssh to a remote machine and execute commands:
#!/bin/bash
USERNAME=someUser
HOSTS="host1 host2 host3"
SCRIPT="pwd; ls"
for HOSTNAME in ${HOSTS} ; do
ssh -l ${USERNAME} ${HOSTNAME} "${SCRIPT}"
done
From how do i run a script at start up (askubuntu):
You will need root privileges for any the following. To get root, open
a terminal and run the command
sudo su
and the command prompt will change to '#' indicating that the terminal
session has root privileges.
Alternative #1. Add an initscript.
Create a new script in /etc/init.d/myscript.
vi /etc/init.d/myscript
(Obviously it doesn't have to be called "myscript".) In this script,
do whatever you want to do. Perhaps just run the script you mentioned.
#!/bin/sh
/path/to/my/script.sh
Make it executable.
chmod ugo+x /etc/init.d/myscript
Configure the init system to run this script at startup.
update-rc.d myscript defaults
Alternative #2. Add commands to /etc/rc.local
vi /etc/rc.local
with content like the following.
# This script is executed at the end of each multiuser runlevel
/path/to/my/script.sh || exit 1 # Added by me
exit 0
Alternative #3. Add an Upstart job.
Create /etc/init/myjob.conf
vi /etc/init/myjob.conf
with content like the following
description "my job"
start on startup
task
exec /path/to/my/script.sh
Depending on what you do with the ssh connection, if it needs to stay open over the entire up time of the device, you will need to use some more trickery however (ssh connections are autoclosed after a period of inactivity).
I've written a python script. One of the functions opens a port to listen on. To open a port to listen on I need to do it as super user. I don't want to run the script with sudo or with root permissions, etc. I saw an answer here regarding sub-process using sudo. It's not a sub-process I want as far as I know. It's just a function within the application.
Question: How do I programmatically open a port with super user permissions?
You can't do that. If you could then malicious code would have free access to any system as root at any time!
If you want super user privileges you need to run the script from the root account or use sudo and type in the password - this is the whole point of having user accounts.
EDIT
It is worth noting that you can run bash commands from within a python script - for example using the subprocess module.
import subprocess
subprocess.run(['sudo', 'blah'])
This essentially creates a new bash process to run the given command.
If you do this your user will be prompted to enter their password in the same way as you would expect, and the privileges will only apply to the subprocess that is being created - not to the script that you are calling it from (which may have been the original question).
You could use sudo inside your python script like this, so you don't have to run the script with sudo or as root.
import subprocess
subprocess.call(["sudo", "cat", "/etc/shadow"])
I need this command to run automatically on boot or when told to. At the moment i need to run the command in SSH and leave the session open, otherwise it stops.
python CouchPotatoServer/CouchPotato.py
This is on a ReadyNAS (Debian 7)
One easy way to do this would be to create it as a service. Take a look in /etc/init.d and you will find scripts that run as services. Copy one and modify it so that it calls your python script. An good example could be the init script used for starting the avahi daemon. Now, you can use 'service couchPotato start/stop/status', etc. It will also start the service automatically at boot time if the server ever reboots. Find a simple file to use as your template and google init scripts for further assistance. Good luck.
From this page:
To run on boot copy the init script. sudo cp CouchPotatoServer/init/ubuntu /etc/init.d/couchpotato
Change the paths inside the init script. sudo nano /etc/init.d/couchpotato
Make it executable. sudo chmod +x /etc/init.d/couchpotato
Add it to defaults. sudo update-rc.d couchpotato defaults
CouchPotatoServer/init/ubuntu can be found here
sudo update-rc.d <service> <runlevels> is the official Debian way of inserting a service at startup. Its manpage can be read there.
my 2 cents,
Use chkconfig to add the service and specify the run level. Google will give you all you need for examples of how to do this. Good luck.
Is it possible to create a raw socket without root privileges? If not, can a script elevate its privileges itself?
I wrote a Python script using a raw socket:
#!/usr/bin/env python
import socket
rawSocket = socket.socket(socket.PF_PACKET, socket.SOCK_RAW, socket.htons(0x0800))
print "Worked!"
Running it with root privileges prints Worked!. However, it gives an error when run with normal user privileges.
I want to execute my script as a normal user, and it should create a raw socket without asking for anything. Is it possible?
As you noted raw sockets require higher privilege than a regular user have.
You can circumvent this issue in two ways:
Activating the SUID bit for the file with a command like chmod +s file and set its owner to root with chown root.root file. This will run your script as root, regardless of the effective user that executed it. Of course this could be dangerous if your script has some flaw.
Setting the CAP_NET_RAW capability on the given file with a command like setcap cap_net_raw+ep file. This will give it only the privileges required to open a raw socket and nothing else.
EDIT:
As pointed out by #Netch the given solutions will not work with any interpreted language (like Python). You will need some "hack" to make it work. Try googling for "Python SUID", you should find something.
There is not a way for an unprivileged process (Python or otherwise) to elevate their own privileges. It's kind of the cornerstone of having this whole privileged/unprivileged users thinga-ma-jig. In regards to raw sockets, from manual page raw(7):
Only processes with an effective user ID of 0 or the CAP_NET_RAW capability are allowed to open raw sockets.
User ID of 0 means root. See here for info about raw sockets on linux.
As pointed out in Faust's answer/comments you won't be able to directly set the CAP_NET_RAW capability for your python program, due to it being a script that gets executed by the Python interpreter, but there may be solutions out on the web that can get around this limitation.
You can also go another path and set up the application using the sudoers file, then run it via sudo
Or my preferred option is just to compile it with Nuitka, then it runs like any other executable and can be assigned run as root etc