forked from KptltD00M/nixy
Add new server modules and configurations for various services
- Introduced `default-creds` module for managing default credentials with Umami integration. - Added `fail2ban` module for brute-force attack protection with configurable ban times. - Created `firewall` module to enable and configure basic firewall settings. - Implemented `gitea` module for self-hosted Git service with PostgreSQL backend. - Developed `glance` module for a customizable dashboard with various widgets and themes. - Added `iknowyou` module for a self-hosted password manager with production and demo environments. - Introduced `kernel-hardening` module for enhancing kernel security settings. - Created `mazanoke` module for a simple web application with Nginx integration. - Added `mealie` module for a self-hosted meal planning application. - Implemented `stirling-pdf` module for PDF generation service. - Developed `umami` module for self-hosted analytics with secret management. - Added `ssh` module for secure SSH configuration with user restrictions. - Introduced `nixy` theme for a customized aesthetic experience across services.
This commit is contained in:
@@ -0,0 +1,154 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
inherit (import ../mk-container.nix {inherit lib config;}) mkContainer;
|
||||
domain = config.var.domain;
|
||||
hostIp = "10.233.12.1";
|
||||
|
||||
# Convert 6-char hex color to "H S L" string for glance (integers, no % sign)
|
||||
hexToGlanceHsl = hex: let
|
||||
h = lib.toLower hex;
|
||||
d = c:
|
||||
if c == "a"
|
||||
then 10
|
||||
else if c == "b"
|
||||
then 11
|
||||
else if c == "c"
|
||||
then 12
|
||||
else if c == "d"
|
||||
then 13
|
||||
else if c == "e"
|
||||
then 14
|
||||
else if c == "f"
|
||||
then 15
|
||||
else lib.toInt c;
|
||||
byte = pos: d (builtins.substring pos 1 h) * 16 + d (builtins.substring (pos + 1) 1 h);
|
||||
ri = byte 0;
|
||||
gi = byte 2;
|
||||
bi = byte 4;
|
||||
r = ri * 1.0 / 255.0;
|
||||
g = gi * 1.0 / 255.0;
|
||||
b = bi * 1.0 / 255.0;
|
||||
mx =
|
||||
if r >= g && r >= b
|
||||
then "r"
|
||||
else if g >= b
|
||||
then "g"
|
||||
else "b";
|
||||
mn =
|
||||
if r <= g && r <= b
|
||||
then "r"
|
||||
else if g <= b
|
||||
then "g"
|
||||
else "b";
|
||||
cmax =
|
||||
if mx == "r"
|
||||
then r
|
||||
else if mx == "g"
|
||||
then g
|
||||
else b;
|
||||
cmin =
|
||||
if mn == "r"
|
||||
then r
|
||||
else if mn == "g"
|
||||
then g
|
||||
else b;
|
||||
delta = cmax - cmin;
|
||||
l = (cmax + cmin) / 2.0;
|
||||
s =
|
||||
if delta < 0.0001
|
||||
then 0.0
|
||||
else if l <= 0.5
|
||||
then delta / (cmax + cmin)
|
||||
else delta / (2.0 - cmax - cmin);
|
||||
hue =
|
||||
if delta < 0.0001
|
||||
then 0.0
|
||||
else if mx == "r"
|
||||
then let
|
||||
raw = 60.0 * (g - b) / delta;
|
||||
in
|
||||
if raw < 0.0
|
||||
then raw + 360.0
|
||||
else raw
|
||||
else if mx == "g"
|
||||
then 60.0 * ((b - r) / delta + 2.0)
|
||||
else 60.0 * ((r - g) / delta + 4.0);
|
||||
in "${toString (builtins.floor (hue + 0.5))} ${toString (builtins.floor (s * 100.0 + 0.5))} ${
|
||||
toString (builtins.floor (l * 100.0 + 0.5))
|
||||
}";
|
||||
|
||||
c = config.stylix.base16Scheme;
|
||||
in {
|
||||
# 0444 so the glance user inside the container can read the bind-mounted file
|
||||
sops.secrets.adguard-pwd.mode = "0444";
|
||||
|
||||
imports = [
|
||||
(mkContainer {
|
||||
name = "glance";
|
||||
hostIp = hostIp;
|
||||
containerIp = "10.233.12.2";
|
||||
internet = true;
|
||||
bindMounts."/run/secrets/adguard-pwd" = {
|
||||
hostPath = config.sops.secrets.adguard-pwd.path;
|
||||
isReadOnly = true;
|
||||
};
|
||||
nixosConfig = {lib, ...}: {
|
||||
_module.args.domain = domain;
|
||||
_module.args.adguardUrl = "http://${hostIp}:3000";
|
||||
imports = [
|
||||
./home.nix
|
||||
./server.nix
|
||||
];
|
||||
|
||||
services.glance = {
|
||||
enable = true;
|
||||
settings = {
|
||||
server = {
|
||||
port = 5678;
|
||||
host = "127.0.0.1";
|
||||
};
|
||||
theme = {
|
||||
light = false;
|
||||
background-color = hexToGlanceHsl c.base00; # background
|
||||
primary-color = hexToGlanceHsl c.base0D; # accent (iris/purple)
|
||||
positive-color = hexToGlanceHsl c.base0B; # positive (pine/teal)
|
||||
negative-color = hexToGlanceHsl c.base08; # negative (love/rose)
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
appendHttpConfig = ''
|
||||
proxy_cache_path /var/cache/nginx/glance levels=1:2 keys_zone=glance:1m inactive=30m max_size=100m;
|
||||
'';
|
||||
virtualHosts."glance" = {
|
||||
listen = [
|
||||
{
|
||||
addr = "0.0.0.0";
|
||||
port = 8080;
|
||||
}
|
||||
];
|
||||
locations."/" = {
|
||||
proxyPass = "http://127.0.0.1:5678";
|
||||
extraConfig = ''
|
||||
proxy_cache glance;
|
||||
proxy_cache_valid 200 30m;
|
||||
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
|
||||
add_header X-Cache-Status $upstream_cache_status;
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = [8080];
|
||||
system.stateVersion = "24.05";
|
||||
};
|
||||
})
|
||||
];
|
||||
|
||||
services.cloudflared.tunnels."${config.var.tunnelId}".ingress."home.${domain}" = "http://10.233.12.2:8080";
|
||||
}
|
||||
@@ -0,0 +1,245 @@
|
||||
{domain, ...}: {
|
||||
services.glance.settings.pages = [
|
||||
{
|
||||
name = "Home";
|
||||
hide-desktop-navigation = false;
|
||||
columns = [
|
||||
{
|
||||
size = "small";
|
||||
widgets = [
|
||||
{
|
||||
type = "clock";
|
||||
hour-format = "24h";
|
||||
}
|
||||
{
|
||||
type = "weather";
|
||||
location = "Paris, France";
|
||||
}
|
||||
{
|
||||
type = "markets";
|
||||
markets = [
|
||||
{
|
||||
symbol = "BTC-USD";
|
||||
name = "Bitcoin";
|
||||
chart-link = "https://www.tradingview.com/chart/?symbol=INDEX:BTCUSD";
|
||||
}
|
||||
{
|
||||
symbol = "SOL-USD";
|
||||
name = "Solana";
|
||||
chart-link = "https://www.tradingview.com/chart/?symbol=INDEX:SOLUSD";
|
||||
}
|
||||
{
|
||||
symbol = "ETH-USD";
|
||||
name = "Ethereum";
|
||||
chart-link = "https://www.tradingview.com/chart/?symbol=INDEX:ETHUSD";
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
}
|
||||
{
|
||||
size = "full";
|
||||
widgets = [
|
||||
{
|
||||
type = "search";
|
||||
search-engine = "startpage";
|
||||
}
|
||||
{
|
||||
type = "group";
|
||||
widgets = [
|
||||
{
|
||||
type = "bookmarks";
|
||||
title = "Bookmarks";
|
||||
groups = [
|
||||
{
|
||||
title = "";
|
||||
same-tab = true;
|
||||
color = "245 50 64";
|
||||
links = [
|
||||
{
|
||||
title = "Mail";
|
||||
url = "https://mail.proton.me";
|
||||
}
|
||||
{
|
||||
title = "Drive";
|
||||
url = "https://drive.proton.me";
|
||||
}
|
||||
{
|
||||
title = "Lumo";
|
||||
url = "https://lumo.proton.me";
|
||||
}
|
||||
{
|
||||
title = "Calendar";
|
||||
url = "https://calendar.proton.me";
|
||||
}
|
||||
{
|
||||
title = "Maps";
|
||||
url = "https://maps.apple.com";
|
||||
}
|
||||
{
|
||||
title = "Amazon";
|
||||
url = "https://amazon.fr";
|
||||
}
|
||||
];
|
||||
}
|
||||
{
|
||||
title = "Tools";
|
||||
same-tab = true;
|
||||
color = "245 50 64";
|
||||
links = [
|
||||
{
|
||||
title = "Excalidraw";
|
||||
url = "https://excalidraw.com";
|
||||
}
|
||||
{
|
||||
title = "Cobalt (downloader)";
|
||||
url = "https://cobalt.meowing.de";
|
||||
}
|
||||
{
|
||||
title = "Mazanoke (image downgrading)";
|
||||
url = "https://mazanoke.${domain}";
|
||||
}
|
||||
{
|
||||
title = "Stirling PDF";
|
||||
url = "https://pdf.${domain}";
|
||||
}
|
||||
{
|
||||
title = "Vert (file converter)";
|
||||
url = "https://vert.sh";
|
||||
}
|
||||
{
|
||||
title = "Markdown to pdf";
|
||||
url = "https://md2file.com";
|
||||
}
|
||||
{
|
||||
title = "Image to Vector";
|
||||
url = "https://www.vectorcascade.com/";
|
||||
}
|
||||
{
|
||||
title = "PrivateBin";
|
||||
url = "https://privatebin.net";
|
||||
}
|
||||
];
|
||||
}
|
||||
{
|
||||
title = "Social";
|
||||
same-tab = true;
|
||||
color = "245 50 64";
|
||||
links = [
|
||||
{
|
||||
title = "Bsky";
|
||||
url = "https://bsky.app";
|
||||
}
|
||||
{
|
||||
title = "Reddit";
|
||||
url = "https://reddit.com";
|
||||
}
|
||||
{
|
||||
title = "Youtube";
|
||||
url = "https://youtube.com";
|
||||
}
|
||||
{
|
||||
title = "Instagram";
|
||||
url = "https://instagram.com";
|
||||
}
|
||||
{
|
||||
title = "Github";
|
||||
url = "https://github.com";
|
||||
}
|
||||
{
|
||||
title = "Discord";
|
||||
url = "https://discord.com/channels/@me/";
|
||||
}
|
||||
];
|
||||
}
|
||||
{
|
||||
title = "Other";
|
||||
same-tab = true;
|
||||
color = "245 50 64";
|
||||
links = [
|
||||
{
|
||||
title = "Startpage config";
|
||||
url = "https://www.startpage.com/do/mypage.pl?prfe=45d331deb05471d659dba933e7400df51d952bb103da6f6125c0e769a6be1d65610456a479f495ceeee7e97311cf227d7c1bb198de0ceeb193d8cddf9c455c19a409cc35c3e3f542ee27bd7cecd3";
|
||||
}
|
||||
{
|
||||
title = "Hyprland Wiki";
|
||||
url = "https://wiki.hypr.land";
|
||||
}
|
||||
{
|
||||
title = "Search NixOS";
|
||||
url = "https://mynixos.com";
|
||||
}
|
||||
{
|
||||
title = "Nixpkgs";
|
||||
url = "https://github.com/NixOS/nixpkgs";
|
||||
}
|
||||
{
|
||||
title = "Claude";
|
||||
url = "https://claude.ai";
|
||||
}
|
||||
{
|
||||
title = "Gemini";
|
||||
url = "https://gemini.google.com";
|
||||
}
|
||||
{
|
||||
title = "Medium";
|
||||
url = "https://medium.com";
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
}
|
||||
{
|
||||
type = "bookmarks";
|
||||
title = "Infosec";
|
||||
groups = [
|
||||
{
|
||||
title = "";
|
||||
same-tab = true;
|
||||
color = "245 50 64";
|
||||
links = [
|
||||
{
|
||||
title = "Nix 4 Cyber";
|
||||
url = "https://n4c.${domain}";
|
||||
}
|
||||
{
|
||||
title = "Cyberchef";
|
||||
url = "https://cyberchef.${domain}";
|
||||
}
|
||||
{
|
||||
title = "TryHackMe";
|
||||
url = "https://tryhackme.com";
|
||||
}
|
||||
{
|
||||
title = "Root-Me";
|
||||
url = "https://root-me.org";
|
||||
}
|
||||
{
|
||||
title = "Exploit-DB";
|
||||
url = "https://exploit-db.com";
|
||||
}
|
||||
{
|
||||
title = "Crack Station";
|
||||
url = "https://crackstation.net";
|
||||
}
|
||||
{
|
||||
title = "Osint Tracker";
|
||||
url = "https://app.osintracker.com";
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
}
|
||||
{
|
||||
type = "hacker-news";
|
||||
limit = 15;
|
||||
collapse-after = 5;
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
{
|
||||
domain,
|
||||
adguardUrl,
|
||||
...
|
||||
}: {
|
||||
services.glance.settings.pages = [
|
||||
{
|
||||
name = "Server";
|
||||
hide-desktop-navigation = false;
|
||||
columns = [
|
||||
{
|
||||
size = "full";
|
||||
widgets = [
|
||||
{
|
||||
type = "server-stats";
|
||||
servers = [
|
||||
{
|
||||
type = "local";
|
||||
name = "Jack";
|
||||
}
|
||||
];
|
||||
}
|
||||
{
|
||||
type = "group";
|
||||
widgets = [
|
||||
{
|
||||
type = "monitor";
|
||||
title = "Services";
|
||||
cache = "1m";
|
||||
sites = [
|
||||
{
|
||||
title = "Adguard";
|
||||
url = "https://adguard.${domain}";
|
||||
icon = "si:adguard";
|
||||
}
|
||||
{
|
||||
title = "Blog";
|
||||
url = "https://${domain}";
|
||||
icon = "si:blogger";
|
||||
}
|
||||
{
|
||||
title = "Gitea";
|
||||
url = "https://git.${domain}";
|
||||
icon = "si:gitea";
|
||||
}
|
||||
{
|
||||
title = "Mealie";
|
||||
url = "https://mealie.${domain}";
|
||||
icon = "si:mealie";
|
||||
}
|
||||
{
|
||||
title = "Umami";
|
||||
url = "https://umami.${domain}";
|
||||
icon = "si:umami";
|
||||
}
|
||||
{
|
||||
title = "Iknowyou";
|
||||
url = "https://iknowyou.${domain}";
|
||||
icon = "sh:iknowyou";
|
||||
}
|
||||
{
|
||||
title = "Iknowyou Prod";
|
||||
url = "https://iknowyou-prod.${domain}";
|
||||
icon = "sh:iknowyou";
|
||||
}
|
||||
{
|
||||
title = "Wallpapers";
|
||||
url = "https://wallpapers.${domain}";
|
||||
icon = "si:unsplash";
|
||||
}
|
||||
{
|
||||
title = "Mazanoke";
|
||||
url = "https://mazanoke.${domain}";
|
||||
icon = "sh:mazanoke";
|
||||
}
|
||||
{
|
||||
title = "Stirling PDF";
|
||||
url = "https://pdf.${domain}";
|
||||
icon = "sh:stirling-pdf";
|
||||
}
|
||||
{
|
||||
title = "Default-creds";
|
||||
url = "https://default-creds.${domain}";
|
||||
icon = "si:passbolt";
|
||||
}
|
||||
{
|
||||
title = "Cyberchef";
|
||||
url = "https://cyberchef.${domain}";
|
||||
icon = "si:codechef";
|
||||
}
|
||||
];
|
||||
}
|
||||
{
|
||||
type = "monitor";
|
||||
title = "*arr";
|
||||
cache = "1m";
|
||||
sites = [
|
||||
{
|
||||
title = "Jellyfin";
|
||||
url = "https://media.${domain}";
|
||||
icon = "si:jellyfin";
|
||||
}
|
||||
{
|
||||
title = "Jellyseerr";
|
||||
url = "https://demandemedia.${domain}";
|
||||
icon = "si:odysee";
|
||||
}
|
||||
{
|
||||
title = "Radarr";
|
||||
url = "https://radarr.${domain}";
|
||||
icon = "si:radarr";
|
||||
}
|
||||
{
|
||||
title = "Sonarr";
|
||||
url = "https://sonarr.${domain}";
|
||||
icon = "si:sonarr";
|
||||
}
|
||||
{
|
||||
title = "Bazarr";
|
||||
url = "https://bazarr.${domain}";
|
||||
icon = "si:subtitleedit";
|
||||
}
|
||||
{
|
||||
title = "Prowlarr";
|
||||
url = "https://prowlarr.${domain}";
|
||||
icon = "si:podcastindex";
|
||||
}
|
||||
{
|
||||
title = "Transmission";
|
||||
url = "https://transmission.${domain}";
|
||||
icon = "si:transmission";
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
{
|
||||
type = "dns-stats";
|
||||
service = "adguard";
|
||||
url = adguardUrl;
|
||||
username = "hadi";
|
||||
password = "\${secret:adguard-pwd}";
|
||||
}
|
||||
|
||||
{
|
||||
type = "bookmarks";
|
||||
groups = [
|
||||
{
|
||||
title = "";
|
||||
same-tab = true;
|
||||
color = "245 50 64";
|
||||
links = [
|
||||
{
|
||||
title = "Router";
|
||||
url = "http://192.168.1.254/";
|
||||
}
|
||||
{
|
||||
title = "Cloudflare";
|
||||
url = "https://dash.cloudflare.com/";
|
||||
}
|
||||
{
|
||||
title = "Cloudflare Zero Trust";
|
||||
url = "https://one.dash.cloudflare.com/";
|
||||
}
|
||||
{
|
||||
title = "Cloudflare Access";
|
||||
url = "https://anotherhadi.cloudflareaccess.com";
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
}
|
||||
Reference in New Issue
Block a user