From efe21725f8d68a6be6fb3c4697c88666d11b13a8 Mon Sep 17 00:00:00 2001 From: Preston Pan Date: Sat, 14 Feb 2026 22:42:19 -0800 Subject: fix internet again for real this time --- nix/modules/configuration.nix | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'nix') diff --git a/nix/modules/configuration.nix b/nix/modules/configuration.nix index 128ad5b..e09571b 100644 --- a/nix/modules/configuration.nix +++ b/nix/modules/configuration.nix @@ -110,12 +110,16 @@ country=CA "snd-rawmidi" "xhci_hcd" "kvm_intel" - "crm" + "af_packet" + "ccm" "ctr" "cmac" "arc4" "ecb" "michael_mic" + "gcm" + "sha256" + "sha384" ]; kernelParams = [ -- cgit v1.3 From 06198567765055febc8829f9f2ca398dd6817d93 Mon Sep 17 00:00:00 2001 From: Preston Pan Date: Mon, 16 Feb 2026 23:13:47 -0800 Subject: finish up most of the sysadmin work --- config/elfeed.org | 2 + config/emacs.org | 6 + config/nix.org | 382 ++++++++++++++++++++++++++++++++-- index.org | 6 +- nix/data/public-inbox.css | 143 +++++++++++++ nix/init.el | 6 + nix/modules/conduit.nix | 2 +- nix/modules/configuration.nix | 10 + nix/modules/gotosocial.nix | 14 ++ nix/modules/home/default.nix | 6 +- nix/modules/home/emacs.nix | 1 + nix/modules/home/mpd.nix | 10 +- nix/modules/home/user.nix | 8 + nix/modules/maddy.nix | 6 + nix/modules/matrix-appservice-irc.nix | 10 + nix/modules/nginx.nix | 42 +++- nix/modules/public_inbox.nix | 82 ++++++++ nix/modules/secrets.nix | 24 +++ nix/secrets/secrets.yaml | 8 +- nix/secrets/vps_secrets.yaml | 7 +- nix/systems/home.nix | 1 + nix/systems/spontaneity/default.nix | 4 + 22 files changed, 738 insertions(+), 42 deletions(-) create mode 100644 nix/data/public-inbox.css create mode 100644 nix/modules/gotosocial.nix create mode 100644 nix/modules/matrix-appservice-irc.nix create mode 100644 nix/modules/public_inbox.nix (limited to 'nix') diff --git a/config/elfeed.org b/config/elfeed.org index b659f8e..c114294 100644 --- a/config/elfeed.org +++ b/config/elfeed.org @@ -22,6 +22,8 @@ This is a podcast by Luke Smith that talks about anything that he wants to. ** Forums :forum: *** [[http://lesserwrong.com/feed.xml][LessWrong]] The birthplace of bay area rationalism. +*** [[https://list.nullring.xyz/discussion/new.atom][Nullring Discussion]] +My own mailing list feed. ** Science Journals :journal: I like to get new information about recent studies related to technology. *** [[http://www.nature.com/nmat/current_issue/rss/][Nature]] diff --git a/config/emacs.org b/config/emacs.org index c919b96..69316e5 100644 --- a/config/emacs.org +++ b/config/emacs.org @@ -767,6 +767,8 @@ Email in emacs can be done with Mu4e. (use-package mu4e :after smtpmail + :hook + ((mu4e-compose-mode . mml-secure-message-sign-pgpmime)) :custom (mu4e-drafts-folder "/Drafts" "Set drafts folder mu db") (mu4e-sent-folder "/Sent" "Set sent folder in mu db") @@ -784,6 +786,10 @@ Email in emacs can be done with Mu4e. (mu4e-headers-auto-update t "Auto-updates feed") (mu4e-view-show-images t "Shows images") (mu4e-compose-signature-auto-include nil) + (mml-secure-openpgp-sign-with-sender t) + (mml-secure-openpgp-signers (list system-gpgkey)) + (mail-user-agent 'mu4e-user-agent) + (message-mail-user-agent 'mu4e-user-agent) (mu4e-use-fancy-chars t "Random option to make mu4e look nicer")) #+end_src ** Music diff --git a/config/nix.org b/config/nix.org index 158fd99..cf0e8c5 100644 --- a/config/nix.org +++ b/config/nix.org @@ -472,6 +472,15 @@ the yaml file specified. Yes, this is safe to include in the repo. templates = if config.monorepo.profiles.server.enable then { + "public-inbox-netrc" = { + owner = "public-inbox"; + group = "public-inbox"; + mode = "0400"; + content = '' + machine mail.${config.monorepo.vars.orgHost} login monorepo@${config.monorepo.vars.orgHost} password ${config.sops.placeholder."mail_monorepo_password_pi"} + machine mail.${config.monorepo.vars.orgHost} login discussion@${config.monorepo.vars.orgHost} password ${config.sops.placeholder."mail_monorepo_password_pi"} + ''; + }; "matterbridge" = { owner = "matterbridge"; content = '' @@ -556,6 +565,17 @@ the yaml file specified. Yes, this is safe to include in the repo. format = "yaml"; owner = "maddy"; }; + + mail_monorepo_password = { + format = "yaml"; + owner = "maddy"; + }; + + mail_monorepo_password_pi = { + format = "yaml"; + owner = "public-inbox"; + }; + conduit_secrets = { format = "yaml"; }; @@ -568,6 +588,10 @@ the yaml file specified. Yes, this is safe to include in the repo. discord_token = { format = "yaml"; }; + mpd_password = { + format = "yaml"; + owner = "nginx"; + }; ntfy = { format = "yaml"; owner = "ntfy-sh"; @@ -901,7 +925,7 @@ for lk-jwt and livekit which is important for configuring p2p calls in matrix. services.lk-jwt-service = { enable = lib.mkDefault config.monorepo.profiles.server.enable; port = 6495; - livekitUrl = "wss://livekit.nullring.xyz"; + livekitUrl = "wss://livekit.${config.monorepo.vars.orgHost}"; keyFile = "/run/secrets/livekit_secret"; }; services.livekit = { @@ -929,17 +953,21 @@ for lk-jwt and livekit which is important for configuring p2p calls in matrix. }; } #+end_src -** Coturn -This is important for p2p calls in matrix as well. -#+begin_src nix :tangle ../nix/modules/coturn.nix +** GoToSocial +This is a basic ActivityPub server. +#+begin_src nix :tangle ../nix/modules/gotosocial.nix { lib, config, ... }: { - services.coturn = { - enable = false; - use-auth-secret = true; - listening-ips = [ "0.0.0.0" ]; - cert = "/var/lib/acme/matrix.${config.monorepo.vars.orgHost}/fullchain.pem"; - static-auth-secret-file = "/run/secrets/coturn_secret"; + services.gotosocial = { + enable = lib.mkDefault config.monorepo.profiles.server.enable; + setupPostgresqlDB = true; + settings = { + application-name = "Nullring GoToSocial Instance"; + host = "gotosocial.${config.monorepo.vars.orgHost}"; + protocol = "https"; + bind-address = "127.0.0.1"; + port = 8080; + }; }; } #+end_src @@ -954,6 +982,19 @@ I want to connect IRC to discord with matterbridge. }; } #+end_src +** TODO matrix-appservice-irc +#+begin_src nix :tangle ../nix/modules/matrix-appservice-irc.nix + { lib, config, ... }: + { + enable = lib.mkDefault config.monorepo.profiles.server.enable; + registrationUrl = "localhost"; + + settings = { + homeserver.url = "https://matrix.nullring.xyz"; + homserver.domain = "matrix.nullring.xyz"; + }; + } +#+end_src *** Mautrix I use this bridge to bridge myself from Matrix to Discord and vise versa, because Matterbridge is not maintained very well and therefore does not support conduit at the moment. Note that this is not fully declarative and requires that you add @@ -1223,7 +1264,7 @@ to the outside world under a domain. gitweb = { enable = true; - virtualHost = "${config.monorepo.vars.remoteHost}"; + virtualHost = "${config.monorepo.vars.orgHost}"; }; virtualHosts = { @@ -1262,11 +1303,12 @@ to the outside world under a domain. }; locations."= /.well-known/matrix/server" = { extraConfig = '' + default_type application/json; add_header Content-Type application/json; add_header Access-Control-Allow-Origin *; ''; - return = ''200 '{"m.server": "matrix.nullring.xyz:443"}' ''; + return = ''200 '{"m.server": "matrix.${config.monorepo.vars.orgHost}:443"}' ''; }; locations."/.well-known/matrix/client" = { extraConfig = '' @@ -1328,8 +1370,8 @@ to the outside world under a domain. proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; - # proxy_set_header Upgrade $http_upgrade; - # proxy_set_header Connection "upgrade"; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; # --- CORS CONFIGURATION START --- # 1. Allow all origins (including app.element.io) @@ -1374,6 +1416,39 @@ to the outside world under a domain. enableACME = true; }; + "list.${config.monorepo.vars.orgHost}" = { + forceSSL = true; + enableACME = true; + locations."/" = { + proxyPass = "http://localhost:9090"; + extraConfig = '' + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + ''; + }; + }; + + # the port comes from ssh tunnelling + "music.${config.monorepo.vars.remoteHost}" = { + addSSL = true; + enableACME = true; + basicAuthFile = config.sops.secrets."mpd_password".path; + locations."/" = { + proxyPass = "http://localhost:8000"; + extraConfig = '' + proxy_buffering off; + proxy_http_version 1.1; + proxy_set_header Connection ""; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_read_timeout 36000s; + ''; + }; + }; + "${config.monorepo.vars.orgHost}" = { serverName = "${config.monorepo.vars.orgHost}"; root = "/var/www/nullring/"; @@ -1481,10 +1556,249 @@ There is a non declarative part of setting dkims and spf. "${config.monorepo.vars.internetName}@${config.monorepo.vars.orgHost}" = { passwordFile = "/run/secrets/mail_password"; }; + "monorepo@${config.monorepo.vars.orgHost}" = { + passwordFile = "/run/secrets/mail_monorepo_password"; + }; + "discussion@${config.monorepo.vars.orgHost}" = { + passwordFile = "/run/secrets/mail_monorepo_password"; + }; }; }; } #+end_src +*** Public Inbox +This is my mailing list software that I will use to develop software. +#+begin_src nix :tangle ../nix/modules/public_inbox.nix + { lib, config, ... }: + { + systemd.tmpfiles.rules = [ + "C+ /var/lib/public-inbox/style.css 0644 public-inbox public-inbox - ${../data/public-inbox.css}" + ]; + systemd.services.public-inbox-httpd = if config.monorepo.profiles.server.enable then { + preStart = '' + # Copy or link the file. + # Using 'cp' is often safer for sandboxed services than linking to the store. Lol. + cp -f ${../data/public-inbox.css} /var/lib/public-inbox/style.css + chmod 644 /var/lib/public-inbox/style.css + ''; + + serviceConfig = { + # Allow the service to see the file it just created + BindPaths = [ + "/var/lib/public-inbox" + ]; + ReadOnlyPaths = [ "/var/lib/public-inbox/style.css" ]; + # Ensure it can actually write to the directory during preStart + ReadWritePaths = [ "/var/lib/public-inbox" ]; + }; + } else {}; + + systemd.services.public-inbox-watch = if config.monorepo.profiles.server.enable then { + after = [ "sops-nix.service" ]; + confinement.enable = lib.mkForce false; + preStart = '' + mkdir -p /var/lib/public-inbox/.tmp + chmod 0700 /var/lib/public-inbox/.tmp + ln -sfn ${config.sops.templates."public-inbox-netrc".path} /var/lib/public-inbox/.netrc + ''; + environment = { + PUBLIC_INBOX_FORCE_IPV4 = "1"; + NETRC = config.sops.templates."public-inbox-netrc".path; + HOME = "/var/lib/public-inbox"; + TMPDIR = "/var/lib/public-inbox/.tmp"; + }; + + serviceConfig = { + RestrictSUIDSGID = lib.mkForce false; + ReadWritePaths = [ "/var/lib/public-inbox" ]; + RestrictAddressFamilies = lib.mkForce [ "AF_UNIX" "AF_INET" "AF_INET6" ]; + PrivateNetwork = lib.mkForce false; + SystemCallFilter = lib.mkForce []; + RootDirectory = lib.mkForce ""; + + CapabilityBoundingSet = lib.mkForce [ "~" ]; + UMask = lib.mkForce "0022"; + ProtectSystem = lib.mkForce false; + }; + } else {}; + + services.public-inbox = { + enable = lib.mkDefault config.monorepo.profiles.server.enable; + settings = { + publicinbox.css = ["/var/lib/public-inbox/style.css"]; + publicinbox.wwwlisting = "all"; + }; + http = { + enable = true; + port = 9090; + }; + inboxes = { + "monorepo" = { + description = "discussion of ret2pop's monorepo project and related work."; + address = [ "monorepo@${config.monorepo.vars.orgHost}" ]; + inboxdir = "/var/lib/public-inbox/monorepo"; + url = "https://list.${config.monorepo.vars.orgHost}/monorepo"; + watch = [ "imaps://monorepo%40${config.monorepo.vars.orgHost}@mail.${config.monorepo.vars.orgHost}/INBOX" ]; + }; + + "discussion" = { + description = "Main Nullring Discussion Mailing List"; + address = [ "discussion@${config.monorepo.vars.orgHost}" ]; + inboxdir = "/var/lib/public-inbox/discuss"; + url = "https://list.${config.monorepo.vars.orgHost}/discussion"; + watch = [ "imaps://discussion%40${config.monorepo.vars.orgHost}@mail.${config.monorepo.vars.orgHost}/INBOX" ]; + }; + }; + }; + } +#+end_src +*** Public Inbox CSS +This is a minimal stylesheet for public inbox so that I don't get eye cancer while reading it. +#+begin_src nix :tangle ../nix/data/public-inbox.css + :root { + --bg: #f8f9fa; + --fg: #2e3440; + --link: #5e81ac; + --link-hover: #81a1c1; + --border: #d8dee9; + --card-bg: #ffffff; + --meta-fg: #4c566a; /* Darker gray for better legibility */ + --btn-fg: #ffffff; + --max-width: 780px; + } + + @media (prefers-color-scheme: dark) { + :root { + --bg: #1a1b26; + --fg: #a9b1d6; + --link: #7aa2f7; + --link-hover: #bb9af7; + --border: #414868; /* Distinct border for dark mode */ + --card-bg: #1f2335; + --meta-fg: #9aa5ce; /* Brighter gray for dark mode */ + --btn-fg: #1a1b26; + } + } + + span.q { + color: var(--meta-fg); + font-style: italic; + } + + body { + background-color: var(--bg); + color: var(--fg); + line-height: 1.6; + max-width: var(--max-width); + margin: 3rem auto; + padding: 0 1.5rem; + font-family: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace; + + /* Keep this for smoother rendering on macOS/iOS */ + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + } + + /* 1. Global Link Fixes */ + body a, body a:visited { + color: var(--link); + } + + /* 2. Card Styling */ + body pre { + white-space: pre-wrap; + background: var(--card-bg); + padding: 2rem; + border-radius: 12px; + border: 1px solid var(--border); + margin-bottom: 2.5rem; + } + + /* 3. Header Cleanup */ + body pre b:first-of-type { + font-weight: 700; + color: var(--link); + font-size: 1.1rem; + display: block; + margin-bottom: 0.5rem; + } + + /* 4. Fixing the "Permalink" label on documentation */ + /* We target links ending in / but EXCLUDE system paths like help or mirror */ + body pre a[href$="/"]:not([href*="_/"]):not([href*="new.atom"]) { + font-size: 0; + text-decoration: none; + margin-right: 10px; + } + + body pre a[href$="/"]:not([href*="_/"]):not([href*="new.atom"]):after { + content: "permalink"; + font-size: 11px; + font-weight: bold; + color: var(--fg); /* Use main text color for high contrast */ + background: var(--bg); + border: 1px solid var(--link); /* Use link color for the border */ + padding: 4px 10px; + border-radius: 4px; + display: inline-block; + } + + /* 5. Fixing the "Raw" button contrast */ + body pre a[href$="/raw"] { + font-size: 0; + text-decoration: none; + } + + body pre a[href$="/raw"]:after { + content: "raw"; + font-size: 11px; + font-weight: bold; + color: var(--fg); + background: var(--bg); + border: 1px solid var(--link); + padding: 4px 10px; + border-radius: 4px; + display: inline-block; + } + + /* Hover effect for ghost buttons: solid color shift */ + body pre a[href$="/"]:hover:after, + body pre a[href$="/raw"]:hover:after { + background: var(--link); + color: var(--btn-fg); + } + + /* 6. The Reply Button (Primary Action) */ + body pre a[href$="#R"], body pre a[href$="#R"]:visited { + font-size: 0; + text-decoration: none; + } + + body pre a[href$="#R"]:after { + content: "REPLY"; + font-size: 12px; + font-weight: bold; + padding: 6px 20px; + background: var(--link); + color: var(--btn-fg); + border-radius: 6px; + display: inline-block; + margin-left: 10px; + } + + /* 7. Hide clutter */ + body pre a[href^="#r"], body pre a[href^="#r"] + b, body hr { + display: none; + } + + /* Fix: Mathematically outscore the header rule to keep link text inline */ + body pre a[href] b:first-of-type { + display: inline; + font-size: inherit; + margin-bottom: 0; + color: inherit; + } +#+end_src ** Fail2Ban This is a service that bans bots that try to sign in on my server. #+begin_src nix :tangle ../nix/modules/fail2ban.nix @@ -1611,6 +1925,7 @@ because they enhance security. { config, pkgs, lib, ... }: { imports = [ + ./public_inbox.nix ./matterbridge.nix ./mautrix.nix ./xserver.nix @@ -2014,6 +2329,7 @@ because they enhance security. users.groups.matterbridge = lib.mkDefault {}; users.groups.maddy = lib.mkDefault {}; users.groups.ntfy-sh = lib.mkDefault {}; + users.groups.public-inbox = lib.mkDefault {}; users.users = { conduit = { @@ -2037,11 +2353,18 @@ because they enhance security. extraGroups = [ "acme" "nginx" ]; }; + public-inbox = { + isSystemUser = lib.mkDefault true; + group = "public-inbox"; + + extraGroups = [ "acme" "nginx" ]; + }; ngircd = { isSystemUser = lib.mkDefault true; group = "ngircd"; extraGroups = [ "acme" "nginx" ]; }; + livekit = { isSystemUser = lib.mkDefault true; group = "livekit"; @@ -2073,6 +2396,7 @@ because they enhance security. group = "git"; openssh.authorizedKeys.keys = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICts6+MQiMwpA+DfFQxjIN214Jn0pCw/2BDvOzPhR/H2 preston@continuity-dell" + "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCedJm0yYB0qLah/Y7PqLVgNh6qp+yujssGtuR05KbZLzSnsLUjUMObMyjFB9xTKrSGDqyoMkNe2l5VXMBJ9wBKLbzqMWbkakAWOj7EC/qZ6dFWA075mniwAuWKY/Q8QYohAJbbeU4j0ObWrltd4ar2Ac9vsVyftYF5efg8PEqVdOxzrBn5taY1zCCRjee5ISeRDIovnBbq7x86jsx5VnXTjMN9FZCI2qmz992Sg/PPXpXat+O1YQlG0eBHEny2Ug9gaAYnGOVr6kZKE4lrjz47nrXVXO6lJsNXmuzTVnEgo30DAA3dV4fws/M5ptM5Pgg2qe94HyHWhhmtXOekWmGtP3YxpVe3M/SPl31UL570ZDuuCcpJTsbe90ZyXC3CiSJkLKbmFkfOgZ6DI2LT8KSp09/2NCtZYriLN/nXObn6gQzByGMxVyKNx2hh8ENt9hzTCAk5lYDK3g3wS8eLCY3EH/caEqT9mLZEZeRHtAhtfozo1VJL7sSZ0Zm7wiIxHylwOshh1sYI1gb1MgMqNnrr1t8+8UK+Q0NERQW3yiphG36HXWy/DdCG0EF+N850KbgH1FFur+m+3hZCZCFVp3tGCcOC+bxWMBT3+9yC6LARi5cFjLQaWLsNO5xEs4vqX3+s3QjJ0pAYDkgtoeY2Fbh+imN+JasWn/cSy5p3UdE4ZQ== andrei@kiss" ]; }; "${config.monorepo.vars.userName}" = { @@ -2346,19 +2670,19 @@ I have many imports that we'll go through next. email = { email = lib.mkOption { type = lib.types.str; - default = "ret2pop@gmail.com"; + default = "ret2pop@nullring.xyz"; example = "john@example.com"; description = "Email address and imaps/smtps account"; }; imapsServer = lib.mkOption { type = lib.types.str; - default = "imap.gmail.com"; + default = "mail.nullring.xyz"; example = "imap.example.com"; description = "imaps server address"; }; smtpsServer = lib.mkOption { type = lib.types.str; - default = "smtp.gmail.com"; + default = "mail.nullring.xyz"; example = "smtp.example.com"; description = "smtp server address"; }; @@ -2858,6 +3182,7 @@ as an org file which gets automatically tangled to an emacs-lisp file. (setq system-email "${config.monorepo.profiles.email.email}") (setq system-username "${config.monorepo.vars.internetName}") (setq system-fullname "${config.monorepo.vars.fullName}") + (setq system-gpgkey "${config.monorepo.vars.gpgKey}") (load "${pkgs.writeText "init.el" (builtins.readFile ../../init.el)}") ''; @@ -3361,16 +3686,16 @@ in the ~~/music~ directory and then run ~mpc add /~ afterwards. type "pipewire" name "pipewire output" } + audio_output { type "httpd" - name "My HTTP Stream" + name "Ret2pop's Music Stream" encoder "opus" # optional port "8000" - # quality "5.0" # do not define if bitrate is defined - bitrate "128000" # do not define if quality is defined + bitrate "128000" format "48000:16:1" - always_on "yes" # prevent MPD from disconnecting all listeners when playback is stopped. - tags "yes" # httpd supports sending tags to listening streams. + always_on "yes" + tags "yes" } audio_output { @@ -4013,6 +4338,8 @@ for these configurations. packages = with pkgs; (if config.monorepo.profiles.graphics.enable then [ # wikipedia # kiwix kiwix-tools + gnupg + unzip mupdf zathura @@ -4132,6 +4459,12 @@ for these configurations. ''; }; }; + xdg.mimeApps = { + enable = true; + defaultApplications = { + "x-scheme-handler/mailto" = "emacsclient-mail.desktop"; + }; + }; programs.bash.enable = true; fonts.fontconfig.enable = true; @@ -4145,6 +4478,7 @@ the path. { config, sops-nix, ... }: { home-manager = { + backupFileExtension = "backup"; sharedModules = [ sops-nix.homeManagerModules.sops ]; @@ -4338,6 +4672,7 @@ some DNS records to match what you have on your system after deployment. 7881 8443 8448 + 9418 ]; allowedUDPPorts = [ 3478 5349 7882 @@ -4389,6 +4724,7 @@ some DNS records to match what you have on your system after deployment. "ntfy.${config.monorepo.vars.remoteHost}" = {}; "matrix.${config.monorepo.vars.remoteHost}" = {}; "www.${config.monorepo.vars.remoteHost}" = {}; + "music.${config.monorepo.vars.remoteHost}" = {}; "mail.${config.monorepo.vars.remoteHost}" = { }; @@ -4396,6 +4732,8 @@ some DNS records to match what you have on your system after deployment. "${config.monorepo.vars.orgHost}" = {}; "git.${config.monorepo.vars.orgHost}" = {}; "matrix.${config.monorepo.vars.orgHost}" = {}; + "social.${config.monorepo.vars.orgHost}" = {}; + "list.${config.monorepo.vars.orgHost}" = {}; "talk.${config.monorepo.vars.orgHost}" = {}; "mail.${config.monorepo.vars.orgHost}" = {}; "${config.monorepo.vars.internetName}.${config.monorepo.vars.orgHost}" = {}; diff --git a/index.org b/index.org index 7d3ef8a..3d4b26a 100644 --- a/index.org +++ b/index.org @@ -52,7 +52,7 @@ can therefore publish them. So I did! Configurations include: - Qutebrowser …and many more! * [[https://git.nullring.xyz][Projects]] -My programming projects can be found on my [[https://ret2pop.net/gitweb][git server]]; other projects that do not directly pertain +My programming projects can be found on my [[https://nullring.xyz/gitweb][git server]]; other projects that do not directly pertain to my projects on git or need a more in-depth explanation are explained further in my blog. I also have a [[https://github.com/ret2pop][github]] for those interested. * [[https://youtube.com/@ret2pop][Music and Media]] @@ -65,9 +65,11 @@ but of course that won't be kept in a public repository. I think that it's cool to automatically and transparently let people know what I'm up to, so you don't have to ask. Also, it gives me some motivation to do things if a part of my agenda is public. +* [[https://list.nullring.xyz][Mailing List]] +Here, I keep a mailing list which you can figure out how to mail to by emailing me first (I don't want spammers). +It's meant to be a general purpose mailing list as well as a collaborative space for working on projects with others. * [[file:about.org][About]] Who is the man behind ret2pop? How do you contact him? So many mysteries await… - ** About this Website I wrote this website in org mode. For more information, see the [[file:README.org][README]]. Here is how I upload my website: diff --git a/nix/data/public-inbox.css b/nix/data/public-inbox.css new file mode 100644 index 0000000..df94873 --- /dev/null +++ b/nix/data/public-inbox.css @@ -0,0 +1,143 @@ +:root { + --bg: #f8f9fa; + --fg: #2e3440; + --link: #5e81ac; + --link-hover: #81a1c1; + --border: #d8dee9; + --card-bg: #ffffff; + --meta-fg: #4c566a; /* Darker gray for better legibility */ + --btn-fg: #ffffff; + --max-width: 780px; +} + +@media (prefers-color-scheme: dark) { + :root { + --bg: #1a1b26; + --fg: #a9b1d6; + --link: #7aa2f7; + --link-hover: #bb9af7; + --border: #414868; /* Distinct border for dark mode */ + --card-bg: #1f2335; + --meta-fg: #9aa5ce; /* Brighter gray for dark mode */ + --btn-fg: #1a1b26; + } +} + +span.q { + color: var(--meta-fg); + font-style: italic; +} + +body { + background-color: var(--bg); + color: var(--fg); + line-height: 1.6; + max-width: var(--max-width); + margin: 3rem auto; + padding: 0 1.5rem; + font-family: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace; + + /* Keep this for smoother rendering on macOS/iOS */ + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +/* 1. Global Link Fixes */ +body a, body a:visited { + color: var(--link); +} + +/* 2. Card Styling */ +body pre { + white-space: pre-wrap; + background: var(--card-bg); + padding: 2rem; + border-radius: 12px; + border: 1px solid var(--border); + margin-bottom: 2.5rem; +} + +/* 3. Header Cleanup */ +body pre b:first-of-type { + font-weight: 700; + color: var(--link); + font-size: 1.1rem; + display: block; + margin-bottom: 0.5rem; +} + +/* 4. Fixing the "Permalink" label on documentation */ +/* We target links ending in / but EXCLUDE system paths like help or mirror */ +body pre a[href$="/"]:not([href*="_/"]):not([href*="new.atom"]) { + font-size: 0; + text-decoration: none; + margin-right: 10px; +} + +body pre a[href$="/"]:not([href*="_/"]):not([href*="new.atom"]):after { + content: "permalink"; + font-size: 11px; + font-weight: bold; + color: var(--fg); /* Use main text color for high contrast */ + background: var(--bg); + border: 1px solid var(--link); /* Use link color for the border */ + padding: 4px 10px; + border-radius: 4px; + display: inline-block; +} + +/* 5. Fixing the "Raw" button contrast */ +body pre a[href$="/raw"] { + font-size: 0; + text-decoration: none; +} + +body pre a[href$="/raw"]:after { + content: "raw"; + font-size: 11px; + font-weight: bold; + color: var(--fg); + background: var(--bg); + border: 1px solid var(--link); + padding: 4px 10px; + border-radius: 4px; + display: inline-block; +} + +/* Hover effect for ghost buttons: solid color shift */ +body pre a[href$="/"]:hover:after, +body pre a[href$="/raw"]:hover:after { + background: var(--link); + color: var(--btn-fg); +} + +/* 6. The Reply Button (Primary Action) */ +body pre a[href$="#R"], body pre a[href$="#R"]:visited { + font-size: 0; + text-decoration: none; +} + +body pre a[href$="#R"]:after { + content: "REPLY"; + font-size: 12px; + font-weight: bold; + padding: 6px 20px; + background: var(--link); + color: var(--btn-fg); + border-radius: 6px; + display: inline-block; + margin-left: 10px; +} + +/* 7. Hide clutter */ +body pre a[href^="#r"], body pre a[href^="#r"] + b, body hr { + display: none; +} + +/* Fix: Mathematically outscore the header rule to keep link text inline */ +body pre a[href] b:first-of-type { + display: inline; + font-size: inherit; + margin-bottom: 0; + color: inherit; +} diff --git a/nix/init.el b/nix/init.el index ac01689..a51afac 100644 --- a/nix/init.el +++ b/nix/init.el @@ -625,6 +625,8 @@ (use-package mu4e :after smtpmail + :hook + ((mu4e-compose-mode . mml-secure-message-sign-pgpmime)) :custom (mu4e-drafts-folder "/Drafts" "Set drafts folder mu db") (mu4e-sent-folder "/Sent" "Set sent folder in mu db") @@ -642,6 +644,10 @@ (mu4e-headers-auto-update t "Auto-updates feed") (mu4e-view-show-images t "Shows images") (mu4e-compose-signature-auto-include nil) + (mml-secure-openpgp-sign-with-sender t) + (mml-secure-openpgp-signers (list system-gpgkey)) + (mail-user-agent 'mu4e-user-agent) + (message-mail-user-agent 'mu4e-user-agent) (mu4e-use-fancy-chars t "Random option to make mu4e look nicer")) (use-package emms diff --git a/nix/modules/conduit.nix b/nix/modules/conduit.nix index 6e4611f..4d7a30c 100644 --- a/nix/modules/conduit.nix +++ b/nix/modules/conduit.nix @@ -18,7 +18,7 @@ services.lk-jwt-service = { enable = lib.mkDefault config.monorepo.profiles.server.enable; port = 6495; - livekitUrl = "wss://livekit.nullring.xyz"; + livekitUrl = "wss://livekit.${config.monorepo.vars.orgHost}"; keyFile = "/run/secrets/livekit_secret"; }; services.livekit = { diff --git a/nix/modules/configuration.nix b/nix/modules/configuration.nix index e09571b..02d4a94 100644 --- a/nix/modules/configuration.nix +++ b/nix/modules/configuration.nix @@ -1,6 +1,7 @@ { config, pkgs, lib, ... }: { imports = [ + ./public_inbox.nix ./matterbridge.nix ./mautrix.nix ./xserver.nix @@ -404,6 +405,7 @@ country=CA users.groups.matterbridge = lib.mkDefault {}; users.groups.maddy = lib.mkDefault {}; users.groups.ntfy-sh = lib.mkDefault {}; + users.groups.public-inbox = lib.mkDefault {}; users.users = { conduit = { @@ -427,11 +429,18 @@ country=CA extraGroups = [ "acme" "nginx" ]; }; + public-inbox = { + isSystemUser = lib.mkDefault true; + group = "public-inbox"; + + extraGroups = [ "acme" "nginx" ]; + }; ngircd = { isSystemUser = lib.mkDefault true; group = "ngircd"; extraGroups = [ "acme" "nginx" ]; }; + livekit = { isSystemUser = lib.mkDefault true; group = "livekit"; @@ -463,6 +472,7 @@ country=CA group = "git"; openssh.authorizedKeys.keys = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICts6+MQiMwpA+DfFQxjIN214Jn0pCw/2BDvOzPhR/H2 preston@continuity-dell" + "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCedJm0yYB0qLah/Y7PqLVgNh6qp+yujssGtuR05KbZLzSnsLUjUMObMyjFB9xTKrSGDqyoMkNe2l5VXMBJ9wBKLbzqMWbkakAWOj7EC/qZ6dFWA075mniwAuWKY/Q8QYohAJbbeU4j0ObWrltd4ar2Ac9vsVyftYF5efg8PEqVdOxzrBn5taY1zCCRjee5ISeRDIovnBbq7x86jsx5VnXTjMN9FZCI2qmz992Sg/PPXpXat+O1YQlG0eBHEny2Ug9gaAYnGOVr6kZKE4lrjz47nrXVXO6lJsNXmuzTVnEgo30DAA3dV4fws/M5ptM5Pgg2qe94HyHWhhmtXOekWmGtP3YxpVe3M/SPl31UL570ZDuuCcpJTsbe90ZyXC3CiSJkLKbmFkfOgZ6DI2LT8KSp09/2NCtZYriLN/nXObn6gQzByGMxVyKNx2hh8ENt9hzTCAk5lYDK3g3wS8eLCY3EH/caEqT9mLZEZeRHtAhtfozo1VJL7sSZ0Zm7wiIxHylwOshh1sYI1gb1MgMqNnrr1t8+8UK+Q0NERQW3yiphG36HXWy/DdCG0EF+N850KbgH1FFur+m+3hZCZCFVp3tGCcOC+bxWMBT3+9yC6LARi5cFjLQaWLsNO5xEs4vqX3+s3QjJ0pAYDkgtoeY2Fbh+imN+JasWn/cSy5p3UdE4ZQ== andrei@kiss" ]; }; "${config.monorepo.vars.userName}" = { diff --git a/nix/modules/gotosocial.nix b/nix/modules/gotosocial.nix new file mode 100644 index 0000000..6b81128 --- /dev/null +++ b/nix/modules/gotosocial.nix @@ -0,0 +1,14 @@ +{ lib, config, ... }: +{ + services.gotosocial = { + enable = lib.mkDefault config.monorepo.profiles.server.enable; + setupPostgresqlDB = true; + settings = { + application-name = "Nullring GoToSocial Instance"; + host = "gotosocial.${config.monorepo.vars.orgHost}"; + protocol = "https"; + bind-address = "127.0.0.1"; + port = 8080; + }; + }; +} diff --git a/nix/modules/home/default.nix b/nix/modules/home/default.nix index b1c07c3..a45ce59 100644 --- a/nix/modules/home/default.nix +++ b/nix/modules/home/default.nix @@ -53,19 +53,19 @@ email = { email = lib.mkOption { type = lib.types.str; - default = "ret2pop@gmail.com"; + default = "ret2pop@nullring.xyz"; example = "john@example.com"; description = "Email address and imaps/smtps account"; }; imapsServer = lib.mkOption { type = lib.types.str; - default = "imap.gmail.com"; + default = "mail.nullring.xyz"; example = "imap.example.com"; description = "imaps server address"; }; smtpsServer = lib.mkOption { type = lib.types.str; - default = "smtp.gmail.com"; + default = "mail.nullring.xyz"; example = "smtp.example.com"; description = "smtp server address"; }; diff --git a/nix/modules/home/emacs.nix b/nix/modules/home/emacs.nix index 4256d34..cdf1def 100644 --- a/nix/modules/home/emacs.nix +++ b/nix/modules/home/emacs.nix @@ -9,6 +9,7 @@ (setq system-email "${config.monorepo.profiles.email.email}") (setq system-username "${config.monorepo.vars.internetName}") (setq system-fullname "${config.monorepo.vars.fullName}") +(setq system-gpgkey "${config.monorepo.vars.gpgKey}") (load "${pkgs.writeText "init.el" (builtins.readFile ../../init.el)}") ''; diff --git a/nix/modules/home/mpd.nix b/nix/modules/home/mpd.nix index 8f646ea..2ab711b 100644 --- a/nix/modules/home/mpd.nix +++ b/nix/modules/home/mpd.nix @@ -13,16 +13,16 @@ type "pipewire" name "pipewire output" } + audio_output { type "httpd" - name "My HTTP Stream" + name "Ret2pop's Music Stream" encoder "opus" # optional port "8000" - # quality "5.0" # do not define if bitrate is defined - bitrate "128000" # do not define if quality is defined + bitrate "128000" format "48000:16:1" - always_on "yes" # prevent MPD from disconnecting all listeners when playback is stopped. - tags "yes" # httpd supports sending tags to listening streams. + always_on "yes" + tags "yes" } audio_output { diff --git a/nix/modules/home/user.nix b/nix/modules/home/user.nix index 55e16fc..cb29b4c 100644 --- a/nix/modules/home/user.nix +++ b/nix/modules/home/user.nix @@ -30,6 +30,8 @@ packages = with pkgs; (if config.monorepo.profiles.graphics.enable then [ # wikipedia # kiwix kiwix-tools + gnupg + unzip mupdf zathura @@ -149,6 +151,12 @@ cd "$HOME" ''; }; }; + xdg.mimeApps = { + enable = true; + defaultApplications = { + "x-scheme-handler/mailto" = "emacsclient-mail.desktop"; + }; + }; programs.bash.enable = true; fonts.fontconfig.enable = true; diff --git a/nix/modules/maddy.nix b/nix/modules/maddy.nix index 42f24f9..1d4710d 100644 --- a/nix/modules/maddy.nix +++ b/nix/modules/maddy.nix @@ -29,6 +29,12 @@ "${config.monorepo.vars.internetName}@${config.monorepo.vars.orgHost}" = { passwordFile = "/run/secrets/mail_password"; }; + "monorepo@${config.monorepo.vars.orgHost}" = { + passwordFile = "/run/secrets/mail_monorepo_password"; + }; + "discussion@${config.monorepo.vars.orgHost}" = { + passwordFile = "/run/secrets/mail_monorepo_password"; + }; }; }; } diff --git a/nix/modules/matrix-appservice-irc.nix b/nix/modules/matrix-appservice-irc.nix new file mode 100644 index 0000000..518cdde --- /dev/null +++ b/nix/modules/matrix-appservice-irc.nix @@ -0,0 +1,10 @@ +{ lib, config, ... }: +{ + enable = lib.mkDefault config.monorepo.profiles.server.enable; + registrationUrl = "localhost"; + + settings = { + homeserver.url = "https://matrix.nullring.xyz"; + homserver.domain = "matrix.nullring.xyz"; + }; +} diff --git a/nix/modules/nginx.nix b/nix/modules/nginx.nix index 87f11c1..621c9ef 100644 --- a/nix/modules/nginx.nix +++ b/nix/modules/nginx.nix @@ -10,7 +10,7 @@ gitweb = { enable = true; - virtualHost = "${config.monorepo.vars.remoteHost}"; + virtualHost = "${config.monorepo.vars.orgHost}"; }; virtualHosts = { @@ -49,11 +49,12 @@ }; locations."= /.well-known/matrix/server" = { extraConfig = '' + default_type application/json; add_header Content-Type application/json; add_header Access-Control-Allow-Origin *; ''; - return = ''200 '{"m.server": "matrix.nullring.xyz:443"}' ''; + return = ''200 '{"m.server": "matrix.${config.monorepo.vars.orgHost}:443"}' ''; }; locations."/.well-known/matrix/client" = { extraConfig = '' @@ -115,8 +116,8 @@ proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; - # proxy_set_header Upgrade $http_upgrade; - # proxy_set_header Connection "upgrade"; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; # --- CORS CONFIGURATION START --- # 1. Allow all origins (including app.element.io) @@ -161,6 +162,39 @@ enableACME = true; }; + "list.${config.monorepo.vars.orgHost}" = { + forceSSL = true; + enableACME = true; + locations."/" = { + proxyPass = "http://localhost:9090"; + extraConfig = '' + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + ''; + }; + }; + + # the port comes from ssh tunnelling + "music.${config.monorepo.vars.remoteHost}" = { + addSSL = true; + enableACME = true; + basicAuthFile = config.sops.secrets."mpd_password".path; + locations."/" = { + proxyPass = "http://localhost:8000"; + extraConfig = '' +proxy_buffering off; +proxy_http_version 1.1; +proxy_set_header Connection ""; +proxy_set_header Host $host; +proxy_set_header X-Real-IP $remote_addr; +proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; +proxy_read_timeout 36000s; +''; + }; + }; + "${config.monorepo.vars.orgHost}" = { serverName = "${config.monorepo.vars.orgHost}"; root = "/var/www/nullring/"; diff --git a/nix/modules/public_inbox.nix b/nix/modules/public_inbox.nix new file mode 100644 index 0000000..9f1532c --- /dev/null +++ b/nix/modules/public_inbox.nix @@ -0,0 +1,82 @@ +{ lib, config, ... }: +{ + systemd.tmpfiles.rules = [ + "C+ /var/lib/public-inbox/style.css 0644 public-inbox public-inbox - ${../data/public-inbox.css}" + ]; + systemd.services.public-inbox-httpd = if config.monorepo.profiles.server.enable then { + preStart = '' + # Copy or link the file. + # Using 'cp' is often safer for sandboxed services than linking to the store. Lol. + cp -f ${../data/public-inbox.css} /var/lib/public-inbox/style.css + chmod 644 /var/lib/public-inbox/style.css + ''; + + serviceConfig = { + # Allow the service to see the file it just created + BindPaths = [ + "/var/lib/public-inbox" + ]; + ReadOnlyPaths = [ "/var/lib/public-inbox/style.css" ]; + # Ensure it can actually write to the directory during preStart + ReadWritePaths = [ "/var/lib/public-inbox" ]; + }; + } else {}; + + systemd.services.public-inbox-watch = if config.monorepo.profiles.server.enable then { + after = [ "sops-nix.service" ]; + confinement.enable = lib.mkForce false; + preStart = '' + mkdir -p /var/lib/public-inbox/.tmp + chmod 0700 /var/lib/public-inbox/.tmp + ln -sfn ${config.sops.templates."public-inbox-netrc".path} /var/lib/public-inbox/.netrc + ''; + environment = { + PUBLIC_INBOX_FORCE_IPV4 = "1"; + NETRC = config.sops.templates."public-inbox-netrc".path; + HOME = "/var/lib/public-inbox"; + TMPDIR = "/var/lib/public-inbox/.tmp"; + }; + + serviceConfig = { + RestrictSUIDSGID = lib.mkForce false; + ReadWritePaths = [ "/var/lib/public-inbox" ]; + RestrictAddressFamilies = lib.mkForce [ "AF_UNIX" "AF_INET" "AF_INET6" ]; + PrivateNetwork = lib.mkForce false; + SystemCallFilter = lib.mkForce []; + RootDirectory = lib.mkForce ""; + + CapabilityBoundingSet = lib.mkForce [ "~" ]; + UMask = lib.mkForce "0022"; + ProtectSystem = lib.mkForce false; + }; + } else {}; + + services.public-inbox = { + enable = lib.mkDefault config.monorepo.profiles.server.enable; + settings = { + publicinbox.css = ["/var/lib/public-inbox/style.css"]; + publicinbox.wwwlisting = "all"; + }; + http = { + enable = true; + port = 9090; + }; + inboxes = { + "monorepo" = { + description = "discussion of ret2pop's monorepo project and related work."; + address = [ "monorepo@${config.monorepo.vars.orgHost}" ]; + inboxdir = "/var/lib/public-inbox/monorepo"; + url = "https://list.${config.monorepo.vars.orgHost}/monorepo"; + watch = [ "imaps://monorepo%40${config.monorepo.vars.orgHost}@mail.${config.monorepo.vars.orgHost}/INBOX" ]; + }; + + "discussion" = { + description = "Main Nullring Discussion Mailing List"; + address = [ "discussion@${config.monorepo.vars.orgHost}" ]; + inboxdir = "/var/lib/public-inbox/discuss"; + url = "https://list.${config.monorepo.vars.orgHost}/discussion"; + watch = [ "imaps://discussion%40${config.monorepo.vars.orgHost}@mail.${config.monorepo.vars.orgHost}/INBOX" ]; + }; + }; + }; +} diff --git a/nix/modules/secrets.nix b/nix/modules/secrets.nix index f7deb5d..1a09652 100644 --- a/nix/modules/secrets.nix +++ b/nix/modules/secrets.nix @@ -7,6 +7,15 @@ templates = if config.monorepo.profiles.server.enable then { + "public-inbox-netrc" = { + owner = "public-inbox"; + group = "public-inbox"; + mode = "0400"; + content = '' +machine mail.${config.monorepo.vars.orgHost} login monorepo@${config.monorepo.vars.orgHost} password ${config.sops.placeholder."mail_monorepo_password_pi"} +machine mail.${config.monorepo.vars.orgHost} login discussion@${config.monorepo.vars.orgHost} password ${config.sops.placeholder."mail_monorepo_password_pi"} + ''; + }; "matterbridge" = { owner = "matterbridge"; content = '' @@ -91,6 +100,17 @@ channel="-5290629325" format = "yaml"; owner = "maddy"; }; + + mail_monorepo_password = { + format = "yaml"; + owner = "maddy"; + }; + + mail_monorepo_password_pi = { + format = "yaml"; + owner = "public-inbox"; + }; + conduit_secrets = { format = "yaml"; }; @@ -103,6 +123,10 @@ channel="-5290629325" discord_token = { format = "yaml"; }; + mpd_password = { + format = "yaml"; + owner = "nginx"; + }; ntfy = { format = "yaml"; owner = "ntfy-sh"; diff --git a/nix/secrets/secrets.yaml b/nix/secrets/secrets.yaml index f2c3136..6a15ac1 100644 --- a/nix/secrets/secrets.yaml +++ b/nix/secrets/secrets.yaml @@ -1,7 +1,9 @@ -mail: ENC[AES256_GCM,data:IFJnuVbshByUh5S3HoSnX5AyOg==,iv:gF0JlnBGAMLduMIG/hZtssdkHVL9/RDmDwBw/WoMDwQ=,tag:adDgcz/VrAN6/kfYTKa5XA==,type:str] +mail: ENC[AES256_GCM,data:3gWbYL94WTUDNpSa/43Mrlc9Dj1zyWMpBqVCt+U=,iv:dqiIkQ0oF2lTbuQjZpEx6hp7jA+dijs8erfrITVF/KI=,tag:jOsR4RMUC7rUOQG5j8SASw==,type:str] +mail_old: ENC[AES256_GCM,data:rZLF7iE+JZu6NNwmws3EDgSs4A==,iv:Cfy/Q4wPeD/nx9r/afqlTVo5KarNJpxsAUd2eFT5tUE=,tag:gjMk8cTs1/6da/o5loWriw==,type:str] digikey: ENC[AES256_GCM,data:U1c2HYB/YjwlyHvD3XVTqWJdb9/8BeS6,iv:DNsBoaqgUPdfO9knQLCMeJVO8kctQ9XNvcY2xcpI0NM=,tag:kuJ9BYqVx0GeTBSW5EsItg==,type:str] cloudflare-dns: ENC[AES256_GCM,data:Gztc/M+r/eRO2DwyLxlIBxS7B7MpOXimbFkQwlYhq9SzGG/fLl6Xqw==,iv:aDyNwbc8EyrNyhucULUkeg7VM7BmqNQTndSTh1SWqq0=,tag:HvysjKquD1g2PCrCgX2swg==,type:str] dn42: ENC[AES256_GCM,data:xSYssg7ReFjmf7LvmqmH/A==,iv:Gj/LZrxzRJLOLbP5rumjmViYWP6ufW3ocngektBW3V8=,tag:SA4f1vAnMFUO5Yk6NTr81Q==,type:str] +nginx_password: ENC[AES256_GCM,data:/vDYWMEzNtu9h6jStzFlhdlfLDCimWUC/hmH4XoUWG1hW0RaQhn2vy+Qrr2O,iv:4YPQvar2qrFBMXvWyTn7M+WLpNPwrMB9mf7a9oyY2Yg=,tag:axsTqOuBdsbEIF+UvRuNfA==,type:str] sops: age: - recipient: age165ul43e8rc0qwzz2f2q9cw02psm2mkudsrwavq2e0pxs280p64yqy2z0dr @@ -13,7 +15,7 @@ sops: OFFNeEtOTk5FSm9RaDFad0UyeWZ2WDgKIwGoB4a5WAIkE93gzqdUzNlo5vgQ1zLy yhEFrE1NbhyItnZIg/yRhqFG0dv7D3pEP3pq2Seew6pKJg/s9UTJ8Q== -----END AGE ENCRYPTED FILE----- - lastmodified: "2026-02-09T22:27:35Z" - mac: ENC[AES256_GCM,data:51iA4W4Sou4OC5pk5oFr9vAbBHDdbiZTi9jiLsSh4/IHx4SDQONc05EoMUsqjidodeAfQCpmvqBFKdVPIaaSZE+0fqyPTs/wjCtbZTAhsH+NTUKn4yU5/HBC3hw2QLz7tCLKgRLhfooHUDQxdFWGMJNB7xSjxdPVcy/1+gngOrE=,iv:TrWBcs/Px2bmh716Jl5xSP/SCXM7akaGrhsC6/pXbQg=,tag:AFqp09TkLkdu903jY5YjEw==,type:str] + lastmodified: "2026-02-16T06:29:48Z" + mac: ENC[AES256_GCM,data:EQ/faGU28DJlmfITjnVe/9W0Gq8RCYYQVxOtL9l4T6n68Tthj+F9cRujdfeNS/eLkrkyni4HQM4gj1yuwbWDe3/c3Fi2XXy8fY3NJq2T2LJn8M1O6GFR0lczJ4vg5C5vnhtJOMthhKfz2UwSbUYJ6WE/K4PF9T8NrZnxG923ckQ=,iv:yJRKxq/KnhVQM5KWxosoimGKT0tlUgQMxFGy5YrUqAM=,tag:QmlwF3t6E0Z7WirDzUuMug==,type:str] unencrypted_suffix: _unencrypted version: 3.11.0 diff --git a/nix/secrets/vps_secrets.yaml b/nix/secrets/vps_secrets.yaml index 87c513b..ca86225 100644 --- a/nix/secrets/vps_secrets.yaml +++ b/nix/secrets/vps_secrets.yaml @@ -1,6 +1,7 @@ livekit_secret: ENC[AES256_GCM,data:akkd9OREC024n5NfE/suM0B9SjBdPZbXMnz62Qwy2XNW+HhJw1ixhYoR8PQoR6K0unrAUAFhwWtQp+aJ1i+5q1rdpLV/3povvXYPaGg8EnE=,iv:uMuIfLYT1lvDWY8PYjnWWne7WOd0BBgBJn5mvd9ltAs=,tag:JQlRe5IY4f1RVvsq+56lKQ==,type:str] livekit: ENC[AES256_GCM,data:DFWsez5+O7fyI1P/3w8wKj2YpblP+fDR/r4Ry7lLJNnZxiCbT3iS0Rm9lfe3zqZbjHvhpnYtOMPApoegJFEonQ==,iv:SditYIuc+W+AdX4AgKx2j4A4K7FXXHpewcf7KzMB8qY=,tag:EwF9DKf7uGZZKf7kF8RsNg==,type:str] znc: ENC[AES256_GCM,data:iFNZ0tgciFU=,iv:oAAqMoov5Nv9AUBILlRpgTLJyu7l1uQshbag0ujewP4=,tag:RXtbn4EEH2523qX9MC0ODA==,type:str] +mpd_password: ENC[AES256_GCM,data:yuSxdkf6ihe1a4qh6yGnrWLUzfe6+NiL9xdscw3mDNkDuqfhCcFAk4SSFNCH,iv:fJL42NDSPUk7b19nONu7pVwpfDaE//r/MgdoIpCI53w=,tag:OJst5kg3wvCU36YE7KuDGQ==,type:str] conduit_secrets: ENC[AES256_GCM,data:q6r4f275/6JKStX51+5qWozz+5L3UF4gTPaj4TOXskjRSn28cLKuoKix4mpKCqamef3SVU8THmPg3kwF5o4Gbm3XpZLieUyPaGCWxnwEaGZ8V5XaBZE=,iv:vsxezaahD0yCBmg0bAHMQfg9AjB52x/At5AowBTFARs=,tag:AXhgVDcTG7q1K91He7CFJA==,type:str] mautrix_env: ENC[AES256_GCM,data:Ab1mRgaXSS3VSB2sBo5AT0KaceubrcbAdomUEArmavbsjdWYQLkXbu8/BEALMTgif6c6+4u0iR3dLbRmmobBXGS03mdcR94MQbuWWH6VmHZ5VpydJQOMSl6FBcbOVgGBBp8srUmjVTLsDFobaZCCQJNfK2J3f2wbJqbDMgoUDb5B2LuElAJAuKABxCgl/isCovZpAKwbl65rK1GzZCDc9Z54o3BKLPH6Wa2K4RHnhnYjRl8HZCd/g4WRTVZh6kMIRluWtqdIVHPXAH0oc80=,iv:USZqyHzLt53mkveDxIUq0Tvyw08sUm+MpgsrjWeDiO8=,tag:4Ftfu3ALM77YnftxLkz/YQ==,type:str] matrix_bridge: ENC[AES256_GCM,data:w0BEETuDXVlKLlAs4JIQxMs=,iv:6IBAyKHmPJLqQWZFJD0NVT0rSXuGuAiCV2O6c3bP42o=,tag:oiyMCb4wtyqLIBrfvTirQw==,type:str] @@ -9,6 +10,8 @@ znc_password_salt: ENC[AES256_GCM,data:e7YZkNB32RiqgCPGoehwsfZzOHM=,iv:GrhwBRBZ1 telegram_token: ENC[AES256_GCM,data:hfstqM3NphVnK86LYp8EYe09kflMzQ1/SO5rm5UIkWN7wdl7mbq+sw3svc4YhQ==,iv:o6TbrGBCly0s3US9041cKmpLpThB/umhBEdZE9E3v54=,tag:WJ/KS4Uc9wtIcjpyfmzLfA==,type:str] discord_token: ENC[AES256_GCM,data:1mJ0lKTz2SmaP3PIn3ThWX6Mjbv3tywtLtF65SVkkCEtI79wcPeqK83l6jb3yG+ugntNR7lfQxLgbbURnTil3jc7yVOsYreL,iv:ExZ8xFkH6RR7rHATh8oBEEZWfV5Rt1YVEx8gUicQrV0=,tag:wKJ3P8ie/ppHU9VStQlk0Q==,type:str] mail_password: ENC[AES256_GCM,data:W24/1l9YrV+M1enkAgRv2uZuhUIYAjpcRkX7tbc=,iv:F8oLCpthhecllJvGSmHUaFgmBKDg/g3o85CPJ/nCcxU=,tag:bPxcZNXdQ/jkK+saaIKbSw==,type:str] +mail_monorepo_password: ENC[AES256_GCM,data:jZ1QCB+BAMTEiLVD3FZ0LZBWHP+SSaI8uz5ln4e8be5w7rhJFw==,iv:yJe4mP4PmrJpgdpyjKajZP/F6PXglGY2EsRyIn+a7E0=,tag:LA1PkGXckc8huWI4QH6NdQ==,type:str] +mail_monorepo_password_pi: ENC[AES256_GCM,data:9hEu6C9K7SidQtsJWoyOPBW3wSn1otg7fuXz2VUFWTPDYOHUjQ==,iv:R3I8bUHweR3UdfZkIHr7nkv8MqSPB8r/FaHA71mpxUg=,tag:aZuteMevsdX8PlZBVoXDjA==,type:str] ntfy: ENC[AES256_GCM,data:wKCZ/7GXRWPoVRoXDBD0E0sR6ZRQjSE8USwqHQFOT/QiqIx+aI0awcRuORyGbCE=,iv:aBO9I/528sX6ncnBHMBDVB6mLbc45A7xXiu9p7Kh0Ao=,tag:Xgp3UURxPYcO5DlN53sBVw==,type:str] sops: age: @@ -21,7 +24,7 @@ sops: dDZONnI0bG5heTYzaDkxeGo3VlFmdm8K377mvFFxtFSURAWeFvLDJTkm8wppKr/B Y4qrdU3xBaTwqlsC/7lElQClaUbM+YMF/padENsD6IfyoGN8lGUQQw== -----END AGE ENCRYPTED FILE----- - lastmodified: "2026-02-12T08:21:04Z" - mac: ENC[AES256_GCM,data:537FYu1bJ+0KgbdtKt7kw3Wx4JT2Nb71L36cMZLEFUpwE+pvpe3+iYV/J28TzYVHwByoQ1Q4LYRc/EQqSlT0oaV7yOpfLNS+cb7devATEHhGVrDUThmnF8YvyQFiQsyq/PFNqQ3RLEmSeAsJBWrFB5r8uqRJZKAW/URfFjYqdj0=,iv:tXRflj6rvxewU0QhbsOUSmAHkfWExDZMA6Z8Z65/y0w=,tag:h+y17+ilWPQ4+I/WZIbWAQ==,type:str] + lastmodified: "2026-02-15T22:41:35Z" + mac: ENC[AES256_GCM,data:H/OmVDNzaOL4QIr+5WOL9hgdoRUcxYQqL9ykGX3CR2xYsrPI17ktkoUR6sxjg2oW9bgvRVU3cU8DryiwGgziFyP6cnA0FlTKGp2CGw3KoKYjDtzgKucT7e0mYOmktirQVaQR604gpbB33/yHLTpbz4vNKkiyxQsv+VCUg9tuDvE=,iv:EJqFMQgrq/w0jIpHg8rj0OKWWf02+unOIeyYPwXTCfw=,tag:b6HouUF7BMSrF4fPBit7PA==,type:str] unencrypted_suffix: _unencrypted version: 3.11.0 diff --git a/nix/systems/home.nix b/nix/systems/home.nix index 7d5939c..ad5f096 100644 --- a/nix/systems/home.nix +++ b/nix/systems/home.nix @@ -1,6 +1,7 @@ { config, sops-nix, ... }: { home-manager = { + backupFileExtension = "backup"; sharedModules = [ sops-nix.homeManagerModules.sops ]; diff --git a/nix/systems/spontaneity/default.nix b/nix/systems/spontaneity/default.nix index 7bdcf74..e2df04b 100644 --- a/nix/systems/spontaneity/default.nix +++ b/nix/systems/spontaneity/default.nix @@ -80,6 +80,7 @@ 7881 8443 8448 + 9418 ]; allowedUDPPorts = [ 3478 5349 7882 @@ -131,6 +132,7 @@ "ntfy.${config.monorepo.vars.remoteHost}" = {}; "matrix.${config.monorepo.vars.remoteHost}" = {}; "www.${config.monorepo.vars.remoteHost}" = {}; + "music.${config.monorepo.vars.remoteHost}" = {}; "mail.${config.monorepo.vars.remoteHost}" = { }; @@ -138,6 +140,8 @@ "${config.monorepo.vars.orgHost}" = {}; "git.${config.monorepo.vars.orgHost}" = {}; "matrix.${config.monorepo.vars.orgHost}" = {}; + "social.${config.monorepo.vars.orgHost}" = {}; + "list.${config.monorepo.vars.orgHost}" = {}; "talk.${config.monorepo.vars.orgHost}" = {}; "mail.${config.monorepo.vars.orgHost}" = {}; "${config.monorepo.vars.internetName}.${config.monorepo.vars.orgHost}" = {}; -- cgit v1.3 From 9a930ea12bd743e9ca57b70911f8c35d97af3320 Mon Sep 17 00:00:00 2001 From: Preston Pan Date: Tue, 17 Feb 2026 19:17:13 -0800 Subject: cgit interface public-inbox integration --- config/nix.org | 139 +++++++++++++++++++++++++++----------- nix/modules/cgit.nix | 23 ++++++- nix/modules/configuration.nix | 63 +++++++---------- nix/modules/home/git.nix | 13 +++- nix/modules/home/user.nix | 2 +- nix/modules/maddy.nix | 9 +++ nix/modules/nginx.nix | 4 ++ nix/modules/public_inbox.nix | 19 ++++++ nix/modules/secrets.nix | 1 + nix/systems/installer/default.nix | 2 +- 10 files changed, 194 insertions(+), 81 deletions(-) (limited to 'nix') diff --git a/config/nix.org b/config/nix.org index cf0e8c5..2b7bdb8 100644 --- a/config/nix.org +++ b/config/nix.org @@ -479,6 +479,7 @@ the yaml file specified. Yes, this is safe to include in the repo. content = '' machine mail.${config.monorepo.vars.orgHost} login monorepo@${config.monorepo.vars.orgHost} password ${config.sops.placeholder."mail_monorepo_password_pi"} machine mail.${config.monorepo.vars.orgHost} login discussion@${config.monorepo.vars.orgHost} password ${config.sops.placeholder."mail_monorepo_password_pi"} + machine mail.${config.monorepo.vars.orgHost} login nullerbot@${config.monorepo.vars.orgHost} password ${config.sops.placeholder."mail_monorepo_password_pi"} ''; }; "matterbridge" = { @@ -1416,6 +1417,10 @@ to the outside world under a domain. enableACME = true; }; + "git.${config.monorepo.vars.orgHost}" = { + forceSSL = true; + enableACME = true; + }; "list.${config.monorepo.vars.orgHost}" = { forceSSL = true; enableACME = true; @@ -1483,6 +1488,34 @@ world. This was the easiest frontend to set up on NixOS. }; } #+end_src +** CGit Interface +#+begin_src nix :tangle ../nix/modules/cgit.nix + { lib, config, ... }: + { + services.cgit."my-projects" = { + enable = true; + scanPath = "/srv/git"; + settings = { + root-title = "Nullring Git Server"; + root-desc = "Projects and cool things"; + enable-commit-graph = 1; + enable-log-filecount = 1; + enable-log-linecount = 1; + enable-index-owner = 0; + clone-prefix = "https://git.${config.monorepo.vars.orgHost}"; + enable-tree-linenumbers = 1; + strict-export = "git-daemon-export-ok"; + }; + gitHttpBackend = { + enable = true; + checkExportOkFiles = true; + }; + nginx = { + virtualHost = "git.${config.monorepo.vars.orgHost}"; + }; + }; + } +#+end_src ** Nvidia I have an Nvidia GPU on my computer. #+begin_src nix :tangle ../nix/modules/nvidia.nix @@ -1552,6 +1585,12 @@ There is a non declarative part of setting dkims and spf. "imap tls://0.0.0.0:993 tcp://0.0.0.0:143" "submission tls://0.0.0.0:465 tcp://0.0.0.0:587" ] options.services.maddy.config.default; + ensureAccounts = [ + "${config.monorepo.vars.internetName}@${config.monorepo.vars.orgHost}" + "monorepo@${config.monorepo.vars.orgHost}" + "nullerbot@${config.monorepo.vars.orgHost}" + "discussion@${config.monorepo.vars.orgHost}" + ]; ensureCredentials = { "${config.monorepo.vars.internetName}@${config.monorepo.vars.orgHost}" = { passwordFile = "/run/secrets/mail_password"; @@ -1559,6 +1598,9 @@ There is a non declarative part of setting dkims and spf. "monorepo@${config.monorepo.vars.orgHost}" = { passwordFile = "/run/secrets/mail_monorepo_password"; }; + "nullerbot@${config.monorepo.vars.orgHost}" = { + passwordFile = "/run/secrets/mail_monorepo_password"; + }; "discussion@${config.monorepo.vars.orgHost}" = { passwordFile = "/run/secrets/mail_monorepo_password"; }; @@ -1586,6 +1628,7 @@ This is my mailing list software that I will use to develop software. # Allow the service to see the file it just created BindPaths = [ "/var/lib/public-inbox" + "/srv/git/" ]; ReadOnlyPaths = [ "/var/lib/public-inbox/style.css" ]; # Ensure it can actually write to the directory during preStart @@ -1625,6 +1668,10 @@ This is my mailing list software that I will use to develop software. services.public-inbox = { enable = lib.mkDefault config.monorepo.profiles.server.enable; settings = { + coderepo."nullerbot".dir = "/srv/git/nullerbot.git"; + coderepo."nullerbot".cgitUrl = "https://git.nullring.xyz/nullerbot.git"; + coderepo."monorepo".dir = "/srv/git/monorepo.git"; + coderepo."monorepo".cgitUrl = "https://git.nullring.xyz/monorepo.git"; publicinbox.css = ["/var/lib/public-inbox/style.css"]; publicinbox.wwwlisting = "all"; }; @@ -1639,6 +1686,9 @@ This is my mailing list software that I will use to develop software. inboxdir = "/var/lib/public-inbox/monorepo"; url = "https://list.${config.monorepo.vars.orgHost}/monorepo"; watch = [ "imaps://monorepo%40${config.monorepo.vars.orgHost}@mail.${config.monorepo.vars.orgHost}/INBOX" ]; + coderepo = [ + "monorepo" + ]; }; "discussion" = { @@ -1648,6 +1698,17 @@ This is my mailing list software that I will use to develop software. url = "https://list.${config.monorepo.vars.orgHost}/discussion"; watch = [ "imaps://discussion%40${config.monorepo.vars.orgHost}@mail.${config.monorepo.vars.orgHost}/INBOX" ]; }; + + "nullerbot" = { + description = "Discussion of Nullerbot Matrix Bot"; + address = [ "nullerbot@${config.monorepo.vars.orgHost}" ]; + inboxdir = "/var/lib/public-inbox/nullerbot"; + url = "https://list.${config.monorepo.vars.orgHost}/nullerbot"; + watch = [ "imaps://nullerbot%40${config.monorepo.vars.orgHost}@mail.${config.monorepo.vars.orgHost}/INBOX" ]; + coderepo = [ + "nullerbot" + ]; + }; }; }; } @@ -1923,8 +1984,23 @@ This is the backbone of the all the NixOS configurations, with all these options because they enhance security. #+begin_src nix :tangle ../nix/modules/configuration.nix { config, pkgs, lib, ... }: + let + userGroups = [ + "nginx" + "git" + "ircd" + "ngircd" + "conduit" + "livekit" + "matterbridge" + "maddy" + "ntfy-sh" + "public-inbox" + ]; + in { imports = [ + ./cgit.nix ./public_inbox.nix ./matterbridge.nix ./mautrix.nix @@ -2302,7 +2378,7 @@ because they enhance security. environment.systemPackages = with pkgs; [ restic sbctl - git + gitFull git-lfs git-lfs-transfer vim @@ -2320,55 +2396,29 @@ because they enhance security. ) ]; - users.groups.nginx = lib.mkDefault {}; - users.groups.git = lib.mkDefault {}; - users.groups.ircd = lib.mkDefault {}; - users.groups.ngircd = lib.mkDefault {}; - users.groups.conduit = lib.mkDefault {}; - users.groups.livekit = lib.mkDefault {}; - users.groups.matterbridge = lib.mkDefault {}; - users.groups.maddy = lib.mkDefault {}; - users.groups.ntfy-sh = lib.mkDefault {}; - users.groups.public-inbox = lib.mkDefault {}; + users.groups = lib.genAttrs userGroups (name: lib.mkDefault {}); - users.users = { + users.users = lib.genAttrs userGroups (name: { + isSystemUser = lib.mkDefault true; + group = "${name}"; + extraGroups = [ "acme" "nginx" ]; + }) // { conduit = { isSystemUser = lib.mkDefault true; group = "conduit"; + extraGroups = []; }; matterbridge = { isSystemUser = lib.mkDefault true; group = "matterbridge"; - }; - - maddy = { - isSystemUser = lib.mkDefault true; - group = "maddy"; - extraGroups = [ "acme" "nginx" ]; - }; - - ntfy-sh = { - isSystemUser = lib.mkDefault true; - group = "ntfy-sh"; - extraGroups = [ "acme" "nginx" ]; + extraGroups = []; }; public-inbox = { isSystemUser = lib.mkDefault true; group = "public-inbox"; - extraGroups = [ "acme" "nginx" ]; - }; - ngircd = { - isSystemUser = lib.mkDefault true; - group = "ngircd"; - extraGroups = [ "acme" "nginx" ]; - }; - - livekit = { - isSystemUser = lib.mkDefault true; - group = "livekit"; - extraGroups = [ "acme" "nginx" ]; + extraGroups = [ "acme" "nginx" "git" ]; }; ircd = { @@ -3304,10 +3354,11 @@ the timezone. My git configuration uses information set in the ~vars.nix~ in order to set configuration options. Make sure those are set correctly. I've set it to sign by default. #+begin_src nix :tangle ../nix/modules/home/git.nix - { lib, config, ... }: + { pkgs, lib, config, ... }: { programs.git = { enable = lib.mkDefault config.monorepo.profiles.graphics.enable; + package = pkgs.gitFull; lfs.enable = lib.mkDefault config.monorepo.profiles.graphics.enable; userName = config.monorepo.vars.fullName; userEmail = config.monorepo.profiles.email.email; @@ -3318,6 +3369,16 @@ Make sure those are set correctly. I've set it to sign by default. extraConfig = { init.defaultBranch = "main"; + credential."${config.monorepo.profiles.email.smtpsServer}" = { + username = "${config.monorepo.profiles.email.email}"; + helper = "!f() { test \"$1\" = get && echo \"password=$(cat /run/user/1000/secrets/mail)\"; }; f"; + }; + sendemail = { + smtpserver = "${config.monorepo.profiles.email.smtpsServer}"; + smtpuser = "${config.monorepo.profiles.email.email}"; + smtpserverport = 465; + smtpencryption = "ssl"; + }; }; aliases = { @@ -4361,7 +4422,7 @@ for these configurations. pavucontrol alsa-utils imagemagick ffmpeg helvum # Net - curl rsync git iamb ungoogled-chromium + curl rsync gitFull iamb ungoogled-chromium # Tor torsocks tor-browser @@ -4808,7 +4869,7 @@ This contains the installation script I use to install my systems. ]; nixos = { packages = with pkgs; [ - git + gitFull curl gum (writeShellScriptBin "nix_installer" diff --git a/nix/modules/cgit.nix b/nix/modules/cgit.nix index cfb9158..54eb90c 100644 --- a/nix/modules/cgit.nix +++ b/nix/modules/cgit.nix @@ -1,6 +1,25 @@ -{ config, lib, ... }: +{ lib, config, ... }: { - services.cgit = { + services.cgit."my-projects" = { enable = true; + scanPath = "/srv/git"; + settings = { + root-title = "Nullring Git Server"; + root-desc = "Projects and cool things"; + enable-commit-graph = 1; + enable-log-filecount = 1; + enable-log-linecount = 1; + enable-index-owner = 0; + clone-prefix = "https://git.${config.monorepo.vars.orgHost}"; + enable-tree-linenumbers = 1; + strict-export = "git-daemon-export-ok"; + }; + gitHttpBackend = { + enable = true; + checkExportOkFiles = true; + }; + nginx = { + virtualHost = "git.${config.monorepo.vars.orgHost}"; + }; }; } diff --git a/nix/modules/configuration.nix b/nix/modules/configuration.nix index 02d4a94..decc121 100644 --- a/nix/modules/configuration.nix +++ b/nix/modules/configuration.nix @@ -1,6 +1,21 @@ { config, pkgs, lib, ... }: +let + userGroups = [ + "nginx" + "git" + "ircd" + "ngircd" + "conduit" + "livekit" + "matterbridge" + "maddy" + "ntfy-sh" + "public-inbox" + ]; +in { imports = [ + ./cgit.nix ./public_inbox.nix ./matterbridge.nix ./mautrix.nix @@ -378,7 +393,7 @@ country=CA environment.systemPackages = with pkgs; [ restic sbctl - git + gitFull git-lfs git-lfs-transfer vim @@ -396,55 +411,29 @@ country=CA ) ]; - users.groups.nginx = lib.mkDefault {}; - users.groups.git = lib.mkDefault {}; - users.groups.ircd = lib.mkDefault {}; - users.groups.ngircd = lib.mkDefault {}; - users.groups.conduit = lib.mkDefault {}; - users.groups.livekit = lib.mkDefault {}; - users.groups.matterbridge = lib.mkDefault {}; - users.groups.maddy = lib.mkDefault {}; - users.groups.ntfy-sh = lib.mkDefault {}; - users.groups.public-inbox = lib.mkDefault {}; - - users.users = { + users.groups = lib.genAttrs userGroups (name: lib.mkDefault {}); + + users.users = lib.genAttrs userGroups (name: { + isSystemUser = lib.mkDefault true; + group = "${name}"; + extraGroups = [ "acme" "nginx" ]; + }) // { conduit = { isSystemUser = lib.mkDefault true; group = "conduit"; + extraGroups = []; }; matterbridge = { isSystemUser = lib.mkDefault true; group = "matterbridge"; - }; - - maddy = { - isSystemUser = lib.mkDefault true; - group = "maddy"; - extraGroups = [ "acme" "nginx" ]; - }; - - ntfy-sh = { - isSystemUser = lib.mkDefault true; - group = "ntfy-sh"; - extraGroups = [ "acme" "nginx" ]; + extraGroups = []; }; public-inbox = { isSystemUser = lib.mkDefault true; group = "public-inbox"; - extraGroups = [ "acme" "nginx" ]; - }; - ngircd = { - isSystemUser = lib.mkDefault true; - group = "ngircd"; - extraGroups = [ "acme" "nginx" ]; - }; - - livekit = { - isSystemUser = lib.mkDefault true; - group = "livekit"; - extraGroups = [ "acme" "nginx" ]; + extraGroups = [ "acme" "nginx" "git" ]; }; ircd = { diff --git a/nix/modules/home/git.nix b/nix/modules/home/git.nix index c80b6f9..24e84b4 100644 --- a/nix/modules/home/git.nix +++ b/nix/modules/home/git.nix @@ -1,7 +1,8 @@ -{ lib, config, ... }: +{ pkgs, lib, config, ... }: { programs.git = { enable = lib.mkDefault config.monorepo.profiles.graphics.enable; + package = pkgs.gitFull; lfs.enable = lib.mkDefault config.monorepo.profiles.graphics.enable; userName = config.monorepo.vars.fullName; userEmail = config.monorepo.profiles.email.email; @@ -12,6 +13,16 @@ extraConfig = { init.defaultBranch = "main"; + credential."${config.monorepo.profiles.email.smtpsServer}" = { + username = "${config.monorepo.profiles.email.email}"; + helper = "!f() { test \"$1\" = get && echo \"password=$(cat /run/user/1000/secrets/mail)\"; }; f"; + }; + sendemail = { + smtpserver = "${config.monorepo.profiles.email.smtpsServer}"; + smtpuser = "${config.monorepo.profiles.email.email}"; + smtpserverport = 465; + smtpencryption = "ssl"; + }; }; aliases = { diff --git a/nix/modules/home/user.nix b/nix/modules/home/user.nix index cb29b4c..28bbd22 100644 --- a/nix/modules/home/user.nix +++ b/nix/modules/home/user.nix @@ -53,7 +53,7 @@ pavucontrol alsa-utils imagemagick ffmpeg helvum # Net - curl rsync git iamb ungoogled-chromium + curl rsync gitFull iamb ungoogled-chromium # Tor torsocks tor-browser diff --git a/nix/modules/maddy.nix b/nix/modules/maddy.nix index 1d4710d..706e187 100644 --- a/nix/modules/maddy.nix +++ b/nix/modules/maddy.nix @@ -25,6 +25,12 @@ "imap tls://0.0.0.0:993 tcp://0.0.0.0:143" "submission tls://0.0.0.0:465 tcp://0.0.0.0:587" ] options.services.maddy.config.default; + ensureAccounts = [ + "${config.monorepo.vars.internetName}@${config.monorepo.vars.orgHost}" + "monorepo@${config.monorepo.vars.orgHost}" + "nullerbot@${config.monorepo.vars.orgHost}" + "discussion@${config.monorepo.vars.orgHost}" + ]; ensureCredentials = { "${config.monorepo.vars.internetName}@${config.monorepo.vars.orgHost}" = { passwordFile = "/run/secrets/mail_password"; @@ -32,6 +38,9 @@ "monorepo@${config.monorepo.vars.orgHost}" = { passwordFile = "/run/secrets/mail_monorepo_password"; }; + "nullerbot@${config.monorepo.vars.orgHost}" = { + passwordFile = "/run/secrets/mail_monorepo_password"; + }; "discussion@${config.monorepo.vars.orgHost}" = { passwordFile = "/run/secrets/mail_monorepo_password"; }; diff --git a/nix/modules/nginx.nix b/nix/modules/nginx.nix index 621c9ef..791e3a4 100644 --- a/nix/modules/nginx.nix +++ b/nix/modules/nginx.nix @@ -162,6 +162,10 @@ enableACME = true; }; + "git.${config.monorepo.vars.orgHost}" = { + forceSSL = true; + enableACME = true; + }; "list.${config.monorepo.vars.orgHost}" = { forceSSL = true; enableACME = true; diff --git a/nix/modules/public_inbox.nix b/nix/modules/public_inbox.nix index 9f1532c..cba1e39 100644 --- a/nix/modules/public_inbox.nix +++ b/nix/modules/public_inbox.nix @@ -15,6 +15,7 @@ # Allow the service to see the file it just created BindPaths = [ "/var/lib/public-inbox" + "/srv/git/" ]; ReadOnlyPaths = [ "/var/lib/public-inbox/style.css" ]; # Ensure it can actually write to the directory during preStart @@ -54,6 +55,10 @@ services.public-inbox = { enable = lib.mkDefault config.monorepo.profiles.server.enable; settings = { + coderepo."nullerbot".dir = "/srv/git/nullerbot.git"; + coderepo."nullerbot".cgitUrl = "https://git.nullring.xyz/nullerbot.git"; + coderepo."monorepo".dir = "/srv/git/monorepo.git"; + coderepo."monorepo".cgitUrl = "https://git.nullring.xyz/monorepo.git"; publicinbox.css = ["/var/lib/public-inbox/style.css"]; publicinbox.wwwlisting = "all"; }; @@ -68,6 +73,9 @@ inboxdir = "/var/lib/public-inbox/monorepo"; url = "https://list.${config.monorepo.vars.orgHost}/monorepo"; watch = [ "imaps://monorepo%40${config.monorepo.vars.orgHost}@mail.${config.monorepo.vars.orgHost}/INBOX" ]; + coderepo = [ + "monorepo" + ]; }; "discussion" = { @@ -77,6 +85,17 @@ url = "https://list.${config.monorepo.vars.orgHost}/discussion"; watch = [ "imaps://discussion%40${config.monorepo.vars.orgHost}@mail.${config.monorepo.vars.orgHost}/INBOX" ]; }; + + "nullerbot" = { + description = "Discussion of Nullerbot Matrix Bot"; + address = [ "nullerbot@${config.monorepo.vars.orgHost}" ]; + inboxdir = "/var/lib/public-inbox/nullerbot"; + url = "https://list.${config.monorepo.vars.orgHost}/nullerbot"; + watch = [ "imaps://nullerbot%40${config.monorepo.vars.orgHost}@mail.${config.monorepo.vars.orgHost}/INBOX" ]; + coderepo = [ + "nullerbot" + ]; + }; }; }; } diff --git a/nix/modules/secrets.nix b/nix/modules/secrets.nix index 1a09652..9c1dbed 100644 --- a/nix/modules/secrets.nix +++ b/nix/modules/secrets.nix @@ -14,6 +14,7 @@ content = '' machine mail.${config.monorepo.vars.orgHost} login monorepo@${config.monorepo.vars.orgHost} password ${config.sops.placeholder."mail_monorepo_password_pi"} machine mail.${config.monorepo.vars.orgHost} login discussion@${config.monorepo.vars.orgHost} password ${config.sops.placeholder."mail_monorepo_password_pi"} +machine mail.${config.monorepo.vars.orgHost} login nullerbot@${config.monorepo.vars.orgHost} password ${config.sops.placeholder."mail_monorepo_password_pi"} ''; }; "matterbridge" = { diff --git a/nix/systems/installer/default.nix b/nix/systems/installer/default.nix index 0341b0d..e9232cb 100644 --- a/nix/systems/installer/default.nix +++ b/nix/systems/installer/default.nix @@ -36,7 +36,7 @@ in ]; nixos = { packages = with pkgs; [ - git + gitFull curl gum (writeShellScriptBin "nix_installer" -- cgit v1.3