From cab89dc4c14ab8b11488c1974c75323661def3ed Mon Sep 17 00:00:00 2001 From: quietsy Date: Fri, 22 Sep 2023 21:24:57 +0300 Subject: [PATCH 1/2] Add auth to the proxies table --- root/dashboard/swag-proxies.py | 50 ++++++++++++++++++++++++++-------- root/dashboard/www/index.php | 12 ++++++-- 2 files changed, 49 insertions(+), 13 deletions(-) diff --git a/root/dashboard/swag-proxies.py b/root/dashboard/swag-proxies.py index 059c5bb0..16b1fe66 100644 --- a/root/dashboard/swag-proxies.py +++ b/root/dashboard/swag-proxies.py @@ -7,9 +7,16 @@ import socket import urllib3 +PROXY_REGEX = r"\s+set \$upstream_app (?P\S+?);.*\n(\s+)set \$upstream_port (?P\d+);.*\n(\s+)set \$upstream_proto (?P\w+);.*" +AUTHELIA_REGEX = r"\n\s+include \/config\/nginx\/authelia-location\.conf;.*" +AUTHENTIK_REGEX = r"\n\s+include \/config\/nginx\/authentik-location\.conf;.*" +BASIC_AUTH_REGEX = r"\n\s+auth_basic.*" +LDAP_REGEX = r"\n\s+include \/config\/nginx\/ldap-location\.conf;.*" + def find_apps(): apps = {} + auths = collections.defaultdict(dict) file_paths = glob.glob("/config/nginx/**/**", recursive=True) auto_confs = glob.glob("/etc/nginx/http.d/*", recursive=True) file_paths.extend(auto_confs) @@ -18,17 +25,36 @@ def find_apps(): continue file = open(file_path, "r") content = file.read() - results = re.finditer(r"(\s+)set \$upstream_app (?P\S+?);.*\n(\s+)set \$upstream_port (?P\d+);.*\n(\s+)set \$upstream_proto (?P\w+);.*", content) - for result in results: - params = result.groupdict() - app = f"{params['proto']}://{params['name']}:{params['port']}/" - if app not in apps: - apps[app] = set() - if file_path.startswith("/config/nginx/site-confs/") or file_path.endswith(".conf"): - file_path = "auto-proxy" if file_path.startswith("/etc/nginx/http.d/") else file_path - apps[app].add(file_path) - return apps + match_proxy(content, file_path, apps) + match_auth(apps, auths) + return apps, auths + +def match_proxy(content, file_path, apps): + results = re.finditer(PROXY_REGEX, content) + for result in results: + params = result.groupdict() + app = f"{params['proto']}://{params['name']}:{params['port']}/" + if app not in apps: + apps[app] = set() + if file_path.startswith("/config/nginx/site-confs/") or file_path.endswith(".conf"): + file_path = "auto-proxy" if file_path.startswith("/etc/nginx/http.d/") else file_path + apps[app].add(file_path) +def match_auth(apps, auths): + for app, file_paths in apps.items(): + for file_path in file_paths: + file = open(file_path, "r") + content = file.read() + if re.findall(AUTHELIA_REGEX, content): + auths[app][file_path] = "Authelia" + elif re.findall(AUTHENTIK_REGEX, content): + auths[app][file_path] = "Authentik" + elif re.findall(BASIC_AUTH_REGEX, content): + auths[app][file_path] = "Basic Auth" + elif re.findall(LDAP_REGEX, content): + auths[app][file_path] = "LDAP" + else: + auths[app][file_path] = "No Auth" def is_available(url): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) @@ -45,7 +71,7 @@ def is_available(url): urllib3.disable_warnings() -apps = find_apps() +apps, auths = find_apps() discovered_apps = collections.defaultdict(dict) with concurrent.futures.ThreadPoolExecutor(max_workers=100) as executor: futures = {executor.submit(is_available, app): app for app in apps.keys()} @@ -55,5 +81,7 @@ def is_available(url): continue discovered_apps[app]["status"] = future.result() discovered_apps[app]["locations"] = list(apps[app]) + discovered_apps[app]["auths"] = list(f"{path} - {auth}" for path, auth in auths[app].items()) + discovered_apps[app]["auth_status"] = all(auth != "No Auth" for auth in auths[app].values()) print(json.dumps(discovered_apps, sort_keys=True)) diff --git a/root/dashboard/www/index.php b/root/dashboard/www/index.php index 64478b3e..309e0e24 100644 --- a/root/dashboard/www/index.php +++ b/root/dashboard/www/index.php @@ -63,14 +63,21 @@ function GetProxies() { if (!empty($data->locations)) { $locations = $data->locations; $location = implode(",", $locations); - $status .= ''.$location.''; + $status .= ''; + $auths = implode(PHP_EOL, $data->auths); + if ($data->auth_status == 1) { + $status .= ''; + } else { + $status .= ''; + } + $status .= ''.$location.''; } else { $error = 'Unable to locate the proxy config for '.$result.', it must use the following structure:'.PHP_EOL; $error .= ' set $upstream_app ;'.PHP_EOL; $error .= ' set $upstream_port ;'.PHP_EOL; $error .= ' set $upstream_proto ;'.PHP_EOL; $error .= ' proxy_pass $upstream_proto://$upstream_app:$upstream_port;'.PHP_EOL; - $status .= ''; + $status .= ''; } $status .= ''; $index++; @@ -85,6 +92,7 @@ function GetProxies() {

Application

Available

Proxied

+

Auth

Location

From b5fb66d9a36275c1548edd19591de377e547e746 Mon Sep 17 00:00:00 2001 From: quietsy Date: Fri, 22 Sep 2023 21:54:00 +0300 Subject: [PATCH 2/2] A bit of refactoring --- root/dashboard/swag-proxies.py | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/root/dashboard/swag-proxies.py b/root/dashboard/swag-proxies.py index 16b1fe66..0e6182dc 100644 --- a/root/dashboard/swag-proxies.py +++ b/root/dashboard/swag-proxies.py @@ -25,11 +25,10 @@ def find_apps(): continue file = open(file_path, "r") content = file.read() - match_proxy(content, file_path, apps) - match_auth(apps, auths) + match_proxy(apps, auths, content, file_path) return apps, auths -def match_proxy(content, file_path, apps): +def match_proxy(apps, auths, content, file_path): results = re.finditer(PROXY_REGEX, content) for result in results: params = result.groupdict() @@ -39,22 +38,19 @@ def match_proxy(content, file_path, apps): if file_path.startswith("/config/nginx/site-confs/") or file_path.endswith(".conf"): file_path = "auto-proxy" if file_path.startswith("/etc/nginx/http.d/") else file_path apps[app].add(file_path) + match_auth(auths, app, file_path, content) -def match_auth(apps, auths): - for app, file_paths in apps.items(): - for file_path in file_paths: - file = open(file_path, "r") - content = file.read() - if re.findall(AUTHELIA_REGEX, content): - auths[app][file_path] = "Authelia" - elif re.findall(AUTHENTIK_REGEX, content): - auths[app][file_path] = "Authentik" - elif re.findall(BASIC_AUTH_REGEX, content): - auths[app][file_path] = "Basic Auth" - elif re.findall(LDAP_REGEX, content): - auths[app][file_path] = "LDAP" - else: - auths[app][file_path] = "No Auth" +def match_auth(auths, app, file_path, content): + if re.findall(AUTHELIA_REGEX, content): + auths[app][file_path] = "Authelia" + elif re.findall(AUTHENTIK_REGEX, content): + auths[app][file_path] = "Authentik" + elif re.findall(BASIC_AUTH_REGEX, content): + auths[app][file_path] = "Basic Auth" + elif re.findall(LDAP_REGEX, content): + auths[app][file_path] = "LDAP" + else: + auths[app][file_path] = "No Auth" def is_available(url): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)