diff --git a/README.md b/README.md index ca0d380..c7afd59 100644 --- a/README.md +++ b/README.md @@ -10,11 +10,17 @@ In the container's docker arguments, set an environment variable DOCKER_MODS=lin If adding multiple mods, enter them in an array separated by |, such as DOCKER_MODS=linuxserver/mods:swag-dashboard|linuxserver/mods:swag-mod2 -# Usage +## Internal access using `:81` -Navigate to `dashboard.domain.com` from your LAN to view the dashboard. +Add a mapping of `81:81` to swag's docker run command or compose -You can remove the allow/deny in `/config/nginx/proxy-confs/dashboard.subdomain.com` to expose it (on a VPS for example), and instead protect it some other way (like Authelia for example). +## Internal access using `dashboard.domain.com` + +Requires an internal DNS, add a rewrite of `dashboard.domain.com` to your server's IP address + +## External access using `dashboard.domain.com` + +Remove the allow/deny lines in `/config/nginx/proxy-confs/dashboard.subdomain.com`, and instead secure it some other way (like Authelia for example). ## Notes - The application discovery scans the proxy configs and looks for the following structure in accordance with the samples: @@ -25,6 +31,8 @@ You can remove the allow/deny in `/config/nginx/proxy-confs/dashboard.subdomain. proxy_pass $upstream_proto://$upstream_app:$upstream_port; ``` - Either [Swag Maxmind mod](https://github.com/linuxserver/docker-mods/tree/swag-maxmind) or [Swag DBIP mod](https://github.com/linuxserver/docker-mods/tree/swag-dbip) are required to enable the geo location graph. +- The host's fail2ban can be supported by mounting it to swag `- /path/to/host/fail2ban.sqlite3:/dashboard/fail2ban.sqlite3:ro` +- The host's logs can be supported by mounting it to swag `- /path/to/host/logs:/dashboard/logs:ro` # Example ![Example](.assets/example.png) diff --git a/root/dashboard/dashboard.subdomain.conf.sample b/root/dashboard/dashboard.subdomain.conf.sample index 127ef29..8162525 100644 --- a/root/dashboard/dashboard.subdomain.conf.sample +++ b/root/dashboard/dashboard.subdomain.conf.sample @@ -1,6 +1,54 @@ ## Version 2022/01/14 # Make sure that your dns has a cname set for dashboard +server { + listen 81; + + server_name _; + + root /dashboard/www; + index index.php; + + client_max_body_size 0; + + # enable for ldap auth, fill in ldap details in ldap.conf + #include /config/nginx/ldap.conf; + + # enable for Authelia + #include /config/nginx/authelia-server.conf; + + location / { + # enable the next two lines for http auth + #auth_basic "Restricted"; + #auth_basic_user_file /config/nginx/.htpasswd; + + # enable the next two lines for ldap auth + #auth_request /auth; + #error_page 401 =200 /ldaplogin; + + # enable for Authelia + #include /config/nginx/authelia-location.conf; + + allow 10.0.0.0/8; + allow 172.16.0.0/12; + allow 192.168.0.0/16; + deny all; + + try_files $uri $uri/ /index.php?$args =404; + } + location ~ \.php$ { + allow 10.0.0.0/8; + allow 172.16.0.0/12; + allow 192.168.0.0/16; + deny all; + + fastcgi_split_path_info ^(.+\.php)(/.+)$; + fastcgi_pass 127.0.0.1:9000; + fastcgi_index index.php; + include /etc/nginx/fastcgi_params; + } +} + server { listen 443 ssl; listen [::]:443 ssl; diff --git a/root/dashboard/swag-f2b.py b/root/dashboard/swag-f2b.py index d59074e..c1d144d 100644 --- a/root/dashboard/swag-f2b.py +++ b/root/dashboard/swag-f2b.py @@ -1,25 +1,32 @@ import json +import os import sqlite3 +def _get_f2b_data(db_path): + if not os.path.isfile(db_path): + return [] + + con = sqlite3.connect(db_path) + cur = con.cursor() + results = cur.execute(""" + SELECT jails.name, + COUNT(bans.ip) AS bans, + (SELECT DISTINCT bans.ip from bans where jails.name = bans.jail ORDER BY timeofban DESC) as last_ban, + (SELECT DISTINCT bans.data from bans where jails.name = bans.jail ORDER BY timeofban DESC) as data + FROM jails + LEFT JOIN bans ON jails.name=bans.jail + GROUP BY jails.name + """).fetchall() + con.close() + return [{ + "name": name, + "bans": bans, + "last_ban": last_ban, + "data": json.dumps(json.loads(data), indent=4, sort_keys=True) if data else None + } for (name, bans, last_ban, data) in results] -con = sqlite3.connect("/config/fail2ban/fail2ban.sqlite3") -cur = con.cursor() -results = cur.execute(""" - SELECT jails.name, - COUNT(bans.ip) AS bans, - (SELECT DISTINCT bans.ip from bans where jails.name = bans.jail ORDER BY timeofban DESC) as last_ban, - (SELECT DISTINCT bans.data from bans where jails.name = bans.jail ORDER BY timeofban DESC) as data - FROM jails - LEFT JOIN bans ON jails.name=bans.jail - GROUP BY jails.name - """).fetchall() -con.close() -formatted_results = [{ - "name": name, - "bans": bans, - "last_ban": last_ban, - "data": json.dumps(json.loads(data), indent=4, sort_keys=True) if data else None -} for (name, bans, last_ban, data) in results] +swag_f2b = _get_f2b_data("/config/fail2ban/fail2ban.sqlite3") +host_f2b = _get_f2b_data("/dashboard/fail2ban/fail2ban.sqlite3") -output = json.dumps(formatted_results, sort_keys=True) +output = json.dumps(swag_f2b + host_f2b, sort_keys=True) print(output) diff --git a/root/dashboard/swag-proxies.py b/root/dashboard/swag-proxies.py index ab9b280..059c5bb 100644 --- a/root/dashboard/swag-proxies.py +++ b/root/dashboard/swag-proxies.py @@ -1,5 +1,4 @@ import collections -import contextlib import concurrent.futures import glob import json @@ -11,7 +10,7 @@ import urllib3 def find_apps(): apps = {} - file_paths = glob.glob("/config/nginx/**/*", recursive=True) + file_paths = glob.glob("/config/nginx/**/**", recursive=True) auto_confs = glob.glob("/etc/nginx/http.d/*", recursive=True) file_paths.extend(auto_confs) for file_path in file_paths: