Add root_password setting, better locking robustness and fix dendrite issues
This commit is contained in:
parent
4c51b1bd0a
commit
2d3338b835
1 changed files with 126 additions and 49 deletions
|
|
@ -8,10 +8,48 @@ import json
|
||||||
CHANGES_REQUIRING_RESTART = ['wifi_password', 'ssid', 'enable_access_point', 'enable_chat', 'enable_deltachat', 'butterbox_hostname', 'ssh_access_settings', 'root_account_settings']
|
CHANGES_REQUIRING_RESTART = ['wifi_password', 'ssid', 'enable_access_point', 'enable_chat', 'enable_deltachat', 'butterbox_hostname', 'ssh_access_settings', 'root_account_settings']
|
||||||
|
|
||||||
def lock_root_account():
|
def lock_root_account():
|
||||||
result = run(["sudo", "passwd", "-l", "root"])
|
check_usr = run(["sudo", "passwd", "-S", "root"], capture_output = True, text = True)
|
||||||
if result.returncode != 0:
|
if ' L ' in check_usr.stdout:
|
||||||
|
print(f"Root account already locked")
|
||||||
return False
|
return False
|
||||||
return True
|
print(f"Root account not locked, trying to lock it.")
|
||||||
|
if not load_setting('root_password'):
|
||||||
|
print(f"Root account has no password, setting one before locking it.")
|
||||||
|
# password must be empty so we set it to be 'root' before locking the account
|
||||||
|
result_set_dummy_password = run(["sudo", "passwd", "-s", "root"], capture_output = True, text = True, input="root")
|
||||||
|
print(result_set_dummy_password)
|
||||||
|
if result_set_dummy_password.returncode !=0:
|
||||||
|
print(f"Issue setting dummy pass for root account")
|
||||||
|
print(result_set_dummy_password)
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
print(f"running the lock command now")
|
||||||
|
result_lock = run(["sudo", "passwd", "-l", "root"], capture_output = True, text = True)
|
||||||
|
if result_lock.returncode != 0:
|
||||||
|
print(f"Issue locking root account")
|
||||||
|
print(result_lock)
|
||||||
|
return False
|
||||||
|
print(f"Root account now locked.")
|
||||||
|
return True
|
||||||
|
|
||||||
|
def set_root_password(new_pass):
|
||||||
|
check_usr = run(["sudo", "passwd", "-S", "root"], capture_output = True, text = True)
|
||||||
|
if ' L ' in check_usr.stdout:
|
||||||
|
print(f"Root account locked, unlocking...")
|
||||||
|
unlock_result = run(["sudo", "passwd", "-u", "root"], capture_output = True, text = True)
|
||||||
|
if unlock_result.returncode != 0:
|
||||||
|
print(f"Issue unlocking root account")
|
||||||
|
print(unlock_result)
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
result = run(["passwd", "-s", "root"],capture_output = True, text = True, input=new_pass)
|
||||||
|
if result.returncode != 0:
|
||||||
|
print(f"Issue setting password for root account")
|
||||||
|
print(result)
|
||||||
|
return False
|
||||||
|
|
||||||
|
print(f"Root account password set successfully.")
|
||||||
|
return True
|
||||||
|
|
||||||
def enable_service(service: str):
|
def enable_service(service: str):
|
||||||
is_enabled = run(["sudo", "systemctl", "is-enabled", service], capture_output = True, text = True)
|
is_enabled = run(["sudo", "systemctl", "is-enabled", service], capture_output = True, text = True)
|
||||||
|
|
@ -26,6 +64,8 @@ def enable_service(service: str):
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
print(f"Service {service} already enabled")
|
print(f"Service {service} already enabled")
|
||||||
|
return False
|
||||||
|
print(f"Service {service} has been enabled.")
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def disable_service(service: str):
|
def disable_service(service: str):
|
||||||
|
|
@ -35,18 +75,23 @@ def disable_service(service: str):
|
||||||
return False
|
return False
|
||||||
if 'enabled' in is_enabled.stdout:
|
if 'enabled' in is_enabled.stdout:
|
||||||
enable = run(["sudo", "systemctl", "disable", service])
|
enable = run(["sudo", "systemctl", "disable", service])
|
||||||
|
print(enable)
|
||||||
if enable.returncode != 0:
|
if enable.returncode != 0:
|
||||||
print(f"issue disabling service {service}:")
|
print(f"issue disabling service {service}:")
|
||||||
print(enable)
|
print(enable)
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
print(f"Service {service} already enabled")
|
print(f"Service {service} already disabled")
|
||||||
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def load_setting(setting):
|
def load_setting(setting):
|
||||||
with open("./settings.txt", "r") as f:
|
with open("./settings.txt", "r") as f:
|
||||||
settings = json.load(f)
|
settings = json.load(f)
|
||||||
return settings[setting]
|
try:
|
||||||
|
return settings[setting]
|
||||||
|
except:
|
||||||
|
return None
|
||||||
|
|
||||||
def change_service_status(setting, service):
|
def change_service_status(setting, service):
|
||||||
if load_setting(setting) == "true":
|
if load_setting(setting) == "true":
|
||||||
|
|
@ -67,7 +112,7 @@ def change_keanu_weblite_config(new_hostname):
|
||||||
if match:
|
if match:
|
||||||
match_exists = True
|
match_exists = True
|
||||||
old_hostname = match.group(1)
|
old_hostname = match.group(1)
|
||||||
print(f"Old ostname {old_hostname}, new is {new_hostname}")
|
print(f"Old hostname {old_hostname}, new is {new_hostname}")
|
||||||
if old_hostname != new_hostname:
|
if old_hostname != new_hostname:
|
||||||
lines[i] = re.sub(old_hostname, new_hostname, lines[i])
|
lines[i] = re.sub(old_hostname, new_hostname, lines[i])
|
||||||
match_changed = True
|
match_changed = True
|
||||||
|
|
@ -94,8 +139,12 @@ def change_line_in_file(target_file: str, regex: str, replacement: str):
|
||||||
if not os.path.isfile(target_file):
|
if not os.path.isfile(target_file):
|
||||||
raise FileNotFoundError(f"File {target_file} does not exist")
|
raise FileNotFoundError(f"File {target_file} does not exist")
|
||||||
else:
|
else:
|
||||||
|
changed = False
|
||||||
with open(target_file, "r") as f:
|
with open(target_file, "r") as f:
|
||||||
lines = f.readlines()
|
lines = f.readlines()
|
||||||
|
if not lines:
|
||||||
|
print(f"File {target_file} empty")
|
||||||
|
return False
|
||||||
for i, line in enumerate(lines):
|
for i, line in enumerate(lines):
|
||||||
match = re.fullmatch(replacement, line)
|
match = re.fullmatch(replacement, line)
|
||||||
if match:
|
if match:
|
||||||
|
|
@ -104,14 +153,12 @@ def change_line_in_file(target_file: str, regex: str, replacement: str):
|
||||||
for i, line in enumerate(lines):
|
for i, line in enumerate(lines):
|
||||||
match = re.fullmatch(regex, line)
|
match = re.fullmatch(regex, line)
|
||||||
if match:
|
if match:
|
||||||
lines.pop(i)
|
lines[i] = replacement
|
||||||
break
|
changed = True
|
||||||
try:
|
|
||||||
lines.append(replacement)
|
|
||||||
except NameError:
|
|
||||||
raise NameError(f"File {target_file} is empty.")
|
|
||||||
return False
|
|
||||||
new_lines = "".join(lines)
|
new_lines = "".join(lines)
|
||||||
|
if not changed:
|
||||||
|
print(f"Can't match line: {regex}, adding it to the end of target file {target_file}!")
|
||||||
|
new_lines += replacement
|
||||||
with open(target_file, "w") as f:
|
with open(target_file, "w") as f:
|
||||||
print(f"Writing changed line to file {target_file}.")
|
print(f"Writing changed line to file {target_file}.")
|
||||||
f.write(new_lines)
|
f.write(new_lines)
|
||||||
|
|
@ -123,73 +170,103 @@ def check_settings(raspap_installed: bool):
|
||||||
return
|
return
|
||||||
last_modified = os.path.getmtime('./settings.txt')
|
last_modified = os.path.getmtime('./settings.txt')
|
||||||
diff_in_minutes = (datetime.now().timestamp() - last_modified)/60
|
diff_in_minutes = (datetime.now().timestamp() - last_modified)/60
|
||||||
if diff_in_minutes < 2:
|
needs_restart = False
|
||||||
|
if diff_in_minutes < 1:
|
||||||
for s in CHANGES_REQUIRING_RESTART:
|
for s in CHANGES_REQUIRING_RESTART:
|
||||||
print(f"Now at setting: {s}")
|
print(f"Now at setting: {s}")
|
||||||
if s == "wifi_password" and raspap_installed:
|
if s == "wifi_password" and raspap_installed:
|
||||||
regex_wpa_method = "wpa=.*?\n"
|
regex_wpa_method = "wpa=.*?\n"
|
||||||
if load_setting("wifi_password") == "":
|
if load_setting("wifi_password") == "":
|
||||||
change_line_in_file("/etc/hostapd/hostapd.conf", regex_wpa_method, f"wpa=none\n")
|
needs_restart = change_line_in_file("/etc/hostapd/hostapd.conf", regex_wpa_method, f"wpa=none\n") or needs_restart
|
||||||
else:
|
else:
|
||||||
change_line_in_file("/etc/hostapd/hostapd.conf", regex_wpa_method, f"wpa=3\n")
|
needs_restart = change_line_in_file("/etc/hostapd/hostapd.conf", regex_wpa_method, f"wpa=3\n") or needs_restart
|
||||||
regex_pass = "wpa_passphrase=.*?\n"
|
regex_pass = "wpa_passphrase=.*?\n"
|
||||||
change_line_in_file("/etc/hostapd/hostapd.conf", regex_pass,
|
needs_restart = change_line_in_file("/etc/hostapd/hostapd.conf", regex_pass,
|
||||||
f"wpa_passphrase={load_setting("wifi_password")}\n")
|
f"wpa_passphrase={load_setting("wifi_password")}\n") or needs_restart
|
||||||
|
|
||||||
if s == "ssid" and raspap_installed:
|
if s == "ssid" and raspap_installed:
|
||||||
regex_ssid = "ssid=.*?\n"
|
regex_ssid = "ssid=.*?\n"
|
||||||
change_line_in_file("/etc/hostapd/hostapd.conf", regex_ssid, f"ssid={load_setting("ssid")}\n")
|
needs_restart = change_line_in_file("/etc/hostapd/hostapd.conf", regex_ssid, f"ssid={load_setting("ssid")}\n") or needs_restart
|
||||||
if s == "enable_chat":
|
if s == "enable_chat":
|
||||||
change_service_status("enable_chat", "dendrite")
|
needs_restart = change_service_status("enable_chat", "dendrite") or needs_restart
|
||||||
if s == "enable_access_point" and raspap_installed:
|
if s == "enable_access_point" and raspap_installed:
|
||||||
change_service_status("enable_access_point", "raspapd")
|
needs_restart = change_service_status("enable_access_point", "raspapd") or needs_restart
|
||||||
if s == "enable_deltachat":
|
if s == "enable_deltachat":
|
||||||
change_service_status("enable_deltachat", "madmail")
|
needs_restart = change_service_status("enable_deltachat", "madmail") or needs_restart
|
||||||
if s == "butterbox_hostname":
|
if s == "butterbox_hostname":
|
||||||
# change in keanu-weblite compiled assets
|
# change in keanu-weblite compiled assets
|
||||||
new_hostname=f"{load_setting('butterbox_hostname')}.local"
|
new_hostname=f"{load_setting('butterbox_hostname')}.local"
|
||||||
print(f"Changing keanu weblite assets {change_keanu_weblite_config(new_hostname)}")
|
# result_keanu = change_keanu_weblite_config(new_hostname)
|
||||||
# change in butterbox-dendrite.conf
|
# print(f"Changing keanu weblite assets {result_keanu}")
|
||||||
regex_matrix_server = "server_name:.*?.local\n"
|
# # change in butterbox-dendrite.conf
|
||||||
result = change_line_in_file("../dendrite/butterbox-dendrite.conf", regex_matrix_server,
|
# regex_matrix_server = " server_name:.*?.local\n"
|
||||||
f"server_name: {load_setting("butterbox_hostname")}.local\n")
|
# result_matrix = change_line_in_file("../dendrite/butterbox-dendrite.conf", regex_matrix_server,
|
||||||
print(f"Changing dendrite config: {result}")
|
# f" server_name: {load_setting("butterbox_hostname")}.local\n")
|
||||||
|
# print(f"Changing dendrite config: {result_matrix}")
|
||||||
|
# change in /etc/hostname
|
||||||
|
|
||||||
|
print("Writing new hostname to /etc/hostname")
|
||||||
|
with open("/etc/hostname", 'w') as f:
|
||||||
|
f.write(load_setting('butterbox_hostname'))
|
||||||
|
f.write("\n")
|
||||||
|
# change in nginx.conf
|
||||||
|
regex_nginx_server = " server_name.*?.local;\n"
|
||||||
|
replacement = f" server_name {load_setting('butterbox_hostname')}.local;\n"
|
||||||
|
|
||||||
|
result_nginx = change_line_in_file("/etc/nginx/sites-available/default", regex_nginx_server, replacement)
|
||||||
|
needs_restart = needs_restart or result_nginx
|
||||||
|
|
||||||
# change in butterbox-dnsmasq.conf
|
# change in butterbox-dnsmasq.conf
|
||||||
if raspap_installed:
|
if raspap_installed:
|
||||||
regex_dns = "address=/.*?.local/10.3.141.1\n"
|
regex_dns = "address=/.*?.local/10.3.141.1\n"
|
||||||
result = change_line_in_file("/etc/dnsmasq.d/butterbox-dnsmasq.conf", regex_dns,
|
result = change_line_in_file("/etc/dnsmasq.d/butterbox-dnsmasq.conf", regex_dns,
|
||||||
f"address=/{load_setting("butterbox_hostname")}.local/10.3.141.1\n")
|
f"address=/{load_setting("butterbox_hostname")}.local/10.3.141.1\n")
|
||||||
print(f"Changing dnsmasq config: {result}")
|
print(f"Changing dnsmasq config: {result}")
|
||||||
|
needs_restart = needs_restart or result
|
||||||
if s == "ssh_access_settings":
|
if s == "ssh_access_settings":
|
||||||
if load_setting("ssh_access_settings") == "ssh_disabled":
|
if load_setting("ssh_access_settings") == "disable_ssh":
|
||||||
disable_service('ssh')
|
needs_restart = disable_service('ssh') or needs_restart
|
||||||
if load_setting("ssh_access_settings") == "enable_ssh_with_password":
|
if load_setting("ssh_access_settings") == "enable_ssh_with_root_password":
|
||||||
|
print("looking at the service")
|
||||||
|
needs_restart = enable_service('ssh') or needs_restart
|
||||||
|
print("now looking at the password line")
|
||||||
regex_password_auth = "PasswordAuthentication.*?\n"
|
regex_password_auth = "PasswordAuthentication.*?\n"
|
||||||
change_line_in_file("/etc/ssh/sshd_config", regex_password_auth,
|
needs_restart = change_line_in_file("/etc/ssh/sshd_config", regex_password_auth,
|
||||||
f"PasswordAuthentication yes\n")
|
f"PasswordAuthentication yes\n") or needs_restart
|
||||||
|
print("now looking at the permit login line")
|
||||||
regex_root_login = "PermitRootLogin.*?\n"
|
regex_root_login = "PermitRootLogin.*?\n"
|
||||||
change_line_in_file("/etc/ssh/sshd_config", regex_root_login,
|
needs_restart = change_line_in_file("/etc/ssh/sshd_config", regex_root_login,
|
||||||
f"PermitRootLogin yes\n")
|
f"PermitRootLogin yes\n") or needs_restart
|
||||||
elif load_setting("ssh_access_settings") == "enable_ssh_with_public_key":
|
# elif load_setting("ssh_access_settings") == "enable_ssh_with_public_key":
|
||||||
regex_password_auth = "PasswordAuthentication.*?\n"
|
# needs_restart = needs_restart or enable_service('ssh')
|
||||||
change_line_in_file("/etc/ssh/sshd_config", regex_password_auth,
|
# regex_password_auth = "PasswordAuthentication.*?\n"
|
||||||
f"PasswordAuthentication no\n")
|
# needs_restart = needs_restart or change_line_in_file("/etc/ssh/sshd_config", regex_password_auth,
|
||||||
regex_root_login = "PermitRootLogin.*?\n"
|
# f"PasswordAuthentication no\n")
|
||||||
change_line_in_file("/etc/ssh/sshd_config", regex_root_login,
|
# regex_root_login = "PermitRootLogin.*?\n"
|
||||||
f"PermitRootLogin prohibit-password\n")
|
# needs_restart = needs_restart or change_line_in_file("/etc/ssh/sshd_config", regex_root_login,
|
||||||
|
# f"PermitRootLogin prohibit-password\n")
|
||||||
|
# if load_setting('ssh_key'):
|
||||||
|
# regex_key = f"{load_setting('ssh_key')}\n"
|
||||||
|
# needs_restart = needs_restart or change_line_in_file("/home/root/.ssh/authorized_keys", regex_key,
|
||||||
|
# regex_key)
|
||||||
# append here new key!!!
|
# append here new key!!!
|
||||||
if s == "root_account_settings":
|
if s == "root_account_settings":
|
||||||
if load_setting("root_account_settings") == "lock_root_account":
|
setting = load_setting("root_account_settings")
|
||||||
lock_root_account()
|
print(setting)
|
||||||
else:
|
if setting == "lock_root_account":
|
||||||
# root password implementation here
|
needs_restart = lock_root_account() or needs_restart
|
||||||
pass
|
elif setting == "set_root_password":
|
||||||
|
if load_setting('root_password'):
|
||||||
|
print("will set root password...")
|
||||||
|
needs_restart = set_root_password(load_setting('root_password')) or needs_restart
|
||||||
|
if needs_restart:
|
||||||
|
print("I am restarting here")
|
||||||
|
run(["sudo", "reboot"])
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
raspap_installed = os.path.exists("/var/www/html/raspapd")
|
raspap_installed = os.path.exists("/var/www/html/raspapd")
|
||||||
while True:
|
while True:
|
||||||
print("sleep 10 sec")
|
print("Sleep 10 sec")
|
||||||
check_settings(raspap_installed)
|
check_settings(raspap_installed)
|
||||||
time.sleep(10)
|
time.sleep(10)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue