From: Preston Pan Date: Tue, 17 Feb 2026 07:13:47 +0000 (-0800) Subject: finish up most of the sysadmin work X-Git-Url: https://nullring.xyz/gitweb/%22../style.css/static/git-logo.png?a=commitdiff_plain;h=06198567765055febc8829f9f2ca398dd6817d93;p=monorepo.git finish up most of the sysadmin work --- 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}" = {};