** 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]]
(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")
(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
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 = ''
format = "yaml";
owner = "maddy";
};
+
+ mail_monorepo_password = {
+ format = "yaml";
+ owner = "maddy";
+ };
+
+ mail_monorepo_password_pi = {
+ format = "yaml";
+ owner = "public-inbox";
+ };
+
conduit_secrets = {
format = "yaml";
};
discord_token = {
format = "yaml";
};
+ mpd_password = {
+ format = "yaml";
+ owner = "nginx";
+ };
ntfy = {
format = "yaml";
owner = "ntfy-sh";
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 = {
};
}
#+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
};
}
#+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
gitweb = {
enable = true;
- virtualHost = "${config.monorepo.vars.remoteHost}";
+ virtualHost = "${config.monorepo.vars.orgHost}";
};
virtualHosts = {
};
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 = ''
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)
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/";
"${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
{ config, pkgs, lib, ... }:
{
imports = [
+ ./public_inbox.nix
./matterbridge.nix
./mautrix.nix
./xserver.nix
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 = {
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";
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}" = {
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";
};
(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)}")
'';
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 {
packages = with pkgs; (if config.monorepo.profiles.graphics.enable then [
# wikipedia
# kiwix kiwix-tools
+ gnupg
+ unzip
mupdf
zathura
'';
};
};
+ xdg.mimeApps = {
+ enable = true;
+ defaultApplications = {
+ "x-scheme-handler/mailto" = "emacsclient-mail.desktop";
+ };
+ };
programs.bash.enable = true;
fonts.fontconfig.enable = true;
{ config, sops-nix, ... }:
{
home-manager = {
+ backupFileExtension = "backup";
sharedModules = [
sops-nix.homeManagerModules.sops
];
7881
8443
8448
+ 9418
];
allowedUDPPorts = [
3478 5349 7882
"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}" = {
};
"${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}" = {};
- 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]]
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:
--- /dev/null
+: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;
+}
(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")
(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
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 = {
{ config, pkgs, lib, ... }:
{
imports = [
+ ./public_inbox.nix
./matterbridge.nix
./mautrix.nix
./xserver.nix
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 = {
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";
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}" = {
--- /dev/null
+{ 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;
+ };
+ };
+}
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";
};
(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)}")
'';
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 {
packages = with pkgs; (if config.monorepo.profiles.graphics.enable then [
# wikipedia
# kiwix kiwix-tools
+ gnupg
+ unzip
mupdf
zathura
'';
};
};
+ xdg.mimeApps = {
+ enable = true;
+ defaultApplications = {
+ "x-scheme-handler/mailto" = "emacsclient-mail.desktop";
+ };
+ };
programs.bash.enable = true;
fonts.fontconfig.enable = true;
"${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";
+ };
};
};
}
--- /dev/null
+{ lib, config, ... }:
+{
+ enable = lib.mkDefault config.monorepo.profiles.server.enable;
+ registrationUrl = "localhost";
+
+ settings = {
+ homeserver.url = "https://matrix.nullring.xyz";
+ homserver.domain = "matrix.nullring.xyz";
+ };
+}
gitweb = {
enable = true;
- virtualHost = "${config.monorepo.vars.remoteHost}";
+ virtualHost = "${config.monorepo.vars.orgHost}";
};
virtualHosts = {
};
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 = ''
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)
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/";
--- /dev/null
+{ 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" ];
+ };
+ };
+ };
+}
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 = ''
format = "yaml";
owner = "maddy";
};
+
+ mail_monorepo_password = {
+ format = "yaml";
+ owner = "maddy";
+ };
+
+ mail_monorepo_password_pi = {
+ format = "yaml";
+ owner = "public-inbox";
+ };
+
conduit_secrets = {
format = "yaml";
};
discord_token = {
format = "yaml";
};
+ mpd_password = {
+ format = "yaml";
+ owner = "nginx";
+ };
ntfy = {
format = "yaml";
owner = "ntfy-sh";
-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
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
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]
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:
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
{ config, sops-nix, ... }:
{
home-manager = {
+ backupFileExtension = "backup";
sharedModules = [
sops-nix.homeManagerModules.sops
];
7881
8443
8448
+ 9418
];
allowedUDPPorts = [
3478 5349 7882
"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}" = {
};
"${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}" = {};