The Python implementation changes the current process running user on the Linux system

  • 2020-04-02 14:33:39
  • OfStack

In this article, we talked about how to write a daemon in python on Linux. The main principle is to use the Linux fork function to create a process, and then exit the parent process to run, the generated child process will become a daemon. Careful observation may reveal that the running identity of the daemon is the user executing the program. If the daemon is added to the service item of the system, the executing identity of the daemon should be root.

In one case, root has more privileges, and it is more dangerous to operate through the daemon of root identity. A good approach is to generate a master process with the identity of root to accept the request and a number of woker processes to handle the request, so that there is no over-privilege problem. In fact, a lot of software today, nginx, mysql, apache, VSFTPD, etc., almost always does this.

So how do you change the running identity of a child process in Linux? In fact, Linux provides such a function, let's take a look at the python code:


#!/usr/bin/env python
import time,os,pwd,sys,signal
logfile="/tmp/d2.log"
#step one, get the username you want to running with
try:
    user=sys.argv[1]
except:
    user=raw_input('Please input a username in this machine you want to run this program: ')
if user=="":sys.exit(-1)
try:
    uid=pwd.getpwnam(user)
    uid=uid.pw_uid
except:
    print "Uer not exists!"
    sys.exit(-1)
#step two:Generation of daemon
pid=os.fork()
if(pid):sys.exit(0)
os.setsid()
os.chdir("/")
os.umask(0)
#step three :fork again
pid=os.fork()
if(pid==0):
    os.setuid(uid)
    os.setsid()
    os.chdir("/")
    os.umask(0)
log=open(logfile,'a')
log.write('Daemon start up at %sn'%(time.strftime('%Y:%m:%d',time.localtime(time.time()))))
log.close()
def reload(a,b):
  log=open(logfile,'a')
  log.write('Daemon reload at %sn'%(time.strftime('%Y:%m:%d',time.localtime(time.time()))))
  log.close()
while True:
  signal.signal(signal.SIGHUP,reload)
  time.sleep(2)

Run this program, type nginx (nginx is the added user in the system), and then use ps aux|grep python to view the python programs running in the system. You can see that the identity of one woker process has changed to become nginx:


[root@home ~]# ps aux|grep python
root   1139 0.0 0.5  5288 2372 ?    Ss  22:40  0:00 python ./d2.py nginx
nginx   1140 0.0 0.5  5288 2360 ?    S  22:40  0:00 python ./d2.py nginx
root   1151 0.0 0.1  2336  648 pts/0  S+  22:50  0:00 grep python

Since the process with the identity of nginx is used to handle the request, some permissions belonging to the root will not be invoked by the process. It can also limit the process to operate a single file by setting the permissions of the file, so as to achieve better permission control effect and reduce security risks.


Related articles: