From 0c4f3acb281be6290c55a6e96bc29fab5b5c7a11 Mon Sep 17 00:00:00 2001 From: tv Date: Mon, 11 Sep 2023 18:24:28 +0200 Subject: stockholm -> hrm --- configs/autotether.nix | 19 ++ configs/backup.nix | 108 ++++++++++++ configs/bash/default.nix | 66 +++++++ configs/binary-cache/default.nix | 28 +++ configs/br.nix | 49 ++++++ configs/default.nix | 131 ++++++++++++++ configs/elm-packages-proxy.nix | 359 ++++++++++++++++++++++++++++++++++++++ configs/exim-retiolum.nix | 8 + configs/exim-smarthost.nix | 45 +++++ configs/fs/CAC-CentOS-7-64bit.nix | 20 +++ configs/gitconfig.nix | 15 ++ configs/gitrepos.nix | 237 +++++++++++++++++++++++++ configs/htop.nix | 39 +++++ configs/hw/AO753.nix | 47 +++++ configs/hw/winmax2.nix | 48 +++++ configs/hw/x220.nix | 88 ++++++++++ configs/imgur.nix | 21 +++ configs/initrd/sshd.nix | 17 ++ configs/mail-client.nix | 9 + configs/man.nix | 13 ++ configs/nets/hkw.nix | 68 ++++++++ configs/networkd.nix | 4 + configs/nginx/default.nix | 21 +++ configs/nginx/public_html.nix | 17 ++ configs/nix.nix | 9 + configs/pki/certs/tv.crt | 31 ++++ configs/pki/default.nix | 67 +++++++ configs/ppp.nix | 85 +++++++++ configs/pulse.nix | 119 +++++++++++++ configs/repo-sync/wiki.nix | 39 +++++ configs/retiolum.nix | 26 +++ configs/smartd.nix | 17 ++ configs/ssh.nix | 21 +++ configs/sshd.nix | 26 +++ configs/urlwatch.nix | 118 +++++++++++++ configs/vim.nix | 184 +++++++++++++++++++ configs/weechat-server.nix | 24 +++ configs/wiregrill.nix | 36 ++++ configs/xdg.nix | 10 ++ configs/xserver/Xmodmap.nix | 28 +++ configs/xserver/default.nix | 166 ++++++++++++++++++ configs/xserver/sxiv.nix | 11 ++ configs/xserver/urxvt.nix | 72 ++++++++ configs/xserver/xkiller.nix | 14 ++ configs/xserver/xserver.conf.nix | 38 ++++ configs/xsessions/default.nix | 5 + configs/xsessions/urxvtd.nix | 15 ++ 47 files changed, 2638 insertions(+) create mode 100644 configs/autotether.nix create mode 100644 configs/backup.nix create mode 100644 configs/bash/default.nix create mode 100644 configs/binary-cache/default.nix create mode 100644 configs/br.nix create mode 100644 configs/default.nix create mode 100644 configs/elm-packages-proxy.nix create mode 100644 configs/exim-retiolum.nix create mode 100644 configs/exim-smarthost.nix create mode 100644 configs/fs/CAC-CentOS-7-64bit.nix create mode 100644 configs/gitconfig.nix create mode 100644 configs/gitrepos.nix create mode 100644 configs/htop.nix create mode 100644 configs/hw/AO753.nix create mode 100644 configs/hw/winmax2.nix create mode 100644 configs/hw/x220.nix create mode 100644 configs/imgur.nix create mode 100644 configs/initrd/sshd.nix create mode 100644 configs/mail-client.nix create mode 100644 configs/man.nix create mode 100644 configs/nets/hkw.nix create mode 100644 configs/networkd.nix create mode 100644 configs/nginx/default.nix create mode 100644 configs/nginx/public_html.nix create mode 100644 configs/nix.nix create mode 100644 configs/pki/certs/tv.crt create mode 100644 configs/pki/default.nix create mode 100644 configs/ppp.nix create mode 100644 configs/pulse.nix create mode 100644 configs/repo-sync/wiki.nix create mode 100644 configs/retiolum.nix create mode 100644 configs/smartd.nix create mode 100644 configs/ssh.nix create mode 100644 configs/sshd.nix create mode 100644 configs/urlwatch.nix create mode 100644 configs/vim.nix create mode 100644 configs/weechat-server.nix create mode 100644 configs/wiregrill.nix create mode 100644 configs/xdg.nix create mode 100644 configs/xserver/Xmodmap.nix create mode 100644 configs/xserver/default.nix create mode 100644 configs/xserver/sxiv.nix create mode 100644 configs/xserver/urxvt.nix create mode 100644 configs/xserver/xkiller.nix create mode 100644 configs/xserver/xserver.conf.nix create mode 100644 configs/xsessions/default.nix create mode 100644 configs/xsessions/urxvtd.nix (limited to 'configs') diff --git a/configs/autotether.nix b/configs/autotether.nix new file mode 100644 index 0000000..43b5575 --- /dev/null +++ b/configs/autotether.nix @@ -0,0 +1,19 @@ +{ config, pkgs, ... }: let + cfg.serial = "17e064850405"; +in { + systemd.services.usb_tether.serviceConfig = { + SyslogIdentifier = "usb_tether"; + ExecStartPre = "${pkgs.android-tools}/bin/adb -s ${cfg.serial} wait-for-device"; + ExecStart = "${pkgs.android-tools}/bin/adb -s ${cfg.serial} shell svc usb setFunctions rndis"; + }; + services.udev.extraRules = /* sh */ '' + ACTION=="add", SUBSYSTEM=="net", KERNEL=="usb*", NAME="android" + + ACTION=="add", SUBSYSTEM=="usb", ATTR{serial}=="${cfg.serial}", \ + TAG+="systemd", ENV{SYSTEMD_WANTS}="usb_tether.service" + ''; + systemd.network.networks.android = { + matchConfig.Name = "android"; + DHCP = "yes"; + }; +} diff --git a/configs/backup.nix b/configs/backup.nix new file mode 100644 index 0000000..30d6011 --- /dev/null +++ b/configs/backup.nix @@ -0,0 +1,108 @@ +{ config, lib, mylib, pkgs, ... }: { + krebs.backup.plans = { + } // lib.mapAttrs (_: lib.recursiveUpdate { + snapshots = { + daily = { format = "%Y-%m-%d"; retain = 7; }; + weekly = { format = "%YW%W"; retain = 4; }; + monthly = { format = "%Y-%m"; retain = 12; }; + yearly = { format = "%Y"; }; + }; + }) { + bu-home-xu = { + method = "push"; + src = { host = config.krebs.hosts.bu; path = "/home"; }; + dst = { host = config.krebs.hosts.xu; path = "/bku/bu-home"; }; + startAt = "05:20"; + }; + bu-home-zu = { + method = "push"; + src = { host = config.krebs.hosts.bu; path = "/home"; }; + dst = { host = config.krebs.hosts.zu; path = "/bku/bu-home"; }; + startAt = "05:25"; + }; + nomic-home-xu = { + method = "push"; + src = { host = config.krebs.hosts.nomic; path = "/home"; }; + dst = { host = config.krebs.hosts.xu; path = "/bku/nomic-home"; }; + startAt = "05:00"; + }; + nomic-home-zu = { + method = "push"; + src = { host = config.krebs.hosts.nomic; path = "/home"; }; + dst = { host = config.krebs.hosts.zu; path = "/bku/nomic-home"; }; + startAt = "04:20"; + }; + nomic-pull-querel-home = { + method = "pull"; + src = { host = config.krebs.hosts.querel; path = "/home"; }; + dst = { host = config.krebs.hosts.nomic; path = "/fs/ponyhof/bku/querel-home"; }; + startAt = "22:00"; + }; + xu-home-bu = { + method = "push"; + src = { host = config.krebs.hosts.xu; path = "/home"; }; + dst = { host = config.krebs.hosts.bu; path = "/bku/xu-home"; }; + startAt = "04:50"; + }; + xu-home-nomic = { + method = "push"; + src = { host = config.krebs.hosts.xu; path = "/home"; }; + dst = { host = config.krebs.hosts.nomic; path = "/fs/cis3hG/bku/xu-home"; }; + startAt = "05:20"; + }; + xu-home-zu = { + method = "push"; + src = { host = config.krebs.hosts.xu; path = "/home"; }; + dst = { host = config.krebs.hosts.zu; path = "/bku/xu-home"; }; + startAt = "06:20"; + }; + xu-pull-ni-ejabberd = { + method = "pull"; + src = { host = config.krebs.hosts.ni; path = "/var/lib/ejabberd"; }; + dst = { host = config.krebs.hosts.xu; path = "/bku/ni-ejabberd"; }; + startAt = "07:00"; + }; + xu-pull-ni-home = { + method = "pull"; + src = { host = config.krebs.hosts.ni; path = "/home"; }; + dst = { host = config.krebs.hosts.xu; path = "/bku/ni-home"; }; + startAt = "07:00"; + }; + zu-home-xu = { + method = "push"; + src = { host = config.krebs.hosts.zu; path = "/home"; }; + dst = { host = config.krebs.hosts.xu; path = "/bku/zu-home"; }; + startAt = "05:00"; + }; + zu-pull-ni-ejabberd = { + method = "pull"; + src = { host = config.krebs.hosts.ni; path = "/var/lib/ejabberd"; }; + dst = { host = config.krebs.hosts.zu; path = "/bku/ni-ejabberd"; }; + startAt = "06:00"; + }; + zu-pull-ni-home = { + method = "pull"; + src = { host = config.krebs.hosts.ni; path = "/home"; }; + dst = { host = config.krebs.hosts.zu; path = "/bku/ni-home"; }; + startAt = "06:30"; + }; + } // lib.mapAttrs (_: lib.recursiveUpdate { + snapshots = { + minutely = { format = "%Y-%m-%dT%H:%M"; retain = 3; }; + hourly = { format = "%Y-%m-%dT%H"; retain = 3; }; + daily = { format = "%Y-%m-%d"; retain = 3; }; + }; + startAt = null; + }) { + xu-test-push-xu = { + method = "push"; + src = { host = config.krebs.hosts.xu; path = "/tmp/xu-bku-test-data"; }; + dst = { host = config.krebs.hosts.xu; path = "/bku/xu-test-push"; }; + }; + xu-test-pull-xu = { + method = "pull"; + src = { host = config.krebs.hosts.xu; path = "/tmp/xu-bku-test-data"; }; + dst = { host = config.krebs.hosts.xu; path = "/bku/xu-test-pull"; }; + }; + }; +} diff --git a/configs/bash/default.nix b/configs/bash/default.nix new file mode 100644 index 0000000..2e18d5b --- /dev/null +++ b/configs/bash/default.nix @@ -0,0 +1,66 @@ +{ config, mylib, pkgs, ... }: { + programs.bash = { + interactiveShellInit = /* sh */ '' + HISTCONTROL='erasedups:ignorespace' + HISTSIZE=900001 + HISTFILESIZE=$HISTSIZE + HISTTIMEFORMAT= + + shopt -s checkhash + shopt -s histappend histreedit histverify + shopt -s no_empty_cmd_completion + complete -d cd + + case $UID in + ${mylib.shell.escape (toString config.krebs.users.tv.uid)}) + if test ''${SHLVL-1} = 1 && test -n "''${DISPLAY-}"; then + _CURRENT_DESKTOP_NAME=''${_CURRENT_DESKTOP_NAME-$( + ${pkgs.xorg.xprop}/bin/xprop -notype -root \ + 32i _NET_CURRENT_DESKTOP \ + 8s _NET_DESKTOP_NAMES \ + | + ${pkgs.gnused}/bin/sed -r 's/.* = //;s/"//g;s/, /\a/g' | + { + read -r _NET_CURRENT_DESKTOP + IFS=$'\a' read -ra _NET_DESKTOP_NAMES + echo "''${_NET_DESKTOP_NAMES[$_NET_CURRENT_DESKTOP]}" + } + )} + case $_CURRENT_DESKTOP_NAME in + stockholm) + cd ~/stockholm + ;; + esac + fi + + export NIX_PATH="stockholm=$HOME/stockholm:$NIX_PATH" + ;; + esac + + ${pkgs.bash-fzf-history.bind} + + if test -n "''${BASH_EXTRA_INIT-}"; then + . "$BASH_EXTRA_INIT" + fi + ''; + promptInit = /* sh */ '' + case $UID in + 0) + PS1='\[\e[1;31m\]\w\[\e[0m\] ' + ;; + ${toString config.krebs.build.user.uid}) + PS1='\[\e[1;32m\]\w\[\e[0m\] ' + ;; + *) + PS1='\[\e[1;35m\]\u \[\e[1;32m\]\w\[\e[0m\] ' + ;; + esac + if test -n "$SSH_CLIENT"; then + PS1='\[\e[35m\]\h'" $PS1" + fi + if test -n "$SSH_AGENT_PID"; then + PS1="ssh-agent[$SSH_AGENT_PID] $PS1" + fi + ''; + }; +} diff --git a/configs/binary-cache/default.nix b/configs/binary-cache/default.nix new file mode 100644 index 0000000..d9e87c7 --- /dev/null +++ b/configs/binary-cache/default.nix @@ -0,0 +1,28 @@ +{ config, pkgs, ... }: { + environment.etc."binary-cache.pubkey".text = + config.krebs.build.host.binary-cache.pubkey; + + nixpkgs.overlays = [ + (self: super: { + nix-serve = self.haskellPackages.nix-serve-ng; + }) + ]; + + services.nix-serve = { + enable = true; + secretKeyFile = "${config.krebs.secret.directory}/nix-serve.key"; + }; + + services.nginx = { + enable = true; + virtualHosts.nix-serve = { + serverAliases = [ + "cache.${config.krebs.build.host.name}.hkw" + "cache.${config.krebs.build.host.name}.r" + ]; + locations."/".extraConfig = '' + proxy_pass http://localhost:${toString config.services.nix-serve.port}; + ''; + }; + }; +} diff --git a/configs/br.nix b/configs/br.nix new file mode 100644 index 0000000..b9bc70b --- /dev/null +++ b/configs/br.nix @@ -0,0 +1,49 @@ +{ config, lib, modulesPath, mylib, pkgs, ... }: { + + imports = [ + (modulesPath + "/services/hardware/sane_extra_backends/brscan4.nix") + ]; + + krebs.nixpkgs.allowUnfreePredicate = + pkg: lib.any (mylib.eq (mylib.packageName pkg)) [ + "brother-udev-rule-type1" + "brscan4" + "brscan4-etc-files" + "mfcl2700dnlpr" + ]; + + hardware.sane = { + enable = true; + brscan4 = { + enable = true; + netDevices = { + bra = { + model = "MFCL2700DN"; + ip = "10.23.1.214"; + }; + }; + }; + }; + + services.saned.enable = true; + + # usage: scanimage -d "$(find-scanner bra)" --batch --format=tiff --resolution 150 -x 211 -y 298 + environment.systemPackages = [ + (pkgs.writeDashBin "find-scanner" '' + set -efu + name=$1 + ${pkgs.sane-backends}/bin/scanimage -f '%m %d + ' \ + | ${pkgs.gawk}/bin/awk -v dev="*$name" '$1 == dev { print $2; exit }' \ + | ${pkgs.gnugrep}/bin/grep . + '') + ]; + + services.printing = { + enable = true; + drivers = [ + pkgs.mfcl2700dncupswrapper + ]; + }; + +} diff --git a/configs/default.nix b/configs/default.nix new file mode 100644 index 0000000..5d74d96 --- /dev/null +++ b/configs/default.nix @@ -0,0 +1,131 @@ +{ config, inputs, lib, mylib, pkgs, ... }: { + boot.tmpOnTmpfs = true; + + krebs.enable = true; + + krebs.build.user = config.krebs.users.tv; + + networking.hostId = lib.mkDefault (mylib.hashToLength 8 config.networking.hostName); + networking.hostName = config.krebs.build.host.name; + + imports = [ + ./backup.nix + ./bash + ./htop.nix + ./nets/hkw.nix + ./networkd.nix + ./nginx + ./nix.nix + ./pki + ./ssh.nix + ./sshd.nix + ./vim.nix + ./xdg.nix + { + users = { + defaultUserShell = "/run/current-system/sw/bin/bash"; + mutableUsers = false; + users = { + tv = { + inherit (config.krebs.users.tv) home uid; + isNormalUser = true; + extraGroups = [ "tv" ]; + }; + }; + }; + } + { + i18n.defaultLocale = lib.mkDefault "C.UTF-8"; + security.sudo.extraConfig = '' + Defaults env_keep+="SSH_CLIENT _CURRENT_DESKTOP_NAME" + Defaults mailto="${config.krebs.users.tv.mail}" + Defaults !lecture + ''; + time.timeZone = "Europe/Berlin"; + } + + { + nixpkgs.config.allowUnfree = false; + } + { + environment.homeBinInPath = true; + + environment.profileRelativeEnvVars.PATH = lib.mkForce [ "/bin" ]; + + environment.systemPackages = with pkgs; [ + rxvt_unicode.terminfo + ]; + + environment.shellAliases = lib.mkForce { + gp = "${pkgs.pari}/bin/gp -q"; + df = "df -h"; + du = "du -h"; + + # TODO alias cannot contain #\' + # "ps?" = "ps ax | head -n 1;ps ax | fgrep -v ' grep --color=auto ' | grep"; + + ls = "ls -h --color=auto --group-directories-first"; + dmesg = "dmesg -L --reltime"; + view = "vim -R"; + }; + + environment.variables = { + NIX_PATH = lib.mkForce (lib.concatStringsSep ":" [ + "secrets=/var/src/stockholm/null" + "/var/src" + ]); + }; + } + + { + services.cron.enable = false; + services.ntp.enable = false; + services.timesyncd.enable = true; + } + + { + boot.kernel.sysctl = { + # Enable IPv6 Privacy Extensions + # + # XXX use mkForce here because since NixOS 21.11 there's a collision in + # net.ipv6.conf.default.use_tempaddr, and boot.kernel.sysctl incapable + # of merging. + # + # XXX net.ipv6.conf.all.use_tempaddr is set because it was mentioned in + # https://tldp.org/HOWTO/Linux+IPv6-HOWTO/ch06s05.html + # TODO check if that is really necessary, otherwise we can rely solely + # on networking.tempAddresses in the future (when nothing is <21.11) + "net.ipv6.conf.all.use_tempaddr" = lib.mkForce 2; + "net.ipv6.conf.default.use_tempaddr" = lib.mkForce 2; + }; + } + + { + tv.iptables.enable = true; + tv.iptables.accept-echo-request = "internet"; + } + + { + services.journald.extraConfig = '' + SystemMaxUse=1G + RuntimeMaxUse=128M + ''; + } + + { + environment.systemPackages = [ + pkgs.field + pkgs.get + pkgs.git + pkgs.git-crypt + pkgs.git-preview + pkgs.hashPassword + pkgs.htop + pkgs.kpaste + pkgs.nix-prefetch-scripts + pkgs.ovh-zone + pkgs.push + ]; + } + ]; +} diff --git a/configs/elm-packages-proxy.nix b/configs/elm-packages-proxy.nix new file mode 100644 index 0000000..caea188 --- /dev/null +++ b/configs/elm-packages-proxy.nix @@ -0,0 +1,359 @@ +{ config, lib, pkgs, ... }: let + + cfg.nameserver = "1.1.1.1"; + cfg.packageDir = "/var/lib/elm-packages"; + cfg.port = 7782; + + # TODO secret files + cfg.htpasswd = "/var/lib/certs/package.elm-lang.org/htpasswd"; + cfg.sslCertificate = "/var/lib/certs/package.elm-lang.org/fullchain.pem"; + cfg.sslCertificateKey = "/var/lib/certs/package.elm-lang.org/key.pem"; + + semverRegex = + "(?0|[1-9]\\d*)\\.(?0|[1-9]\\d*)\\.(?0|[1-9]\\d*)(?:-(?(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+(?[0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?"; + +in { + services.nginx.virtualHosts."package.elm-lang.org" = { + addSSL = true; + + sslCertificate = cfg.sslCertificate; + sslCertificateKey = cfg.sslCertificateKey; + + locations."/all-packages".extraConfig = '' + proxy_pass http://127.0.0.1:${toString config.krebs.htgen.elm-packages-proxy.port}; + proxy_pass_header Server; + ''; + + locations."/all-packages/since/".extraConfig = '' + proxy_pass http://127.0.0.1:${toString config.krebs.htgen.elm-packages-proxy.port}; + proxy_pass_header Server; + ''; + + locations."~ ^/packages/(?[A-Za-z0-9-]+)/(?[A-Za-z0-9-]+)/(?${semverRegex})\$".extraConfig = '' + auth_basic "Restricted Area"; + auth_basic_user_file ${cfg.htpasswd}; + + proxy_set_header X-User $remote_user; + proxy_set_header X-Author $author; + proxy_set_header X-Package $pname; + proxy_set_header X-Version $version; + proxy_pass_header Server; + + proxy_pass http://127.0.0.1:${toString config.krebs.htgen.elm-packages-proxy.port}; + ''; + + locations."~ ^/packages/(?[A-Za-z0-9-]+)/(?[A-Za-z0-9-]+)/(?${semverRegex})/(?:zipball|elm.json|endpoint.json)\$".extraConfig = '' + set $zipball "${cfg.packageDir}/$author/$pname/$version/zipball"; + proxy_set_header X-Author $author; + proxy_set_header X-Package $pname; + proxy_set_header X-Version $version; + proxy_set_header X-Zipball $zipball; + proxy_pass_header Server; + resolver ${cfg.nameserver}; + + if (-f $zipball) { + set $new_uri http://127.0.0.1:${toString config.krebs.htgen.elm-packages-proxy.port}; + } + if (!-f $zipball) { + set $new_uri https://package.elm-lang.org$request_uri; + } + + proxy_pass $new_uri; + ''; + + locations."/search.json".extraConfig = '' + proxy_pass http://127.0.0.1:${toString config.krebs.htgen.elm-packages-proxy.port}; + proxy_pass_header Server; + ''; + }; + + krebs.htgen.elm-packages-proxy = { + port = cfg.port; + script = /* sh */ ''. ${pkgs.writeDash "elm-packages-proxy.sh" '' + PATH=${lib.makeBinPath [ + pkgs.attr + pkgs.coreutils + pkgs.curl + pkgs.findutils + pkgs.gnugrep + pkgs.jq + pkgs.p7zip + ]} + export PATH + file_response() {( + status_code=$1 + status_reason=$2 + file=$3 + content_type=$4 + + content_length=$(wc -c "$file" | cut -d\ -f1) + + printf "HTTP/1.1 $status_code $status_reason\r\n" + printf 'Connection: close\r\n' + printf 'Content-Length: %d\r\n' "$content_length" + printf 'Content-Type: %s\r\n' "$content_type" + printf 'Server: %s\r\n' "$Server" + printf '\r\n' + cat "$file" + )} + string_response() {( + status_code=$1 + status_reason=$2 + response_body=$3 + content_type=$4 + + printf "HTTP/1.1 $status_code $status_reason\r\n" + printf 'Connection: close\r\n' + printf 'Content-Length: %d\r\n' "$(expr ''${#response_body} + 1)" + printf 'Content-Type: %s\r\n' "$content_type" + printf 'Server: %s\r\n' "$Server" + printf '\r\n' + printf '%s\n' "$response_body" + )} + + case "$Method $Request_URI" in + 'GET /packages/'*) + + author=$req_x_author + pname=$req_x_package + version=$req_x_version + + zipball=${cfg.packageDir}/$author/$pname/$version/zipball + elmjson=$HOME/cache/$author%2F$pname%2F$version%2Felm.json + endpointjson=$HOME/cache/$author%2F$pname%2F$version%2Fendpoint.json + mkdir -p "$HOME/cache" + + case $(basename $Request_URI) in + zipball) + file_response 200 OK "$zipball" application/zip + exit + ;; + elm.json) + if ! test -f "$elmjson"; then + 7z x -so "$zipball" \*/elm.json > "$elmjson" + fi + file_response 200 OK "$elmjson" 'application/json; charset=UTF-8' + exit + ;; + endpoint.json) + if ! test -f "$endpointjson"; then + hash=$(sha1sum "$zipball" | cut -d\ -f1) + url=https://package.elm-lang.org/packages/$author/$pname/$version/zipball + jq -n \ + --arg hash "$hash" \ + --arg url "$url" \ + '{ $hash, $url }' \ + > "$endpointjson" + fi + file_response 200 OK "$endpointjson" 'application/json; charset=UTF-8' + exit + ;; + esac + ;; + 'POST /packages/'*) + + author=$req_x_author + pname=$req_x_package + user=$req_x_user + version=$req_x_version + + action=uploading + force=''${req_x_force-false} + zipball=${cfg.packageDir}/$author/$pname/$version/zipball + elmjson=$HOME/cache/$author%2F$pname%2F$version%2Felm.json + endpointjson=$HOME/cache/$author%2F$pname%2F$version%2Fendpoint.json + + if test -e "$zipball"; then + if test "$force" = true; then + zipball_owner=$(attr -q -g X-User "$zipball" || :) + if test "$zipball_owner" = "$req_x_user"; then + action=replacing + rm -f "$elmjson" + rm -f "$endpointjson" + else + string_response 403 Forbidden \ + "package already exists: $author/$pname@$version" \ + text/plain + exit + fi + else + string_response 409 Conflict \ + "package already exists: $author/$pname@$version" \ + text/plain + exit + fi + fi + + echo "user $user is $action package $author/$pname@$version" >&2 + # TODO check package + mkdir -p "$(dirname "$zipball")" + head -c $req_content_length > "$zipball" + + attr -q -s X-User -V "$user" "$zipball" || : + + string_response 200 OK \ + "package created: $author/$pname@$version" \ + text/plain + + exit + ;; + 'DELETE /packages/'*) + + author=$req_x_author + pname=$req_x_package + user=$req_x_user + version=$req_x_version + + zipball=${cfg.packageDir}/$author/$pname/$version/zipball + elmjson=$HOME/cache/$author%2F$pname%2F$version%2Felm.json + endpointjson=$HOME/cache/$author%2F$pname%2F$version%2Fendpoint.json + + if test -e "$zipball"; then + zipball_owner=$(attr -q -g X-User "$zipball" || :) + if test "$zipball_owner" = "$req_x_user"; then + echo "user $user is deleting package $author/$pname@$version" >&2 + rm -f "$elmjson" + rm -f "$endpointjson" + rm "$zipball" + string_response 200 OK \ + "package deleted: $author/$pname@$version" \ + text/plain + exit + else + string_response 403 Forbidden \ + "package already exists: $author/$pname@$version" \ + text/plain + exit + fi + fi + ;; + 'GET /all-packages'|'POST /all-packages') + + response=$(mktemp -t htgen.$$.elm-packages-proxy.all-packages.XXXXXXXX) + trap "rm $response >&2" EXIT + + { + # upstream packages + curl -fsS https://package.elm-lang.org"$Request_URI" + + # private packages + (cd ${cfg.packageDir}; find -mindepth 3 -maxdepth 3) | + jq -Rs ' + split("\n") | + map( + select(.!="") | + match("^\\./(?[^/]+)/(?[^/]+)/(?[^/]+)$").captures | + map({key:.name,value:.string}) | + from_entries + ) | + reduce .[] as $item ({}; + ($item|"\(.author)/\(.pname)") as $name | + . + { "\($name)": ((.[$name] // []) + [$item.version]) } + ) + ' + } | + jq -cs add > $response + + file_response 200 OK "$response" 'application/json; charset=UTF-8' + exit + ;; + 'GET /all-packages/since/'*|'POST /all-packages/since/'*) + + response=$(mktemp -t htgen.$$.elm-packages-proxy.all-packages.XXXXXXXX) + trap "rm $response >&2" EXIT + + { + # upstream packages + curl -fsS https://package.elm-lang.org"$Request_URI" + + # private packages + (cd ${cfg.packageDir}; find -mindepth 3 -maxdepth 3) | + jq -Rs ' + split("\n") | + map( + select(.!="") | + sub("^\\./(?[^/]+)/(?[^/]+)/(?[^/]+)$";"\(.author)/\(.pname)@\(.version)") + ) | + sort_by(split("@") | [.[0]]+(.[1]|split(".")|map(tonumber))) | + reverse + ' + } | + jq -cs add > $response + + file_response 200 OK "$response" 'application/json; charset=UTF-8' + exit + ;; + 'GET /search.json') + + searchjson=$HOME/cache/search.json + mkdir -p "$HOME/cache" + + # update cached search.json + ( + last_modified=$( + if test -f "$searchjson"; then + date -Rr "$searchjson" + else + date -R -d @0 + fi + ) + tempsearchjson=$(mktemp "$searchjson.XXXXXXXX") + trap 'rm "$tempsearchjson" >&2' EXIT + curl -fsS --compressed https://package.elm-lang.org/search.json \ + -H "If-Modified-Since: $last_modified" \ + -o "$tempsearchjson" + if test -s "$tempsearchjson"; then + mv "$tempsearchjson" "$searchjson" + trap - EXIT + fi + ) + + response=$(mktemp -t htgen.$$.elm-packages-proxy.search.XXXXXXXX) + trap 'rm "$response" >&2' EXIT + + { + printf '{"upstream":'; cat "$searchjson" + printf ',"private":'; (cd ${cfg.packageDir}; find -mindepth 3 -maxdepth 3) | + jq -Rs ' + split("\n") | + map( + select(.!="") | + match("^\\./(?[^/]+)/(?[^/]+)/(?[^/]+)$").captures | + map({key:.name,value:.string}) | + from_entries + ) | + map({ + key: "\(.author)/\(.pname)", + value: .version, + }) | + from_entries + ' + printf '}' + } | + jq -c ' + reduce .upstream[] as $upstreamItem ({ private, output: [] }; + .private[$upstreamItem.name] as $privateItem | + if $privateItem then + .output += [$upstreamItem * { version: $privateItem.version }] | + .private |= del(.[$upstreamItem.name]) + else + .output += [$upstreamItem] + end + ) | + + .output + (.private | to_entries | sort_by(.key) | map({ + name: .key, + version: .value, + summary: "dummy summary", + license: "dummy license", + })) + ' \ + > $response + + file_response 200 OK "$response" 'application/json; charset=UTF-8' + exit + ;; + esac + ''}''; + }; +} diff --git a/configs/exim-retiolum.nix b/configs/exim-retiolum.nix new file mode 100644 index 0000000..7903ac3 --- /dev/null +++ b/configs/exim-retiolum.nix @@ -0,0 +1,8 @@ +{ config, pkgs, ... }: { + environment.systemPackages = [ + pkgs.eximlog + ]; + krebs.exim-retiolum.enable = true; + krebs.exim-retiolum.rspamd.enable = config.krebs.build.host.name == "nomic"; + tv.iptables.input-retiolum-accept-tcp = [ "smtp" ]; +} diff --git a/configs/exim-smarthost.nix b/configs/exim-smarthost.nix new file mode 100644 index 0000000..d983165 --- /dev/null +++ b/configs/exim-smarthost.nix @@ -0,0 +1,45 @@ +{ config, lib, pkgs, ... }: { + environment.systemPackages = [ + pkgs.eximlog + ]; + krebs.exim-smarthost = { + enable = true; + dkim = [ + { domain = "viljetic.de"; } + ]; + sender_domains = [ + "krebsco.de" + "shackspace.de" + "viljetic.de" + ]; + relay_from_hosts = lib.concatMap (host: host.nets.retiolum.addrs) [ + config.krebs.hosts.nomic + config.krebs.hosts.xu + ]; + internet-aliases = with config.krebs.users; [ + { from = "bku-eppler@viljetic.de"; to = tv.mail; } + { from = "postmaster@viljetic.de"; to = tv.mail; } # RFC 822 + { from = "mirko@viljetic.de"; to = mv-ni.mail; } + { from = "tomislav@viljetic.de"; to = tv.mail; } + { from = "tv@viljetic.de"; to = tv.mail; } + { from = "tv@shackspace.de"; to = tv.mail; } + ]; + system-aliases = [ + { from = "mailer-daemon"; to = "postmaster"; } + { from = "postmaster"; to = "root"; } + { from = "nobody"; to = "root"; } + { from = "hostmaster"; to = "root"; } + { from = "usenet"; to = "root"; } + { from = "news"; to = "root"; } + { from = "webmaster"; to = "root"; } + { from = "www"; to = "root"; } + { from = "ftp"; to = "root"; } + { from = "abuse"; to = "root"; } + { from = "noc"; to = "root"; } + { from = "security"; to = "root"; } + { from = "root"; to = "tv"; } + { from = "mirko"; to = "mv"; } + ]; + }; + tv.iptables.input-internet-accept-tcp = lib.singleton "smtp"; +} diff --git a/configs/fs/CAC-CentOS-7-64bit.nix b/configs/fs/CAC-CentOS-7-64bit.nix new file mode 100644 index 0000000..c9eb97f --- /dev/null +++ b/configs/fs/CAC-CentOS-7-64bit.nix @@ -0,0 +1,20 @@ +_: + +{ + boot.loader.grub = { + device = "/dev/sda"; + }; + fileSystems = { + "/" = { + device = "/dev/centos/root"; + fsType = "xfs"; + }; + "/boot" = { + device = "/dev/sda1"; + fsType = "xfs"; + }; + }; + swapDevices = [ + { device = "/dev/centos/swap"; } + ]; +} diff --git a/configs/gitconfig.nix b/configs/gitconfig.nix new file mode 100644 index 0000000..c4111ed --- /dev/null +++ b/configs/gitconfig.nix @@ -0,0 +1,15 @@ +{ pkgs, ... }: { + environment.etc.gitconfig.text = '' + [alias] + patch = !${pkgs.git}/bin/git --no-pager diff --no-color + [diff-so-fancy] + markEmptyLines = false + stripLeadingSymbols = false + [pager] + diff = ${pkgs.gitAndTools.diff-so-fancy}/bin/diff-so-fancy \ + | ${pkgs.less}/bin/less -FRX + [user] + email = tv@krebsco.de + name = tv + ''; +} diff --git a/configs/gitrepos.nix b/configs/gitrepos.nix new file mode 100644 index 0000000..c69ffa4 --- /dev/null +++ b/configs/gitrepos.nix @@ -0,0 +1,237 @@ +{ config, lib, mylib, pkgs, ... }: let { + + body = { + + nixpkgs.config.packageOverrides = super: { + cgit = pkgs.symlinkJoin { + name = "${super.cgit.name}-tv"; + paths = [ + (pkgs.runCommand "${super.cgit.name}-tv-overrides" { + } /* sh */ '' + mkdir -p $out/lib/cgit/filters + cd $out/lib/cgit/filters + cp \ + ${super.cgit}/lib/cgit/filters/syntax-highlighting.py \ + ${super.cgit}/lib/cgit/filters/.syntax-highlighting.py-wrapped \ + . + sed -i "s:${super.cgit}:$out:" syntax-highlighting.py + sed -i ' + s:^\(formatter =\).*:\1 HtmlFormatter(style="algol_nu"): + ' .syntax-highlighting.py-wrapped + '') + super.cgit + ]; + }; + }; + + krebs.git = { + enable = true; + cgit = { + settings = { + about-filter = pkgs.exec "krebs.cgit.about-filter" rec { + filename = "${pkgs.python3Packages.markdown2}/bin/markdown2"; + argv = [ + filename + "--extras=fenced-code-blocks" + ]; + envp = {}; + }; + readme = [ + ":README.md" + ]; + root-desc = "mostly krebs"; + root-title = "repositories at ${config.krebs.build.host.name}"; + source-filter = "${pkgs.cgit}/lib/cgit/filters/syntax-highlighting.py"; + }; + }; + repos = repos; + rules = rules; + }; + }; + + cgit-clear-cache = pkgs.cgit-clear-cache.override { + inherit (config.krebs.git.cgit.settings) cache-root; + }; + + repos = + public-repos // + lib.optionalAttrs config.krebs.build.host.secure restricted-repos; + + rules = lib.concatMap make-rules (builtins.attrValues repos); + + public-repos = lib.mapAttrs make-public-repo ({ + } // lib.mapAttrs (_: lib.recursiveUpdate { cgit.section = "1. miscellaneous"; }) { + couchfs = { + cgit.desc = "filesystem (in userspace) on top of CouchDB"; + }; + crx = { + cgit.desc = "utilities for working with Chrome extensions"; + }; + dic = { + cgit.desc = "dict.leo.org command line interface"; + }; + disko = { + cgit.desc = "declarative partitioning and formatting tool"; + }; + fswm = { + cgit.desc = "simple full screen window manager"; + }; + htgen = { + cgit.desc = "toy HTTP server"; + }; + ircaids = { + cgit.desc = "Assortment of aids for working with Internet relay chat"; + }; + krops = { + cgit.desc = "deployment tools"; + }; + mailaids = { + cgit.desc = "Assortment of aids for working with electronic mail"; + }; + much = {}; + netcup = { + cgit.desc = "netcup command line interface"; + }; + nix-writers = { + cgit.desc = "collection of package builders"; + }; + nixpkgs = { + cgit.desc = "Nix Packages collection"; + }; + pager = { + }; + populate = { + cgit.desc = "source code installer"; + }; + q = {}; + reaktor2 = {}; + stockholm = { + cgit.desc = "NixOS configuration"; + }; + TabFS = { + cgit.desc = "mount browser tabs & co. as a filesystem"; + }; + texnix = { + cgit.desc = "TeX live environment generator"; + }; + with-ssh = {}; + } // lib.mapAttrs (_: lib.recursiveUpdate { cgit.section = "2. Host configurations"; }) { + ni = { + }; + } // lib.mapAttrs (_: lib.recursiveUpdate { cgit.section = "3. Haskell libraries"; }) { + X11-aeson = {}; + blessings = {}; + hack = {}; + hc = {}; + mime = {}; + quipper = {}; + scanner = {}; + wai-middleware-time = {}; + web-routes-wai-custom = {}; + xintmap = {}; + xmonad-aeson = {}; + xmonad-web = {}; + } // lib.mapAttrs (_: lib.recursiveUpdate { cgit.section = "4. museum"; }) { + cac-api = { + cgit.desc = "CloudAtCost API command line interface"; + }; + cgserver = {}; + crude-mail-setup = {}; + dot-xmonad = {}; + flameshot-once = { + cgit.desc = "flameshot runner that automatically starts/stops the daemon"; + }; + hirc = {}; + hstool = { + cgit.desc = "Haskell Development Environment ^_^"; + }; + kirk = { + cgit.desc = "IRC tools"; + }; + make-snapshot = {}; + nixos-infest = {}; + painload = {}; + push = {}; + Reaktor = {}; + regfish = {}; + with-tmpdir = {}; + get = {}; + load-env = {}; + loldns = { + cgit.desc = "toy DNS server"; + }; + soundcloud = { + cgit.desc = "SoundCloud command line interface"; + }; + xmonad-stockholm = {}; + }); + + restricted-repos = lib.mapAttrs make-restricted-repo ( + { + brain = { + collaborators = with config.krebs.users; [ lass makefu ]; + hooks = { + post-receive = /* sh */ '' + (${irc-announce { cgit_endpoint = null; }}) + ${cgit-clear-cache}/bin/cgit-clear-cache + ''; + }; + }; + } // + # TODO don't put secrets/repos.nix into the store + mylib.importSecret "repos.nix" { inherit config lib pkgs; } + ); + + irc-announce = args: pkgs.git-hooks.irc-announce (lib.recursiveUpdate { + channel = "#xxx"; + # TODO make nick = config.krebs.build.host.name the default + nick = config.krebs.build.host.name; + server = "irc.r"; + verbose = { + exclude = [ + "refs/heads/head" + ]; + }; + } args); + + make-public-repo = name: { cgit ? {}, ... }: { + inherit cgit name; + public = true; + hooks = { + post-receive = /* sh */ '' + (${lib.optionalString (config.krebs.build.host.name == "ni") + (irc-announce {})}) + ${cgit-clear-cache}/bin/cgit-clear-cache + ''; + }; + }; + + make-restricted-repo = name: { collaborators ? [], hooks ? {}, ... }: { + inherit collaborators name; + public = false; + hooks = hooks // { + post-receive = /* sh */ '' + (${hooks.post-receive or ":"}) + ${cgit-clear-cache}/bin/cgit-clear-cache + ''; + }; + }; + + make-rules = + with mylib.git // config.krebs.users; + repo: + [ + { + user = [ tv tv-xu ]; + repo = [ repo ]; + perm = push "refs/*" [ non-fast-forward create delete merge ]; + } + ] + ++ + lib.optional (repo.collaborators or [] != []) { + user = repo.collaborators; + repo = [ repo ]; + perm = fetch; + }; + +} diff --git a/configs/htop.nix b/configs/htop.nix new file mode 100644 index 0000000..e60cc51 --- /dev/null +++ b/configs/htop.nix @@ -0,0 +1,39 @@ +{ pkgs, ... }: { + nixpkgs.config.packageOverrides = super: { + htop = pkgs.symlinkJoin { + name = "htop"; + paths = [ + (pkgs.writeDashBin "htop" '' + export HTOPRC=${pkgs.writeText "htoprc" '' + fields=0 48 17 18 38 39 40 2 46 47 49 1 + sort_key=46 + sort_direction=1 + hide_threads=0 + hide_kernel_threads=1 + hide_userland_threads=0 + shadow_other_users=1 + show_thread_names=1 + show_program_path=1 + highlight_base_name=1 + highlight_megabytes=1 + highlight_threads=1 + tree_view=1 + header_margin=0 + detailed_cpu_time=0 + cpu_count_from_zero=0 + update_process_names=0 + account_guest_in_cpu_meter=1 + color_scheme=0 + delay=15 + left_meters=LeftCPUs2 RightCPUs2 Memory Swap + left_meter_modes=1 1 1 1 + right_meters=Uptime Tasks LoadAverage Battery + right_meter_modes=2 2 2 2 + ''} + exec ${super.htop}/bin/htop "$@" + '') + super.htop + ]; + }; + }; +} diff --git a/configs/hw/AO753.nix b/configs/hw/AO753.nix new file mode 100644 index 0000000..ea58c01 --- /dev/null +++ b/configs/hw/AO753.nix @@ -0,0 +1,47 @@ +{ config, ... }: { + imports = [ + ../smartd.nix + + { + nix.settings.cores = 2; + nix.settings.max-jobs = 2; + } + (if lib.versionAtLeast (lib.versions.majorMinor lib.version) "21.11" then { + nix.daemonCPUSchedPolicy = "batch"; + nix.daemonIOSchedPriority = 1; + } else { + nix.daemonIONiceLevel = 1; + nix.daemonNiceLevel = 1; + }) + ]; + + boot.loader.grub = { + device = "/dev/sda"; + splashImage = null; + }; + + boot.initrd.availableKernelModules = [ + "ahci" + ]; + + boot.kernelModules = [ + "kvm-intel" + "wl" + ]; + + boot.extraModulePackages = [ + config.boot.kernelPackages.broadcom_sta + ]; + + services.logind.extraConfig = '' + HandleHibernateKey=ignore + HandleLidSwitch=ignore + HandlePowerKey=ignore + HandleSuspendKey=ignore + ''; + + krebs.nixpkgs.allowUnfreePredicate = pkg: packageName pkg == "broadcom-sta"; + + tv.hw.screens.primary.width = 1366; + tv.hw.screens.primary.height = 768; +} diff --git a/configs/hw/winmax2.nix b/configs/hw/winmax2.nix new file mode 100644 index 0000000..7b28466 --- /dev/null +++ b/configs/hw/winmax2.nix @@ -0,0 +1,48 @@ +{ pkgs, ... }: { + + imports = [ + ../smartd.nix + ]; + + boot.initrd.availableKernelModules = [ "nvme" "xhci_pci" "thunderbolt" "usbhid" ]; + boot.initrd.kernelModules = [ "amdgpu" ]; + boot.kernelModules = [ + "amd-pstate" + "kvm-amd" + ]; + boot.kernelPackages = pkgs.linuxPackages_latest; + boot.kernelParams = [ + "amd_pstate=passive" + ]; + + hardware.bluetooth.enable = true; + + hardware.cpu.amd.updateMicrocode = true; + hardware.enableRedistributableFirmware = true; + + hardware.opengl.enable = true; + hardware.opengl.extraPackages = [ + pkgs.amdvlk + pkgs.rocm-opencl-icd + pkgs.rocm-opencl-runtime + ]; + + networking.wireless.enable = true; + networking.wireless.interfaces = [ + "wlp1s0" + ]; + networking.interfaces.wlp1s0.useDHCP = true; + + nixpkgs.hostPlatform = "x86_64-linux"; + + services.illum.enable = true; + + services.logind.extraConfig = /* ini */ '' + HandlePowerKey=ignore + ''; + + tv.lidControl.enable = true; + + tv.hw.screens.primary.width = 2560; + tv.hw.screens.primary.height = 1600; +} diff --git a/configs/hw/x220.nix b/configs/hw/x220.nix new file mode 100644 index 0000000..6993413 --- /dev/null +++ b/configs/hw/x220.nix @@ -0,0 +1,88 @@ +{ config, lib, pkgs, ... }: { + imports = [ + ../smartd.nix + { + boot.extraModulePackages = [ + config.boot.kernelPackages.acpi_call + ]; + + boot.kernelModules = [ + "acpi_call" + ]; + + environment.systemPackages = [ + pkgs.tpacpi-bat + ]; + } + + # fix jumpy touchpad + # https://wiki.archlinux.org/index.php/Lenovo_ThinkPad_X220#X220_Touchpad_cursor_jump/imprecise + { + services.udev.extraHwdb = /* sh */ '' + touchpad:i8042:* + LIBINPUT_MODEL_LENOVO_X220_TOUCHPAD_FW81=1 + ''; + } + + { + nix.settings.cores = 2; + nix.settings.max-jobs = 2; + } + (if lib.versionAtLeast (lib.versions.majorMinor lib.version) "21.11" then { + nix.daemonCPUSchedPolicy = "batch"; + nix.daemonIOSchedPriority = 1; + } else { + nix.daemonIONiceLevel = 1; + nix.daemonNiceLevel = 1; + }) + ]; + + boot.extraModulePackages = [ + config.boot.kernelPackages.tp_smapi + ]; + + boot.kernelModules = [ "tp_smapi" ]; + + boot.loader.systemd-boot.enable = true; + boot.loader.efi.canTouchEfiVariables = true; + + # Required for Centrino. + hardware.enableRedistributableFirmware = true; + + hardware.opengl.extraPackages = [ pkgs.vaapiIntel pkgs.vaapiVdpau ]; + + hardware.trackpoint = { + enable = true; + sensitivity = 220; + speed = 0; + emulateWheel = true; + }; + + # Conflicts with TLP, but gets enabled by DEs. + services.power-profiles-daemon.enable = false; + + services.tlp.enable = true; + services.tlp.settings = { + START_CHARGE_THRESH_BAT0 = 80; + }; + + + services.logind.extraConfig = '' + HandleHibernateKey=ignore + HandleLidSwitch=ignore + HandlePowerKey=ignore + HandleSuspendKey=ignore + ''; + + # because extraConfig is not extra enough: + services.logind.lidSwitch = "ignore"; + services.logind.lidSwitchDocked = "ignore"; + services.logind.lidSwitchExternalPower = "ignore"; + + services.xserver = { + videoDriver = "intel"; + }; + + tv.hw.screens.primary.width = lib.mkDefault 1366; + tv.hw.screens.primary.height = lib.mkDefault 768; +} diff --git a/configs/imgur.nix b/configs/imgur.nix new file mode 100644 index 0000000..ece4749 --- /dev/null +++ b/configs/imgur.nix @@ -0,0 +1,21 @@ +{ config, pkgs, ... }: { + services.nginx.virtualHosts."ni.r" = { + locations."/image" = { + extraConfig = /* nginx */ '' + client_max_body_size 20M; + + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + proxy_pass http://127.0.0.1:${toString config.krebs.htgen.imgur.port}; + proxy_pass_header Server; + ''; + }; + }; + + krebs.htgen.imgur = { + port = 7771; + scriptFile = "${pkgs.htgen-imgur}/bin/htgen-imgur"; + }; +} diff --git a/configs/initrd/sshd.nix b/configs/initrd/sshd.nix new file mode 100644 index 0000000..eff8480 --- /dev/null +++ b/configs/initrd/sshd.nix @@ -0,0 +1,17 @@ +{ config, ... }: { + boot.initrd.availableKernelModules = [ + "e1000e" + ]; + boot.initrd.network.enable = true; + boot.initrd.network.ssh = { + enable = true; + port = 11423; + authorizedKeys = [ + config.krebs.users.tv.pubkey + ]; + ignoreEmptyHostKeys = true; + }; + boot.initrd.secrets = { + "/etc/ssh/ssh_host_rsa_key" = ; + }; +} diff --git a/configs/mail-client.nix b/configs/mail-client.nix new file mode 100644 index 0000000..fc8fc81 --- /dev/null +++ b/configs/mail-client.nix @@ -0,0 +1,9 @@ +{ pkgs, ... }: { + environment.systemPackages = [ + pkgs.haskellPackages.much + pkgs.msmtp + pkgs.notmuch + pkgs.qprint + pkgs.w3m + ]; +} diff --git a/configs/man.nix b/configs/man.nix new file mode 100644 index 0000000..c723138 --- /dev/null +++ b/configs/man.nix @@ -0,0 +1,13 @@ +{ config, lib, pkgs, ... }: +{ + #environment.etc."man.conf".source = pkgs.runCommand "man.conf" {} '' + # ${pkgs.gnused}/bin/sed <${pkgs.man}/lib/man.conf >$out ' + # s:^NROFF\t.*:& -Wbreak: + # ' + #''; + environment.systemPackages = [ + pkgs.man-pages + pkgs.posix_man_pages + pkgs.xorg.xorgdocs + ]; +} diff --git a/configs/nets/hkw.nix b/configs/nets/hkw.nix new file mode 100644 index 0000000..51a8a73 --- /dev/null +++ b/configs/nets/hkw.nix @@ -0,0 +1,68 @@ +{ + krebs = { + dns.providers.hkw = "hosts"; + hosts = { + au = { + nets.hkw = { + ip4 = { + addr = "10.23.1.39"; + prefix = "10.23.1.0/24"; + }; + aliases = [ + "au.hkw" + ]; + ssh.port = 11423; + }; + }; + nomic = { + nets.hkw = { + ip4 = { + addr = "10.23.1.110"; + prefix = "10.23.1.0/24"; + }; + aliases = [ + "nomic.hkw" + ]; + ssh.port = 11423; + }; + }; + ok = { + external = true; + nets.hkw = { + ip4 = { + addr = "10.23.1.1"; + prefix = "10.23.1.0/24"; + }; + aliases = [ + "ok.hkw" + ]; + }; + }; + xu = { + nets.hkw = { + ip4 = { + addr = "10.23.1.38"; + prefix = "10.23.1.0/24"; + }; + aliases = [ + "xu.hkw" + "cache.xu.hkw" + ]; + ssh.port = 11423; + }; + }; + zu = { + nets.hkw = { + ip4 = { + addr = "10.23.1.40"; + prefix = "10.23.1.0/24"; + }; + aliases = [ + "zu.hkw" + ]; + ssh.port = 11423; + }; + }; + }; + }; +} diff --git a/configs/networkd.nix b/configs/networkd.nix new file mode 100644 index 0000000..da0d9ce --- /dev/null +++ b/configs/networkd.nix @@ -0,0 +1,4 @@ +{ + # often hangs + systemd.services.systemd-networkd-wait-online.enable = false; +} diff --git a/configs/nginx/default.nix b/configs/nginx/default.nix new file mode 100644 index 0000000..e288c52 --- /dev/null +++ b/configs/nginx/default.nix @@ -0,0 +1,21 @@ +{ config, ... }: { + services.nginx = { + enableReload = true; + + recommendedGzipSettings = true; + recommendedOptimisation = true; + recommendedTlsSettings = true; + + virtualHosts.${builtins.toJSON ""} = { + default = true; + extraConfig = '' + error_page 400 =444 /; + return 444; + ''; + rejectSSL = true; + }; + }; + tv.iptables = { + input-retiolum-accept-tcp = [ "http" ]; + }; +} diff --git a/configs/nginx/public_html.nix b/configs/nginx/public_html.nix new file mode 100644 index 0000000..cd8e3c4 --- /dev/null +++ b/configs/nginx/public_html.nix @@ -0,0 +1,17 @@ +{ config, ... }: { + services.nginx = { + enable = true; + virtualHosts.default = { + serverAliases = [ + "localhost" + "${config.krebs.build.host.name}" + "${config.krebs.build.host.name}.hkw" + "${config.krebs.build.host.name}.r" + ]; + locations."~ ^/~([a-z]+)(?:/(.*))?\$" = { + alias = "/srv/$1/public_html/$2"; + }; + }; + }; + tv.iptables.input-internet-accept-tcp = [ "http" ]; +} diff --git a/configs/nix.nix b/configs/nix.nix new file mode 100644 index 0000000..fa96d45 --- /dev/null +++ b/configs/nix.nix @@ -0,0 +1,9 @@ +{ pkgs, ... }: { + nix.settings.auto-optimise-store = true; + + # TODO check if both are required: + nix.settings.extra-sandbox-paths = [ + "/etc/protocols" + pkgs.iana-etc.outPath + ]; +} diff --git a/configs/pki/certs/tv.crt b/configs/pki/certs/tv.crt new file mode 100644 index 0000000..ccb2623 --- /dev/null +++ b/configs/pki/certs/tv.crt @@ -0,0 +1,31 @@ +tv Root CA +-----BEGIN CERTIFICATE----- +MIIFGzCCAwOgAwIBAgIUbLFkDA1OgKbej/FQiJZ4gpGPg/4wDQYJKoZIhvcNAQEL +BQAwFTETMBEGA1UEAwwKdHYgUm9vdCBDQTAeFw0xOTA0MjEwNzI1MTdaFw0yOTA0 +MTgwNzI1MTdaMBUxEzARBgNVBAMMCnR2IFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQDEVpZo1PLayK2AULwNtRY/2RIs/h+Uz1k/I7AY5o7H +HTD6pxNH3DZS82Y89nAHDVEnotK26TW6N1O2fBHUxH2GXVD+MaA/D9ngbNTJa7DW +2EThezOyesAbXk7dkoHh4Bouj5L7Ronka5+IREFmb3mHmcXLuR/sot9Pwr9A7Lwm +55Avv+VwMFnqVMXiCYQsDL7Mxf7Vm79+kXShpfDhNmHhyZc/xPjVk7lttSEp0LCq +hhJjte3xDGbk7OThTSxoqP+K4Ek7NGatCcm4AUZlDl1kLN2QKudYqj0VRQpfE+4Q +jMAAtttc/10MV0e08pRK0FvJsDsi70YZrHnDP6hIBrRNjC8iB/8rz2pjnYzgriUt +HHEDr26234VB5Zqhsi8pmXA16FVkoKlucADXXKEcR/3VreTvZLdSsP3OrDdSCwhi +H2W/7tshDPp+I9Q9fGNixry7PODbud1h/wLsq3Geg/U6VkDdl7uDNMB/O7LvlFaC +7jkHv/xFLqV1Xx9+yFMdJTKLf9jnIIjeINfV4VcJZDrtgGpnC6cYD5DNLA4j7Mny +EnBV9IRhmKiZLvUZP62dPhqIfSSPNxXV2+rT5ZfaXCuVe79R5npgJzF7/qslvnZ6 +0mjZfQdJiXY+/oT9zPUxTroFx7Qtda15aIVwXR+1cMRY/Hg/uBQyp7yWsvwhPYwH +awIDAQABo2MwYTAdBgNVHQ4EFgQUWYjGpR7J/UqggxQV87hBQ8ZT0qkwHwYDVR0j +BBgwFoAUWYjGpR7J/UqggxQV87hBQ8ZT0qkwDwYDVR0TAQH/BAUwAwEB/zAOBgNV +HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggIBAA++eAA7KLEd4n05n8w95sJ7 +cxqQSkVxV3ASnEUQRwVGo3CqEKcNufbCTG7KKGQFUi2Xd3/SWgnEiSZZWo06azbV +vlquG+9ilwnrnqfjlbUEjLMHDzukrEeIiRuFY7gZv6S2o4WkW/M9IPkP34+PRjip +AJ8kFcy7wLPaeH7OagslAVUcf68lMm+8W4U1g0HZaY2zXFgdRrIO1dXKlJ22Wh4X +fcblHjkASAGi+BK+xRJ9G7s3sie2wPyk+WKKv0Z+WheKf+L+TPBg2sJ+d25gW+gG +XNJSQOzCqSfHrCtcW1xkGgifog28/ymN03ggn8oMBUebOp+ayLkbPQDaj6te3y1v +YE0cfkzQ0T6sSzPzoOrwBEuSX8cLWTpzO2Zgqbf36UtHjgxi58vY46p7MjAInxAf +j+k67rF7qWH38drg4nfGjNgiEdeJw9dtDFdmso+ZiWipUyGF4VYh+Q6JnXDMF0+A +wXcYWa7ckXvVOLVpHJfrLDYTXznGnk2u4ToVNEk1j/klMRn96lxfFg04iv8fz8m6 +/Y8g0G1uIT5Mq9l68oZUoEkUHZabPNhYOiYtg4t5v/T3AIV8nm2A5jZYj0am26xT +iqF/tqL3alWXs9OHP7FNdrVWtwO8vcspYcd4mOHdAC/dmhq+77BowR5Lldx9T+mR +QT8jW9PXL0IH0wKMBXxf +-----END CERTIFICATE----- diff --git a/configs/pki/default.nix b/configs/pki/default.nix new file mode 100644 index 0000000..05a608d --- /dev/null +++ b/configs/pki/default.nix @@ -0,0 +1,67 @@ +{ config, lib, mylib, pkgs, ... }: let + + certFile = config.environment.etc."ssl/certs/ca-certificates.crt".source; + +in { + + environment.etc."pki/nssdb".source = + pkgs.runCommand "system-wide-nssdb" { + inherit certFile; + buildInputs = [ + pkgs.jq + pkgs.nssTools + ]; + parseInfoScript = /* jq */ '' + ${builtins.toJSON certFile} as $certFile | + + split("\t-----END CERTIFICATE-----\n")[] | + select(test("\t-----BEGIN CERTIFICATE-----\n")) | + . + "\t-----END CERTIFICATE-----\n" | + + sub("^([0-9]+\t\n)*";"") | + + (match("^([0-9]+)\t").captures[0].string | tonumber) as $lineNumber | + + gsub("(?m)^[0-9]+\t";"") | + + match("^([^\n]+)\n(.*)";"m").captures | map(.string) | + + # Line numbers are added to the names to ensure uniqueness. + "\(.[0]) (\($certFile):\($lineNumber))" as $name | + .[1] as $cert | + + { $name, $cert } + ''; + passAsFile = [ + "parseInfoScript" + ]; + } /* sh */ '' + mkdir nssdb + + nl -ba -w1 "$certFile" | + jq -ceRs -f "$parseInfoScriptPath" > certinfo.ndjson + + exec < certinfo.ndjson + while read -r certinfo; do + name=$(printf %s "$certinfo" | jq -er .name) + cert=$(printf %s "$certinfo" | jq -er .cert) + + printf %s "$cert" | certutil -A -d nssdb -n "$name" -t C,C,C + done + + mv nssdb "$out" + ''; + + environment.variables = lib.flip lib.genAttrs (_: toString certFile) [ + "CURL_CA_BUNDLE" + "GIT_SSL_CAINFO" + "SSL_CERT_FILE" + ]; + + security.pki.certificateFiles = + lib.mapAttrsToList + (name: _: (./certs + "/${name}")) + (lib.filterAttrs (_: (mylib.eq "regular")) + (builtins.readDir ./certs)); + +} diff --git a/configs/ppp.nix b/configs/ppp.nix new file mode 100644 index 0000000..63e75af --- /dev/null +++ b/configs/ppp.nix @@ -0,0 +1,85 @@ +{ config, mylib, pkgs, ... }: let + cfg = { + pin = "@${config.krebs.secret.directory}/o2.pin"; + ttys.ppp = "/dev/ttyACM0"; + ttys.com = "/dev/ttyACM1"; + }; +in { + assertions = [ + { + assertion = + config.networking.resolvconf.enable || + config.networking.useNetworkd; + message = "ppp configuration needs resolvconf or networkd"; + } + ]; + environment.etc."ppp/ip-up".source = pkgs.writeDash "ppp.ip-up" '' + ${pkgs.openresolv}/bin/resolvconf -a "$IFNAME" < /etc/ppp/resolv.conf + ''; + environment.etc."ppp/ip-down".source = pkgs.writeDash "ppp.ip-down" '' + ${pkgs.openresolv}/bin/resolvconf -fd "$IFNAME" + ''; + environment.etc."ppp/peers/o2".text = /* sh */ '' + ${cfg.ttys.ppp} + 921600 + crtscts + defaultroute + holdoff 10 + lock + maxfail 0 + noauth + nodetach + noipdefault + passive + persist + usepeerdns + connect "${pkgs.ppp}/bin/chat ''${DEBUG+-v} -Ss -f ${pkgs.writeText "o2.chat" /* sh */ '' + ABORT "BUSY" + ABORT "NO CARRIER" + REPORT CONNECT + "*EMRDY: 1" + ATZ OK + AT+CFUN=1 OK + ${cfg.pin} TIMEOUT 2 ERROR-AT-OK + AT+CGDCONT=1,\042IP\042,\042internet\042 OK + ATDT*99***1# CONNECT + ''}" + ''; + users.users.root.packages = [ + (pkgs.writeDashBin "connect" '' + # usage: + # connect wlan + # connect wwan [PEERNAME] + set -efu + rfkill_wlan=/sys/class/rfkill/rfkill2 + rfkill_wwan=/sys/class/rfkill/rfkill1 + case $1 in + wlan) + ${pkgs.procps}/bin/pkill pppd || : + echo 0 > "$rfkill_wwan"/state + echo 1 > "$rfkill_wlan"/state + ;; + wwan) + name=''${2-o2} + echo 0 > "$rfkill_wlan"/state + echo 1 > "$rfkill_wwan"/state + ${pkgs.ppp}/bin/pppd call "$name" updetach + ;; + *) + echo "$0: error: bad arguments: $*" >&2 + exit 1 + esac + '') + (pkgs.writeDashBin "modem-send" '' + # usage: modem-send ATCOMMAND + set -efu + tty=${mylib.shell.escape cfg.ttys.com} + exec <"$tty" + printf '%s\r\n' "$1" >"$tty" + ${pkgs.gnused}/bin/sed -E ' + /^OK\r?$/q + /^ERROR\r?$/q + ' + '') + ]; +} diff --git a/configs/pulse.nix b/configs/pulse.nix new file mode 100644 index 0000000..17c203c --- /dev/null +++ b/configs/pulse.nix @@ -0,0 +1,119 @@ +{ config, lib, mylib, pkgs, ... }: let + pkg = pkgs.pulseaudio; + runDir = "/run/pulse"; + + pkgs_i686 = pkgs.pkgsi686Linux; + + support32Bit = + pkgs.stdenv.isx86_64 && + pkgs_i686.alsaLib != null && + pkgs_i686.libpulseaudio != null; + + alsaConf = pkgs.writeText "asound.conf" '' + ctl_type.pulse { + libs.native = ${pkgs.alsaPlugins}/lib/alsa-lib/libasound_module_ctl_pulse.so; + ${lib.optionalString support32Bit + "libs.32Bit = ${pkgs_i686.alsaPlugins}/lib/alsa-lib/libasound_module_ctl_pulse.so;"} + } + pcm_type.pulse { + libs.native = ${pkgs.alsaPlugins}/lib/alsa-lib/libasound_module_pcm_pulse.so; + ${lib.optionalString support32Bit + "libs.32Bit = ${pkgs_i686.alsaPlugins}/lib/alsa-lib/libasound_module_pcm_pulse.so;"} + } + ctl.!default { + type pulse + } + pcm.!default { + type pulse + } + ''; + + clientConf = pkgs.writeText "client.conf" '' + autospawn=no + default-server = unix:${runDir}/socket + ''; + + configFile = pkgs.writeText "default.pa" '' + .include ${pkg}/etc/pulse/default.pa + load-module ${toString [ + "module-native-protocol-unix" + "auth-anonymous=1" + "socket=${runDir}/socket" + ]} + ${lib.optionalString (config.krebs.build.host.name == "au") '' + load-module ${toString [ + "module-native-protocol-tcp" + "auth-ip-acl=127.0.0.1;10.23.1.0/24" + ]} + ''} + ${lib.optionalString (config.krebs.build.host.name != "au") '' + load-module ${toString [ + "module-tunnel-sink-new" + "server=au.hkw" + "sink_name=au" + "channels=2" + "rate=44100" + ]} + ''} + ''; +in + +{ + environment = { + etc = { + "asound.conf".source = alsaConf; + # XXX mkForce is not strong enough (and neither is mkOverride) to create + # /etc/pulse/client.conf, see pulseaudio-hack below for a solution. + #"pulse/client.conf" = mkForce { source = clientConf; }; + #"pulse/client.conf".source = mkForce clientConf; + "pulse/default.pa".source = configFile; + }; + systemPackages = [ + pkg + ] ++ lib.optionals config.services.xserver.enable [ + pkgs.pavucontrol + ]; + }; + + hardware.pulseaudio = { + inherit support32Bit; + }; + + # Allow PulseAudio to get realtime priority using rtkit. + security.rtkit.enable = true; + + system.activationScripts.pulseaudio-hack = '' + ln -fns ${clientConf} /etc/pulse/client.conf + ''; + + systemd.services.pulse = { + wantedBy = [ "sound.target" ]; + before = [ "sound.target" ]; + environment = { + PULSE_RUNTIME_PATH = "${runDir}/home"; + }; + serviceConfig = { + ExecStart = "${pkg}/bin/pulseaudio --exit-idle-time=-1"; + ExecStartPre = pkgs.writeDash "pulse-start" '' + install -o pulse -g pulse -m 0750 -d ${runDir} + install -o pulse -g pulse -m 0700 -d ${runDir}/home + ''; + PermissionsStartOnly = "true"; + User = "pulse"; + }; + }; + + # TODO assert that pulse is the only user with "audio" in group/extraGroups + # otherwise the audio device can be hijacked while the pulse service restarts + # (e.g. when mpv is running) and then the service will fail. + users = { + groups.pulse.gid = config.users.users.pulse.uid; + users.pulse = { + uid = mylib.genid_uint31 "pulse"; + group = "pulse"; + extraGroups = [ "audio" ]; + home = "${runDir}/home"; + isSystemUser = true; + }; + }; +} diff --git a/configs/repo-sync/wiki.nix b/configs/repo-sync/wiki.nix new file mode 100644 index 0000000..94f7e80 --- /dev/null +++ b/configs/repo-sync/wiki.nix @@ -0,0 +1,39 @@ +{ config, lib, mylib, pkgs, ... }: { + krebs.repo-sync.enable = true; + krebs.repo-sync.repos.wiki.branches.hotdog = { + origin.url = "http://cgit.hotdog.r/wiki"; + mirror.url = "git@${config.krebs.build.host.name}.r:wiki"; + }; + krebs.git.repos.wiki = { + public = true; + name = "wiki"; + cgit.desc = toString [ + "mirror of" + config.krebs.repo-sync.repos.wiki.branches.hotdog.origin.url + ]; + cgit.section = "7. mirrors"; + hooks.post-receive = /* sh */ '' + ${pkgs.git-hooks.irc-announce { + channel = "#xxx"; + nick = config.krebs.build.host.name; + server = "irc.r"; + }} + ${pkgs.cgit-clear-cache.override { + inherit (config.krebs.git.cgit.settings) cache-root; + }}/bin/cgit-clear-cache + ''; + }; + krebs.git.rules = lib.singleton { + user = lib.singleton config.krebs.users.repo-sync; + repo = lib.singleton config.krebs.git.repos.wiki; + perm = mylib.git.push "refs/*" [ + mylib.git.create + mylib.git.delete + mylib.git.merge + mylib.git.non-fast-forward + ]; + }; + krebs.users.${config.krebs.repo-sync.user.name}.pubkey = { + ni = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINK9U0Ob9/O0kxg3trhZY/vDnbqfN+R5cASGiClRr4IM"; + }.${config.krebs.build.host.name}; +} diff --git a/configs/retiolum.nix b/configs/retiolum.nix new file mode 100644 index 0000000..632cc97 --- /dev/null +++ b/configs/retiolum.nix @@ -0,0 +1,26 @@ +{ config, lib, mylib, pkgs, ... }: { + krebs.tinc.retiolum = { + enable = true; + connectTo = builtins.filter (mylib.ne config.krebs.build.host.name) [ + "ni" + "prism" + "eve" + ]; + extraConfig = '' + LocalDiscovery = yes + ''; + tincPackage = pkgs.tinc_pre; + tincUp = lib.mkIf config.systemd.network.enable ""; + }; + systemd.network.networks.retiolum = { + matchConfig.Name = "retiolum"; + address = let + inherit (config.krebs.build.host.nets.retiolum) ip4 ip6; + in [ + "${ip4.addr}/${toString ip4.prefixLength}" + "${ip6.addr}/${toString ip6.prefixLength}" + ]; + }; + tv.iptables.input-internet-accept-tcp = [ "tinc" ]; + tv.iptables.input-internet-accept-udp = [ "tinc" ]; +} diff --git a/configs/smartd.nix b/configs/smartd.nix new file mode 100644 index 0000000..9c4d8b2 --- /dev/null +++ b/configs/smartd.nix @@ -0,0 +1,17 @@ +{ config, pkgs, ... }: + +{ + services.smartd = { + enable = true; + devices = [ + { + device = "DEVICESCAN"; + options = toString [ + "-a" + "-m ${config.krebs.users.tv.mail}" + "-s (O/../.././09|S/../.././04|L/../../6/05)" + ]; + } + ]; + }; +} diff --git a/configs/ssh.nix b/configs/ssh.nix new file mode 100644 index 0000000..0dda6e5 --- /dev/null +++ b/configs/ssh.nix @@ -0,0 +1,21 @@ +{ config, lib, pkgs, ... }: { + # Override NixOS's "Allow DSA keys for now." + environment.etc."ssh/ssh_config".text = lib.mkForce '' + AddressFamily ${if config.networking.enableIPv6 then "any" else "inet"} + + ${lib.optionalString config.programs.ssh.setXAuthLocation '' + XAuthLocation ${pkgs.xorg.xauth}/bin/xauth + ''} + + ForwardX11 ${if config.programs.ssh.forwardX11 then "yes" else "no"} + + ${config.programs.ssh.extraConfig} + ''; + + programs.ssh = { + extraConfig = '' + Us