commit 373ada0f2b0a78125c5f9c8f0579e59c15c7bcec
parent 81e9ea1ac6189d4b8a5cf990fcba4074fc23c54f
Author: Leah (ctucx) <git@ctu.cx>
Date: Sat, 13 May 2023 17:17:00 +0200
parent 81e9ea1ac6189d4b8a5cf990fcba4074fc23c54f
Author: Leah (ctucx) <git@ctu.cx>
Date: Sat, 13 May 2023 17:17:00 +0200
cleanup
10 files changed, 319 insertions(+), 1793 deletions(-)
A
|
272
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
D
|
1004
-------------------------------------------------------------------------------
D
|
97
-------------------------------------------------------------------------------
D
|
250
-------------------------------------------------------------------------------
D
|
359
-------------------------------------------------------------------------------
M
|
82
++++++++++++++++++++++++++++++++++++++-----------------------------------------
diff --git a/machines/trabbi/configuration.nix b/machines/trabbi/configuration.nix @@ -9,7 +9,7 @@ ../../configurations/linux/services/dns.nix # git server (gitolite+stagit) - ./git + ./git.nix # monitoring ../../configurations/linux/services/prometheus-exporters.nix
diff --git a/machines/trabbi/git.nix b/machines/trabbi/git.nix @@ -0,0 +1,272 @@ +{ config, lib, pkgs, ... }: + +let + rebuildScript = pkgs.writeShellScript "init-stagit" '' + systemctl start init-stagit; + systemctl status init-stagit; + ''; + + stagitFunctions = '' + export LC_CTYPE="en_US.UTF-8" + + is_public_and_listed() { + if [ ! -f "$1/git-daemon-export-ok" ]; then + return 1 + fi + return 0 + } + + make_stagit_index() { + printf "Generating stagit index... " + + # set assets if not already there + ln -sf "${pkgs.stagit}/share/doc/stagit/style.css" "/var/lib/stagit/style.css" 2> /dev/null + + # generate index arguments + args="-n 'ctucx.git' -e 'git@ctu.cx'" + + for category in "nix" "etc" "nimlang" "nimlang libraries" "archive"; do + args="$args -c '$category'" + for repo in "$HOME/repositories/"*.git/; do + repo="''${repo%/}" + is_public_and_listed "$repo" || continue + + [ "$(${pkgs.gawk}/bin/awk -F '=' '/category/ {print $2}' $repo/config | ${pkgs.gnused}/bin/sed -e 's/^[[:space:]]*//')" = "$category" ] && args="$args $repo" + done + done + + # make index + echo "$args" | xargs ${pkgs.stagit}/bin/stagit-index > /var/lib/stagit/index.html + + # set correct permissions + chmod 755 /var/lib/stagit/index.html; + chown git:git /var/lib/stagit/index.html; + + echo "done" + } + ''; + +in { + + dns.zones."ctu.cx".subdomains = { + cgit.CNAME = [ "${config.networking.fqdn}." ]; + git.CNAME = [ "${config.networking.fqdn}." ]; + }; + + age.secrets.restic-gitolite.file = ./. + "/../../secrets/${config.networking.hostName}/restic/gitolite.age"; + + restic-backups.gitolite = { + user = "git"; + passwordFile = config.age.secrets.restic-gitolite.path; + paths = [ "/var/lib/gitolite" ]; + }; + + security.sudo.extraRules = [{ + users = [ "git" ]; + commands = [ + { command = "${rebuildScript}"; options = [ "SETENV" "NOPASSWD" ]; } + ]; + }]; + + services = { + }; + + systemd.services.init-stagit = { + script = '' + ${stagitFunctions} + + make_repo_web() { + reponame="$(basename "$1" ".git")" + printf "[%s] stagit HTML pages... " "$reponame" + + mkdir -p "/var/lib/stagit/$reponame" + cd "/var/lib/stagit/$reponame" || return 1 + + # make pages + ${pkgs.stagit}/bin/stagit -c '.stagit-build-cache' -n 'ctucx.git' -h 'https://git.ctu.cx/' -s 'git@${config.networking.hostName}.ctu.cx:' "$1" + + echo "done" + } + + # clean webdir + rm -rf /var/lib/stagit/* + + # make files per repo + for repo in "$HOME/repositories/"*.git/; do + repo="''${repo%/}" + is_public_and_listed "$repo" || continue + + make_repo_web "$repo" + done + + make_stagit_index + ''; + + serviceConfig = { + Type = "oneshot"; + + User = "git"; + Group = "git"; + + WorkingDirectory = "~"; + StateDirectory = "stagit"; + StateDirectoryMode = "755"; + + NoNewPrivileges = true; + PrivateTmp = true; + PrivateDevices = true; + + RestrictAddressFamilies = "AF_INET AF_INET6"; + RestrictNamespaces = true; + RestrictRealtime = true; + + ProtectSystem = "full"; + ProtectControlGroups = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + + DevicePolicy = "closed"; + LockPersonality = true; + }; + }; + + services = { + gitolite = { + enable = true; + user = "git"; + group = "git"; + adminPubkey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDb2eZ2ymt+Zsf0eTlmjW2jPdS013lbde1+EGkgu6bz9lVTR8aawshF2HcoaWp5a5dJr3SKyihDM8hbWSYB3qyTHihNGyCArqSvAtZRw301ailRVHGqiwUITTfcg1533TtmWvlJZgOIFM1VvSAfdueDRRRzbygmn749fS9nhUTDzLtjqX5LvhpqhzsD+eOqPrV6Ne8E1e42JxQb5AJPY1gj9mk6eAarvtEHQYEe+/hp9ERjtCdN5DfuOJnqfaKS0ytPj/NbQskbX/TMgeUVio11iC2NbXsnAtzMmtbLX4mxlDQrR6aZmU/rHQ4aeJqI/Tj2rrF46icri7s0tnnit1OjT5PSxXgifcOtn06qoxYZMT1x+Dyrt40vNkGmxmxCnirm8B+6MKXgd/Ys+7tnOm1ht8TmLm96x6KdOiF3Zq/tMxhPAzp8JriTKSo7k7U9XxStFghTbhhBNc7OX89ZbpalLEnvbQiz87gZxhcx8cLvzIjslOHmZOSWC5Pgr4wwuj3Akq63i4ya6/BzM6v4UoBuDAB6fz3NHKL4R5X20la7Pvt7OBysQkGClWfj6ipMR1bFE2mfYtlMioXNgTjC+NCpEl1+81MH7dv2565Hk8CLV8FMxv6GujbAZGjjcM47lpWM1cBQvpBMUA/lLkyiCPK0YxNWAB7Co+jYDl6CR0Ubew== cardno:6445161"; + extraGitoliteRc = '' + $RC{UMASK} = 0027; + $RC{GIT_CONFIG_KEYS} = ".*"; + push( @{$RC{ENABLE}}, 'cgit' ); + ''; + hooks.postReceive = '' + ${stagitFunctions} + + is_forced_update() { + test "$oldrev" = "0000000000000000000000000000000000000000" && return 1 + test "$newrev" = "0000000000000000000000000000000000000000" && return 1 + + hasrevs="$(${pkgs.git}/bin/git rev-list "$oldrev" "^$newrev" | ${pkgs.gnused}/bin/sed 1q)" + if test -n "$hasrevs"; then + return 0 + fi + return 1 + } + + make_repo_web() { + reponame="$(basename "$1" ".git")" + printf "[%s] stagit HTML pages... " "$reponame" + + # if forced update, remove directory and cache file + is_forced_update && printf "forced update... " && rm -rf "/var/lib/stagit/$reponame" + + mkdir -p "/var/lib/stagit/$reponame" + cd "/var/lib/stagit/$reponame" || return 1 + + # make pages + ${pkgs.stagit}/bin/stagit -c '.stagit-build-cache' -n 'ctucx.git' -h 'https://git.ctu.cx/' -s 'git@${config.networking.hostName}.ctu.cx:' "$1" + + # set correct permissions + chmod 755 -R /var/lib/stagit/$reponame; + chown git:git -R /var/lib/stagit/$reponame; + + echo "done" + } + + update_stagit_repo() { + repo="$(pwd)" + + cd "$repo" || return 1 + is_public_and_listed "$repo" || return 0 + + make_repo_web "$repo" + make_stagit_index + } + + update_stagit_repo "$1" + + #rebuild stagit + [ "$GL_REPO" == "gitolite-admin" ] && sudo ${rebuildScript} + ''; + + }; + + fcgiwrap = { + enable = true; + user = "git"; + group = "git"; + }; + + nginx = { + enable = true; + virtualHosts = { + "cgit.ctu.cx" = { + enableACME = true; + forceSSL = true; + kTLS = true; + locations = { + "~ '^/[a-zA-Z0-9._-]+/(git-(receive|upload)-pack|HEAD|info/refs|objects/(info/(http-)?alternates|packs)|[0-9a-f]{2}/[0-9a-f]{38}|pack/pack-[0-9a-f]{40}\.(pack|idx))$'".return = "307 https://git.ctu.cx$request_uri"; + "~ '^/([a-zA-Z0-9_.]+)/*$'".return = "307 https://git.ctu.cx/$1"; + "~ '^/([a-zA-Z0-9_.]+)/tree/([a-zA-Z0-9_./-]+[a-zA-Z0-9_-])/*$'".return = "307 https://git.ctu.cx/$1/tree/$2.html"; + "~ '^/([a-zA-Z0-9_.]+)/tree/*$'".return = "307 https://git.ctu.cx/$1/tree.html"; + "~ '^/([a-zA-Z0-9_.]+)/log/*$'".return = "307 https://git.ctu.cx/$1/log.html"; + "~ '^/([a-zA-Z0-9_.]+)/commit/*$'".extraConfig = '' + if ($arg_id) { + return 307 https://git.ctu.cx/$1/commit/$arg_id.html; + } + + return 307 https://git.ctu.cx/$1/log.html; + ''; + }; + }; + + "git.ctu.cx" = { + enableACME = true; + forceSSL = true; + kTLS = true; + root = "/var/lib/stagit"; + locations = { + "~ '^/[a-zA-Z0-9._-]+/raw'".extraConfig = '' + types { + application/json json; + + application/wasm wasm; + font/woff woff; + font/woff2 woff2; + + application/pdf pdf; + + image/gif gif; + image/jpeg jpeg jpg; + image/png png; + image/svg+xml svg svgz; + image/webp webp; + image/x-icon ico; + } + + default_type text/plain; + try_files $uri =404; + ''; + + "~ '^/[a-zA-Z0-9._-]+/(git-(receive|upload)-pack|HEAD|info/refs|objects/(info/(http-)?alternates|packs)|[0-9a-f]{2}/[0-9a-f]{38}|pack/pack-[0-9a-f]{40}\.(pack|idx))$'".extraConfig = '' + if ($query_string = service=git-receive-pack) { + return 403; + } + + include "${pkgs.nginx}/conf/fastcgi_params"; + fastcgi_param SCRIPT_FILENAME "${pkgs.git}/libexec/git-core/git-http-backend"; + fastcgi_param GIT_PROJECT_ROOT /var/lib/gitolite/repositories; + fastcgi_param PATH_INFO $uri; + fastcgi_pass unix:${config.services.fcgiwrap.socketAddress}; + ''; + }; + }; + + }; + }; + + }; + +}
diff --git a/machines/trabbi/git/cgit-assets/cgit.css b/machines/trabbi/git/cgit-assets/cgit.css @@ -1,1004 +0,0 @@ -/* - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License v2 as published - * by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * See <https://www.gnu.org/licenses/>. - */ - -div#cgit { - padding: 0em; - margin: 0em; - font-family: sans-serif; - font-size: 10pt; - color: #333; - background: white; - padding: 4px; -} - -div#cgit a { - color: blue; - text-decoration: none; -} - -div#cgit a:hover { - text-decoration: underline; -} - -div#cgit table { - border-collapse: collapse; -} - -div#cgit table#header { - width: 100%; - margin-bottom: 1em; -} - -div#cgit table#header td.logo { - width: 96px; - vertical-align: top; -} - -div#cgit table#header td.main { - font-size: 250%; - padding-left: 10px; - white-space: nowrap; -} - -div#cgit table#header td.main a { - color: #000; -} - -div#cgit table#header td.form { - text-align: right; - vertical-align: bottom; - padding-right: 1em; - padding-bottom: 2px; - white-space: nowrap; -} - -div#cgit table#header td.form form, -div#cgit table#header td.form input, -div#cgit table#header td.form select { - font-size: 90%; -} - -div#cgit table#header td.sub { - color: #777; - border-top: solid 1px #ccc; - padding-left: 10px; -} - -div#cgit table.tabs { - border-bottom: solid 3px #ccc; - border-collapse: collapse; - margin-top: 2em; - margin-bottom: 0px; - width: 100%; -} - -div#cgit table.tabs td { - padding: 0px 1em; - vertical-align: bottom; -} - -div#cgit table.tabs td a { - padding: 2px 0.75em; - color: #777; - font-size: 110%; -} - -div#cgit table.tabs td a.active { - color: #000; - background-color: #ccc; -} - -div#cgit table.tabs a[href^="http://"]:after, div#cgit table.tabs a[href^="https://"]:after { - content: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAQAAAAnOwc2AAAAAmJLR0QA/4ePzL8AAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfgAhcJDQY+gm2TAAAAHWlUWHRDb21tZW50AAAAAABDcmVhdGVkIHdpdGggR0lNUGQuZQcAAABbSURBVAhbY2BABs4MU4CwhYHBh2Erww4wrGFQZHjI8B8IgUIscJWyDHcggltQhI4zGDCcRwhChPggHIggP1QoAVmQkSETrGoHsiAEsACtBYN0oDAMbgU6EBcAAL2eHUt4XUU4AAAAAElFTkSuQmCC); - opacity: 0.5; - margin: 0 0 0 5px; -} - -div#cgit table.tabs td.form { - text-align: right; -} - -div#cgit table.tabs td.form form { - padding-bottom: 2px; - font-size: 90%; - white-space: nowrap; -} - -div#cgit table.tabs td.form input, -div#cgit table.tabs td.form select { - font-size: 90%; -} - -div#cgit div.path { - margin: 0px; - padding: 5px 2em 2px 2em; - color: #000; - background-color: #eee; -} - -div#cgit div.content { - margin: 0px; - padding: 2em; - border-bottom: solid 3px #ccc; -} - - -div#cgit table.list { - width: 100%; - border: none; - border-collapse: collapse; -} - -div#cgit table.list tr { - background: white; -} - -div#cgit table.list tr.logheader { - background: #eee; -} - -div#cgit table.list tr:nth-child(even) { - background: #f7f7f7; -} - -div#cgit table.list tr:nth-child(odd) { - background: white; -} - -div#cgit table.list tr:hover { - background: #eee; -} - -div#cgit table.list tr.nohover { - background: white; -} - -div#cgit table.list tr.nohover:hover { - background: white; -} - -div#cgit table.list tr.nohover-highlight:hover:nth-child(even) { - background: #f7f7f7; -} - -div#cgit table.list tr.nohover-highlight:hover:nth-child(odd) { - background: white; -} - -div#cgit table.list th { - font-weight: bold; - /* color: #888; - border-top: dashed 1px #888; - border-bottom: dashed 1px #888; - */ - padding: 0.1em 0.5em 0.05em 0.5em; - vertical-align: baseline; -} - -div#cgit table.list td { - border: none; - padding: 0.1em 0.5em 0.1em 0.5em; -} - -div#cgit table.list td.commitgraph { - font-family: monospace; - white-space: pre; -} - -div#cgit table.list td.commitgraph .column1 { - color: #a00; -} - -div#cgit table.list td.commitgraph .column2 { - color: #0a0; -} - -div#cgit table.list td.commitgraph .column3 { - color: #aa0; -} - -div#cgit table.list td.commitgraph .column4 { - color: #00a; -} - -div#cgit table.list td.commitgraph .column5 { - color: #a0a; -} - -div#cgit table.list td.commitgraph .column6 { - color: #0aa; -} - -div#cgit table.list td.logsubject { - font-family: monospace; - font-weight: bold; -} - -div#cgit table.list td.logmsg { - font-family: monospace; - white-space: pre; - padding: 0 0.5em; -} - -div#cgit table.list td a { - color: black; -} - -div#cgit table.list td a.ls-dir { - font-weight: bold; - color: #00f; -} - -div#cgit table.list td a:hover { - color: #00f; -} - -div#cgit img { - border: none; -} - -div#cgit input#switch-btn { - margin: 2px 0px 0px 0px; -} - -div#cgit td#sidebar input.txt { - width: 100%; - margin: 2px 0px 0px 0px; -} - -div#cgit table#grid { - margin: 0px; -} - -div#cgit td#content { - vertical-align: top; - padding: 1em 2em 1em 1em; - border: none; -} - -div#cgit div#summary { - vertical-align: top; - margin-bottom: 1em; - max-width: 70ch; -} - -div#cgit table#downloads { - float: right; - border-collapse: collapse; - border: solid 1px #777; - margin-left: 0.5em; - margin-bottom: 0.5em; -} - -div#cgit table#downloads th { - background-color: #ccc; -} - -div#cgit div#blob { - border: solid 1px black; -} - -div#cgit div.error { - color: red; - font-weight: bold; - margin: 1em 2em; -} - -div#cgit a.ls-blob, div#cgit a.ls-dir, div#cgit .ls-mod { - font-family: monospace; -} - -div#cgit td.ls-size { - text-align: right; - font-family: monospace; - width: 10em; -} - -div#cgit td.ls-mode { - font-family: monospace; - width: 10em; -} - -div#cgit table.blob { - margin-top: 0.5em; - border-top: solid 1px black; -} - -div#cgit table.blob td.hashes, -div#cgit table.blob td.lines { - margin: 0; padding: 0 0 0 0.5em; - vertical-align: top; - color: black; -} - -div#cgit table.blob td.linenumbers { - margin: 0; padding: 0 0.5em 0 0.5em; - vertical-align: top; - text-align: right; - border-right: 1px solid gray; -} - -div#cgit table.blob pre { - padding: 0; margin: 0; -} - -div#cgit table.blob td.linenumbers a, -div#cgit table.ssdiff td.lineno a { - color: gray; - text-align: right; - text-decoration: none; -} - -div#cgit table.blob td.linenumbers a:hover, -div#cgit table.ssdiff td.lineno a:hover { - color: black; -} - -div#cgit table.blame td.hashes, -div#cgit table.blame td.lines, -div#cgit table.blame td.linenumbers { - padding: 0; -} - -div#cgit table.blame td.hashes div.alt, -div#cgit table.blame td.lines div.alt { - padding: 0 0.5em 0 0.5em; -} - -div#cgit table.blame td.linenumbers div.alt { - padding: 0 0.5em 0 0; -} - -div#cgit table.blame div.alt:nth-child(even) { - background: #eee; -} - -div#cgit table.blame div.alt:nth-child(odd) { - background: white; -} - -div#cgit table.blame td.lines > div { - position: relative; -} - -div#cgit table.blame td.lines > div > pre { - padding: 0 0 0 0.5em; - position: absolute; - top: 0; -} - -div#cgit table.bin-blob { - margin-top: 0.5em; - border: solid 1px black; -} - -div#cgit table.bin-blob th { - font-family: monospace; - white-space: pre; - border: solid 1px #777; - padding: 0.5em 1em; -} - -div#cgit table.bin-blob td { - font-family: monospace; - white-space: pre; - border-left: solid 1px #777; - padding: 0em 1em; -} - -div#cgit table.nowrap td { - white-space: nowrap; -} - -div#cgit table.commit-info { - border-collapse: collapse; - margin-top: 1.5em; -} - -div#cgit div.cgit-panel { - float: right; - margin-top: 1.5em; -} - -div#cgit div.cgit-panel table { - border-collapse: collapse; - border: solid 1px #aaa; - background-color: #eee; -} - -div#cgit div.cgit-panel th { - text-align: center; -} - -div#cgit div.cgit-panel td { - padding: 0.25em 0.5em; -} - -div#cgit div.cgit-panel td.label { - padding-right: 0.5em; -} - -div#cgit div.cgit-panel td.ctrl { - padding-left: 0.5em; -} - -div#cgit table.commit-info th { - text-align: left; - font-weight: normal; - padding: 0.1em 1em 0.1em 0.1em; - vertical-align: top; -} - -div#cgit table.commit-info td { - font-weight: normal; - padding: 0.1em 1em 0.1em 0.1em; -} - -div#cgit div.commit-subject { - font-weight: bold; - font-size: 125%; - margin: 1.5em 0em 0.5em 0em; - padding: 0em; -} - -div#cgit div.commit-msg { - white-space: pre; - font-family: monospace; -} - -div#cgit div.notes-header { - font-weight: bold; - padding-top: 1.5em; -} - -div#cgit div.notes { - white-space: pre; - font-family: monospace; - border: solid 1px #ee9; - background-color: #ffd; - padding: 0.3em 2em 0.3em 1em; - float: left; -} - -div#cgit div.notes-footer { - clear: left; -} - -div#cgit div.diffstat-header { - font-weight: bold; - padding-top: 1.5em; -} - -div#cgit table.diffstat { - border-collapse: collapse; - border: solid 1px #aaa; - background-color: #eee; -} - -div#cgit table.diffstat th { - font-weight: normal; - text-align: left; - text-decoration: underline; - padding: 0.1em 1em 0.1em 0.1em; - font-size: 100%; -} - -div#cgit table.diffstat td { - padding: 0.2em 0.2em 0.1em 0.1em; - font-size: 100%; - border: none; -} - -div#cgit table.diffstat td.mode { - white-space: nowrap; -} - -div#cgit table.diffstat td span.modechange { - padding-left: 1em; - color: red; -} - -div#cgit table.diffstat td.add a { - color: green; -} - -div#cgit table.diffstat td.del a { - color: red; -} - -div#cgit table.diffstat td.upd a { - color: blue; -} - -div#cgit table.diffstat td.graph { - width: 500px; - vertical-align: middle; -} - -div#cgit table.diffstat td.graph table { - border: none; -} - -div#cgit table.diffstat td.graph td { - padding: 0px; - border: 0px; - height: 7pt; -} - -div#cgit table.diffstat td.graph td.add { - background-color: #5c5; -} - -div#cgit table.diffstat td.graph td.rem { - background-color: #c55; -} - -div#cgit div.diffstat-summary { - color: #888; - padding-top: 0.5em; -} - -div#cgit table.diff { - width: 100%; -} - -div#cgit table.diff td { - font-family: monospace; - white-space: pre; -} - -div#cgit table.diff td div.head { - font-weight: bold; - margin-top: 1em; - color: black; -} - -div#cgit table.diff td div.hunk { - color: #009; -} - -div#cgit table.diff td div.add { - color: green; -} - -div#cgit table.diff td div.del { - color: red; -} - -div#cgit .sha1 { - font-family: monospace; - font-size: 90%; -} - -div#cgit .left { - text-align: left; -} - -div#cgit .right { - text-align: right; -} - -div#cgit table.list td.reposection { - font-style: italic; - color: #888; -} - -div#cgit a.button { - font-size: 80%; - padding: 0em 0.5em; -} - -div#cgit a.primary { - font-size: 100%; -} - -div#cgit a.secondary { - font-size: 90%; -} - -div#cgit td.toplevel-repo { - -} - -div#cgit table.list td.sublevel-repo { - padding-left: 1.5em; -} - -div#cgit ul.pager { - list-style-type: none; - text-align: center; - margin: 1em 0em 0em 0em; - padding: 0; -} - -div#cgit ul.pager li { - display: inline-block; - margin: 0.25em 0.5em; -} - -div#cgit ul.pager a { - color: #777; -} - -div#cgit ul.pager .current { - font-weight: bold; -} - -div#cgit span.age-mins { - font-weight: bold; - color: #080; -} - -div#cgit span.age-hours { - color: #080; -} - -div#cgit span.age-days { - color: #040; -} - -div#cgit span.age-weeks { - color: #444; -} - -div#cgit span.age-months { - color: #888; -} - -div#cgit span.age-years { - color: #bbb; -} - -div#cgit span.insertions { - color: #080; -} - -div#cgit span.deletions { - color: #800; -} - -div#cgit div.footer { - margin-top: 0.5em; - text-align: center; - font-size: 80%; - color: #ccc; -} - -div#cgit div.footer a { - color: #ccc; - text-decoration: none; -} - -div#cgit div.footer a:hover { - text-decoration: underline; -} - -div#cgit a.branch-deco { - color: #000; - margin: 0px 0.5em; - padding: 0px 0.25em; - background-color: #88ff88; - border: solid 1px #007700; -} - -div#cgit a.tag-deco { - color: #000; - margin: 0px 0.5em; - padding: 0px 0.25em; - background-color: #ffff88; - border: solid 1px #777700; -} - -div#cgit a.tag-annotated-deco { - color: #000; - margin: 0px 0.5em; - padding: 0px 0.25em; - background-color: #ffcc88; - border: solid 1px #777700; -} - -div#cgit a.remote-deco { - color: #000; - margin: 0px 0.5em; - padding: 0px 0.25em; - background-color: #ccccff; - border: solid 1px #000077; -} - -div#cgit a.deco { - color: #000; - margin: 0px 0.5em; - padding: 0px 0.25em; - background-color: #ff8888; - border: solid 1px #770000; -} - -div#cgit div.commit-subject a.branch-deco, -div#cgit div.commit-subject a.tag-deco, -div#cgit div.commit-subject a.tag-annotated-deco, -div#cgit div.commit-subject a.remote-deco, -div#cgit div.commit-subject a.deco { - margin-left: 1em; - font-size: 75%; -} - -div#cgit table.stats { - border: solid 1px black; - border-collapse: collapse; -} - -div#cgit table.stats th { - text-align: left; - padding: 1px 0.5em; - background-color: #eee; - border: solid 1px black; -} - -div#cgit table.stats td { - text-align: right; - padding: 1px 0.5em; - border: solid 1px black; -} - -div#cgit table.stats td.total { - font-weight: bold; - text-align: left; -} - -div#cgit table.stats td.sum { - color: #c00; - font-weight: bold; -/* background-color: #eee; */ -} - -div#cgit table.stats td.left { - text-align: left; -} - -div#cgit table.vgraph { - border-collapse: separate; - border: solid 1px black; - height: 200px; -} - -div#cgit table.vgraph th { - background-color: #eee; - font-weight: bold; - border: solid 1px white; - padding: 1px 0.5em; -} - -div#cgit table.vgraph td { - vertical-align: bottom; - padding: 0px 10px; -} - -div#cgit table.vgraph div.bar { - background-color: #eee; -} - -div#cgit table.hgraph { - border: solid 1px black; - width: 800px; -} - -div#cgit table.hgraph th { - background-color: #eee; - font-weight: bold; - border: solid 1px black; - padding: 1px 0.5em; -} - -div#cgit table.hgraph td { - vertical-align: middle; - padding: 2px 2px; -} - -div#cgit table.hgraph div.bar { - background-color: #eee; - height: 1em; -} - -div#cgit table.ssdiff { - width: 100%; -} - -div#cgit table.ssdiff td { - font-size: 75%; - font-family: monospace; - white-space: pre; - padding: 1px 4px 1px 4px; - border-left: solid 1px #aaa; - border-right: solid 1px #aaa; -} - -div#cgit table.ssdiff td.add { - color: black; - background: #cfc; - min-width: 50%; -} - -div#cgit table.ssdiff td.add_dark { - color: black; - background: #aca; - min-width: 50%; -} - -div#cgit table.ssdiff span.add { - background: #cfc; - font-weight: bold; -} - -div#cgit table.ssdiff td.del { - color: black; - background: #fcc; - min-width: 50%; -} - -div#cgit table.ssdiff td.del_dark { - color: black; - background: #caa; - min-width: 50%; -} - -div#cgit table.ssdiff span.del { - background: #fcc; - font-weight: bold; -} - -div#cgit table.ssdiff td.changed { - color: black; - background: #ffc; - min-width: 50%; -} - -div#cgit table.ssdiff td.changed_dark { - color: black; - background: #cca; - min-width: 50%; -} - -div#cgit table.ssdiff td.lineno { - color: black; - background: #eee; - text-align: right; - width: 3em; - min-width: 3em; -} - -div#cgit table.ssdiff td.hunk { - color: black; - background: #ccf; - border-top: solid 1px #aaa; - border-bottom: solid 1px #aaa; -} - -div#cgit table.ssdiff td.head { - border-top: solid 1px #aaa; - border-bottom: solid 1px #aaa; -} - -div#cgit table.ssdiff td.head div.head { - font-weight: bold; - color: black; -} - -div#cgit table.ssdiff td.foot { - border-top: solid 1px #aaa; - border-left: none; - border-right: none; - border-bottom: none; -} - -div#cgit table.ssdiff td.space { - border: none; -} - -div#cgit table.ssdiff td.space div { - min-height: 3em; -} -* { line-height: 1.25em; } - -article { - font-family: sans-serif; - max-width: 70ch; - margin-left: auto; - margin-right: auto; -} - -div#cgit { - margin: auto; - font-family: monospace; - -moz-tab-size: 4; - tab-size: 4; - display: table; -} - -div#cgit table#header { - margin-left: auto; - margin-right: auto; -} -div#cgit table#header td.logo { - display: none; -} -div#cgit table#header td.main { - font-size: 2em; - font-weight: bold; -} -div#cgit table#header td.sub { - border-top: none; -} -div#cgit table.tabs { - margin-left: auto; - margin-right: auto; - border-bottom: none; -} -div#cgit div.content { - border-bottom: none; - min-width: 108ch; -} -div#cgit div.content div#summary { - display: table; - margin-left: auto; - margin-right: auto; -} -div#cgit table.list { - margin-left: auto; - margin-right: auto; -} -div#cgit table.list th a { - color: inherit; -} -div#cgit table.list tr:nth-child(even) { - background: inherit; -} -div#cgit table.list tr:hover { - background: inherit; -} -div#cgit table.list tr.nohover-highlight:hover:nth-child(even) { - background: inherit; -} -div#cgit table.list td:last-child { - width: 0; -} -div#cgit div.footer { - font-size: 1em; - margin-top: 0; -} - -div#cgit table.blob td.linenumbers:nth-last-child(3) { - display: none; -} - -div#cgit table.blob td.linenumbers a:target { - color: goldenrod; - text-decoration: underline; - outline: none; -} - -body.hl { background-color:#e0eaee; } -pre.hl { color:#000000; background-color:#e0eaee; font-size:10pt; font-family:'Courier New',monospace;} -.hl.num { color:#b07e00; } -.hl.esc { color:#ff00ff; } -.hl.str { color:#bf0303; } -.hl.pps { color:#818100; } -.hl.slc { color:#838183; font-style:italic; } -.hl.com { color:#838183; font-style:italic; } -.hl.ppc { color:#008200; } -.hl.opt { color:#000000; } -.hl.ipl { color:#0057ae; } -.hl.lin { color:#555555; } -.hl.kwa { color:#000000; font-weight:bold; } -.hl.kwb { color:#0057ae; } -.hl.kwc { color:#000000; font-weight:bold; } -.hl.kwd { color:#010181; }
diff --git a/machines/trabbi/git/cgit.nix b/machines/trabbi/git/cgit.nix @@ -1,97 +0,0 @@ -{ config, lib, pkgs, ... }: - -let - cgitAssets = ./cgit-assets; - cgitConfig = pkgs.writeText "cgitrc" (lib.generators.toKeyValue { } { - css = "/assets/cgit.css"; - logo = "/cgit.png"; - - virtual-root = "/"; - - root-title = "ctucx.cgit"; - root-desc = "my personal git repos"; - - local-time = 1; - cache-size = 30; - - about-filter = "${pkgs.cgit}/lib/cgit/filters/about-formatting.sh"; - source-filter = "${pkgs.cgit}/lib/cgit/filters/syntax-highlighting.py"; - - clone-url = (lib.concatStringsSep " " [ - "https://cgit.ctu.cx/$CGIT_REPO_URL" - "ssh://git@${config.networking.hostName}.${config.networking.domain}:$CGIT_REPO_URL" - ]); - - snapshots = (lib.concatStringsSep " " [ - "tar.gz" - "tar.bz2" - "zip" - ]); - - max-stats-quarter = "quarter"; - - enable-commit-graph = 1; - - enable-index-links = 1; - enable-index-owner = 0; - - enable-log-filecount = 1; - enable-log-linecount = 1; - - enable-blame = 1; - - enable-git-config = 1; - - remove-suffix = 1; - project-list = "/var/lib/gitolite/projects.list"; - scan-path = "/var/lib/gitolite/repositories"; - }); - -in { - - dns.zones."ctu.cx".subdomains.cgit.CNAME = [ "${config.networking.fqdn}." ]; - - services = { - - fcgiwrap = { - enable = true; - user = "git"; - group = "git"; - }; - - nginx = { - enable = true; - virtualHosts."cgit.ctu.cx" = { - enableACME = true; - forceSSL = true; - kTLS = true; - locations = { - "/".tryFiles = "$uri @cgit"; - "/assets/".alias = "${cgitAssets}/"; - "~ '^/[a-zA-Z0-9._-]+/(git-(receive|upload)-pack|HEAD|info/refs|objects/(info/(http-)?alternates|packs)|[0-9a-f]{2}/[0-9a-f]{38}|pack/pack-[0-9a-f]{40}\.(pack|idx))$'".extraConfig = '' - if ($query_string = service=git-receive-pack) { - return 403; - } - - include "${pkgs.nginx}/conf/fastcgi_params"; - fastcgi_param SCRIPT_FILENAME "${pkgs.git}/libexec/git-core/git-http-backend"; - fastcgi_param GIT_PROJECT_ROOT /var/lib/gitolite/repositories; - fastcgi_param PATH_INFO $uri; - fastcgi_pass unix:${config.services.fcgiwrap.socketAddress}; - ''; - "@cgit".extraConfig = '' - include "${pkgs.nginx}/conf/fastcgi_params"; - fastcgi_param CGIT_CONFIG "${cgitConfig}"; - fastcgi_param SCRIPT_FILENAME "${pkgs.cgit}/cgit/cgit.cgi"; - fastcgi_param PATH_INFO $uri; - fastcgi_param QUERY_STRING $args; - fastcgi_param HTTP_HOST $server_name; - fastcgi_pass unix:${config.services.fcgiwrap.socketAddress}; - ''; - }; - }; - }; - - }; - -}
diff --git a/machines/trabbi/git/default.nix b/machines/trabbi/git/default.nix @@ -1,32 +0,0 @@ -{ config, lib, pkgs, ... }: - -{ - - imports = [ -# ./cgit.nix - ./stagit.nix - ]; - - age.secrets.restic-gitolite.file = ../../../secrets/trabbi/restic/gitolite.age; - - restic-backups.gitolite = { - user = "git"; - passwordFile = config.age.secrets.restic-gitolite.path; - paths = [ "/var/lib/gitolite" ]; - }; - - services = { - gitolite = { - enable = true; - user = "git"; - group = "git"; - adminPubkey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDb2eZ2ymt+Zsf0eTlmjW2jPdS013lbde1+EGkgu6bz9lVTR8aawshF2HcoaWp5a5dJr3SKyihDM8hbWSYB3qyTHihNGyCArqSvAtZRw301ailRVHGqiwUITTfcg1533TtmWvlJZgOIFM1VvSAfdueDRRRzbygmn749fS9nhUTDzLtjqX5LvhpqhzsD+eOqPrV6Ne8E1e42JxQb5AJPY1gj9mk6eAarvtEHQYEe+/hp9ERjtCdN5DfuOJnqfaKS0ytPj/NbQskbX/TMgeUVio11iC2NbXsnAtzMmtbLX4mxlDQrR6aZmU/rHQ4aeJqI/Tj2rrF46icri7s0tnnit1OjT5PSxXgifcOtn06qoxYZMT1x+Dyrt40vNkGmxmxCnirm8B+6MKXgd/Ys+7tnOm1ht8TmLm96x6KdOiF3Zq/tMxhPAzp8JriTKSo7k7U9XxStFghTbhhBNc7OX89ZbpalLEnvbQiz87gZxhcx8cLvzIjslOHmZOSWC5Pgr4wwuj3Akq63i4ya6/BzM6v4UoBuDAB6fz3NHKL4R5X20la7Pvt7OBysQkGClWfj6ipMR1bFE2mfYtlMioXNgTjC+NCpEl1+81MH7dv2565Hk8CLV8FMxv6GujbAZGjjcM47lpWM1cBQvpBMUA/lLkyiCPK0YxNWAB7Co+jYDl6CR0Ubew== cardno:6445161"; - extraGitoliteRc = '' - $RC{UMASK} = 0027; - $RC{GIT_CONFIG_KEYS} = ".*"; - push( @{$RC{ENABLE}}, 'cgit' ); - ''; - }; - }; - -}
diff --git a/machines/trabbi/git/stagit.nix b/machines/trabbi/git/stagit.nix @@ -1,250 +0,0 @@ -{ config, lib, pkgs, ... }: - -let - rebuildScript = pkgs.writeShellScript "init-stagit" '' - systemctl start init-stagit; - systemctl status init-stagit; - ''; - - stagitFunctions = '' - export LC_CTYPE="en_US.UTF-8" - - is_public_and_listed() { - if [ ! -f "$1/git-daemon-export-ok" ]; then - return 1 - fi - return 0 - } - - make_stagit_index() { - printf "Generating stagit index... " - - # set assets if not already there - ln -sf "${pkgs.stagit}/share/doc/stagit/style.css" "/var/lib/stagit/style.css" 2> /dev/null - - # generate index arguments - args="-n 'ctucx.git' -e 'git@ctu.cx'" - - for category in "nix" "etc" "nimlang" "nimlang libraries" "archive"; do - args="$args -c '$category'" - for repo in "$HOME/repositories/"*.git/; do - repo="''${repo%/}" - is_public_and_listed "$repo" || continue - - [ "$(${pkgs.gawk}/bin/awk -F '=' '/category/ {print $2}' $repo/config | ${pkgs.gnused}/bin/sed -e 's/^[[:space:]]*//')" = "$category" ] && args="$args $repo" - done - done - - # make index - echo "$args" | xargs ${pkgs.stagit}/bin/stagit-index > /var/lib/stagit/index.html - - # set correct permissions - chmod 755 /var/lib/stagit/index.html; - chown git:git /var/lib/stagit/index.html; - - echo "done" - } - ''; - -in { - - dns.zones."ctu.cx".subdomains = { - cgit.CNAME = [ "${config.networking.fqdn}." ]; - git.CNAME = [ "${config.networking.fqdn}." ]; - }; - - security.sudo.extraRules = [{ - users = [ "git" ]; - commands = [ - { command = "${rebuildScript}"; options = [ "SETENV" "NOPASSWD" ]; } - ]; - }]; - - systemd = { - services.init-stagit = { - script = '' - ${stagitFunctions} - - make_repo_web() { - reponame="$(basename "$1" ".git")" - printf "[%s] stagit HTML pages... " "$reponame" - - mkdir -p "/var/lib/stagit/$reponame" - cd "/var/lib/stagit/$reponame" || return 1 - - # make pages - ${pkgs.stagit}/bin/stagit -c '.stagit-build-cache' -n 'ctucx.git' -h 'https://git.ctu.cx/' -s 'git@${config.networking.hostName}.ctu.cx:' "$1" - - echo "done" - } - - # clean webdir - rm -rf /var/lib/stagit/* - - # make files per repo - for repo in "$HOME/repositories/"*.git/; do - repo="''${repo%/}" - is_public_and_listed "$repo" || continue - - make_repo_web "$repo" - done - - make_stagit_index - ''; - - serviceConfig = { - Type = "oneshot"; - - User = "git"; - Group = "git"; - - WorkingDirectory = "~"; - StateDirectory = "stagit"; - StateDirectoryMode = "755"; - - NoNewPrivileges = true; - PrivateTmp = true; - PrivateDevices = true; - - RestrictAddressFamilies = "AF_INET AF_INET6"; - RestrictNamespaces = true; - RestrictRealtime = true; - - ProtectSystem = "full"; - ProtectControlGroups = true; - ProtectKernelModules = true; - ProtectKernelTunables = true; - - DevicePolicy = "closed"; - LockPersonality = true; - }; - }; - }; - - services = { - gitolite.hooks.postReceive = '' - ${stagitFunctions} - - is_forced_update() { - test "$oldrev" = "0000000000000000000000000000000000000000" && return 1 - test "$newrev" = "0000000000000000000000000000000000000000" && return 1 - - hasrevs="$(${pkgs.git}/bin/git rev-list "$oldrev" "^$newrev" | ${pkgs.gnused}/bin/sed 1q)" - if test -n "$hasrevs"; then - return 0 - fi - return 1 - } - - make_repo_web() { - reponame="$(basename "$1" ".git")" - printf "[%s] stagit HTML pages... " "$reponame" - - # if forced update, remove directory and cache file - is_forced_update && printf "forced update... " && rm -rf "/var/lib/stagit/$reponame" - - mkdir -p "/var/lib/stagit/$reponame" - cd "/var/lib/stagit/$reponame" || return 1 - - # make pages - ${pkgs.stagit}/bin/stagit -c '.stagit-build-cache' -n 'ctucx.git' -h 'https://git.ctu.cx/' -s 'git@${config.networking.hostName}.ctu.cx:' "$1" - - # set correct permissions - chmod 755 -R /var/lib/stagit/$reponame; - chown git:git -R /var/lib/stagit/$reponame; - - echo "done" - } - - update_stagit_repo() { - repo="$(pwd)" - - cd "$repo" || return 1 - is_public_and_listed "$repo" || return 0 - - make_repo_web "$repo" - make_stagit_index - } - - update_stagit_repo "$1" - - #rebuild stagit - [ "$GL_REPO" == "gitolite-admin" ] && sudo ${rebuildScript} - ''; - - fcgiwrap = { - enable = true; - user = "git"; - group = "git"; - }; - - nginx = { - enable = true; - virtualHosts = { - "cgit.ctu.cx" = { - enableACME = true; - forceSSL = true; - kTLS = true; - locations = { - "~ '^/[a-zA-Z0-9._-]+/(git-(receive|upload)-pack|HEAD|info/refs|objects/(info/(http-)?alternates|packs)|[0-9a-f]{2}/[0-9a-f]{38}|pack/pack-[0-9a-f]{40}\.(pack|idx))$'".return = "307 https://git.ctu.cx$request_uri"; - "~ '^/([a-zA-Z0-9_.]+)/*$'".return = "307 https://git.ctu.cx/$1"; - "~ '^/([a-zA-Z0-9_.]+)/tree/([a-zA-Z0-9_./-]+[a-zA-Z0-9_-])/*$'".return = "307 https://git.ctu.cx/$1/tree/$2.html"; - "~ '^/([a-zA-Z0-9_.]+)/tree/*$'".return = "307 https://git.ctu.cx/$1/tree.html"; - "~ '^/([a-zA-Z0-9_.]+)/log/*$'".return = "307 https://git.ctu.cx/$1/log.html"; - "~ '^/([a-zA-Z0-9_.]+)/commit/*$'".extraConfig = '' - if ($arg_id) { - return 307 https://git.ctu.cx/$1/commit/$arg_id.html; - } - - return 307 https://git.ctu.cx/$1/log.html; - ''; - }; - }; - - "git.ctu.cx" = { - enableACME = true; - forceSSL = true; - kTLS = true; - root = "/var/lib/stagit"; - locations = { - "~ '^/[a-zA-Z0-9._-]+/raw'".extraConfig = '' - types { - application/json json; - - application/wasm wasm; - font/woff woff; - font/woff2 woff2; - - application/pdf pdf; - - image/gif gif; - image/jpeg jpeg jpg; - image/png png; - image/svg+xml svg svgz; - image/webp webp; - image/x-icon ico; - } - - default_type text/plain; - try_files $uri =404; - ''; - - "~ '^/[a-zA-Z0-9._-]+/(git-(receive|upload)-pack|HEAD|info/refs|objects/(info/(http-)?alternates|packs)|[0-9a-f]{2}/[0-9a-f]{38}|pack/pack-[0-9a-f]{40}\.(pack|idx))$'".extraConfig = '' - if ($query_string = service=git-receive-pack) { - return 403; - } - - include "${pkgs.nginx}/conf/fastcgi_params"; - fastcgi_param SCRIPT_FILENAME "${pkgs.git}/libexec/git-core/git-http-backend"; - fastcgi_param GIT_PROJECT_ROOT /var/lib/gitolite/repositories; - fastcgi_param PATH_INFO $uri; - fastcgi_pass unix:${config.services.fcgiwrap.socketAddress}; - ''; - }; - }; - }; - }; - - }; - -}
diff --git a/machines/trabbi/maddy.nix b/machines/trabbi/maddy.nix @@ -1,359 +0,0 @@ -{ inputs, config, lib, pkgs, ... }: - -let - mailboxFilterScript = pkgs.writePythonScriptBin "mailbox-filter.py" (ps: [ ps.toml ps.mail-parser ]) '' - from email.header import Header, decode_header, make_header - import sys, re - import toml, mailparser - - def filter_mail(config, sender, recipient, subject): - for type in [ 'recipient', 'subject', 'sender' ]: - if type not in config: - continue - - for key, value in config[type].items(): - if(re.search("^" + key + "$", str(eval(type)))): - print(value.replace(",", "\n")) - sys.exit(0) - - try: - account_name = sys.argv[1] - config = toml.load('/etc/maddy/filters/mailbox/' + account_name + '.toml') - - if len(sys.argv) > 2: - filter_mail(config, sys.argv[2], sys.argv[3], make_header(decode_header(sys.argv[4]))) - else: - sender = subject = "" - message = mailparser.parse_from_string(sys.stdin.read()) - - if len(message.from_) > 0: - if len(message.from_[0]) == 2: - sender = message.from_[0][1] - - if message.subject is not None: - subject = message.subject - - for recipient in message.to: - filter_mail(config, sender, recipient[1], subject) - - except: - pass - - sys.exit(0) - ''; - - receiveFilterScript = pkgs.writePythonScriptBin "receive-filter.py" (ps: [ ps.toml ]) '' - import sys, toml - - try: - sender = sys.argv[1] - recipient = sys.argv[2] - config = toml.load('/etc/maddy/filters/receive.toml') - - for type in [ 'recipient', 'sender' ]: - if type not in config: - continue - - if 'reject' in config[type]: - if eval(type) in config[type]['reject']: - sys.exit(10) - - if 'quarantine' in config[type]: - if eval(type) in config[type]['quarantine']: - sys.exit(20) - - except SystemExit as e: - sys.exit(e) - - except: - pass - - sys.exit(0) - ''; - -in { - - environment.etc."maddy/filters/mailbox/leah@ctu.cx.toml".text = "${inputs.nix-std.lib.serde.toTOML inputs.local-secrets.maddy.mailboxFilter}"; - environment.etc."maddy/filters/receive.toml".text = "${inputs.nix-std.lib.serde.toTOML inputs.local-secrets.maddy.receiveFilter}"; - - security.acme.certs."${config.networking.fqdn}".reloadServices = [ "maddy.service" ]; - - systemd.services.maddy.serviceConfig.ReadOnlyPaths = [ "/etc/maddy/filters" ]; - systemd.services.maddy-restarter = { - script = "${pkgs.systemd}/bin/systemctl restart maddy.service"; - startAt = "0/12:00:00"; - }; - - age.secrets.restic-maddy.file = ../../secrets/trabbi/restic/maddy.age; - - networking.firewall.allowedTCPPorts = [ 25 143 465 587 993 ]; - - dns.zones = with pkgs.dns.lib.combinators; let - TXT = [ "v=spf1 a mx ip4:185.232.70.80 +ip6:2a03:4000:4e:af1::1 ~all" ]; - DMARC = "v=DMARC1; p=none"; - MX = with mx; [ (mx 10 "${config.networking.fqdn}.") ]; - in { - "ctu.cx" = { - inherit MX TXT; - - SRV = [ - { proto = "tcp"; service = "imaps"; priority = 0; weight = 1; port = 993; target = "${config.networking.fqdn}."; } - { proto = "tcp"; service = "imap"; priority = 0; weight = 1; port = 143; target = "${config.networking.fqdn}."; } - { proto = "tcp"; service = "submission"; priority = 0; weight = 1; port = 587; target = "${config.networking.fqdn}."; } - ]; - - subdomains = { - _dmarc.TXT = [ DMARC ]; - "default._domainkey".TXT = [ "v=DKIM1; k=ed25519; p=nWRKCHE19fL1RHJ2cVkC8Xvfzm9OtgeF5VC2lD+EaEo=" ]; - }; - }; - - "ctucx.de" = { - inherit MX TXT; - - subdomains = { - _dmarc.TXT = [ DMARC ]; - "default._domainkey".TXT = [ "v=DKIM1; k=ed25519; p=U9JMZlv7BpLXGIpO7WdJ/7ephxwJtJ02jaVUUadyP9s" ]; - }; - }; - - "thein.ovh" = { - inherit MX TXT; - - subdomains = { - _dmarc.TXT = [ DMARC ]; - "default._domainkey".TXT = [ "v=DKIM1; k=ed25519; p=KYkebiXYSc/+7Rtdz/ZZFRAXAsQnyLPYA6r2uboh5oc=" ]; - }; - }; - - "zug.network" = { - inherit MX TXT; - - subdomains = { - _dmarc.TXT = [ DMARC ]; - "default._domainkey".TXT = [ "v=DKIM1; k=ed25519; p=dH1h2nvPlmT0lIrGddpYRZFTm0AD6D+fsU36McEso2g=" ]; - }; - }; - }; - - users.groups.maddy = {}; - users.users.maddy = { - isSystemUser = true; - home = "/var/lib/maddy"; - group = "maddy"; - extraGroups = [ "nginx" ]; - }; - - restic-backups.maddy = { - user = "maddy"; - passwordFile = config.age.secrets.restic-maddy.path; - paths = [ "/var/lib/maddy" ]; - }; - - services.maddy = { - enable = true; - user = "maddy"; - group = "maddy"; - hostname = config.networking.fqdn; - primaryDomain = "ctu.cx"; - localDomains = [ - "$(hostname)" - "$(primary_domain)" - "thein.ovh" - "ctucx.de" - "trans-agenda.de" - "zug.network" - ]; - - config = '' - #debug on - log syslog - - tls file /var/lib/acme/${config.networking.fqdn}/fullchain.pem /var/lib/acme/${config.networking.fqdn}/key.pem - - # ---------------------------------------------------------------------------- - # Local storage & authentication - - # pass_table provides local hashed passwords storage for authentication of - # users. It can be configured to use any "table" module, in default - # configuration a table in SQLite DB is used. - # Table can be replaced to use e.g. a file for passwords. Or pass_table module - # can be replaced altogether to use some external source of credentials (e.g. - # PAM, /etc/shadow file). - # - # If table module supports it (sql_table does) - credentials can be managed - # using 'maddyctl creds' command. - - auth.pass_table local_authdb { - table sql_table { - driver sqlite3 - dsn credentials.db - table_name passwords - } - } - - # imapsql module stores all indexes and metadata necessary for IMAP using a - # relational database. It is used by IMAP endpoint for mailbox access and - # also by SMTP & Submission endpoints for delivery of local messages. - # - # IMAP accounts, mailboxes and all message metadata can be inspected using - # imap-* subcommands of maddyctl utility. - - storage.imapsql local_mailboxes { - driver sqlite3 - dsn imapsql.db - disable_recent false - compression zstd - - imap_filter { - command ${mailboxFilterScript} {account_name} - } - } - - # ---------------------------------------------------------------------------- - # SMTP endpoints + message routing - - msgpipeline local_routing { - dmarc yes - check { - require_mx_record - dkim - spf { - permerr_action ignore - } - command ${receiveFilterScript} {sender} {rcpts} { - run_on rcpt - - code 1 ignore - code 2 ignore - code 10 reject - code 20 quarantine - } - } - - destination postmaster $(local_domains) { - modify { - replace_rcpt static { - entry postmaster postmaster@$(primary_domain) - entry leon@thein.ovh leah@ctu.cx - entry aufsicht@zug.network mail@zug.network - entry verwaltung@zug.network mail@zug.network - } - - # Implement plus-address notation. - replace_rcpt regexp "(.+)\+(.+)@(.+)" "$1@$3" - - replace_rcpt regexp "(.+)@ctucx.de" "leah@ctu.cx" - replace_rcpt regexp "(.+)@ctu.cx" "leah@ctu.cx" - } - - deliver_to &local_mailboxes - } - - default_destination { - reject 550 5.1.1 "User doesn't exist" - } - } - - smtp tcp://0.0.0.0:25 { - limits { - # Up to 20 msgs/sec across max. 10 SMTP connections. - all rate 20 1s - all concurrency 10 - } - - source $(local_domains) { - reject 501 5.1.8 "Use Submission for outgoing SMTP" - } - - default_source { - destination postmaster $(local_domains) { - deliver_to &local_routing - } - - default_destination { - reject 550 5.1.1 "User doesn't exist" - } - } - } - - submission tls://0.0.0.0:465 tcp://0.0.0.0:587 { - limits { - # Up to 50 msgs/sec across any amount of SMTP connections. - all rate 50 1s - } - - auth &local_authdb - - source $(local_domains) { - destination postmaster $(local_domains) { - deliver_to &local_routing - } - - default_destination { - modify { - dkim $(primary_domain) $(local_domains) default { - newkey_algo ed25519 - } - } - deliver_to &remote_queue - } - } - - default_source { - reject 501 5.1.8 "Non-local sender domain" - } - } - - target.remote outbound_delivery { - limits { - # Up to 20 msgs/sec across max. 10 SMTP connections - # for each recipient domain. - destination rate 20 1s - destination concurrency 10 - } - - mx_auth { - dane - - mtasts { - cache fs - fs_dir mtasts_cache/ - } - - local_policy { - min_tls_level encrypted - min_mx_level none - } - } - } - - target.queue remote_queue { - target &outbound_delivery - max_parallelism 16 - max_tries 4 - - autogenerated_msg_domain $(primary_domain) - - bounce { - destination postmaster $(local_domains) { - deliver_to &local_routing - } - - default_destination { - reject 550 5.0.0 "Refusing to send DSNs to non-local addresses" - } - } - } - - # ---------------------------------------------------------------------------- - # IMAP endpoints - - imap tls://0.0.0.0:993 tcp://0.0.0.0:143 { - auth &local_authdb - storage &local_mailboxes - } - ''; - }; - -}
diff --git a/machines/trabbi/mail.nix b/machines/trabbi/mail.nix @@ -6,9 +6,9 @@ inputs.simple-nixos-mailserver.nixosModule ]; - age.secrets.restic-mail.file = ../../secrets/trabbi/restic/mail.age; - age.secrets.mail-password-leah.file = ../../secrets/trabbi/mail/password-leah-ctu.cx.age; - age.secrets.mail-password-zugnetwork.file = ../../secrets/trabbi/mail/password-mail-zug.network.age; + age.secrets.restic-mail.file = ./. + "/../../secrets/${config.networking.hostName}/restic/mail.age"; + age.secrets.mail-password-leah.file = ./. + "/../../secrets/${config.networking.hostName}/mail/password-leah-ctu.cx.age"; + age.secrets.mail-password-zugnetwork.file = ./. + "/../../secrets/${config.networking.hostName}/mail/password-mail-zug.network.age"; dns.zones = with pkgs.dns.lib.combinators; let TXT = [ "v=spf1 a mx ip4:${config.networking.primaryIP4} +ip6:${config.networking.primaryIP} ~all" ];
diff --git a/machines/trabbi/matrix-synapse.nix b/machines/trabbi/matrix-synapse.nix @@ -2,10 +2,12 @@ { + dns.zones."ctu.cx".subdomains.matrix.CNAME = [ "${config.networking.fqdn}." ]; + age.secrets = { - restic-matrix-synapse.file = ../../secrets/trabbi/restic/matrix-synapse.age; + restic-matrix-synapse.file = ./. + "/../../secrets/${config.networking.hostName}/restic/matrix-synapse.age"; matrix-registration_shared_secret = { - file = ../../secrets/trabbi/matrix-synapse/registration_shared_secret.age; + file = ./. + "/../../secrets/${config.networking.hostName}/matrix-synapse/registration_shared_secret.age"; owner = "matrix-synapse"; }; }; @@ -19,8 +21,6 @@ systemd.services.matrix-synapse.onFailure = [ "email-notify@%i.service" ]; - dns.zones."ctu.cx".subdomains.matrix.CNAME = [ "${config.networking.fqdn}." ]; - services = { postgresql = { enable = true;
diff --git a/machines/trabbi/websites/bikemap.ctu.cx.nix b/machines/trabbi/websites/bikemap.ctu.cx.nix @@ -11,12 +11,10 @@ in { dns.zones."ctu.cx".subdomains.bikemap.CNAME = [ "${config.networking.fqdn}." ]; - users = { - users."bikemap" = { - home = "/var/lib/bikemap"; - group = "git"; - isSystemUser = true; - }; + users.users."bikemap" = { + home = "/var/lib/bikemap"; + group = "git"; + isSystemUser = true; }; security.sudo.extraRules = [{ @@ -26,56 +24,54 @@ in { ]; }]; - systemd = { - services.deploy-bikemap = { - script = '' - # strict mode - set -euo pipefail - IFS=$'\n\t' + systemd.services.deploy-bikemap = { + script = '' + # strict mode + set -euo pipefail + IFS=$'\n\t' - TMP_DIR=$(mktemp -d) - trap "{ rm -rf "$TMP_DIR"; }" SIGINT SIGTERM ERR EXIT + TMP_DIR=$(mktemp -d) + trap "{ rm -rf "$TMP_DIR"; }" SIGINT SIGTERM ERR EXIT - ${pkgs.git}/bin/git clone /var/lib/gitolite/repositories/biketracks.git $TMP_DIR/tracks + ${pkgs.git}/bin/git clone /var/lib/gitolite/repositories/biketracks.git $TMP_DIR/tracks - mkdir $TMP_DIR/tiles + mkdir $TMP_DIR/tiles - ${pkgs.generateTilesFromGPX}/bin/generateTilesFromGPX $TMP_DIR/tracks $TMP_DIR/tiles + ${pkgs.generateTilesFromGPX}/bin/generateTilesFromGPX $TMP_DIR/tracks $TMP_DIR/tiles - rm -rf ~/*; + rm -rf ~/*; - ln -sf ${pkgs.gpx-map}/index.html ~/index.html - ln -sf ${pkgs.gpx-map}/bundle.js ~/bundle.js - mv $TMP_DIR/tiles ~/tiles; - echo "{\"lastUpdated\":\"$(date +"%Y-%m-%d %H:%M")\"}" > ~/lastUpdated.json - ''; + ln -sf ${pkgs.gpx-map}/index.html ~/index.html + ln -sf ${pkgs.gpx-map}/bundle.js ~/bundle.js + mv $TMP_DIR/tiles ~/tiles; + echo "{\"lastUpdated\":\"$(date +"%Y-%m-%d %H:%M")\"}" > ~/lastUpdated.json + ''; - serviceConfig = { - Type = "oneshot"; + serviceConfig = { + Type = "oneshot"; - User = "bikemap"; - Group = "git"; + User = "bikemap"; + Group = "git"; - WorkingDirectory = "~"; - StateDirectory = "bikemap"; - StateDirectoryMode = "755"; + WorkingDirectory = "~"; + StateDirectory = "bikemap"; + StateDirectoryMode = "755"; - NoNewPrivileges = true; - PrivateTmp = true; - PrivateDevices = true; + NoNewPrivileges = true; + PrivateTmp = true; + PrivateDevices = true; - RestrictAddressFamilies = "none"; - RestrictNamespaces = true; - RestrictRealtime = true; + RestrictAddressFamilies = "none"; + RestrictNamespaces = true; + RestrictRealtime = true; - ProtectSystem = "full"; - ProtectControlGroups = true; - ProtectKernelModules = true; - ProtectKernelTunables = true; + ProtectSystem = "full"; + ProtectControlGroups = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; - DevicePolicy = "closed"; - LockPersonality = true; - }; + DevicePolicy = "closed"; + LockPersonality = true; }; };