1
Fork 0

Compare commits

..

2 commits

Author SHA1 Message Date
prescientmoon fd36e012f9
Custom octodns setup! 2024-07-08 03:06:27 +02:00
prescientmoon 9e853e9684
Commit after not doing it for weeks 2024-07-06 19:32:14 +02:00
47 changed files with 605 additions and 155 deletions

74
dns/common.nix Normal file
View file

@ -0,0 +1,74 @@
# DNS entries which do not belong to a particular host
{ lib, ... }:
let
# {{{ Github pages helper
ghPage = at: [{
inherit at; type = "CNAME";
value = "prescientmoon.github.io.";
}];
# }}}
# {{{ Migadu mail DNS setup
migaduMail = at: verifyKey:
let atPrefix = prefix: if at == "" then prefix else "${prefix}.${at}";
in
[
{
inherit at;
ttl = 600;
type = "MX";
value = [
{
exchange = "aspmx1.migadu.com.";
preference = 10;
}
{
exchange = "aspmx2.migadu.com.";
preference = 20;
}
];
}
{
inherit at;
ttl = 600;
type = "TXT";
value = [
"v=spf1 include:spf.migadu.com -all"
"hosted-email-verify=${verifyKey}"
];
}
{
at = atPrefix "_dmarc";
type = "TXT";
value = ''v=DMARC1\; p=quarantine\;'';
ttl = 600;
}
{
at = atPrefix "key1._domainkey";
type = "CNAME";
value = "key1.orbit.moonythm.dev._domainkey.migadu.com.";
ttl = 600;
}
{
at = atPrefix "key2._domainkey";
type = "CNAME";
value = "key2.orbit.moonythm.dev._domainkey.migadu.com.";
ttl = 600;
}
{
at = atPrefix "key3._domainkey";
type = "CNAME";
value = "key3.orbit.moonythm.dev._domainkey.migadu.com.";
ttl = 600;
}
];
# }}}
in
{
satellite.dns.domain = "moonythm.dev";
satellite.dns.records = lib.flatten [
(ghPage "doffycup")
(ghPage "erratic-gate")
(migaduMail "" "kfkhyexd")
(migaduMail "orbit" "24s7lnum")
];
}

20
dns/octodns.yaml Normal file
View file

@ -0,0 +1,20 @@
manager:
max_workers: 10
providers:
zones:
class: octodns.provider.yaml.YamlProvider
default_ttl: 300
enforce_order: true
directory: this is set by nix :3
cloudflare:
class: octodns_cloudflare.CloudflareProvider
token: 'env/CLOUDFLARE_TOKEN'
zones:
moonythm.dev.:
sources:
- zones
targets:
- cloudflare

37
dns/pkgs.nix Normal file
View file

@ -0,0 +1,37 @@
{ pkgs, self, system, ... }: rec {
octodns-zones =
let
nixosConfigModules = pkgs.lib.mapAttrsToList
(_: current: { satellite.dns = current.config.satellite.dns; })
self.nixosConfigurations;
evaluated = pkgs.lib.evalModules {
specialArgs = { inherit pkgs; };
modules = [
../modules/nixos/dns.nix
../modules/common/octodns.nix
./common.nix
]
++ nixosConfigModules;
};
in
evaluated.config.satellite.dns.octodns;
octodns-sync =
pkgs.symlinkJoin {
name = "octodns-sync";
paths = [ self.packages.${system}.octodns ];
buildInputs = [ pkgs.makeWrapper pkgs.yq ];
postBuild = ''
cat ${./octodns.yaml} | yq '.providers.zones.directory="${octodns-zones}"' > $out/config.yaml
wrapProgram $out/bin/octodns-sync \
--run 'export CLOUDFLARE_TOKEN=$( \
sops \
--decrypt \
--extract "[\"cloudflare_dns_api_token\"]" \
./hosts/nixos/common/secrets.yaml \
)' \
--add-flags "--config-file $out/config.yaml"
'';
};
}

View file

@ -569,6 +569,22 @@
}
},
"flake-compat_5": {
"flake": false,
"locked": {
"lastModified": 1696426674,
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
"type": "github"
},
"original": {
"owner": "edolstra",
"repo": "flake-compat",
"type": "github"
}
},
"flake-compat_6": {
"flake": false,
"locked": {
"lastModified": 1673956053,
@ -584,7 +600,7 @@
"type": "github"
}
},
"flake-compat_6": {
"flake-compat_7": {
"flake": false,
"locked": {
"lastModified": 1696426674,
@ -600,7 +616,7 @@
"type": "github"
}
},
"flake-compat_7": {
"flake-compat_8": {
"flake": false,
"locked": {
"lastModified": 1673956053,
@ -788,7 +804,7 @@
},
"flake-utils_6": {
"inputs": {
"systems": "systems_4"
"systems": "systems_5"
},
"locked": {
"lastModified": 1685518550,
@ -806,7 +822,7 @@
},
"flake-utils_7": {
"inputs": {
"systems": "systems_5"
"systems": "systems_6"
},
"locked": {
"lastModified": 1710146030,
@ -824,7 +840,7 @@
},
"flake-utils_8": {
"inputs": {
"systems": "systems_6"
"systems": "systems_7"
},
"locked": {
"lastModified": 1685518550,
@ -1396,6 +1412,29 @@
"type": "github"
}
},
"nixos-dns": {
"inputs": {
"flake-compat": "flake-compat_5",
"nixpkgs": [
"nixpkgs"
],
"systems": "systems_4",
"treefmt-nix": "treefmt-nix_2"
},
"locked": {
"lastModified": 1715321534,
"narHash": "sha256-cDTRRrLj08k867/lajKXkCg9HTNWuoYGfgr8wyAVaTY=",
"owner": "Janik-Haag",
"repo": "nixos-dns",
"rev": "c4f734d771038db15700a61a8703d0da5f993b3a",
"type": "github"
},
"original": {
"owner": "Janik-Haag",
"repo": "nixos-dns",
"type": "github"
}
},
"nixos-hardware": {
"locked": {
"lastModified": 1711352745,
@ -1776,7 +1815,7 @@
},
"pre-commit-hooks_2": {
"inputs": {
"flake-compat": "flake-compat_5",
"flake-compat": "flake-compat_6",
"flake-utils": "flake-utils_6",
"gitignore": "gitignore_2",
"nixpkgs": "nixpkgs_12",
@ -1798,7 +1837,7 @@
},
"pre-commit-hooks_3": {
"inputs": {
"flake-compat": "flake-compat_6",
"flake-compat": "flake-compat_7",
"flake-utils": "flake-utils_7",
"gitignore": "gitignore_3",
"nixpkgs": "nixpkgs_13",
@ -1929,6 +1968,7 @@
"miros": "miros",
"neovim-nightly-overlay": "neovim-nightly-overlay",
"nix-index-database": "nix-index-database",
"nixos-dns": "nixos-dns",
"nixos-hardware": "nixos-hardware",
"nixpkgs": "nixpkgs_8",
"nixpkgs-unstable": "nixpkgs-unstable",
@ -2157,7 +2197,7 @@
"base16-kitty": "base16-kitty",
"base16-tmux": "base16-tmux",
"base16-vim": "base16-vim",
"flake-compat": "flake-compat_7",
"flake-compat": "flake-compat_8",
"gnome-shell": "gnome-shell",
"home-manager": "home-manager_4",
"nixpkgs": "nixpkgs_14"
@ -2280,9 +2320,8 @@
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
"id": "systems",
"type": "indirect"
}
},
"systems_5": {
@ -2315,6 +2354,21 @@
"type": "github"
}
},
"systems_7": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"template-haskell-reload": {
"flake": false,
"locked": {
@ -2354,6 +2408,27 @@
"type": "github"
}
},
"treefmt-nix_2": {
"inputs": {
"nixpkgs": [
"nixos-dns",
"nixpkgs"
]
},
"locked": {
"lastModified": 1714058656,
"narHash": "sha256-Qv4RBm4LKuO4fNOfx9wl40W2rBbv5u5m+whxRYUMiaA=",
"owner": "numtide",
"repo": "treefmt-nix",
"rev": "c6aaf729f34a36c445618580a9f95a48f5e4e03f",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "treefmt-nix",
"type": "github"
}
},
"validity": {
"flake": false,
"locked": {

View file

@ -33,6 +33,9 @@
sops-nix.inputs.nixpkgs.follows = "nixpkgs";
korora.url = "github:adisbladis/korora";
nixos-dns.url = "github:Janik-Haag/nixos-dns";
nixos-dns.inputs.nixpkgs.follows = "nixpkgs";
# }}}
# {{{ Standalone software
# {{{ Nightly versions of things
@ -79,9 +82,6 @@
outputs = { self, nixpkgs, home-manager, ... }@inputs:
let
# Main username
pilot = "adrielus";
# {{{ Common helpers
inherit (self) outputs;
forAllSystems = nixpkgs.lib.genAttrs [
@ -101,10 +101,18 @@
{
# {{{ Packages
# Accessible through 'nix build', 'nix shell', etc
packages = forAllSystems (system:
let pkgs = nixpkgs.legacyPackages.${system};
in import ./pkgs { inherit pkgs; }
);
packages = forAllSystems
(system:
let
pkgs = nixpkgs.legacyPackages.${system};
upkgs = inputs.nixpkgs-unstable.legacyPackages.${system};
myPkgs = import ./pkgs { inherit pkgs upkgs; };
in
myPkgs // {
octodns = upkgs.octodns.withProviders
(ps: [ myPkgs.octodns-cloudflare ]);
} // (import ./dns/pkgs.nix) { inherit pkgs self system; }
);
# }}}
# {{{ Bootstrapping and other pinned devshells
# Accessible through 'nix develop'
@ -170,33 +178,6 @@
};
# }}}
# {{{ Home manager
# Standalone home-manager configuration entrypoint
# Available through 'home-manager --flake .#...
homeConfigurations =
let
mkHomeConfig = { system, hostname }:
home-manager.lib.homeManagerConfiguration {
pkgs = nixpkgs.legacyPackages.${system};
extraSpecialArgs = specialArgs system // { inherit hostname; };
modules = [ ./home/${hostname}.nix ];
};
in
{
"${pilot}@tethys" = mkHomeConfig {
system = "x86_64-linux";
hostname = "tethys";
};
"guest@euporie" = mkHomeConfig {
system = "x86_64-linux";
hostname = "euporie";
};
"${pilot}@lapetus" = mkHomeConfig {
system = "x86_64-linux";
hostname = "lapetus";
};
};
# }}}
};
# {{{ Caching and whatnot

View file

@ -13,6 +13,7 @@
];
programs.bash.enable = true;
stylix.targets.yazi.enable = true;
home.packages = with pkgs; [
# {{{ System information
@ -42,12 +43,12 @@
home.shellAliases = {
# {{{ Storage
# -h = humans readable units
# -h: humans readable units
df = "df -h";
du = "du -h";
# short for `du here`
# -d = depth
# duh: short for `du here`
# -d: depth
duh = "du -hd 1";
# }}}
};

View file

@ -17,6 +17,8 @@ let
"\\e\\[13\\;2u" = "commandline -a ' | $PAGER' && commandline -f execute";
# C-g to open lazygit
"\\cg" = "lazygit";
# C-S-f to open mini.files
"\\e\\[70\\;5u" = ''nvim +":lua require('mini.files').open()"'';
};
mkKeybind = key: value:

View file

@ -39,20 +39,15 @@ in
};
# }}}
# {{{ Add desktop entry
home.packages =
# Start smos with a custom class so our WM can move it to the correct workspace
let smosgui = pkgs.writeShellScriptBin "smosgui" ''
wezterm start --class "org.wezfurlong.wezterm.smos" --cwd ${workflowDir} smos
'';
in
[ smosgui ];
xdg.desktopEntries.smosgui = {
name = "Smos GUI";
# Start smos with a custom class so our WM can move it to the correct workspace
xdg.desktopEntries.smostui = {
name = "Smos TUI";
type = "Application";
exec = "smosgui";
terminal = false;
icon = ../../../../../common/icons/smos.svg;
exec = builtins.toString (pkgs.writeShellScript "smostui" ''
wezterm start --class "org.wezfurlong.wezterm.smos" --cwd ${workflowDir} smos
'');
};
# }}}
}

View file

@ -2,19 +2,19 @@
lib.fix (self: {
"Catppuccin Mocha" = fetchurl {
url = "https://catppuccin.github.io/discord/dist/catppuccin-mocha.theme.css";
sha256 = "1agw88vg2dh948365mx8x7hzvghvscdpqhm70icg2x6bs5zszg9l";
sha256 = "01j5xhzpy3a68qlrzchzclj7mnxj106bwxq2vyvxw7fd2n3zn96b";
};
"Catppuccin Frappe" = fetchurl {
url = "https://catppuccin.github.io/discord/dist/catppuccin-frappe.theme.css";
sha256 = "0rrz71n05jb0fd2jymis43i325y87qwrb5s6rryh8gd8anbk8h6y";
sha256 = "037jr133zw04sslkl1hdspkqqb40c3a7hcs72lzjlimaqhnxd044";
};
"Catppuccin Latte" = fetchurl {
url = "https://catppuccin.github.io/discord/dist/catppuccin-latte.theme.css";
sha256 = "HixxRdOTU7RynNseRWAWd4VzqYoX52n2nWlt9DX5MS8=";
sha256 = "1bijp2ysm7ifah6xqz95ag4hi7k7r0s9c8jz0s5a4b00k59qd6qc";
};
"Catppuccin Macchiato" = fetchurl {
url = "https://catppuccin.github.io/discord/dist/catppuccin-macchiato.theme.css";
sha256 = "1dgq1sdy07m0ra3ysn1g29y2ba37cna3sxy2vv125f2pjmdx0vci";
sha256 = "1ggw9iyn7d7z0sv784kgmxbf94xvwn2cnkd8g08xzy5c17gky6ln";
};
default.dark = self."Catppuccin Macchiato";
default.light = self."Catppuccin Latte";

View file

@ -1,19 +1,17 @@
{ config, pkgs, ... }: {
home.packages =
let
vaultDir = "${config.xdg.userDirs.extraConfig.XDG_PROJECTS_DIR}/stellar-sanctum";
# Start nvim with a custom class so our WM can move it to the correct workspace
obsidiantui = pkgs.writeShellScriptBin "obsidiantui" ''
wezterm start --class "org.wezfurlong.wezterm.obsidian" --cwd ${vaultDir} nvim
'';
in
[ obsidiantui pkgs.obsidian ];
home.packages = [ pkgs.obsidian ];
# Start nvim with a custom class so our WM can move it to the correct workspace
xdg.desktopEntries.obsidiantui = {
name = "Obsidian TUI";
type = "Application";
exec = "obsidiantui";
terminal = false;
icon = "obsidian";
terminal = false;
exec =
let vaultDir = "${config.xdg.userDirs.extraConfig.XDG_PROJECTS_DIR}/stellar-sanctum";
in
builtins.toString (pkgs.writeShellScript "obsidiantui" ''
wezterm start --class "org.wezfurlong.wezterm.obsidian" --cwd ${vaultDir} nvim
'');
};
}

View file

@ -80,7 +80,7 @@ M.unicode = {
-- }}}
-- {{{ Common relations
{ "sim", "" }, -- similarity
{ "simeq", "" },
{ "simeq", "" }, -- isomorphism
{ "cong", "" }, -- congruence
{ "iin", "" }, -- [I]ncluded [i][n]

View file

@ -2,7 +2,8 @@ local runtime = require("my.tempest")
local M = {
"folke/which-key.nvim",
event = "VeryLazy",
-- event = "VeryLazy",
lazy = true,
cond = runtime.blacklist("vscode"),
}

View file

@ -13,6 +13,10 @@ M.setup = function(config)
local augroup = vim.api.nvim_create_augroup("M", {})
local on_vimenter = function()
if vim.o.filetype ~= "" then
return
end
if vim.fn.argc() > 0 then
return
end

View file

@ -0,0 +1 @@
Context/!

Binary file not shown.

View file

@ -1406,6 +1406,28 @@ let
event = "VeryLazy";
};
# }}}
# {{{ djot support
djot =
let djot = pkgs.fetchFromGitHub {
owner = "jgm";
repo = "djot";
rev = "2fec440ab7a75a06a1e18c29a00de64ec7c94b9d";
sha256 = "1xy2x1qbmv1kjxdpj2pjm03d9l7qrl0wx96gn5m0lkfxkg766i7z";
};
in
{
dir = "${djot}/editors/vim";
cond = blacklist "vscode";
ft = "djot";
config.autocmds = {
event = "FileType";
group = "UserDjotSettings";
pattern = "djot";
action.vim.opt.commentstring = ''{\% %s \%}'';
};
};
# }}}
# }}}
# {{{ external
# These plugins integrate neovim with external services

View file

@ -44,7 +44,7 @@ animations {
}
# Execute apps at launch
exec-once = wezterm & firefox & discocss & spot & obsidian & obsidiantui & smosgui
exec-once = wezterm & firefox & discocss & spotify & obsidiantui & smostui
# Without this, xdg-open doesn't work
exec = systemctl --user import-environment PATH && systemctl --user restart xdg-desktop-portal.service

View file

@ -1,6 +1,3 @@
{
imports = [ ./global.nix ];
# Arbitrary extra packages
home.packages = [ ];
}

View file

@ -7,6 +7,7 @@ let
inputs.disko.nixosModules.default
inputs.stylix.nixosModules.stylix
inputs.sops-nix.nixosModules.sops
inputs.nixos-dns.nixosModules.dns
# }}}
# {{{ global configuration
./cli/fish.nix
@ -53,4 +54,7 @@ in
config.allowUnfree = true;
};
# Root domain used throughout my config
satellite.dns.domain = "moonythm.dev";
}

View file

@ -23,5 +23,6 @@
forgejo = 8419;
jupyterhub = 8420;
guacamole = 8421;
syncthing = 8422;
};
}

View file

@ -5,10 +5,4 @@
remotePlay.openFirewall = true; # Open ports in the firewall for Steam Remote Play
dedicatedServer.openFirewall = true; # Open ports in the firewall for Source Dedicated Server
};
nixpkgs.config.allowUnfreePredicate = pkg: builtins.elem (lib.getName pkg) [
"steam"
"steam-original"
"steam-runtime"
];
}

View file

@ -1,6 +1,5 @@
{
imports = [ ./acme.nix ];
satellite.nginx.domain = "moonythm.dev"; # Root domain used throughout my config
services.nginx = {
enable = true;
recommendedGzipSettings = true;

View file

@ -28,8 +28,15 @@ in
extraOptions.options.crashReportingEnabled = false;
};
guiAddress = "127.0.0.1:${toString config.satellite.ports.syncthing}";
settings.gui.insecureSkipHostcheck = true;
};
# Expose gui interface via nginx
satellite.nginx.at."syncthing.${config.networking.hostName}".port =
config.satellite.ports.syncthing;
# Syncthing seems to leak memory, so we want to restart it daily.
systemd.services.syncthing.serviceConfig.RuntimeMaxSec = "1d";

View file

@ -1,6 +1,6 @@
wireless: ENC[AES256_GCM,data:Ib0PdBd2r/DPyE6Ah9NffT8Tw8c2y+seGFrE0e9GkyRaStdYMiiIlWCiaBO0u1HHaVV+2MQ33MnMdqyCGRlqGk45kl0GIwVR5iAiSYnobj/6wcse+kx/+5mzNOHXD1kJRGJBm5+SN9ntiGABNkQXJdn/Qoc/ukY1uaGe2nBeFKmGdD9JL7KfgdI5jYjQYyDbCL9JUszxkXNcplIRBAAy8JDaBVeo9HgI0QDIZToPKwuEeQoA9XzdimrjbCazlZy3ZvjAuoQXmrc1nIRHF5GabSRGTFTnTfcBeW2fGpUxmIhLyucn2DIQBXLm+RDdMLWoqcGbKiLVqKyUXck3ZZyoHMf2b9N52xMUwcS7,iv:ozkDwWmurWTD8TZHGvWL9Yh8cOrP1PzSBkz+1bBZybo=,tag:iGPjRaOoGRcOWJMweTL2yA==,type:str]
pilot_password: ENC[AES256_GCM,data:PiKJCv5x68O9HFM4UvqLnsSPtqFslBLeAg67OkvFAbw7WaqbXh/p5SQblhPHcJ7jQDc4kI3XesOxruZrfJ0aZNDV1g7MWecgKg==,iv:EVs/m83Zfx2NRQMO52cF6pCe1ETpYfaR6lmXg2Na/DI=,tag:dl2x1aTsaTgtHEZYdW2lmg==,type:str]
cloudflare_dns_api_token: ENC[AES256_GCM,data:SAIMCvKOpGb5g9s03Xapc08KpOgLI+qlT5oiH/uNGxV+9JFSX3nvmQ==,iv:HFKcmHRG4EEOuJ8gRD0ZWsE18SLaZjewMSLznboLUeI=,tag:z21GURSxvNmZ4qkbri9mDQ==,type:str]
cloudflare_dns_api_token: ENC[AES256_GCM,data:QlLxQ/4AQsdqdWJC//FRgbMRqR0Ni51JgCDlyXfNe4pfPtiPs+Gb6Q==,iv:7SS+EzeHk0J1DzVvKxd40AuZUidV2asoQbSr5vyxl+U=,tag:T1KGXOsZ26sICYbrcmU8+w==,type:str]
backup_password: ENC[AES256_GCM,data:Tu7ODTALfQLX7Mbo/BqiM6gaErGv07urwN1iHwGgurKWDuuE1h5NMV5J0cJqW6orTIloVtoZTJgSJ2lZlMcfUQ==,iv:78ha833ZzgEDChIuGjCMVA89U4qY9lWqUmfPCiiQeQM=,tag:u8KWw/060UVP+OOoPhbjRA==,type:str]
sops:
kms: []
@ -35,8 +35,8 @@ sops:
WFd4ZFNHWG5Cakw5cU9MRE9HWHQ4THMKr/S7v1Oj3zQziMtI/NuFVm6AaJF5JV5U
sEr2nEptYFz4G6YL5psQGXHaKzQKBg+crgKRbYL4akhqT7pfYPC0bQ==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2024-05-29T22:07:18Z"
mac: ENC[AES256_GCM,data:HQJU1hZs8S4b8LAPdAg1/IuIX3VETXHrE/lKzODjCb/ndWV8Qh5v8OKg4X8xFw13PJpEeQqIznh6qplxMHJYGcYnUK/TSTP+399BZ3M0NLGWyF0vfFn1JIKu7zg8iHpi491/T+I6TDy5hp9+Y6V0sjpZ4pEzhZTwPW9t+NieSbQ=,iv:lNu0aLUO2P+2Mq7kVDGt6llshu5wgb++3VMX91w1a+8=,tag:WSoUh4XnRenvhb+vwLUpRg==,type:str]
lastmodified: "2024-07-08T00:25:56Z"
mac: ENC[AES256_GCM,data:v+p223kf9JLRMJ6moIpA5wZOemJY0+BSnX30MY8g28RBGaR+I7AbUHOrd+GUPAXLqwfqtrFdPt8pULT+fzuxL4wnlB9NPZxCYFMhSGGj8HysmDuytYXfSD1LZWD9fymE4KuyTZHv7I/coEM/iobbvutu9cmTKN05i1atjeh4B30=,iv:hPiQkvbeFjLyzTNoHMqqPikMPuDvT2X2iAo7JBlEpHY=,tag:fdHvvH+qPrv8UhwIA6aZSA==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.8.1

View file

@ -1,4 +1,4 @@
{
{ config, ... }: {
imports = [
../common/global
../common/users/pilot.nix
@ -7,6 +7,7 @@
../common/optional/services/kanata.nix
../common/optional/services/nginx.nix
../common/optional/services/postgres.nix
../common/optional/services/syncthing.nix
../common/optional/services/restic
# ./services/commafeed.nix
@ -30,7 +31,6 @@
./services/radicale.nix
./services/redlib.nix
./services/smos.nix
./services/syncthing.nix
./services/vaultwarden.nix
./services/whoogle.nix
./services/zfs.nix
@ -49,4 +49,18 @@
# Bootloader
boot.loader.systemd-boot.enable = true;
# Tailscale internal IP DNS records
satellite.dns.records = [
{
at = config.networking.hostName;
type = "A";
value = "100.93.136.59";
}
{
at = config.networking.hostName;
type = "AAAA";
value = "fd7a:115c:a1e0::e75d:883b";
}
];
}

View file

@ -7,7 +7,11 @@ grafana_discord_webhook: https://discord.com/api/webhooks/...
invidious_hmac_key: ...
# contents of `credentials.json` file generated by `cloudflared tunnel create`
cloudflare_tunnel_credentials: |
...
{
"AccountTag": "...",
"TunnelSecret": "...",
"TunnelID": "..."
}
microbin_env: |
MICROBIN_ADMIN_PASSWORD=...
MICROBIN_UPLOAD_PASSWORD=...

View file

@ -9,7 +9,6 @@ in
virtualisation.oci-containers.containers.commafeed = {
image = "athou/commafeed:latest";
autoStart = true;
ports = [ "${toString port}:8082" ]; # server:docker
volumes = [ "${dataDir}:/commafeed/data" ]; # server:docker

View file

@ -1,17 +1,12 @@
{ lib, config, ... }:
let
port = config.satellite.ports.forgejo;
host = "git.moonythm.dev";
cfg = config.services.forgejo;
in
{
sops.secrets.forgejo_mail_password = {
sopsFile = ../secrets.yaml;
owner = cfg.user;
group = cfg.group;
owner = config.services.forgejo.user;
group = config.services.forgejo.group;
};
satellite.cloudflared.targets.${host}.port = port;
satellite.cloudflared.at.git.port = config.satellite.ports.forgejo;
services.forgejo = {
enable = true;
@ -30,9 +25,9 @@ in
default.APP_NAME = "moonforge";
server = {
DOMAIN = host;
HTTP_PORT = port;
ROOT_URL = "https://${host}";
DOMAIN = config.satellite.cloudflared.at.git.host;
HTTP_PORT = config.satellite.cloudflared.at.git.port;
ROOT_URL = config.satellite.cloudflared.at.git.host.url;
LANDING_PAGE = "prescientmoon"; # Make my profile the landing page
};

View file

@ -12,9 +12,7 @@
"/var/lib/guacamole:/config"
];
environment = {
TZ = config.time.timeZone;
};
environment.TZ = config.time.timeZone;
};
# Allow ssh-ing using the provided key

View file

@ -55,7 +55,7 @@ in
name = "Syncthing";
subtitle = "File synchronization";
logo = icon "syncthing.png";
url = "https://lapetus.syncthing.moonythm.dev";
url = "https://syncthing.lapetus.moonythm.dev";
}
{
name = "Guacamole";

View file

@ -5,17 +5,15 @@
# {{{ Storage
environment.persistence."/persist/state".directories = [{
inherit (config.services.jellyfin) user group;
directory = "/var/lib/jellyfin";
mode = "u=rwx,g=r,o=r";
user = config.services.jellyfin.user;
group = config.services.jellyfin.group;
}];
environment.persistence."/persist/local/cache".directories = [{
inherit (config.services.jellyfin) user group;
directory = "/var/cache/jellyfin";
mode = "u=rwx,g=,o=";
user = config.services.jellyfin.user;
group = config.services.jellyfin.group;
}];
# }}}
}

View file

@ -18,7 +18,7 @@ in
services.jupyterhub = {
enable = true;
port = config.satellite.ports.jupyterhub;
port = config.satellite.cloudflared.at.jupyter.port;
jupyterhubEnv = appEnv;
jupyterlabEnv = appEnv;
@ -71,7 +71,7 @@ in
};
# }}}
# {{{ Networking & storage
satellite.cloudflared.targets."jupyter.moonythm.dev".port = config.services.jupyterhub.port;
satellite.cloudflared.at.jupyter.port = config.services.jupyterhub.port;
environment.persistence."/persist/state".directories = [
"/var/lib/${config.services.jupyterhub.stateDirectory}"

View file

@ -1,11 +1,7 @@
{ config, lib, ... }:
let
port = config.satellite.ports.microbin;
host = "bin.moonythm.dev";
in
{
sops.secrets.microbin_env.sopsFile = ../secrets.yaml;
satellite.cloudflared.targets.${host}.port = port;
satellite.cloudflared.at.bin.port = config.satellite.ports.microbin;
services.microbin = {
enable = true;
@ -16,8 +12,8 @@ in
settings = {
# High level settings
MICROBIN_ADMIN_USERNAME = "prescientmoon";
MICROBIN_PORT = toString port;
MICROBIN_PUBLIC_PATH = "https://bin.moonythm.dev/";
MICROBIN_PORT = toString config.satellite.cloudflared.at.bin.port;
MICROBIN_PUBLIC_PATH = config.satellite.cloudflared.at.bin.url;
MICROBIN_DEFAULT_EXPIRY = "1week";
# Disable online features

View file

@ -28,9 +28,22 @@ in
# Configure pounce
services.pounce = {
enable = true;
externalHost = "irc.moonythm.dev";
bindHost = "irc.moonythm.dev";
externalHost = "irc.${config.satellite.dns.domain}";
bindHost = "irc.${config.satellite.dns.domain}";
certDir = "/var/lib/acme/wildcard-irc.moonythm.dev";
networks.tilde.config = config.sops.templates."pounce-tilde.cfg".path;
};
satellite.dns.records = [
{
type = "CNAME";
at = "*.irc";
to = "irc";
}
{
type = "CNAME";
at = "irc";
to = config.networking.hostName;
}
];
}

View file

@ -25,8 +25,9 @@ in
environment = {
WEBUI_PORT = toString port;
PGID = "100";
PUID = "1000";
PGID = config.users.groups.users.gid;
TZ = config.time.timeZone;
};
};
# }}}

View file

@ -1,12 +0,0 @@
{ config, ... }:
let port = 8384;
in
{
services.syncthing = {
settings.folders = { };
guiAddress = "127.0.0.1:${toString port}";
settings.gui.insecureSkipHostcheck = true;
};
satellite.nginx.at."lapetus.syncthing".port = port;
}

View file

@ -1,4 +1,4 @@
{ lib, pkgs, ... }: {
{ config, lib, pkgs, ... }: {
# {{{ Imports
imports = [
../common/global
@ -43,6 +43,7 @@
programs.firejail.enable = true;
programs.extra-container.enable = true;
virtualisation.docker.enable = true;
virtualisation.waydroid.enable = true;
# virtualisation.spiceUSBRedirection.enable = true; # This was required for the vm usb passthrough tomfoolery
# }}}
# {{{ Ad-hoc stylix targets
@ -56,7 +57,7 @@
blacklisted = [
# "twitter.com"
# "www.reddit.com"
# "minesweeper.online"
"minesweeper.online"
];
blacklist = lib.concatStringsSep "\n" (lib.forEach blacklisted (host: "127.0.0.1 ${host}"));
in
@ -71,4 +72,18 @@
programs.dconf.enable = true;
services.gnome.evolution-data-server.enable = true;
services.gnome.gnome-online-accounts.enable = true;
# Tailscale internal IP DNS records
satellite.dns.records = [
# {
# at = config.networking.hostName;
# type = "A";
# value = "100.93.136.59";
# }
# {
# at = config.networking.hostName;
# type = "AAAA";
# value = "fd7a:115c:a1e0::e75d:883b";
# }
];
}

View file

@ -0,0 +1,46 @@
{ config, pkgs, lib, ... }:
let
format = pkgs.formats.yaml { };
cfg = config.satellite.dns;
in
{
options.satellite.dns.octodns = lib.mkOption {
description = "Derivation building a directory containing all the zone files";
type = lib.types.path;
};
config.satellite.dns.octodns =
let
grouped = builtins.groupBy (entry: entry.zone) cfg.records;
cpLines = lib.mapAttrsToList
(zone: group:
let
grouped = builtins.groupBy (entry: entry.at) group;
contents = lib.mapAttrs
(at: entries: lib.lists.forEach entries
(entry:
let
content =
if builtins.typeOf entry.value == "list"
then { values = entry.value; }
else { inherit (entry) value; };
cloudflare =
if entry.enableCloudflareProxy then {
octodns.cloudflare.proxied = true;
} else { };
in
{ inherit (entry) ttl type; }
// content // cloudflare
))
grouped;
file = format.generate "${zone}.yaml" contents;
in
"cp ${file} $out/${zone}.yaml"
)
grouped;
in
pkgs.runCommand "octodns-zones" { } ''
mkdir $out
${lib.concatStringsSep "\n" cpLines}
'';
}

View file

@ -5,25 +5,47 @@ in
options.satellite.cloudflared = {
tunnel = lib.mkOption {
type = lib.types.str;
description = "Cloudflare tunnel id to use for the `satellite.cloudflared.targets` helper";
description = "Cloudflare tunnel id to use for the `satellite.cloudflared.at` helper";
};
targets = lib.mkOption {
domain = lib.mkOption {
description = "Root domain to use as a default for configurations.";
type = lib.types.str;
default = config.satellite.dns.domain;
};
at = lib.mkOption {
description = "List of hosts to set up ingress rules for";
default = { };
type = lib.types.attrsOf (lib.types.submodule ({ name, ... }: {
type = lib.types.attrsOf (lib.types.submodule ({ name, config, ... }: {
options = {
subdomain = lib.mkOption {
description = ''
Subdomain to use for host generation.
Only required if `host` is not set manually.
'';
type = lib.types.str;
default = name;
};
port = lib.mkOption {
type = lib.types.port;
description = "Localhost port to point the tunnel at";
type = lib.types.port;
};
host = lib.mkOption {
default = name;
type = lib.types.str;
description = "Host to direct traffic from";
type = lib.types.str;
default = "${config.subdomain}.${cfg.domain}";
};
url = lib.mkOption {
description = "External https url used to access this host";
type = lib.types.str;
};
};
config.url = "https://${config.host}";
}));
};
};
@ -33,5 +55,14 @@ in
name = host;
value = "http://localhost:${toString port}";
})
cfg.targets;
cfg.at;
config.satellite.dns.records =
let mkDnsRecord = { subdomain, ... }: {
type = "CNAME";
at = subdomain;
zone = cfg.domain;
value = "${cfg.tunnel}.cfargotunnel.com.";
};
in lib.attrsets.mapAttrsToList (_: mkDnsRecord) cfg.at;
}

View file

@ -7,4 +7,6 @@
nginx = import ./nginx.nix;
pilot = import ./pilot.nix;
pounce = import ./pounce.nix;
dns = import ./dns.nix;
dns-assertions = import ./dns-assertions.nix;
}

View file

@ -0,0 +1,17 @@
# This must only be loaded on actual Nixos, otherwise `assertions`
# won't be defined when running `evaluateModules`.
{ config, ... }:
let cfg = config.satellite.dns;
in
{
config.assertions =
let assertProperToUsage = config:
{
assertion = (config.to == null) || (config.type == "CNAME");
message = ''
The option `satellite.dns.records[*].to` can only be used with `CNAME` records.
This was not the case for ${config.type} record at ${config.at}.${config.zone}.
'';
};
in builtins.map assertProperToUsage cfg.records;
}

59
modules/nixos/dns.nix Normal file
View file

@ -0,0 +1,59 @@
{ config, pkgs, lib, ... }:
let
format = pkgs.formats.yaml { };
cfg = config.satellite.dns;
in
{
options.satellite.dns = {
domain = lib.mkOption {
description = "Default zone to include records in";
type = lib.types.str;
};
records = lib.mkOption {
description = "List of records to create";
default = [ ];
type = lib.types.listOf (lib.types.submodule ({ config, ... }: {
options = {
at = lib.mkOption {
description = "Subdomain to use for entry";
type = lib.types.nullOr lib.types.str;
};
zone = lib.mkOption {
description = "Zone this record is a part of";
type = lib.types.str;
default = cfg.domain;
};
type = lib.mkOption {
type = lib.types.enum [ "A" "AAAA" "TXT" "CNAME" "MX" ];
description = "The type of the DNS record";
};
to = lib.mkOption {
type = lib.types.nullOr lib.types.str;
description = "Shorthand for CNMAE-ing to a subdomain of the given zone";
default = null;
};
value = lib.mkOption {
type = format.type;
description = "The value assigned to the record, in octodns format";
};
ttl = lib.mkOption {
type = lib.types.int;
description = "The TTL assigned to the record";
default = 300;
};
enableCloudflareProxy = lib.mkEnableOption "proxying using cloudflare";
};
config.value = lib.mkIf (config.type == "CNAME" && config.to != null)
"${config.to}.${config.zone}.";
}));
};
};
}

View file

@ -6,24 +6,28 @@ in
domain = lib.mkOption {
description = "Root domain to use as a default for configurations.";
type = lib.types.str;
default = config.satellite.dns.domain;
};
at = lib.mkOption {
description = "Per-subdomain nginx configuration";
type = lib.types.attrsOf (lib.types.submodule ({ name, config, ... }: {
options.name = lib.mkOption {
description = "Attribute name leading to this submodule";
options.subdomain = lib.mkOption {
description = ''
Subdomain to use for host generation.
Only required if `host` is not set manually.
'';
type = lib.types.str;
default = name;
};
config.name = name;
options.host = lib.mkOption {
description = "Host to route requests from";
type = lib.types.str;
default = "${name}.${cfg.domain}";
};
config.host = "${config.subdomain}.${cfg.domain}";
options.url = lib.mkOption {
description = "External https url used to access this host";
type = lib.types.str;
@ -53,8 +57,8 @@ in
{
assertion = (config.port == null) == (config.files != null);
message = ''
Precisely one of the options 'satellite.nginx.at.${config.name}.port'
and 'satellite.nginx.at.${config.name}.files' must be specified.
Precisely one of the options 'satellite.nginx.at.${config.subdomain}.port'
and 'satellite.nginx.at.${config.subdomain}.files' must be specified.
'';
};
in lib.mapAttrsToList (_: assertSingleTarget) cfg.at;
@ -81,5 +85,14 @@ in
} // extra;
};
in lib.attrsets.mapAttrs' (_: mkNginxConfig) cfg.at;
satellite.dns.records =
let mkDnsRecord = { subdomain, ... }: {
type = "CNAME";
zone = cfg.domain;
at = subdomain;
to = config.networking.hostName;
};
in lib.attrsets.mapAttrsToList (_: mkDnsRecord) cfg.at;
};
}

View file

@ -1,12 +1,15 @@
# Custom packages, that can be defined similarly to ones from nixpkgs
# You can build them using 'nix build .#example' or (legacy) 'nix-build -A example'
{ pkgs ? (import ../nixpkgs.nix) { } }:
{ pkgs ? (import ../nixpkgs.nix) { }, upkgs ? pkgs, ... }:
let plymouthThemes = pkgs.callPackage (import ./plymouth-themes.nix) { }; in
{
# example = pkgs.callPackage (import ./example.nix) {};
vimclip = pkgs.callPackage (import ./vimclip.nix) { };
homer = pkgs.callPackage (import ./homer.nix) { };
# REASON: octodns not in nixpkgs 23.11
octodns-cloudflare = upkgs.python3Packages.callPackage (import ./octodns-cloudflare.nix) { };
plymouthThemeCutsAlt = plymouthThemes.cuts_alt;
}

View file

@ -0,0 +1,45 @@
{ lib
, buildPythonPackage
, fetchFromGitHub
, octodns
, pytestCheckHook
, pythonOlder
, dnspython
, setuptools
, requests
, requests-mock
}:
buildPythonPackage rec {
pname = "octodns-cloudflare";
version = "unstable-2024-05-31";
pyproject = true;
disabled = pythonOlder "3.8";
src = fetchFromGitHub {
owner = "octodns";
repo = "octodns-cloudflare";
rev = "3c01938e280767f433eb276a75d6b02c152c02af";
sha256 = "1dnvyvf6mlpqcsrj11192li2mhqfs8w6pvaqmsy3jsqjqczmgmf5";
};
nativeBuildInputs = [
setuptools
];
propagatedBuildInputs = [
octodns
dnspython
requests
];
env.OCTODNS_RELEASE = 1;
pythonImportsCheck = [ "octodns_cloudflare" ];
nativeCheckInputs = [
pytestCheckHook
requests-mock
];
}

0
scripts/dns/delete-all-records.sh Normal file → Executable file
View file

View file

@ -34,7 +34,7 @@ yt IN CNAME lapetus
*.irc IN CNAME irc
; Tunnel used by lapetus
tunnel.lapetus IN CNAME 347d9ead-a523-4f8b-bca7-3066e31e2952.cfargotunnel.com
tunnel.lapetus IN CNAME 347d9ead-a523-4f8b-bca7-3066e31e2952.cfargotunnel.com.
; lapetus services using cloudflare tunnels
bin IN CNAME tunnel.lapetus