Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add auth to the proxies table #767

Merged
merged 2 commits into from
Sep 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 35 additions & 11 deletions root/dashboard/swag-proxies.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,16 @@
import socket
import urllib3

PROXY_REGEX = r"\s+set \$upstream_app (?P<name>\S+?);.*\n(\s+)set \$upstream_port (?P<port>\d+);.*\n(\s+)set \$upstream_proto (?P<proto>\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)
Expand All @@ -18,17 +25,32 @@ def find_apps():
continue
file = open(file_path, "r")
content = file.read()
results = re.finditer(r"(\s+)set \$upstream_app (?P<name>\S+?);.*\n(\s+)set \$upstream_port (?P<port>\d+);.*\n(\s+)set \$upstream_proto (?P<proto>\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(apps, auths, content, file_path)
return apps, auths

def match_proxy(apps, auths, content, file_path):
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)
match_auth(auths, app, file_path, content)

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)
Expand All @@ -45,7 +67,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()}
Expand All @@ -55,5 +77,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))
12 changes: 10 additions & 2 deletions root/dashboard/www/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,14 +63,21 @@ function GetProxies() {
if (!empty($data->locations)) {
$locations = $data->locations;
$location = implode(",", $locations);
$status .= '<i class="fas fa-check-circle"></i></td><td class="left-text"><span class="status-text">'.$location.'</span></td>';
$status .= '<i class="fas fa-check-circle"></i></td><td class="align-td">';
$auths = implode(PHP_EOL, $data->auths);
if ($data->auth_status == 1) {
$status .= '<i class="fas fa-check-circle" title="'.$auths.'"></i>';
} else {
$status .= '<i class="fas fa-exclamation-circle" title="'.$auths.'"></i>';
}
$status .= '</td><td class="left-text"><span class="status-text">'.$location.'</span></td>';
} else {
$error = 'Unable to locate the proxy config for '.$result.', it must use the following structure:'.PHP_EOL;
$error .= '&#09;set $upstream_app <container/address>;'.PHP_EOL;
$error .= '&#09;set $upstream_port <port>;'.PHP_EOL;
$error .= '&#09;set $upstream_proto <protocol>;'.PHP_EOL;
$error .= '&#09;proxy_pass $upstream_proto://$upstream_app:$upstream_port;'.PHP_EOL;
$status .= '<i class="fas fa-exclamation-circle" title="'.$error.'"></i></td><td></td>';
$status .= '<i class="fas fa-exclamation-circle" title="'.$error.'"></i></td><td></td><td></td>';
}
$status .= '</tr>';
$index++;
Expand All @@ -85,6 +92,7 @@ function GetProxies() {
<td><h3>Application</h3></td>
<td><h3>Available</h3></td>
<td><h3>Proxied</h3></td>
<td><h3>Auth</h3></td>
<td><h3>Location</h3></td>
</tr>
</thead>
Expand Down