summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--flake.nix1
-rw-r--r--hosts/cloud/proxy/git.nix13
-rw-r--r--microvms/cgit/cgit.nix203
-rw-r--r--microvms/cgit/default.nix24
-rw-r--r--modules/wg/proxy.nix8
5 files changed, 245 insertions, 4 deletions
diff --git a/flake.nix b/flake.nix
index 5215376..51836fb 100644
--- a/flake.nix
+++ b/flake.nix
@@ -57,6 +57,7 @@
"forgejo"
"miniflux"
"stream"
+ "cgit"
];
microvm-unstable-list = [
"auth"
diff --git a/hosts/cloud/proxy/git.nix b/hosts/cloud/proxy/git.nix
index 6b4a895..0a6a753 100644
--- a/hosts/cloud/proxy/git.nix
+++ b/hosts/cloud/proxy/git.nix
@@ -1,4 +1,9 @@
-{ ... }:
+{ lib, ... }:
+let
+ cgit = "10.89.88.19";
+ cgit6 = "fd31:185d:722f::19";
+ gitport = 8080;
+in
{
# ssh config for forgejo
# need ip forward for nat
@@ -12,11 +17,11 @@
# git.oxapentane.com: port forward 22 to forgejo
# TODO do a proper thing with ipv6
extraCommands = ''
- iptables -t nat -I PREROUTING -p tcp --dport 22 -d 116.202.5.66 -j DNAT --to-destination 10.89.88.15:2222
+ iptables -t nat -I PREROUTING -p tcp --dport 22 -d 116.202.5.66 -j DNAT --to-destination ${cgit}:22
iptables ! -o lo -t nat -A POSTROUTING -j MASQUERADE
'';
extraStopCommands = ''
- iptables -t nat -D PREROUTING -p tcp --dport 22 -d 116.202.5.66 -j DNAT --to-destination 10.89.88.15:2222 || true
+ iptables -t nat -D PREROUTING -p tcp --dport 22 -d 116.202.5.66 -j DNAT --to-destination ${cgit}:22 || true
'';
};
# host sshd: only listen on oxapentane.com and mgmt vpn
@@ -36,6 +41,6 @@
];
services.caddy.virtualHosts."git.oxapentane.com".extraConfig = ''
- respond "Temporary unavailable due to maintenance" 503
+ reverse_proxy ${cgit}:${lib.toString gitport}
'';
}
diff --git a/microvms/cgit/cgit.nix b/microvms/cgit/cgit.nix
new file mode 100644
index 0000000..09b1048
--- /dev/null
+++ b/microvms/cgit/cgit.nix
@@ -0,0 +1,203 @@
+{ pkgs, lib, ... }:
+let
+ host = "git.oxapentane.com";
+ gitHome = "/var/lib/git";
+ cgitPort = 8080;
+
+ defaultBranch = "main";
+
+ mkCreateRepoCommand =
+ {
+ command,
+ visibility,
+ }:
+ pkgs.writeShellApplication {
+ name = command;
+
+ runtimeInputs = [
+ pkgs.coreutils
+ pkgs.git
+ pkgs.gnugrep
+ ];
+
+ text = ''
+ set -eu
+
+ if [ "$#" -ne 1 ]; then
+ printf 'usage: ${command} NAME\n' >&2
+ exit 2
+ fi
+
+ name=$1
+
+ # Accept either "foo" or "foo.git".
+ case "$name" in
+ *.git)
+ name="''${name%.git}"
+ ;;
+ esac
+
+ # Deliberately only allow a single path component.
+ # This excludes traversal, slashes, spaces and shell metacharacters.
+ if ! printf '%s\n' "$name" \
+ | grep -Eq '^[A-Za-z0-9][A-Za-z0-9._-]*$'
+ then
+ printf '%s\n' \
+ 'invalid repository name: use letters, digits, ".", "_" and "-"' \
+ >&2
+ exit 2
+ fi
+
+ base=${lib.escapeShellArg "${gitHome}/${visibility}"}
+ repo="$base/$name.git"
+
+ umask 0027
+
+ # mkdir is the existence check: never silently reinitialize a repo.
+ if ! mkdir -- "$repo" 2>/dev/null; then
+ printf 'repository already exists or cannot be created: %s\n' \
+ "$name.git" >&2
+ exit 1
+ fi
+
+ if ! git init \
+ --bare \
+ --initial-branch=${lib.escapeShellArg defaultBranch} \
+ "$repo" \
+ >/dev/null
+ then
+ printf 'failed to initialize repository: %s\n' "$name.git" >&2
+ exit 1
+ fi
+
+ # Avoid Git's default "Unnamed repository..." text appearing in cgit.
+ : > "$repo/description"
+
+ # This is the only successful stdout output, making $() safe.
+ printf '%s\n' "git@${host}:${visibility}/$name.git"
+ '';
+ };
+
+ createPrivate = mkCreateRepoCommand {
+ command = "create";
+ visibility = "private";
+ };
+
+ createPublic = mkCreateRepoCommand {
+ command = "create-pub";
+ visibility = "public";
+ };
+
+ noInteractiveLogin = pkgs.writeShellScript "no-interactive-login" ''
+ printf '%s\n' "Interactive shell access is disabled." >&2
+ exit 128
+ '';
+
+ restrictedGitShell =
+ (pkgs.writeShellApplication {
+ name = "restricted-git-shell";
+
+ text = ''
+ umask 0027
+ exec ${pkgs.git}/bin/git-shell "$@"
+ '';
+ }).overrideAttrs (old: {
+ passthru = (old.passthru or { }) // {
+ shellPath = "/bin/restricted-git-shell";
+ };
+ });
+in
+{
+ # public repos in cgit
+ services.cgit."${host}" = {
+ enable = true;
+ user = "cgit";
+ group = "cgit";
+ scanPath = "${gitHome}/public";
+ gitHttpBackend = {
+ enable = true;
+ checkExportOkFiles = false; # /public is unconditionally public anyway...
+ };
+
+ settings = {
+ root-title = "0xa's compilable shitposts";
+ root-desc = "Public directory of my finest spaghetti";
+
+ remove-suffix = true;
+ clone-url =
+ "https://${host}/$CGIT_REPO_URL.git "
+ + "git@${host}:public/$CGIT_REPO_URL.git";
+
+ enable-http-clone = false;
+ enable-filter-overrides = false;
+ enable-git-config = false;
+ enable-http-serving = false;
+
+ max-blob-size = 2048;
+ noplainemail = true;
+
+ snapshots = "";
+ };
+
+ nginx = {
+ virtualHost = host;
+ location = "/";
+ };
+ };
+
+ # just bind to proxy interface, everything's handeled by caddy
+ services.nginx.virtualHosts.${host}.listen = [
+ {
+ addr = "10.89.88.19";
+ port = cgitPort;
+ }
+ ];
+
+ # private - bare repos behind separate user
+ users.groups.git = {};
+ users.users.git = {
+ isSystemUser = true;
+ group = "git";
+ home = gitHome;
+ createHome = false;
+ shell = restrictedGitShell;
+ hashedPassword = "!";
+ openssh.authorizedKeys.keys = [
+ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAXrwZsBChUhVuF5gFEfj8GwQlnrqEttAytS5jVCfuE4 0xa@frituurpan"
+ ];
+ };
+
+ # enable and cofigure ssh
+ services.openssh = {
+ enable = true;
+ extraConfig = ''
+ Match User git
+ AuthenticationMethods publickey
+ PasswordAuthentication no
+ KbdInteractiveAuthentication no
+ DisableForwarding yes
+ PermitTTY no
+ PermitUserRC no
+ '';
+ };
+
+ # ensure directories and rights
+ systemd.tmpfiles.rules = [
+ "d ${gitHome} 0711 git git -"
+ "d ${gitHome}/public 2750 git cgit -"
+ "d ${gitHome}/private 0711 git git -"
+ "d ${gitHome}/git-shell-commands 0700 git git -"
+
+
+ "L+ ${gitHome}/git-shell-commands/create - - - - ${createPrivate}/bin/create"
+ "L+ ${gitHome}/git-shell-commands/create-pub - - - - ${createPublic}/bin/create-pub"
+ "L+ ${gitHome}/git-shell-commands/no-interactive-login - - - - ${noInteractiveLogin}"
+ ];
+
+ # dubious ownership error
+ systemd.services."fcgiwrap-cgit-${host}".environment = {
+ GIT_CONFIG_COUNT = "1";
+ GIT_CONFIG_KEY_0 = "safe.directory";
+ GIT_CONFIG_VALUE_0 = "${gitHome}/public/*";
+ };
+}
diff --git a/microvms/cgit/default.nix b/microvms/cgit/default.nix
new file mode 100644
index 0000000..f58b7c0
--- /dev/null
+++ b/microvms/cgit/default.nix
@@ -0,0 +1,24 @@
+{ config, ... }:
+{
+ imports = [
+ ../lib
+ ./cgit.nix
+ ];
+
+ oxalab.vm.number = 9;
+
+ networking.hostName = "cgit";
+ system.stateVersion = "26.05";
+
+ sops.secrets = {
+ "wg/0xa-proxy" = {
+ owner = config.users.users.systemd-network.name;
+ };
+ };
+
+
+ microvm = {
+ mem = 1 * 1024;
+ vcpu = 2;
+ };
+}
diff --git a/modules/wg/proxy.nix b/modules/wg/proxy.nix
index 091f057..ada0a8e 100644
--- a/modules/wg/proxy.nix
+++ b/modules/wg/proxy.nix
@@ -71,6 +71,14 @@
publicKey = "RDxbOvd/1FSWqIp5v1++wPBcG1hScAT4mhIlMZdvxU4=";
privateKeyFile = config.sops.secrets."wg/0xa-proxy".path;
};
+ "cgit" = {
+ address = [
+ "10.89.88.19/24"
+ "fd31:185d:722f::19/48"
+ ];
+ publicKey = "E9cs2Lq5hsBkz5UoUviJEf22pF0EpX6IYGm9L8D7QDc=";
+ privateKeyFile = config.sops.secrets."wg/0xa-proxy".path;
+ };
};
}
];