I'd like to build a web interface like ISPConfig, cPanel, Webmin that would allow me to administer my server using a web browser, for example: after clicking a button on a web page a "dnf update' command would be sent to the server and the server would be updated.
While the web interface itself might not be a big problem, building an engine for it that would be able to receive and execute the commands would.
A solution i'm thinking of now would be to build a Python program that would create and read a named pipe from one unprivileged user and then execute the commands. I'm a beginner in Python and this is a great opportunity for me to learn more.
Here's what i've come up with so far:
#!/usr/bin/python3
import os
import sys
import atexit
import platform
# The UID ang GID of the pipe file to be owned by.
TARGET_UID=1000
TARGET_GID=1000
# Set up the FIFO
PIPE_FILE = 'comms.fifo'
### FUNCTION BLOCK ###
def check_OS():
"""Checking if the program is running on Linux."""
OS=platform.system()
if OS != "Linux":
print("This service can only run on Linux! It will be stopped now.")
quit()
def if_exists_FILE(FILE):
"""Check if a file is accessible/exists."""
try:
with open(FILE, encoding='utf-8') as f:
f.close()
except FileNotFoundError:
return False
return True
def exec_CMD(CMD):
"""Executes system command based on the permissions the program runs with. It's assumed that the command has already been filtered for security."""
print(f"\x1b[6;30;42m" + f">>>> COMMAND START : \"{CMD.strip()}\" <<<<" + "\x1b[0m")
os.system(CMD.strip())
print(f"\x1b[6;30;42m" + f">>>> COMMAND END : \"{CMD.strip()}\" <<<<" + "\x1b[0m" + "\n")
def prep_FIFO(PIPE_FILE):
"""Creates the named pipe and sets permissions."""
os.mkfifo(PIPE_FILE,0o600)
# Ownership of the pipe needs to be changed so that normal users
# can send stuff to it.
os.chown(PIPE_FILE, TARGET_UID, TARGET_GID)
### FUNCTION BLOCK ###
check_OS()
# Remove the PIPE_FILE if it already exists to avoid errors on the program's startup.
if if_exists_FILE(PIPE_FILE):
print("Pipe file already exists and it's going to be removed.")
os.remove(FILE)
prep_FIFO(PIPE_FILE)
# Make sure to clean up after ourselves
def cleanup_PIPE():
os.remove(PIPE_FILE)
atexit.register(cleanup_PIPE)
print ("Waiting for commands.")
# Go into reading loop
while True:
with open(PIPE_FILE, 'r') as FIFO:
for LINE in FIFO:
exec_CMD(LINE)
I need it to run on Linux, be secure and be made according to best practices and so on. I can't just let the commands be received and blindly executed. I should find out how to run it properly as a Linux daemon, so it should be able to log messages/errors etc.
I hope i am going the right way with this.
Thank you in advance for all tips, thoughts.
Aucun commentaire:
Enregistrer un commentaire