Compare commits

...

9 commits

30 changed files with 593 additions and 3459 deletions

View file

@ -180,7 +180,7 @@
},
"flake-utils_2": {
"inputs": {
"systems": "systems_2"
"systems": "systems_3"
},
"locked": {
"lastModified": 1710146030,
@ -239,11 +239,11 @@
]
},
"locked": {
"lastModified": 1713294767,
"narHash": "sha256-LmaabaQZdx52MPGKPRt9Opoc9Gd9RbwvCdysUUYQoXI=",
"lastModified": 1713713092,
"narHash": "sha256-rvyr6BBtn3cq5B/48rhJlbIOpxprwlO/71663sd9Gik=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "fa8c16e2452bf092ac76f09ee1fb1e9f7d0796e7",
"rev": "2846d5230a3c3923618eabb367deaf8885df580f",
"type": "github"
},
"original": {
@ -279,11 +279,11 @@
"nixpkgs-lib": "nixpkgs-lib"
},
"locked": {
"lastModified": 1713105314,
"narHash": "sha256-X3URKbcgIy4UaQGrsy3DmY5x+fePQ5IYaa76YewoUE0=",
"lastModified": 1713701427,
"narHash": "sha256-v6z8hz/UDaC/rbnkH+hxGFUxlNyseVntRetVpSxLU6c=",
"owner": "nix-community",
"repo": "lib-aggregate",
"rev": "f347ed9a1cab12c27541ed4d173e2f2d5c9bc0bb",
"rev": "3b32a98eb3053f8c8ca55497d1881443ef2996e6",
"type": "github"
},
"original": {
@ -297,7 +297,7 @@
"flake-parts": "flake-parts",
"nix-github-actions": "nix-github-actions",
"nixpkgs": "nixpkgs_6",
"treefmt-nix": "treefmt-nix"
"treefmt-nix": "treefmt-nix_2"
},
"locked": {
"lastModified": 1705242886,
@ -373,14 +373,16 @@
"flake-compat": "flake-compat_2",
"nixpkgs": [
"nixpkgs"
]
],
"systems": "systems_2",
"treefmt-nix": "treefmt-nix"
},
"locked": {
"lastModified": 1708022692,
"narHash": "sha256-T2o3XwFWK5bYNnVqEYdW9JqmOtgpn26/GCgbrVJ47ls=",
"lastModified": 1713393417,
"narHash": "sha256-YriEUgA8u37V859nbSpqeYlL/GiezzeBIyBAAzhxZaI=",
"owner": "Janik-Haag",
"repo": "nixos-dns",
"rev": "0205c8cc6b4f7f75689a922b0bf20730c64a51f4",
"rev": "1cf30ea07873b291fc39265d4c6dc63bfdf67ad7",
"type": "github"
},
"original": {
@ -412,11 +414,11 @@
},
"nixos-hardware": {
"locked": {
"lastModified": 1712909959,
"narHash": "sha256-7/5ubuwdEbQ7Z+Vqd4u0mM5L2VMNDsBh54visp27CtQ=",
"lastModified": 1713521961,
"narHash": "sha256-EwR8wW9AqJhSIY+0oxWRybUZ32BVKuZ9bjlRh8SJvQ8=",
"owner": "NixOS",
"repo": "nixos-hardware",
"rev": "f58b25254be441cd2a9b4b444ed83f1e51244f1f",
"rev": "5d48925b815fd202781bfae8fb6f45c07112fdb2",
"type": "github"
},
"original": {
@ -444,11 +446,11 @@
},
"nixpkgs-lib": {
"locked": {
"lastModified": 1713055793,
"narHash": "sha256-vIrZQykYW32RnlI2lT/gCcB59BOIqqrAmPirBdiirrc=",
"lastModified": 1713660444,
"narHash": "sha256-2bVnrEGyWJhRNKspzfTJmVD/fsH9HQURD4cWpz79Ulw=",
"owner": "nix-community",
"repo": "nixpkgs.lib",
"rev": "361d8a4f443bbfab20bd6d222f9022b8c6665906",
"rev": "6882347415e352cfc9c277cc01f73e0f5cb7b93c",
"type": "github"
},
"original": {
@ -467,11 +469,11 @@
]
},
"locked": {
"lastModified": 1713349019,
"narHash": "sha256-H8FjOiATw0/k2fq2VcCE7Vov5Ic+S1x0h4nDImM1cUQ=",
"lastModified": 1713719682,
"narHash": "sha256-d6YzWLGoHF3si3fHZ5qv587gR16Bgk7EQgrvgtCaoRM=",
"owner": "nix-community",
"repo": "nixpkgs-wayland",
"rev": "f8c128a08d5873682e8518af7c401512381cfd73",
"rev": "df1a94e03aaf5324dd2d9fe6d965422d26d1e6e1",
"type": "github"
},
"original": {
@ -530,11 +532,11 @@
},
"nixpkgs_5": {
"locked": {
"lastModified": 1713254108,
"narHash": "sha256-0TZIsfDbHG5zibtlw6x0yOp3jkInIGaJ35B7Y4G8Pec=",
"lastModified": 1713687659,
"narHash": "sha256-Yd8KuOBpZ0Slau/NxFhMPJI0gBxeax0vq/FD0rqKwuQ=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "2fd19c8be2551a61c1ddc3d9f86d748f4db94f00",
"rev": "f2d7a289c5a5ece8521dd082b81ac7e4a57c2c5c",
"type": "github"
},
"original": {
@ -605,6 +607,20 @@
}
},
"systems_2": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"id": "systems",
"type": "indirect"
}
},
"systems_3": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
@ -678,6 +694,27 @@
}
},
"treefmt-nix": {
"inputs": {
"nixpkgs": [
"nixos-dns",
"nixpkgs"
]
},
"locked": {
"lastModified": 1711963903,
"narHash": "sha256-N3QDhoaX+paWXHbEXZapqd1r95mdshxToGowtjtYkGI=",
"owner": "numtide",
"repo": "treefmt-nix",
"rev": "49dc4a92b02b8e68798abd99184f228243b6e3ac",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "treefmt-nix",
"type": "github"
}
},
"treefmt-nix_2": {
"inputs": {
"nixpkgs": [
"nixpkgs-wayland",

View file

@ -54,7 +54,7 @@
owner = "octodns";
repo = pname;
rev = "main";
sha256 = "sha256-KVdH55wkTk2n2t/Y+n9+/5SCk3ml8vXIlFbtmOL4DlA=";
sha256 = "sha256-cBdR6LCIivR4L9PePy5ZOOhV/JdanlujWgueCQma9fo=";
};
doCheck = false;
propagatedBuildInputs = with pkgs.python3Packages; [
@ -163,26 +163,26 @@
libraries = [
pkgs.python3Packages.requests
];
flakeIgnore = [ "E501" ];
flakeIgnore = ["E501"];
}
''
import json
import requests
import os
import json
import requests
import os
auth = os.getenv("NEXTDNS_API_KEY")
g
with open('${self.packages.x86_64-linux.nextdns-rewrites}', 'r') as file:
rewrites = json.load(file)
auth = os.getenv("NEXTDNS_API_KEY")
for profile in rewrites:
for rewrite in rewrites[profile]:
print(json.dumps(rewrite))
req = requests.post(
f'https://api.nextdns.io/profiles/{profile}/rewrites', data=json.dumps(rewrite),
headers={'X-Api-Key': auth, 'Content-Type': 'application/json'}
)
print(req.text)
with open('${self.packages.x86_64-linux.nextdns-rewrites}', 'r') as file:
rewrites = json.load(file)
for profile in rewrites:
for rewrite in rewrites[profile]:
print(json.dumps(rewrite))
req = requests.post(
f'https://api.nextdns.io/profiles/{profile}/rewrites', data=json.dumps(rewrite),
headers={'X-Api-Key': auth, 'Content-Type': 'application/json'}
)
print(req.text)
'');
};
@ -402,6 +402,38 @@ g
}
];
};
dnsmasq = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
agenix.nixosModules.default
(import ./nix/dnsmasq/configuration.nix)
{
_module.args.nixinate = {
host = "192.168.50.87";
sshUser = "root";
buildOn = "remote";
substituteOnTarget = true;
hermetic = false;
};
}
];
};
dnsmasq-floof = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
agenix.nixosModules.default
(import ./nix/dnsmasq-floof/configuration.nix)
{
_module.args.nixinate = {
host = "10.230.101.104";
sshUser = "root";
buildOn = "remote";
substituteOnTarget = true;
hermetic = false;
};
}
];
};
};
};
}

View file

@ -1,12 +0,0 @@
# http://editorconfig.org
root = true
[*]
indent_style = tab
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.yml]
indent_style = space

172
friends/.gitignore vendored
View file

@ -1,172 +0,0 @@
# Logs
logs
_.log
npm-debug.log_
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
.pnpm-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json
# Runtime data
pids
_.pid
_.seed
\*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
\*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# Snowpack dependency directory (https://snowpack.dev/)
web_modules/
# TypeScript cache
\*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional stylelint cache
.stylelintcache
# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
\*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variable files
.env
.env.development.local
.env.test.local
.env.production.local
.env.local
# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache
# Next.js build output
.next
out
# Nuxt.js build / generate output
.nuxt
dist
# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public
# vuepress build output
.vuepress/dist
# vuepress v2.x temp and cache directory
.temp
.cache
# Docusaurus cache and generated files
.docusaurus
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# TernJS port file
.tern-port
# Stores VSCode versions used for testing VSCode extensions
.vscode-test
# yarn v2
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.\*
# wrangler project
.dev.vars
.wrangler/

View file

@ -1,6 +0,0 @@
{
"printWidth": 140,
"singleQuote": true,
"semi": true,
"useTabs": true
}

2930
friends/package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -1,16 +0,0 @@
{
"name": "friends",
"version": "0.0.0",
"private": true,
"scripts": {
"deploy": "wrangler deploy",
"dev": "wrangler dev",
"start": "wrangler dev",
"test": "vitest"
},
"devDependencies": {
"wrangler": "^3.0.0",
"vitest": "1.3.0",
"@cloudflare/vitest-pool-workers": "^0.1.0"
}
}

View file

@ -1,20 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="description" content="I'm a silly dog">
<title>friends of the arch.dog</title>
<link rel="stylesheet" href="/styles.css">
</head>
<body>
<main><div id="error"></div>
<header>
<img src="/avatar.png" alt="A cute golden retriever with a stylish blue hairstyle and glasses">
<h1>Friends of Arch</h1>
</header>
<p>A collection of wonderful beans across the internet.</p>
<div id="friends"></div>
</main>
</body>
</html>

View file

@ -1,54 +0,0 @@
import friendsPage from "./index.html";
export default {
async fetch(request, env, ctx) {
const renderFriends = async (error) => {
const friends = await env.FRIENDS.list();
const friendList = await Promise.all(friends.keys.map(async f => {
if (f.metadata && f.metadata.noImage) {
const value = await env.FRIENDS.get(f.name);
return `<a href="https://${f.name}"><p>${value}</p></a>`
}
return `<a href="https://${f.name}"><img src="./${f.name}" alt="${f.name}"></a>`
}));
return new HTMLRewriter()
.on("#friends", {
element(element) {
element.setInnerContent(friendList.join("\n"), { html: true });
},
})
.on("#error", {
element(element) {
if (error) {
element.setInnerContent(error);
} else {
element.remove();
}
},
})
.transform(
new Response(friendsPage, { headers: { "Content-Type": "text/html" } }),
);
};
const url = new URL(request.url);
const { pathname } = url;
const friend = pathname.replace("/friends", "", 1);
switch (friend) {
case "":
return Response.redirect("https://arch.dog/friends/", 301);
case "/":
return await renderFriends()
default:
const { value, metadata } = await env.FRIENDS.getWithMetadata(friend.replace("/", "", 1), { type: "stream" });
if (value === null) {
return new Response("not found", {status: 404});
}
return new Response(value, {});
}
},
};

View file

@ -1,20 +0,0 @@
import { env, createExecutionContext, waitOnExecutionContext, SELF } from "cloudflare:test";
import { describe, it, expect } from "vitest";
import worker from "../src";
describe("Hello World worker", () => {
it("responds with Hello World! (unit style)", async () => {
const request = new Request("http://example.com");
// Create an empty context to pass to `worker.fetch()`.
const ctx = createExecutionContext();
const response = await worker.fetch(request, env, ctx);
// Wait for all `Promise`s passed to `ctx.waitUntil()` to settle before running test assertions
await waitOnExecutionContext(ctx);
expect(await response.text()).toMatchInlineSnapshot(`"Hello World!"`);
});
it("responds with Hello World! (integration style)", async () => {
const response = await SELF.fetch("http://example.com");
expect(await response.text()).toMatchInlineSnapshot(`"Hello World!"`);
});
});

View file

@ -1,11 +0,0 @@
import { defineWorkersConfig } from "@cloudflare/vitest-pool-workers/config";
export default defineWorkersConfig({
test: {
poolOptions: {
workers: {
wrangler: { configPath: "./wrangler.toml" },
},
},
},
});

View file

@ -1,20 +0,0 @@
#:schema node_modules/wrangler/config-schema.json
name = "friends"
main = "src/index.js"
compatibility_date = "2024-04-05"
compatibility_flags = ["nodejs_compat"]
workers_dev = false
[limits]
cpu_ms = 10
kv_namespaces = [
{ binding = "FRIENDS", id = "4c7b1469a4cb4050b0c8b8b41a7396aa", preview_id = "4c7b1469a4cb4050b0c8b8b41a7396aa" }
]
routes = [
{ pattern = "arch.dog/friends", zone_name = "arch.dog" },
{ pattern = "arch.dog/friends/*", zone_name = "arch.dog" }
]

View file

@ -1,51 +1,49 @@
image:
tag: 2024.2.1
authentik:
error_reporting:
enabled: false
env:
AUTHENTIK_WEB__THREADS: "2"
envValueFrom:
AUTHENTIK_SECRET_KEY:
secretKeyRef:
name: authentik-secrets
key: secret-key
AUTHENTIK_POSTGRESQL__HOST:
secretKeyRef:
name: hippo-pguser-authentik
key: host
AUTHENTIK_POSTGRESQL__PASSWORD:
secretKeyRef:
name: hippo-pguser-authentik
key: password
AUTHENTIK_POSTGRESQL__USER:
secretKeyRef:
name: hippo-pguser-authentik
key: user
AUTHENTIK_POSTGRESQL__PORT:
secretKeyRef:
name: hippo-pguser-authentik
key: port
global:
image:
tag: 2024.2.3
env:
- name: AUTHENTIK_WEB__THREADS
value: "2"
- name: AUTHENTIK_SECRET_KEY
valueFrom:
secretKeyRef:
name: authentik-secrets
key: secret-key
- name: AUTHENTIK_POSTGRESQL__HOST
valueFrom:
secretKeyRef:
name: hippo-pguser-authentik
key: host
- name: AUTHENTIK_POSTGRESQL__PASSWORD
valueFrom:
secretKeyRef:
name: hippo-pguser-authentik
key: password
- name: AUTHENTIK_POSTGRESQL__USER
valueFrom:
secretKeyRef:
name: hippo-pguser-authentik
key: user
- name: AUTHENTIK_POSTGRESQL__PORT
valueFrom:
secretKeyRef:
name: hippo-pguser-authentik
key: port
prometheus:
serviceMonitor:
create: true
ingress:
server:
metrics:
enabled: true
ingress:
# Specify kubernetes ingress controller class name
ingressClassName: nginx
enabled: true
hosts:
# Specify external host name
- host: authentik.gmem.ca
paths:
- path: "/"
pathType: Prefix
# Specify external host name
- host: prometheus.gmem.ca
paths:
- path: "/"
pathType: Prefix
hosts: [ authentik.gmem.ca ]
tls:
- hosts:
- authentik.gmem.ca
secretName: gmem-ca-wildcard
redis:
enabled: true

View file

@ -130,6 +130,13 @@
};
};
}
{
"Paperless-ngx" = {
icon = "paperless-ngx.png";
href = "https://docs.gmem.ca";
description = "Document storage and indexing";
};
}
];
}
{

View file

@ -2,35 +2,35 @@ let
appName = "nitter-bot";
appImage = "git.gmem.ca/arch/nitter-bot:latest";
in
{
lib,
config,
kubenix,
...
}: {
kubernetes.resources.statefulSets.nitter-bot.spec = {
selector.matchLabels.app = appName;
serviceName = appName;
template = {
metadata.labels.app = appName;
spec = {
containers = {
nitter-bot = {
image = appImage;
envFrom = [{secretRef.name = "nitter-bot";}];
resources = {
requests = {
cpu = "1m";
memory = "32Mi";
};
limits = {
cpu = "1";
memory = "128Mi";
{
lib,
config,
kubenix,
...
}: {
kubernetes.resources.statefulSets.nitter-bot.spec = {
selector.matchLabels.app = appName;
serviceName = appName;
template = {
metadata.labels.app = appName;
spec = {
containers = {
nitter-bot = {
image = appImage;
envFrom = [{secretRef.name = "nitter-bot";}];
resources = {
requests = {
cpu = "1m";
memory = "32Mi";
};
limits = {
cpu = "1";
memory = "128Mi";
};
};
};
};
};
};
};
};
}
}

View file

@ -74,7 +74,7 @@
};
kubernetes.resources.cronJobs.piped-refresh.spec = {
schedule = "*/5 * * * *";
schedule = "*/10 * * * *";
jobTemplate.spec.template.spec = {
restartPolicy = "Never";
containers.refresh-subscriptions = {
@ -88,7 +88,8 @@
export PGPASSWORD=$password &&
export subs=$(psql -U piped -h hippo-primary.default.svc -qtAX -c 'select id from public.pubsub;') &&
while IFS= read -r line; do
curl -k "https://pipedapi.gmem.ca/channel/$line" > /dev/null
echo "refreshing $line"
curl -k -S -s -o /dev/null "https://pipedapi.gmem.ca/channel/$line"
done < <(printf '%s' "$subs")
''
];

View file

@ -4,53 +4,52 @@ let
"1002:ab30" # Audio
];
in
{
pkgs,
lib,
config,
...
}: {
options.vfio.enable = with lib;
mkEnableOption "Configure the machine for VFIO";
{
pkgs,
lib,
config,
...
}: {
options.vfio.enable = with lib;
mkEnableOption "Configure the machine for VFIO";
config = let
cfg = config.vfio;
in {
boot = {
kernelModules = [ "kvm-amd" "vfio_pci" "vfio" "vfio_iommu_type1" "kvmfr" ];
extraModulePackages = with config.boot.kernelPackages; [
kvmfr
];
extraModprobeConfig = ''
# The memory size is calculates in the same way as VM's shmem.
options kvmfr static_size_mb=64
'';
config = let
cfg = config.vfio;
in {
boot = {
kernelModules = ["kvm-amd" "vfio_pci" "vfio" "vfio_iommu_type1" "kvmfr"];
extraModulePackages = with config.boot.kernelPackages; [
kvmfr
];
extraModprobeConfig = ''
# The memory size is calculates in the same way as VM's shmem.
options kvmfr static_size_mb=64
'';
kernelParams =
[
kernelParams = [
"amd_iommu=on"
"pcie_acs_override=downstream,multifunction"
"vfio-pci.ids=1002:744c,1002:ab30"
"pcie_aspm=off"
"pcie_aspm=off"
];
};
services.udev.extraRules = ''
SUBSYSTEM=="kvmfr", OWNER="gsimmer", GROUP="kvm", MODE="0660"
'';
hardware.opengl.enable = true;
virtualisation.spiceUSBRedirection.enable = true;
virtualisation.libvirtd = {
qemu = {
verbatimConfig = ''
cgroup_device_acl = [
"/dev/null", "/dev/full", "/dev/zero",
"/dev/random", "/dev/urandom",
"/dev/ptmx", "/dev/kvm", "/dev/kqemu",
"/dev/rtc","/dev/hpet", "/dev/vfio/vfio",
"/dev/kvmfr0"
]
'';
};
services.udev.extraRules = ''
SUBSYSTEM=="kvmfr", OWNER="gsimmer", GROUP="kvm", MODE="0660"
'';
hardware.opengl.enable = true;
virtualisation.spiceUSBRedirection.enable = true;
virtualisation.libvirtd = {
qemu = {
verbatimConfig = ''
cgroup_device_acl = [
"/dev/null", "/dev/full", "/dev/zero",
"/dev/random", "/dev/urandom",
"/dev/ptmx", "/dev/kvm", "/dev/kqemu",
"/dev/rtc","/dev/hpet", "/dev/vfio/vfio",
"/dev/kvmfr0"
]
'';
};
};
};
};
}
}

View file

@ -0,0 +1,80 @@
# Edit this configuration file to define what should be installed on
# your system. Help is available in the configuration.nix(5) man page, on
# https://search.nixos.org/options and in the NixOS manual (`nixos-help`).
{
config,
lib,
pkgs,
...
}: {
imports = [
# Include the results of the hardware scan.
./hardware-configuration.nix
];
age.secrets.dnsmasq-nextdns-profile = {
file = ../../secrets/dnsmasq-nextdns-profile.age;
owner = "dnsmasq";
};
nix = {
settings = {
auto-optimise-store = true;
experimental-features = ["nix-command" "flakes"];
};
};
# Use the systemd-boot EFI boot loader.
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
networking = {
hostName = "dnsmasq-cache"; # Define your hostname.
firewall = {
enable = true;
allowedUDPPorts = [53];
allowedTCPPorts = [22 53 9153];
trustedInterfaces = ["enp6s18" "tailscale0"];
checkReversePath = "loose";
allowedUDPPortRanges = [
{
from = 3000;
to = 22000;
}
];
};
nftables.enable = true;
};
services = {
openssh.enable = true;
tailscale.enable = true;
dnsmasq = {
enable = true;
settings = {
interface = "tailscale0";
cache-size = "4000";
no-resolv = true;
bogus-priv = true;
strict-order = true;
server = ["2a07:a8c1::" "45.90.30.0" "2a07:a8c0::" "45.90.28.0"];
conf-file = "${config.age.secrets.dnsmasq-nextdns-profile.path}";
};
};
};
environment = {
systemPackages = with pkgs; [
tailscale
];
};
virtualisation.oci-containers.containers = {
dnsmasq_exporter = {
image = "git.gmem.ca/arch/dnsmasq_exporter";
extraOptions = ["--network=host"];
};
};
system.stateVersion = "23.11"; # Did you read the comment?
}

View file

@ -0,0 +1,32 @@
{
disko.devices = {
disk = {
my-disk = {
device = "/dev/sda";
type = "disk";
content = {
type = "gpt";
partitions = {
ESP = {
type = "EF00";
size = "500M";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
};
};
root = {
size = "100%";
content = {
type = "filesystem";
format = "ext4";
mountpoint = "/";
};
};
};
};
};
};
};
}

View file

@ -0,0 +1,33 @@
# Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{
config,
lib,
pkgs,
modulesPath,
...
}: {
imports = [
(modulesPath + "/profiles/qemu-guest.nix")
''${builtins.fetchTarball {
url = "https://github.com/nix-community/disko/archive/master.tar.gz";
sha256 = "0qyl65hs2j4f5ffj2lv5kb4hc1gradkqvv2j35hbdyiik155l4gn";
}}/module.nix''
./disk-config.nix
];
boot.initrd.availableKernelModules = ["uhci_hcd" "ehci_pci" "ahci" "virtio_pci" "virtio_scsi" "sd_mod" "sr_mod"];
boot.initrd.kernelModules = [];
boot.kernelModules = [];
boot.extraModulePackages = [];
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's
# still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true;
# networking.interfaces.enp6s18.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
}

View file

@ -0,0 +1,90 @@
# Edit this configuration file to define what should be installed on
# your system. Help is available in the configuration.nix(5) man page, on
# https://search.nixos.org/options and in the NixOS manual (`nixos-help`).
{
config,
lib,
pkgs,
...
}: {
imports = [
# Include the results of the hardware scan.
./hardware-configuration.nix
];
age.secrets.dnsmasq-nextdns-profile = {
file = ../../secrets/dnsmasq-nextdns-profile.age;
owner = "dnsmasq";
};
nix = {
settings = {
auto-optimise-store = true;
experimental-features = ["nix-command" "flakes"];
};
};
# Use the systemd-boot EFI boot loader.
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
networking = {
hostName = "dnsmasq-cache"; # Define your hostname.
useDHCP = false;
interfaces.enp6s18.ipv4.addresses = [
{
address = "192.168.50.87";
prefixLength = 24;
}
];
nameservers = ["1.1.1.1" "1.0.0.1"];
firewall = {
enable = true;
allowedUDPPorts = [53];
allowedTCPPorts = [22 53 9153];
trustedInterfaces = ["enp6s18" "tailscale0"];
checkReversePath = "loose";
allowedUDPPortRanges = [
{
from = 3000;
to = 22000;
}
];
};
defaultGateway = "192.168.50.1";
defaultGateway6 = "2a02:1648:6709::1";
nftables.enable = true;
};
services = {
openssh.enable = true;
tailscale.enable = true;
dnsmasq = {
enable = true;
settings = {
interface = "tailscale0";
cache-size = "4000";
no-resolv = true;
bogus-priv = true;
strict-order = true;
server = ["2a07:a8c1::" "45.90.30.0" "2a07:a8c0::" "45.90.28.0"];
conf-file = "${config.age.secrets.dnsmasq-nextdns-profile.path}";
};
};
};
environment = {
systemPackages = with pkgs; [
tailscale
];
};
virtualisation.oci-containers.containers = {
dnsmasq_exporter = {
image = "git.gmem.ca/arch/dnsmasq_exporter";
extraOptions = ["--network=host"];
};
};
system.stateVersion = "23.11"; # Did you read the comment?
}

View file

@ -0,0 +1,32 @@
{
disko.devices = {
disk = {
my-disk = {
device = "/dev/sda";
type = "disk";
content = {
type = "gpt";
partitions = {
ESP = {
type = "EF00";
size = "500M";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
};
};
root = {
size = "100%";
content = {
type = "filesystem";
format = "ext4";
mountpoint = "/";
};
};
};
};
};
};
};
}

View file

@ -0,0 +1,33 @@
# Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{
config,
lib,
pkgs,
modulesPath,
...
}: {
imports = [
(modulesPath + "/profiles/qemu-guest.nix")
''${builtins.fetchTarball {
url = "https://github.com/nix-community/disko/archive/master.tar.gz";
sha256 = "0qyl65hs2j4f5ffj2lv5kb4hc1gradkqvv2j35hbdyiik155l4gn";
}}/module.nix''
./disk-config.nix
];
boot.initrd.availableKernelModules = ["uhci_hcd" "ehci_pci" "ahci" "virtio_pci" "virtio_scsi" "sd_mod" "sr_mod"];
boot.initrd.kernelModules = [];
boot.kernelModules = [];
boot.extraModulePackages = [];
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's
# still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true;
# networking.interfaces.enp6s18.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
}

View file

@ -22,7 +22,7 @@
config.boot.kernelPackages.v4l2loopback
];
kernelPackages = pkgs.linuxPackages_latest;
kernelModules = [ "coretemp" "kvm-amd" "v4l2loopback"];
kernelModules = ["coretemp" "kvm-amd" "v4l2loopback"];
plymouth = {
enable = true;
theme = "breeze";
@ -56,7 +56,7 @@
interfaces.br0.useDHCP = true;
bridges = {
"br0" = {
interfaces = [ "enp14s0" ];
interfaces = ["enp14s0"];
};
};
firewall = {

View file

@ -22,7 +22,7 @@
in [
(import (builtins.fetchTarball {
url = "https://github.com/nix-community/emacs-overlay/archive/master.tar.gz";
sha256 = "11x80s4jh06ibk390q8wgvvi614fapiswmbi6z9xy9d21pf7mw33";
sha256 = "1xa3vqw4kbrpqh6qkkkhrglgj6armrpdgc057kbsfcbaan5xc2pm";
}))
discordOverlay
];
@ -135,6 +135,7 @@
comma
transmission_4-qt
ungoogled-chromium
looking-glass-client
];
# This value determines the Home Manager release that your

View file

@ -104,7 +104,6 @@
max_chunk_age = "1h";
chunk_target_size = 999999;
chunk_retain_period = "30s";
max_transfer_retries = 0;
};
schema_config = {
@ -127,7 +126,6 @@
active_index_directory = "/var/lib/loki/boltdb-shipper-active";
cache_location = "/var/lib/loki/boltdb-shipper-cache";
cache_ttl = "24h";
shared_store = "filesystem";
};
filesystem = {
@ -140,10 +138,6 @@
reject_old_samples_max_age = "168h";
};
chunk_store_config = {
max_look_back_period = "0s";
};
table_manager = {
retention_deletes_enabled = false;
retention_period = "0s";
@ -151,7 +145,6 @@
compactor = {
working_directory = "/var/lib/loki";
shared_store = "filesystem";
compactor_ring = {
kvstore = {
store = "inmemory";
@ -329,10 +322,6 @@
job_name = "forgejo";
static_configs = [{targets = ["git.gmem.ca"];}];
}
{
job_name = "coredns";
static_configs = [{targets = ["vancouver:9253"];}];
}
{
job_name = "healthchecks";
scrape_interval = "60s";
@ -344,6 +333,11 @@
scrape_interval = "60s";
static_configs = [{targets = ["vancouver:6534"];}];
}
{
job_name = "dnsmasq";
scrape_interval = "10s";
static_configs = [{targets = ["100.102.19.124:9153" "100.92.113.87:9153"];}];
}
{
job_name = "blackbox_home";
metrics_path = "/probe";

View file

@ -330,10 +330,12 @@
};
};
};
gitea = {
forgejo = {
enable = true;
stateDir = "/tank/forgejo";
package = pkgs.forgejo;
user = "git";
group = "git";
settings = {
DEFAULT = {
APP_NAME = "Arch's Git Forge";
@ -376,6 +378,7 @@
enable = true;
labels = [
"debian-latest:docker://node:18-bullseye"
"ubuntu-latest:docker://node:18-bullseye"
"docker:docker://gitea/act_runner:nightly-dind-rootless"
"nix:docker://nixos/nix"
];
@ -471,13 +474,36 @@
};
environment.shells = with pkgs; [zsh fish];
users.users = {
gsimmer = {
shell = pkgs.fish;
isNormalUser = true;
home = "/tank/gsimmer";
extraGroups = ["wheel" "libvirtd" "qemu-libvirtd"];
openssh.authorizedKeys.keys = let
users = {
groups.git = {};
users = {
git = {
home = "/tank/forgejo";
useDefaultShell = true;
group = "git";
isSystemUser = true;
};
gsimmer = {
shell = pkgs.fish;
isNormalUser = true;
home = "/tank/gsimmer";
extraGroups = ["wheel" "libvirtd" "qemu-libvirtd"];
openssh.authorizedKeys.keys = let
authorizedKeys = pkgs.fetchurl {
url = "https://gmem.ca/ssh";
hash = "sha256-7PpFDgWVfp26c9PuW+2s3O8MBAODtHr4q7WU/l3BoG4=";
};
in
pkgs.lib.splitString "\n" (builtins.readFile
authorizedKeys);
};
becki = {
shell = pkgs.fish;
isNormalUser = true;
home = "/tank/becki";
};
root.openssh.authorizedKeys.keys = let
authorizedKeys = pkgs.fetchurl {
url = "https://gmem.ca/ssh";
hash = "sha256-7PpFDgWVfp26c9PuW+2s3O8MBAODtHr4q7WU/l3BoG4=";
@ -486,19 +512,6 @@
pkgs.lib.splitString "\n" (builtins.readFile
authorizedKeys);
};
becki = {
shell = pkgs.fish;
isNormalUser = true;
home = "/tank/becki";
};
root.openssh.authorizedKeys.keys = let
authorizedKeys = pkgs.fetchurl {
url = "https://gmem.ca/ssh";
hash = "sha256-7PpFDgWVfp26c9PuW+2s3O8MBAODtHr4q7WU/l3BoG4=";
};
in
pkgs.lib.splitString "\n" (builtins.readFile
authorizedKeys);
};
home-manager.users.gsimmer = {pkgs, ...}: {

View file

@ -3,6 +3,11 @@ let
monitoring = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEDtzsbxKgZ/NBYlYO2EJQZhBy3nVBVERWebbsP9mLcy";
machines = [vancouver monitoring];
dnsmasq-cache = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKpZvxrLo8kbbCVODAES8xfPbzHN6fx3cRfhYC+me0R9";
dnsmasq-cache-floof = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAghUyhsM/pRXmKf6NjQGULxshwXP0l93yzFvqEdM9dC";
dnsmasq = [dnsmasq-cache dnsmasq-cache-floof];
proxmox-k3s-node = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB1KEjdFl0UmuKfESJTMZdKR2H9a405z0SSlt75NKKht";
seattle = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIF9pTEqeVljLq0ctFgDn25Q76mCqpddkSNN9kd3IQXd1";
glasgow = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMgZSpfnx/4kfE4P1tFpq047IZkF2Q0UYahputnWxtEJ";
@ -24,4 +29,6 @@ in {
"secrets/cloudflare-dns.age".publicKeys = machines ++ users;
"secrets/monitoring-grafana-client-secret.age".publicKeys = [monitoring gsimmer];
"secrets/k3s-token.age".publicKeys = k3s ++ users;
"secrets/dnsmasq-nextdns-profile.age".publicKeys = dnsmasq ++ users;
}

View file

@ -0,0 +1,9 @@
age-encryption.org/v1
-> ssh-ed25519 o0sdgw 9I44ptc/Dwhk2EcjCtJhl3kSu69BXMRCPHZAdt9kJgE
t8gc+3qVIkEuyNSWE3S3vEhV+q7uSMe/qIJccV6ln54
-> ssh-ed25519 C7Rp1Q G0PsVpG+bRptzUhAxYNkerKqhYRgnYatX2S4vEj0F2M
sivnnSL3QRKXPubK6Bk1ASdriuOx7uwoA89iWjsazi8
-> ssh-ed25519 qbziOw sZzOsi5z1YTAHY809dsew0rLRuSxLQLLbwF+zTXHLjo
j0uANQ6MrUdwCI+Qf9dimMnZheP2zUNsGzHGgrD4oO4
--- QJmFdG6wwF307+25uBp0E9aSGjH0eAmNEYI/RfZ5c7k
¦ÆÔ§ƾw5ÞôÚ7…ÿÐTÚ¼!É>ƒýÔZö½p]Ÿ<àÇO‰ï¿<C3AF>íÎÎX

View file

@ -1,10 +1,7 @@
age-encryption.org/v1
-> ssh-ed25519 oN6OTQ 290Jjq3X3EKWAJjbrxxNdLVYq7OOdTZAQBLnb0JlzEw
Ci/Ngx0O5JbCbxNqkUdSz1zuHs2YMvi+st/Nf+BlhXk
-> ssh-ed25519 qbziOw pexX+lrzjrIvjD1BXDOwZ6jvHNwHvI8NN7t0g+WAHE4
8TlaRQnd/H/1nML+bJOL9J6rG1FOSFY7qTTiu11gqRo
-> Q5TArB-grease
bYTE3nqG4aLFTuXCpjRNM7rnVFlL7BCJ2BlqJbMn0CImH3owoMnYwpBBEO2i5/O7
XdBin6lrZDYiFZMLzQ4DRd8B
--- GfQW76dgud6sOfFfB1VoRiiZZqDePubrWRTbvKcx3Z0
“n-‡ŽA3]Éró]YHp'`º2óH^Î%Ï}= Nzútoöä:³5õ³ˆªéùê—R <52>§¾áýL瞶6‹©ÀÐÝ24¼ª"WË
-> ssh-ed25519 oN6OTQ e6ldvoLxjS1vUBY2glP9UbAvOoDkgTF/Hsjy22C4E3E
qjdy/Zh7+0wSIJjNuov0/KQaiWJzVfzSLKzIYhK3tKE
-> ssh-ed25519 qbziOw 8daUrL9RuNfduBTXesLd1ndSFSRJwKj3+fqAWJlRrG8
kazcLzdfpBIVhyFJuDMEtCr1EXRDa0wNkGMxrGPXcFw
--- PW+ZaxdW9FYv129kt44jeeiY3GwrLkH5szOsr/ziJEQ
Û2ÄÐ)þ*“…Œmã<£>=²^¶ñTžc•¿¯Q—%ø 7wF†<»+{&[Ø!0&Gùù+„ùô¶·œSЇýÍà˜ÉÎl~{