From 8b01e35da7b3632ac41220448ae2fe9290367506 Mon Sep 17 00:00:00 2001 From: Alex Stan Date: Thu, 29 Feb 2024 01:53:07 +0200 Subject: [PATCH] e Signed-off-by: Alex Stan --- .gitignore | 1 + hosts/hypnos/services/caddy.nix | 19 ++ hosts/hypnos/services/cloud.nix | 24 ++ hosts/hypnos/services/dnsmasq.nix | 19 ++ hosts/hypnos/services/forge.nix | 28 +++ hosts/hypnos/services/lemmy.nix | 231 ++++++++++++++++++++ hosts/hypnos/services/lemmy_credentials.txt | 2 + hosts/hypnos/services/mail-server.nix | 30 +++ hosts/hypnos/services/matrix.nix | 36 +++ hosts/hypnos/services/office.nix | 8 + hosts/hypnos/services/vaultwarden.nix | 12 + 11 files changed, 410 insertions(+) create mode 100644 hosts/hypnos/services/caddy.nix create mode 100644 hosts/hypnos/services/cloud.nix create mode 100644 hosts/hypnos/services/dnsmasq.nix create mode 100644 hosts/hypnos/services/forge.nix create mode 100644 hosts/hypnos/services/lemmy.nix create mode 100644 hosts/hypnos/services/lemmy_credentials.txt create mode 100644 hosts/hypnos/services/mail-server.nix create mode 100644 hosts/hypnos/services/matrix.nix create mode 100644 hosts/hypnos/services/office.nix create mode 100644 hosts/hypnos/services/vaultwarden.nix diff --git a/.gitignore b/.gitignore index ae013ac..26ddae5 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ hosts/titan/services/Sharkey/.config/* hosts/titan/services/Sharkey/files hosts/titan/services/Sharkey/db hosts/titan/services/Sharkey/redis +hosts/hypnos/services/Sharkey/* diff --git a/hosts/hypnos/services/caddy.nix b/hosts/hypnos/services/caddy.nix new file mode 100644 index 0000000..8760a49 --- /dev/null +++ b/hosts/hypnos/services/caddy.nix @@ -0,0 +1,19 @@ +inputs: { config, ... }: { + services.caddy = { + enable = true; + /* + virtualHosts = { + "https://gra.phite.ro".extraConfig = '' + root * /home/ultra/code/html/blog + ''; + "https://git.gra.phite.ro".extraConfig = '' + reverse_proxy :3000 + ''; + "https://phite.ro".extraConfig = '' + redir https://gra.phite.ro{uri} permanent + ''; + }; + */ + configFile = /home/ultra/code/html/blog/Caddyfile; + }; +} diff --git a/hosts/hypnos/services/cloud.nix b/hosts/hypnos/services/cloud.nix new file mode 100644 index 0000000..193dd32 --- /dev/null +++ b/hosts/hypnos/services/cloud.nix @@ -0,0 +1,24 @@ +inputs: { pkgs, config, ... }: { + services.nextcloud = { + enable = true; + package = pkgs.nextcloud27; + hostName = "localhost"; + config = { + adminpassFile = "/var/keys/nextcloud_initial_password"; + extraTrustedDomains = [ + "cloud.gra.phite.ro" + ]; + overwriteProtocol = "https"; + }; + extraApps = with config.services.nextcloud.package.packages.apps; { + inherit news files_markdown files_texteditor forms maps memories music onlyoffice polls calendar tasks contacts; + }; + /* + extraOptions = { + trusted_domains = [ "https://cloud.gra.phite.ro" ]; + }; + */ + extraAppsEnable = true; + }; + services.nginx.virtualHosts."localhost".listen = [ { addr = "127.0.0.1"; port = 3001; } ]; +} diff --git a/hosts/hypnos/services/dnsmasq.nix b/hosts/hypnos/services/dnsmasq.nix new file mode 100644 index 0000000..8e0969f --- /dev/null +++ b/hosts/hypnos/services/dnsmasq.nix @@ -0,0 +1,19 @@ +inputs: { config, pkgs, ... }: { + services.dnsmasq = { + enable = true; + settings = { + server = [ + "9.9.9.9" + "8.8.8.8" + ]; + listen-address = [ + "192.168.100.35" + ]; + resolv-file = '' + ${pkgs.writeText "$out/resolv.conf" '' + 5.12.179.165 gra.phite.ro + ''} + ''; + }; + }; +} diff --git a/hosts/hypnos/services/forge.nix b/hosts/hypnos/services/forge.nix new file mode 100644 index 0000000..4f5afe7 --- /dev/null +++ b/hosts/hypnos/services/forge.nix @@ -0,0 +1,28 @@ +inputs: { config, pkgs, ... }: { + services = { + /* + postgresql = { + ensureDatabases = [ config.services.gitea.user ]; + ensureUsers = [ + { + name = config.services.gitea.database.user; + ensurePermissions."DATABASE ${config.services.gitea.database.name}" = "ALL PRIVILEGES"; + } + ]; + }; + */ + gitea = { + enable = true; + package = pkgs.forgejo; + appName = "Graphite's Forge"; + domain = "git.gra.phite.ro"; + rootUrl = "https://git.gra.phite.ro"; + settings = { + server = { + HTTP_PORT = 3004; + }; + }; + lfs.enable = true; + }; + }; +} diff --git a/hosts/hypnos/services/lemmy.nix b/hosts/hypnos/services/lemmy.nix new file mode 100644 index 0000000..2364c1b --- /dev/null +++ b/hosts/hypnos/services/lemmy.nix @@ -0,0 +1,231 @@ +inputs: { config, pkgs, lib, ... } : +let + + # add nginx reverse proxy and ACME web certificate + add_nginx = true; + nginx_ports = [ 80 443 ]; + + lemmy = { + upstreamName = "lemmy"; + dataDir = "/var/lib/lemmy"; + ip = "127.0.0.1"; + port = 1234; + domain = "lemmy.gra.phi.te"; + }; + + lemmy-ui = { + upstreamName = "lemmy-ui"; + ip = "127.0.0.1"; + port = 8536; + }; + + pict-rs = { + ip = "127.0.0.1"; + port = 8080; + }; + + acmeDomain = lemmy.domain; + nginxVhost = lemmy.domain; + +in { + + security.acme = lib.mkIf add_nginx { + acceptTerms = true; + defaults = { + email = "ultra980@proton.me"; + dnsProvider = "cloudflare"; + credentialsFile = ./lemmy_credentials.txt; + }; + certs."${acmeDomain}" = { + domain = "${acmeDomain}"; + }; + }; + + networking.firewall.allowedTCPPorts = lib.mkIf add_nginx nginx_ports; + + # is needed because of certificate file permissions + users.users.nginx.extraGroups = lib.mkIf add_nginx ["acme"]; + + services.nginx = lib.mkIf add_nginx { + upstreams."${lemmy.upstreamName}".servers."${lemmy.ip}:${builtins.toString lemmy.port}" = {}; + upstreams."${lemmy-ui.upstreamName}".servers."${lemmy-ui.ip}:${builtins.toString lemmy-ui.port}" = {}; + + virtualHosts."${nginxVhost}" = { + useACMEHost = "${acmeDomain}"; + # inherit from config.security.acme.acmeRoot; + acmeRoot = null; + # add redirects from http to https + forceSSL = true; + # this whole block was lifted from https://github.com/LemmyNet/lemmy/blob/ef1aa18fd20cc03d492a81cb70cc75cf3281649f/docker/nginx.conf#L21 lines 21-32 + extraConfig = '' + # disables emitting nginx version on error pages and in the “Server” response header field + server_tokens off; + + gzip on; + gzip_types text/css application/javascript image/svg+xml; + gzip_vary on; + + # Upload limit, relevant for pictrs + client_max_body_size 20M; + + add_header X-Frame-Options SAMEORIGIN; + add_header X-Content-Type-Options nosniff; + add_header X-XSS-Protection "1; mode=block"; + ''; + + locations = { + "/" = { + # we do not use the nixos "locations..proxyPass" option because the nginx config needs to do something fancy. + # again, lifted wholesale from https://github.com/LemmyNet/lemmy/blob/ef1aa18fd20cc03d492a81cb70cc75cf3281649f/docker/nginx.conf#L36 lines 36-55 + extraConfig = '' + # distinguish between ui requests and backend + # don't change lemmy-ui or lemmy here, they refer to the upstream definitions on top + set $proxpass "http://${lemmy-ui.upstreamName}"; + + if ($http_accept = "application/activity+json") { + set $proxpass "http://${lemmy.upstreamName}"; + } + if ($http_accept = "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"") { + set $proxpass "http://${lemmy.upstreamName}"; + } + if ($request_method = POST) { + set $proxpass "http://${lemmy.upstreamName}"; + } + proxy_pass $proxpass; + + # Cuts off the trailing slash on URLs to make them valid + rewrite ^(.+)/+$ $1 permanent; + + # Send actual client IP upstream + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + ''; + }; + + # again, lifted wholesale from https://github.com/LemmyNet/lemmy/blob/ef1aa18fd20cc03d492a81cb70cc75cf3281649f/docker/nginx.conf#L60 lines 60-69 (nice!) + "~ ^/(api|pictrs|feeds|nodeinfo|.well-known)" = { + proxyPass = "http://${lemmy.upstreamName}"; + extraConfig = '' + # proxy common stuff + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + + ## Send actual client IP upstream + #proxy_set_header X-Real-IP $remote_addr; + #proxy_set_header Host $host; + #proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + ''; + }; + }; + }; + }; + + systemd.services.lemmy-ui = { + environment = { + LEMMY_UI_HOST = lib.mkForce "${lemmy-ui.ip}:${toString lemmy-ui.port}"; + LEMMY_UI_LEMMY_INTERNAL_HOST = lib.mkForce "${lemmy.ip}:${toString lemmy.port}"; + LEMMY_UI_LEMMY_EXTERNAL_HOST = lib.mkForce lemmy.domain ; + LEMMY_UI_HTTPS="true"; + }; + }; + + services.pict-rs = { + enable = true; + port = pict-rs.port; + dataDir = "${dataDir}/pict-rs"; + address = pict-rs.ip; + }; + + systemd.services.lemmy = { + requires = ["postgresql.service"]; + after = ["postgresql.service"]; + environment = { + LEMMY_DATABASE_URL = lib.mkForce "postgresql://lemmy@127.0.0.1:${toString config.services.postgresql.port}/lemmy"; + }; + }; + + services.lemmy = { + enable = true; + ui.port = lemmy-ui.port; + database.createLocally = true; + settings = { + # TODO: Enable this much later when you tested everything. + # N.B. you can't change your domain name after enabling this. + federation.enabled = false; + # settings related to the postgresql database + database = { + user = "lemmy"; + password = "secretlemmypassword"; + host = "127.0.0.1"; + port = ${config.services.postgresql.port}; + database = "lemmy"; + pool_size = 5; + }; + /* + # Pictrs image server configuration. + pictrs = { + # Address where pictrs is available (for image hosting) + url = "http://${pict-rs.ip}:${toString pict-rs.port}/"; + # TODO: Set a custom pictrs API key. ( Required for deleting images ) + api_key = ""; + }; + */ + # TODO: Email sending configuration. All options except login/password are mandatory + email = { + # Hostname and port of the smtp server + smtp_server = ""; + # Login name for smtp server + smtp_login = ""; + # Password to login to the smtp server + smtp_password = ""; + # Address to send emails from, eg "noreply@your-instance.com"; + smtp_from_address = "noreply@${lemmy.domain}"; + # Whether or not smtp connections should use tls. Can be none, tls, or starttls + tls_type = "none"; + }; + # TODO: Parameters for automatic configuration of new instance (only used at first start) + setup = { + # Username for the admin user + admin_username = "superawesomeadmin"; + # Password for the admin user. It must be at least 10 characters. + admin_password = ""; + # Name of the site (can be changed later) + site_name = "Lemmy at ${lemmy.domain}"; + # Email for the admin user (optional, can be omitted and set later through the website) + admin_email = "admin@${lemmy.domain}"; + }; + # the domain name of your instance (mandatory) + hostname = lemmy.domain; + # Address where lemmy should listen for incoming requests + bind = lemmy.ip; + # Port where lemmy should listen for incoming requests + port = lemmy.port; + # Whether the site is available over TLS. Needs to be true for federation to work. + tls_enabled = true; + }; + + }; + + + # needed for now + nixpkgs.config.permittedInsecurePackages = [ + "nodejs-14.21.3" + "openssl-1.1.1t" + ]; + + system.activationScripts."make_sure_lemmy_user_owns_files" = '' + uid='${config.users.users.lemmy.uid}'; + gid='${config.users.groups.lemmy.gid}'; + dir='${lemmy.dataDir}' + + mkdir -p "''${dir}" + + if [[ "$(${pkgs.toybox}/bin/stat "''${dir}" -c '%u:%g' | tee /dev/stderr )" != "''${uid}:''${gid}" ]]; then + chown -R "''${uid}:''${gid}" "''${dir}" + fi + ''; + }; + }; +} diff --git a/hosts/hypnos/services/lemmy_credentials.txt b/hosts/hypnos/services/lemmy_credentials.txt new file mode 100644 index 0000000..60fd5b3 --- /dev/null +++ b/hosts/hypnos/services/lemmy_credentials.txt @@ -0,0 +1,2 @@ +CLOUDFLARE_EMAIL=ultra980@proton.me +CLOUDFLARE_API_KEY=vlu4ukCvUSXXbh3wDBL7xXTmmjLWrmupV4dRilcC diff --git a/hosts/hypnos/services/mail-server.nix b/hosts/hypnos/services/mail-server.nix new file mode 100644 index 0000000..51eb49c --- /dev/null +++ b/hosts/hypnos/services/mail-server.nix @@ -0,0 +1,30 @@ +inputs: { config, pkgs, ... }: { + imports = [ + inputs.mailserver.nixosModules.default + ]; + mailserver = { + enable = true; + fqdn = "mail.gra.phite.ro"; + domains = [ "gra.phite.ro" ]; + + loginAccounts = { + "alex@gra.phite.ro" = { + aliases = [ + "postmaster@gra.phite.ro" + "ultra@gra.phite.ro" + "graphite@gra.phite.ro" + "me@gra.phite.ro" + "webmaster@gra.phite.ro" + "security@gra.phite.ro" + ]; + hashedPasswordFile = "/home/ultra/hashed_mail_password.txt"; + }; + }; + certificateScheme = "acme-nginx"; + }; + security.acme = { + acceptTerms = true; + email = "security@gra.phite.ro"; + }; + +} diff --git a/hosts/hypnos/services/matrix.nix b/hosts/hypnos/services/matrix.nix new file mode 100644 index 0000000..d4c6b6b --- /dev/null +++ b/hosts/hypnos/services/matrix.nix @@ -0,0 +1,36 @@ +inputs: { pkgs, ... }: { + services.postgresql.enable = true; + services.postgresql.initialScript = pkgs.writeText "synapse-init.sql" '' + CREATE ROLE "matrix-synapse" WITH LOGIN PASSWORD 'synapse'; + CREATE DATABASE "matrix-synapse" WITH OWNER "matrix-synapse" + TEMPLATE template0 + LC_COLLATE = "C" + LC_CTYPE = "C"; + ''; + services.matrix-synapse = { + enable = true; + settings = { + registration_shared_secret_path = "/var/synapse/.synapseregsec"; + server_name = "gra.phite.ro"; + public_baseurl = "https://matrix.gra.phite.ro"; + listeners = [ + { + port = 3003; + bind_addresses = [ "127.0.0.1" ]; + + # Caddy handles HTTPS and TLS + type = "http"; + tls = false; + + x_forwarded = true; + resources = [ + { + names = [ "client" "federation" ]; + compress = true; + } + ]; + } + ]; + }; + }; +} diff --git a/hosts/hypnos/services/office.nix b/hosts/hypnos/services/office.nix new file mode 100644 index 0000000..1acd943 --- /dev/null +++ b/hosts/hypnos/services/office.nix @@ -0,0 +1,8 @@ +inputs: { ... }: { + services.onlyoffice = { + enable = true; + hostname = "localhost"; + port = 3005; + }; + services.nginx.virtualHosts."localhost".listen = [ { addr = "127.0.0.1"; port = 3005; } ]; +} diff --git a/hosts/hypnos/services/vaultwarden.nix b/hosts/hypnos/services/vaultwarden.nix new file mode 100644 index 0000000..8453e81 --- /dev/null +++ b/hosts/hypnos/services/vaultwarden.nix @@ -0,0 +1,12 @@ +inputs: { config, pkgs, ... }: { + services.vaultwarden = { + enable = true; + backupDir = "/var/vaultwarden/backups"; + config = { + ROCKET_ADDRESS = "127.0.0.1"; + ROCKET_PORT = 3002; + DOMAIN = "https://pwd.gra.phite.ro"; + SIGNUPS_ALLOWED = false; + }; + }; +}