Drop root privileges after binding to server port

This commit is contained in:
Henri 2020-12-05 14:39:44 +01:00
parent ebcecf8394
commit e51938b617
2 changed files with 19 additions and 8 deletions

View File

@ -68,13 +68,18 @@ def chown(username, path):
uid = pwd.getpwnam(username).pw_uid uid = pwd.getpwnam(username).pw_uid
os.chown(path, uid, -1) os.chown(path, uid, -1)
def drop_privileges(uid_name='nobody', gid_name='nogroup'): def get_uid_gid(uid_name='nobody', gid_name='nogroup'):
"""""" """Returns uid and gid for the given username and groupname"""
if not is_root():
raise ValueError('No privileges present to drop')
uid = pwd.getpwnam(uid_name).pw_uid uid = pwd.getpwnam(uid_name).pw_uid
gid = grp.getgrnam(gid_name).gr_gid gid = grp.getgrnam(gid_name).gr_gid
# os.setgroups([]) # remove group privileges return uid, gid
def drop_privileges(uid_name='nobody', gid_name='nogroup'):
"""Drop privileges towards the given username and groupname"""
if not is_root():
raise ValueError('No privileges present to drop')
uid, gid = get_uid_gid(uid_name, gid_name)
os.setgroups([]) # remove group privileges
os.setgid(gid) os.setgid(gid)
os.setuid(uid) os.setuid(uid)
@ -168,8 +173,6 @@ def setup_environment():
print(f'8d) Ensuring ownership of server private key file {cfg.sslkeyfile} in case it exists.') print(f'8d) Ensuring ownership of server private key file {cfg.sslkeyfile} in case it exists.')
if os.path.exists(cfg.sslkeyfile): if os.path.exists(cfg.sslkeyfile):
chown(cfg.user, cfg.sslkeyfile) chown(cfg.user, cfg.sslkeyfile)
print(f'9) Dropping root privileges to user/group "{cfg.user}".')
drop_privileges(cfg.user, cfg.user)
print(f'Attempting to start web frontend...') print(f'Attempting to start web frontend...')
return cfg return cfg

View File

@ -10,6 +10,7 @@ import string
import subprocess import subprocess
from . import pwdtools from . import pwdtools
from . import setupenv
from . import wgcfg from . import wgcfg
@ -133,7 +134,14 @@ def run_webapp(cfg):
cherrypy.config.update({'server.socket_host': '0.0.0.0', cherrypy.config.update({'server.socket_host': '0.0.0.0',
'server.socket_port': 8080, 'server.socket_port': 8080,
}) })
cherrypy.quickstart(app, '/', app_conf) cherrypy.tree.mount(app, config=app_conf)
if setupenv.is_root():
# Drop privileges
uid, gid = setupenv.get_uid_gid(cfg.user, cfg.user)
cherrypy.process.plugins.DropPrivileges(cherrypy.engine, umask=0o022, uid=uid, gid=gid).subscribe()
cherrypy.engine.start()
cherrypy.engine.signals.subscribe()
cherrypy.engine.block()
if __name__ == '__main__': if __name__ == '__main__':