diff options
Diffstat (limited to 'old')
114 files changed, 8237 insertions, 0 deletions
diff --git a/old/Makefile b/old/Makefile new file mode 100644 index 000000000..bef7727ce --- /dev/null +++ b/old/Makefile @@ -0,0 +1,48 @@ +all:;@exit 23 + +tv-cluster := cd mkdir nomic rmdir wu +deploy-cd:; ./deploy cd +deploy-mkdir:; ./deploy mkdir +deploy-nomic:; ./deploy nomic root@nomic-local +deploy-rmdir:; ./deploy rmdir +deploy-wu:; ./deploy wu root@localhost + +ifndef cluster +cluster := $(LOGNAME) +endif +hosts := $($(cluster)-cluster) +ifeq ($(hosts),) +$(error bad cluster: $(cluster)) +else +.ONESHELL: + +.PHONY: deploy $(addprefix deploy-,$(hosts)) +deploy: + exec parallel \ + -j 0 \ + --no-notice \ + --rpl '{u} s/^.* deploy-(.*)/\1/' \ + --tagstring '{u}' \ + --line-buffer \ + $(MAKE) deploy-{} ::: $(hosts) + +.PHONY: rotate-consul-encrypt +rotate-consul-encrypt: + umask 0377 + mkencrypt() { dd status=none if=/dev/random bs=1 count=16 | base64; } + json=$$(printf '{"encrypt":"%s"}\n' $$(mkencrypt)) + cmd=' + f=secrets/{}/rsync/etc/consul/encrypt.json + rm -f "$$f" + echo "$$json" > "$$f" + ' + export json + exec parallel \ + -j 0 \ + --no-notice \ + --rpl '{u} s/^.* deploy-(.*)/\1/' \ + --tagstring '{u}' \ + --line-buffer \ + --quote \ + sh -eufc "$$cmd" ::: $(hosts) +endif diff --git a/old/README.md b/old/README.md new file mode 100644 index 000000000..8a72d2fee --- /dev/null +++ b/old/README.md @@ -0,0 +1,32 @@ + + +# Turn a Cloud at Cost CentOS-7-64bit server into NixOS + +1. Configure the system (`$systemname`) you'd like to install (see Configuration below). +2. Create new server instance (either Custom or cloudpro) using "CentOS-7-64bit". + Note the servername (something like c731445864-cloudpro-388922936). +3. `cac_login=xxx cac_key=yyy ./infest-cac-CentOS-7-64bit.sh servername:$servername $systename` +4. Enjoy. (`ssh root@$systename`) + +# Configuration + +Configure your system in modules/$systemname +See modules/cd/default.nix as an example. + +Notice that modules/$systemname/networking will be autogenerated (but not committed). + +secrets/$systemname/nix/foo can be accessed as `<secrets/foo>` from within the configuration. + +You might want `secrets/$systemname/rsync/etc/tinc/retiolum/rsa_key.priv`. + +You might want `secrets/$systemname/nix/hashedPasswords.nix`, which looks like + +```nix +_: { users.extraUsers.root.hashedPassword = "XXX"; } +``` + +`XXX` can be generated with e.g. + +``` +mkpasswd -m sha-512 -S $(openssl rand -base64 16 | tr -d '+=' | head -c 16) +``` diff --git a/old/bin/copy-secrets b/old/bin/copy-secrets new file mode 100755 index 000000000..f40493599 --- /dev/null +++ b/old/bin/copy-secrets @@ -0,0 +1,69 @@ +#! /bin/sh +# +# copy-secrets system_name target +# +set -euf + +system_name=$1 +target=$2 + +nixos_config=$config_root/modules/$system_name +secrets_nix=$secrets_root/$system_name/nix +secrets_rsync=$secrets_root/$system_name/rsync + +if ! test -e "$secrets_rsync"; then + exit # nothing to do +fi + +# XXX this is ugly +# Notice NIX_PATH used from host +# Notice secrets required to evaluate configuration +NIX_PATH=$NIX_PATH:nixos-config=$PWD/modules/$system_name +NIX_PATH=$NIX_PATH:secrets=$PWD/secrets/$system_name/nix +export NIX_PATH + +case $(nixos-query tv.retiolum.enable 2>/dev/null) in true) + retiolum_secret=$(nixos-query tv.retiolum.privateKeyFile) + retiolum_uid=$(nixos-query users.extraUsers.retiolum-tinc.uid) +esac + +case $(nixos-query services.ejabberd-cd.enable 2>/dev/null) in true) + ejabberd_secret=$(nixos-query services.ejabberd-cd.certFile) + ejabberd_uid=$(nixos-query users.extraUsers.ejabberd.uid) +esac + +case $(nixos-query tv.consul.enable 2>/dev/null) in true) + consul_secret=$(nixos-query tv.consul.encrypt-file) + consul_uid=$(nixos-query users.extraUsers.consul.uid) +esac + +(set -x + rsync \ + --rsync-path="mkdir -p \"$2\" && rsync" \ + -vzrlptD \ + "$secrets_rsync/" \ + "$target:/") + +ssh "$target" -T <<EOF +set -euf + +retiolum_secret=${retiolum_secret-} +retiolum_uid=${retiolum_uid-} +ejabberd_secret=${ejabberd_secret-} +ejabberd_uid=${ejabberd_uid-} +consul_secret=${consul_secret-} +consul_uid=${consul_uid-} + +if test -n "\$retiolum_secret"; then + chown -v "\$retiolum_uid:0" "\$retiolum_secret" +fi + +if test -n "\$ejabberd_secret"; then + chown -v "\$ejabberd_uid:0" "\$ejabberd_secret" +fi + +if test -n "\$consul_secret"; then + chown -v "\$consul_uid:0" "\$consul_secret" +fi + +EOF diff --git a/old/bin/genid b/old/bin/genid new file mode 100755 index 000000000..8e2240746 --- /dev/null +++ b/old/bin/genid @@ -0,0 +1,11 @@ +#! /bin/sh +# usage: genid NAME +set -euf +name=$1 +hash=$(printf %s "$name" | sha1sum | cut -d\ -f1 | tr a-f A-F) +echo " + min=2^16 # bigger than nobody and nogroup, see <nixos/modules/misc/ids.nix> + max=2^32 # see 2^(8*sizeof(uid_t)) + ibase=16 + ($hash + min) % max +" | bc diff --git a/old/bin/netmask-to-prefix b/old/bin/netmask-to-prefix new file mode 100755 index 000000000..1c4dbeb28 --- /dev/null +++ b/old/bin/netmask-to-prefix @@ -0,0 +1,12 @@ +#! /bin/sh +set -euf + +netmask=$1 + +binaryNetmask=$(echo $1 | sed 's/^/obase=2;/;s/\./;/g' | bc | tr -d \\n) +binaryPrefix=$(echo $binaryNetmask | sed -n 's/^\(1*\)0*$/\1/p') +if ! echo $binaryPrefix | grep -q .; then + echo $0: bad netmask: $netmask >&2 + exit 4 +fi +printf %s $binaryPrefix | tr -d 0 | wc -c diff --git a/old/bin/nixos-query b/old/bin/nixos-query new file mode 100755 index 000000000..1111aead5 --- /dev/null +++ b/old/bin/nixos-query @@ -0,0 +1,4 @@ +#! /bin/sh +set -euf +result=$(nix-instantiate -A config."$1" --eval --json '<nixos>') +echo $result | jq -r . diff --git a/old/bin/urlencode b/old/bin/urlencode new file mode 100755 index 000000000..02ca03075 --- /dev/null +++ b/old/bin/urlencode @@ -0,0 +1,35 @@ +#! /bin/sh +set -euf +exec sed ' + s/%/%25/g + s/ /%20/g + s/!/%21/g + s/"/%22/g + s/#/%23/g + s/\$/%24/g + s/\&/%26/g + s/'\''/%27/g + s/(/%28/g + s/)/%29/g + s/\*/%2a/g + s/+/%2b/g + s/,/%2c/g + s/-/%2d/g + s/\./%2e/g + s/\//%2f/g + s/:/%3a/g + s/;/%3b/g + s//%3e/g + s/?/%3f/g + s/@/%40/g + s/\[/%5b/g + s/\\/%5c/g + s/\]/%5d/g + s/\^/%5e/g + s/_/%5f/g + s/`/%60/g + s/{/%7b/g + s/|/%7c/g + s/}/%7d/g + s/~/%7e/g +' diff --git a/old/cac b/old/cac new file mode 100755 index 000000000..fb816b997 --- /dev/null +++ b/old/cac @@ -0,0 +1,337 @@ +#! /bin/sh +set -euf + +PATH=$PWD/bin:$PATH +export PATH + +cac_listservers_cache=$PWD/tmp/cac_listservers_cache.json + + +cac() { + __cac_cli__command=$1 + shift + __cac_cli__"$__cac_cli__command" "$@" +} + +# WIP +__cac_cli__help() {( + exec sed < "$0" -n ' + s/^__cac_cli__\([^(]\+\)().*/\1/p + ' +)} + +# usage: console +__cac_cli__console() {( + server=$(__cac_cli__getserver "$1") + sid=$(echo $server | jq -r .sid) + # TODO check reply status == ok + _cac_post_api_v1 console sid="$sid" | jq -r .console +)} + +__cac_cli__listservers() { + jq -r . $cac_listservers_cache +} + +__cac_cli__update() {( + umask 0077 + servers=$(_cac_listservers) + echo $servers > $cac_listservers_cache.tmp + mv $cac_listservers_cache.tmp $cac_listservers_cache +)} + +__cac_cli__getserver() {( + + case $1 in + *:*) + k=${1%%:*} + v=${1#*:} + ;; + *) + k=label + v=${1#*:} + ;; + esac + + if result=$(jq \ + -e \ + --arg k "$k" \ + --arg v "$v" \ + ' + map(select(.[$k]==$v)) | + if (. | length) == 1 then + .[0] + else + null + end + ' \ + $cac_listservers_cache); then + echo $result | jq -r . + else + echo "$0 getserver $k:$v => not unique server found" >&2 + exit 23 + fi +)} + +__cac_cli__generatenetworking() {( + server=$(__cac_cli__getserver "$1") + + hostname=$(echo $server | jq -r .label) + + address=$(echo $server | jq -r .ip) + gateway=$(echo $server | jq -r .gateway) + nameserver=8.8.8.8 + netmask=$(echo $server | jq -r .netmask) + prefix=$(netmask-to-prefix $netmask) + + #printf '# Generated file: %s generatenetworking %s %s\n' "$0" "$1" "$2" + #printf '# on %s\n' "$(date -Is)" + #printf '\n' + printf '_:\n' + printf '\n' + printf '{\n' + printf ' networking.hostName = "%s";\n' $hostname + printf ' networking.interfaces.enp2s1.ip4 = [\n' + printf ' {\n' + printf ' address = "%s";\n' $address + printf ' prefixLength = %d;\n' $prefix + printf ' }\n' + printf ' ];\n' + printf ' networking.defaultGateway = "%s";\n' $gateway + printf ' networking.nameservers = [\n' + printf ' "%s"\n' $nameserver + printf ' ];\n' + printf '}\n' +)} + +__cac_cli__powerop() {( + server=$(__cac_cli__getserver "$1") + action=$2 + + sid=$(echo $server | jq -r .sid) + + reply=$(_cac_post_api_v1 powerop sid="$sid" action="$action") + + case $(echo $reply | jq -r .status) in + ok) + echo $reply | jq -r . >&2 + __cac_cli__update + ;; + *) + echo bad reply: >&2 + echo $reply | jq -r . >&2 + exit 23 + ;; + esac +)} +__cac_cli__pushconfig() {( + server=$(__cac_cli__getserver "$1") + + prefix=${2-/} + + hostname=$(echo $server | jq -r .label) + + address=$(echo $server | jq -r .ip) + target=root@$address + + RSYNC_RSH='sshpass -e ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null' + SSHPASS=$(echo $server | jq -r .rootpass) + export RSYNC_RSH SSHPASS + + pushgit . $target:$prefix/etc/nixos/ + pushgit hosts $target:$prefix/etc/nixos/hosts/ + pushgit tmp/nixpkgs/$hostname $target:$prefix/etc/nixos/nixpkgs/ + pushdir secrets/$hostname/nix $target:$prefix/etc/nixos/secrets/ + pushdir secrets/$hostname/rsync $target:$prefix/ + echo "_:{imports=[./modules/$hostname];}" \ + | $RSYNC_RSH "$target" tee "$prefix/etc/nixos/configuration.nix" \ + > /dev/null + + ## TODO chmod and chown secrets +)} + +__cac_cli__setlabel() {( + server=$(__cac_cli__getserver "$1") + label=$2 + + sid=$(echo $server | jq -r .sid) + + reply=$(_cac_post_api_v1 renameserver sid="$sid" name="$label") + + case $(echo $reply | jq -r .status) in + ok) + echo $reply | jq -r . >&2 + __cac_cli__update + ;; + *) + echo bad reply: >&2 + echo $reply | jq -r . >&2 + exit 23 + ;; + esac +)} + +__cac_cli__setmode() {( + server=$(__cac_cli__getserver "$1") + mode=$2 + + sid=$(echo $server | jq -r .sid) + + reply=$(_cac_post_api_v1 runmode sid="$sid" mode="$mode") + + case $(echo $reply | jq -r .status) in + ok) + echo $reply | jq -r . >&2 + __cac_cli__update + ;; + *) + echo bad reply: >&2 + echo $reply | jq -r . + exit 23 + ;; + esac +)} + +__cac_cli__ssh() {( + server=$(__cac_cli__getserver "$1") + shift + + address=$(echo $server | jq -r .ip) + target=root@$address + + SSHPASS=$(echo $server | jq -r .rootpass) + export SSHPASS + + exec sshpass -e ssh \ + -S none \ + -o StrictHostKeyChecking=no \ + -o UserKnownHostsFile=/dev/null \ + $target \ + "$@" +)} + + +# usage: ./cac waitstatus mode:Safe 'Powered On' +# blocks until server has specfied state +__cac_cli__waitstatus() { + server=$(__cac_cli__getserver "$1") + status=$(echo $server | jq -r .status) + + case $status in + $2) + return + ;; + esac + + echo "$(date -Is) Waiting for status: $2; current status: $status ..." >&2 + + __cac_cli__waitforcacheupdate __cac_cli__waitstatus "$@" +} + + +# XXX for __cac_cli__waitforcacheupdate and __cac_cli__poll cache means $cac_listservers_cache + +# blocks until cache has been updated then executes "$@" +__cac_cli__waitforcacheupdate() { + case $(inotifywait --format %f -q -e moved_to $(dirname $cac_listservers_cache)) in + $(basename $cac_listservers_cache)) "$@";; + *) __cac_cli__waitforcacheupdate "$@";; + esac +} + +# usage: with cac ./cac poll 60s +# continuously update cache, sleeping at least $1 between updates +__cac_cli__poll() { + __cac_cli__update + t=${1-1m} + echo "$(date -Is) cache updated; sleeping $t ..." >&2 + sleep "$t" + __cac_cli__poll "$@" +} + + +_cac_listservers() {( + servers=$(_cac_get_api_v1 listservers) + status=$(echo $servers | jq -r .status) + + if [ "$status" = ok ]; then + echo "$servers" | jq -r .data + else + echo "cac_listservers: bad listservers status: $status" >&2 + exit 1 + fi +)} + + + + +# rsyncfiles : lines filename |> local-dir x rsync-target -> ? |> ? +rsyncfiles() {( + set -x + rsync \ + --rsync-path="mkdir -p \"$2\" && rsync" \ + -vzrlptD \ + --files-from=- \ + "$1"/ \ + "$2" +)} + + +# gitfiles : git-work-tree -> lines filename +gitfiles() { + git -C "$1" archive --format=tar HEAD | tar t | sed '/\/$/d' +} + +# pushgit : git-work-tree x rsync-target -> ? +pushgit() { + gitfiles "$1" | rsyncfiles "$1" "$2" +} + +# dirfiles : local-dir -> lines filename +dirfiles() {( + cd "$1" + find . -type f | sed 's/^\.\///' +)} + +# pushdir : local-dir x rsync-target -> ? +pushdir() { + dirfiles "$1" | rsyncfiles "$1" "$2" +} + + + + + + +_cac_get_api_v1() { + _cac_curl_api_v1 -G "$@" +} + +_cac_post_api_v1() { + _cac_curl_api_v1 -XPOST "$@" +} + +_cac_curl_api_v1() { + _cac_exec curl -sS "$1" "https://panel.cloudatcost.com/api/v1/$2.php" $( + shift 2 + set -- "$@" login="$cac_login" key="$cac_key" + for arg; do + echo -d $(printf '%s' "$arg" | urlencode) + done + ) +} + +_cac_exec() { + if test -z "${cac_via-}"; then + env -- "$@" + else + ssh -q "$cac_via" -t "$@" + fi +} + + + + + +case ${run-true} in + true) cac "$@";; +esac diff --git a/old/certs/zalora-ca.crt b/old/certs/zalora-ca.crt new file mode 100644 index 000000000..12cdf8fc6 --- /dev/null +++ b/old/certs/zalora-ca.crt @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIID7zCCAtegAwIBAgIJAPImpJwMgGmhMA0GCSqGSIb3DQEBBQUAMIGNMQswCQYD +VQQGEwJTRzESMBAGA1UECAwJU2luZ2Fwb3JlMQ8wDQYDVQQKDAZaYWxvcmExCzAJ +BgNVBAsMAklUMSUwIwYDVQQDDBxaYWxvcmEgQ2VydGlmaWNhdGUgQXV0aG9yaXR5 +MSUwIwYJKoZIhvcNAQkBFhZpdC1zZXJ2aWNlc0B6YWxvcmEuY29tMB4XDTE0MDkx +ODIxNDY0N1oXDTI0MDkxNTIxNDY0N1owgY0xCzAJBgNVBAYTAlNHMRIwEAYDVQQI +DAlTaW5nYXBvcmUxDzANBgNVBAoMBlphbG9yYTELMAkGA1UECwwCSVQxJTAjBgNV +BAMMHFphbG9yYSBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxJTAjBgkqhkiG9w0BCQEW +Fml0LXNlcnZpY2VzQHphbG9yYS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +ggEKAoIBAQDi48Tkh6XuS2gdE1+gsPPQjTI8Q2wbXqZGTHnyAZx75btOIUZHeHJm +Fvu8erAD+vtx1nD1GOG30uvHFk9Of2mFY1fxw0R1LthJHSLFJU1/GjFSggHWkaI3 +HBSmeALjss/XHG3EtShLo8SHBc/+B8ehqj1JqcXF8q50JtfTQ+zlf+k26ke2S5Xo +OdHLxjlNaPwj+TgJI1DHqs/bTapaPHPKk5+jFQzAcMmq0bygzpQTHCvvKqcoXaJk +UgDBQnVsJUtwfObrM1TKu2TOXUhqgfnnflYf2sz5Sr30QlkrHP+PM3BRLB+6FXhr +UlKKVcAcIwrBo0aJ5Sd0fv39GwV1XCWVAgMBAAGjUDBOMB0GA1UdDgQWBBQFftMH +5/dc0pUNDqLbVQ8gm7+I5TAfBgNVHSMEGDAWgBQFftMH5/dc0pUNDqLbVQ8gm7+I +5TAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQC2aSKJ15v5OI7Zj/HQ +lW+iY9STBPJi9lgOjaGrNaPX0IuhJLkeKDntmzjvpGwvcylHMp6Im02svTymteNN +38s8A0aStnmW4ysGT853H7L7Jxzf7J2vrUF0Dj4QkZ07Gp3vAgKnWVcqz36Xr0Se +DEqrKMl/6fq3Ygl35fZXP1kb6t/wP6qx69bnENH6ksHFpZapWYssKNZO9yiB8+Eq +ngB22X/ycMmAqOnNQDzw1JBw7LzdXypCG75UKEK6kbnUy2yPADdHpH8v9qcRa1U9 +vEmUTJs6i1CpPO+2frPJ8A8QIp61nNxe7xJ1SnNVtwk9d6SRet6YGySvgG748Wjw +GwWx +-----END CERTIFICATE----- diff --git a/old/default.nix b/old/default.nix new file mode 100644 index 000000000..841534824 --- /dev/null +++ b/old/default.nix @@ -0,0 +1,151 @@ +{ system-name +, rsync-target ? null +, deploy-target ? null +}: + +# TODO assert that only one of rsync-target or deploy-target is not null + +with builtins; +assert (typeOf system-name == "string"); +with import <nixpkgs/lib>; +let + paths-file = toPath "${dirOf __curPos.file}/modules/${system-name}/paths.nix"; + + paths = import paths-file; + + prefetch.file = '' + echo "$prefetch_in_url" + ''; + + prefetch.git = '' + ${concatMapStringsSep "\n" (attr-name: '' + case ''${prefetch_in_${escapeShellArg attr-name}-?} in \?) + printf '%s: %s: missing attribute: %s' \ + ${escapeShellArg paths-file} \ + "$prefetch_name" \ + ${escapeShellArg attr-name} \ + >&2 + return 1 + esac + '') [ "rev" "url" "cache" ]} + + git_rev=$prefetch_in_rev + git_url=$prefetch_in_url + + # cache_dir points to a (maybe non-existent) directory, where a shared cache of + # the repository should be maintained. The shared cache is used to create + # multiple working trees of the repository. + cache_dir=$prefetch_in_cache/$(echo "$git_url" | urlencode) + cache_git() { + git --git-dir="$cache_dir" "$@" + } + + # work_dir points to a (maybe non-existent) directory, where a specific + # revision of the repository is checked out. + # XXX this is probably a bad idea if git_rev is not a commit + work_dir=$cache_dir-$(cache_git rev-parse --verify "$git_rev" | urlencode) + work_git() { + git -C "$work_dir" "$@" + } + + is_up_to_date() { + test -d "$cache_dir" && + test -d "$work_dir" && + test "$(cache_git rev-parse --verify "$git_rev")" = "$git_rev" && + test "$(work_git rev-parse --verify HEAD)" = "$git_rev" + } + + # Notice how the remote name "origin" has been chosen arbitrarily, but must be + # kept in sync with the default value of nixpkgs.rev. + if ! is_up_to_date; then + if ! test -d "$cache_dir"; then + mkdir -p "$cache_dir" + cache_git init --bare + fi + if ! cache_git_url=$(cache_git config remote.origin.url); then + cache_git remote add origin "$git_url" + elif test "$cache_git_url" != "$git_url"; then + cache_git remote set-url origin "$git_url" + fi + cache_git fetch origin + if ! test -d "$work_dir"; then + git clone -n --shared "$cache_dir" "$work_dir" + fi + commit_name=$(cache_git rev-parse --verify "$git_rev") + work_git checkout "$commit_name" -- "$(readlink -f "$work_dir")" + work_git checkout -q "$commit_name" + work_git submodule init + work_git submodule update + fi + work_git clean -dxf + + echo "$work_dir" + ''; + + + f = pkg-name: pkg-spec: + let + types = attrNames pkg-spec; + type = elemAt types 0; + in + assert (length types == 1); # there can be only one source type + '' + out=$(${concatStringsSep " \\\n" (mapAttrsToList (k: v: + "prefetch_in_${escapeShellArg k}=${escapeShellArg (toString v)}") pkg-spec.${type})} \ + prefetch_name=${escapeShellArg pkg-name} \ + __prefetch_${escapeShellArg type}) + printf '%s=%s\n' \ + ${escapeShellArg pkg-name} \ + "$out" + ''; +in +'' +#! /bin/sh +set -euf + +PATH=${toString ./.}/bin:$PATH +export PATH + +__prefetch_file() { +${prefetch.file} +} +__prefetch_git() { +${prefetch.git} +} + +# TODO make sure x contains only sane chars +x=$(${concatStrings (mapAttrsToList f paths)}) + +${optionalString (rsync-target != null) '' + proot $(echo "$x" | sed -n 's@^\([^=]\+\)=\(.*\)@-b \2:/shitment/\1@p') \ + rsync --delete --delete-excluded \ + --filter='- /*/.git' \ + --rsync-path='mkdir -p -m 0700 /shitment/ && rsync' \ + -vaz \ + --no-owner \ + --no-group \ + '/shitment/' \ + ${escapeShellArg rsync-target} +''} + + +${optionalString (deploy-target != null) '' + system_path=$(proot $(echo "$x" | sed -n 's@^\([^=]\+\)=\(.*\)@-b \2:/shitment/\1@p') \ + env \ + NIX_PATH=/shitment \ + NIXOS_CONFIG=/shitment/modules/${escapeShellArg system-name} \ + nix-build -A system --no-out-link '<nixpkgs/nixos>') + + system_name=${escapeShellArg system-name} + target=${escapeShellArg deploy-target} + + nix-copy-closure --gzip --to "$target" "$system_path" + + secrets_root=${toString ./.}/secrets \ + config_root=${toString ./.} \ + copy-secrets "$system_name" "$target" + + ssh ''${NIX_SSHOPTS-} "$target" "$system_path/bin/switch-to-configuration" switch +''} + +'' diff --git a/old/deploy b/old/deploy new file mode 100755 index 000000000..a9dbf45e0 --- /dev/null +++ b/old/deploy @@ -0,0 +1,15 @@ +#! /bin/sh +# +# usage: ./deploy system_name [target] +# +set -euf + +system_name=$1 +target=${2-root@$system_name} + +nix-instantiate \ + --argstr system-name "$system_name" \ + --argstr deploy-target "$target" \ + --eval --json . \ + | jq -r . \ + | sh diff --git a/old/infest-cac-CentOS-7-64bit.sh b/old/infest-cac-CentOS-7-64bit.sh new file mode 100755 index 000000000..1e96e0e20 --- /dev/null +++ b/old/infest-cac-CentOS-7-64bit.sh @@ -0,0 +1,51 @@ +#! /bin/sh +set -xeuf + +serverspec=$1 +systemname=$2 + +( + PATH=$PWD/bin:$PATH + export PATH + + # Notice NIX_PATH used from host + # Notice secrets required to evaluate configuration + NIX_PATH=$NIX_PATH:nixos-config=$PWD/modules/$systemname + NIX_PATH=$NIX_PATH:secrets=$PWD/secrets/$systemname/nix + export NIX_PATH + + case $(nixos-query nixpkgs.dirty) in true) + echo "$0: cannot use nixpkgs.dirty" >&2 # b/c ./cac pushconfig + exit -1 + esac + + prefetch nixpkgs tmp/nixpkgs/$systemname +) + +./cac poll 10s 2>/dev/null & +pollpid=$! +trap "kill $pollpid; trap - EXIT" EXIT + +./cac waitstatus $serverspec 'Powered On' + +# TODO don't set label/mode if they're already good +./cac setlabel $serverspec $systemname +./cac setmode $systemname normal +./cac generatenetworking $systemname > modules/$systemname/networking.nix + +cat infest.d/cac-CentOS-7-64bit/prepare.sh | ./cac ssh $systemname \ + nix_url=https://nixos.org/releases/nix/nix-1.9/nix-1.9-x86_64-linux.tar.bz2 \ + nix_sha256=5c76611c631e79aef5faf3db2d253237998bbee0f61fa093f925fa32203ae32b \ + /bin/sh + +./cac pushconfig $systemname /mnt + +# This needs to be run twice because (at least): +# Initialized empty Git repository in /var/lib/git/$reponame +# chown: invalid user: 'git:nogroup' +cat infest.d/nixos-install.sh | ./cac ssh $systemname || : +cat infest.d/nixos-install.sh | ./cac ssh $systemname + +cat infest.d/cac-CentOS-7-64bit/finalize.sh | ./cac ssh $systemname + +./cac powerop $systemname reset diff --git a/old/infest.d/cac-CentOS-7-64bit/finalize.sh b/old/infest.d/cac-CentOS-7-64bit/finalize.sh new file mode 100644 index 000000000..b70276b33 --- /dev/null +++ b/old/infest.d/cac-CentOS-7-64bit/finalize.sh @@ -0,0 +1,66 @@ +#! /bin/sh +set -eu +{ + umount /mnt2 + umount /mnt/nix + umount /mnt/boot + umount /mnt + umount /boot + + PATH=$(for i in /nix/store/*coreutils*/bin; do :; done; echo $i) + export PATH + + mkdir /oldshit + + mv /bin /oldshit/ + mv /newshit/bin / + + # TODO ensure /boot is empty + rmdir /newshit/boot + + # skip /dev + rmdir /newshit/dev + + mv /etc /oldshit/ + mv /newshit/etc / + + # TODO ensure /home is empty + rmdir /newshit/home + + # skip /nix (it's already there) + rmdir /newshit/nix + + # skip /proc + rmdir /newshit/proc + + # skip /run + rmdir /newshit/run + + # skip /sys + rmdir /newshit/sys + + # skip /tmp + # TODO rmdir /newshit/tmp + + mv /usr /oldshit/ + mv /newshit/usr / + + mv /var /oldshit/ + mv /newshit/var / + + mv /root /oldshit/ + mv /newshit/root / + + mv /lib /oldshit/ + mv /lib64 /oldshit/ + mv /sbin /oldshit/ + mv /mnt2 /oldshit/ + mv /srv /oldshit/ + mv /opt /oldshit/ + + + mv /newshit /root/ # TODO this one shoult be empty + mv /oldshit /root/ + + sync +} diff --git a/old/infest.d/cac-CentOS-7-64bit/prepare.sh b/old/infest.d/cac-CentOS-7-64bit/prepare.sh new file mode 100644 index 000000000..f932e9c30 --- /dev/null +++ b/old/infest.d/cac-CentOS-7-64bit/prepare.sh @@ -0,0 +1,104 @@ +#! /bin/sh +set -euf + +: $nix_url +: $nix_sha256 + +{ + # + # prepare host + # + + type bzip2 2>/dev/null || yum install -y bzip2 + type rsync 2>/dev/null || yum install -y rsync + + if ! getent group nixbld >/dev/null; then + groupadd -g 30000 -r nixbld + fi + for i in `seq 1 10`; do + if ! getent passwd nixbld$i 2>/dev/null; then + useradd \ + -c "CentOS Nix build user $i" \ + -d /var/empty \ + -g 30000 \ + -G 30000 \ + -l \ + -M \ + -s /sbin/nologin \ + -u $(expr 30000 + $i) \ + nixbld$i + rm -f /var/spool/mail/nixbld$i + fi + done + + # generate fake sudo because + # sudo: sorry, you must have a tty to run sudo + mkdir -p bin + printf '#! /bin/sh\nexec env "$@"\n' > bin/sudo + chmod +x bin/sudo + + PATH=$PWD/bin:$PATH + export PATH + + # install nix on host (cf. https://nixos.org/nix/install) + if ! test -e /root/.nix-profile/etc/profile.d/nix.sh; then + ( + verify() { + echo $nix_sha256 $(basename $nix_url) | sha256sum -c + } + if ! verify; then + curl -C - -O "$nix_url" + verify + fi + ) + tar jxf $(basename $nix_url) + $(basename $nix_url .tar.bz2)/install + fi + + MANPATH=/var/empty . /root/.nix-profile/etc/profile.d/nix.sh + + if ! type nixos-install 2>/dev/null; then + nixpkgs_expr='import <nixpkgs> { system = builtins.currentSystem; }' + nixpkgs_path=$(find /nix/store -mindepth 1 -maxdepth 1 -name *-nixpkgs-* -type d) + nix-env \ + --arg config "{ nix.package = ($nixpkgs_expr).nix; }" \ + --arg pkgs "$nixpkgs_expr" \ + --arg modulesPath 'throw "no modulesPath"' \ + -f $nixpkgs_path/nixpkgs/nixos/modules/installer/tools/tools.nix \ + -iA config.system.build.nixos-install + fi + + # + # mount install directory + # + + if ! mount | grep -Fq '/dev/mapper/centos-root on /mnt type xfs'; then + mkdir -p /newshit + mount --bind /newshit /mnt + fi + + if ! mount | grep -Fq '/dev/sda1 on /mnt/boot type xfs'; then + mkdir -p /mnt/boot + mount /dev/sda1 /mnt/boot + fi + + if ! mount | grep -Fq '/dev/mapper/centos-root on /mnt/nix type xfs'; then + mkdir -p /mnt/nix + mount --bind /nix /mnt/nix + fi + + mount | grep 'on /mnt\>' >&2 + + # + # prepare install directory + # + # XXX This should be done by (?) + # remote_dir=/mnt ./cac pushconfig servername:c731445864-cloudpro-134581046 rmdir + + mkdir -p /mnt/etc/nixos + mkdir -m 0555 -p /mnt/var/empty + + # add eye candy + address=$(echo $SSH_CONNECTION | awk '{print$3}') + echo 'PS1='\''\[\e[1;31m\]\u@'"$address"'\[\e[m\] \[\e[1;32m\]\w\[\e[m\] '\' > .bashrc +} diff --git a/old/infest.d/nixos-install.sh b/old/infest.d/nixos-install.sh new file mode 100644 index 000000000..df01a3468 --- /dev/null +++ b/old/infest.d/nixos-install.sh @@ -0,0 +1,8 @@ +#! /bin/sh +# usage: cat infest-nixos-install.sh | ./cac ssh ... +set -euf +nixos-install \ + -I secrets=/etc/nixos/secrets \ + -I retiolum-hosts=/etc/nixos/hosts \ + -I pubkeys=/etc/nixos/pubkeys \ + -I nixpkgs=/etc/nixos/nixpkgs diff --git a/old/lib/default.nix b/old/lib/default.nix new file mode 100644 index 000000000..164a6a1aa --- /dev/null +++ b/old/lib/default.nix @@ -0,0 +1,62 @@ +{ lib, pkgs, ... }: + +with builtins; + +let + inherit (lib) mapAttrs stringAsChars; +in + +rec { + git = import ./git.nix { + lib = lib // { + inherit addNames; + }; + inherit pkgs; + }; + + addName = name: set: + set // { inherit name; }; + + addNames = mapAttrs addName; + + + # "7.4.335" -> "74" + majmin = with lib; x : concatStrings (take 2 (splitString "." x)); + + + concat = xs : + if xs == [] + then "" + else head xs + concat (tail xs) + ; + + flip = f : x : y : f y x; + + # isSuffixOf :: String -> String -> Bool + isSuffixOf = + s : xs : + let + sn = stringLength s; + xsn = stringLength xs; + in + xsn >= sn && substring (xsn - sn) sn xs == s ; + + removeSuffix = + s : xs : substring 0 (stringLength xs - stringLength s) xs; + + # setMap :: (String -> a -> b) -> Set String a -> [b] + #setMap = f: xs: map (k : f k (getAttr k xs)) (attrNames xs); + + # setToList :: Set k a -> [a] + #setToList = setMap (_: v: v); + + shell-escape = + let + isSafeChar = c: match "[-./0-9_a-zA-Z]" c != null; + in + stringAsChars (c: + if isSafeChar c then c + else if c == "\n" then "'\n'" + else "\\${c}"); + +} diff --git a/old/lib/git.nix b/old/lib/git.nix new file mode 100644 index 000000000..8dc176114 --- /dev/null +++ b/old/lib/git.nix @@ -0,0 +1,181 @@ +{ lib, pkgs, ... }: + +let + inherit (lib) addNames escapeShellArg makeSearchPath; + + commands = addNames { + git-receive-pack = {}; + git-upload-pack = {}; + }; + + receive-modes = addNames { + fast-forward = {}; + non-fast-forward = {}; + create = {}; + delete = {}; + merge = {}; # TODO implement in git.nix + }; + + permissions = { + fetch = { + allow-commands = [ + commands.git-upload-pack + ]; + }; + + push = ref: extra-modes: { + allow-commands = [ + commands.git-receive-pack + commands.git-upload-pack + ]; + allow-receive-ref = ref; + allow-receive-modes = [ receive-modes.fast-forward ] ++ extra-modes; + }; + }; + + refs = { + master = "refs/heads/master"; + all-heads = "refs/heads/*"; + }; + + irc-announce-script = pkgs.writeScript "irc-announce-script" '' + #! /bin/sh + set -euf + + export PATH=${makeSearchPath "bin" (with pkgs; [ + coreutils + gawk + gnused + netcat + nettools + ])} + + IRC_SERVER=$1 + IRC_PORT=$2 + IRC_NICK=$3$$ + IRC_CHANNEL=$4 + message=$5 + + export IRC_CHANNEL # for privmsg_cat + + # echo2 and cat2 are used output to both, stdout and stderr + # This is used to see what we send to the irc server. (debug output) + echo2() { echo "$*"; echo "$*" >&2; } + cat2() { tee /dev/stderr; } + + # privmsg_cat transforms stdin to a privmsg + privmsg_cat() { awk '{ print "PRIVMSG "ENVIRON["IRC_CHANNEL"]" :"$0 }'; } + + # ircin is used to feed the output of netcat back to the "irc client" + # so we can implement expect-like behavior with sed^_^ + # XXX mkselfdestructingtmpfifo would be nice instead of this cruft + tmpdir="$(mktemp -d irc-announce_XXXXXXXX)" + cd "$tmpdir" + mkfifo ircin + trap " + rm ircin + cd '$OLDPWD' + rmdir '$tmpdir' + trap - EXIT INT QUIT + " EXIT INT QUIT + + { + echo2 "USER $LOGNAME 0 * :$LOGNAME@$(hostname)" + echo2 "NICK $IRC_NICK" + + # wait for MODE message + sed -n '/^:[^ ]* MODE /q' + + echo2 "JOIN $IRC_CHANNEL" + + printf '%s' "$message" \ + | privmsg_cat \ + | cat2 + + echo2 "PART $IRC_CHANNEL" + + # wait for PART confirmation + sed -n '/:'"$IRC_NICK"'![^ ]* PART /q' + + echo2 'QUIT :Gone to have lunch' + } < ircin \ + | nc "$IRC_SERVER" "$IRC_PORT" | tee -a ircin + ''; + + hooks = { + # TODO make this a package? + irc-announce = { nick, channel, server, port ? 6667 }: '' + #! /bin/sh + set -euf + + export PATH=${makeSearchPath "bin" (with pkgs; [ + coreutils + git + gnused + ])} + + nick=${escapeShellArg nick} + channel=${escapeShellArg channel} + server=${escapeShellArg server} + port=${toString port} + + host=$nick + + empty=0000000000000000000000000000000000000000 + + unset message + while read oldrev newrev ref; do + + if [ $oldrev = $empty ]; then + receive_mode=create + elif [ $newrev = $empty ]; then + receive_mode=delete + elif [ "$(git merge-base $oldrev $newrev)" = $oldrev ]; then + receive_mode=fast-forward + else + receive_mode=non-fast-forward + fi + + h=$(echo $ref | sed 's:^refs/heads/::') + + # empty_tree=$(git hash-object -t tree /dev/null + empty_tree=4b825dc6 + + id=$(echo $newrev | cut -b-7) + id2=$(echo $oldrev | cut -b-7) + if [ $newrev = $empty ]; then id=$empty_tree; fi + if [ $oldrev = $empty ]; then id2=$empty_tree; fi + + case $receive_mode in + create) + #git log --oneline $id2 + link="http://$host/cgit/$GIT_SSH_REPO/?h=$h" + ;; + delete) + #git log --oneline $id2 + link="http://$host/cgit/$GIT_SSH_REPO/ ($h)" + ;; + fast-forward|non-fast-forward) + #git diff --stat $id..$id2 + link="http://$host/cgit/$GIT_SSH_REPO/diff/?h=$h&id=$id&id2=$id2" + ;; + esac + + #$host $GIT_SSH_REPO $ref $link + message="''${message+$message + }$GIT_SSH_USER $receive_mode $link" + done + + if test -n "''${message-}"; then + exec ${irc-announce-script} \ + "$server" \ + "$port" \ + "$nick" \ + "$channel" \ + "$message" + fi + ''; + }; + +in +commands // receive-modes // permissions // refs // hooks diff --git a/old/lib/modules.nix b/old/lib/modules.nix new file mode 100644 index 000000000..248e638ea --- /dev/null +++ b/old/lib/modules.nix @@ -0,0 +1,21 @@ +let + pkgs = import <nixpkgs> {}; + inherit (pkgs.lib) concatMap hasAttr; +in rec { + + no-touch-args = { + config = throw "no-touch-args: can't touch config!"; + lib = throw "no-touch-args: can't touch lib!"; + pkgs = throw "no-touch-args: can't touch pkgs!"; + }; + + # list-imports : path -> [path] + # Return a module's transitive list of imports. + # XXX duplicates won't get eliminated from the result. + list-imports = path: + let module = import path no-touch-args; + imports = if hasAttr "imports" module + then concatMap list-imports module.imports + else []; + in [path] ++ imports; +} diff --git a/old/modules/cd/default.nix b/old/modules/cd/default.nix new file mode 100644 index 000000000..e3abd47ef --- /dev/null +++ b/old/modules/cd/default.nix @@ -0,0 +1,91 @@ +{ config, pkgs, ... }: + +let + inherit (builtins) readFile; +in + +{ + imports = + [ + { users.extraUsers = import <secrets/extraUsers.nix>; } + ./networking.nix + ./users.nix + ../tv/base.nix + ../tv/base-cac-CentOS-7-64bit.nix + ../tv/config/consul-server.nix + ../tv/ejabberd.nix # XXX echtes modul + ../tv/exim-smarthost.nix + ../tv/git/public.nix + ../tv/sanitize.nix + { + imports = [ ../tv/identity ]; + tv.identity = { + enable = true; + self = config.tv.identity.hosts.cd; + }; + } + { + imports = [ ../tv/iptables ]; + tv.iptables = { + enable = true; + input-internet-accept-new-tcp = [ + "ssh" + "tinc" + "smtp" + "xmpp-client" + "xmpp-server" + ]; + input-retiolum-accept-new-tcp = [ + "http" + ]; + }; + } + { + imports = [ ../tv/retiolum ]; + tv.retiolum = { + enable = true; + hosts = <retiolum-hosts>; + connectTo = [ + "fastpoke" + "pigstarter" + "ire" + ]; + }; + } + ]; + + # "Developer 2" plan has two vCPUs. + nix.maxJobs = 2; + + environment.systemPackages = with pkgs; [ + git # required for ./deploy, clone_or_update + htop + iftop + iotop + iptables + mutt # for mv + nethogs + rxvt_unicode.terminfo + tcpdump + ]; + + services.ejabberd-cd = { + enable = true; + }; + + services.journald.extraConfig = '' + SystemMaxUse=1G + RuntimeMaxUse=128M + ''; + + services.openssh = { + enable = true; + hostKeys = [ + # XXX bits here make no science + { bits = 8192; type = "ed25519"; path = "/etc/ssh/ssh_host_ed25519_key"; } + ]; + permitRootLogin = "yes"; + }; + + sound.enable = false; +} diff --git a/old/modules/cd/networking.nix b/old/modules/cd/networking.nix new file mode 100644 index 000000000..215e20829 --- /dev/null +++ b/old/modules/cd/networking.nix @@ -0,0 +1,14 @@ +{...}: +{ + networking.hostName = "cd"; + networking.interfaces.enp2s1.ip4 = [ + { + address = "162.219.7.216"; + prefixLength = 24; + } + ]; + networking.defaultGateway = "162.219.7.1"; + networking.nameservers = [ + "8.8.8.8" + ]; +} diff --git a/old/modules/cd/paths.nix b/old/modules/cd/paths.nix new file mode 100644 index 000000000..f873912fb --- /dev/null +++ b/old/modules/cd/paths.nix @@ -0,0 +1,12 @@ +{ + lib.file.url = ../../lib; + modules.file.url = ../../modules; + nixpkgs.git = { + url = https://github.com/NixOS/nixpkgs; + rev = "4c01e6d91993b6de128795f4fbdd25f6227fb870"; + cache = ../../tmp/git-cache; + }; + pubkeys.file.url = ../../pubkeys; + retiolum-hosts.file.url = ../../hosts; + secrets.file.url = ../../secrets/cd/nix; +} diff --git a/old/modules/cd/users.nix b/old/modules/cd/users.nix new file mode 100644 index 000000000..656336d6c --- /dev/null +++ b/old/modules/cd/users.nix @@ -0,0 +1,53 @@ +{ ... }: + +let + inherit (builtins) readFile; +in + +{ + users.extraGroups = { + + # ● systemd-tmpfiles-setup.service - Create Volatile Files and Directories + # Loaded: loaded (/nix/store/2l33gg7nmncqkpysq9f5fxyhlw6ncm2j-systemd-217/example/systemd/system/systemd-tmpfiles-setup.service) + # Active: failed (Result: exit-code) since Mon 2015-03-16 10:29:18 UTC; 4s ago + # Docs: man:tmpfiles.d(5) + # man:systemd-tmpfiles(8) + # Process: 19272 ExecStart=/nix/store/2l33gg7nmncqkpysq9f5fxyhlw6ncm2j-systemd-217/bin/systemd-tmpfiles --create --remove --boot --exclude-prefix=/dev (code=exited, status=1/FAILURE) + # Main PID: 19272 (code=exited, status=1/FAILURE) + # + # Mar 16 10:29:17 cd systemd-tmpfiles[19272]: [/usr/lib/tmpfiles.d/legacy.conf:26] Unknown group 'lock'. + # Mar 16 10:29:18 cd systemd-tmpfiles[19272]: Two or more conflicting lines for /var/log/journal configured, ignoring. + # Mar 16 10:29:18 cd systemd-tmpfiles[19272]: Two or more conflicting lines for /var/log/journal/7b35116927d74ea58785e00b47ac0f0d configured, ignoring. + # Mar 16 10:29:18 cd systemd[1]: systemd-tmpfiles-setup.service: main process exited, code=exited, status=1/FAILURE + # Mar 16 10:29:18 cd systemd[1]: Failed to start Create Volatile Files and Directories. + # Mar 16 10:29:18 cd systemd[1]: Unit systemd-tmpfiles-setup.service entered failed state. + # Mar 16 10:29:18 cd systemd[1]: systemd-tmpfiles-setup.service failed. + # warning: error(s) occured while switching to the new configuration + lock.gid = 10001; + + }; + users.extraUsers = + { + root = { + openssh.authorizedKeys.keys = [ + (readFile <pubkeys/deploy_wu.ssh.pub>) + (readFile <pubkeys/tv_wu.ssh.pub>) + ]; + }; + + mv = rec { + name = "mv"; + uid = 1338; + group = "users"; + home = "/home/${name}"; + createHome = true; + useDefaultShell = true; + openssh.authorizedKeys.keys = [ + (readFile <pubkeys/mv_vod.ssh.pub>) + ]; + }; + + }; + + users.mutableUsers = false; +} diff --git a/old/modules/cloudkrebs/default.nix b/old/modules/cloudkrebs/default.nix new file mode 100644 index 000000000..938447e0e --- /dev/null +++ b/old/modules/cloudkrebs/default.nix @@ -0,0 +1,69 @@ +{ config, pkgs, ... }: + +{ + imports = [ + ../tv/base-cac-CentOS-7-64bit.nix + ../lass/retiolum-cloudkrebs.nix + ./networking.nix + ../../secrets/cloudkrebs-pw.nix + ../lass/sshkeys.nix + ../lass/base.nix + ../common/nixpkgs.nix + ]; + + nixpkgs = { + url = "https://github.com/Lassulus/nixpkgs"; + rev = "b42ecfb8c61e514bf7733b4ab0982d3e7e27dacb"; + }; + + nix.maxJobs = 1; + + #activationScripts + #split up and move into base + + #TODO move into modules + users.extraUsers = { + #main user + root = { + openssh.authorizedKeys.keys = [ + config.sshKeys.lass.pub + ]; + }; + mainUser = { + uid = 1337; + name = "lass"; + #isNormalUser = true; + group = "users"; + createHome = true; + home = "/home/lass"; + useDefaultShell = true; + isSystemUser = false; + description = "lassulus"; + extraGroups = [ "wheel" ]; + openssh.authorizedKeys.keys = [ + config.sshKeys.lass.pub + ]; + }; + }; + + environment.systemPackages = with pkgs; [ + ]; + + services.openssh = { + enable = true; + hostKeys = [ + # XXX bits here make no science + { bits = 8192; type = "ed25519"; path = "/etc/ssh/ssh_host_ed25519_key"; } + ]; + permitRootLogin = "yes"; + }; + + networking.firewall = { + enable = true; + + allowedTCPPorts = [ + 22 + ]; + }; + +} diff --git a/old/modules/cloudkrebs/networking.nix b/old/modules/cloudkrebs/networking.nix new file mode 100644 index 000000000..fc5007365 --- /dev/null +++ b/old/modules/cloudkrebs/networking.nix @@ -0,0 +1,14 @@ +{...}: +{ + networking.hostName = "cloudkrebs"; + networking.interfaces.enp2s1.ip4 = [ + { + address = "104.167.113.104"; + prefixLength = 24; + } + ]; + networking.defaultGateway = "104.167.113.1"; + networking.nameservers = [ + "8.8.8.8" + ]; +} diff --git a/old/modules/common/krebs-keys.nix b/old/modules/common/krebs-keys.nix new file mode 100644 index 000000000..5e349338d --- /dev/null +++ b/old/modules/common/krebs-keys.nix @@ -0,0 +1,18 @@ +# alle public keys der krebsminister fuer R in krebs repos +{ config, ... }: + +let + inherit (builtins) readFile; +in + +with import ../lass/sshkeys.nix { + config.sshKeys.lass.pub = config.sshKeys.lass.pub; + config.sshKeys.uriel.pub = config.sshKeys.uriel.pub; + }; +{ + imports = [ + ./sshkeys.nix + ]; + + config.sshKeys.tv.pub = readFile <pubkeys/tv_wu.ssh.pub>; +} diff --git a/old/modules/common/krebs-repos.nix b/old/modules/common/krebs-repos.nix new file mode 100644 index 000000000..86f373123 --- /dev/null +++ b/old/modules/common/krebs-repos.nix @@ -0,0 +1,36 @@ +{ lib, ... }: + +let + inherit (lib) mkDefault; + + mkSecureRepo = name: + { inherit name; + value = { + users = { + lass = mkDefault "R"; + tv = mkDefault "R"; + makefu = mkDefault "R"; + }; + }; + }; + + mkRepo = name: + { inherit name; + value = { + users = { + lass = mkDefault "R"; + tv = mkDefault "R"; + makefu = mkDefault "R"; + }; + }; + }; + +in { + services.gitolite.repos = + (lib.listToAttrs (map mkSecureRepo [ "brain" ])) // + (lib.listToAttrs (map mkRepo [ + "painload" + "services" + "hosts" + ])); +} diff --git a/old/modules/common/nixpkgs.nix b/old/modules/common/nixpkgs.nix new file mode 100644 index 000000000..486cf0207 --- /dev/null +++ b/old/modules/common/nixpkgs.nix @@ -0,0 +1,25 @@ +{ lib, ... }: + +with lib; + +{ + options = { + nixpkgs.url = mkOption { + type = types.str; + description = "URL of the nixpkgs repository."; + }; + nixpkgs.rev = mkOption { + type = types.str; + default = "origin/master"; + description = "Revision of the remote repository."; + }; + nixpkgs.dirty = mkOption { + type = types.bool; + default = false; + description = '' + If nixpkgs.url is a local path, then use that as it is. + TODO this break if URL is not a local path. + ''; + }; + }; +} diff --git a/old/modules/common/sshkeys.nix b/old/modules/common/sshkeys.nix new file mode 100644 index 000000000..5f1c60668 --- /dev/null +++ b/old/modules/common/sshkeys.nix @@ -0,0 +1,26 @@ +{ lib, ... }: + +with lib; + +{ + options = { + sshKeys = mkOption { + type = types.attrsOf (types.submodule ( + { config, ... }: + { + options = { + pub = mkOption { + type = types.str; + description = "Public part of the ssh key."; + }; + + priv = mkOption { + type = types.str; + description = "Private part of the ssh key."; + }; + }; + })); + description = "collection of ssh-keys"; + }; + }; +} diff --git a/old/modules/lass/base.nix b/old/modules/lass/base.nix new file mode 100644 index 000000000..3a8d879eb --- /dev/null +++ b/old/modules/lass/base.nix @@ -0,0 +1,110 @@ +{ config, pkgs, ... }: + +{ + imports = [ + ./sshkeys.nix + ]; + + nix.useChroot = true; + + users.mutableUsers = false; + + boot.tmpOnTmpfs = true; + # see tmpfiles.d(5) + systemd.tmpfiles.rules = [ + "d /tmp 1777 root root - -" + ]; + + # multiple-definition-problem when defining environment.variables.EDITOR + environment.extraInit = '' + EDITOR=vim + PAGER=most + ''; + + environment.systemPackages = with pkgs; [ + git + most + rxvt_unicode.terminfo + + #network + iptables + ]; + + programs.bash = { + enableCompletion = true; + interactiveShellInit = '' + HISTCONTROL='erasedups:ignorespace' + HISTSIZE=65536 + HISTFILESIZE=$HISTSIZE + + shopt -s checkhash + shopt -s histappend histreedit histverify + shopt -s no_empty_cmd_completion + complete -d cd + + #fancy colors + if [ -e ~/LS_COLORS ]; then + eval $(dircolors ~/LS_COLORS) + fi + + if [ -e /etc/nixos/dotfiles/link ]; then + /etc/nixos/dotfiles/link + fi + ''; + promptInit = '' + if test $UID = 0; then + PS1='\[\033[1;31m\]\w\[\033[0m\] ' + elif test $UID = 1337; then + PS1='\[\033[1;32m\]\w\[\033[0m\] ' + else + PS1='\[\033[1;33m\]\u@\w\[\033[0m\] ' + fi + if test -n "$SSH_CLIENT"; then + PS1='\[\033[35m\]\h'" $PS1" + fi + ''; + }; + + services.gitolite = { + enable = true; + dataDir = "/home/gitolite"; + adminPubkey = config.sshKeys.lass.pub; + }; + + services.openssh = { + enable = true; + hostKeys = [ + # XXX bits here make no science + { bits = 8192; type = "ed25519"; path = "/etc/ssh/ssh_host_ed25519_key"; } + ]; + }; + + services.journald.extraConfig = '' + SystemMaxUse=1G + RuntimeMaxUse=128M + ''; + + networking.firewall = { + enable = true; + + allowedTCPPorts = [ + 22 + ]; + + extraCommands = '' + iptables -A INPUT -j ACCEPT -m conntrack --ctstate RELATED,ESTABLISHED + iptables -A INPUT -j ACCEPT -i lo + iptables -A INPUT -j ACCEPT -p icmp + + #iptables -N Retiolum + iptables -A INPUT -j Retiolum -i retiolum + iptables -A Retiolum -j ACCEPT -m conntrack --ctstate RELATED,ESTABLISHED + iptables -A Retiolum -j REJECT -p tcp --reject-with tcp-reset + iptables -A Retiolum -j REJECT -p udp --reject-with icmp-port-unreachable + iptables -A Retiolum -j REJECT --reject-with icmp-proto-unreachable + iptables -A Retiolum -j REJECT + ''; + + extraStopCommands = "iptables -F"; + }; +} diff --git a/old/modules/lass/binary-caches.nix b/old/modules/lass/binary-caches.nix new file mode 100644 index 000000000..c2727520d --- /dev/null +++ b/old/modules/lass/binary-caches.nix @@ -0,0 +1,13 @@ +{ config, ... }: + +{ + nix.sshServe.enable = true; + nix.sshServe.keys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBF9SBNKE3Pw/ALwTfzpzs+j6Rpaf0kUy6FiPMmgNNNt root@mors" + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFCZSq5oLrokkh3F+MOdK5/nzVIEDvqyvfzLMNWmzsYD root@uriel" + ]; + nix.binaryCaches = [ + #"scp://nix-ssh@mors" + #"scp://nix-ssh@uriel" + ]; +} diff --git a/old/modules/lass/bird.nix b/old/modules/lass/bird.nix new file mode 100644 index 000000000..3fc265cd7 --- /dev/null +++ b/old/modules/lass/bird.nix @@ -0,0 +1,13 @@ +{ config, ... }: + +{ + config.services.bird = { + enable = true; + config = '' + router id 192.168.122.1; + protocol device { + scan time 10; + } + ''; + }; +} diff --git a/old/modules/lass/bitcoin.nix b/old/modules/lass/bitcoin.nix new file mode 100644 index 000000000..d3bccbf5c --- /dev/null +++ b/old/modules/lass/bitcoin.nix @@ -0,0 +1,17 @@ +{ config, pkgs, ... }: + +{ + environment.systemPackages = with pkgs; [ + electrum + ]; + + users.extraUsers = { + bitcoin = { + name = "bitcoin"; + description = "user for bitcoin stuff"; + home = "/home/bitcoin"; + useDefaultShell = true; + createHome = true; + }; + }; +} diff --git a/old/modules/lass/browsers.nix b/old/modules/lass/browsers.nix new file mode 100644 index 000000000..8aecea925 --- /dev/null +++ b/old/modules/lass/browsers.nix @@ -0,0 +1,67 @@ +{ config, pkgs, ... }: + +let + mainUser = config.users.extraUsers.mainUser; + +in { + + nixpkgs.config.packageOverrides = pkgs : { + chromium = pkgs.chromium.override { + pulseSupport = true; + }; + }; + + environment.systemPackages = with pkgs; [ + firefox + ]; + + users.extraUsers = { + firefox = { + name = "firefox"; + description = "user for running firefox"; + home = "/home/firefox"; + useDefaultShell = true; + extraGroups = [ "audio" ]; + createHome = true; + }; + chromium = { + name = "chromium"; + description = "user for running chromium"; + home = "/home/chromium"; + useDefaultShell = true; + extraGroups = [ "audio" ]; + createHome = true; + }; + facebook = { + name = "facebook"; + description = "user for running facebook in chromium"; + home = "/home/facebook"; + useDefaultShell = true; + extraGroups = [ "audio" ]; + createHome = true; + }; + google = { + name = "google"; + description = "user for running google+/gmail in chromium"; + home = "/home/google"; + useDefaultShell = true; + createHome = true; + }; + flash = { + name = "flash"; + description = "user for running flash stuff"; + home = "/home/flash"; + useDefaultShell = true; + extraGroups = [ "audio" ]; + createHome = true; + }; + }; + + security.sudo.extraConfig = '' + ${mainUser.name} ALL=(firefox) NOPASSWD: ALL + ${mainUser.name} ALL=(chromium) NOPASSWD: ALL + ${mainUser.name} ALL=(facebook) NOPASSWD: ALL + ${mainUser.name} ALL=(google) NOPASSWD: ALL + ${mainUser.name} ALL=(flash) NOPASSWD: ALL + ''; +} diff --git a/old/modules/lass/chromium-patched.nix b/old/modules/lass/chromium-patched.nix new file mode 100644 index 000000000..715181778 --- /dev/null +++ b/old/modules/lass/chromium-patched.nix @@ -0,0 +1,48 @@ +{ config, pkgs, ... }: + +#settings to test: +# + #"ForceEphemeralProfiles": true, +let + masterPolicy = pkgs.writeText "master.json" '' + { + "PasswordManagerEnabled": false, + "DefaultGeolocationSetting": 2, + "RestoreOnStartup": 1, + "AutoFillEnabled": false, + "BackgroundModeEnabled": false, + "DefaultBrowserSettingEnabled": false, + "SafeBrowsingEnabled": false, + "ExtensionInstallForcelist": [ + "cjpalhdlnbpafiamejdnhcphjbkeiagm;https://clients2.google.com/service/update2/crx", + "ihlenndgcmojhcghmfjfneahoeklbjjh;https://clients2.google.com/service/update2/crx" + ] + } + ''; + + master_preferences = pkgs.writeText "master_preferences" '' + { + "browser": { + "custom_chrome_frame": true + }, + + "extensions": { + "theme": { + "id": "", + "use_system": true + } + } + } + ''; +in { + environment.etc."chromium/policies/managed/master.json".source = pkgs.lib.mkForce masterPolicy; + + environment.systemPackages = [ + #pkgs.chromium + (pkgs.lib.overrideDerivation pkgs.chromium (attrs: { + buildCommand = attrs.buildCommand + '' + touch $out/TEST123 + ''; + })) + ]; +} diff --git a/old/modules/lass/desktop-base.nix b/old/modules/lass/desktop-base.nix new file mode 100644 index 000000000..94184548e --- /dev/null +++ b/old/modules/lass/desktop-base.nix @@ -0,0 +1,37 @@ +{ config, pkgs, ... }: + +{ + imports = [ + ./base.nix + ]; + + time.timeZone = "Europe/Berlin"; + + virtualisation.libvirtd.enable = true; + + hardware.pulseaudio = { + enable = true; + systemWide = true; + }; + + programs.ssh.startAgent = false; + + security.setuidPrograms = [ "slock" ]; + + services.printing = { + enable = true; + drivers = [ pkgs.foomatic_filters ]; + }; + + environment.systemPackages = with pkgs; [ + + powertop + + #window manager stuff + haskellPackages.xmobar + haskellPackages.yeganesh + dmenu2 + xlibs.fontschumachermisc + ]; + +} diff --git a/old/modules/lass/elster.nix b/old/modules/lass/elster.nix new file mode 100644 index 000000000..1edd01896 --- /dev/null +++ b/old/modules/lass/elster.nix @@ -0,0 +1,20 @@ +{ config, pkgs, ... }: + +let + mainUser = config.users.extraUsers.mainUser; + +in { + users.extraUsers = { + elster = { + name = "elster"; + description = "user for running elster-online"; + home = "/home/elster"; + useDefaultShell = true; + extraGroups = []; + createHome = true; + }; + }; + security.sudo.extraConfig = '' + ${mainUser.name} ALL=(elster) NOPASSWD: ALL + ''; +} diff --git a/old/modules/lass/games.nix b/old/modules/lass/games.nix new file mode 100644 index 000000000..6043a8759 --- /dev/null +++ b/old/modules/lass/games.nix @@ -0,0 +1,25 @@ +{ config, pkgs, ... }: + +let + mainUser = config.users.extraUsers.mainUser; + +in { + environment.systemPackages = with pkgs; [ + dwarf_fortress + ]; + + users.extraUsers = { + games = { + name = "games"; + description = "user playing games"; + home = "/home/games"; + extraGroups = [ "audio" "video" "input" ]; + createHome = true; + useDefaultShell = true; + }; + }; + + security.sudo.extraConfig = '' + ${mainUser.name} ALL=(games) NOPASSWD: ALL + ''; +} diff --git a/old/modules/lass/gitolite-base.nix b/old/modules/lass/gitolite-base.nix new file mode 100644 index 000000000..b47629956 --- /dev/null +++ b/old/modules/lass/gitolite-base.nix @@ -0,0 +1,173 @@ +{ config, ... }: + +{ + services.gitolite = { + mutable = false; + keys = { + lass = config.sshKeys.lass.pub; + uriel = config.sshKeys.uriel.pub; + }; + rc = '' + %RC = ( + UMASK => 0077, + GIT_CONFIG_KEYS => "", + LOG_EXTRA => 1, + ROLES => { + READERS => 1, + WRITERS => 1, + }, + LOCAL_CODE => "$ENV{HOME}/.gitolite", + ENABLE => [ + 'help', + 'desc', + 'info', + 'perms', + 'writable', + 'ssh-authkeys', + 'git-config', + 'daemon', + 'gitweb', + 'repo-specific-hooks', + ], + ); + 1; + ''; + + repoSpecificHooks = { + irc-announce = '' + #! /bin/sh + set -euf + + config_file="$GL_ADMIN_BASE/conf/irc-announce.conf" + if test -f "$config_file"; then + . "$config_file" + fi + + # XXX when changing IRC_CHANNEL or IRC_SERVER/_PORT, don't forget to update + # any relevant gitolite LOCAL_CODE! + # CAVEAT we hope that IRC_NICK is unique + IRC_NICK="''${IRC_NICK-gl$GL_TID}" + IRC_CHANNEL="''${IRC_CHANNEL-#retiolum}" + IRC_SERVER="''${IRC_SERVER-ire.retiolum}" + IRC_PORT="''${IRC_PORT-6667}" + + # for privmsg_cat below + export IRC_CHANNEL + + # collect users that are mentioned in the gitolite configuration + interested_users="$(perl -e ' + do "gl-conf"; + print join(" ", keys%{ $one_repo{$ENV{"GL_REPO"}} }); + ')" + + # CAVEAT beware of real TABs in grep pattern! + # CAVEAT there will never be more than 42 relevant log entries! + tab=$(printf '\x09') + log="$(tail -n 42 "$GL_LOGFILE" | grep "^[^$tab]*$tab$GL_TID$tab" || :)" + + update_log="$(echo "$log" | grep "^[^$tab]*$tab$GL_TID''${tab}update")" + + # (debug output) + env | sed 's/^/env: /' + echo "$log" | sed 's/^/log: /' + + # see http://gitolite.com/gitolite/dev-notes.html#lff + reponame=$(echo "$update_log" | cut -f 4) + username=$(echo "$update_log" | cut -f 5) + ref_name=$(echo "$update_log" | cut -f 7 | sed 's|^refs/heads/||') + old_sha=$(echo "$update_log" | cut -f 8) + new_sha=$(echo "$update_log" | cut -f 9) + + # check if new branch is created + if test $old_sha = 0000000000000000000000000000000000000000; then + # TODO what should we really show? + old_sha=$new_sha^ + fi + + # + git_log="$(git log $old_sha..$new_sha --pretty=oneline --abbrev-commit)" + commit_count=$(echo "$git_log" | wc -l) + + # echo2 and cat2 are used output to both, stdout and stderr + # This is used to see what we send to the irc server. (debug output) + echo2() { echo "$*"; echo "$*" >&2; } + cat2() { tee /dev/stderr; } + + # privmsg_cat transforms stdin to a privmsg + privmsg_cat() { awk '{ print "PRIVMSG "ENVIRON["IRC_CHANNEL"]" :"$0 }'; } + + # ircin is used to feed the output of netcat back to the "irc client" + # so we can implement expect-like behavior with sed^_^ + # XXX mkselfdestructingtmpfifo would be nice instead of this cruft + tmpdir="$(mktemp -d irc-announce_XXXXXXXX)" + cd "$tmpdir" + mkfifo ircin + trap " + rm ircin + cd '$OLDPWD' + rmdir '$tmpdir' + trap - EXIT INT QUIT + " EXIT INT QUIT + + # + # + # + { + echo2 "USER $LOGNAME 0 * :$LOGNAME@$(hostname)" + echo2 "NICK $IRC_NICK" + + # wait for MODE message + sed -n '/^:[^ ]* MODE /q' + + echo2 "JOIN $IRC_CHANNEL" + + echo "$interested_users" \ + | tr ' ' '\n' \ + | grep -v "^$GL_USER" \ + | sed 's/$/: poke/' \ + | privmsg_cat \ + | cat2 + + printf '[\x0313%s\x03] %s pushed %s new commit%s to \x036%s %s\x03\n' \ + "$reponame" \ + "$username" \ + "$commit_count" \ + "$(test $commit_count = 1 || echo s)" \ + "$(hostname)" \ + "$ref_name" \ + | privmsg_cat \ + | cat2 + + echo "$git_log" \ + | sed 's/^/\x0314/;s/ /\x03 /' \ + | privmsg_cat \ + | cat2 + + echo2 "PART $IRC_CHANNEL" + + # wait for PART confirmation + sed -n '/:'"$IRC_NICK"'![^ ]* PART /q' + + echo2 'QUIT :Gone to have lunch' + } < ircin \ + | nc "$IRC_SERVER" "$IRC_PORT" | tee -a ircin + ''; + }; + customFiles = [ + { + path = ".gitolite/conf/irc-announce.conf"; + file = '' + IRC_NICK="$(hostname)$GL_TID" + case "$GL_REPO" in + brain|painload|services|load-env|config) + IRC_CHANNEL='#retiolum' + ;; + *) + IRC_CHANNEL='&testing' + ;; + esac + ''; + } + ]; + }; +} diff --git a/old/modules/lass/ircd.nix b/old/modules/lass/ircd.nix new file mode 100644 index 000000000..3c9e25718 --- /dev/null +++ b/old/modules/lass/ircd.nix @@ -0,0 +1,83 @@ +{ config, pkgs, ... }: + +{ + config.services.charybdis = { + enable = true; + config = '' + serverinfo { + name = "ire.irc.retiolum"; + sid = "4z3"; + description = "miep!"; + network_name = "irc.retiolum"; + network_desc = "Retiolum IRC Network"; + hub = yes; + + vhost = "0.0.0.0"; + vhost6 = "::"; + + #ssl_private_key = "etc/ssl.key"; + #ssl_cert = "etc/ssl.cert"; + #ssl_dh_params = "etc/dh.pem"; + #ssld_count = 1; + + #default_max_clients = 1024; + #nicklen = 30; + }; + + listen { + defer_accept = yes; + + /* If you want to listen on a specific IP only, specify host. + * host definitions apply only to the following port line. + */ + host = "0.0.0.0"; + port = 6667; + sslport = 6697; + + /* Listen on IPv6 (if you used host= above). */ + host = "::"; + port = 6667; + sslport = 9999; + }; + + auth { + user = "*@*"; + class = "users"; + }; + + class "users" { + ping_time = 2 minutes; + number_per_ident = 10; + number_per_ip = 10; + number_per_ip_global = 50; + cidr_ipv4_bitlen = 24; + cidr_ipv6_bitlen = 64; + number_per_cidr = 200; + max_number = 3000; + sendq = 400 kbytes; + }; + + channel { + use_invex = yes; + use_except = yes; + use_forward = yes; + use_knock = yes; + knock_delay = 5 minutes; + knock_delay_channel = 1 minute; + max_chans_per_user = 15; + max_bans = 100; + max_bans_large = 500; + default_split_user_count = 0; + default_split_server_count = 0; + no_create_on_split = no; + no_join_on_split = no; + burst_topicwho = yes; + kick_on_split_riding = no; + only_ascii_channels = no; + resv_forcepart = yes; + channel_target_change = yes; + disable_local_channels = no; + }; + ''; + }; +} diff --git a/old/modules/lass/pass.nix b/old/modules/lass/pass.nix new file mode 100644 index 000000000..33eca0a17 --- /dev/null +++ b/old/modules/lass/pass.nix @@ -0,0 +1,10 @@ +{ config, pkgs, ... }: + +{ + environment.systemPackages = with pkgs; [ + pass + gnupg1 + ]; + + services.xserver.startGnuPGAgent = true; +} diff --git a/old/modules/lass/programs.nix b/old/modules/lass/programs.nix new file mode 100644 index 000000000..41d241bac --- /dev/null +++ b/old/modules/lass/programs.nix @@ -0,0 +1,24 @@ +{ config, pkgs, ... }: + +## TODO sort and split up +{ + environment.systemPackages = with pkgs; [ + aria2 + gnupg1compat + htop + i3lock + mc + mosh + mpv + pass + pavucontrol + pv + pwgen + python34Packages.livestreamer + remmina + silver-searcher + wget + xsel + youtube-dl + ]; +} diff --git a/old/modules/lass/retiolum-cloudkrebs.nix b/old/modules/lass/retiolum-cloudkrebs.nix new file mode 100644 index 000000000..1f035271d --- /dev/null +++ b/old/modules/lass/retiolum-cloudkrebs.nix @@ -0,0 +1,21 @@ +{ config, pkgs, ... }: + +{ + imports = [ + ../tv/retiolum.nix + ]; + + services.retiolum = { + enable = true; + hosts = ../../hosts; + privateKeyFile = "/etc/nixos/secrets/cloudkrebs.retiolum.rsa_key.priv"; + connectTo = [ + "fastpoke" + "gum" + "ire" + ]; + }; + + networking.firewall.allowedTCPPorts = [ 655 ]; + networking.firewall.allowedUDPPorts = [ 655 ]; +} diff --git a/old/modules/lass/retiolum-mors.nix b/old/modules/lass/retiolum-mors.nix new file mode 100644 index 000000000..61a7856c1 --- /dev/null +++ b/old/modules/lass/retiolum-mors.nix @@ -0,0 +1,21 @@ +{ config, pkgs, ... }: + +{ + imports = [ + ../tv/retiolum.nix + ]; + + services.retiolum = { + enable = true; + hosts = ../../hosts; + privateKeyFile = "/etc/nixos/secrets/mors.retiolum.rsa_key.priv"; + connectTo = [ + "fastpoke" + "gum" + "ire" + ]; + }; + + networking.firewall.allowedTCPPorts = [ 655 ]; + networking.firewall.allowedUDPPorts = [ 655 ]; +} diff --git a/old/modules/lass/retiolum-uriel.nix b/old/modules/lass/retiolum-uriel.nix new file mode 100644 index 000000000..11dc61c11 --- /dev/null +++ b/old/modules/lass/retiolum-uriel.nix @@ -0,0 +1,21 @@ +{ config, pkgs, ... }: + +{ + imports = [ + ../tv/retiolum.nix + ]; + + services.retiolum = { + enable = true; + hosts = ../../hosts; + privateKeyFile = "/etc/nixos/secrets/uriel.retiolum.rsa_key.priv"; + connectTo = [ + "fastpoke" + "gum" + "ire" + ]; + }; + + networking.firewall.allowedTCPPorts = [ 655 ]; + networking.firewall.allowedUDPPorts = [ 655 ]; +} diff --git a/old/modules/lass/sshkeys.nix b/old/modules/lass/sshkeys.nix new file mode 100644 index 000000000..f2b0786e5 --- /dev/null +++ b/old/modules/lass/sshkeys.nix @@ -0,0 +1,11 @@ +{ config, ... }: + +{ + imports = [ + ../common/sshkeys.nix + ]; + + config.sshKeys.lass.pub = "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAp83zynhIueJJsWlSEykVSBrrgBFKq38+vT8bRfa+csqyjZBl2SQFuCPo+Qbh49mwchpZRshBa9jQEIGqmXxv/PYdfBFQuOFgyUq9ZcTZUXqeynicg/SyOYFW86iiqYralIAkuGPfQ4howLPVyjTZtWeEeeEttom6p6LMY5Aumjz2em0FG0n9rRFY2fBzrdYAgk9C0N6ojCs/Gzknk9SGntA96MDqHJ1HXWFMfmwOLCnxtE5TY30MqSmkrJb7Fsejwjoqoe9Y/mCaR0LpG2cStC1+37GbHJNH0caCMaQCX8qdfgMVbWTVeFWtV6aWOaRgwLrPDYn4cHWQJqTfhtPrNQ== lass@mors"; + + config.sshKeys.uriel.pub = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDExWuRcltGM2FqXO695nm6/QY3wU3r1bDTyCpMrLfUSym7TxcXDSmZSWcueexPXV6GENuUfjJPZswOdWqIo5u2AXw9t0aGvwEDmI6uJ7K5nzQOsXIneGMdYuoOaAzWI8pxZ4N+lIP1HsOYttIPDp8RwU6kyG+Ud8mnVHWSTO13C7xC9vePnDP6b+44nHS691Zj3X/Cq35Ls0ISC3EM17jreucdP62L3TKk2R4NCm3Sjqj+OYEv0LAqIpgqSw5FypTYQgNByxRcIcNDlri63Q1yVftUP1338UiUfxtraUu6cqa2CdsHQmtX5mTNWEluVWO3uUKTz9zla3rShC+d3qvr lass@uriel"; +} diff --git a/old/modules/lass/steam.nix b/old/modules/lass/steam.nix new file mode 100644 index 000000000..d54873b1f --- /dev/null +++ b/old/modules/lass/steam.nix @@ -0,0 +1,29 @@ +{ config, pkgs, ... }: + +{ + + imports = [ + ./games.nix + ]; + # + # Steam stuff + # source: https://nixos.org/wiki/Talk:Steam + # + ##TODO: make steam module + hardware.opengl.driSupport32Bit = true; + + environment.systemPackages = with pkgs; [ + steam + ]; + networking.firewall = { + allowedUDPPorts = [ + 27031 + 27036 + ]; + allowedTCPPorts = [ + 27036 + 27037 + ]; + }; + +} diff --git a/old/modules/lass/texlive.nix b/old/modules/lass/texlive.nix new file mode 100644 index 000000000..295df31cd --- /dev/null +++ b/old/modules/lass/texlive.nix @@ -0,0 +1,7 @@ +{ pkgs, ... }: + +{ + environment.systemPackages = with pkgs; [ + (pkgs.texLiveAggregationFun { paths = [ pkgs.texLive pkgs.texLiveFull ]; }) + ]; +} diff --git a/old/modules/lass/urxvt.nix b/old/modules/lass/urxvt.nix new file mode 100644 index 000000000..889f768ac --- /dev/null +++ b/old/modules/lass/urxvt.nix @@ -0,0 +1,40 @@ +{ config, pkgs, ... }: + +let + inherit (config.users.extraUsers) mainUser; + +in + +{ + imports = [ + ./urxvtd.nix + ./xresources.nix + ]; + + services.urxvtd = { + enable = true; + users = [ mainUser.name ]; + urxvtPackage = pkgs.rxvt_unicode_with-plugins; + }; + services.xresources.enable = true; + services.xresources.resources.urxvt = '' + URxvt*scrollBar: false + URxvt*urgentOnBell: true + URxvt*font: -*-clean-*-*-*-*-*-*-*-*-*-*-iso10646-* + URxvt*boldFont: -*-clean-*-*-*-*-*-*-*-*-*-*-iso10646-* + URxvt.perl-ext-common: default,clipboard,url-select,keyboard-select + URxvt.url-select.launcher: browser-select + URxvt.url-select.underline: true + URxvt.keysym.M-u: perl:url-select:select_next + URxvt.keysym.M-Escape: perl:keyboard-select:activate + URxvt.keysym.M-s: perl:keyboard-select:search + + URxvt.intensityStyles: false + + URxvt*background: #000000 + URxvt*foreground: #ffffff + + !change unreadable blue + URxvt*color4: #268bd2 + ''; +} diff --git a/old/modules/lass/urxvtd.nix b/old/modules/lass/urxvtd.nix new file mode 100644 index 000000000..469616a9f --- /dev/null +++ b/old/modules/lass/urxvtd.nix @@ -0,0 +1,55 @@ +{ config, lib, pkgs, ... }: + +let +in + +with builtins; +with lib; + +{ + options = { + services.urxvtd = { + enable = mkOption { + type = types.bool; + default = false; + description = "Enable urxvtd per user"; + }; + users = mkOption { + type = types.listOf types.string; + default = []; + description = "users to run urxvtd for"; + }; + urxvtPackage = mkOption { + type = types.package; + default = pkgs.rxvt_unicode; + description = "urxvt package to use"; + }; + }; + }; + + config = + let + cfg = config.services.urxvtd; + users = cfg.users; + urxvt = cfg.urxvtPackage; + mkService = user: { + description = "urxvt terminal daemon"; + wantedBy = [ "multi-user.target" ]; + restartIfChanged = false; + path = [ pkgs.xlibs.xrdb ]; + environment = { + DISPLAY = ":0"; + URXVT_PERL_LIB = "${urxvt}/lib/urxvt/perl"; + }; + serviceConfig = { + Restart = "always"; + User = user; + ExecStart = "${urxvt}/bin/urxvtd"; + }; + }; + in + mkIf cfg.enable { + environment.systemPackages = [ urxvt ]; + systemd.services = listToAttrs (map (u: { name = "${u}-urxvtd"; value = mkService u; }) users); + }; +} diff --git a/old/modules/lass/vim.nix b/old/modules/lass/vim.nix new file mode 100644 index 000000000..e1cff0d24 --- /dev/null +++ b/old/modules/lass/vim.nix @@ -0,0 +1,116 @@ +{ config, pkgs, ... }: + +let + customPlugins.mustang2 = pkgs.vimUtils.buildVimPlugin { + name = "Mustang2"; + src = pkgs.fetchFromGitHub { + owner = "croaker"; + repo = "mustang-vim"; + rev = "6533d7d21bf27cae94d9c2caa575f627f003dfd5"; + sha256 = "0zlmcrr04j3dkiivrhqi90f618lmnnnpvbz1b9msfs78cmgw9w67"; + }; + }; + +in { + + environment.systemPackages = [ + (pkgs.vim_configurable.customize { + name = "vim"; + + vimrcConfig.customRC = '' + set nocompatible + set t_Co=16 + syntax on + " TODO autoload colorscheme file + set background=dark + colorscheme mustang + filetype off + filetype plugin indent on + + imap <F1> <nop> + + set mouse=a + set ruler + set showmatch + set backspace=2 + set visualbell + set encoding=utf8 + set showcmd + set wildmenu + + set title + set titleold= + set titlestring=%t%(\ %M%)%(\ (%{expand(\"%:p:h\")})%)%(\ %a%)\ -\ %{v:servername} + + set autoindent + + set ttyfast + + set pastetoggle=<INS> + + + " Force Saving Files that Require Root Permission + command! W silent w !sudo tee "%" >/dev/null + + nnoremap <C-c> :q<Return> + vnoremap < <gv + vnoremap > >gv + + "Tabwidth + set ts=2 sts=2 sw=2 et + + " create Backup/tmp/undo dirs + function! InitBackupDir() + let l:parent = $HOME . '/.vim/' + let l:backup = l:parent . 'backups/' + let l:tmpdir = l:parent . 'tmp/' + let l:undodi = l:parent . 'undo/' + + if !isdirectory(l:parent) + call mkdir(l:parent) + endif + if !isdirectory(l:backup) + call mkdir(l:backup) + endif + if !isdirectory(l:tmpdir) + call mkdir(l:tmpdir) + endif + if !isdirectory(l:undodi) + call mkdir(l:undodi) + endif + endfunction + call InitBackupDir() + + " Backups & Files + set backup + set backupdir=~/.vim/backups + set directory=~/.vim/tmp// + set viminfo='20,<1000,s100,h,n~/.vim/tmp/info + set undodir=$HOME/.vim/undo + set undofile + + " highlight whitespaces + highlight ExtraWhitespace ctermbg=red guibg=red + match ExtraWhitespace /\s\+$/ + autocmd BufWinEnter * match ExtraWhitespace /\s\+$/ + autocmd InsertEnter * match ExtraWhitespace /\s\+\%#\@<!$/ + autocmd InsertLeave * match ExtraWhitespace /\s\+$/ + autocmd BufWinLeave * call clearmatches() + + "ft specific stuff + autocmd BufRead *.js,*.json set ts=2 sts=2 sw=2 et + autocmd BufRead *.hs set ts=4 sts=4 sw=4 et + + "esc timeout + set timeoutlen=1000 ttimeoutlen=0 + ''; + + vimrcConfig.vam.knownPlugins = pkgs.vimPlugins // customPlugins; + vimrcConfig.vam.pluginDictionaries = [ + { names = [ "Gundo" "commentary" "mustang2" ]; } + { names = [ "vim-addon-nix" ]; ft_regex = "^nix\$"; } + ]; + + }) + ]; +} diff --git a/old/modules/lass/virtualbox.nix b/old/modules/lass/virtualbox.nix new file mode 100644 index 000000000..026203124 --- /dev/null +++ b/old/modules/lass/virtualbox.nix @@ -0,0 +1,22 @@ +{ config, pkgs, ... }: + +let + mainUser = config.users.extraUsers.mainUser; + +in { + services.virtualboxHost.enable = true; + + users.extraUsers = { + virtual = { + name = "virtual"; + description = "user for running VirtualBox"; + home = "/home/virtual"; + useDefaultShell = true; + extraGroups = [ "vboxusers" "audio" ]; + createHome = true; + }; + }; + security.sudo.extraConfig = '' + ${mainUser.name} ALL=(virtual) NOPASSWD: ALL + ''; +} diff --git a/old/modules/lass/wine.nix b/old/modules/lass/wine.nix new file mode 100644 index 000000000..8d55da7fd --- /dev/null +++ b/old/modules/lass/wine.nix @@ -0,0 +1,23 @@ +{ config, pkgs, ... }: + +let + mainUser = config.users.extraUsers.mainUser; + +in { + environment.systemPackages = with pkgs; [ + wineUnstable + ]; + users.extraUsers = { + wine = { + name = "wine"; + description = "user for running wine"; + home = "/home/wine"; + useDefaultShell = true; + extraGroups = [ "audio" ]; + createHome = true; + }; + }; + security.sudo.extraConfig = '' + ${mainUser.name} ALL=(wine) NOPASSWD: ALL + ''; +} diff --git a/old/modules/lass/xresources.nix b/old/modules/lass/xresources.nix new file mode 100644 index 000000000..00a9e5c91 --- /dev/null +++ b/old/modules/lass/xresources.nix @@ -0,0 +1,57 @@ +{ config, lib, pkgs, ... }: + +#TODO: +#prefix with Attribute Name +#ex: urxvt + +# +# +with builtins; +with lib; + + +let + + inherit (import ../../lib { inherit pkgs; inherit lib; }) shell-escape; + inherit (pkgs) writeScript; + +in + +{ + + options = { + services.xresources.enable = mkOption { + type = types.bool; + default = false; + description = '' + Whether to enable the automatic loading of Xresources definitions at display-manager start; + ''; + }; + + services.xresources.resources = mkOption { + default = {}; + type = types.attrsOf types.str; + example = { + urxvt = '' + URxvt*scrollBar: false + URxvt*urgentOnBell: true + ''; + }; + description = '' + Xresources definitions. + ''; + }; + }; + + config = + let + cfg = config.services.xresources; + xres = concatStringsSep "\n" (attrValues cfg.resources); + + in mkIf cfg.enable { + services.xserver.displayManager.sessionCommands = '' + echo ${shell-escape xres} | xrdb -merge + ''; + }; + +} diff --git a/old/modules/lass/xserver-lass.nix b/old/modules/lass/xserver-lass.nix new file mode 100644 index 000000000..5c2d169bb --- /dev/null +++ b/old/modules/lass/xserver-lass.nix @@ -0,0 +1,43 @@ +{ config, pkgs, ... }: + +let + mainUser = config.users.extraUsers.mainUser; + +in { + services.xserver.enable = true; + + + #fonts.enableFontConfig = true; + #fonts.enableFontDir = true; + fonts.fonts = [ + pkgs.xlibs.fontschumachermisc + ]; + #services.xfs.enable = true; + #services.xserver.useXFS = "unix/:7100"; + + #services.xserver.displayManager.desktopManagerHandlesLidAndPower = true; + + #services.xserver.display = 11; + #services.xserver.tty = 11; + # services.xserver.layout = "us"; + # services.xserver.xkbOptions = "eurosign:e"; + + #services.xserver.multitouch.enable = true; + + services.xserver.windowManager.xmonad.extraPackages = hspkgs: with hspkgs; [ + X11-xshape + ]; + services.xserver.windowManager.xmonad.enable = true; + services.xserver.windowManager.xmonad.enableContribAndExtras = true; + services.xserver.windowManager.default = "xmonad"; + services.xserver.desktopManager.default = "none"; + services.xserver.desktopManager.xterm.enable = false; + + services.xserver.displayManager.slim.enable = true; + services.xserver.displayManager.auto.enable = true; + services.xserver.displayManager.auto.user = mainUser.name; + #services.xserver.displayManager.job.logsXsession = true; + + services.xserver.vaapiDrivers = [ pkgs.vaapiIntel ]; + +} diff --git a/old/modules/mkdir/default.nix b/old/modules/mkdir/default.nix new file mode 100644 index 000000000..76f0bb6bc --- /dev/null +++ b/old/modules/mkdir/default.nix @@ -0,0 +1,86 @@ +{ config, pkgs, ... }: + +let + inherit (builtins) readFile; +in + +{ + imports = + [ + { users.extraUsers = import <secrets/extraUsers.nix>; } + ./networking.nix + ./users.nix + ../tv/base.nix + ../tv/base-cac-CentOS-7-64bit.nix + ../tv/config/consul-server.nix + ../tv/exim-smarthost.nix + ../tv/git/public.nix + ../tv/sanitize.nix + { + imports = [ ../tv/identity ]; + tv.identity = { + enable = true; + self = config.tv.identity.hosts.mkdir; + }; + } + { + imports = [ ../tv/iptables ]; + tv.iptables = { + enable = true; + input-internet-accept-new-tcp = [ + "ssh" + "tinc" + "smtp" + "xmpp-client" + "xmpp-server" + ]; + input-retiolum-accept-new-tcp = [ + "http" + ]; + }; + } + { + imports = [ ../tv/retiolum ]; + tv.retiolum = { + enable = true; + hosts = <retiolum-hosts>; + connectTo = [ + "cd" + "fastpoke" + "pigstarter" + "ire" + ]; + }; + } + ]; + + nix.maxJobs = 1; + + environment.systemPackages = with pkgs; [ + git # required for ./deploy, clone_or_update + htop + iftop + iotop + iptables + mutt # for mv + nethogs + rxvt_unicode.terminfo + tcpdump + ]; + + services.journald.extraConfig = '' + SystemMaxUse=1G + RuntimeMaxUse=128M + ''; + + services.openssh = { + enable = true; + hostKeys = [ + # XXX bits here make no science + { bits = 8192; type = "ed25519"; path = "/etc/ssh/ssh_host_ed25519_key"; } + ]; + permitRootLogin = "yes"; + }; + + sound.enable = false; +} diff --git a/old/modules/mkdir/networking.nix b/old/modules/mkdir/networking.nix new file mode 100644 index 000000000..c75e33a1b --- /dev/null +++ b/old/modules/mkdir/networking.nix @@ -0,0 +1,14 @@ +{...}: +{ + networking.hostName = "mkdir"; + networking.interfaces.enp2s1.ip4 = [ + { + address = "162.248.167.241"; + prefixLength = 24; + } + ]; + networking.defaultGateway = "162.248.167.1"; + networking.nameservers = [ + "8.8.8.8" + ]; +} diff --git a/old/modules/mkdir/paths.nix b/old/modules/mkdir/paths.nix new file mode 100644 index 000000000..f873912fb --- /dev/null +++ b/old/modules/mkdir/paths.nix @@ -0,0 +1,12 @@ +{ + lib.file.url = ../../lib; + modules.file.url = ../../modules; + nixpkgs.git = { + url = https://github.com/NixOS/nixpkgs; + rev = "4c01e6d91993b6de128795f4fbdd25f6227fb870"; + cache = ../../tmp/git-cache; + }; + pubkeys.file.url = ../../pubkeys; + retiolum-hosts.file.url = ../../hosts; + secrets.file.url = ../../secrets/cd/nix; +} diff --git a/old/modules/mkdir/users.nix b/old/modules/mkdir/users.nix new file mode 100644 index 000000000..82f078b4e --- /dev/null +++ b/old/modules/mkdir/users.nix @@ -0,0 +1,19 @@ +{ ... }: + +let + inherit (builtins) readFile; +in + +{ + users.extraUsers = + { + root = { + openssh.authorizedKeys.keys = [ + (readFile <pubkeys/deploy_wu.ssh.pub>) + (readFile <pubkeys/tv_wu.ssh.pub>) + ]; + }; + }; + + users.mutableUsers = false; +} diff --git a/old/modules/mors/default.nix b/old/modules/mors/default.nix new file mode 100644 index 000000000..d83d6abc9 --- /dev/null +++ b/old/modules/mors/default.nix @@ -0,0 +1,283 @@ +{ config, pkgs, ... }: + +{ + imports = [ + ../lass/xresources.nix + ../lass/desktop-base.nix + ../lass/programs.nix + ../lass/retiolum-mors.nix + ../lass/xserver-lass.nix + ../tv/synaptics.nix + ../lass/bitcoin.nix + ../lass/browsers.nix + ../lass/games.nix + ../tv/exim-retiolum.nix + ../lass/pass.nix + ../lass/vim.nix + ../lass/virtualbox.nix + ../lass/elster.nix + ../lass/urxvt.nix + ../lass/steam.nix + ../lass/wine.nix + ../lass/texlive.nix + ../common/nixpkgs.nix + ../lass/binary-caches.nix + ../lass/ircd.nix + ../../secrets/mors-pw.nix + ./repos.nix + ../lass/chromium-patched.nix + ./git.nix + ]; + + nixpkgs = { + url = "https://github.com/Lassulus/nixpkgs"; + rev = "45c99e522dcc4ef24cf71dbe38d94a308cb30530"; + }; + + networking.hostName = "mors"; + networking.wireless.enable = true; + + networking.extraHosts = '' + ''; + + nix.maxJobs = 4; + + hardware.enableAllFirmware = true; + nixpkgs.config.allowUnfree = true; + + boot = { + kernelParams = [ + "acpi.brightness_switch_enabled=0" + ]; + loader.grub.enable = true; + loader.grub.version = 2; + loader.grub.device = "/dev/sda"; + + initrd.luks.devices = [ { name = "luksroot"; device = "/dev/sda2"; } ]; + initrd.luks.cryptoModules = [ "aes" "sha512" "sha1" "xts" ]; + initrd.availableKernelModules = [ "xhci_hcd" "ehci_pci" "ahci" "usb_storage" ]; + #kernelModules = [ "kvm-intel" "msr" ]; + kernelModules = [ "msr" ]; + }; + fileSystems = { + "/" = { + device = "/dev/big/nix"; + fsType = "ext4"; + }; + + "/boot" = { + device = "/dev/sda1"; + }; + + "/mnt/loot" = { + device = "/dev/big/loot"; + fsType = "ext4"; + }; + + "/home" = { + device = "/dev/big/home"; + fsType = "ext4"; + }; + + "/home/lass" = { + device = "/dev/big/home-lass"; + fsType = "ext4"; + }; + + "/mnt/backups" = { + device = "/dev/big/backups"; + fsType = "ext4"; + }; + + "/home/games/.local/share/Steam" = { + device = "/dev/big/steam"; + fsType = "ext4"; + }; + + "/home/virtual/virtual" = { + device = "/dev/big/virtual"; + fsType = "ext4"; + }; + + "/mnt/public" = { + device = "/dev/big/public"; + fsType = "ext4"; + }; + }; + + services.udev.extraRules = '' + SUBSYSTEM=="net", ATTR{address}=="a0:88:b4:29:26:bc", NAME="wl0" + SUBSYSTEM=="net", ATTR{address}=="f0:de:f1:0c:a7:63", NAME="et0" + ''; + + #activationScripts + #split up and move into base + system.activationScripts.powertopTunables = '' + #Enable Audio codec power management + echo '1' > '/sys/module/snd_hda_intel/parameters/power_save' + #VM writeback timeout + echo '1500' > '/proc/sys/vm/dirty_writeback_centisecs' + #Autosuspend for USB device Broadcom Bluetooth Device [Broadcom Corp] + echo 'auto' > '/sys/bus/usb/devices/1-1.4/power/control' + #Autosuspend for USB device Biometric Coprocessor + echo 'auto' > '/sys/bus/usb/devices/1-1.3/power/control' + + #Runtime PMs + echo 'auto' > '/sys/bus/pci/devices/0000:00:02.0/power/control' + echo 'auto' > '/sys/bus/pci/devices/0000:00:16.0/power/control' + echo 'auto' > '/sys/bus/pci/devices/0000:00:00.0/power/control' + echo 'auto' > '/sys/bus/pci/devices/0000:03:00.0/power/control' + echo 'auto' > '/sys/bus/pci/devices/0000:00:1f.3/power/control' + echo 'auto' > '/sys/bus/pci/devices/0000:00:1f.2/power/control' + echo 'auto' > '/sys/bus/pci/devices/0000:00:1f.0/power/control' + echo 'auto' > '/sys/bus/pci/devices/0000:00:1d.0/power/control' + echo 'auto' > '/sys/bus/pci/devices/0000:00:1c.3/power/control' + echo 'auto' > '/sys/bus/pci/devices/0000:0d:00.0/power/control' + echo 'auto' > '/sys/bus/pci/devices/0000:00:1c.0/power/control' + echo 'auto' > '/sys/bus/pci/devices/0000:00:1b.0/power/control' + echo 'auto' > '/sys/bus/pci/devices/0000:00:1a.0/power/control' + echo 'auto' > '/sys/bus/pci/devices/0000:00:19.0/power/control' + echo 'auto' > '/sys/bus/pci/devices/0000:00:16.3/power/control' + echo 'auto' > '/sys/bus/pci/devices/0000:00:1c.1/power/control' + echo 'auto' > '/sys/bus/pci/devices/0000:00:1c.4/power/control' + ''; + system.activationScripts.trackpoint = '' + echo 0 > '/sys/devices/platform/i8042/serio1/serio2/speed' + echo 220 > '/sys/devices/platform/i8042/serio1/serio2/sensitivity' + ''; + + services.xserver = { + videoDriver = "intel"; + vaapiDrivers = [ pkgs.vaapiIntel ]; + deviceSection = '' + Option "AccelMethod" "sna" + BusID "PCI:0:2:0" + ''; + }; + + users.extraUsers = { + #main user + mainUser = { + uid = 1337; + name = "lass"; + #isNormalUser = true; + group = "users"; + createHome = true; + home = "/home/lass"; + useDefaultShell = true; + isSystemUser = false; + extraGroups = [ "wheel" "audio" ]; + }; + }; + + environment.systemPackages = with pkgs; [ + ]; + + #TODO: fix this shit + ##fprint stuff + ##sudo fprintd-enroll $USER to save fingerprints + #services.fprintd.enable = true; + #security.pam.services.sudo.fprintAuth = true; + + users.extraGroups = { + loot = { + members = [ + config.users.extraUsers.mainUser.name + "firefox" + "chromium" + "google" + "virtual" + ]; + }; + }; + + networking.firewall = { + allowPing = true; + allowedTCPPorts = [ + 8000 + ]; + allowedUDPPorts = [ + 67 + ]; + }; + + #services.ircdHybrid = { + # enable = true; + + # description = "local test server"; + #}; + + #TODO + #services.urxvtd = { + # enable = true; + # users = [ "lass" ]; + # urxvtPackage = pkgs.rxvt_unicode_with-plugins; + #}; + + #system.activationScripts.iptables = + # let + # log = false; + # when = c: f: if c then f else ""; + # in + # '' + # ip4tables() { ${pkgs.iptables}/sbin/iptables "$@"; } + # ip6tables() { ${pkgs.iptables}/sbin/ip6tables "$@"; } + # ipXtables() { ip4tables "$@"; ip6tables "$@"; } + + # # + # # nat + # # + + # # reset tables + # ipXtables -t nat -F + # ipXtables -t nat -X + + # # + # #ipXtables -t nat -A PREROUTING -j REDIRECT ! -i retiolum -p tcp --dport ssh --to-ports 0 + # ipXtables -t nat -A PREROUTING -j REDIRECT -p tcp --dport 11423 --to-ports ssh + + # # + # # filter + # # + + # # reset tables + # ipXtables -P INPUT DROP + # ipXtables -P FORWARD DROP + # ipXtables -F + # ipXtables -X + + # # create custom chains + # ipXtables -N Retiolum + + # # INPUT + # ipXtables -A INPUT -j ACCEPT -m conntrack --ctstate RELATED,ESTABLISHED + # ipXtables -A INPUT -j ACCEPT -i lo + # ipXtables -A INPUT -j ACCEPT -p tcp --dport ssh -m conntrack --ctstate NEW + # ipXtables -A INPUT -j ACCEPT -p tcp --dport http -m conntrack --ctstate NEW + # ipXtables -A INPUT -j ACCEPT -p tcp --dport tinc -m conntrack --ctstate NEW + # ipXtables -A INPUT -j ACCEPT -p tcp --dport smtp -m conntrack --ctstate NEW + + # #mc + # ipXtables -A INPUT -j ACCEPT -p tcp --dport 25565 + # ipXtables -A INPUT -j ACCEPT -p udp --dport 25565 + + # ipXtables -A INPUT -j Retiolum -i retiolum + # ${when log "ipXtables -A INPUT -j LOG --log-level info --log-prefix 'INPUT DROP '"} + + # # FORWARD + # ${when log "ipXtables -A FORWARD -j LOG --log-level info --log-prefix 'FORWARD DROP '"} + + # # Retiolum + # ip4tables -A Retiolum -j ACCEPT -p icmp --icmp-type echo-request + # ip6tables -A Retiolum -j ACCEPT -p ipv6-icmp -m icmp6 --icmpv6-type echo-request + + + # ${when log "ipXtables -A Retiolum -j LOG --log-level info --log-prefix 'REJECT '"} + # ipXtables -A Retiolum -j REJECT -p tcp --reject-with tcp-reset + # ip4tables -A Retiolum -j REJECT -p udp --reject-with icmp-port-unreachable + # ip4tables -A Retiolum -j REJECT --reject-with icmp-proto-unreachable + # ip6tables -A Retiolum -j REJECT -p udp --reject-with icmp6-port-unreachable + # ip6tables -A Retiolum -j REJECT + + # ''; +} diff --git a/old/modules/mors/git.nix b/old/modules/mors/git.nix new file mode 100644 index 000000000..1dd61d164 --- /dev/null +++ b/old/modules/mors/git.nix @@ -0,0 +1,71 @@ +{ config, lib, pkgs, ... }: + +{ + imports = [ + ../tv/git + ]; + + services.git = + let + inherit (builtins) readFile; + # TODO lib should already include our stuff + inherit (import ../../lib { inherit lib pkgs; }) addNames git; + + krebs-private = name: desc: + { + inherit desc; + hooks = { + post-receive = git.irc-announce { + nick = config.networking.hostName; # TODO make this the default + channel = "#retiolum"; + server = "ire.retiolum"; + }; + }; + } + in rec { + enable = true; + + users = addNames { + tv = { pubkey = readFile <pubkeys/tv.ssh.pub>; }; + lass = { pubkey = readFile <pubkeys/lass.ssh.pub>; }; + uriel = { pubkey = readFile <pubkeys/lass.ssh.pub>; }; + makefu = { pubkey = "xxx"; }; + }; + + repos = addNames { + shitment = { + desc = "shitment repository"; + hooks = { + post-receive = git.irc-announce { + nick = config.networking.hostName; # TODO make this the default + channel = "#retiolum"; + server = "ire.retiolum"; + }; + }; + public = true; + }; + testing = { + desc = "testing repository"; + hooks = { + post-receive = git.irc-announce { + nick = config.networking.hostName; # TODO make this the default + channel = "#repository"; + server = "ire.retiolum"; + }; + }; + public = true; + }; + }; + + rules = with git; with users; with repos; [ + { user = lass; + repo = [ testing shitment ]; + perm = push master [ non-fast-forward create delete merge ]; + } + { user = [ tv uriel makefu ]; + repo = [ testing shitment ]; + perm = fetch; + } + ]; + }; +} diff --git a/old/modules/mors/repos.nix b/old/modules/mors/repos.nix new file mode 100644 index 000000000..e31ba9481 --- /dev/null +++ b/old/modules/mors/repos.nix @@ -0,0 +1,78 @@ +{ ... }: + +{ + imports = [ + ../lass/gitolite-base.nix + ../common/krebs-keys.nix + ../common/krebs-repos.nix + ]; + + services.gitolite = { + repos = { + + config = { + users = { + lass = "RW+"; + uriel = "R"; + tv = "R"; + }; + extraConfig = "option hook.post-receive = irc-announce"; + }; + + pass = { + users = { + lass = "RW+"; + uriel = "R"; + }; + }; + + load-env = { + users = { + lass = "RW+"; + uriel = "R"; + tv = "R"; + }; + extraConfig = "option hook.post-receive = irc-announce"; + }; + + emse-hsdb = { + users = { + lass = "RW+"; + uriel = "R"; + tv = "R"; + }; + extraConfig = "option hook.post-receive = irc-announce"; + }; + + brain = { + users = { + lass = "RW+"; + }; + extraConfig = "option hook.post-receive = irc-announce"; + #hooks.post-receive = irc-announce; + }; + + painload = { + users = { + lass = "RW+"; + }; + extraConfig = "option hook.post-receive = irc-announce"; + }; + + services = { + users = { + lass = "RW+"; + }; + extraConfig = "option hook.post-receive = irc-announce"; + }; + + xmonad-config = { + users = { + lass = "RW+"; + uriel = "R"; + }; + }; + + }; + }; +} diff --git a/old/modules/mu/default.nix b/old/modules/mu/default.nix new file mode 100644 index 000000000..1f4888718 --- /dev/null +++ b/old/modules/mu/default.nix @@ -0,0 +1,466 @@ +# TODO maybe give RT-stuff only to group rt or sth. + +{ config, pkgs, ... }: + +let + lib = import ../../lib { inherit pkgs; }; + + inherit (lib) majmin; +in + +{ + imports = [ + <secrets/mu.hashedPasswords.nix> + ../tv/base.nix + ../tv/exim-retiolum.nix + ../tv/retiolum.nix + ../tv/sanitize.nix + ]; + + nix.maxJobs = 2; + + services.udev.extraRules = '' + SUBSYSTEM=="net", ATTR{address}=="00:90:f5:da:aa:c3", NAME="en0" + SUBSYSTEM=="net", ATTR{address}=="a0:88:b4:1b:ae:6c", NAME="wl0" + + # for jack + KERNEL=="rtc0", GROUP="audio" + KERNEL=="hpet", GROUP="audio" + ''; + + + # hardware configuration + boot.initrd.luks.devices = [ + { name = "vgmu1"; device = "/dev/sda2"; } + ]; + boot.initrd.luks.cryptoModules = [ "aes" "sha512" "xts" ]; + boot.initrd.availableKernelModules = [ "ahci" ]; + #boot.kernelParams = [ + # "intel_pstate=enable" + #]; + boot.kernelModules = [ "fbcon" "kvm-intel" ]; + boot.extraModulePackages = [ ]; + + #boot.kernelPackages = pkgs.linuxPackages_3_17; + + boot.kernel.sysctl = { + # Enable IPv6 Privacy Extensions + "net.ipv6.conf.all.use_tempaddr" = 2; + "net.ipv6.conf.default.use_tempaddr" = 2; + }; + + boot.extraModprobeConfig = '' + options kvm_intel nested=1 + ''; + + fileSystems = { + "/" = { + device = "/dev/vgmu1/nixroot"; + fsType = "ext4"; + options = "defaults,noatime"; + }; + "/home" = { + device = "/dev/vgmu1/home"; + options = "defaults,noatime"; + }; + "/boot" = { + device = "/dev/sda1"; + }; + "/tmp" = { + device = "tmpfs"; + fsType = "tmpfs"; + options = "nosuid,nodev,noatime"; + }; + }; + + swapDevices =[ ]; + + nixpkgs.config.firefox.enableAdobeFlash = true; + nixpkgs.config.chromium.enablePepperFlash = true; + + nixpkgs.config.allowUnfree = true; + hardware.opengl.driSupport32Bit = true; + + hardware.pulseaudio.enable = true; + + hardware.enableAllFirmware = true; + + # Use the gummiboot efi boot loader. + boot.loader.gummiboot.enable = true; + boot.loader.efi.canTouchEfiVariables = true; + + networking.hostName = "mu"; + #networking.wireless.enable = true; + networking.networkmanager.enable = true; + + networking.extraHosts = '' + ''; + + #system.activationScripts.powertopTunables = + # '' + # #echo 1 > /sys/module/snd_hda_intel/parameters/power_save + # echo 1500 > /proc/sys/vm/dirty_writeback_centisecs + # (cd /sys/bus/pci/devices + # for i in *; do + # echo auto > $i/power/control # defaults to 'on' + # done) + # # TODO maybe do this via udev or systemd + # # ref https://wiki.archlinux.org/index.php/Wake-on-LAN + # # disable wol this cannot find ethtool + # # TODO (cd /sys/class/net + # # TODO for i in *; do + # # TODO if ethtool $i | grep -q Wake-on && + # # TODO ! ethtool $i | grep -q 'Wake-on: d'; then + # # TODO ethtool -s $i wol d + # # TODO fi + # # TODO done) + # ${pkgs.ethtool}/sbin/ethtool -s en0 wol d + # ''; + + environment.systemPackages = with pkgs; [ + slock + tinc + iptables + vim + gimp + xsane + firefoxWrapper + chromiumDev + skype + libreoffice + kde4.l10n.de + kde4.networkmanagement + pidgin-with-plugins + pidginotr + + kde4.print_manager + #foomatic_filters + #gutenprint + #cups_pdf_filter + #ghostscript + ]; + + + environment.etc."vim/vimrc".text = '' + set nocp + ''; + environment.etc."vim/vim${majmin pkgs.vim.version}".source = + "${pkgs.vim}/share/vim/vim${majmin pkgs.vim.version}"; + + # multiple-definition-problem when defining environment.variables.EDITOR + environment.extraInit = '' + EDITOR=vim + ''; + environment.variables.VIM = "/etc/vim"; + + i18n.defaultLocale = "de_DE.UTF-8"; + + environment.shellAliases = { + # alias cal='cal -m3' + bc = "bc -q"; + gp = "gp -q"; + df = "df -h"; + du = "du -h"; + # alias grep='grep --color=auto' + + # TODO alias cannot contain #\' + # "ps?" = "ps ax | head -n 1;ps ax | fgrep -v ' grep --color=auto ' | grep"; + + # alias la='ls -lA' + lAtr = "ls -lAtr"; + # alias ll='ls -l' + ls = "ls -h --color=auto --group-directories-first"; + # alias vim='vim -p' + # alias vi='vim' + # alias view='vim -R' + dmesg = "dmesg -L --reltime"; + }; + + + programs.bash = { + interactiveShellInit = '' + HISTCONTROL='erasedups:ignorespace' + HISTSIZE=65536 + HISTFILESIZE=$HISTSIZE + + shopt -s checkhash + shopt -s histappend histreedit histverify + shopt -s no_empty_cmd_completion + complete -d cd + + # TODO source bridge + ''; + promptInit = '' + case $UID in + 0) + PS1='\[\e[1;31m\]\w\[\e[0m\] ' + ;; + 1337) + PS1='\[\e[1;32m\]\w\[\e[0m\] ' + ;; + 2000) + 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 + ''; + }; + + + programs.ssh.startAgent = false; + + + security.setuidPrograms = [ + "sendmail" # for cron + "slock" + ]; + + security.pam.loginLimits = [ + # for jack + { domain = "@audio"; item = "memlock"; type = "-"; value = "unlimited"; } + { domain = "@audio"; item = "rtprio"; type = "-"; value = "99"; } + ]; + + #services.haveged.enable = true; + #security.rngd.enable = true; + + services.retiolum = { + enable = true; + hosts = /etc/nixos/hosts; + connectTo = [ + "gum" + "pigstarter" + ]; + }; + + #services.dbus.enable = true; # rqd4 wpa_supplicant + + fonts.fonts = [ + pkgs.xlibs.fontschumachermisc + ]; + + #services.logind.extraConfig = '' + # HandleHibernateKey=ignore + # HandleLidSwitch=ignore + # HandlePowerKey=ignore + # HandleSuspendKey=ignore + #''; + #services.xserver.displayManager.desktopManagerHandlesLidAndPower = true; + + # Enable the OpenSSH daemon. + services.openssh = { + enable = true; + hostKeys = [ + # XXX bits here make no science + { bits = 8192; type = "ed25519"; path = "/etc/ssh/ssh_host_ed25519_key"; } + ]; + }; + + # Enable CUPS to print documents. + # services.printing.enable = true; + services.printing = { + enable = true; + #drivers = [ + # #pkgs.foomatic_filters + # #pkgs.gutenprint + # #pkgs.cups_pdf_filter + # #pkgs.ghostscript + #]; + #cupsdConf = '' + # LogLevel debug2 + #''; + }; + + # Enable the X11 windowing system. + services.xserver.enable = true; + #services.xserver.display = 11; + #services.xserver.tty = 11; + services.xserver.layout = "de"; + services.xserver.xkbOptions = "eurosign:e"; + + # TODO this is host specific + services.xserver.synaptics = { + enable = true; + twoFingerScroll = true; + #accelFactor = "0.035"; + #additionalOptions = '' + # Option "FingerHigh" "60" + # Option "FingerLow" "60" + #''; + }; + + services.xserver.desktopManager.kde4.enable = true; + services.xserver.displayManager.auto = { + enable = true; + user = "vv"; + }; + + users.defaultUserShell = "/run/current-system/sw/bin/bash"; + users.mutableUsers = false; + users.extraGroups = + { + }; + users.extraUsers = + { + tv = { + uid = 1337; + name = "tv"; + group = "users"; + home = "/home/tv"; + useDefaultShell = true; + extraGroups = [ + "audio" + "video" + "wheel" + ]; + createHome = true; + }; + + vv = { + uid = 2000; + name = "vv"; + home = "/home/vv"; + createHome = true; + group = "users"; + useDefaultShell = true; + extraGroups = [ + "audio" + "video" + "networkmanager" + ]; + }; + }; + + services.journald.extraConfig = '' + SystemMaxUse=1G + RuntimeMaxUse=128M + ''; + + # see tmpfiles.d(5) + systemd.tmpfiles.rules = [ + "d /tmp 1777 root root - -" # does this work with mounted /tmp? + ]; + + # TODO services.smartd + # TODO services.statsd + # TODO services.tor + # TODO write arandr + # TODO what does system.copySystemConfiguration (we need some kind of bku scheme) + # TODO systemd.timers instead of cron(??) + + virtualisation.libvirtd.enable = true; + + # + # iptables + # + networking.firewall.enable = false; + system.activationScripts.iptables = + let + log = false; + when = c: f: if c then f else ""; + in + '' + ip4tables() { ${pkgs.iptables}/sbin/iptables "$@"; } + ip6tables() { ${pkgs.iptables}/sbin/ip6tables "$@"; } + ipXtables() { ip4tables "$@"; ip6tables "$@"; } + + # + # nat + # + + # reset tables + ipXtables -t nat -F + ipXtables -t nat -X + + # + ipXtables -t nat -A PREROUTING -j REDIRECT ! -i retiolum -p tcp --dport ssh --to-ports 0 + ipXtables -t nat -A PREROUTING -j REDIRECT -p tcp --dport 11423 --to-ports ssh + + # + # filter + # + + # reset tables + ipXtables -P INPUT DROP + ipXtables -P FORWARD DROP + ipXtables -F + ipXtables -X + + # create custom chains + ipXtables -N Retiolum + + # INPUT + ipXtables -A INPUT -j ACCEPT -m conntrack --ctstate RELATED,ESTABLISHED + ipXtables -A INPUT -j ACCEPT -i lo + ipXtables -A INPUT -j ACCEPT -p tcp --dport ssh -m conntrack --ctstate NEW + ipXtables -A INPUT -j ACCEPT -p tcp --dport http -m conntrack --ctstate NEW + ipXtables -A INPUT -j ACCEPT -p tcp --dport tinc -m conntrack --ctstate NEW + ipXtables -A INPUT -j ACCEPT -p tcp --dport smtp -m conntrack --ctstate NEW + ipXtables -A INPUT -j Retiolum -i retiolum + ${when log "ipXtables -A INPUT -j LOG --log-level info --log-prefix 'INPUT DROP '"} + + # FORWARD + ${when log "ipXtables -A FORWARD -j LOG --log-level info --log-prefix 'FORWARD DROP '"} + + # Retiolum + ip4tables -A Retiolum -j ACCEPT -p icmp --icmp-type echo-request + ip6tables -A Retiolum -j ACCEPT -p ipv6-icmp -m icmp6 --icmpv6-type echo-request + + + ${when log "ipXtables -A Retiolum -j LOG --log-level info --log-prefix 'REJECT '"} + ipXtables -A Retiolum -j REJECT -p tcp --reject-with tcp-reset + ip4tables -A Retiolum -j REJECT -p udp --reject-with icmp-port-unreachable + ip4tables -A Retiolum -j REJECT --reject-with icmp-proto-unreachable + ip6tables -A Retiolum -j REJECT -p udp --reject-with icmp6-port-unreachable + ip6tables -A Retiolum -j REJECT + + ''; + + + + + #system.replaceRuntimeDependencies = with pkgs; + # let + # bashVulnPatches = [ + # (fetchurl { + # url = "mirror://gnu/bash/bash-4.2-patches/bash42-048"; + # sha256 = "091xk1ms7ycnczsl3fx461gjhj69j6ycnfijlymwj6mj60ims6km"; + # }) + # (fetchurl { + # url = "file:///etc/nixos/bash-20140926.patch"; + # sha256 = "0gdwnimsbi4vh5l46krss4wjrgbch94skn4y2w3rpvb1w4jypha4"; + # }) + # ]; + # in + # [ + # { + # original = bash; + # replacement = pkgs.lib.overrideDerivation bash (oldAttrs: { + # patches = oldAttrs.patches ++ bashVulnPatches; + # }); + # } + # { + # original = bashInteractive; + # replacement = pkgs.lib.overrideDerivation bashInteractive (oldAttrs: { + # patches = oldAttrs.patches ++ bashVulnPatches; + # }); + # } + # { + # original = bitlbee; + # replacement = pkgs.lib.overrideDerivation bitlbee (oldAttrs: { + # configureFlags = [ + # "--gcov=1" + # "--otr=1" + # "--ssl=gnutls" + # ]; + # }); + # } + #]; + + +} diff --git a/old/modules/mu/paths.nix b/old/modules/mu/paths.nix new file mode 100644 index 000000000..1c4ce52a1 --- /dev/null +++ b/old/modules/mu/paths.nix @@ -0,0 +1,12 @@ +{ + lib.file.url = ../../lib; + modules.file.url = ../../modules; + nixpkgs.git = { + url = https://github.com/NixOS/nixpkgs; + rev = "4c01e6d91993b6de128795f4fbdd25f6227fb870"; + cache = ../../tmp/git-cache; + }; + pubkeys.file.url = ../../pubkeys; + retiolum-hosts.file.url = ../../hosts; + secrets.file.url = ../../secrets/wu/nix; +} diff --git a/old/modules/nomic/default.nix b/old/modules/nomic/default.nix new file mode 100644 index 000000000..f61f97a89 --- /dev/null +++ b/old/modules/nomic/default.nix @@ -0,0 +1,105 @@ +{ config, pkgs, ... }: + +let + location = pkgs.lib.nameValuePair; # TODO this is also in modules/tv/git/cgit.nix +in + +{ + imports = [ + ./hardware-configuration.nix + ./users.nix + ../tv/base.nix + ../tv/config/consul-server.nix + ../tv/environment.nix + ../tv/exim-retiolum.nix + ../tv/git/public.nix + ../tv/sanitize.nix + ../tv/smartd.nix + { + imports = [ ../tv/identity ]; + tv.identity = { + enable = true; + self = config.tv.identity.hosts.nomic; + }; + } + { + imports = [ ../tv/iptables ]; + tv.iptables = { + enable = true; + input-internet-accept-new-tcp = [ + "ssh" + "http" + "tinc" + "smtp" + ]; + }; + } + { + imports = [ ../tv/nginx ]; + tv.nginx = { + enable = true; + retiolum-locations = [ + (location "~ ^/~(.+?)(/.*)?\$" '' + alias /home/$1/public_html$2; + '') + ]; + }; + } + { + imports = [ ../tv/retiolum ]; + tv.retiolum = { + enable = true; + hosts = <retiolum-hosts>; + connectTo = [ + "gum" + "pigstarter" + ]; + }; + } + ]; + + boot.kernel.sysctl = { + # Enable IPv6 Privacy Extensions + "net.ipv6.conf.all.use_tempaddr" = 2; + "net.ipv6.conf.default.use_tempaddr" = 2; + }; + + boot.tmpOnTmpfs = true; + + environment.systemPackages = with pkgs; [ + (writeScriptBin "play" '' + #! /bin/sh + set -euf + mpv() { exec ${mpv}/bin/mpv "$@"; } + case $1 in + deepmix) mpv http://deepmix.ru/deepmix128.pls;; + groovesalad) mpv http://somafm.com/play/groovesalad;; + ntslive) mpv http://listen2.ntslive.co.uk/listen.pls;; + *) + echo "$0: bad argument: $*" >&2 + exit 23 + esac + '') + rxvt_unicode.terminfo + tmux + ]; + + networking = { + hostName = "nomic"; + wireless.enable = true; + }; + + services.logind.extraConfig = '' + HandleHibernateKey=ignore + HandleLidSwitch=ignore + HandlePowerKey=ignore + HandleSuspendKey=ignore + ''; + + services.openssh = { + enable = true; + hostKeys = [ + { type = "ed25519"; path = "/etc/ssh/ssh_host_ed25519_key"; } + ]; + }; +} diff --git a/old/modules/nomic/hardware-configuration.nix b/old/modules/nomic/hardware-configuration.nix new file mode 100644 index 000000000..8a00730f1 --- /dev/null +++ b/old/modules/nomic/hardware-configuration.nix @@ -0,0 +1,49 @@ +{ config, ... }: + +{ + boot.initrd.luks = { + cryptoModules = [ "aes" "sha1" "xts" ]; + devices = [ + { + name = "luks1"; + device = "/dev/disk/by-uuid/cac73902-1023-4906-8e95-3a8b245337d4"; + } + ]; + }; + + boot.initrd.availableKernelModules = [ "ahci" ]; + boot.kernelModules = [ "kvm-intel" "wl" ]; + boot.extraModulePackages = [ config.boot.kernelPackages.broadcom_sta ]; + + boot.loader.grub = { + device = "/dev/sda"; + splashImage = null; + }; + + fileSystems."/" = + { device = "/dev/disk/by-uuid/de4780fc-0473-4708-81df-299b7383274c"; + fsType = "btrfs"; + }; + + fileSystems."/boot" = + { device = "/dev/disk/by-uuid/be3a1d80-3157-4d7c-86cc-ef01b64eff5e"; + fsType = "ext4"; + }; + + fileSystems."/home" = + { device = "/dev/disk/by-uuid/9db9c8ff-51da-4cbd-9f0a-0cd3333bbaff"; + fsType = "btrfs"; + }; + + swapDevices = [ ]; + + nix = { + buildCores = 2; + maxJobs = 2; + daemonIONiceLevel = 1; + daemonNiceLevel = 1; + }; + + # For config.boot.kernelPackages.broadcom_sta + nixpkgs.config.allowUnfree = true; +} diff --git a/old/modules/nomic/paths.nix b/old/modules/nomic/paths.nix new file mode 100644 index 000000000..0bcf1d36d --- /dev/null +++ b/old/modules/nomic/paths.nix @@ -0,0 +1,12 @@ +{ + lib.file.url = ../../lib; + modules.file.url = ../../modules; + nixpkgs.git = { + url = https://github.com/NixOS/nixpkgs; + rev = "4e5e441"; + cache = ../../tmp/git-cache; + }; + pubkeys.file.url = ../../pubkeys; + retiolum-hosts.file.url = ../../hosts; + secrets.file.url = ../../secrets/nomic/nix; +} diff --git a/old/modules/nomic/users.nix b/old/modules/nomic/users.nix new file mode 100644 index 000000000..70e1d8dcd --- /dev/null +++ b/old/modules/nomic/users.nix @@ -0,0 +1,42 @@ +{ pkgs, ... }: + +{ + imports = [ + { users = import <secrets/users.nix>; } + { + users.extraUsers = { + root = { + openssh.authorizedKeys.keys = [ + (pkgs.lib.readFile <pubkeys/tv_wu.ssh.pub>) + ]; + }; + tv = { + uid = 1337; + group = "users"; + home = "/home/tv"; + createHome = true; + useDefaultShell = true; + extraGroups = [ + "audio" + "video" + "wheel" + ]; + openssh.authorizedKeys.keys = [ + (pkgs.lib.readFile <pubkeys/tv_wu.ssh.pub>) + ]; + }; + }; + } + ]; + + users.defaultUserShell = "/run/current-system/sw/bin/bash"; + users.mutableUsers = false; + + security.setuidPrograms = [ + "sendmail" # for sudo + ]; + + security.sudo.extraConfig = '' + Defaults mailto="tv@wu.retiolum" + ''; +} diff --git a/old/modules/rmdir/default.nix b/old/modules/rmdir/default.nix new file mode 100644 index 000000000..7279df778 --- /dev/null +++ b/old/modules/rmdir/default.nix @@ -0,0 +1,87 @@ +{ config, pkgs, ... }: + +let + inherit (builtins) readFile; +in + +{ + imports = + [ + { users.extraUsers = import <secrets/extraUsers.nix>; } + ./networking.nix + ./users.nix + ../tv/base.nix + ../tv/base-cac-CentOS-7-64bit.nix + ../tv/config/consul-server.nix + ../tv/exim-smarthost.nix + ../tv/git/public.nix + ../tv/sanitize.nix + { + imports = [ ../tv/identity ]; + tv.identity = { + enable = true; + self = config.tv.identity.hosts.rmdir; + }; + } + { + imports = [ ../tv/iptables ]; + tv.iptables = { + enable = true; + input-internet-accept-new-tcp = [ + "ssh" + "tinc" + "smtp" + "xmpp-client" + "xmpp-server" + ]; + input-retiolum-accept-new-tcp = [ + "http" + ]; + }; + } + { + imports = [ ../tv/retiolum ]; + tv.retiolum = { + enable = true; + hosts = <retiolum-hosts>; + connectTo = [ + "cd" + "mkdir" + "fastpoke" + "pigstarter" + "ire" + ]; + }; + } + ]; + + nix.maxJobs = 1; + + environment.systemPackages = with pkgs; [ + git # required for ./deploy, clone_or_update + htop + iftop + iotop + iptables + mutt # for mv + nethogs + rxvt_unicode.terminfo + tcpdump + ]; + + services.journald.extraConfig = '' + SystemMaxUse=1G + RuntimeMaxUse=128M + ''; + + services.openssh = { + enable = true; + hostKeys = [ + # XXX bits here make no science + { bits = 8192; type = "ed25519"; path = "/etc/ssh/ssh_host_ed25519_key"; } + ]; + permitRootLogin = "yes"; + }; + + sound.enable = false; +} diff --git a/old/modules/rmdir/networking.nix b/old/modules/rmdir/networking.nix new file mode 100644 index 000000000..fb39c5dd5 --- /dev/null +++ b/old/modules/rmdir/networking.nix @@ -0,0 +1,15 @@ +_: + +{ + networking.hostName = "rmdir"; + networking.interfaces.enp2s1.ip4 = [ + { + address = "167.88.44.94"; + prefixLength = 24; + } + ]; + networking.defaultGateway = "167.88.44.1"; + networking.nameservers = [ + "8.8.8.8" + ]; +} diff --git a/old/modules/rmdir/paths.nix b/old/modules/rmdir/paths.nix new file mode 100644 index 000000000..f873912fb --- /dev/null +++ b/old/modules/rmdir/paths.nix @@ -0,0 +1,12 @@ +{ + lib.file.url = ../../lib; + modules.file.url = ../../modules; + nixpkgs.git = { + url = https://github.com/NixOS/nixpkgs; + rev = "4c01e6d91993b6de128795f4fbdd25f6227fb870"; + cache = ../../tmp/git-cache; + }; + pubkeys.file.url = ../../pubkeys; + retiolum-hosts.file.url = ../../hosts; + secrets.file.url = ../../secrets/cd/nix; +} diff --git a/old/modules/rmdir/users.nix b/old/modules/rmdir/users.nix new file mode 100644 index 000000000..82f078b4e --- /dev/null +++ b/old/modules/rmdir/users.nix @@ -0,0 +1,19 @@ +{ ... }: + +let + inherit (builtins) readFile; +in + +{ + users.extraUsers = + { + root = { + openssh.authorizedKeys.keys = [ + (readFile <pubkeys/deploy_wu.ssh.pub>) + (readFile <pubkeys/tv_wu.ssh.pub>) + ]; + }; + }; + + users.mutableUsers = false; +} diff --git a/old/modules/tv/base-cac-CentOS-7-64bit.nix b/old/modules/tv/base-cac-CentOS-7-64bit.nix new file mode 100644 index 000000000..42ab481b3 --- /dev/null +++ b/old/modules/tv/base-cac-CentOS-7-64bit.nix @@ -0,0 +1,27 @@ +{ config, pkgs, ... }: + +{ + boot.loader.grub.device = "/dev/sda"; + boot.loader.grub.enable = true; + boot.loader.grub.version = 2; + + boot.initrd.availableKernelModules = [ + "ata_piix" + "vmw_pvscsi" + ]; + + fileSystems."/" = { + device = "/dev/centos/root"; + fsType = "xfs"; + }; + + fileSystems."/boot" = { + device = "/dev/sda1"; + fsType = "xfs"; + }; + + swapDevices = [ + { device = "/dev/centos/swap"; } + ]; +} + diff --git a/old/modules/tv/base.nix b/old/modules/tv/base.nix new file mode 100644 index 000000000..94f3609cc --- /dev/null +++ b/old/modules/tv/base.nix @@ -0,0 +1,16 @@ +{ config, pkgs, ... }: + +{ + time.timeZone = "Europe/Berlin"; + + # TODO check if both are required: + nix.chrootDirs = [ "/etc/protocols" pkgs.iana_etc.outPath ]; + + nix.trustedBinaryCaches = [ + "https://cache.nixos.org" + "http://cache.nixos.org" + "http://hydra.nixos.org" + ]; + + nix.useChroot = true; +} diff --git a/old/modules/tv/config/consul-client.nix b/old/modules/tv/config/consul-client.nix new file mode 100644 index 000000000..0a8bf4d75 --- /dev/null +++ b/old/modules/tv/config/consul-client.nix @@ -0,0 +1,9 @@ +{ pkgs, ... }: + +{ + imports = [ ./consul-server.nix ]; + + tv.consul = { + server = pkgs.lib.mkForce false; + }; +} diff --git a/old/modules/tv/config/consul-server.nix b/old/modules/tv/config/consul-server.nix new file mode 100644 index 000000000..4cedbd349 --- /dev/null +++ b/old/modules/tv/config/consul-server.nix @@ -0,0 +1,22 @@ +{ config, ... }: + +{ + imports = [ ../../tv/consul ]; + tv.consul = rec { + enable = true; + + inherit (config.tv.identity) self; + inherit (self) dc; + + server = true; + + hosts = with config.tv.identity.hosts; [ + # TODO get this list automatically from each host where tv.consul.enable is true + cd + mkdir + nomic + rmdir + #wu + ]; + }; +} diff --git a/old/modules/tv/consul/default.nix b/old/modules/tv/consul/default.nix new file mode 100644 index 000000000..2ee6fb8c2 --- /dev/null +++ b/old/modules/tv/consul/default.nix @@ -0,0 +1,121 @@ +{ config, lib, pkgs, ... }: + +# if quorum gets lost, then start any node with a config that doesn't contain bootstrap_expect +# but -bootstrap +# TODO consul-bootstrap HOST that actually does is +# TODO tools to inspect state of a cluster in outage state + +with builtins; +with lib; +let + cfg = config.tv.consul; + + out = { + imports = [ ../../tv/iptables ]; + options.tv.consul = api; + config = mkIf cfg.enable (mkMerge [ + imp + { tv.iptables.input-retiolum-accept-new-tcp = [ "8300" "8301" ]; } + # TODO udp for 8301 + ]); + }; + + api = { + # TODO inherit (lib) api.options.enable; oder so + enable = mkOption { + type = types.bool; + default = false; + description = "enable tv.consul"; + }; + dc = mkOption { + type = types.unspecified; + }; + hosts = mkOption { + type = with types; listOf unspecified; + }; + encrypt-file = mkOption { + type = types.str; # TODO path (but not just into store) + default = "/etc/consul/encrypt.json"; + }; + data-dir = mkOption { + type = types.str; # TODO path (but not just into store) + default = "/var/lib/consul"; + }; + self = mkOption { + type = types.unspecified; + }; + server = mkOption { + type = types.bool; + default = false; + }; + GOMAXPROCS = mkOption { + type = types.int; + default = cfg.self.cores; + }; + }; + + consul-config = { + datacenter = cfg.dc; + data_dir = cfg.data-dir; + log_level = "INFO"; + #node_name = + server = cfg.server; + bind_addr = cfg.self.addr; # TODO cfg.addr + enable_syslog = true; + retry_join = map (getAttr "addr") (filter (host: host.fqdn != cfg.self.fqdn) cfg.hosts); + leave_on_terminate = true; + } // optionalAttrs cfg.server { + bootstrap_expect = length cfg.hosts; + leave_on_terminate = false; + }; + + imp = { + environment.systemPackages = with pkgs; [ + consul + ]; + + systemd.services.consul = { + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + path = with pkgs; [ + consul + ]; + environment = { + GOMAXPROCS = toString cfg.GOMAXPROCS; + }; + serviceConfig = { + PermissionsStartOnly = "true"; + SyslogIdentifier = "consul"; + User = user.name; + PrivateTmp = "true"; + Restart = "always"; + ExecStartPre = pkgs.writeScript "consul-init" '' + #! /bin/sh + mkdir -p ${cfg.data-dir} + chown consul: ${cfg.data-dir} + ''; + ExecStart = pkgs.writeScript "consul-service" '' + #! /bin/sh + set -euf + exec >/dev/null + exec consul agent \ + -config-file=${toFile "consul.json" (toJSON consul-config)} \ + -config-file=${cfg.encrypt-file} \ + ''; + #-node=${cfg.self.fqdn} \ + #ExecStart = "${tinc}/sbin/tincd -c ${confDir} -d 0 -U ${user} -D"; + }; + }; + + users.extraUsers = singleton { + inherit (user) name uid; + }; + }; + + user = { + name = "consul"; + uid = 2983239726; # genid consul + }; + +in +out diff --git a/old/modules/tv/ejabberd.nix b/old/modules/tv/ejabberd.nix new file mode 100644 index 000000000..54a9aad0f --- /dev/null +++ b/old/modules/tv/ejabberd.nix @@ -0,0 +1,867 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + inherit (pkgs) ejabberd writeScript writeScriptBin utillinux; + inherit (lib) makeSearchPath; + + cfg = config.services.ejabberd-cd; + + # XXX this is a placeholder that happens to work the default strings. + toErlang = builtins.toJSON; + +in + +{ + + ####### interface + + options = { + + services.ejabberd-cd = { + + enable = mkOption { + default = false; + description = "Whether to enable ejabberd server"; + }; + + certFile = mkOption { + # TODO if it's types.path then it gets copied to /nix/store with + # bad unsafe permissions... + type = types.string; + default = "/etc/ejabberd/ejabberd.pem"; + description = '' + TODO + ''; + }; + + config = mkOption { + type = types.string; + default = ""; + description = '' + TODO + ''; + }; + + user = mkOption { + type = types.string; + default = "ejabberd"; + description = '' + TODO + ''; + }; + + group = mkOption { + type = types.string; + default = "ejabberd"; + description = '' + TODO + ''; + }; + + + # spoolDir = mkOption { + # default = "/var/lib/ejabberd"; + # description = "Location of the spooldir of ejabberd"; + # }; + + # logsDir = mkOption { + # default = "/var/log/ejabberd"; + # description = "Location of the logfile directory of ejabberd"; + # }; + + # confDir = mkOption { + # default = "/var/ejabberd"; + # description = "Location of the config directory of ejabberd"; + # }; + + # virtualHosts = mkOption { + # default = "\"localhost\""; + # description = "Virtualhosts that ejabberd should host. Hostnames are surrounded with doublequotes and separated by commas"; + # }; + + # loadDumps = mkOption { + # default = []; + # description = "Configuration dump that should be loaded on the first startup"; + # example = literalExample "[ ./myejabberd.dump ]"; + # }; + + # config + }; + + }; + + + ####### implementation + + config = + let + my-ejabberdctl = writeScriptBin "ejabberdctl" '' + #! /bin/sh + set -euf + exec env \ + SPOOLDIR=/var/ejabberd \ + EJABBERD_CONFIG_PATH=/etc/ejabberd.cfg \ + ${ejabberd}/bin/ejabberdctl \ + --logs /var/ejabberd \ + "$@" + ''; + in + mkIf cfg.enable { + #environment.systemPackages = [ pkgs.ejabberd ]; + + environment = { + etc."ejabberd.cfg".text = '' + %%% + %%% ejabberd configuration file + %%% + %%%' + + %%% The parameters used in this configuration file are explained in more detail + %%% in the ejabberd Installation and Operation Guide. + %%% Please consult the Guide in case of doubts, it is included with + %%% your copy of ejabberd, and is also available online at + %%% http://www.process-one.net/en/ejabberd/docs/ + + %%% This configuration file contains Erlang terms. + %%% In case you want to understand the syntax, here are the concepts: + %%% + %%% - The character to comment a line is % + %%% + %%% - Each term ends in a dot, for example: + %%% override_global. + %%% + %%% - A tuple has a fixed definition, its elements are + %%% enclosed in {}, and separated with commas: + %%% {loglevel, 4}. + %%% + %%% - A list can have as many elements as you want, + %%% and is enclosed in [], for example: + %%% [http_poll, web_admin, tls] + %%% + %%% - A keyword of ejabberd is a word in lowercase. + %%% Strings are enclosed in "" and can contain spaces, dots, ... + %%% {language, "en"}. + %%% {ldap_rootdn, "dc=example,dc=com"}. + %%% + %%% - This term includes a tuple, a keyword, a list, and two strings: + %%% {hosts, ["jabber.example.net", "im.example.com"]}. + %%% + + + %%%. ======================= + %%%' OVERRIDE STORED OPTIONS + + %% + %% Override the old values stored in the database. + %% + + %% + %% Override global options (shared by all ejabberd nodes in a cluster). + %% + %%override_global. + + %% + %% Override local options (specific for this particular ejabberd node). + %% + %%override_local. + + %% + %% Remove the Access Control Lists before new ones are added. + %% + %%override_acls. + + + %%%. ========= + %%%' DEBUGGING + + %% + %% loglevel: Verbosity of log files generated by ejabberd. + %% 0: No ejabberd log at all (not recommended) + %% 1: Critical + %% 2: Error + %% 3: Warning + %% 4: Info + %% 5: Debug + %% + {loglevel, 3}. + + %% + %% watchdog_admins: Only useful for developers: if an ejabberd process + %% consumes a lot of memory, send live notifications to these XMPP + %% accounts. + %% + %%{watchdog_admins, ["bob@example.com"]}. + + + %%%. ================ + %%%' SERVED HOSTNAMES + + %% + %% hosts: Domains served by ejabberd. + %% You can define one or several, for example: + %% {hosts, ["example.net", "example.com", "example.org"]}. + %% + {hosts, ["jabber.viljetic.de"]}. + + %% + %% route_subdomains: Delegate subdomains to other XMPP servers. + %% For example, if this ejabberd serves example.org and you want + %% to allow communication with an XMPP server called im.example.org. + %% + %%{route_subdomains, s2s}. + + + %%%. =============== + %%%' LISTENING PORTS + + %% + %% listen: The ports ejabberd will listen on, which service each is handled + %% by and what options to start it with. + %% + {listen, + [ + + {5222, ejabberd_c2s, [ + + %% + %% If TLS is compiled in and you installed a SSL + %% certificate, specify the full path to the + %% file and uncomment this line: + %% + starttls, + {certfile, ${toErlang cfg.certFile}}, + + {access, c2s}, + {shaper, c2s_shaper}, + {max_stanza_size, 65536} + ]}, + + {5269, ejabberd_s2s_in, [ + {shaper, s2s_shaper}, + {max_stanza_size, 131072} + ]}, + + %% + %% ejabberd_service: Interact with external components (transports, ...) + %% + %%{8888, ejabberd_service, [ + %% {access, all}, + %% {shaper_rule, fast}, + %% {ip, {127, 0, 0, 1}}, + %% {hosts, ["icq.example.org", "sms.example.org"], + %% [{password, "secret"}] + %% } + %% ]}, + + %% + %% ejabberd_stun: Handles STUN Binding requests + %% + %%{{3478, udp}, ejabberd_stun, []}, + + {5280, ejabberd_http, [ + %%{request_handlers, + %% [ + %% {["pub", "archive"], mod_http_fileserver} + %% ]}, + captcha, + http_bind, + http_poll, + %%register, + web_admin + ]} + + ]}. + + %% + %% s2s_use_starttls: Enable STARTTLS + Dialback for S2S connections. + %% Allowed values are: false optional required required_trusted + %% You must specify a certificate file. + %% + {s2s_use_starttls, required}. + + %% + %% s2s_certfile: Specify a certificate file. + %% + {s2s_certfile, ${toErlang cfg.certFile}}. + + %% + %% domain_certfile: Specify a different certificate for each served hostname. + %% + %%{domain_certfile, "example.org", "/path/to/example_org.pem"}. + %%{domain_certfile, "example.com", "/path/to/example_com.pem"}. + + %% + %% S2S whitelist or blacklist + %% + %% Default s2s policy for undefined hosts. + %% + %%{s2s_default_policy, allow}. + + %% + %% Allow or deny communication with specific servers. + %% + %%{{s2s_host, "goodhost.org"}, allow}. + %%{{s2s_host, "badhost.org"}, deny}. + + %% + %% Outgoing S2S options + %% + %% Preferred address families (which to try first) and connect timeout + %% in milliseconds. + %% + %%{outgoing_s2s_options, [ipv4, ipv6], 10000}. + + + %%%. ============== + %%%' AUTHENTICATION + + %% + %% auth_method: Method used to authenticate the users. + %% The default method is the internal. + %% If you want to use a different method, + %% comment this line and enable the correct ones. + %% + {auth_method, internal}. + %% + %% Store the plain passwords or hashed for SCRAM: + %%{auth_password_format, plain}. + %%{auth_password_format, scram}. + %% + %% Define the FQDN if ejabberd doesn't detect it: + %%{fqdn, "server3.example.com"}. + + %% + %% Authentication using external script + %% Make sure the script is executable by ejabberd. + %% + %%{auth_method, external}. + %{extauth_program, "$ {ejabberd-auth}"}. + + %% + %% Authentication using ODBC + %% Remember to setup a database in the next section. + %% + %%{auth_method, odbc}. + + %% + %% Authentication using PAM + %% + %%{auth_method, pam}. + %%{pam_service, "pamservicename"}. + + %% + %% Authentication using LDAP + %% + %%{auth_method, ldap}. + %% + %% List of LDAP servers: + %%{ldap_servers, ["localhost"]}. + %% + %% Encryption of connection to LDAP servers: + %%{ldap_encrypt, none}. + %%{ldap_encrypt, tls}. + %% + %% Port to connect to on LDAP servers: + %%{ldap_port, 389}. + %%{ldap_port, 636}. + %% + %% LDAP manager: + %%{ldap_rootdn, "dc=example,dc=com"}. + %% + %% Password of LDAP manager: + %%{ldap_password, "******"}. + %% + %% Search base of LDAP directory: + %%{ldap_base, "dc=example,dc=com"}. + %% + %% LDAP attribute that holds user ID: + %%{ldap_uids, [{"mail", "%u@mail.example.org"}]}. + %% + %% LDAP filter: + %%{ldap_filter, "(objectClass=shadowAccount)"}. + + %% + %% Anonymous login support: + %% auth_method: anonymous + %% anonymous_protocol: sasl_anon | login_anon | both + %% allow_multiple_connections: true | false + %% + %%{host_config, "public.example.org", [{auth_method, anonymous}, + %% {allow_multiple_connections, false}, + %% {anonymous_protocol, sasl_anon}]}. + %% + %% To use both anonymous and internal authentication: + %% + %%{host_config, "public.example.org", [{auth_method, [internal, anonymous]}]}. + + + %%%. ============== + %%%' DATABASE SETUP + + %% ejabberd by default uses the internal Mnesia database, + %% so you do not necessarily need this section. + %% This section provides configuration examples in case + %% you want to use other database backends. + %% Please consult the ejabberd Guide for details on database creation. + + %% + %% MySQL server: + %% + %%{odbc_server, {mysql, "server", "database", "username", "password"}}. + %% + %% If you want to specify the port: + %%{odbc_server, {mysql, "server", 1234, "database", "username", "password"}}. + + %% + %% PostgreSQL server: + %% + %%{odbc_server, {pgsql, "server", "database", "username", "password"}}. + %% + %% If you want to specify the port: + %%{odbc_server, {pgsql, "server", 1234, "database", "username", "password"}}. + %% + %% If you use PostgreSQL, have a large database, and need a + %% faster but inexact replacement for "select count(*) from users" + %% + %%{pgsql_users_number_estimate, true}. + + %% + %% ODBC compatible or MSSQL server: + %% + %%{odbc_server, "DSN=ejabberd;UID=ejabberd;PWD=ejabberd"}. + + %% + %% Number of connections to open to the database for each virtual host + %% + %%{odbc_pool_size, 10}. + + %% + %% Interval to make a dummy SQL request to keep the connections to the + %% database alive. Specify in seconds: for example 28800 means 8 hours + %% + %%{odbc_keepalive_interval, undefined}. + + + %%%. =============== + %%%' TRAFFIC SHAPERS + + %% + %% The "normal" shaper limits traffic speed to 1000 B/s + %% + {shaper, normal, {maxrate, 1000}}. + + %% + %% The "fast" shaper limits traffic speed to 50000 B/s + %% + {shaper, fast, {maxrate, 50000}}. + + %% + %% This option specifies the maximum number of elements in the queue + %% of the FSM. Refer to the documentation for details. + %% + {max_fsm_queue, 1000}. + + + %%%. ==================== + %%%' ACCESS CONTROL LISTS + + %% + %% The 'admin' ACL grants administrative privileges to XMPP accounts. + %% You can put here as many accounts as you want. + %% + %%{acl, admin, {user, "aleksey", "localhost"}}. + %%{acl, admin, {user, "ermine", "example.org"}}. + + %% + %% Blocked users + %% + %%{acl, blocked, {user, "baduser", "example.org"}}. + %%{acl, blocked, {user, "test"}}. + + %% + %% Local users: don't modify this line. + %% + {acl, local, {user_regexp, ""}}. + + %% + %% More examples of ACLs + %% + %%{acl, jabberorg, {server, "jabber.org"}}. + %%{acl, aleksey, {user, "aleksey", "jabber.ru"}}. + %%{acl, test, {user_regexp, "^test"}}. + %%{acl, test, {user_glob, "test*"}}. + + %% + %% Define specific ACLs in a virtual host. + %% + %%{host_config, "localhost", + %% [ + %% {acl, admin, {user, "bob-local", "localhost"}} + %% ] + %%}. + + + %%%. ============ + %%%' ACCESS RULES + + %% Maximum number of simultaneous sessions allowed for a single user: + {access, max_user_sessions, [{10, all}]}. + + %% Maximum number of offline messages that users can have: + {access, max_user_offline_messages, [{5000, admin}, {100, all}]}. + + %% This rule allows access only for local users: + {access, local, [{allow, local}]}. + + %% Only non-blocked users can use c2s connections: + {access, c2s, [{deny, blocked}, + {allow, all}]}. + + %% For C2S connections, all users except admins use the "normal" shaper + {access, c2s_shaper, [{none, admin}, + {normal, all}]}. + + %% All S2S connections use the "fast" shaper + {access, s2s_shaper, [{fast, all}]}. + + %% Only admins can send announcement messages: + {access, announce, [{allow, admin}]}. + + %% Only admins can use the configuration interface: + {access, configure, [{allow, admin}]}. + + %% Admins of this server are also admins of the MUC service: + {access, muc_admin, [{allow, admin}]}. + + %% Only accounts of the local ejabberd server can create rooms: + {access, muc_create, [{allow, local}]}. + + %% All users are allowed to use the MUC service: + {access, muc, [{allow, all}]}. + + %% Only accounts on the local ejabberd server can create Pubsub nodes: + {access, pubsub_createnode, [{allow, local}]}. + + %% In-band registration allows registration of any possible username. + %% To disable in-band registration, replace 'allow' with 'deny'. + {access, register, [{allow, all}]}. + + %% By default the frequency of account registrations from the same IP + %% is limited to 1 account every 10 minutes. To disable, specify: infinity + %%{registration_timeout, 600}. + + %% + %% Define specific Access Rules in a virtual host. + %% + %%{host_config, "localhost", + %% [ + %% {access, c2s, [{allow, admin}, {deny, all}]}, + %% {access, register, [{deny, all}]} + %% ] + %%}. + + + %%%. ================ + %%%' DEFAULT LANGUAGE + + %% + %% language: Default language used for server messages. + %% + {language, "en"}. + + %% + %% Set a different default language in a virtual host. + %% + %%{host_config, "localhost", + %% [{language, "ru"}] + %%}. + + + %%%. ======= + %%%' CAPTCHA + + %% + %% Full path to a script that generates the image. + %% + %%{captcha_cmd, "/lib/ejabberd/priv/bin/captcha.sh"}. + + %% + %% Host for the URL and port where ejabberd listens for CAPTCHA requests. + %% + %%{captcha_host, "example.org:5280"}. + + %% + %% Limit CAPTCHA calls per minute for JID/IP to avoid DoS. + %% + %%{captcha_limit, 5}. + + %%%. ======= + %%%' MODULES + + %% + %% Modules enabled in all ejabberd virtual hosts. + %% + {modules, + [ + {mod_adhoc, []}, + {mod_announce, [{access, announce}]}, % recommends mod_adhoc + {mod_blocking,[]}, % requires mod_privacy + {mod_caps, []}, + {mod_configure,[]}, % requires mod_adhoc + {mod_disco, []}, + %%{mod_echo, [{host, "echo.localhost"}]}, + {mod_irc, []}, + {mod_http_bind, []}, + %%{mod_http_fileserver, [ + %% {docroot, "/var/www"}, + %% {accesslog, "/var/log/ejabberd/access.log"} + %% ]}, + {mod_last, []}, + {mod_muc, [ + %%{host, "conference.@HOST@"}, + {access, muc}, + {access_create, muc_create}, + {access_persistent, muc_create}, + {access_admin, muc_admin} + ]}, + %%{mod_muc_log,[]}, + {mod_offline, [{access_max_user_messages, max_user_offline_messages}]}, + {mod_ping, []}, + %%{mod_pres_counter,[{count, 5}, {interval, 60}]}, + {mod_privacy, []}, + {mod_private, []}, + %%{mod_proxy65,[]}, + {mod_pubsub, [ + {access_createnode, pubsub_createnode}, + {ignore_pep_from_offline, true}, % reduces resource comsumption, but XEP incompliant + %%{ignore_pep_from_offline, false}, % XEP compliant, but increases resource comsumption + {last_item_cache, false}, + {plugins, ["flat", "hometree", "pep"]} % pep requires mod_caps + ]}, + {mod_register, [ + %% + %% Protect In-Band account registrations with CAPTCHA. + %% + %%{captcha_protected, true}, + + %% + %% Set the minimum informational entropy for passwords. + %% + %%{password_strength, 32}, + + %% + %% After successful registration, the user receives + %% a message with this subject and body. + %% + {welcome_message, {"Welcome!", + "Hi.\nWelcome to this XMPP server."}}, + + %% + %% When a user registers, send a notification to + %% these XMPP accounts. + %% + %%{registration_watchers, ["admin1@example.org"]}, + + %% + %% Only clients in the server machine can register accounts + %% + {ip_access, [{allow, "127.0.0.0/8"}, + {deny, "0.0.0.0/0"}]}, + + %% + %% Local c2s or remote s2s users cannot register accounts + %% + %%{access_from, deny}, + + {access, register} + ]}, + %%{mod_register_web, [ + %% + %% When a user registers, send a notification to + %% these XMPP accounts. + %% + %%{registration_watchers, ["admin1@example.org"]} + %% ]}, + {mod_roster, []}, + %%{mod_service_log,[]}, + {mod_shared_roster,[]}, + {mod_stats, []}, + {mod_time, []}, + {mod_vcard, []}, + {mod_version, []} + ]}. + + %% + %% Enable modules with custom options in a specific virtual host + %% + %%{host_config, "localhost", + %% [{{add, modules}, + %% [ + %% {mod_echo, [{host, "mirror.localhost"}]} + %% ] + %% } + %% ]}. + + + %%%. + %%%' + + %%% $Id$ + + %%% Local Variables: + %%% mode: erlang + %%% End: + %%% vim: set filetype=erlang tabstop=8 foldmarker=%%%',%%%. foldmethod=marker: + ''; + # TODO properly configured wrapper + systemPackages = [ my-ejabberdctl ]; + }; + #exim_user = ${cfg.user} + #exim_group = ${cfg.group} + #exim_path = /var/setuid-wrappers/exim + #spool_directory = ${cfg.spoolDir} + #${cfg.config} + + users.extraUsers = singleton { + name = "ejabberd"; + description = "TODO"; + uid = 405222; + group = "ejabberd"; + home = "/var/ejabberd"; + createHome = true; + }; + + users.extraGroups = singleton { + name = "ejabberd"; + gid = 405222; + }; + + #security.setuidPrograms = [ "exim" ]; + + systemd.services.ejabberd = { + description = "ejabberd XMPP Daemon"; + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + reloadIfChanged = true; + serviceConfig = { + ExecStart = "${my-ejabberdctl}/bin/ejabberdctl start"; + ExecStop = "${my-ejabberdctl}/bin/ejabberdctl stop"; + ExecReload = "${my-ejabberdctl}/bin/ejabberdctl restart"; + Type = "oneshot"; + RemainAfterExit = "yes"; + RestartSec = 5; + LimitNOFILE = 16000; + User = "ejabberd"; + Group = "ejabberd"; + }; + }; + + systemd.services.ejabberd-prepare = { + description = "ejabberd XMPP Preparetion Service"; + requiredBy = [ "ejabberd.service" ]; + serviceConfig = { + Type = "oneshot"; + RestartSec = 5; + ExecStart = "${writeScript "ejabberd-prepare" + '' + #! /bin/sh + set -euf + chown ejabberd: /etc/nixos/secrets/ejabberd.cd.retiolum.pem + '' + }"; + }; + }; + + + + }; + + #config = mkIf cfg.enable { + # environment.systemPackages = [ pkgs.ejabberd ]; + + # jobs.ejabberd = + # { description = "EJabberd server"; + + # startOn = "started network-interfaces"; + # stopOn = "stopping network-interfaces"; + + # environment = { + # PATH = "$PATH:${pkgs.ejabberd}/sbin:${pkgs.ejabberd}/bin:${pkgs.coreutils}/bin:${pkgs.bash}/bin:${pkgs.gnused}/bin"; + # }; + + # preStart = + # '' + # PATH="$PATH:${pkgs.ejabberd}/sbin:${pkgs.ejabberd}/bin:${pkgs.coreutils}/bin:${pkgs.bash}/bin:${pkgs.gnused}/bin"; + # + # # Initialise state data + # mkdir -p ${cfg.logsDir} + + # if ! test -d ${cfg.spoolDir} + # then + # initialize=1 + # cp -av ${pkgs.ejabberd}/var/lib/ejabberd /var/lib + # fi + + # #if ! test -d ${cfg.confDir} + # #then + # # mkdir -p ${cfg.confDir} + # # cp ${pkgs.ejabberd}/etc/ejabberd/* ${cfg.confDir} + # # sed -e 's|{hosts, \["localhost"\]}.|{hosts, \[${cfg.virtualHosts}\]}.|' ${pkgs.ejabberd}/etc/ejabberd/ejabberd.cfg > ${cfg.confDir}/ejabberd.cfg + # #fi + # mkdir -p ${cfg.confDir} + + + # ejabberdctl --config-dir ${cfg.confDir} --logs ${cfg.logsDir} --spool ${cfg.spoolDir} start + + # ${if cfg.loadDumps == [] then "" else + # '' + # if [ "$initialize" = "1" ] + # then + # # Wait until the ejabberd server is available for use + # count=0 + # while ! ejabberdctl --config-dir ${cfg.confDir} --logs ${cfg.logsDir} --spool ${cfg.spoolDir} status + # do + # if [ $count -eq 30 ] + # then + # echo "Tried 30 times, giving up..." + # exit 1 + # fi + + # echo "Ejabberd daemon not yet started. Waiting for 1 second..." + # count=$((count++)) + # sleep 1 + # done + + # ${concatMapStrings (dump: + # '' + # echo "Importing dump: ${dump}" + + # if [ -f ${dump} ] + # then + # ejabberdctl --config-dir ${cfg.confDir} --logs ${cfg.logsDir} --spool ${cfg.spoolDir} load ${dump} + # elif [ -d ${dump} ] + # then + # for i in ${dump}/ejabberd-dump/* + # do + # ejabberdctl --config-dir ${cfg.confDir} --logs ${cfg.logsDir} --spool ${cfg.spoolDir} load $i + # done + # fi + # '') cfg.loadDumps} + # fi + # ''} + # ''; + + # postStop = + # '' + # ejabberdctl --config-dir ${cfg.confDir} --logs ${cfg.logsDir} --spool ${cfg.spoolDir} stop + # ''; + # }; + + # security.pam.services.ejabberd = {}; + + #}; + +} diff --git a/old/modules/tv/environment.nix b/old/modules/tv/environment.nix new file mode 100644 index 000000000..9e5a819a9 --- /dev/null +++ b/old/modules/tv/environment.nix @@ -0,0 +1,93 @@ +{ pkgs, ... }: + +let + lib = import ../../lib { lib = pkgs.lib; inherit pkgs; }; + + inherit (lib) majmin; +in + +{ + imports = [ + { + imports = [ ../tv/users ]; + tv.users.tv.packages = with pkgs; [ + ascii + mpv + ]; + } + ]; + + environment.systemPackages = with pkgs; [ + vim + ]; + + environment.etc."vim/vimrc".text = '' + set nocp + ''; + + environment.etc."vim/vim${majmin pkgs.vim.version}".source = + "${pkgs.vim}/share/vim/vim${majmin pkgs.vim.version}"; + + # multiple-definition-problem when defining environment.variables.EDITOR + environment.extraInit = '' + EDITOR=vim + ''; + + environment.shellAliases = { + # alias cal='cal -m3' + gp = "${pkgs.pari}/bin/gp -q"; + df = "df -h"; + du = "du -h"; + # alias grep='grep --color=auto' + + # TODO alias cannot contain #\' + # "ps?" = "ps ax | head -n 1;ps ax | fgrep -v ' grep --color=auto ' | grep"; + + # alias la='ls -lA' + lAtr = "ls -lAtr"; + # alias ll='ls -l' + ls = "ls -h --color=auto --group-directories-first"; + # alias vim='vim -p' + # alias vi='vim' + # alias view='vim -R' + dmesg = "dmesg -L --reltime"; + }; + + environment.variables.VIM = "/etc/vim"; + + programs.bash = { + interactiveShellInit = '' + HISTCONTROL='erasedups:ignorespace' + HISTSIZE=65536 + HISTFILESIZE=$HISTSIZE + + shopt -s checkhash + shopt -s histappend histreedit histverify + shopt -s no_empty_cmd_completion + complete -d cd + + # TODO source bridge + ''; + promptInit = '' + case $UID in + 0) + PS1='\[\e[1;31m\]\w\[\e[0m\] ' + ;; + 1337) + 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 + ''; + }; + + programs.ssh.startAgent = false; +} diff --git a/old/modules/tv/exim-retiolum.nix b/old/modules/tv/exim-retiolum.nix new file mode 100644 index 000000000..efab5cf32 --- /dev/null +++ b/old/modules/tv/exim-retiolum.nix @@ -0,0 +1,126 @@ +{ config, pkgs, ... }: + +{ + services.exim = + # This configuration makes only sense for retiolum-enabled hosts. + # TODO modular configuration + assert config.tv.retiolum.enable; + let + # TODO get the hostname from config.tv.retiolum. + retiolumHostname = "${config.networking.hostName}.retiolum"; + in + { enable = true; + config = '' + primary_hostname = ${retiolumHostname} + domainlist local_domains = @ : localhost + domainlist relay_to_domains = *.retiolum + hostlist relay_from_hosts = <; 127.0.0.1 ; ::1 + + acl_smtp_rcpt = acl_check_rcpt + acl_smtp_data = acl_check_data + + host_lookup = * + rfc1413_hosts = * + rfc1413_query_timeout = 5s + + log_file_path = syslog + syslog_timestamp = false + syslog_duplication = false + + begin acl + + acl_check_rcpt: + accept hosts = : + control = dkim_disable_verify + + deny message = Restricted characters in address + domains = +local_domains + local_parts = ^[.] : ^.*[@%!/|] + + deny message = Restricted characters in address + domains = !+local_domains + local_parts = ^[./|] : ^.*[@%!] : ^.*/\\.\\./ + + accept local_parts = postmaster + domains = +local_domains + + #accept + # hosts = *.retiolum + # domains = *.retiolum + # control = dkim_disable_verify + + #require verify = sender + + accept hosts = +relay_from_hosts + control = submission + control = dkim_disable_verify + + accept authenticated = * + control = submission + control = dkim_disable_verify + + require message = relay not permitted + domains = +local_domains : +relay_to_domains + + require verify = recipient + + accept + + + acl_check_data: + accept + + + begin routers + + retiolum: + driver = manualroute + domains = ! ${retiolumHostname} : *.retiolum + transport = remote_smtp + route_list = ^.* $0 byname + no_more + + nonlocal: + debug_print = "R: nonlocal for $local_part@$domain" + driver = redirect + domains = ! +local_domains + allow_fail + data = :fail: Mailing to remote domains not supported + no_more + + local_user: + # debug_print = "R: local_user for $local_part@$domain" + driver = accept + check_local_user + # local_part_suffix = +* : -* + # local_part_suffix_optional + transport = home_maildir + cannot_route_message = Unknown user + + + begin transports + + remote_smtp: + driver = smtp + + home_maildir: + driver = appendfile + maildir_format + directory = $home/Maildir + directory_mode = 0700 + delivery_date_add + envelope_to_add + return_path_add + # group = mail + # mode = 0660 + + begin retry + *.retiolum * F,42d,1m + * * F,2h,15m; G,16h,1h,1.5; F,4d,6h + + begin rewrite + + begin authenticators + ''; + }; +} diff --git a/old/modules/tv/exim-smarthost.nix b/old/modules/tv/exim-smarthost.nix new file mode 100644 index 000000000..a4c47b399 --- /dev/null +++ b/old/modules/tv/exim-smarthost.nix @@ -0,0 +1,474 @@ +{ config, pkgs, ... }: + +let + inherit (builtins) toFile; + inherit (pkgs.lib.attrsets) mapAttrs; + inherit (pkgs.lib.strings) concatMapStringsSep; +in + +{ + services.exim = + let + retiolumHostname = "${config.networking.hostName}.retiolum"; + + internet-aliases = [ + { from = "tomislav@viljetic.de"; to = "tv@wu.retiolum"; } + + # (mindestens) lisp-stammtisch und elli haben die: + { from = "tv@viljetic.de"; to = "tv@wu.retiolum"; } + + { from = "tv@destroy.dyn.shackspace.de"; to = "tv@wu.retiolum"; } + + { from = "mirko@viljetic.de"; to = "mv@cd.retiolum"; } + + # TODO killme (wo wird die benutzt?) + { from = "tv@cd.retiolum"; to = "tv@wu.retiolum"; } + + { from = "postmaster@krebsco.de"; to = "tv@wu.retiolum"; } + ]; + + 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"; } + ]; + + to-lsearch = concatMapStringsSep "\n" ({ from, to }: "${from}: ${to}"); + lsearch = + mapAttrs (name: set: toFile name (to-lsearch set)) { + inherit internet-aliases; + inherit system-aliases; + }; + in + { + enable = true; + config = + '' + primary_hostname = ${retiolumHostname} + + # HOST_REDIR contains the real destinations for "local_domains". + #HOST_REDIR = /etc/exim4/host_redirect + + + # Domains not listed in local_domains need to be deliverable remotely. + # XXX We abuse local_domains to mean "domains, we're the gateway for". + domainlist local_domains = @ : localhost + #: viljetic.de : SHACK_REDIR_HOSTNAME + domainlist relay_to_domains = + hostlist relay_from_hosts = <; 127.0.0.1 ; ::1 ; 10.243.13.37 + + acl_smtp_rcpt = acl_check_rcpt + acl_smtp_data = acl_check_data + + # av_scanner = clamd:/tmp/clamd + # spamd_address = 127.0.0.1 783 + + # tls_advertise_hosts = * + # tls_certificate = /etc/ssl/exim.crt + # tls_privatekey = /etc/ssl/exim.pem + # (debian) tls_verify_certificates (to check client certs) + + # daemon_smtp_ports = 25 : 465 : 587 + # tls_on_connect_ports = 465 + + # qualify_domain defaults to primary_hostname + # qualify_recipient defaults to qualify_domain + + # allow_domain_literals + + never_users = root + + host_lookup = * + + # ident callbacks for all incoming SMTP calls + rfc1413_hosts = * + rfc1413_query_timeout = 5s + + # sender_unqualified_hosts = + # recipient_unqualified_hosts = + + # percent_hack_domains = + + # arch & debian + #ignore_bounce_errors_after = 2d + #timeout_frozen_after = 7d + # debian + #smtp_banner = $smtp_active_hostname ESMTP Exim $version_number $tod_full + #freeze_tell = postmaster + #trusted_users = uucp + # arch + #split_spool_directory = true + + log_selector = -queue_run +address_rewrite +all_parents +queue_time + log_file_path = syslog + syslog_timestamp = false + syslog_duplication = false + + begin acl + + acl_check_rcpt: + # Accept if the source is local SMTP (i.e. not over TCP/IP). + # We do this by testing for an empty sending host field. + accept hosts = : + # arch & debian: + control = dkim_disable_verify + + deny message = Restricted characters in address + domains = +local_domains + local_parts = ^[.] : ^.*[@%!/|] + + deny message = Restricted characters in address + domains = !+local_domains + local_parts = ^[./|] : ^.*[@%!] : ^.*/\\.\\./ + + accept local_parts = postmaster + domains = +local_domains + + ## feature RETIOLUM_MAIL + #accept + # hosts = *.retiolum + # domains = *.retiolum + # control = dkim_disable_verify + + #require verify = sender + + accept hosts = +relay_from_hosts + control = submission + # debian: control = submission/sender_retain + # arch & debian: + control = dkim_disable_verify + + accept authenticated = * + control = submission + control = dkim_disable_verify + + accept message = relay not permitted 2 + recipients = lsearch;${lsearch.internet-aliases} + + require message = relay not permitted + domains = +local_domains : +relay_to_domains + + require + message = unknown user + verify = recipient/callout + + # deny message = rejected because $sender_host_address is in a black list at $dnslist_domain\n$dnslist_text + # dnslists = black.list.example + # + # warn dnslists = black.list.example + # add_header = X-Warning: $sender_host_address is in a black list at $dnslist_domain + # log_message = found in $dnslist_domain + + # Client SMTP Authorization (csa) checks on the sending host. + # Such checks do DNS lookups for special SRV records. + # require verify = csa + + accept + + + acl_check_data: + # see av_scanner + #deny malware = * + # message = This message contains a virus ($malware_name). + + # Add headers to a message if it is judged to be spam. Before enabling this, + # you must install SpamAssassin. You may also need to set the spamd_address + # option above. + # + # warn spam = nobody + # add_header = X-Spam_score: $spam_score\n\ + # X-Spam_score_int: $spam_score_int\n\ + # X-Spam_bar: $spam_bar\n\ + # X-Spam_report: $spam_report + + # feature HELO_REWRITE + # XXX note that the public ip (162.219.5.183) resolves to viljetic.de + warn + sender_domains = viljetic.de : shackspace.de + set acl_m_special_dom = $sender_address_domain + + accept + + + begin routers + + # feature RETIOLUM_MAIL + retiolum: + debug_print = "R: retiolum for $local_part@$domain" + driver = manualroute + domains = ! ${retiolumHostname} : *.retiolum + transport = retiolum_smtp + route_list = ^.* $0 byname + no_more + + internet_aliases: + debug_print = "R: internet_aliases for $local_part@$domain" + driver = redirect + data = ''${lookup{$local_part@$domain}lsearch{${lsearch.internet-aliases}}} + + dnslookup: + debug_print = "R: dnslookup for $local_part@$domain" + driver = dnslookup + domains = ! +local_domains + transport = remote_smtp + ignore_target_hosts = 0.0.0.0 : 127.0.0.0/8 + # if ipv6-enabled then instead use: + # ignore_target_hosts = <; 0.0.0.0 ; 127.0.0.0/8 ; ::1 + + # (debian) same_domain_copy_routing = yes + # (debian) ignore private rfc1918 and APIPA addresses + # (debian) ignore_target_hosts = 0.0.0.0 : 127.0.0.0/8 : 192.168.0.0/16 :\ + # 172.16.0.0/12 : 10.0.0.0/8 : 169.254.0.0/16 :\ + # 255.255.255.255 + + # Fail and bounce if the router does not find the domain in the DNS. + # I.e. no more routers are tried. + # There are a few cases where a dnslookup router will decline to accept an + # address; if such a router is expected to handle "all remaining non-local + # domains", then it is important to set no_more. + no_more + + # XXX this is only used because these "well known aliases" goto tv@cd.retiolum + # TODO bounce everything, there is no @cd.retiolum + system_aliases: + debug_print = "R: system_aliases for $local_part@$domain" + driver = redirect + data = ''${lookup{$local_part}lsearch{${lsearch.system-aliases}}} + + # TODO this is only b/c mv here... send mv's mails somewhere else... + local_user: + debug_print = "R: local_user for $local_part@$domain" + driver = accept + check_local_user + # local_part_suffix = +* : -* + # local_part_suffix_optional + transport = home_maildir + cannot_route_message = Unknown user + + begin transports + + retiolum_smtp: + driver = smtp + retry_include_ip_address = false + # serialize_hosts = TODO-all-slow-hosts + + remote_smtp: + driver = smtp + # debian has also stuff for tls, headers_rewrite and more here + + # feature HELO_REWRITE + # XXX note that the public ip (162.219.5.183) resolves to viljetic.de + helo_data = ''${if eq{$acl_m_special_dom}{} \ + {$primary_hostname} \ + {$acl_m_special_dom} } + + home_maildir: + driver = appendfile + maildir_format + maildir_use_size_file + directory = $home/Mail + directory_mode = 0700 + delivery_date_add + envelope_to_add + return_path_add + + begin retry + *.retiolum * F,42d,1m + * * F,2h,15m; G,16h,1h,1.5; F,4d,6h + + begin rewrite + begin authenticators + ''; + + + # group = mail + # mode = 0660 + + + #address_pipe: + # driver = pipe + # return_output + # + #address_file: + # driver = appendfile + # delivery_date_add + # envelope_to_add + # return_path_add + # + #address_reply: + # driver = autoreply + + + #maildrop_pipe: + # debug_print = "T: maildrop_pipe for $local_part@$domain" + # driver = pipe + # path = "/bin:/usr/bin:/usr/local/bin" + # command = "/usr/bin/maildrop" + # return_path_add + # delivery_date_add + # envelope_to_add + + + + + + ##begin retry + # Address or Domain Error Retries + + # Our host_redirect destinations might be offline a lot. + # TODO define fallback destinations(?) + #lsearch;${lsearch.internet-aliases} * F,42d,1m + + + ## begin rewrite + + # just in case (shackspace.de should already do this) + #tv@shackspace.de tv@SHACK_REDIR_HOSTNAME T + + + ## begin authenticators + #PLAIN: + # driver = plaintext + # server_set_id = $auth2 + # server_prompts = : + # server_condition = Authentication is not yet configured + # server_advertise_condition = ''${if def:tls_in_cipher } + + #LOGIN: + # driver = plaintext + # server_set_id = $auth1 + # server_prompts = <| Username: | Password: + # server_condition = Authentication is not yet configured + # server_advertise_condition = ''${if def:tls_in_cipher } + + + + }; + +} + +# config = '' +# primary_hostname = ${retiolumHostname} +# domainlist local_domains = @ : localhost +# domainlist relay_to_domains = *.retiolum +# hostlist relay_from_hosts = <; 127.0.0.1 ; ::1 +# +# acl_smtp_rcpt = acl_check_rcpt +# acl_smtp_data = acl_check_data +# +# host_lookup = * +# rfc1413_hosts = * +# rfc1413_query_timeout = 5s +# +# log_file_path = syslog +# syslog_timestamp = false +# syslog_duplication = false +# +# begin acl +# +# acl_check_rcpt: +# accept hosts = : +# control = dkim_disable_verify +# +# deny message = Restricted characters in address +# domains = +local_domains +# local_parts = ^[.] : ^.*[@%!/|] +# +# deny message = Restricted characters in address +# domains = !+local_domains +# local_parts = ^[./|] : ^.*[@%!] : ^.*/\\.\\./ +# +# accept local_parts = postmaster +# domains = +local_domains +# +# #accept +# # hosts = *.retiolum +# # domains = *.retiolum +# # control = dkim_disable_verify +# +# #require verify = sender +# +# accept hosts = +relay_from_hosts +# control = submission +# control = dkim_disable_verify +# +# accept authenticated = * +# control = submission +# control = dkim_disable_verify +# +# require message = relay not permitted +# domains = +local_domains : +relay_to_domains +# +# require verify = recipient +# +# accept +# +# +# acl_check_data: +# accept +# +# +# begin routers +# +# retiolum: +# driver = manualroute +# domains = ! ${retiolumHostname} : *.retiolum +# transport = remote_smtp +# route_list = ^.* $0 byname +# no_more +# +# nonlocal: +# debug_print = "R: nonlocal for $local_part@$domain" +# driver = redirect +# domains = ! +local_domains +# allow_fail +# data = :fail: Mailing to remote domains not supported +# no_more +# +# local_user: +# # debug_print = "R: local_user for $local_part@$domain" +# driver = accept +# check_local_user +# # local_part_suffix = +* : -* +# # local_part_suffix_optional +# transport = home_maildir +# cannot_route_message = Unknown user +# +# +# begin transports +# +# remote_smtp: +# driver = smtp +# +# home_maildir: +# driver = appendfile +# maildir_format +# directory = $home/Maildir +# directory_mode = 0700 +# delivery_date_add +# envelope_to_add +# return_path_add +# # group = mail +# # mode = 0660 +# +# begin retry +# *.retiolum * F,42d,1m +# * * F,2h,15m; G,16h,1h,1.5; F,4d,6h +# +# begin rewrite +# +# begin authenticators +# ''; +# }; +#} diff --git a/old/modules/tv/git/cgit.nix b/old/modules/tv/git/cgit.nix new file mode 100644 index 000000000..747a93135 --- /dev/null +++ b/old/modules/tv/git/cgit.nix @@ -0,0 +1,93 @@ +{ cfg, config, lib, pkgs, ... }: + +let + inherit (builtins) attrValues filter getAttr; + inherit (lib) concatMapStringsSep mkIf optionalString; + + location = lib.nameValuePair; # TODO this is also in modules/wu/default.nix + + isPublicRepo = getAttr "public"; # TODO this is also in ./default.nix +in + +{ + users.extraUsers = lib.singleton { + name = "fcgiwrap"; + uid = 2851179180; # genid fcgiwrap + group = "fcgiwrap"; + home = toString (pkgs.runCommand "empty" {} "mkdir -p $out"); + }; + + users.extraGroups = lib.singleton { + name = "fcgiwrap"; + gid = 2851179180; # genid fcgiwrap + }; + + services.fcgiwrap = { + enable = true; + user = "fcgiwrap"; + group = "fcgiwrap"; + # socketAddress = "/run/fcgiwrap.sock" (default) + # socketType = "unix" (default) + }; + + environment.etc."cgitrc".text = '' + css=/cgit-static/cgit.css + logo=/cgit-static/cgit.png + + # if you do not want that webcrawler (like google) index your site + robots=noindex, nofollow + + virtual-root=/cgit + + # TODO make this nicer (and/or somewhere else) + cache-root=/tmp/cgit + + cache-size=1000 + enable-commit-graph=1 + enable-index-links=1 + enable-index-owner=0 + enable-log-filecount=1 + enable-log-linecount=1 + enable-remote-branches=1 + + root-title=public repositories at ${config.networking.hostName} + root-desc=keep calm and engage + + snapshots=0 + max-stats=year + + ${concatMapStringsSep "\n" (repo: '' + repo.url=${repo.name} + repo.path=${cfg.dataDir}/${repo.name} + ${optionalString (repo.section != null) "repo.section=${repo.section}"} + ${optionalString (repo.desc != null) "repo.desc=${repo.desc}"} + '') (filter isPublicRepo (attrValues cfg.repos))} + ''; + + system.activationScripts.cgit = '' + mkdir -m 0700 -p /tmp/cgit + chown fcgiwrap: /tmp/cgit + ''; + + tv.nginx = { + enable = true; + retiolum-locations = [ + (location "/cgit/" '' + include ${pkgs.nginx}/conf/fastcgi_params; + fastcgi_param SCRIPT_FILENAME ${pkgs.cgit}/cgit/cgit.cgi; + fastcgi_split_path_info ^(/cgit/?)(.+)$; + fastcgi_param PATH_INFO $fastcgi_path_info; + fastcgi_param QUERY_STRING $args; + fastcgi_param HTTP_HOST $server_name; + fastcgi_pass unix:${config.services.fcgiwrap.socketAddress}; + '') + (location "= /cgit" '' + return 301 /cgit/; + '') + (location "/cgit-static/" '' + root ${pkgs.cgit}/cgit; + rewrite ^/cgit-static(/.*)$ $1 break; + '') + ]; + }; +} diff --git a/old/modules/tv/git/config.nix b/old/modules/tv/git/config.nix new file mode 100644 index 000000000..4f44c3839 --- /dev/null +++ b/old/modules/tv/git/config.nix @@ -0,0 +1,272 @@ +arg@{ cfg, lib, pkgs, ... }: + +let + inherit (builtins) head tail typeOf; + inherit (lib) + attrValues concatStringsSep concatMapStringsSep escapeShellArg filter + getAttr hasAttr hasPrefix lessThan makeSearchPath mapAttrsToList + optional optionalString removePrefix singleton sort unique; + inherit (pkgs) linkFarm writeScript; + + ensureList = x: + if typeOf x == "list" then x else [x]; + + getName = x: x.name; + + isPublicRepo = getAttr "public"; # TODO this is also in ./cgit.nix + + makeAuthorizedKey = git-ssh-command: user@{ name, pubkey }: + # TODO assert name + # TODO assert pubkey + let + options = concatStringsSep "," [ + ''command="exec ${git-ssh-command} ${name}"'' + "no-agent-forwarding" + "no-port-forwarding" + "no-pty" + "no-X11-forwarding" + ]; + in + "${options} ${pubkey}"; + + # [case-pattern] -> shell-script + # Create a shell script that succeeds (exit 0) when all its arguments + # match the case patterns (in the given order). + makeAuthorizeScript = + let + # TODO escape + to-pattern = x: concatStringsSep "|" (ensureList x); + go = i: ps: + if ps == [] + then "exit 0" + else '' + case ''$${toString i} in ${to-pattern (head ps)}) + ${go (i + 1) (tail ps)} + esac''; + in + patterns: '' + #! /bin/sh + set -euf + ${concatStringsSep "\n" (map (go 1) patterns)} + exit -1 + ''; + + reponames = rules: sort lessThan (unique (map (x: x.repo.name) rules)); + + # TODO makeGitHooks that uses runCommand instead of scriptFarm? + scriptFarm = + farm-name: scripts: + let + makeScript = script-name: script-string: { + name = script-name; + path = writeScript "${farm-name}_${script-name}" script-string; + }; + in + linkFarm farm-name (mapAttrsToList makeScript scripts); + + + git-ssh-command = writeScript "git-ssh-command" '' + #! /bin/sh + set -euf + + PATH=${makeSearchPath "bin" (with pkgs; [ + coreutils + git + gnugrep + gnused + systemd + ])} + + abort() { + echo "error: $1" >&2 + systemd-cat -p err -t git echo "error: $1" + exit -1 + } + + GIT_SSH_USER=$1 + + systemd-cat -p info -t git echo \ + "authorizing $GIT_SSH_USER $SSH_CONNECTION $SSH_ORIGINAL_COMMAND" + + # References: The Base Definitions volume of + # POSIX.1‐2013, Section 3.278, Portable Filename Character Set + portable_filename_bre="^[A-Za-z0-9._-]\\+$" + + command=$(echo "$SSH_ORIGINAL_COMMAND" \ + | sed -n 's/^\([^ ]*\) '"'"'\(.*\)'"'"'/\1/p' \ + | grep "$portable_filename_bre" \ + || abort 'cannot read command') + + GIT_SSH_REPO=$(echo "$SSH_ORIGINAL_COMMAND" \ + | sed -n 's/^\([^ ]*\) '"'"'\(.*\)'"'"'/\2/p' \ + | grep "$portable_filename_bre" \ + || abort 'cannot read reponame') + + ${cfg.etcDir}/authorize-command \ + "$GIT_SSH_USER" "$GIT_SSH_REPO" "$command" \ + || abort 'access denied' + + repodir=${escapeShellArg cfg.dataDir}/$GIT_SSH_REPO + + systemd-cat -p info -t git \ + echo "authorized exec $command $repodir" + + export GIT_SSH_USER + export GIT_SSH_REPO + exec "$command" "$repodir" + ''; + + init-script = writeScript "git-init" '' + #! /bin/sh + set -euf + + PATH=${makeSearchPath "bin" (with pkgs; [ + coreutils + findutils + gawk + git + gnugrep + gnused + ])} + + dataDir=${escapeShellArg cfg.dataDir} + mkdir -p "$dataDir" + + # Notice how the presence of hooks symlinks determine whether + # we manage a repositry or not. + + # Make sure that no existing repository has hooks. We can delete + # symlinks because we assume we created them. + find "$dataDir" -mindepth 2 -maxdepth 2 -name hooks -type l -delete + bad_hooks=$(find "$dataDir" -mindepth 2 -maxdepth 2 -name hooks) + if echo "$bad_hooks" | grep -q .; then + printf 'error: unknown hooks:\n%s\n' \ + "$(echo "$bad_hooks" | sed 's/^/ /')" \ + >&2 + exit -1 + fi + + # Initialize repositories. + ${concatMapStringsSep "\n" (repo: + let + hooks = scriptFarm "git-hooks" (makeHooks repo); + in + '' + reponame=${escapeShellArg repo.name} + repodir=$dataDir/$reponame + mode=${toString (if isPublicRepo repo then 0711 else 0700)} + if ! test -d "$repodir"; then + mkdir -m "$mode" "$repodir" + git init --bare --template=/var/empty "$repodir" + chown -R git:nogroup "$repodir" + fi + ln -s ${hooks} "$repodir/hooks" + '' + ) (attrValues cfg.repos)} + + # Warn about repositories that exist but aren't mentioned in the + # current configuration (and thus didn't receive a hooks symlink). + unknown_repos=$(find "$dataDir" -mindepth 1 -maxdepth 1 \ + -type d \! -exec test -e '{}/hooks' \; -print) + if echo "$unknown_repos" | grep -q .; then + printf 'warning: stale repositories:\n%s\n' \ + "$(echo "$unknown_repos" | sed 's/^/ /')" \ + >&2 + fi + ''; + + makeHooks = repo: removeAttrs repo.hooks [ "pre-receive" ] // { + pre-receive = '' + #! /bin/sh + set -euf + + PATH=${makeSearchPath "bin" (with pkgs; [ + coreutils # env + git + systemd + ])} + + accept() { + #systemd-cat -p info -t git echo "authorized $1" + accept_string="''${accept_string+$accept_string + }authorized $1" + } + reject() { + #systemd-cat -p err -t git echo "denied $1" + #echo 'access denied' >&2 + #exit_code=-1 + reject_string="''${reject_string+$reject_string + }access denied: $1" + } + + empty=0000000000000000000000000000000000000000 + + accept_string= + reject_string= + while read oldrev newrev ref; do + + if [ $oldrev = $empty ]; then + receive_mode=create + elif [ $newrev = $empty ]; then + receive_mode=delete + elif [ "$(git merge-base $oldrev $newrev)" = $oldrev ]; then + receive_mode=fast-forward + else + receive_mode=non-fast-forward + fi + + if ${cfg.etcDir}/authorize-push \ + "$GIT_SSH_USER" "$GIT_SSH_REPO" "$ref" "$receive_mode"; then + accept "$receive_mode $ref" + else + reject "$receive_mode $ref" + fi + done + + if [ -n "$reject_string" ]; then + systemd-cat -p err -t git echo "$reject_string" + exit -1 + fi + + systemd-cat -p info -t git echo "$accept_string" + + ${optionalString (hasAttr "post-receive" repo.hooks) '' + # custom post-receive hook + ${repo.hooks.post-receive}''} + ''; + }; + + etc-base = + assert (hasPrefix "/etc/" cfg.etcDir); + removePrefix "/etc/" cfg.etcDir; +in + +{ + system.activationScripts.git-init = "${init-script}"; + + # TODO maybe put all scripts here and then use PATH? + environment.etc."${etc-base}".source = + scriptFarm "git-ssh-authorizers" { + authorize-command = makeAuthorizeScript (map ({ repo, user, perm }: [ + (map getName (ensureList user)) + (map getName (ensureList repo)) + (map getName perm.allow-commands) + ]) cfg.rules); + + authorize-push = makeAuthorizeScript (map ({ repo, user, perm }: [ + (map getName (ensureList user)) + (map getName (ensureList repo)) + (ensureList perm.allow-receive-ref) + (map getName perm.allow-receive-modes) + ]) (filter (x: hasAttr "allow-receive-ref" x.perm) cfg.rules)); + }; + + users.extraUsers = singleton { + description = "Git repository hosting user"; + name = "git"; + shell = "/bin/sh"; + openssh.authorizedKeys.keys = + mapAttrsToList (_: makeAuthorizedKey git-ssh-command) cfg.users; + uid = 112606723; # genid git + }; +} diff --git a/old/modules/tv/git/default.nix b/old/modules/tv/git/default.nix new file mode 100644 index 000000000..17bc3738b --- /dev/null +++ b/old/modules/tv/git/default.nix @@ -0,0 +1,27 @@ +arg@{ config, pkgs, lib, ... }: + +let + inherit (lib) mkIf mkMerge; + + cfg = config.tv.git; + arg' = arg // { inherit cfg; }; +in + +# TODO unify logging of shell scripts to user and journal +# TODO move all scripts to ${etcDir}, so ControlMaster connections +# immediately pick up new authenticators +# TODO when authorized_keys changes, then restart ssh +# (or kill already connected users somehow) + +{ + imports = [ + ../../tv/nginx + ]; + + options.tv.git = import ./options.nix arg'; + + config = mkIf cfg.enable (mkMerge [ + (import ./config.nix arg') + (mkIf cfg.cgit (import ./cgit.nix arg')) + ]); +} diff --git a/old/modules/tv/git/options.nix b/old/modules/tv/git/options.nix new file mode 100644 index 000000000..c251d7d4c --- /dev/null +++ b/old/modules/tv/git/options.nix @@ -0,0 +1,93 @@ +{ lib, ... }: + +let + inherit (lib) literalExample mkOption types; +in + +{ + enable = mkOption { + type = types.bool; + default = false; + description = "Enable Git repository hosting."; + }; + cgit = mkOption { + type = types.bool; + default = true; + description = "Enable cgit."; # TODO better desc; talk about nginx + }; + dataDir = mkOption { + type = types.str; + default = "/var/lib/git"; + description = "Directory used to store repositories."; + }; + etcDir = mkOption { + type = types.str; + default = "/etc/git"; + }; + rules = mkOption { + type = types.unspecified; + }; + repos = mkOption { + type = types.attrsOf (types.submodule ({ + options = { + desc = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + Repository description. + ''; + }; + section = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + Repository section. + ''; + }; + name = mkOption { + type = types.str; + description = '' + Repository name. + ''; + }; + hooks = mkOption { + type = types.attrsOf types.str; + description = '' + Repository-specific hooks. + ''; + }; + public = mkOption { + type = types.bool; + default = false; + description = '' + Allow everybody to read the repository via HTTP if cgit enabled. + ''; + # TODO allow every configured user to fetch the repository via SSH. + }; + }; + })); + + default = {}; + + example = literalExample '' + { + testing = { + name = "testing"; + hooks.post-update = ''' + #! /bin/sh + set -euf + echo post-update hook: $* >&2 + '''; + }; + testing2 = { name = "testing2"; }; + } + ''; + + description = '' + Repositories. + ''; + }; + users = mkOption { + type = types.unspecified; + }; +} diff --git a/old/modules/tv/git/public.nix b/old/modules/tv/git/public.nix new file mode 100644 index 000000000..de6ed7fdf --- /dev/null +++ b/old/modules/tv/git/public.nix @@ -0,0 +1,82 @@ +{ config, lib, pkgs, ... }: + +let + inherit (builtins) map readFile; + inherit (lib) concatMap listToAttrs; + # TODO lib should already include our stuff + inherit (import ../../../lib { inherit lib pkgs; }) addNames git; + + public-git-repos = [ + (public "cgserver") + (public "crude-mail-setup") + (public "dot-xmonad") + (public "hack") + (public "load-env") + (public "make-snapshot") + (public "mime") + (public "much") + (public "nixos-infest") + (public "nixpkgs") + (public "painload") + (public "regfish") + (public' { + name = "shitment"; + desc = "turn all the computers into one computer!"; + }) + (public "wai-middleware-time") + (public "web-routes-wai-custom") + ]; + + users = addNames { + tv = { pubkey = readFile <pubkeys/tv_wu.ssh.pub>; }; + lass = { pubkey = readFile <pubkeys/lass.ssh.pub>; }; + uriel = { pubkey = readFile <pubkeys/uriel.ssh.pub>; }; + makefu = { pubkey = readFile <pubkeys/makefu.ssh.pub>; }; + }; + + repos = listToAttrs (map ({ repo, ... }: { name = repo.name; value = repo; }) public-git-repos); + + rules = concatMap ({ rules, ... }: rules) public-git-repos; + + public' = { name, desc }: + let + x = public name; + in + x // { repo = x.repo // { inherit desc; }; }; + + public = repo-name: + rec { + repo = { + name = repo-name; + hooks = { + post-receive = git.irc-announce { + nick = config.networking.hostName; # TODO make this the default + channel = "#retiolum"; + server = "ire.retiolum"; + }; + }; + public = true; + }; + rules = with git; with users; [ + { user = tv; + repo = [ repo ]; + perm = push "refs/*" [ non-fast-forward create delete merge ]; + } + { user = [ lass makefu uriel ]; + repo = [ repo ]; + perm = fetch; + } + ]; + }; + +in + +{ + imports = [ + ./. + ]; + tv.git = { + enable = true; + inherit repos rules users; + }; +} diff --git a/old/modules/tv/identity/default.nix b/old/modules/tv/identity/default.nix new file mode 100644 index 000000000..7cf90de01 --- /dev/null +++ b/old/modules/tv/identity/default.nix @@ -0,0 +1,71 @@ +{ lib, ... }: + +with lib; + +let + + cfg = config.tv.identity; + + out = { + options.tv.identity = api; + #config = mkIf cfg.enable imp; + }; + + api = { + enable = mkOption { + type = types.bool; + default = false; + }; + self = mkOption { + type = types.unspecified; + }; + hosts = mkOption { + type = with types; attrsOf unspecified; + default = { + cd = { + #dc = "cac"; + dc = "tv"; + fqdn = "cd.retiolum"; + addr = "10.243.113.222"; + #addr6 = "42:4522:25f8:36bb:8ccb:0150:231a:2af3"; + #internet-addr = "162.219.5.183"; + cores = 2; + }; + mkdir = { + #dc = "cac"; + dc = "tv"; + fqdn = "mkdir.retiolum"; + addr = "10.243.113.223"; + cores = 1; + }; + nomic = { + #dc = "gg"; + dc = "tv"; + fqdn = "nomic.retiolum"; + addr = "10.243.0.110"; + cores = 2; + }; + rmdir = { + #dc = "cac"; + dc = "tv"; + fqdn = "rmdir.retiolum"; + addr = "10.243.113.224"; + #addr = "42:4522:25f8:36bb:8ccb:0150:231a:2af5"; + cores = 1; + }; + wu = { + #dc = "gg"; + dc = "tv"; + fqdn = "wu.retiolum"; + addr = "10.243.13.37"; + cores = 8; + }; + }; + }; + }; + + #imp = { + #}; + +in +out diff --git a/old/modules/tv/iptables/config.nix b/old/modules/tv/iptables/config.nix new file mode 100644 index 000000000..a525cfa5d --- /dev/null +++ b/old/modules/tv/iptables/config.nix @@ -0,0 +1,93 @@ +{ cfg, lib, pkgs, ... }: + +let + inherit (pkgs) writeScript writeText; + inherit (lib) concatMapStringsSep; + + accept-new-tcp = port: + "-p tcp -m tcp --dport ${port} -m conntrack --ctstate NEW -j ACCEPT"; + + rules = iptables-version: + writeText "tv-iptables-rules${toString iptables-version}" '' + *nat + :PREROUTING ACCEPT [0:0] + :INPUT ACCEPT [0:0] + :OUTPUT ACCEPT [0:0] + :POSTROUTING ACCEPT [0:0] + ${concatMapStringsSep "\n" (rule: "-A PREROUTING ${rule}") ([] + ++ [ + "! -i retiolum -p tcp -m tcp --dport 22 -j REDIRECT --to-ports 0" + "-p tcp -m tcp --dport 11423 -j REDIRECT --to-ports 22" + ] + )} + COMMIT + *filter + :INPUT DROP [0:0] + :FORWARD DROP [0:0] + :OUTPUT ACCEPT [0:0] + :Retiolum - [0:0] + ${concatMapStringsSep "\n" (rule: "-A INPUT ${rule}") ([] + ++ [ + "-m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT" + "-i lo -j ACCEPT" + ] + ++ map accept-new-tcp cfg.input-internet-accept-new-tcp + ++ ["-i retiolum -j Retiolum"] + )} + ${concatMapStringsSep "\n" (rule: "-A Retiolum ${rule}") ([] + ++ { + ip4tables = [ + "-p icmp -m icmp --icmp-type echo-request -j ACCEPT" + ]; + ip6tables = [ + "-p ipv6-icmp -m icmp6 --icmpv6-type echo-request -j ACCEPT" + ]; + }."ip${toString iptables-version}tables" + ++ map accept-new-tcp cfg.input-retiolum-accept-new-tcp + ++ { + ip4tables = [ + "-p tcp -j REJECT --reject-with tcp-reset" + "-p udp -j REJECT --reject-with icmp-port-unreachable" + "-j REJECT --reject-with icmp-proto-unreachable" + ]; + ip6tables = [ + "-p tcp -j REJECT --reject-with tcp-reset" + "-p udp -j REJECT --reject-with icmp6-port-unreachable" + "-j REJECT" + ]; + }."ip${toString iptables-version}tables" + )} + COMMIT + ''; + + startScript = writeScript "tv-iptables_start" '' + #! /bin/sh + set -euf + iptables-restore < ${rules 4} + ip6tables-restore < ${rules 6} + ''; +in + +{ + networking.firewall.enable = false; + + systemd.services.tv-iptables = { + description = "tv-iptables"; + wantedBy = [ "network-pre.target" ]; + before = [ "network-pre.target" ]; + after = [ "systemd-modules-load.service" ]; + + path = with pkgs; [ + iptables + ]; + + restartIfChanged = true; + + serviceConfig = { + Type = "simple"; + RemainAfterExit = true; + Restart = "always"; + ExecStart = "@${startScript} tv-iptables_start"; + }; + }; +} diff --git a/old/modules/tv/iptables/default.nix b/old/modules/tv/iptables/default.nix new file mode 100644 index 000000000..cf27a26ac --- /dev/null +++ b/old/modules/tv/iptables/default.nix @@ -0,0 +1,11 @@ +arg@{ config, lib, pkgs, ... }: + +let + cfg = config.tv.iptables; + arg' = arg // { inherit cfg; }; +in + +{ + options.tv.iptables = import ./options.nix arg'; + config = lib.mkIf cfg.enable (import ./config.nix arg'); +} diff --git a/old/modules/tv/iptables/options.nix b/old/modules/tv/iptables/options.nix new file mode 100644 index 000000000..1adffebdb --- /dev/null +++ b/old/modules/tv/iptables/options.nix @@ -0,0 +1,29 @@ +{ lib, ... }: + +let + inherit (lib) mkOption types; +in + +{ + enable = mkOption { + type = types.bool; + default = false; + description = "Enable iptables."; + }; + + input-internet-accept-new-tcp = mkOption { + type = with types; listOf str; + default = []; + description = '' + TCP ports, accepting incoming connections from anywhere. + ''; + }; + + input-retiolum-accept-new-tcp = mkOption { + type = with types; listOf str; + default = []; + description = '' + TCP ports, accepting incoming connections from Retiolum. + ''; + }; +} diff --git a/old/modules/tv/nginx/config.nix b/old/modules/tv/nginx/config.nix new file mode 100644 index 000000000..4bfd8ad28 --- /dev/null +++ b/old/modules/tv/nginx/config.nix @@ -0,0 +1,49 @@ +{ cfg, config, lib, pkgs, ... }: + +let + inherit (lib) concatStrings replaceChars; + + indent = replaceChars ["\n"] ["\n "]; + + to-location = { name, value }: '' + location ${name} { + ${indent value} + } + ''; +in + +{ + services.nginx = + let + name = config.tv.retiolum.name; + qname = "${name}.retiolum"; + in + assert config.tv.retiolum.enable; + { + enable = true; + httpConfig = '' + include ${pkgs.nginx}/conf/mime.types; + default_type application/octet-stream; + sendfile on; + keepalive_timeout 65; + gzip on; + server { + listen 80 default_server; + server_name _; + location / { + return 404; + } + } + server { + listen 80; + server_name ${name} ${qname}; + + ${indent (concatStrings (map to-location cfg.retiolum-locations))} + + location / { + return 404; + } + } + ''; + }; +} diff --git a/old/modules/tv/nginx/default.nix b/old/modules/tv/nginx/default.nix new file mode 100644 index 000000000..49133fbb3 --- /dev/null +++ b/old/modules/tv/nginx/default.nix @@ -0,0 +1,11 @@ +arg@{ config, pkgs, lib, ... }: + +let + cfg = config.tv.nginx; + arg' = arg // { inherit cfg; }; +in + +{ + options.tv.nginx = import ./options.nix arg'; + config = lib.mkIf cfg.enable (import ./config.nix arg'); +} diff --git a/old/modules/tv/nginx/options.nix b/old/modules/tv/nginx/options.nix new file mode 100644 index 000000000..ddfb38049 --- /dev/null +++ b/old/modules/tv/nginx/options.nix @@ -0,0 +1,21 @@ +{ lib, ... }: + +let + inherit (lib) mkOption types; +in + +{ + enable = mkOption { + type = types.bool; + default = false; + description = "Enable nginx."; + }; + + retiolum-locations = mkOption { + type = with types; listOf (attrsOf str); + default = []; + description = '' + TODO + ''; + }; +} diff --git a/old/modules/tv/retiolum/config.nix b/old/modules/tv/retiolum/config.nix new file mode 100644 index 000000000..f1d227f6b --- /dev/null +++ b/old/modules/tv/retiolum/config.nix @@ -0,0 +1,130 @@ +{ cfg, config, lib, pkgs, ... }: + +let + inherit (lib) concatStrings singleton; + + tinc = cfg.tincPackage; + hostsType = builtins.typeOf cfg.hosts; + hosts = + if hostsType == "package" then + # use package as is + cfg.hosts + else if hostsType == "path" then + # use path to generate a package + pkgs.stdenv.mkDerivation { + name = "custom-retiolum-hosts"; + src = cfg.hosts; + installPhase = '' + mkdir $out + find . -name .git -prune -o -type f -print0 | xargs -0 cp --target-directory $out + ''; + } + else + abort "The option `services.retiolum.hosts' must be set to a package or a path" + ; + iproute = cfg.iproutePackage; + + retiolumExtraHosts = import (pkgs.runCommand "retiolum-etc-hosts" + { } + '' + generate() { + (cd ${hosts} + printf \'\' + for i in `ls`; do + names=$(hostnames $i) + for j in `sed -En 's|^ *Aliases *= *(.+)|\1|p' $i`; do + names="$names $(hostnames $j)" + done + sed -En ' + s|^ *Subnet *= *([^ /]*)(/[0-9]*)? *$|\1 '"$names"'|p + ' $i + done | sort + printf \'\' + ) + } + + case ${cfg.generateEtcHosts} in + short) + hostnames() { echo "$1"; } + generate + ;; + long) + hostnames() { echo "$1.${cfg.network}"; } + generate + ;; + both) + hostnames() { echo "$1.${cfg.network} $1"; } + generate + ;; + *) + echo '""' + ;; + esac > $out + ''); + + + confDir = pkgs.runCommand "retiolum" { + # TODO text + executable = true; + preferLocalBuild = true; + } '' + set -euf + + mkdir -p $out + + ln -s ${hosts} $out/hosts + + cat > $out/tinc.conf <<EOF + Name = ${cfg.name} + Device = /dev/net/tun + Interface = ${cfg.network} + ${concatStrings (map (c : "ConnectTo = " + c + "\n") cfg.connectTo)} + PrivateKeyFile = ${cfg.privateKeyFile} + EOF + + # source: krebscode/painload/retiolum/scripts/tinc_setup/tinc-up + cat > $out/tinc-up <<EOF + host=$out/hosts/${cfg.name} + ${iproute}/sbin/ip link set \$INTERFACE up + + addr4=\$(sed -n 's|^ *Subnet *= *\(10[.][^ ]*\) *$|\1|p' \$host) + if [ -n "\$addr4" ];then + ${iproute}/sbin/ip -4 addr add \$addr4 dev \$INTERFACE + ${iproute}/sbin/ip -4 route add 10.243.0.0/16 dev \$INTERFACE + fi + addr6=\$(sed -n 's|^ *Subnet *= *\(42[:][^ ]*\) *$|\1|p' \$host) + ${iproute}/sbin/ip -6 addr add \$addr6 dev \$INTERFACE + ${iproute}/sbin/ip -6 route add 42::/16 dev \$INTERFACE + EOF + + chmod +x $out/tinc-up + ''; + + + user = cfg.network + "-tinc"; + +in + +{ + environment.systemPackages = [ tinc hosts iproute ]; + + networking.extraHosts = retiolumExtraHosts; + + systemd.services.retiolum = { + description = "Tinc daemon for Retiolum"; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + path = [ tinc iproute ]; + serviceConfig = { + # TODO we cannot chroot (-R) b/c we use symlinks to hosts + # and the private key. + ExecStart = "${tinc}/sbin/tincd -c ${confDir} -d 0 -U ${user} -D"; + SyslogIdentifier = "retiolum-tincd"; + }; + }; + + users.extraUsers = singleton { + name = user; + uid = 2961822815; # bin/genid retiolum-tinc + }; +} diff --git a/old/modules/tv/retiolum/default.nix b/old/modules/tv/retiolum/default.nix new file mode 100644 index 000000000..93b0be097 --- /dev/null +++ b/old/modules/tv/retiolum/default.nix @@ -0,0 +1,11 @@ +arg@{ config, pkgs, lib, ... }: + +let + cfg = config.tv.retiolum; + arg' = arg // { inherit cfg; }; +in + +{ + options.tv.retiolum = import ./options.nix arg'; + config = lib.mkIf cfg.enable (import ./config.nix arg'); +} diff --git a/old/modules/tv/retiolum/options.nix b/old/modules/tv/retiolum/options.nix new file mode 100644 index 000000000..a06cbecef --- /dev/null +++ b/old/modules/tv/retiolum/options.nix @@ -0,0 +1,87 @@ +{ config, lib, pkgs, ... }: + +let + inherit (lib) mkOption types; +in + +{ + enable = mkOption { + type = types.bool; + default = false; + description = "Enable tinc daemon for Retiolum."; + }; + + name = mkOption { + type = types.string; + default = config.networking.hostName; + # Description stolen from tinc.conf(5). + description = '' + This is the name which identifies this tinc daemon. It must + be unique for the virtual private network this daemon will + connect to. The Name may only consist of alphanumeric and + underscore characters. If Name starts with a $, then the + contents of the environment variable that follows will be + used. In that case, invalid characters will be converted to + underscores. If Name is $HOST, but no such environment + variable exist, the hostname will be read using the + gethostnname() system call This is the name which identifies + the this tinc daemon. + ''; + }; + + generateEtcHosts = mkOption { + type = types.string; + default = "both"; + description = '' + If set to <literal>short</literal>, <literal>long</literal>, or <literal>both</literal>, + then generate entries in <filename>/etc/hosts</filename> from subnets. + ''; + }; + + network = mkOption { + type = types.string; + default = "retiolum"; + description = '' + The tinc network name. + It is used to generate long host entries, + derive the name of the user account under which tincd runs, + and name the TUN device. + ''; + }; + + tincPackage = mkOption { + type = types.package; + default = pkgs.tinc; + description = "Tincd package to use."; + }; + + hosts = mkOption { + default = null; + description = '' + Hosts package or path to use. + If a path is given, then it will be used to generate an ad-hoc package. + ''; + }; + + iproutePackage = mkOption { + type = types.package; + default = pkgs.iproute; + description = "Iproute2 package to use."; + }; + + + privateKeyFile = mkOption { + # TODO if it's types.path then it gets copied to /nix/store with + # bad unsafe permissions... + type = types.string; + default = "/etc/tinc/retiolum/rsa_key.priv"; + description = "Generate file with <literal>tincd -K</literal>."; + }; + + connectTo = mkOption { + type = types.listOf types.string; + default = [ "fastpoke" "pigstarter" "kheurop" ]; + description = "TODO describe me"; + }; + +} diff --git a/old/modules/tv/sanitize.nix b/old/modules/tv/sanitize.nix new file mode 100644 index 000000000..173341452 --- /dev/null +++ b/old/modules/tv/sanitize.nix @@ -0,0 +1,12 @@ +{ ... }: + +{ + nixpkgs.config.packageOverrides = pkgs: + { + nano = pkgs.runCommand "empty" {} "mkdir -p $out"; + }; + + services.cron.enable = false; + services.nscd.enable = false; + services.ntp.enable = false; +} diff --git a/old/modules/tv/smartd.nix b/old/modules/tv/smartd.nix new file mode 100644 index 000000000..2e9d955d1 --- /dev/null +++ b/old/modules/tv/smartd.nix @@ -0,0 +1,17 @@ +{ config, pkgs, ... }: + +{ + services.smartd = { + enable = true; + devices = [ + { + device = "DEVICESCAN"; + options = toString [ + "-a" + "-m tv@wu.retiolum" + "-s (O/../.././09|S/../.././04|L/../../6/05)" + ]; + } + ]; + }; +} diff --git a/old/modules/tv/synaptics.nix b/old/modules/tv/synaptics.nix new file mode 100644 index 000000000..c47cb9deb --- /dev/null +++ b/old/modules/tv/synaptics.nix @@ -0,0 +1,14 @@ +{ config, pkgs, ... }: + +{ + # TODO this is host specific + services.xserver.synaptics = { + enable = true; + twoFingerScroll = true; + accelFactor = "0.035"; + additionalOptions = '' + Option "FingerHigh" "60" + Option "FingerLow" "60" + ''; + }; +} diff --git a/old/modules/tv/urlwatch/default.nix b/old/modules/tv/urlwatch/default.nix new file mode 100644 index 000000000..87ec289f7 --- /dev/null +++ b/old/modules/tv/urlwatch/default.nix @@ -0,0 +1,158 @@ +{ config, lib, pkgs, ... }: + +# TODO multiple users +# TODO inform about unused caches +# cache = url: "${cfg.dataDir}/.urlwatch/cache/${hashString "sha1" url}" +# TODO hooks.py + +let + inherit (builtins) toFile; + inherit (lib) + concatStringsSep escapeShellArg mkIf mkOption optionals singleton types; + inherit (pkgs) writeScript; + + cfg = config.tv.urlwatch; + + api = { + dataDir = mkOption { + type = types.str; + default = "/var/lib/urlwatch"; + description = '' + Directory where the urlwatch service should store its state. + ''; + }; + enable = mkOption { + type = types.bool; + default = false; + description = '' + Whether to enable the urlwatch service. + If enabled, then create a timer that calls urlwatch and sends mails + whenever something has changed or an error occurs. + ''; + }; + from = mkOption { + type = types.str; + default = "${cfg.user}@${config.networking.hostName}.retiolum"; + description = '' + Content of the From: header of the generated mails. + ''; + }; + mailto = mkOption { + type = types.str; + description = '' + Content of the To: header of the generated mails. [AKA recipient :)] + ''; + }; + onCalendar = mkOption { + type = types.str; + description = '' + Run urlwatch at this interval. + The format is described in systemd.time(7), CALENDAR EVENTS. + ''; + example = "04:23"; + }; + urls = mkOption { + type = with types; listOf str; + description = "URL to watch."; + example = [ + https://nixos.org/channels/nixos-unstable/git-revision + ]; + }; + user = mkOption { + type = types.str; + default = "urlwatch"; + description = "User under which urlwatch runs."; + }; + }; + + urlsFile = toFile "urls" (concatStringsSep "\n" cfg.urls); + + impl = { + systemd.timers.urlwatch = { + wantedBy = [ "timers.target" ]; + timerConfig = { + OnCalendar = cfg.onCalendar; + Persistent = "true"; + }; + }; + systemd.services.urlwatch = { + path = with pkgs; [ + coreutils + gnused + urlwatch + ]; + environment = { + HOME = cfg.dataDir; + LC_ALL = "en_US.UTF-8"; + LOCALE_ARCHIVE = "${pkgs.glibcLocales}/lib/locale/locale-archive"; + SSL_CERT_FILE = "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt"; + }; + serviceConfig = { + User = cfg.user; + PermissionsStartOnly = "true"; + PrivateTmp = "true"; + Type = "oneshot"; + ExecStartPre = + writeScript "urlwatch-prestart" '' + #! /bin/sh + set -euf + + dataDir=$HOME + user=${escapeShellArg cfg.user} + + if ! test -e "$dataDir"; then + mkdir -m 0700 -p "$dataDir" + chown "$user": "$dataDir" + fi + ''; + ExecStart = writeScript "urlwatch" '' + #! /bin/sh + set -euf + + from=${escapeShellArg cfg.from} + mailto=${escapeShellArg cfg.mailto} + urlsFile=${escapeShellArg urlsFile} + user=${escapeShellArg cfg.user} + + cd /tmp + + urlwatch -e --urls="$urlsFile" > changes 2>&1 || : + + if test -s changes; then + date=$(date -R) + subject=$(sed -n 's/^\(CHANGED\|ERROR\|NEW\): //p' changes \ + | tr \\n \ ) + { + echo "Date: $date" + echo "From: $from" + echo "Subject: $subject" + echo "To: $mailto" + echo + cat changes + } | /var/setuid-wrappers/sendmail -t + fi + ''; + }; + }; + users.extraUsers = optionals (cfg.user == "urlwatch") (singleton { + name = "urlwatch"; + uid = 3450919516; # bin/genid urlwatch + }); + }; + +in + +{ + # TODO + #imports = [ + # ./exim + #]; + #config = mkIf cfg.enable + # (if config.tv.exim.enable + # then impl + # else throw "tv.exim must be enabled when enabling tv.urlwatch"); + + options.tv.urlwatch = api; + + config = impl; +} diff --git a/old/modules/tv/urxvt.nix b/old/modules/tv/urxvt.nix new file mode 100644 index 000000000..a97581248 --- /dev/null +++ b/old/modules/tv/urxvt.nix @@ -0,0 +1,24 @@ +{ pkgs, ... }: + + with builtins; + +let + users = [ "tv" ]; + urxvt = pkgs.rxvt_unicode; + mkService = user: { + description = "urxvt terminal daemon"; + wantedBy = [ "multi-user.target" ]; + restartIfChanged = false; + serviceConfig = { + Restart = "always"; + User = user; + ExecStart = "${urxvt}/bin/urxvtd"; + }; + }; + +in + +{ + environment.systemPackages = [ urxvt ]; + systemd.services = listToAttrs (map (u: { name = "${u}-urxvtd"; value = mkService u; }) users); +} diff --git a/old/modules/tv/users/default.nix b/old/modules/tv/users/default.nix new file mode 100644 index 000000000..719f57d70 --- /dev/null +++ b/old/modules/tv/users/default.nix @@ -0,0 +1,67 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.tv.users; + + opts = { + enable = mkOption { + default = true; + type = types.bool; + description = '' + If set to false, TODO... + ''; + }; + + packages = mkOption { + default = []; + #example = literalExample "[ pkgs.firefox pkgs.thunderbird ]"; + type = with types; listOf path; + description = '' + TODO this description is for environment.systemPackages + The set of packages that appear in + /run/current-system/sw. These packages are + automatically available to all users, and are + automatically updated every time you rebuild the system + configuration. (The latter is the main difference with + installing them in the default profile, + <filename>/nix/var/nix/profiles/default</filename>. + ''; + }; + }; +in + +{ + options.tv.users = mkOption { + default = {}; + type = with types; attrsOf optionSet; + options = [ opts ]; + description = '' + TODO + ''; + }; + + config = { + system.activationScripts."tv.users" = + let + bindir = name: packages: + pkgs.symlinkJoin "${name}-bindir" (map (path: path + "/" + "bin") packages); + in + '' + mkdir -m 0755 -p /run/tv.users + # TODO delete old + # TODO detect collisions + # TODO don't link .xxx-wrapped + ${concatStrings (mapAttrsToList (name: { packages, ... }: '' + mkdir -m 0755 -p /run/tv.users/${name} + ln -snf ${bindir name packages} /run/tv.users/${name}/bin + '') cfg)} + ''; + environment.shellInit = '' + # XXX lower precedence than ~/bin + PATH=/run/tv.users/$LOGNAME/bin:$PATH + export PATH + ''; + }; +} diff --git a/old/modules/tv/xserver.nix b/old/modules/tv/xserver.nix new file mode 100644 index 000000000..897dbcc28 --- /dev/null +++ b/old/modules/tv/xserver.nix @@ -0,0 +1,40 @@ +{ config, pkgs, ... }: + +{ + services.xserver.enable = true; + + + #fonts.enableFontConfig = true; + #fonts.enableFontDir = true; + fonts.fonts = [ + pkgs.xlibs.fontschumachermisc + ]; + #services.xfs.enable = true; + #services.xserver.useXFS = "unix/:7100"; + + services.xserver.displayManager.desktopManagerHandlesLidAndPower = true; + + #services.xserver.display = 11; + #services.xserver.tty = 11; + # services.xserver.layout = "us"; + # services.xserver.xkbOptions = "eurosign:e"; + + #services.xserver.multitouch.enable = true; + + services.xserver.windowManager.xmonad.extraPackages = hspkgs: with hspkgs; [ + X11-xshape + ]; + services.xserver.windowManager.xmonad.enable = true; + services.xserver.windowManager.xmonad.enableContribAndExtras = true; + services.xserver.windowManager.default = "xmonad"; + services.xserver.desktopManager.default = "none"; + services.xserver.desktopManager.xterm.enable = false; + + services.xserver.displayManager.slim.enable = true; + #services.xserver.displayManager.auto.enable = true; + #services.xserver.displayManager.auto.user = "tv"; + #services.xserver.displayManager.job.logsXsession = true; + + + services.xserver.vaapiDrivers = [ pkgs.vaapiIntel ]; +} diff --git a/old/modules/uriel/default.nix b/old/modules/uriel/default.nix new file mode 100644 index 000000000..7f2b9032b --- /dev/null +++ b/old/modules/uriel/default.nix @@ -0,0 +1,184 @@ +{ config, pkgs, ... }: + +{ + imports = [ + ../lass/desktop-base.nix + ../lass/retiolum-uriel.nix + ../lass/xserver-lass.nix + ../lass/browsers.nix + ../lass/programs.nix + ../lass/games.nix + ../tv/exim-retiolum.nix + ../lass/pass.nix + ../lass/vim.nix + ../lass/urxvt.nix + ../common/nixpkgs.nix + ../../secrets/uriel-pw.nix + ../lass/sshkeys.nix + ../lass/bird.nix + ./repos.nix + ../lass/chromium-patched.nix + ]; + + nixpkgs = { + url = "https://github.com/Lassulus/nixpkgs"; + rev = "45c99e522dcc4ef24cf71dbe38d94a308cb30530"; + }; + + networking.hostName = "uriel"; + networking.wireless.enable = true; + nix.maxJobs = 2; + + hardware.enableAllFirmware = true; + nixpkgs.config.allowUnfree = true; + + boot = { + #kernelParams = [ + # "acpi.brightness_switch_enabled=0" + #]; + #loader.grub.enable = true; + #loader.grub.version = 2; + #loader.grub.device = "/dev/sda"; + + loader.gummiboot.enable = true; + loader.gummiboot.timeout = 5; + + initrd.luks.devices = [ { name = "luksroot"; device = "/dev/sda2"; } ]; + initrd.luks.cryptoModules = [ "aes" "sha512" "sha1" "xts" ]; + initrd.availableKernelModules = [ "xhci_hcd" "ehci_pci" "ahci" "usb_storage" ]; + #kernelModules = [ "kvm-intel" "msr" ]; + kernelModules = [ "msr" ]; + extraModprobeConfig = '' + ''; + }; + fileSystems = { + "/" = { + device = "/dev/pool/root"; + fsType = "ext4"; + }; + + "/boot" = { + device = "/dev/sda1"; + }; + }; + + services.udev.extraRules = '' + SUBSYSTEM=="net", ATTR{address}=="64:27:37:7d:d8:ae", NAME="wl0" + SUBSYSTEM=="net", ATTR{address}=="f0:de:f1:b8:c8:2e", NAME="et0" + ''; + + #services.xserver = { + #}; + + services.xserver.synaptics = { + enable = true; + twoFingerScroll = true; + accelFactor = "0.035"; + additionalOptions = '' + Option "FingerHigh" "60" + Option "FingerLow" "60" + ''; + }; + + users.extraUsers = { + root = { + openssh.authorizedKeys.keys = [ + config.sshKeys.lass.pub + ]; + }; + mainUser = { + uid = 1337; + name = "lass"; + #isNormalUser = true; + group = "users"; + createHome = true; + home = "/home/lass"; + useDefaultShell = true; + isSystemUser = false; + description = "lassulus"; + extraGroups = [ "wheel" "audio" ]; + openssh.authorizedKeys.keys = [ + config.sshKeys.lass.pub + ]; + }; + }; + + environment.systemPackages = with pkgs; [ + ]; + + + #users.extraGroups = { + # loot = { + # members = [ + # "lass" + # "firefox" + # "chromium" + # "google" + # ]; + # }; + #}; + # + # iptables + # + #networking.firewall.enable = false; + #system.activationScripts.iptables = + # let + # log = false; + # when = c: f: if c then f else ""; + # in + # '' + # ip4tables() { ${pkgs.iptables}/sbin/iptables "$@"; } + # ip6tables() { ${pkgs.iptables}/sbin/ip6tables "$@"; } + # ipXtables() { ip4tables "$@"; ip6tables "$@"; } + + # # + # # nat + # # + + # # reset tables + # ipXtables -t nat -F + # ipXtables -t nat -X + + # # + # #ipXtables -t nat -A PREROUTING -j REDIRECT ! -i retiolum -p tcp --dport ssh --to-ports 0 + # ipXtables -t nat -A PREROUTING -j REDIRECT -p tcp --dport 11423 --to-ports ssh + + # # + # # filter + # # + + # # reset tables + # ipXtables -P INPUT DROP + # ipXtables -P FORWARD DROP + # ipXtables -F + # ipXtables -X + + # # create custom chains + # ipXtables -N Retiolum + + # # INPUT + # ipXtables -A INPUT -j ACCEPT -m conntrack --ctstate RELATED,ESTABLISHED + # ipXtables -A INPUT -j ACCEPT -i lo + # ipXtables -A INPUT -j ACCEPT -p tcp --dport ssh -m conntrack --ctstate NEW + # ipXtables -A INPUT -j ACCEPT -p tcp --dport http -m conntrack --ctstate NEW + # ipXtables -A INPUT -j ACCEPT -p tcp --dport tinc -m conntrack --ctstate NEW + # ipXtables -A INPUT -j Retiolum -i retiolum + # ${when log "ipXtables -A INPUT -j LOG --log-level info --log-prefix 'INPUT DROP '"} + + # # FORWARD + # ${when log "ipXtables -A FORWARD -j LOG --log-level info --log-prefix 'FORWARD DROP '"} + + # # Retiolum + # ip4tables -A Retiolum -j ACCEPT -p icmp --icmp-type echo-request + # ip6tables -A Retiolum -j ACCEPT -p ipv6-icmp -m icmp6 --icmpv6-type echo-request + + + # ${when log "ipXtables -A Retiolum -j LOG --log-level info --log-prefix 'REJECT '"} + # ipXtables -A Retiolum -j REJECT -p tcp --reject-with tcp-reset + # ip4tables -A Retiolum -j REJECT -p udp --reject-with icmp-port-unreachable + # ip4tables -A Retiolum -j REJECT --reject-with icmp-proto-unreachable + # ip6tables -A Retiolum -j REJECT -p udp --reject-with icmp6-port-unreachable + # ip6tables -A Retiolum -j REJECT + + # ''; +} diff --git a/old/modules/uriel/repos.nix b/old/modules/uriel/repos.nix new file mode 100644 index 000000000..e31ba9481 --- /dev/null +++ b/old/modules/uriel/repos.nix @@ -0,0 +1,78 @@ +{ ... }: + +{ + imports = [ + ../lass/gitolite-base.nix + ../common/krebs-keys.nix + ../common/krebs-repos.nix + ]; + + services.gitolite = { + repos = { + + config = { + users = { + lass = "RW+"; + uriel = "R"; + tv = "R"; + }; + extraConfig = "option hook.post-receive = irc-announce"; + }; + + pass = { + users = { + lass = "RW+"; + uriel = "R"; + }; + }; + + load-env = { + users = { + lass = "RW+"; + uriel = "R"; + tv = "R"; + }; + extraConfig = "option hook.post-receive = irc-announce"; + }; + + emse-hsdb = { + users = { + lass = "RW+"; + uriel = "R"; + tv = "R"; + }; + extraConfig = "option hook.post-receive = irc-announce"; + }; + + brain = { + users = { + lass = "RW+"; + }; + extraConfig = "option hook.post-receive = irc-announce"; + #hooks.post-receive = irc-announce; + }; + + painload = { + users = { + lass = "RW+"; + }; + extraConfig = "option hook.post-receive = irc-announce"; + }; + + services = { + users = { + lass = "RW+"; + }; + extraConfig = "option hook.post-receive = irc-announce"; + }; + + xmonad-config = { + users = { + lass = "RW+"; + uriel = "R"; + }; + }; + + }; + }; +} diff --git a/old/modules/wu/default.nix b/old/modules/wu/default.nix new file mode 100644 index 000000000..e55fbaf3f --- /dev/null +++ b/old/modules/wu/default.nix @@ -0,0 +1,464 @@ +{ config, pkgs, ... }: + +let + location = pkgs.lib.nameValuePair; # TODO this is also in modules/tv/git/cgit.nix +in + +{ + imports = [ + ./hosts.nix + ../tv/base.nix + ../tv/config/consul-client.nix + ../tv/exim-retiolum.nix + ../tv/environment.nix + ../tv/sanitize.nix + ../tv/smartd.nix + ../tv/synaptics.nix + ../tv/urxvt.nix + ../tv/xserver.nix + ../wu/users.nix + { + imports = [ ../tv/identity ]; + tv.identity = { + enable = true; + self = config.tv.identity.hosts.wu; + }; + } + { + imports = [ ../tv/iptables ]; + tv.iptables = { + enable = true; + input-internet-accept-new-tcp = [ + "ssh" + "http" + "tinc" + "smtp" + ]; + }; + } + { + imports = [ ../tv/nginx ]; + tv.nginx = { + enable = true; + retiolum-locations = [ + (location "~ ^/~(.+?)(/.*)?\$" '' + alias /home/$1/public_html$2; + '') + ]; + }; + } + { + imports = [ ../tv/retiolum ]; + tv.retiolum = { + enable = true; + hosts = <retiolum-hosts>; + connectTo = [ + "gum" + "pigstarter" + ]; + }; + } + { + imports = [ ../tv/urlwatch ]; + tv.urlwatch = { + enable = true; + mailto = "tv@wu.retiolum"; + onCalendar = "*-*-* 05:00:00"; + urls = [ + ## nixpkgs maintenance + + # 2014-07-29 when one of the following urls change + # then we have to update the package + + # ref src/nixpkgs/pkgs/tools/admin/sec/default.nix + http://simple-evcorr.sourceforge.net/ + + # ref src/nixpkgs/pkgs/tools/networking/urlwatch/default.nix + https://thp.io/2008/urlwatch/ + + # 2014-12-20 ref src/nixpkgs/pkgs/tools/networking/tlsdate/default.nix + https://api.github.com/repos/ioerror/tlsdate/tags + + # 2015-02-18 + # ref ~/src/nixpkgs/pkgs/tools/text/qprint/default.nix + http://www.fourmilab.ch/webtools/qprint/ + + # 2014-09-24 ref https://github.com/4z3/xintmap + http://www.mathstat.dal.ca/~selinger/quipper/ + + # 2014-12-12 remove nixopsUnstable when nixops get's bumped to 1.3 + # ref https://github.com/NixOS/nixpkgs/blob/master/pkgs/tools/package-management/nixops/unstable.nix + http://nixos.org/releases/nixops/ + + ## other + + https://nixos.org/channels/nixos-unstable/git-revision + + ## 2014-10-17 + ## TODO update ~/src/login/default.nix + #http://hackage.haskell.org/package/bcrypt + #http://hackage.haskell.org/package/cron + #http://hackage.haskell.org/package/hyphenation + #http://hackage.haskell.org/package/iso8601-time + #http://hackage.haskell.org/package/ixset-typed + #http://hackage.haskell.org/package/system-command + #http://hackage.haskell.org/package/transformers + #http://hackage.haskell.org/package/web-routes-wai + #http://hackage.haskell.org/package/web-page + ]; + }; + } + ]; + + nix = { + buildCores = 4; + maxJobs = 4; + daemonIONiceLevel = 1; + daemonNiceLevel = 1; + }; + + services.udev.extraRules = '' + SUBSYSTEM=="net", ATTR{address}=="00:90:f5:da:aa:c3", NAME="en0" + SUBSYSTEM=="net", ATTR{address}=="a0:88:b4:1b:ae:6c", NAME="wl0" + + # for jack + KERNEL=="rtc0", GROUP="audio" + KERNEL=="hpet", GROUP="audio" + ''; + + #services.virtualbox.enable = true; + #services.virtualboxGuest.enable = false; + services.virtualboxHost.enable = true; + #services.virtualboxHost.addNetworkInterface = false; + #systemd.services.vboxnet = + # let + # remove_vboxnets = '' + # for i in $(cd /sys/class/net && ls | grep ^vboxnet); do + # VBoxManage hostonlyif remove $i + # done + # ''; + # in { + # wantedBy = [ "multi-user.target" ]; + # requires = [ "dev-vboxnetctl.device" ]; + # after = [ "dev-vboxnetctl.device" ]; + # path = with pkgs; [ + # linuxPackages.virtualbox + # nettools + # ]; + # postStop = remove_vboxnets; + # script = '' + # ${remove_vboxnets} # just in case... + # VBoxManage hostonlyif create # vboxnet0 + # ifconfig vboxnet0 up 169.254.13.37/16 + # ''; + # serviceConfig = { + # Type = "oneshot"; + # PrivateTmp = true; + # RemainAfterExit = "yes"; + # }; + # environment.VBOX_USER_HOME = "/tmp"; + # }; + + + services.bitlbee.enable = true; + + #services.rabbitmq = { + # enable = true; + # cookie = "f00f"; + # plugins = [ + # "rabbitmq_management" + # ]; + #}; + + + #services.elasticsearch.enable = true; + + #services.cgserver = { + # enable = true; + # httpPort = 8003; + # #flushLog = false; + # #cgroupRoot = "/sys/fs/cgroup"; + # #user = "zalora"; + #}; + + + + + #services.tlsdated = { + # enable = true; + # extraOptions = "-p"; + #}; + + services.tor.enable = true; + services.tor.client.enable = true; + + + + # hardware configuration + boot.initrd.luks.devices = [ + { name = "home"; device = "/dev/vg840/enchome"; preLVM = false; } + ]; + boot.initrd.luks.cryptoModules = [ "aes" "sha512" "xts" ]; + boot.initrd.availableKernelModules = [ "ahci" ]; + #boot.kernelParams = [ + # "intel_pstate=enable" + #]; + boot.kernelModules = [ "kvm-intel" ]; + boot.extraModulePackages = [ ]; + + # 2014-12-17 pkgs.linuxPackages_3_14 is known good + boot.kernelPackages = pkgs.linuxPackages_3_18; + + boot.kernel.sysctl = { + # Enable IPv6 Privacy Extensions + "net.ipv6.conf.all.use_tempaddr" = 2; + "net.ipv6.conf.default.use_tempaddr" = 2; + }; + + boot.extraModprobeConfig = '' + options kvm_intel nested=1 + ''; + + fileSystems = { + "/" = { + device = "/dev/mapper/vg840-wuroot"; + fsType = "btrfs"; + options = "defaults,noatime,ssd,compress=lzo"; + }; + "/home" = { + device = "/dev/mapper/home"; + options = "defaults,noatime,ssd,compress=lzo"; + }; + "/boot" = { + device = "/dev/sda1"; + }; + "/tmp" = { + device = "tmpfs"; + fsType = "tmpfs"; + options = "nosuid,nodev,noatime"; + }; + }; + + swapDevices =[ ]; + + + nixpkgs.config.firefox.enableAdobeFlash = true; + nixpkgs.config.chromium.enablePepperFlash = true; + + nixpkgs.config.allowUnfree = true; + hardware.bumblebee.enable = true; # TODO this is host specific + hardware.bumblebee.group = "video"; + #services.xserver.videoDrivers = [ "nvidia" ]; + hardware.opengl.driSupport32Bit = true; + + hardware.pulseaudio.enable = true; + + hardware.enableAllFirmware = true; + + # Use the gummiboot efi boot loader. + boot.loader.gummiboot.enable = true; + boot.loader.efi.canTouchEfiVariables = true; + + networking.hostName = "wu"; + networking.wireless.enable = true; + + + # Select internationalisation properties. + # i18n = { + # consoleFont = "lat9w-16"; + # consoleKeyMap = "us"; + # defaultLocale = "en_US.UTF-8"; + # }; + + system.activationScripts.powertopTunables = + '' + echo 1 > /sys/module/snd_hda_intel/parameters/power_save + echo 1500 > /proc/sys/vm/dirty_writeback_centisecs + (cd /sys/bus/pci/devices + for i in *; do + echo auto > $i/power/control # defaults to 'on' + done) + # TODO maybe do this via udev or systemd + # ref https://wiki.archlinux.org/index.php/Wake-on-LAN + # disable wol this cannot find ethtool + # TODO (cd /sys/class/net + # TODO for i in *; do + # TODO if ethtool $i | grep -q Wake-on && + # TODO ! ethtool $i | grep -q 'Wake-on: d'; then + # TODO ethtool -s $i wol d + # TODO fi + # TODO done) + ${pkgs.ethtool}/sbin/ethtool -s en0 wol d + ''; + + environment.systemPackages = with pkgs; [ + xlibs.fontschumachermisc + slock + ethtool + #firefoxWrapper # with plugins + #chromiumDevWrapper + tinc + iptables + #jack2 + ]; + + security.setuidPrograms = [ + "sendmail" # for cron + "slock" + ]; + + # TODO + # Currently ./run doesn't know about certificates + #security.pki.certificateFiles = [ + # ./certs/zalora-ca.crt + #]; + + #security.pam.loginLimits = [ + # # for jack + # { domain = "@audio"; item = "memlock"; type = "-"; value = "unlimited"; } + # { domain = "@audio"; item = "rtprio"; type = "-"; value = "99"; } + #]; + + #services.haveged.enable = true; + #security.rngd.enable = true; + + #services.privoxy = { + # enable = true; + # extraConfig = '' + # actionsfile /etc/privoxy/easylist.script.action + # actionsfile /etc/privoxy/easylistgermany.script.action + # filterfile /etc/privoxy/easylist.script.filter + # filterfile /etc/privoxy/easylistgermany.script.filter + # ''; + #}; + + #services.dbus.enable = true; # rqd4 wpa_supplicant + + services.logind.extraConfig = '' + HandleHibernateKey=ignore + HandleLidSwitch=ignore + HandlePowerKey=ignore + HandleSuspendKey=ignore + ''; + + # Enable the OpenSSH daemon. + services.openssh = { + enable = true; + hostKeys = [ + # XXX bits here make no science + { bits = 8192; type = "ed25519"; path = "/etc/ssh/ssh_host_ed25519_key"; } + ]; + }; + + # services.printing.enable = true; + services.printing = { + enable = true; + #extraConf = '' + # LogLevel debug + #''; + drivers = with pkgs; [ + #cups_filters + #foomatic_filters + #gutenprint + #hplip + ]; + }; + + + + #services.kmscon.enable = true; + + + # TODO virtualisation.libvirtd.enable = true; + # users.extraUsers.tv.extraGroups += [ "libvirtd" ] + + + + + services.journald.extraConfig = '' + SystemMaxUse=1G + RuntimeMaxUse=128M + ''; + + + #systemd.timers.chargeMon = { + # wantedBy = [ "multi-user.target" ]; + # timerConfig.OnCalendar = "*-*-* *:*:00"; + #}; + #systemd.services.chargeMon = { + # path = [ ]; + # environment = { + # ac_online = "/sys/class/power_supply/AC/online"; + # charge_now = "/sys/class/power_supply/BAT/charge_now"; + # charge_full = "/sys/class/power_supply/BAT/charge_full"; + # }; + # serviceConfig = { + # User = "nobody"; + # Type = "oneshot"; + # }; + # script = '' + # if test $(cat $ac_online) == 1; then + # echo "AC is online" + # exit + # fi + # cat $charge_now + # ''; + #}; + + # see tmpfiles.d(5) + systemd.tmpfiles.rules = [ + "d /tmp 1777 root root - -" # does this work with mounted /tmp? + ]; + + # TODO services.smartd + # TODO services.statsd + # TODO services.tor + # TODO write arandr + # TODO what does system.copySystemConfiguration (we need some kind of bku scheme) + # TODO systemd.timers instead of cron(??) + + virtualisation.libvirtd.enable = true; + + + + + #system.replaceRuntimeDependencies = with pkgs; + # let + # bashVulnPatches = [ + # (fetchurl { + # url = "mirror://gnu/bash/bash-4.2-patches/bash42-048"; + # sha256 = "091xk1ms7ycnczsl3fx461gjhj69j6ycnfijlymwj6mj60ims6km"; + # }) + # (fetchurl { + # url = "file:///etc/nixos/bash-20140926.patch"; + # sha256 = "0gdwnimsbi4vh5l46krss4wjrgbch94skn4y2w3rpvb1w4jypha4"; + # }) + # ]; + # in + # [ + # { + # original = bash; + # replacement = pkgs.lib.overrideDerivation bash (oldAttrs: { + # patches = oldAttrs.patches ++ bashVulnPatches; + # }); + # } + # { + # original = bashInteractive; + # replacement = pkgs.lib.overrideDerivation bashInteractive (oldAttrs: { + # patches = oldAttrs.patches ++ bashVulnPatches; + # }); + # } + # { + # original = bitlbee; + # replacement = pkgs.lib.overrideDerivation bitlbee (oldAttrs: { + # configureFlags = [ + # "--gcov=1" + # "--otr=1" + # "--ssl=gnutls" + # ]; + # }); + # } + #]; + + +} diff --git a/old/modules/wu/hosts.nix b/old/modules/wu/hosts.nix new file mode 100644 index 000000000..207553b08 --- /dev/null +++ b/old/modules/wu/hosts.nix @@ -0,0 +1,22 @@ +{ config, pkgs, ... }: + +{ + networking.extraHosts = + '' + 192.168.1.1 wrt.gg23 wrt + 192.168.1.11 mors.gg23 + 192.168.1.12 uriel.gg23 + 192.168.1.23 raspi.gg23 raspi + 192.168.1.37 wu.gg23 + 192.168.1.110 nomic.gg23 + 192.168.1.124 schnabeldrucker.gg23 schnabeldrucker + + 127.0.0.1 dev.zalora.sg www.dev.zalora.sg bob.dev.zalora.sg static.dev.zalora.sg + 127.0.0.1 dev.zalora.com.my www.dev.zalora.com.my bob.dev.zalora.com.my static.dev.zalora.com.my + 127.0.0.1 dev.zalora.com.ph www.dev.zalora.com.ph bob.dev.zalora.com.ph static.dev.zalora.com.ph + 127.0.0.1 dev.zalora.vn www.dev.zalora.vn bob.dev.zalora.vn static.dev.zalora.vn + 127.0.0.1 dev.zalora.co.id www.dev.zalora.co.id bob.dev.zalora.co.id static.dev.zalora.co.id + 127.0.0.1 dev.zalora.co.th www.dev.zalora.co.th bob.dev.zalora.co.th static.dev.zalora.co.th + 127.0.0.1 dev.zalora.com.hk www.dev.zalora.com.hk bob.dev.zalora.com.hk static.dev.zalora.com.hk + ''; +} diff --git a/old/modules/wu/paths.nix b/old/modules/wu/paths.nix new file mode 100644 index 000000000..2d2ff7b74 --- /dev/null +++ b/old/modules/wu/paths.nix @@ -0,0 +1,12 @@ +{ + lib.file.url = ../../lib; + modules.file.url = ../../modules; + nixpkgs.git = { + url = https://github.com/NixOS/nixpkgs; + rev = "e1af50c4c4c0332136283e9231f0a32ac11f2b90"; + cache = ../../tmp/git-cache; + }; + pubkeys.file.url = ../../pubkeys; + retiolum-hosts.file.url = ../../hosts; + secrets.file.url = ../../secrets/wu/nix; +} diff --git a/old/modules/wu/users.nix b/old/modules/wu/users.nix new file mode 100644 index 000000000..e50878cd0 --- /dev/null +++ b/old/modules/wu/users.nix @@ -0,0 +1,227 @@ +{ config, lib, pkgs, ... }: + +let + inherit (builtins) attrValues; + inherit (pkgs.lib) concatMap filterAttrs mapAttrs concatStringsSep; + + + users = { + tv = { + uid = 1337; + group = "users"; + extraGroups = [ + "audio" + "video" + "wheel" + ]; + }; + + ff = { + uid = 13378001; + group = "tv-sub"; + extraGroups = [ + "audio" + "video" + ]; + }; + + cr = { + uid = 13378002; + group = "tv-sub"; + extraGroups = [ + "audio" + "video" + "bumblebee" + ]; + }; + + vimb = { + uid = 13378003; + group = "tv-sub"; + extraGroups = [ + "audio" + "video" + "bumblebee" + ]; + }; + + fa = { + uid = 2300001; + group = "tv-sub"; + }; + + rl = { + uid = 2300002; + group = "tv-sub"; + }; + + tief = { + uid = 2300702; + group = "tv-sub"; + }; + + btc-bitcoind = { + uid = 2301001; + group = "tv-sub"; + }; + + btc-electrum = { + uid = 2301002; + group = "tv-sub"; + }; + + ltc-litecoind = { + uid = 2301101; + group = "tv-sub"; + }; + + eth = { + uid = 2302001; + group = "tv-sub"; + }; + + emse-hsdb = { + uid = 4200101; + group = "tv-sub"; + }; + + wine = { + uid = 13370400; + group = "tv-sub"; + extraGroups = [ + "audio" + "video" + "bumblebee" + ]; + }; + + # dwarffortress + df = { + uid = 13370401; + group = "tv-sub"; + extraGroups = [ + "audio" + "video" + "bumblebee" + ]; + }; + + # XXX visudo: Warning: Runas_Alias `FTL' referenced but not defined + FTL = { + uid = 13370402; + #group = "tv-sub"; + extraGroups = [ + "audio" + "video" + "bumblebee" + ]; + }; + + freeciv = { + uid = 13370403; + group = "tv-sub"; + }; + + xr = { + uid = 13370061; + group = "tv-sub"; + extraGroups = [ + "audio" + "video" + ]; + }; + + "23" = { + uid = 13370023; + group = "tv-sub"; + }; + + electrum = { + uid = 13370102; + group = "tv-sub"; + }; + + Reaktor = { + uid = 4230010; + group = "tv-sub"; + }; + + gitolite = { + uid = 7700; + }; + + skype = { + uid = 6660001; + group = "tv-sub"; + extraGroups = [ + "audio" + ]; + }; + + onion = { + uid = 6660010; + group = "tv-sub"; + }; + + zalora = { + uid = 1000301; + group = "tv-sub"; + extraGroups = [ + "audio" + # TODO remove vboxusers when hardening is active + "vboxusers" + "video" + ]; + }; + + }; + + + extraUsers = + mapAttrs (name: user: user // { + inherit name; + home = "/home/${name}"; + createHome = true; + useDefaultShell = true; + }) users; + + + extraGroups = { + tv-sub.gid = 1337; + }; + + + sudoers = + let + inherit (builtins) filter hasAttr; + inherit (import ../../lib { inherit lib pkgs; }) + concat isSuffixOf removeSuffix setToList; + + hasMaster = { group ? "", ... }: + isSuffixOf "-sub" group; + + masterOf = user : removeSuffix "-sub" user.group; + in + concatStringsSep "\n" + (map (u: "${masterOf u} ALL=(${u.name}) NOPASSWD: ALL") + (filter hasMaster (attrValues extraUsers))); + +in + + +{ + imports = [ + { users.extraUsers = import <secrets/extraUsers.nix>; } + ]; + + users.defaultUserShell = "/run/current-system/sw/bin/bash"; + users.extraGroups = extraGroups; + users.extraUsers = extraUsers; + users.mutableUsers = false; + + security.sudo.extraConfig = + '' + Defaults mailto="tv@wu.retiolum" + ${sudoers} + ''; +} diff --git a/old/pubkeys/deploy_wu.ssh.pub b/old/pubkeys/deploy_wu.ssh.pub new file mode 100644 index 000000000..a54a1ca37 --- /dev/null +++ b/old/pubkeys/deploy_wu.ssh.pub @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEieAihh+o208aeCA14fAtjzyZN/nrpOJt2vZ5VYZp69 deploy@wu diff --git a/old/pubkeys/lass.ssh.pub b/old/pubkeys/lass.ssh.pub new file mode 100644 index 000000000..172fd2dda --- /dev/null +++ b/old/pubkeys/lass.ssh.pub @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAp83zynhIueJJsWlSEykVSBrrgBFKq38+vT8bRfa+csqyjZBl2SQFuCPo+Qbh49mwchpZRshBa9jQEIGqmXxv/PYdfBFQuOFgyUq9ZcTZUXqeynicg/SyOYFW86iiqYralIAkuGPfQ4howLPVyjTZtWeEeeEttom6p6LMY5Aumjz2em0FG0n9rRFY2fBzrdYAgk9C0N6ojCs/Gzknk9SGntA96MDqHJ1HXWFMfmwOLCnxtE5TY30MqSmkrJb7Fsejwjoqoe9Y/mCaR0LpG2cStC1+37GbHJNH0caCMaQCX8qdfgMVbWTVeFWtV6aWOaRgwLrPDYn4cHWQJqTfhtPrNQ== lass@mors diff --git a/old/pubkeys/makefu.ssh.pub b/old/pubkeys/makefu.ssh.pub new file mode 100644 index 000000000..6092ec469 --- /dev/null +++ b/old/pubkeys/makefu.ssh.pub @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCl3RTOHd5DLiVeUbUr/GSiKoRWknXQnbkIf+uNiFO+XxiqZVojPlumQUVhasY8UzDzj9tSDruUKXpjut50FhIO5UFAgsBeMJyoZbgY/+R+QKU00Q19+IiUtxeFol/9dCO+F4o937MC0OpAC10LbOXN/9SYIXueYk3pJxIycXwUqhYmyEqtDdVh9Rx32LBVqlBoXRHpNGPLiswV2qNe0b5p919IGcslzf1XoUzfE3a3yjk/XbWh/59xnl4V7Oe7+iQheFxOT6rFA30WYwEygs5As//ZYtxvnn0gA02gOnXJsNjOW9irlxOUeP7IOU6Ye3WRKFRR0+7PS+w8IJLag2xb makefu@pornocauster diff --git a/old/pubkeys/mv_vod.ssh.pub b/old/pubkeys/mv_vod.ssh.pub new file mode 100644 index 000000000..7b7d2e260 --- /dev/null +++ b/old/pubkeys/mv_vod.ssh.pub @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGer9e2+Lew7vnisgBbsFNECEIkpNJgEaqQqgb9inWkQ mv@vod diff --git a/old/pubkeys/tv_wu.ssh.pub b/old/pubkeys/tv_wu.ssh.pub new file mode 100644 index 000000000..b6e2634e8 --- /dev/null +++ b/old/pubkeys/tv_wu.ssh.pub @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAEAQDFR//RnCvEZAt0F6ExDsatKZ/DDdifanuSL360mqOhaFieKI34RoOwfQT9T+Ga52Vh5V2La6esvlph686EdgzeKLvDoxEwFM9ZYFBcMrNzu4bMTlgE7YUYw5JiORyXNfznBGnme6qpuvx9ibYhUyiZo99kM8ys5YrUHrP2JXQJMezDFZHxT4GFMOuSdh/1daGoKKD6hYL/jEHX8CI4E3BSmKK6ygYr1fVX0K0Tv77lIi5mLXucjR7CytWYWYnhM6DC3Hxpv2zRkPgf3k0x/Y1hrw3V/r0Me5h90pd2C8pFaWA2ZoUT/fmyVqvx1tZPYToU/O2dMItY0zgx2kR0yD+6g7Aahz3R+KlXkV8k5c8bbTbfGnZWDR1ZlbLRM9Yt5vosfwapUD90MmVkpmR3wUkO2sUKi80QfC7b4KvSDXQ+MImbGxMaU5Bnsq1PqLN95q+uat3nlAVBAELkcx51FlE9CaIS65y4J7FEDg8BE5JeuCNshh62VSYRXVSFt8bk3f/TFGgzC8OIo14BhVmiRQQ503Z1sROyf5xLX2a/EJavMm1i2Bs2TH6ROKY9z5Pz8hT5US0r381V8oG7TZyLF9HTtoy3wCYsgWA5EmLanjAsVU2YEeAA0rxzdtYP8Y2okFiJ6u+M4HQZ3Wg3peSodyp3vxdYce2vk4EKeqEFuuS82850DYb7Et7fmp+wQQUT8Q/bMO0DreWjHoMM5lE4LJ4ME6AxksmMiFtfo/4Fe2q9D+LAqZ+ANOcv9M+8Rn6ngiYmuRNd0l/a02q1PEvO6vTfXgcl4f7Z1IULHPEaDNZHCJS1K5RXYFqYQ6OHsTmOm7hnwaRAS97+VFMo1i5uvTx9nYaAcY7yzq3Ckfb67dMBKApGOpJpkvPgfrP7bgBO5rOZXM1opXqVPb09nljAhhAhyCTh1e/8+mJrBo0cLQ/LupQzVxGDgm3awSMPxsZAN45PSWz76zzxdDa1MMo51do+VJHfs7Wl0NcXAQrniOBYL9Wqt0qNkn1gY5smkkISGeQ/vxNap4MmzeZE7b5fpOy+2fpcRVQLpc4nooQzJvSVTFz+25lgZ6iHf45K87gQFMIAri1Pf/EDDpL87az+bRWvWi+BA2kMe1kf+Ay1LyMz8r+g51H0ma0bNFh6+fbWMfUiD9JCepIObclnUJ4NlWfcgHxTf17d/4tl6z4DTcLpCCk8Da77JouSHgvtcRbRlFV1OfhWZLXUsrlfpaQTiItv6TGIr3k7+7b66o3Qw/GQVs5GmYifaIZIz8n8my4XjkaMBd0SZfBzzvFjHMq6YUP9+SbjvReqofuoO+5tW1wTYZXitFFBfwuHlXm6w77K5QDBW6olT7pat41/F5eGxLcz tv@wu diff --git a/old/pubkeys/uriel.ssh.pub b/old/pubkeys/uriel.ssh.pub new file mode 100644 index 000000000..015b57837 --- /dev/null +++ b/old/pubkeys/uriel.ssh.pub @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDExWuRcltGM2FqXO695nm6/QY3wU3r1bDTyCpMrLfUSym7TxcXDSmZSWcueexPXV6GENuUfjJPZswOdWqIo5u2AXw9t0aGvwEDmI6uJ7K5nzQOsXIneGMdYuoOaAzWI8pxZ4N+lIP1HsOYttIPDp8RwU6kyG+Ud8mnVHWSTO13C7xC9vePnDP6b+44nHS691Zj3X/Cq35Ls0ISC3EM17jreucdP62L3TKk2R4NCm3Sjqj+OYEv0LAqIpgqSw5FypTYQgNByxRcIcNDlri63Q1yVftUP1338UiUfxtraUu6cqa2CdsHQmtX5mTNWEluVWO3uUKTz9zla3rShC+d3qvr lass@uriel |