From fd644671af5b48c5930f07af7f3c8cfe5aee8d8b Mon Sep 17 00:00:00 2001 From: Hadi <112569860+anotherhadi@users.noreply.github.com> Date: Tue, 6 Jan 2026 17:24:21 +0100 Subject: [PATCH] Server update Signed-off-by: Hadi <112569860+anotherhadi@users.noreply.github.com> --- docs/SERVER.md | 50 +++++++++---------------------- flake.lock | 6 ++-- hosts/server/configuration.nix | 10 ++++--- hosts/server/secrets/secrets.yaml | 9 ++---- server-modules/adguardhome.nix | 22 ++++---------- server-modules/arr.nix | 30 +++++++++---------- server-modules/bitwarden.nix | 27 ----------------- server-modules/cloudflared.nix | 23 +++++--------- server-modules/cyberchef.nix | 14 +++++++++ server-modules/eleakxir.nix | 12 ++------ server-modules/fail2ban.nix | 13 ++++++++ server-modules/glance.nix | 12 ++------ server-modules/linkding.nix | 23 ++++++++++++++ server-modules/mazanoke.nix | 35 ++++++++++++++++++++++ server-modules/mealie.nix | 22 ++++---------- server-modules/nginx.nix | 42 +------------------------- server-modules/ssh.nix | 10 +++---- server-modules/stirling-pdf.nix | 8 +++++ 18 files changed, 163 insertions(+), 205 deletions(-) delete mode 100644 server-modules/bitwarden.nix create mode 100644 server-modules/cyberchef.nix create mode 100644 server-modules/fail2ban.nix create mode 100644 server-modules/linkding.nix create mode 100644 server-modules/mazanoke.nix create mode 100644 server-modules/stirling-pdf.nix diff --git a/docs/SERVER.md b/docs/SERVER.md index ba3a567..e3fdbcf 100644 --- a/docs/SERVER.md +++ b/docs/SERVER.md @@ -1,53 +1,31 @@ # SERVER -> Update in comming. Early 2026 - ## Overview -This document describes the architecture and setup of the self-hosted **NixOS server**, which is securely accessible via **Tailscale**. The server is designed for private, secure, and easily manageable self-hosting of various services. +This document describes the architecture and setup of the self-hosted **NixOS server**, which is securely accessible via **a Cloudflare Tunnel**. +The server is designed for private, secure, and easily manageable self-hosting of various services. ![server dashboard](../.github/assets/server_dashboard.png) ## **Why This Setup?** -- **Private & Secure**: Services are only accessible through Tailscale, preventing exposure to the public internet. -- **Domain-based Access**: A custom domain (`example.org`) maps to the server's Tailscale IP, making service access simple and consistent. -- **Automatic SSL Certificates**: Using DNS-01 challenges, valid SSL certificates are generated even though the services are not publicly exposed. -- **Modular & Declarative**: Everything is managed through NixOS modules, ensuring reproducibility and easy configuration. +- **Private & Secure**: Services are only accessible through Cloudflare's access control, preventing exposure to the "public internet". +- **Domain-based Access**: A custom domain maps to the server's tunnel, making service access simple and consistent. +- **Modular & Declarative**: Everything is managed through NixOS modules (except for access control), ensuring reproducibility and easy configuration. ## **Self-Hosted Services** The server hosts several key applications: -### **Core Infrastructure** - -- **NGINX**: Reverse proxy for routing traffic to services via `example.org`. - -### **Networking & Security** - +- **NGINX**: Reverse proxy for routing traffic to services via my domain name. - **AdGuard Home**: A self-hosted DNS ad blocker for network-wide ad and tracker filtering. - -### **Monitoring & Storage** - - **Glance**: An awesome dashboard! (See the screenshot above) - -### **Media & Content Management** - - **Arr Stack (Radarr, Sonarr, etc.)**: Automated media management tools for handling movies and TV shows. (legaly ofc) - -## **How It Works** - -1. **Domain Configuration** - - `example.org` is pointed to the Tailscale IP of the server. (cloudflare A record, not proxied) - - This allows for easy access without exposing services to the internet. - -2. **SSL Certificate Generation** - - Certificates are obtained using a **DNS-01 challenge**, verifying domain ownership without requiring public access. - -3. **NGINX Reverse Proxy** - - Routes incoming requests from `*.example.org` to the correct internal service. - - Ensures SSL termination and secure connections. - -4. **Access Control** - - Only devices within the Tailscale network can reach the services. - - Firewall rules restrict access further based on necessity. +- **Mealie**: A self-hosted recipe manager and meal planner with a clean user interface. +- **Stirling-PDF**: A powerful, locally hosted web application for editing, merging, and converting PDF files. +- **CyberChef**: The "Cyber Swiss Army Knife" for data analysis, decoding, and encryption tasks. +- **Linkding**: A simple, fast, and minimalist bookmark manager. +- **Mazanoke**: A utility service for image processing, specialized in format conversion and downgrading/optimization. +- **Eleakxir**: A private search engine for exploring data wells (parquet files) with a modern web interface. +- **SSH**: Secure remote access configuration for server management. (via browser too) +- **Security related stuff**: Cloudflared, Fail2Ban, Firewall diff --git a/flake.lock b/flake.lock index 0f294ab..bf0b606 100644 --- a/flake.lock +++ b/flake.lock @@ -199,11 +199,11 @@ "systems": "systems" }, "locked": { - "lastModified": 1767483034, - "narHash": "sha256-wnSIKOSU1T11qAj+axSCvzlpk7Jjp4D3nlgbGSMhtIc=", + "lastModified": 1767711987, + "narHash": "sha256-1CxY87J0cOetwvzIaZGl0Vaz/pLjIlTKhC3vt189cGk=", "owner": "anotherhadi", "repo": "eleakxir", - "rev": "881cdfa9cbbeed5e8592546042e5e16cdd603f59", + "rev": "717e4136cd728e4fc48e79d04d18c25ef1eb9129", "type": "github" }, "original": { diff --git a/hosts/server/configuration.nix b/hosts/server/configuration.nix index 4469a1f..432e611 100644 --- a/hosts/server/configuration.nix +++ b/hosts/server/configuration.nix @@ -7,19 +7,21 @@ ../../nixos/users.nix ../../nixos/utils.nix ../../nixos/docker.nix - ../../nixos/tailscale.nix # NixOS server modules ../../server-modules/ssh.nix - # ../../server-modules/bitwarden.nix ../../server-modules/firewall.nix ../../server-modules/cloudflared.nix - ../../server-modules/nginx.nix ../../server-modules/glance.nix ../../server-modules/adguardhome.nix ../../server-modules/arr.nix - # ../../server-modules/mealie.nix ../../server-modules/eleakxir.nix + ../../server-modules/stirling-pdf.nix + ../../server-modules/cyberchef.nix + ../../server-modules/linkding.nix + ../../server-modules/mazanoke.nix + ../../server-modules/nginx.nix + ../../server-modules/fail2ban.nix # You should let those lines as is ./hardware-configuration.nix diff --git a/hosts/server/secrets/secrets.yaml b/hosts/server/secrets/secrets.yaml index 6545089..35f5ffa 100644 --- a/hosts/server/secrets/secrets.yaml +++ b/hosts/server/secrets/secrets.yaml @@ -1,10 +1,7 @@ sshconfig: ENC[AES256_GCM,data:R54HVxqAyj9yGO/AYL8p6cnXgYxkQKW9XveHlBMTnDXBJ7r/4HgnefdymprnXmdlbNWcWrRqmaLEuzJs/0BfixXfMvmGTUrmJ0ASVuDrz9k6rOLADAKFikQh0dib7NU4JmPgmUzMncXc2WuCd3BCG3kwBQ==,iv:Ro9FA+MzTAp+ERQMT88z8ioCox/dTj2vWcqCDOSLag4=,tag:5XiXIyz5/pjGFOB5ZjdOVg==,type:str] github-key: ENC[AES256_GCM,data:NRYhcBIwGJEV13+YECLR+2IErsn/7clbnkx0Mltr7dQajSb5WHZ3QDH0KQPylEHhplE5IVS0h4I0z+Pb1B0UteCxFmJ5wZq+2BKZkvE7G3dojqBpgHcVqJV2GLEJkRjlHfRgsbq/OBe8xcsPh20P1KUyP0WIwVbpt+9dFWGxEGYkp2uSyuBIJ98kElt0zuVgl7WcYoDO7v5WmGzZfla+yZwURvMk8zcM3gopo+4KL6YnYUs+UA3VlBBn6VK4Nvbqy6X0R0+ZA5HHAXg+OFgGmfWnENZmsyQJHXEchGGgEldzThkQ4r8yMkgN/ax+AGouLyzbITapGE4sE11FFgL6Hmp4pSXxl3UAGF+cvV5pIujbb28CXmSPRMyYpoNxI93PSYz/txAzE6Cr2dgwxR4zpMelv4i6IaGnY8NgpY8jp2Y6C0uuJxJCN0RtnjQw1rM2uRnm7vMGyU7XXz9DEVfGnYpTWnykXsEjHE5DVGy80ejYQlc6dtmf3vdTWpt+YYdCPw8/cd0PIx2D6geh1c28,iv:wl+RG24mXYMklD8CBGXVD36DMhlWT/7zh8ZMvr7vgOk=,tag:OJhqF8PoXotr7IsyFW6q1g==,type:str] -cloudflare-dns-token: ENC[AES256_GCM,data:JIXUtVDpYS9B74W0ooj50kd4v2+PX+FdF218gvgaS04rYATu4N6w9KEFPfdQqLjUmVihzV6s/IR1fg==,iv:AlbQ86kvFQbetvmFwt/hEyUcqKTI+XzL/NvSMXW9wm4=,tag:1JQeK4KrTDa6Kz+JhWxkxQ==,type:str] -nextcloud-pwd: ENC[AES256_GCM,data:2oqsNceKuwGscBN2VxAK,iv:FoSfHItgeB91fG38zqtuQzayvNjNPFQyZjZlpUq/eic=,tag:MoEpAmTj+zqVu6OLasD4kQ==,type:str] adguard-pwd: ENC[AES256_GCM,data:QavwLWENAURnRrFwiLntkiM=,iv:bxdQfBxNL5rwUr7CEKbwXtv5mUUXZHhvyqQL2KoPwEY=,tag:T+cSyzbGeo7E5smSsuFlHw==,type:str] -hoarder: ENC[AES256_GCM,data:8A3eGqIlHJ2XpC2OdMNBXPm+5BdfMlOfTSgiibPtM+SFyiPtGhjWQNmVCD9REf0P2C4pikZ3R7vtwyKpjrraaoSAY7ztAk9eqqikorIzD8hn8wbHz/y+Eko=,iv:ngoVgF348IxokWGQVpbpTGhdIwjOOA6T8qLb1wX6GEU=,tag:+v9HLUksQJ1e2vRR/5fzEg==,type:str] -recyclarr: ENC[AES256_GCM,data:3rZgs4Z/XaQPxbueepPQlUthHMSKn1e92FyIOpzn1MsGmEL8LBSUJvWp903n1BXDI+SK4ph9DaxOFavPkfCnaNMascX13TkGf03zGTEbd3xDZCL5GoXl3yobt0EMRYyRlYu5C1gidj9CjTujIaEXsF1AT2x0xtYweuC1xhpMhq2gj8eBy06sGnyKV/9Kdxo3H80skHVH6ZokndDyv6LfpkCDKQFsSBsEKBfVBDws7IgGFXCv6toWJPNgidReWzMmwKiClkviWAJiqAvI2IABRe4rEZ3Gkr3XFuoxOX2yfvQ1O7PH6O0dXvtfyBOTpGTaZihOqM1WhIutSr9SWX7QivIwtsVMGEmAmKx8JyDrnjhbCCbzjG+4Y6YoHawHYFFwKyOCxtJcsLBFvvkiuUt2ZVUVYCwhEIp3Xk2xb4cxYOIYRStxhiTuhEb8a9PkvkjmQQ4eAMB8bNPlo+vGqAQGPc6FOhm67dh3JbdQpsr9/U+P/AGsJM60SAhx+OzBcDSIS1U6/qJ6udXPOw58wXhJMD+F+gqV7blVBkXITQJ7AaLl/aWmDlkoqkjFVTIjE980e6ap6BuNbRGsN9x3EiVwqfDnqnQ2udGiLOcu/WguLzNjCvXWILoSYWwpEMwEW3SWASbGgk0wUpwZfNKY1HagdcVFO17OW9DrlTuGuJs4eJgVXm6e3glS3CS0dCL8FRs0EH4Rh8mUzhf9VP0/GlkN0kxJEM8PnjqGl0JMnaeQsSr9FDJdqv/2z4hjQBeq8//ER1BPIRSbXNQqZv5HcumSZs+JEttYUgInWL+LZhQrtpkba3sKQGkQF6X1kGpPZmiVSRgM+7PAt3ezpUKS8nMTS880l03cSaxMm+vebPhYtGC1O+4XLhv7E8MPULMkCOQoNLNcQCqKU82fa3vEtS28X6+izRMi56vbzG6Kjls85/NMGVz6rDySnQHMP5vSapcszSHwqGeAXJKfXYPzXQo1SIy0RlvRbllPt7zfOkTDMr52oH/pbtuxLSrSDe4ZjHkmdDzO+t0yAyG9xsvzldYUbDkfAWbnFXay3TICi5JOGe/Otp62sv3/7fjSmKm+9Um5AFj5F5Zo58LKCrH8qy2omIh80uFW0/yNgbuXmA4GqnDmYWaWlccc7yhPsmdAWHIypNS7GxRyW66+d4P7mhccvKGT7mx/gKuHgdUIRjy8bKtjLN2vuKfIiJR6bqWZGtbNEqY4XPfhdYdGdnox8vdrT/8DiR+6Jq+3qvJswTXhg+wYzOVTNjl8qK215VA2/FF25+T8xmSfV+cnPrLIrOrD8t1D34U4eEMrVzx+6dQ2dN1qDwj5o5GSYuYSQ5o5hy2BKt8PPVDI564MzjPfLaAf8cLK+0PKsbi2E4jGRI5BejmpMWHoLAUJvX4kdajd8Ggh5wZFS07pje3T1adzeS/UUnpy/IeLnEz8FfoH9ro7Qz0XGmtItVSjumppBg6jwbf1se9sP13pHfIh/SvVJhOOH6KiFs0lECSetuhIupsqHuJg6ZLa+V8GO9otYiJGZnOKGiZNrBYSek9l4Ncn/2Q+dqOYaCkZ8Xx6gY+qKHgiwavbsYYiJUPK3DLNhTzH,iv:00efefMekG2TsnDH3yNNdMBIITDyxo/qKN85qVGA6f8=,tag:hmwsyJRiT1MbFPKm4Kt5lw==,type:str] +recyclarr: ENC[AES256_GCM,data:eJNbGHb4SZvbF7FAHMrpRynmpVyPiTpyZqNx40Fo+lanqdm7d7oRhkLD2PfqxpTcIyV6BxJk12wGUC0uWVuAihmToL/Ih2FJWIQFUOdbaov/xNWHE9mtoRX/A3gIwD8e3DoFMK/dAk2/TyvvAfxi2eYTDJvxecEttHQGxafq1jveHFDcC9e1aFk3M8O8YlX5yF3zl90mugsUVP+iaSURnY/nglZuEDzfJ6Edge7r5OSL6WYh3OUIu1yzuuKXRZ47B/gpXO/cP89JMmxdPj3FUJkk7Htf0s9ALzpVE9fRohDGcpPIkR6COCLTL+mqvVmyopA1zPoX8/X8eiuocpaT3vqJit7Bc6InzflY/5rlg1x0SyoXWQfEsperfNBeiZGngp382I7rrZ8QSwF4AIsmngNeyDRAnfasAU5OVwK+yPIVhRueEFLNrJPG3j2hpArlzpvY2EPBVJDrYwFslis8CASoUdvu6C7VxtJXFcOZR8QemwJarJFU7v1bVhQoIkarn3V7FfAXg/8RfYrn9HAIq5AiFFbQRNHWXzIceIgNKQFb5yfagtMtMq6XKhjsV07jeYt9X/YU80XRfkPm05yiLdLQHcDNmlB3R+SFPD7qjTE7LuSH1Kdc3DvxwrKfHJLsJ+nSIL1po8gDMW8BPc0g4n4dpQ6CFK5BaDFK4eovNpgAXoRC9orkGw/16YmMozp6J78VJLzu3jcYMFbySFznDUuWcFf/7dVV+7pLAj2ffWXzScLISRBhZ9RNUMaZAKAk7WTmxBhw0yzNiih8OFUkbpp1FFLuU0bnBY0iEz+8/OSwv8H7t0HYe29HO61p1huH34B/ZkPA5VLKivFh2mOPNzbvMqtIAkq1ro82Psvc6t88gVIc+VAOZ9zDLohp0FXrNVXwnrs7fxevQa0pUClDivO1ib5G4Znor7q+13jZglmh3G7nHiniO607dRoxszzVEQdTn8ku3XAfIPStsSfQwH46nXhr2kDkspcA7BqwJph0dsKKlfzf22C0OJkDY0L1DgKFvJRmmKAhOdB6XxXYwS+BcDT+8ugejTKpulyPSsbdb0m9p9lVAVu0GMxFEbUsuE+QHiAAP5Vle7swpl4h3i8uHSfKFra3qEswwRnPAHhPSdLSaSU6O6T5gN/b0hhO6dAiNR0UOkOG59fPasL0MRpeb3SkM4Nd6g5b/hY8dXaXR7pQHvh+4GmfJFWYaWm/cZ8k9JAYAw9Sn/spWnjRmpv9bnSxADGbkdV8NDHquDDDFVIIoDnWhQJpqrL61KZITx2Ete1SYdNiy++p3mOYisJgHDsRR1RNQNxhRW4EY8c5nCzgc8x+rU432pCOfMbAuGEfQXMwMGFGeoUg6EL5xEyUEJ/aqymxI+Vjk8h7KfDnOyyL/+1BKEd/GccrjeQfeZGRLI0Tu5gVgL6twc+u4av6inNMMhPFzZuVrfeo6bip5C8R0dK6Pbdz2L/fsgn3E4NNi14NM/DgLLhJRLvKQdCQx+BT+3soNRw5htTzuNS48MD2YDwZYvNfu6mo0r4j4I7Tj8zuCjddbGVa2/5XnhcfdUBx1VOd90H1RKkk8kgSoR0bgo7mLls=,iv:HT3a2YnFy0cF9qUO671kwqxuzFfNnfqynCUVGHf+3dM=,tag:nrA++7fsnc4Cx0OPSDKaRw==,type:str] wireguard-pia: ENC[AES256_GCM,data:2IvJARGhesMuH9RdWzsyrwA7eqrhLyacQqZ1RNEkGOPUkQGX4uimKBSzkxXRy/haZ4V2k73JdLSaB9rAuI0n65GmWHmarwZekOyhRZSNb+zvFgw5BPZmywG1wR2HiTGR/qILovAaz47q/VnohUnjbbMCUvarC4PytWGxMUH96GIgZar8HjHFtK8grCSxlvpHKiDeKx8VSXnY/Pxj1EplBtIqwmtAeZdf/VjtwOL0nY54doPwHdIAvJ0B8Cu0a1zJIGEbV1NlKIHEJ1YA7rmv1ODkBnbXbIHMxAR3jeqR/UDqhDmXe41KujhiJI7nNeO7FKo2v92jK3fSbxYKatLrzXktHpE9JsMYVBXzTK7yAXPgoDdgLXzWH0OrJGBSisPrvqmxUko7MPreuwVYfFlKpll6JLifk8sML4A+94UPR8b89guXn7kBkLg1Y1oIAyguCdKpNOD31nXBMFF0nTcmCwyshDySaGTfJDgox65/77AiN1wH,iv:cdu6lBjLnEEfSFmWMC4Vn2sLKsvpCaatzXlgRNkEMeA=,tag:y1rAeNPB+DNGTpnP94iQrA==,type:str] signing-key: ENC[AES256_GCM,data:FrJzuTgH/ooZkcnYL55uQcc4u+QzNnFvNVs2wDSE4nnwku+EuCJBlb8pd/6W0KPwIXzcki/8CY0YfRcRrzjExMgMa4hwxrlxS9bk3LNPzJsrRK5RJgPg3iA8L791f1zcDxNf8RuWatIqm1TCK+Vhdk/p+221zy1Gcq1dW8X+o4XzbPBzHdLagcIdB0wpjYTtIoGP2X8GoL/NJpuzIiQBK1HdGNKvUI2+ztqCQZOsxm+Fki57NteX3/Llw8AwABjdZvviOBZ62OvJ/SsOQ9NYAvKfAkog5zCn8DLvaqAPGSxRBQEYWM8GyL2imgs54YfEsOpGa4DzMiv4Sc5m398E/asaPq357eksUqh3EYpzoKZ5bIbd5+Vs3KBWKHltUCzXLHaLrIX0CuJFQFi7DCxEbYqlb04x5t3jc/c+/7uwqBHv1Y5gwAjd8JswDWmE7Q3xSk96Za57SCxWPYTo2ErsA2XdL+yxXdhmqkhDZKtUzrcHExhnYe7YLpSlBEclJ/G2BeTOFIWoAmN+1y4rh21R,iv:VaZrv5/41ZyIax702Yae4QmFKpcEaWwPmTo2Mxao3bU=,tag:HC0eqDNit7jQKeeDAKWXKg==,type:str] signing-pub-key: ENC[AES256_GCM,data:CB7uU2Q4oTEKihpTIXGLaV0fJ1cv/p4oJJ5kjaU6BZiKhsiMA1JILUw2oVIDTDb+80WPzolDzZwWM8v31d5QIrZpHcPrdRLyV0X2USfG9U4aQ/ls79QAyOOJXA==,iv:/Eb5/+p86tw3tqNiDVHGu7HS1KBtFiYIgasRYJsAiEo=,tag:dGdJlcrnuU73s+IMQ3w3hA==,type:str] @@ -20,7 +17,7 @@ sops: TEc5d01RaVFGNXc3dlljM0FTTHpENjQKOqwI+pl8UxVIVl43glnOYvW660/PsDGY yefODJGVtHrOm3yeXC2xlTi3sFW+c5wUl2yPqddbvcBt5Ud/yd4iXQ== -----END AGE ENCRYPTED FILE----- - lastmodified: "2026-01-03T22:36:21Z" - mac: ENC[AES256_GCM,data:5xF+o8eyeXJBblC96xzvozDjrsrlNIo3sLep/pAcWEcYQU6ya4wg8iiE5wZh+KfqD47R0JV2jbcrrkdWTfo3j/HsDRCeFz68HRsgZRO00pV7gRJmE+tPhXvCiJRYYYQQ+TCmgraWLatPW8Ru4qt807aQiOTgCn/MCfNAvafjcBg=,iv:4XMobDIzpEGyIg8BHS51ch3bNYal5gsAI7L9epGWiaM=,tag:vwpKbJ3a/zUXyBa1txS7pw==,type:str] + lastmodified: "2026-01-04T23:46:09Z" + mac: ENC[AES256_GCM,data:naRZouoaaabUEEYIvpMayzGZ63cHu7zWUbHA6HmoqrkH5MvLDsUrdKymsj5an38egsBoOcoONTIA5sicZel6LmpN6BdNNvMr2UX1GEzJ6k0XZHW0K78MiQ1PYesrlvzNZ7pFN0kqL/u/Ed+E90TVB566p44lUkHh0oHr9WuUIBI=,iv:nnwl2NgYOS7HOHzJ9B9Qt0oDiE8cjE/jWEYTAx+Ugxc=,tag:cHeg7TR7dGcnxXxcVaEvew==,type:str] unencrypted_suffix: _unencrypted version: 3.11.0 diff --git a/server-modules/adguardhome.nix b/server-modules/adguardhome.nix index af3c52a..358ed8a 100644 --- a/server-modules/adguardhome.nix +++ b/server-modules/adguardhome.nix @@ -1,20 +1,10 @@ # Adguard is a network-wide ad blocker # When installed, open localhost:3000 to setup -{config, ...}: let - domain = "adguard.hadi.diy"; -in { - services = { - adguardhome = { - enable = true; - port = 3000; - }; - - nginx.virtualHosts."${domain}" = { - useACMEHost = "hadi.diy"; - forceSSL = true; - locations."/" = { - proxyPass = "http://127.0.0.1:${toString config.services.adguardhome.port}"; - }; - }; +{config, ...}: { + services.adguardhome = { + enable = true; + port = 3000; }; + + services.cloudflared.tunnels."f7c8f777-a36c-4b9a-b6e3-6a112bd43e73".ingress."adguard.hadi.diy" = "http://localhost:${toString config.services.adguardhome.port}"; } diff --git a/server-modules/arr.nix b/server-modules/arr.nix index 085e167..decaecc 100644 --- a/server-modules/arr.nix +++ b/server-modules/arr.nix @@ -2,12 +2,6 @@ # See https://github.com/rasmus-kirk/nixarr # Setup guide: https://nixarr.com/wiki/setup/ {config, ...}: let - domain = "hadi.diy"; - mkVirtualHost = port: { - useACMEHost = domain; - forceSSL = true; - locations."/" = {proxyPass = "http://127.0.0.1:${toString port}";}; - }; username = config.var.username; in { # Add my secrets @@ -43,7 +37,11 @@ in { readarr.enable = true; transmission = { enable = true; - extraSettings = {trash-original-torrent-files = true;}; + extraSettings = { + trash-original-torrent-files = true; + rpc-whitelist-enabled = false; + rpc-host-whitelist-enabled = false; + }; vpn.enable = true; }; recyclarr = { @@ -52,14 +50,14 @@ in { }; }; - services.nginx.virtualHosts = { - "media.${domain}" = mkVirtualHost 8096; - "demandemedia.${domain}" = mkVirtualHost 5055; - "bazarr.${domain}" = mkVirtualHost 6767; - "prowlarr.${domain}" = mkVirtualHost 9696; - "radarr.${domain}" = mkVirtualHost 7878; - "sonarr.${domain}" = mkVirtualHost 8989; - "transmission.${domain}" = mkVirtualHost 9091; - "readarr.${domain}" = mkVirtualHost 8787; + services.cloudflared.tunnels."f7c8f777-a36c-4b9a-b6e3-6a112bd43e73".ingress = { + "media.hadi.diy" = "http://localhost:8096"; + "demandemedia.hadi.diy" = "http://localhost:5055"; + "bazarr.hadi.diy" = "http://localhost:6767"; + "prowlarr.hadi.diy" = "http://localhost:9696"; + "radarr.hadi.diy" = "http://localhost:7878"; + "sonarr.hadi.diy" = "http://localhost:8989"; + "transmission.hadi.diy" = "http://localhost:9091"; + "readarr.hadi.diy" = "http://localhost:8787"; }; } diff --git a/server-modules/bitwarden.nix b/server-modules/bitwarden.nix deleted file mode 100644 index 51af04d..0000000 --- a/server-modules/bitwarden.nix +++ /dev/null @@ -1,27 +0,0 @@ -# Bitwarden (or vaultwarden) is a self-hosted password manager. -{config, ...}: let - domain = "vault.hadi.diy"; -in { - services = { - vaultwarden = { - enable = true; - config = { - DOMAIN = "https://" + domain; - SIGNUPS_ALLOWED = true; - ROCKET_ADDRESS = "127.0.0.1"; - ROCKET_PORT = 8222; - ROCKET_LOG = "critical"; - }; - }; - - nginx.virtualHosts."${domain}" = { - useACMEHost = "hadi.diy"; - forceSSL = true; - locations."/" = { - proxyPass = "http://127.0.0.1:${ - toString config.services.vaultwarden.config.ROCKET_PORT - }"; - }; - }; - }; -} diff --git a/server-modules/cloudflared.nix b/server-modules/cloudflared.nix index 4ecde03..f7ebb8f 100644 --- a/server-modules/cloudflared.nix +++ b/server-modules/cloudflared.nix @@ -3,24 +3,17 @@ pkgs, ... }: { - sops.secrets = { - cloudflared-token = { - mode = "0400"; - }; - }; + sops.secrets.cloudflared-token.mode = "0400"; + # To setup cloudflared, run + # cloudflared tunnel login + # cloudflared tunnel create JackTunnel + # This will create a credentials file & give you the tunnel ID to use below. services.cloudflared = { enable = true; - tunnels = { - "f7c8f777-a36c-4b9a-b6e3-6a112bd43e73" = { - credentialsFile = config.sops.secrets."cloudflared-token".path; - default = "http_status:404"; - ingress = { - "media.hadi.diy" = "http://localhost:443"; - "demandemedia.hadi.diy" = "http://localhost:443"; - "ssh.hadi.diy" = "ssh://localhost:22"; - }; - }; + tunnels."f7c8f777-a36c-4b9a-b6e3-6a112bd43e73" = { + credentialsFile = config.sops.secrets."cloudflared-token".path; + default = "http_status:404"; }; }; diff --git a/server-modules/cyberchef.nix b/server-modules/cyberchef.nix new file mode 100644 index 0000000..cd85b36 --- /dev/null +++ b/server-modules/cyberchef.nix @@ -0,0 +1,14 @@ +{pkgs, ...}: { + services = { + nginx.virtualHosts."cyberchef.local" = { + root = "${pkgs.cyberchef}/share/cyberchef"; + listen = [ + { + addr = "127.0.0.1"; + port = 8754; + } + ]; + }; + cloudflared.tunnels."f7c8f777-a36c-4b9a-b6e3-6a112bd43e73".ingress."cyberchef.hadi.diy" = "http://localhost:8754"; + }; +} diff --git a/server-modules/eleakxir.nix b/server-modules/eleakxir.nix index b649b0e..ed76589 100644 --- a/server-modules/eleakxir.nix +++ b/server-modules/eleakxir.nix @@ -13,7 +13,7 @@ user = "eleakxir"; group = "eleakxir"; limit = 1000; - folders = ["/var/lib/eleakxir/leaks/" "/mnt/data/clean-leak/"]; + folders = ["/var/lib/eleakxir/leaks/" "/mnt/data/big-leaks/"]; debug = true; }; @@ -21,13 +21,5 @@ inputs.eleakxir.packages.${pkgs.stdenv.hostPlatform.system}.leak-utils ]; - services.nginx.virtualHosts."eleakxir-back.hadi.diy" = { - useACMEHost = "hadi.diy"; - forceSSL = true; - locations."/" = { - proxyPass = "http://127.0.0.1:${ - toString config.services.eleakxir.port - }"; - }; - }; + services.cloudflared.tunnels."f7c8f777-a36c-4b9a-b6e3-6a112bd43e73".ingress."eleakxir-back.hadi.diy" = "http://localhost:${toString config.services.eleakxir.port}"; } diff --git a/server-modules/fail2ban.nix b/server-modules/fail2ban.nix new file mode 100644 index 0000000..2be9e75 --- /dev/null +++ b/server-modules/fail2ban.nix @@ -0,0 +1,13 @@ +{ + services.fail2ban = { + enable = true; + maxretry = 5; + bantime = "24h"; # Ban IPs for one day on the first ban + bantime-increment = { + enable = true; # Enable increment of bantime after each violation + multipliers = "1 2 4 8 16 32 64"; + maxtime = "168h"; # Do not ban for more than 1 week + overalljails = true; # Calculate the bantime based on all the violations + }; + }; +} diff --git a/server-modules/glance.nix b/server-modules/glance.nix index d7c06a1..229aed7 100644 --- a/server-modules/glance.nix +++ b/server-modules/glance.nix @@ -33,7 +33,6 @@ in lib.concatMapStringsSep " " roundToString [h s l]; in { - # TODO: Add tailscale custom widget services = { glance = { enable = true; @@ -318,15 +317,6 @@ in { server = {port = 5678;}; }; }; - nginx.virtualHosts."${domain}" = { - useACMEHost = "hadi.diy"; - forceSSL = true; - locations."/" = { - proxyPass = "http://127.0.0.1:${ - toString config.services.glance.settings.server.port - }"; - }; - }; }; systemd.services.glance = { @@ -350,4 +340,6 @@ in { owner = "glance"; mode = "0600"; }; + + services.cloudflared.tunnels."f7c8f777-a36c-4b9a-b6e3-6a112bd43e73".ingress."start.hadi.diy" = "http://localhost:${toString config.services.glance.settings.server.port}"; } diff --git a/server-modules/linkding.nix b/server-modules/linkding.nix new file mode 100644 index 0000000..4e6dd1d --- /dev/null +++ b/server-modules/linkding.nix @@ -0,0 +1,23 @@ +{...}: let + port = 9090; +in { + virtualisation.oci-containers.containers.linkding = { + autoStart = true; + image = "sissbruecker/linkding@sha256:6d4fcc50bee8ee054ad2dfebbc41217f325398b907aff7ec011996c6a5ec17c9"; + volumes = ["/var/lib/linkding/data:/etc/linkding/data"]; + ports = ["${builtins.toString port}:${builtins.toString port}"]; + }; + + # Ensure our mount point exists + systemd.tmpfiles.settings."10-linkding" = { + "/var/lib/linkding/data" = { + d = { + mode = "0755"; + user = "root"; + group = "root"; + }; + }; + }; + + services.cloudflared.tunnels."f7c8f777-a36c-4b9a-b6e3-6a112bd43e73".ingress."linkding.hadi.diy" = "http://localhost:${toString port}"; +} diff --git a/server-modules/mazanoke.nix b/server-modules/mazanoke.nix new file mode 100644 index 0000000..e42321f --- /dev/null +++ b/server-modules/mazanoke.nix @@ -0,0 +1,35 @@ +{pkgs, ...}: let + version = "1.1.5"; # Ajuste la version si nécessaire + mazanoke-pkg = pkgs.stdenv.mkDerivation { + inherit version; + pname = "mazanoke"; + src = pkgs.fetchFromGitHub { + owner = "civilblur"; + repo = "mazanoke"; + rev = "v${version}"; + hash = "sha256-B/AF4diMNxN94BzpZP/C+K8kNj9q+4SDKWa/qd4LrVU="; + }; + + # On utilise installPhase pour copier les fichiers vers $out + installPhase = '' + mkdir -p $out/share/mazanoke + cp -r ./index.html ./favicon.ico ./manifest.json ./service-worker.js ./assets $out/share/mazanoke/ + ''; + }; +in { + services = { + nginx.virtualHosts."mazanoke.local" = { + root = "${mazanoke-pkg}/share/mazanoke"; + locations."/" = { + index = "index.html"; + }; + listen = [ + { + addr = "127.0.0.1"; + port = 8755; + } + ]; + }; + cloudflared.tunnels."f7c8f777-a36c-4b9a-b6e3-6a112bd43e73".ingress."mazanoke.hadi.diy" = "http://localhost:8755"; + }; +} diff --git a/server-modules/mealie.nix b/server-modules/mealie.nix index 78007f7..054307f 100644 --- a/server-modules/mealie.nix +++ b/server-modules/mealie.nix @@ -1,19 +1,9 @@ # Mealie is a recipe management and meal planning application. -{config, ...}: let - domain = "mealie.hadi.diy"; -in { - services = { - mealie = { - enable = true; - port = 8092; - }; - - nginx.virtualHosts."${domain}" = { - useACMEHost = "hadi.diy"; - forceSSL = true; - locations."/" = { - proxyPass = "http://127.0.0.1:${toString config.services.mealie.port}"; - }; - }; +{config, ...}: { + services.mealie = { + enable = true; + port = 8092; }; + + services.cloudflared.tunnels."f7c8f777-a36c-4b9a-b6e3-6a112bd43e73".ingress."mealie.hadi.diy" = "http://localhost:${toString config.services.mealie.port}"; } diff --git a/server-modules/nginx.nix b/server-modules/nginx.nix index 0f0bb24..a556ccd 100644 --- a/server-modules/nginx.nix +++ b/server-modules/nginx.nix @@ -1,45 +1,5 @@ -# Nginx is a web server that can also be used as a reverse proxy, load balancer, and HTTP cache. -{config, ...}: let - domain = "hadi.diy"; -in { - security.acme = { - acceptTerms = true; - defaults.email = config.var.git.email; - certs."${domain}" = { - domain = "${domain}"; - extraDomainNames = ["*.${domain}"]; - group = "nginx"; - dnsProvider = "cloudflare"; - dnsPropagationCheck = true; - credentialsFile = config.sops.secrets.cloudflare-dns-token.path; - }; - }; - - # Return 444 for all requests not matching a used subdomain. +{ services.nginx = { enable = true; - virtualHosts = { - "default" = { - default = true; - locations."/" = {return = 444;}; - }; - "*.${domain}" = { - useACMEHost = domain; - forceSSL = true; - locations."/" = {return = 444;}; - }; - "aaaaaa.${domain}" = { - useACMEHost = domain; - forceSSL = true; - locations."/" = {return = 444;}; - }; - }; }; - - networking.firewall = { - allowedTCPPorts = [80 443]; - allowedUDPPorts = [80 443]; - }; - - sops.secrets.cloudflare-dns-token = {path = "/etc/cloudflare/dnskey.txt";}; } diff --git a/server-modules/ssh.nix b/server-modules/ssh.nix index d162549..d9ec325 100644 --- a/server-modules/ssh.nix +++ b/server-modules/ssh.nix @@ -14,9 +14,9 @@ in { }; # Add my public SSH key to my user - users.users."${username}" = { - openssh.authorizedKeys.keys = [ - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPG9SE80ZyBcXZK/f5ypSKudaM5Jo3XtQikCnGo0jI5E hadi@nixy" - ]; - }; + users.users."${username}".openssh.authorizedKeys.keys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPG9SE80ZyBcXZK/f5ypSKudaM5Jo3XtQikCnGo0jI5E hadi@nixy" + ]; + + services.cloudflared.tunnels."f7c8f777-a36c-4b9a-b6e3-6a112bd43e73".ingress."ssh.hadi.diy" = "ssh://localhost:22"; } diff --git a/server-modules/stirling-pdf.nix b/server-modules/stirling-pdf.nix new file mode 100644 index 0000000..d4dfd75 --- /dev/null +++ b/server-modules/stirling-pdf.nix @@ -0,0 +1,8 @@ +{config, ...}: { + services.stirling-pdf = { + enable = true; + environment."SERVER_PORT" = "8083"; + }; + + services.cloudflared.tunnels."f7c8f777-a36c-4b9a-b6e3-6a112bd43e73".ingress."pdf.hadi.diy" = "http://localhost:${toString config.services.stirling-pdf.environment.SERVER_PORT}"; +}