77import socket
88import urllib3
99
10+ 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+);.*"
11+ AUTHELIA_REGEX = r"\n\s+include \/config\/nginx\/authelia-location\.conf;.*"
12+ AUTHENTIK_REGEX = r"\n\s+include \/config\/nginx\/authentik-location\.conf;.*"
13+ BASIC_AUTH_REGEX = r"\n\s+auth_basic.*"
14+ LDAP_REGEX = r"\n\s+include \/config\/nginx\/ldap-location\.conf;.*"
15+
1016
1117def find_apps ():
1218 apps = {}
19+ auths = collections .defaultdict (dict )
1320 file_paths = glob .glob ("/config/nginx/**/**" , recursive = True )
1421 auto_confs = glob .glob ("/etc/nginx/http.d/*" , recursive = True )
1522 file_paths .extend (auto_confs )
@@ -18,17 +25,32 @@ def find_apps():
1825 continue
1926 file = open (file_path , "r" )
2027 content = file .read ()
21- 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 )
22- for result in results :
23- params = result .groupdict ()
24- app = f"{ params ['proto' ]} ://{ params ['name' ]} :{ params ['port' ]} /"
25- if app not in apps :
26- apps [app ] = set ()
27- if file_path .startswith ("/config/nginx/site-confs/" ) or file_path .endswith (".conf" ):
28- file_path = "auto-proxy" if file_path .startswith ("/etc/nginx/http.d/" ) else file_path
29- apps [app ].add (file_path )
30- return apps
28+ match_proxy (apps , auths , content , file_path )
29+ return apps , auths
30+
31+ def match_proxy (apps , auths , content , file_path ):
32+ results = re .finditer (PROXY_REGEX , content )
33+ for result in results :
34+ params = result .groupdict ()
35+ app = f"{ params ['proto' ]} ://{ params ['name' ]} :{ params ['port' ]} /"
36+ if app not in apps :
37+ apps [app ] = set ()
38+ if file_path .startswith ("/config/nginx/site-confs/" ) or file_path .endswith (".conf" ):
39+ file_path = "auto-proxy" if file_path .startswith ("/etc/nginx/http.d/" ) else file_path
40+ apps [app ].add (file_path )
41+ match_auth (auths , app , file_path , content )
3142
43+ def match_auth (auths , app , file_path , content ):
44+ if re .findall (AUTHELIA_REGEX , content ):
45+ auths [app ][file_path ] = "Authelia"
46+ elif re .findall (AUTHENTIK_REGEX , content ):
47+ auths [app ][file_path ] = "Authentik"
48+ elif re .findall (BASIC_AUTH_REGEX , content ):
49+ auths [app ][file_path ] = "Basic Auth"
50+ elif re .findall (LDAP_REGEX , content ):
51+ auths [app ][file_path ] = "LDAP"
52+ else :
53+ auths [app ][file_path ] = "No Auth"
3254
3355def is_available (url ):
3456 s = socket .socket (socket .AF_INET , socket .SOCK_STREAM )
@@ -45,7 +67,7 @@ def is_available(url):
4567
4668
4769urllib3 .disable_warnings ()
48- apps = find_apps ()
70+ apps , auths = find_apps ()
4971discovered_apps = collections .defaultdict (dict )
5072with concurrent .futures .ThreadPoolExecutor (max_workers = 100 ) as executor :
5173 futures = {executor .submit (is_available , app ): app for app in apps .keys ()}
@@ -55,5 +77,7 @@ def is_available(url):
5577 continue
5678 discovered_apps [app ]["status" ] = future .result ()
5779 discovered_apps [app ]["locations" ] = list (apps [app ])
80+ discovered_apps [app ]["auths" ] = list (f"{ path } - { auth } " for path , auth in auths [app ].items ())
81+ discovered_apps [app ]["auth_status" ] = all (auth != "No Auth" for auth in auths [app ].values ())
5882
5983print (json .dumps (discovered_apps , sort_keys = True ))
0 commit comments