From 30721cfa83acbec6865bbe50bccec3cdc74de65a Mon Sep 17 00:00:00 2001 From: Ingolf Wagner Date: Tue, 28 Dec 2021 16:19:29 +0100 Subject: [PATCH] minimal robi setup --- flake.lock | 2 +- nixos/assets/tinc/robi_host_file | 14 + nixos/configs/pepe/tinc.nix | 2 +- nixos/configs/robi/borg.nix | 30 + nixos/configs/robi/castget.nix | 22 + nixos/configs/robi/configuration.nix | 54 ++ nixos/configs/robi/finance.nix | 58 ++ nixos/configs/robi/gogs.nix | 122 ++++ nixos/configs/robi/grafana.nix | 38 + nixos/configs/robi/graylog.nix | 130 ++++ nixos/configs/robi/hardware-configuration.nix | 38 + nixos/configs/robi/hetzner.nix | 121 ++++ nixos/configs/robi/jenkins.nix | 203 ++++++ nixos/configs/robi/jupyter.nix | 71 ++ nixos/configs/robi/kibana.nix | 25 + nixos/configs/robi/mail-fetcher.nix | 661 ++++++++++++++++++ nixos/configs/robi/metabase.nix | 24 + nixos/configs/robi/mining.nix | 52 ++ nixos/configs/robi/mysql.nix | 20 + nixos/configs/robi/nextcloud.nix | 198 ++++++ nixos/configs/robi/packages.nix | 5 + nixos/configs/robi/prometheus.nix | 106 +++ nixos/configs/robi/property.nix | 43 ++ nixos/configs/robi/syncthing.nix | 140 ++++ nixos/configs/robi/taskserver.nix | 16 + nixos/configs/robi/tinc.nix | 14 + nixos/configs/robi/transmission.nix | 285 ++++++++ nixos/configs/robi/weechat.nix | 38 + nixos/configs/sterni/tinc.nix | 2 +- nixos/configs/workhorse/configuration.nix | 4 +- nixos/flake.nix | 1 + nixos/krops.nix | 4 + nixos/system/all/default.nix | 47 +- nixos/system/all/defaults.nix | 48 ++ nixos/system/all/hosts.nix | 1 + nixos/system/all/sshd-known-hosts-private.nix | 16 +- nixos/system/all/tinc.nix | 8 +- nixos/system/desktop/wtf.nix | 2 +- 38 files changed, 2607 insertions(+), 58 deletions(-) create mode 100644 nixos/assets/tinc/robi_host_file create mode 100644 nixos/configs/robi/borg.nix create mode 100644 nixos/configs/robi/castget.nix create mode 100644 nixos/configs/robi/configuration.nix create mode 100644 nixos/configs/robi/finance.nix create mode 100644 nixos/configs/robi/gogs.nix create mode 100644 nixos/configs/robi/grafana.nix create mode 100644 nixos/configs/robi/graylog.nix create mode 100644 nixos/configs/robi/hardware-configuration.nix create mode 100644 nixos/configs/robi/hetzner.nix create mode 100644 nixos/configs/robi/jenkins.nix create mode 100644 nixos/configs/robi/jupyter.nix create mode 100644 nixos/configs/robi/kibana.nix create mode 100644 nixos/configs/robi/mail-fetcher.nix create mode 100644 nixos/configs/robi/metabase.nix create mode 100644 nixos/configs/robi/mining.nix create mode 100644 nixos/configs/robi/mysql.nix create mode 100644 nixos/configs/robi/nextcloud.nix create mode 100644 nixos/configs/robi/packages.nix create mode 100644 nixos/configs/robi/prometheus.nix create mode 100644 nixos/configs/robi/property.nix create mode 100644 nixos/configs/robi/syncthing.nix create mode 100644 nixos/configs/robi/taskserver.nix create mode 100644 nixos/configs/robi/tinc.nix create mode 100644 nixos/configs/robi/transmission.nix create mode 100644 nixos/configs/robi/weechat.nix create mode 100644 nixos/system/all/defaults.nix diff --git a/flake.lock b/flake.lock index a299d6f..d23ad78 100644 --- a/flake.lock +++ b/flake.lock @@ -62,7 +62,7 @@ "secrets": { "flake": false, "locked": { - "narHash": "sha256-+B8N8FSgrQh1AQcNKaLud+iaJCzmwsvxpp47GLMTCgM=", + "narHash": "sha256-9cKMk8P56Jy5X1Hk5gpisJAHZCAYuwiUNfs2diRWdws=", "path": "/home/palo/dev/secrets", "type": "path" }, diff --git a/nixos/assets/tinc/robi_host_file b/nixos/assets/tinc/robi_host_file new file mode 100644 index 0000000..b5ea6ab --- /dev/null +++ b/nixos/assets/tinc/robi_host_file @@ -0,0 +1,14 @@ +Ed25519PublicKey = bZUbSdME4fwudNVbUoNO7PpoOS2xALsyTs81F260KbL +-----BEGIN RSA PUBLIC KEY----- +MIICCgKCAgEA1wwdd6+Qgn7fiC5C5ueeAsgfG6LlP+5zfb2r8/RZzFkKK+wX0QRx +6i3Dm0SwAvkKYKowEHhpDg941CrkuTGN2wnKvxoUNvaAe+RBK2EZM3xPh0eTP33T +igNEHAcdHlgwd3aaNRmYxC41uUlAjD8JPkQ14yAvi4ZMeDRGQxw3on7Mx8NBwgDp +V2F45c9WpYzaocPCREQE7xLpY3prYpOljqd3hGnBQjdruxnAtIh7nb1SSlMci4RT +Y2d6aOCiDKgtqrPtMSWp0RkuhIlT17AK1b/5+TE4vzcFNkt6xQJnH2rm7D9niXZ2 ++yzl5DsVONk4z29MnEInqzcVY8m6iypjjntBTkHtFWJc4ZMnJC9FBt7il4V2NL+/ +T7uHV1KDFwRZOtfd0WWlgpg3HsZLc+pmZNl77bggcc56+t3FC5UPZKMEEmU7TYtp +jIPYnOV9C7ReaOpYvHJi/6NrtYUjBd2XbtD959cTFR9PpXMaNWh2R8+K7r/tFZrG +q252aCc51J+JegfnhtTfOfPPn7BHV+ZsSQBjMrxz29igOlMPnyOvaxB4mxf6ipoX +HDY7QnQ82HTZCGQ3vPVEgNz0MfsZU0VocazOYOh3RpKBbKaYqo1i8PqKpqfjC7aR +AdbrqBXGFcBbXkna3BQDS4xmK35sUG08OR1g24uiNFKzy8rK+xcp790CAwEAAQ== +-----END RSA PUBLIC KEY----- diff --git a/nixos/configs/pepe/tinc.nix b/nixos/configs/pepe/tinc.nix index 9d8c56c..6563e05 100644 --- a/nixos/configs/pepe/tinc.nix +++ b/nixos/configs/pepe/tinc.nix @@ -7,7 +7,7 @@ with lib; "private" = { enable = true; openPort = true; - connectTo = [ "sputnik" ]; + connectTo = [ "sputnik" "robi" ]; }; "retiolum" = { enable = true; diff --git a/nixos/configs/robi/borg.nix b/nixos/configs/robi/borg.nix new file mode 100644 index 0000000..7e5bda0 --- /dev/null +++ b/nixos/configs/robi/borg.nix @@ -0,0 +1,30 @@ +{ lib, config, pkgs, ... }: { + + services.borgbackup.repos = { + default = { + quota = "100G"; + allowSubRepos = true; + authorizedKeys = [ + (lib.fileContents ../../assets/ssh/borg_access.pub) + (lib.fileContents ../../assets/ssh/card_rsa.pub) + ]; + }; + }; + + # mirror backup folder to /media + systemd.services.borg-mirror-to-media = { + enable = true; + script = '' + ${pkgs.rsync}/bin/rsync -a \ + /var/lib/borgbackup/ \ + /media/borg-backup-mirror \ + --delete-after + ''; + }; + systemd.timers.borg-mirror-to-media = { + enable = true; + timerConfig.OnCalendar = "daily"; + wantedBy = [ "multi-user.target" ]; + }; + +} diff --git a/nixos/configs/robi/castget.nix b/nixos/configs/robi/castget.nix new file mode 100644 index 0000000..0742dad --- /dev/null +++ b/nixos/configs/robi/castget.nix @@ -0,0 +1,22 @@ +{ config, lib, ... }: +let + + home = "/home/syncthing/podcasts"; + +in +{ + custom.services.castget = { + enable = true; + user = "root"; + feeds = { + Alternativlos = { + url = "https://alternativlos.org/alternativlos.rss"; + spool = "${home}/alternativlos"; + }; + gegenstandpunkt = { + url = "https://pc.argudiss.de/"; + spool = "${home}/GegenStandpunkt"; + }; + }; + }; +} diff --git a/nixos/configs/robi/configuration.nix b/nixos/configs/robi/configuration.nix new file mode 100644 index 0000000..24e7e5b --- /dev/null +++ b/nixos/configs/robi/configuration.nix @@ -0,0 +1,54 @@ +{ lib, config, pkgs, ... }: { + imports = [ + + ../../system/all/defaults.nix + ../../system/all/tinc.nix + + ./hetzner.nix + + #./nextcloud.nix + + ./packages.nix + ./tinc.nix + + #./syncthing.nix + #../../system/server + #./hardware-configuration.nix + #./mail-fetcher.nix + #./transmission.nix + #./borg.nix + #./finance.nix + #./gogs.nix + #./grafana.nix + #./graylog.nix + #./jenkins.nix + #./kibana.nix + #./mysql.nix + #./prometheus.nix + #./taskserver.nix + #./weechat.nix + #./property.nix # flask sucks, find something else + + ]; + + security.acme = { + acceptTerms = true; + email = "contact@ingolf-wagner.de"; + }; + + sops.defaultSopsFile = ../../secrets/robi.yaml; + virtualisation.docker.enable = false; + services.printing.enable = false; + services.smartd.enable = true; + + + fileSystems."/var/lib/nextcloud" = + { + device = "/dev/vg/nextcloud"; + fsType = "ext4"; + }; + + + +} + diff --git a/nixos/configs/robi/finance.nix b/nixos/configs/robi/finance.nix new file mode 100644 index 0000000..76de251 --- /dev/null +++ b/nixos/configs/robi/finance.nix @@ -0,0 +1,58 @@ +{ lib, config, pkgs, ... }: +let + + # find symbols with + # https://www.alphavantage.co/query?function=SYMBOL_SEARCH&apikey=&keywords= + # as described here : https://www.alphavantage.co/documentation/#symbolsearch + # + # example: + # -------- + # stocks = [ + # { + # friendly_name = "google"; + # symbol = "GOOGL.DEX"; + # name = "google"; + # currency = "$"; + # } + # ]; + # results in + # P 2020-01-30 GOOGL $123 + stocks = import ../../private_assets/finance/stocks; + stocksFile = toString /home/syncthing/finance/hledger/stocks.journal; + +in +{ + + systemd.services.pull_stocks = { + enable = true; + description = "pull stocks for hledger"; + serviceConfig = { + User = "syncthing"; + Type = "oneshot"; + }; + + script = + let + command = { symbol, name, currency, ... }: '' + APIKEY=${lib.fileContents ../../private_assets/finance/alphavantage/apiKey} + SYMBOL="${symbol}" + ${pkgs.curl}/bin/curl --location --silent \ + "https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol=$SYMBOL&apikey=$APIKEY" \ + | ${pkgs.jq}/bin/jq --raw-output '.["Global Quote"] + | "P \(.["07. latest trading day"]) ${name} ${currency}\(.["05. price"] | tonumber)"' \ + >> ${stocksFile} + sleep 1 + ''; + in + lib.concatStringsSep "\n" (map command stocks); + }; + + systemd.timers.pull_stocks = { + enable = true; + wantedBy = [ "multi-user.target" ]; + timerConfig = { + OnCalendar = "weekly"; + Persistent = "true"; + }; + }; +} diff --git a/nixos/configs/robi/gogs.nix b/nixos/configs/robi/gogs.nix new file mode 100644 index 0000000..258ceea --- /dev/null +++ b/nixos/configs/robi/gogs.nix @@ -0,0 +1,122 @@ +{ config, lib, pkgs, ... }: +let + + errorPages = pkgs.fetchgit { + url = "https://git.ingolf-wagner.de/palo/http-errors.git"; + rev = "74b8e4c1d9bbba3db6ad858b888e1867318af1f0"; + sha256 = "0czdzafx4k76q773lyf3vsjm74g1995iz542dhw15kpy5xbivsrg"; + }; + + error = { + extraConfig = '' + error_page 400 /errors/400.html; + error_page 401 /errors/401.html; + error_page 402 /errors/402.html; + error_page 403 /errors/403.html; + error_page 404 /errors/404.html; + error_page 405 /errors/405.html; + error_page 406 /errors/406.html; + error_page 500 /errors/500.html; + error_page 501 /errors/501.html; + error_page 502 /errors/502.html; + error_page 503 /errors/503.html; + error_page 504 /errors/504.html; + ''; + locations."^~ /errors/" = { + extraConfig = "internal;"; + root = "${errorPages}/"; + }; + }; + +in +{ + + services.nginx = { + enable = true; + statusPage = true; + virtualHosts = { + "git.${config.networking.hostName}.private" = { + extraConfig = error.extraConfig; + locations."/" = { + proxyPass = "http://${config.networking.hostName}.private:${ + toString config.services.gogs.httpPort + }"; + }; + }; + }; + }; + + services.gogs = { + enable = true; + appName = "Kruck GoGs"; + domain = "git.ingolf-wagner.de"; + httpPort = 3000; + repositoryRoot = "/home/gogs/repositories"; + stateDir = "/home/gogs"; + rootUrl = "https://git.ingolf-wagner.de/"; + extraConfig = '' + [service] + DISABLE_REGISTRATION = true + SHOW_REGISTRATION_BUTTON = false + [server] + SSH_DOMAIN = "git.ingolf-wagner.de" + SSH_PORT = 2222 + START_SSH_SERVER = true + SSH_LISTEN_PORT = 2222 + + [log.file] + LEVEL = Warn + + [log.console] + LEVEL = Warn + + [log.sublogger.macaron] + LEVEL = Warn + ''; + }; + backup.dirs = [ config.services.gogs.repositoryRoot ]; + + # services.nginx = { + # enable = true; + # statusPage = true; + # virtualHosts = { + # "gitlab.${config.networking.hostName}.private" = { + # extraConfig = error.extraConfig; + # locations."/" = { + # proxyPass = "http://${config.networking.hostName}.private:${ + # toString config.services.gitlab.port + # }"; + # }; + # }; + # }; + # }; + # services.gitlab = { + # enable = true; + # host = "gitlab.${config.networking.hostname}.private"; + # port = 9897; + # #databasePasswordFile = "path/todo"; + # #initialRootPasswordFile = "path/todo"; + # + # secrets = { + # # Make sure the secret is at least 30 characters and all random, + # # no regular words or you'll be exposed to dictionary attacks + # dbFile = "path/todo"; + # + # # openssl genrsa 2048 + # jwsFile = "path/todo"; + # + # # Make sure the secret is at least 30 characters and all random, + # # no regular words or you'll be exposed to dictionary attacks + # otpFile = "path/todo"; + # + # # Make sure the secret is at least 30 characters and all random, + # # no regular words or you'll be exposed to dictionary attacks + # secretFile = "path/todo"; + # }; + # + # # smtp? + # + # # gitlab-runner? + # }; + +} diff --git a/nixos/configs/robi/grafana.nix b/nixos/configs/robi/grafana.nix new file mode 100644 index 0000000..c9c6390 --- /dev/null +++ b/nixos/configs/robi/grafana.nix @@ -0,0 +1,38 @@ +{ config, ... }: { + services.nginx = { + enable = true; + statusPage = true; + virtualHosts = { + "grafana.${config.networking.hostName}.private" = { + serverAliases = [ ]; + locations."/" = { + proxyPass = "http://${config.networking.hostName}.private:${ + toString config.services.grafana.port + }"; + }; + }; + }; + }; + + services.grafana = { + enable = true; + port = 5656; + addr = + config.module.cluster.services.tinc."private".hosts."${config.networking.hostName}".tincIp; + auth.anonymous = { + enable = true; + org_role = "Editor"; + org_name = "AWESOME"; + }; + provision = { + enable = true; + datasources = [{ + type = "prometheus"; + isDefault = true; + name = "Prometheus Workhorse"; + url = "http://workhorse.private:9090"; + }]; + }; + }; + +} diff --git a/nixos/configs/robi/graylog.nix b/nixos/configs/robi/graylog.nix new file mode 100644 index 0000000..8a31746 --- /dev/null +++ b/nixos/configs/robi/graylog.nix @@ -0,0 +1,130 @@ +{ config, lib, pkgs, ... }: +let port = 9000; +in { + # configure nginx + services.nginx = { + enable = true; + virtualHosts = { + "graylog.workhorse.private" = { + locations."/" = { + proxyPass = "http://localhost:${toString port}"; + extraConfig = '' + proxy_set_header Host $host:$server_port; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_read_timeout 90; + proxy_redirect http://localhost:${ + toString port + } https://graylog.workhorse.private/; + ''; + }; + }; + }; + }; + + services.mongodb.enable = true; + services.elasticsearch = { + enable = true; + listenAddress = "${config.networking.hostName}.private"; + extraJavaOptions = [ "-Des.http.cname_in_publish_address=true" ]; + }; + + services.graylog.enable = true; + services.graylog.elasticsearchHosts = + [ "http://${config.services.elasticsearch.listenAddress}:9200" ]; + + # https://docs.graylog.org/en/3.0/pages/configuration/server.conf.html + services.graylog.extraConfig = '' + http_bind_address = 0.0.0.0:${toString port} + http_publish_uri = http://workhorse.private:${toString port}/ + ''; + + # other wise this does not work + services.graylog.nodeIdFile = "/var/lib/graylog/node-id"; + + # pwgen -N 1 -s 96 + services.graylog.passwordSecret = + lib.fileContents ../../private_assets/graylog/password-secret; + + # echo -n yourpassword | shasum -a 256 + services.graylog.rootPasswordSha2 = + lib.fileContents ../../private_assets/graylog/root-password-hash; + + services.graylog.plugins = [ pkgs.graylogPlugins.slack ]; + + # not working at the moment + #services.geoip-updater.enable = true; + + # https://wiki.splunk.com/Http_status.csv + environment.etc."graylog/server/httpCodes.csv" = { + enable = true; + text = '' + status,status_description,status_type + 100,Continue,Informational + 101,Switching Protocols,Informational + 200,OK,Successful + 201,Created,Successful + 202,Accepted,Successful + 203,Non-Authoritative Information,Successful + 204,No Content,Successful + 205,Reset Content,Successful + 206,Partial Content,Successful + 300,Multiple Choices,Redirection + 301,Moved Permanently,Redirection + 302,Found,Redirection + 303,See Other,Redirection + 304,Not Modified,Redirection + 305,Use Proxy,Redirection + 307,Temporary Redirect,Redirection + 400,Bad Request,Client Error + 401,Unauthorized,Client Error + 402,Payment Required,Client Error + 403,Forbidden,Client Error + 404,Not Found,Client Error + 405,Method Not Allowed,Client Error + 406,Not Acceptable,Client Error + 407,Proxy Authentication Required,Client Error + 408,Request Timeout,Client Error + 409,Conflict,Client Error + 410,Gone,Client Error + 411,Length Required,Client Error + 412,Precondition Failed,Client Error + 413,Request Entity Too Large,Client Error + 414,Request-URI Too Long,Client Error + 415,Unsupported Media Type,Client Error + 416,Requested Range Not Satisfiable,Client Error + 417,Expectation Failed,Client Error + 500,Internal Server Error,Server Error + 501,Not Implemented,Server Error + 502,Bad Gateway,Server Error + 503,Service Unavailable,Server Error + 504,Gateway Timeout,Server Error + 505,HTTP Version Not Supported,Server Error + ''; + }; + + environment.etc."graylog/server/known_servers.csv" = { + enable = true; + text = '' + "ip","host_name" + "95.216.1.150","lassul.us" + ''; + }; + + environment.etc."graylog/systemd/loglevel.csv" = { + enable = true; + text = '' + "value","Servity","Description" + "0","emergency","System is unusable" + "1","alert","Should be corrected immediately" + "2","cirtical","Critical conditions" + "3","error","Error Condition" + "4","warning","May indicate that an error will occur if action is not taken." + "5","notice","Events that are unusual, but not error conditions." + "6","info","Normal operational messages that require no action." + "7","debug","Information useful to developers for debugging the application." + ''; + }; + +} diff --git a/nixos/configs/robi/hardware-configuration.nix b/nixos/configs/robi/hardware-configuration.nix new file mode 100644 index 0000000..31cbc51 --- /dev/null +++ b/nixos/configs/robi/hardware-configuration.nix @@ -0,0 +1,38 @@ +# Do not modify this file! It was generated by ‘nixos-generate-config’ +# and may be overwritten by future invocations. Please make changes +# to /etc/nixos/configuration.nix instead. +{ config, lib, pkgs, modulesPath, ... }: + +{ + imports = + [ + (modulesPath + "/installer/scan/not-detected.nix") + ]; + + boot.initrd.availableKernelModules = [ "ahci" "sd_mod" ]; + boot.initrd.kernelModules = [ "dm-snapshot" ]; + boot.kernelModules = [ "kvm-intel" ]; + boot.extraModulePackages = [ ]; + + fileSystems."/" = + { + device = "/dev/disk/by-uuid/d6a794d2-1da4-4457-9a9a-a39bf9521ae4"; + fsType = "ext4"; + }; + + fileSystems."/boot-1" = + { + device = "/dev/disk/by-uuid/519D-F289"; + fsType = "vfat"; + }; + + fileSystems."/boot-2" = + { + device = "/dev/disk/by-uuid/519E-6EF1"; + fsType = "vfat"; + }; + + swapDevices = [ ]; + + powerManagement.cpuFreqGovernor = lib.mkDefault "ondemand"; +} diff --git a/nixos/configs/robi/hetzner.nix b/nixos/configs/robi/hetzner.nix new file mode 100644 index 0000000..6c15294 --- /dev/null +++ b/nixos/configs/robi/hetzner.nix @@ -0,0 +1,121 @@ +{ config, pkgs, modulesPath, lib, ... }: + +let + + hostName = "robi"; + + # apt install -y lshw + # lshw -C network | grep -Poh 'driver=[[:alnum:]]+' + + networkInterfaceModule = "r8169"; + + networkInterface = "enp3s0"; + + # From the Hetzner control panel + ipv4 = { + address = "144.76.13.147"; # the ip address + gateway = "144.76.13.129"; # the gateway ip address + netmask = "255.255.255.224"; # the netmask -- might not be the same for you! + prefixLength = 27; # must match the netmask, see + }; + ipv6 = { + address = "2a01:4f8:190:9147::1"; # the ipv6 addres + gateway = "fe80::1"; # the ipv6 gateway + prefixLength = 64; # shown in the control panel + }; + +in + +{ + imports = + [ + # Include the results of the hardware scan. + ./hardware-configuration.nix + ]; + + # needed lvm for raid + boot.initrd.kernelModules = [ + "dm-snapshot" + "dm_mirror" + "dm_raid" + "dm_region_hash" + ]; + + # Use GRUB2 as the boot loader. + # We don't use systemd-boot because Hetzner uses BIOS legacy boot. + boot.loader.systemd-boot.enable = false; + boot.loader.grub = { + enable = true; + efiSupport = false; + version = 2; + }; + + # This will mirror all UEFI files, kernels, grub menus and + # things needed to boot to the other drive. + boot.loader.grub.mirroredBoots = [ + { path = "/boot-1"; devices = [ "/dev/sda" ]; } + { path = "/boot-2"; devices = [ "/dev/sdb" ]; } + ]; + + # We want to still be able to boot without one of these + fileSystems."/boot-1".options = [ "nofail" ]; + fileSystems."/boot-2".options = [ "nofail" ]; + + boot.initrd.luks.reusePassphrases = true; + boot.initrd.luks.devices = { + a_encrypted = { + device = "/dev/sda3"; + preLVM = true; + }; + b_encrypted = { + device = "/dev/sdb3"; + preLVM = true; + }; + }; + + networking.hostName = hostName; + + # Network configuration (Hetzner uses static IP assignments, and we don't use DHCP here) + networking.useDHCP = false; + networking.interfaces.${networkInterface} = { + ipv4 = { addresses = [{ address = ipv4.address; prefixLength = ipv4.prefixLength; }]; }; + ipv6 = { addresses = [{ address = ipv6.address; prefixLength = ipv6.prefixLength; }]; }; + }; + networking.defaultGateway = ipv4.gateway; + networking.defaultGateway6 = { address = ipv6.gateway; interface = networkInterface; }; + networking.nameservers = [ "8.8.8.8" ]; + + # Initial empty root password for easy login: + users.users.root.initialHashedPassword = ""; + services.openssh.permitRootLogin = "prohibit-password"; + + users.users.root.openssh.authorizedKeys.keys = [ + "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC6uza62+Go9sBFs3XZE2OkugBv9PJ7Yv8ebCskE5WYPcahMZIKkQw+zkGI8EGzOPJhQEv2xk+XBf2VOzj0Fto4nh8X5+Llb1nM+YxQPk1SVlwbNAlhh24L1w2vKtBtMy277MF4EP+caGceYP6gki5+DzlPUSdFSAEFFWgN1WPkiyUii15Xi3QuCMR8F18dbwVUYbT11vwNhdiAXWphrQG+yPguALBGR+21JM6fffOln3BhoDUp2poVc5Qe2EBuUbRUV3/fOU4HwWVKZ7KCFvLZBSVFutXCj5HuNWJ5T3RuuxJSmY5lYuFZx9gD+n+DAEJt30iXWcaJlmUqQB5awcB1S2d9pJ141V4vjiCMKUJHIdspFrI23rFNYD9k2ZXDA8VOnQE33BzmgF9xOVh6qr4G0oEpsNqJoKybVTUeSyl4+ifzdQANouvySgLJV/pcqaxX1srSDIUlcM2vDMWAs3ryCa0aAlmAVZIHgRhh6wa+IXW8gIYt+5biPWUuihJ4zGBEwkyVXXf2xsecMWCAGPWPDL0/fBfY9krNfC5M2sqxey2ShFIq+R/wMdaI7yVjUCF2QIUNiIdFbJL6bDrDyHnEXJJN+rAo23jUoTZZRv7Jq3DB/A5H7a73VCcblZyUmwMSlpg3wos7pdw5Ctta3zQPoxoAKGS1uZ+yTeZbPMmdbw==" + ]; + + services.openssh.enable = true; + + system.stateVersion = "21.05"; + + # enable ssh on init + # ------------------ + + boot.kernelParams = [ + # See for docs on this + # ip=::::::::: + # The server ip refers to the NFS server -- we don't need it. + "ip=${ipv4.address}::${ipv4.gateway}:${ipv4.netmask}:${hostName}-initrd:${networkInterface}:off:8.8.8.8" + ]; + boot.initrd.availableKernelModules = [ networkInterfaceModule ]; + boot.initrd.network.enable = true; + boot.initrd.network.ssh = { + enable = true; + authorizedKeys = config.users.users.root.openssh.authorizedKeys.keys; + port = 2222; + hostKeys = [ + /etc/secrets/initrd/ssh_host_rsa_key + /etc/secrets/initrd/ssh_host_ed25519_key + ]; + }; + +} diff --git a/nixos/configs/robi/jenkins.nix b/nixos/configs/robi/jenkins.nix new file mode 100644 index 0000000..1f277d6 --- /dev/null +++ b/nixos/configs/robi/jenkins.nix @@ -0,0 +1,203 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + library = import ../../library { inherit pkgs lib; }; + + sync-repo = library.jenkins.syncJob; + job = library.jenkins.job; + +in +{ + + environment.systemPackages = [ pkgs.cabal-install ]; + + services.nginx = { + enable = true; + virtualHosts = { + "jenkins.${config.networking.hostName}.private" = { + locations."/" = { + proxyPass = + "http://localhost:${toString config.services.jenkins.port}"; + extraConfig = '' + proxy_set_header Host $host:$server_port; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + proxy_read_timeout 90; + proxy_redirect http://localhost:${ + toString config.services.jenkins.port + } https://jenkins.${config.networking.hostName}.private/; + ''; + }; + }; + }; + }; + + sops.secrets.jenkins_token = { + owner = "jenkins"; + }; + + services.jenkins = { + enable = true; + home = "/home/jenkins"; + port = 10420; + + # Plugins to Install: + # - all the plugins recommended at the setup + # - Build pipeline + # - SSH Agent + # - mattermost plugin + jobBuilder = { + enable = true; + # create an access token in the admin users panel + accessTokenFile = config.sops.secrets.jenkins_token.path; + accessUser = "admin"; + + # https://docs.openstack.org/infra/jenkins-job-builder/definition.html#modules + nixJobs = + let + # ssh username + key + gogs-id = "bc584c99-0fb7-43fb-af75-4076d64c51b2"; + # ssh username + key + github-id = "bc584c99-0fb7-43fb-af75-4076d64c51b2"; + # ssh username + key + sshSputnik = "d91eb57c-5bff-434c-b317-68aad46848d7"; + + sync-to-github = name: source: target: + sync-repo name + { + url = source; + credentialsId = gogs-id; + } + { + url = target; + credentialsId = github-id; + }; + + in + [ + + (job "sync-retiolum" + { + url = "git@github.com:krebs/retiolum.git"; + credentialsId = github-id; + triggers = [{ timed = "H/30 * * * *"; }]; + } [ + { + "Download Files" = [ + "chmod 755 hosts" + "chmod 755 -R hosts" + '' + nix-shell -p curl -p gnutar -p bzip2 --run "curl https://lassul.us/retiolum-hosts.tar.bz2 | tar xvjf - || true"'' + "chmod 755 -R etc.hosts" + '' + nix-shell -p curl --run "curl https://lassul.us/retiolum.hosts > etc.hosts || true"'' + ]; + } + { + "update repo" = [ + ''nix-shell -p git --run "git add ."'' + '' + nix-shell -p git --run "git -c user.name=\'Ingolf Wagner\' -c user.email=\'contact@ingolf-wagner.de\' commit -m update-`date +%Y-%m-%dT%H:%M:%S` || exit 0"'' + ]; + } + { + Push = [{ + script = ''nix-shell -p git --run "git push origin master"''; + credentialsId = github-id; + }]; + } + ]) + + (job "test-taskninja" + { + url = "ssh://gogs@workhorse.private:2222/palo/taskninja.git"; + credentialsId = gogs-id; + } [ + { + "Create Shell" = [ + '' + nix-shell -p cabal2nix --run "cabal2nix --shell file://. > jenkins.nix"'' + ]; + } + { Update = [ ''nix-shell ./jenkins.nix --run "cabal update"'' ]; } + { + Configure = [ + ''nix-shell ./jenkins.nix --run "cabal configure --enable-tests"'' + '' + nix-shell ./jenkins.nix --run "cabal install --only-dependencies"'' + ]; + } + { Build = [ ''nix-shell ./jenkins.nix --run "cabal build"'' ]; } + { Test = [ ''nix-shell ./jenkins.nix --run "cabal test"'' ]; } + ]) + + # sync to github + # -------------- + (sync-to-github "sync-radiodj" + "ssh://gogs@workhorse.private:2222/crashburn_radio/radio-dj2.git" + "git@github.com:crashburn-radio/radio-dj.git") + (sync-to-github "sync-radiodj-tracks" + "ssh://gogs@workhorse.private:2222/crashburn_radio/radio-dj-tracks.git" + "git@github.com:crashburn-radio/radio-dj-tracks.git") + + (sync-to-github "sync-krops-module" + "ssh://gogs@workhorse.private:2222/nix-modules/krops.git" + "git@github.com:mrVanDalo/module.krops.git") + + (sync-to-github "sync-cluster-module" + "ssh://gogs@workhorse.private:2222/nix-modules/cluster.git" + "git@github.com:mrVanDalo/module.cluster.git") + + (sync-to-github "sync-backup-module" + "ssh://gogs@workhorse.private:2222/nix-modules/backup.git" + "git@github.com:mrVanDalo/module.backup.git") + + (sync-to-github "sync-module-tinc" + "ssh://gogs@workhorse.private:2222/palo/nixos-tinc.git" + "git@github.com:mrVanDalo/nixos-tinc.git") + + (sync-to-github "sync-memo" + "ssh://gogs@workhorse.private:2222/palo/memo.git" + "git@github.com:mrVanDalo/memo.git") + + (sync-to-github "sync-diagrams-template" + "ssh://gogs@workhorse.private:2222/palo/diagrams-template.git" + "git@github.com:mrVanDalo/diagrams.git") + + (sync-to-github "sync-plops" + "ssh://gogs@workhorse.private:2222/palo/plops.git" + "git@github.com:mrVanDalo/plops.git") + + (sync-to-github "sync-image-generator" + "ssh://gogs@workhorse.private:2222/palo/image-generator2.git" + "git@github.com:mrVanDalo/image-generator.git") + + (sync-to-github "sync-image-generator-lib" + "ssh://gogs@workhorse.private:2222/palo/image-generator-lib.git" + "git@github.com:mrVanDalo/image-generator-examples.git") + + (sync-to-github "sync-tech.ingolf-wagner.de" + "ssh://gogs@workhorse.private:2222/palo/tech.ingolf-wagner.de.git" + "git@github.com:mrVanDalo/tech.ingolf-wagner.de.git") + + (sync-to-github "sync-LineageOS-build" + "ssh://gogs@git.ingolf-wagner.de:2222/palo/LineagoOS-build.git" + "git@github.com:mrVanDalo/LineagoOS-build.git") + + (sync-to-github "sync-http-errors" + "ssh://gogs@git.ingolf-wagner.de:2222/palo/http-errors.git" + "git@github.com:mrVanDalo/http-errors.git") + (sync-to-github "sync-light-control" + "ssh://gogs@git.ingolf-wagner.de:2222/palo/light-control.git" + "git@github.com:mrVanDalo/light-control.git") + + ]; + }; + }; + +} diff --git a/nixos/configs/robi/jupyter.nix b/nixos/configs/robi/jupyter.nix new file mode 100644 index 0000000..63bdf7c --- /dev/null +++ b/nixos/configs/robi/jupyter.nix @@ -0,0 +1,71 @@ +{ pkgs, lib, config, ... }: { + + services.jupyter = { + enable = true; + ip = "0.0.0.0"; + #In [1]: from notebook.auth import passwd + #In [2]: passwd('test') + #Out[2]: 'sha1:1b961dc713fb:88483270a63e57d18d43cf337e629539de1436ba' + #NOTE: you need to keep the single quote inside nix string. + password = "'sha1:1b961dc713fb:88483270a63e57d18d43cf337e629539de1436ba'"; + kernels = { + python3 = + let + env = (pkgs.python3.withPackages (pythonPackages: + with pythonPackages; [ + ipykernel + pandas + + # database stuff + mysqlclient + databases + asyncpg + psycopg2 + aiomysql + pymysql + aiosqlite + #aiopg + sqlalchemy + + # pdf export + nbconvert + ])); + in + { + displayName = "Python 3"; + argv = [ + "${env.interpreter}" + "-m" + "ipykernel_launcher" + "-f" + "{connection_file}" + ]; + language = "python"; + }; + }; + }; + + # to generate pdfs and such + environment.systemPackages = [ pkgs.pandoc ]; + + backup.dirs = [ "/var/lib/jupyter" ]; + backup.exclude = + [ "/var/lib/jupyter/.local" "/var/lib/jupyter/.ipynb_checkpoints" ]; + + services.nginx = { + enable = true; + statusPage = true; + virtualHosts = { + "python.${config.networking.hostName}.private" = { + serverAliases = [ "jupyter.${config.networking.hostName}.private" ]; + locations."/" = { + proxyWebsockets = true; + proxyPass = "http://${config.networking.hostName}.private:${ + toString config.services.jupyter.port + }"; + }; + }; + }; + }; + +} diff --git a/nixos/configs/robi/kibana.nix b/nixos/configs/robi/kibana.nix new file mode 100644 index 0000000..279aea1 --- /dev/null +++ b/nixos/configs/robi/kibana.nix @@ -0,0 +1,25 @@ +{ config, ... }: { + services.nginx = { + enable = true; + statusPage = true; + virtualHosts = { + "kibana.${config.networking.hostName}.private" = { + serverAliases = [ ]; + locations."/" = { + proxyPass = "http://${config.networking.hostName}.private:${ + toString config.services.kibana.port + }"; + }; + }; + }; + }; + + services.elasticsearch.enable = true; + services.elasticsearch.listenAddress = "workhorse.private"; + + services.kibana.enable = true; + services.kibana.elasticsearch.hosts = [ "http://workhorse.private:9200" ]; + services.kibana.listenAddress = "workhorse.private"; + services.kibana.port = 5601; + +} diff --git a/nixos/configs/robi/mail-fetcher.nix b/nixos/configs/robi/mail-fetcher.nix new file mode 100644 index 0000000..339972e --- /dev/null +++ b/nixos/configs/robi/mail-fetcher.nix @@ -0,0 +1,661 @@ +# fetches mails for me +{ lib, pkgs, config, ... }: +let + junk_filter = [ + "from:booking.com" + "subject:Gewinn" + "from:brompton.com" + "from:circleci.com OR (from:noreply@github.com AND to:audio-overlay@googlegroups.com)" + "from:codepen.io" + "from:congstarnews.de" + "from:cronullasurfingacademy.com" + "from:cryptohopper.com" + "from:digitalo.de" + "from:facebook.com OR from:facebookmail.com" + "from:fitnessfirst.de" + "from:flixbus.de" + "from:getdigital.de" + "from:getpocket.com" + "from:ghostinspector.com" + "from:globetrotter.de" + "from:hackster.io" + "from:hostelworld.com" + "from:immobilienscout24.de" + "from:kvraudio.com" + "from:letterboxd.com" + "from:linkedin.com" + "from:magix.net" + "from:mailings.gmx.net" + "from:mailings.web.de" + "from:matrix.org" + "from:menospese.com" + "from:microsoftstoreemail.com" + "from:mixcloudmail.com AND subject:Weekly Update" + "from:oknotify2.com AND NOT subject:New message" + "from:paulaschoice.com" + "from:puppet.com" + "from:runtastic.com" + "from:samplemagic.com OR from:wavealchemy.co.uk OR from:creators.gumroad.com" + "from:ticketmaster.de" + "from:trade4less.de" + "from:tumblr.com" + "from:turners.co.nz" + "from:twitch.tv" + "from:vstbuzz.com" + ]; + filters = [ + { + query = "from:hv-geelen.de"; + tags = [ "+wohnung" ]; + } + { + query = "from:computerfutures.com OR from:computerfutures.de"; + tags = [ "+jobs" "-inbox" ]; + } + { + query = "from:seek.com.au or from:seek.co.nz"; + tags = [ "+jobs" ]; + } + { + query = "from:xing.com"; + tags = [ "+jobs" "-inbox" ]; + } + { + query = "from:no-reply@backtrace.io OR to:sononym@noreply.github.com"; + tags = [ "+sononym" "-inbox" ]; + } + { + query = "from:ebay.com OR from:ebay.de OR from:ebay.net"; + tags = [ "+ebay" "+shop" "+billing" ]; + } + { + query = "from:bahn.de"; + tags = [ "+billing" "+bahn" ]; + } + { + query = + "from:fysitech.atlassian.net OR to:engiadina-pwa@noreply.github.com"; + tags = [ "+mia" "+work" "-unread" "-inbox" ]; + } + { + query = + "from:space-left.org OR to:space-left.org OR subject:/\\[space-left\\]/"; + tags = [ "+spaceleft" "+space-left" ]; + } + { + query = "from:landr.com"; + tags = [ "+landr" "+music" ]; + } + { + query = "tag:landr and tag:billing"; + tags = [ "+billing" ]; + } + { + query = "from:oknotify2.com"; + tags = [ "+okcupid" ]; + } + { + query = "from:taxback.de OR to:taxback.de"; + tags = [ "+steuer" ]; + } + { + query = "from:campact.de"; + tags = [ "+campact" "+politics" ]; + } + { + query = "from:aliexpress.com"; + tags = [ "+shop" "+aliexpress" ]; + } + { + query = "from:congstar.de"; + tags = [ "+billing" "+congstar" "-inbox" "-unread" ]; + } + { + query = + "from:steampowered.com AND NOT ( subject:purchase OR subject:received )"; + tags = [ "-inbox" "-unread" ]; + } + { + query = + "from:steampowered.com AND ( subject:purchase OR subject:received )"; + tags = [ "+billing" "+steam" ]; + } + { + query = "from:gog.com AND NOT subject:Bestellung"; + tags = [ "-inbox" "-unread" ]; + } + { + query = "from:gog.com AND subject:Bestellung"; + tags = [ "+billing" "+gog" ]; + } + { + query = "from:stadtmobil.de"; + tags = [ "+billing" "+stadtmobil" "-inbox" "-unread" ]; + } + { + query = "from:drive-now.com"; + tags = [ "+billing" "+drivenow" "-inbox" "-unread" ]; + } + { + query = "from:data-treuhand.de"; + tags = [ "+mindcurv" "+work" "-inbox" "-unread" "-junk" ]; + } + { + query = "from:immocation.de"; + tags = [ "+immobilien" "-inbox" ]; + } + { + query = "from:tinc-vpn.org"; + tags = [ "+tinc" ]; + } + { + query = "from:mindfactory.de"; + tags = [ "+shop" "+billing" ]; + } + { + query = "from:zalando.de"; + tags = [ "+shop" "+billing" "+zalando" ]; + } + { + query = "from:ing.de"; + tags = [ "+bank" "+ingdiba" ]; + } + { + query = "from:nab.com.au"; + tags = [ "+bank" "+nab" "-inbox" "-unread" ]; + } + { + query = "from:dkb.de"; + tags = [ "+bank" "+dkb" ]; + } + { + query = "from:o2online.de"; + tags = [ "+billing" "+o2" ]; + } + { + query = "from:betfair.com"; + tags = [ "+work" "+betfair" ]; + } + { + query = "from:notifications@github.com"; + tags = [ "+github" ]; + } + { + query = "to:NUR@noreply.github.com"; + tags = [ "+nur" "+nixos" "+list" ]; + } + { + query = "to:nixpkgs@noreply.github.com"; + tags = [ "+nixpkgs" "+nixos" "+list" ]; + } + { + query = "from:travis-ci.org AND subject:mrVanDalo/navi"; + tags = [ "+development" "+navi" ]; + } + { + query = "from:travis-ci.org AND subject:nur-packages"; + tags = [ "+development" "+nixos" "+nur-packages" ]; + } + { + query = "from:travis-ci.org AND subject:csv-to-qif"; + tags = [ "+development" "+csv-to-qif" ]; + } + { + query = "to:proaudio@lists.tuxfamily.org"; + tags = [ "-inbox" "-unread" ]; + } + { + query = "from:nixos1@discoursemail.com"; + tags = [ "+nixos" "+discourse" "+list" ]; + } + { + query = "from:nixos1@discoursemail.com AND subject:Development"; + tags = [ "+nixos" "+discourse" "+development" ]; + } + { + query = "from:nixos1@discoursemail.com AND subject:Français"; + tags = [ "+nixos" "+discourse" "-inbox" "-unread" ]; + } + { + query = "from:nixos1@discoursemail.com AND subject:Announcements"; + tags = [ "+nixos" "+discourse" "+announcements" ]; + } + { + query = "from:nixos1@discoursemail.com AND subject:Links"; + tags = [ "+nixos" "+discourse" "+links" ]; + } + { + query = "from:nixos1@discoursemail.com AND subject:Games"; + tags = [ "+nixos" "+discourse" "+games" ]; + } + { + query = "from:nixos1@discoursemail.com AND subject:Meta"; + tags = [ "+nixos" "+discourse" "+meta" ]; + } + { + query = "from:nixos1@discoursemail.com AND subject:Events"; + tags = [ "+nixos" "+discourse" "+events" ]; + } + { + query = "from:limebike.com AND (subject:Funds OR subject:Receipt)"; + tags = [ "-inbox" "-unread" "+billing" "+limebike" ]; + } + { + query = "from:freemusicarchive.org"; + tags = [ "+FMA" ]; + } + { + query = "from:namecheap.com and subject:auto-renewal"; + tags = [ "+namecheap" "+billing" ]; + } + { + query = "from:namecheap.com and subject:order"; + tags = [ "+namecheap" "+billing" ]; + } + { + query = "tag:namecheap.com and tag:billing and body:gaykraft.com"; + tags = [ "+namecheap" "+billing" ]; + } + { + query = "from:nintendo.com"; + tags = [ "+nintendo" "+billing" ]; + } + { + query = "from:oculus.com AND subject:receipt"; + tags = [ "+oculus" "+billing" ]; + } + { + query = "from:car2go.com"; + tags = [ "-inbox" "-unread" ]; + } + { + query = "from:sixt.de"; + tags = [ "-inbox" "-unread" ]; + } + { + query = "from:meetup.com"; + tags = [ "-inbox" "-unread" "+meetup" ]; + } + { + query = "from:slack.com"; + tags = [ "+slack" ]; + } + { + query = "from:keybase.io"; + tags = [ "+keybase" ]; + } + { + query = "from:jobs2web.com"; + tags = [ "+newzealand" "+jobs" "-inbox" ]; + } + { + query = "from:paypal.de AND subject:Bestätigung"; + tags = [ "-unread" "+paypal" "+billing" ]; + } + { + query = "to:c-base.org"; + tags = [ "+cbase" "+list" ]; + } + { + query = "to:c-base.org AND subject=[auto-report]"; + tags = [ "-unread" "-inbox" ]; + } + { + query = "from:browserstack.com"; + tags = [ "+browserstack" ]; + } + { + query = + "to:renoise@ingolf-wagner.de OR to:root@renoise.com OR from:renoise.com OR to:admin@renoise.com"; + tags = [ "+renoise" ]; + } + { + query = "from:amazon.de OR from:amazon.com AND NOT to:renoise.com"; + tags = [ "+shop" "+amazon" "+billing" ]; + } + { + query = "from:hetzner.com OR from:hetzner.de"; + tags = [ "+hetzner" ]; + } + { + query = + "to:renoise.com AND NOT ( from:renoise.com OR from:root OR from:hetzner.com OR from:hetzner.de OR from:amazon.com OR from:gmail.com )"; + tags = [ "-inbox" "-unread" "+junk" "+renoise" ]; + } + { + query = "tag:hetzner and subject:Invoice"; + tags = [ "+billing" ]; + } + # final rules to make imap sync stuff easier + # there can only be one output folder tag, and theses rules are prioritized + { + query = "tag:fraud"; + tags = [ "-inbox" "-archive" "-junk" "-unread" ]; + message = "clean up tag fraud"; + } + { + query = "tag:junk"; + tags = [ "-inbox" "-archive" "-fraud" "-unread" ]; + message = "clean up tag junk"; + } + { + query = "tag:archive"; + tags = [ "-inbox" "-junk" "-fraud" "-unread" ]; + message = "clean up tag archive"; + } + { + query = "tag:inbox"; + tags = [ "-archive" "-junk" "-fraud" ]; + message = "clean up inbox"; + } + { + query = "tag:killed"; + tags = [ "-inbox" "-unread" ]; + message = "clean up tag killed"; + } + { + query = "tag:muted"; + tags = [ "-inbox" "-unread" ]; + } + # remove new tag at the end + { + query = "tag:new"; + tags = [ "-new" ]; + message = "remove new tag at the end"; + } + ]; + + notmuchTagging = + let + + template = index: + { tags, query, message ? "generic", ... }: + let + command = '' + ${pkgs.notmuch}/bin/notmuch tag ${lib.concatStringsSep " " tags} -- "${query}" + ''; + in + '' + echo '${command}' + ${command} + ''; + junk_template = index: query: + template index { + tags = [ "+junk" "-unread" "-inbox" ]; + query = query; + message = "generic junk filter"; + }; + + in + pkgs.writers.writeBash "notmuch-tagging" (lib.concatStringsSep "\n" + ((lib.imap0 junk_template junk_filter) ++ (lib.imap0 template filters))); + + notmuchTaggingNew = + let + + template = index: + { tags, query, message ? "generic", ... }: + let + command = '' + ${pkgs.notmuch}/bin/notmuch tag ${ + lib.concatStringsSep " " tags + } -- "${query} AND tag:new" + ''; + in + '' + echo '${command}' + ${command} + ''; + + junk_template = index: query: + template index { + tags = [ "+junk" "-unread" "-inbox" ]; + query = query; + message = "generic junk filter"; + }; + in + pkgs.writers.writeBash "notmuch-tagging-new" (lib.concatStringsSep "\n" + ((lib.imap0 junk_template junk_filter) ++ (lib.imap0 template filters))); + +in +{ + + backup.dirs = [ "/home/mailfetcher" ]; + + users.users.mailUser = { + isNormalUser = true; + description = "collects mails for me"; + hashedPassword = "!"; + name = "mailfetcher"; + home = "/home/mailfetcher"; + openssh.authorizedKeys.keyFiles = + config.users.users.root.openssh.authorizedKeys.keyFiles; + group = "mailfetcher"; + }; + + users.groups.mailUser = { + name = "mailfetcher"; + }; + + sops.secrets.mail_terranix = { + owner = config.users.users.mailUser.name; + group = config.users.users.mailUser.group; + }; + sops.secrets.mail_gmail = { + owner = config.users.users.mailUser.name; + group = config.users.users.mailUser.group; + }; + sops.secrets.mail_gmx_palo = { + owner = config.users.users.mailUser.name; + group = config.users.users.mailUser.group; + }; + sops.secrets.mail_gmx_ingolf = { + owner = config.users.users.mailUser.name; + group = config.users.users.mailUser.group; + }; + sops.secrets.mail_web = { + owner = config.users.users.mailUser.name; + group = config.users.users.mailUser.group; + }; + sops.secrets.mail_siteground = { + owner = config.users.users.mailUser.name; + group = config.users.users.mailUser.group; + }; + + environment.systemPackages = [ pkgs.muchsync ]; + + # configure accounts + home-manager.users.mailUser.accounts.email = { + accounts = { + + palo_van_dalo-gmx = { + primary = false; + address = "palo_van_dalo@gmx.de"; + aliases = [ ]; + realName = "Ingolf Wagner"; + userName = "palo_van_dalo@gmx.de"; + passwordCommand = + "cat ${toString config.sops.secrets.mail_gmx_palo.path }"; + imap = { + host = "imap.gmx.net"; + tls.enable = true; + port = 993; + }; + mbsync = { + enable = true; + create = "both"; + }; + notmuch.enable = true; + }; + + ingolf-wagner-gmx = { + primary = false; + address = "ingolf.wagner@gmx.de"; + aliases = [ ]; + realName = "Ingolf Wagner"; + userName = "ingolf.wagner@gmx.de"; + passwordCommand = + "cat ${toString config.sops.secrets.mail_gmx_ingolf.path }"; + imap = { + host = "imap.gmx.net"; + tls.enable = true; + port = 993; + }; + mbsync = { + enable = true; + create = "both"; + }; + notmuch.enable = true; + }; + + pali_palo = { + primary = false; + address = "pali_palo@web.de"; + aliases = [ ]; + realName = "Ingolf Wagner"; + userName = "pali_palo@web.de"; + passwordCommand = + "cat ${toString config.sops.secrets.mail_web.path }"; + imap = { + host = "imap.web.de"; + tls.enable = true; + port = 993; + }; + mbsync = { + enable = true; + create = "both"; + }; + notmuch.enable = true; + }; + + gmail = { + # for google accounts you have to allow 'less secure apps' in accounts.google.com + primary = true; + address = "palipalo9@googlemail.com"; + aliases = [ ]; + realName = "Ingolf Wagner"; + userName = "palipalo9@googlemail.com"; + passwordCommand = + "cat ${toString config.sops.secrets.mail_gmail.path }"; + imap = { + host = "imap.gmail.com"; + tls.enable = true; + port = 993; + }; + mbsync = { + enable = true; + create = "both"; + }; + notmuch.enable = true; + }; + + terranix_org = { + primary = false; + address = "palo@terranix.org"; + aliases = [ ]; + realName = "Ingolf Wagner"; + userName = "palo@terranix.org"; + passwordCommand = "cat ${toString config.sops.secrets.mail_terranix.path }"; + imap = { + host = "mail.privateemail.com"; + tls.enable = true; + port = 993; + }; + mbsync = { + enable = true; + create = "both"; + }; + notmuch.enable = true; + }; + + ingolf-wagner-de = { + primary = false; + address = "contact@ingolf-wagner.de"; + aliases = [ ]; + realName = "Ingolf Wagner"; + userName = "contact@ingolf-wagner.de"; + passwordCommand = + "cat ${toString config.sops.secrets.mail_siteground.path }"; + imap = { + host = "securees5.sgcpanel.com"; + port = 993; + tls.enable = true; + #tls.useStartTls = true; + }; + # make sure the upstream mail is deleted + getmail = { + enable = true; + delete = true; + readAll = false; + mailboxes = [ "ALL" ]; + }; + notmuch.enable = true; + }; + + }; + }; + + # configure mbsync + home-manager.users.mailUser.programs.mbsync.enable = true; + + # re-tag everything once a day + systemd.services.retagmail = { + enable = true; + serviceConfig = { User = config.users.users.mailUser.name; }; + environment.NOTMUCH_CONFIG = + "${config.users.users.mailUser.home}/.config/notmuch/notmuchrc"; + script = "${notmuchTagging}"; + }; + systemd.timers.retagmail = { + enable = true; + timerConfig = { + OnCalendar = "daily"; + Persistent = "true"; + }; + wantedBy = [ "multi-user.target" ]; + }; + + # fetch mails every 10 minutes + systemd.services.fetchmail = + let + threadTag = tag: '' + echo "tag threads with ${tag}" + ${pkgs.notmuch}/bin/notmuch tag +${tag} $(${pkgs.notmuch}/bin/notmuch search --output=threads tag:${tag}) + ''; + in + { + enable = true; + serviceConfig = { User = config.users.users.mailUser.name; }; + environment.NOTMUCH_CONFIG = + "${config.users.users.mailUser.home}/.config/notmuch/notmuchrc"; + script = '' + echo "run mbsync" + ${pkgs.isync}/bin/mbsync \ + --all + echo "run getmail" + ${pkgs.getmail}/bin/getmail \ + --quiet \ + --rcfile getmailingolf-wagner-de + + echo "run notmuch" + ${pkgs.notmuch}/bin/notmuch new + ${notmuchTaggingNew} + ${threadTag "muted"} + ${threadTag "wohnung"} + ${threadTag "flagged"} + ''; + }; + systemd.timers.fetchmail = { + enable = true; + # timerConfig.OnCalendar = " *-*-* *:00:00"; + timerConfig.OnCalendar = "*:0/10"; + wantedBy = [ "multi-user.target" ]; + }; + + # configure notmuch + home-manager.users.mailUser.programs.notmuch = { + enable = true; + new.tags = [ "unread" "inbox" "new" ]; + }; + +} diff --git a/nixos/configs/robi/metabase.nix b/nixos/configs/robi/metabase.nix new file mode 100644 index 0000000..8dd3f0b --- /dev/null +++ b/nixos/configs/robi/metabase.nix @@ -0,0 +1,24 @@ +/{ pkgs, lib, config, ... }: { + + services.metabase = { + listen.port = 3040; + enable = true; + }; + + backup.dirs = [ "/var/lib/metabase" ]; + + services.nginx = { + enable = true; + statusPage = true; + virtualHosts = { + "metabase.${config.networking.hostName}.private" = { + locations."/" = { + proxyPass = "http://${config.networking.hostName}.private:${ + toString config.services.metabase.listen.port + }"; + }; + }; + }; + }; + +} diff --git a/nixos/configs/robi/mining.nix b/nixos/configs/robi/mining.nix new file mode 100644 index 0000000..6f95ec0 --- /dev/null +++ b/nixos/configs/robi/mining.nix @@ -0,0 +1,52 @@ +{ pkgs, config, ... }: +let + maxPower = 90; + pool = "eu1.ethermine.org"; + toolkit = "opencl"; + wallet = ""; + rig = config.networking.hostName; + recheckInterval = 2000; + package = pkgs.ethminer; +in +{ + + systemd.services.ethminer = { + description = "ethminer ethereum mining service"; + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + + serviceConfig = { + DynamicUser = true; + ExecStartPre = "${package}/bin/.ethminer-wrapped --list-devices"; + Restart = "always"; + }; + + script = '' + ${package}/bin/.ethminer-wrapped \ + --farm-recheck ${toString recheckInterval} \ + --report-hashrate \ + --${toolkit} \ + --pool stratum1+tcp://${wallet}.${rig}@${pool}:4444 + ''; + + }; + + # https://wiki.archlinux.org/title/GPGPU#Intel + hardware.opengl = { + enable = true; + extraPackages = with pkgs; [ intel-ocl intel-compute-runtime beignet ]; + driSupport = true; + driSupport32Bit = true; + }; + + environment.systemPackages = with pkgs; [ + package + # go-ethereum + go-ethereum + # to check opencl config + clinfo + # check temperature + i7z + ]; + +} diff --git a/nixos/configs/robi/mysql.nix b/nixos/configs/robi/mysql.nix new file mode 100644 index 0000000..727df98 --- /dev/null +++ b/nixos/configs/robi/mysql.nix @@ -0,0 +1,20 @@ +{ pkgs, lib, config, ... }: { + + services.mysql = { + enable = true; + package = pkgs.mysql80; + initialScript = pkgs.writeText "initScript" '' + CREATE USER 'admin'@'%' IDENTIFIED BY 'admin'; + GRANT ALL PRIVILEGES ON * . * TO 'admin'@'%'; + ''; + }; + + services.mysqlBackup = { + enable = true; + databases = [ "property" ]; + #user = "admin"; + }; + + backup.dirs = [ config.services.mysqlBackup.location ]; + +} diff --git a/nixos/configs/robi/nextcloud.nix b/nixos/configs/robi/nextcloud.nix new file mode 100644 index 0000000..438d87c --- /dev/null +++ b/nixos/configs/robi/nextcloud.nix @@ -0,0 +1,198 @@ +{ pkgs, config, lib, ... }: +{ + + + networking.firewall.allowedTCPPorts = [ 80 443 ]; + networking.firewall.allowedUDPPorts = [ 80 443 ]; + + + # host nginx setup + services.nginx = { + enable = true; + recommendedGzipSettings = lib.mkDefault true; + recommendedOptimisation = lib.mkDefault true; + recommendedTlsSettings = lib.mkDefault true; + recommendedProxySettings = true; + sslCiphers = "AES256+EECDH:AES256+EDH:!aNULL"; + + virtualHosts = { + "nextcloud.ingolf-wagner.de" = { + forceSSL = true; + enableACME = true; + }; + }; + }; + + + # nextcloud database + # ================== + # + # set user password: + # ----------------- + # #> mysql + # mysql> ALTER USER 'nextcloud'@'localhost' IDENTIFIED BY 'nextcloud-password'; + # + # recreate database: + # ------------------ + # mysql> DROP DATABASE nextcloud; + # mysql> CREATE DATABASE nextcloud; + # + # migration: + # ---------- + # nextcloud-occ db:convert-type --all-apps mysql nextcloud 127.0.0.1 nextcloud + # + # 4-byte stuff: + # ------------- + # https://docs.nextcloud.com/server/18/admin_manual/configuration_database/mysql_4byte_support.html + # if you do this don't forget --default-character-set=utf8mb4 for mysqldump + services.mysql = { + enable = true; + package = pkgs.mysql; + # https://nixos.org/manual/nixos/stable/release-notes.html#sec-release-20.09-incompatibilities + ensureDatabases = [ "nextcloud" ]; + ensureUsers = [{ + name = "nextcloud"; + ensurePermissions = { "nextcloud.*" = "ALL PRIVILEGES"; }; + }]; + settings.mysqld = { + innodb_large_prefix = true; + innodb_file_format = "barracuda"; + innodb_file_per_table = 1; + }; + }; + + # Backup database + # --------------- + services.mysqlBackup = { + enable = true; + databases = config.services.mysql.ensureDatabases; + singleTransaction = true; + location = "/var/lib/nextcloud/database_backups"; + }; + systemd.services."mysql-backup".serviceConfig = { + ExecStartPre = + [ "+/run/current-system/sw/bin/nextcloud-occ maintenance:mode --on" ]; + ExecStopPost = [ + "+/run/current-system/sw/bin/nextcloud-occ maintenance:mode --off" + ]; + }; + + # in php + services.phpfpm.phpPackage = pkgs.php73; + + # nextcloud setup + services.nextcloud = { + enable = true; + hostName = "nextcloud.ingolf-wagner.de"; + package = pkgs.nextcloud22; + autoUpdateApps.enable = true; + autoUpdateApps.startAt = "05:00:00"; + logLevel = 2; + https = true; + config = { + adminpassFile = config.sops.secrets.nextcloud_root_password.path; + overwriteProtocol = "https"; + dbtype = "mysql"; + dbpassFile = config.sops.secrets.nextcloud_database_password.path; + dbport = 3306; + }; + }; + + sops.secrets.nextcloud_database_password.owner = "nextcloud"; + sops.secrets.nextcloud_root_password.owner = "nextcloud"; + + + #services.journalbeat = { + # enable = true; + # extraConfig = '' + # journalbeat.inputs: + # - paths: [] + # # Position to start reading from journal. Valid values: head, tail, cursor + # seek: cursor + # # Fallback position if no cursor data is available. + # cursor_seek_fallback: tail + # output.logstash: + # # Boolean flag to enable or disable the output module. + # enabled: true + # # Graylog host and the beats input + # hosts: ["${hostAddress}:5044"] + + # # If enabled only a subset of events in a batch of events is transferred per + # # transaction. The number of events to be sent increases up to `bulk_max_size` + # # if no error is encountered. + # slow_start: true + + # # The number of seconds to wait before trying to reconnect to Graylog + # # after a network error. After waiting backoff.init seconds, the Beat + # # tries to reconnect. If the attempt fails, the backoff timer is increased + # # exponentially up to backoff.max. After a successful connection, the backoff + # # timer is reset. The default is 1s. + # backoff.init: 1s + + # # The maximum number of seconds to wait before attempting to connect to + # # Graylog after a network error. The default is 60s. + # backoff.max: 60s + # ''; + #}; + + # give containers internet access + #networking.nat.enable = true; + #networking.nat.internalInterfaces = [ "ve-nextcloud" ]; + #networking.nat.externalInterface = "enp2s0f1"; + + # don't let networkmanager manger container network + #networking.networkmanager.unmanaged = [ "interface-name:ve-*" ]; + + # open ports for logging + #networking.firewall.interfaces."ve-nextcloud".allowedTCPPorts = + # [ 5044 12304 12305 ]; + #networking.firewall.interfaces."ve-nextcloud".allowedUDPPorts = + # [ 5044 12304 12305 ]; + + + # Backup Config + # ------------- + #backup.dirs = [ + # "/home/nextcloud/config" + # "/home/nextcloud/database_backups" # created by mysqlBackup + #]; + + # Backup Files + # ------------ + #services.borgbackup.jobs = { + # "nextcloud-to-media" = { + # repo = "/media/syncthing/borg/nextcloud"; + # # make sure syncthing is capable of reading the files + # postHook = '' + # chown -R syncthing:syncthing /media/syncthing/borg/nextcloud + # ''; + # compression = "lz4"; + # paths = [ + # "/home/nextcloud/data/tina/files/Documents" + # "/home/nextcloud/data/tina/files/Pictures" + # "/home/nextcloud/data/tina/files/Joplin" + # "/home/nextcloud/data/tina/files/SofortUpload" + # "/home/nextcloud/data/palo/files/InstantUpload" + # "/home/nextcloud/data/palo/files/Joplin" + # "/home/nextcloud/data/palo/files/Pictures" + # "/home/nextcloud/data/palo/files/Unterlagen" + # "/home/nextcloud/data/palo/files/Video" + # "/home/nextcloud/data/palo-windows/files/Kunstbuch" + # ]; + # doInit = true; + # encryption = { + # mode = "repokey-blake2"; + # passCommand = + # "cat ${config.sops.secrets.backup_repository_passphrase.path}"; + # }; + # startAt = "0/3:00:00"; + # prune.keep = { + # within = "2d"; # Keep all backups in the last 10 days. + # daily = 10; # Keep 10 additional end of day archives + # weekly = 8; # Keep 8 additional end of week archives. + # month = 8; # Keep 8 additional end of month archives. + # }; + # }; + #}; + +} diff --git a/nixos/configs/robi/packages.nix b/nixos/configs/robi/packages.nix new file mode 100644 index 0000000..3889a0e --- /dev/null +++ b/nixos/configs/robi/packages.nix @@ -0,0 +1,5 @@ +{ config, pkgs, ... }: { + environment.systemPackages = with pkgs; [ + mosh + ]; +} diff --git a/nixos/configs/robi/prometheus.nix b/nixos/configs/robi/prometheus.nix new file mode 100644 index 0000000..6888571 --- /dev/null +++ b/nixos/configs/robi/prometheus.nix @@ -0,0 +1,106 @@ +{ config, pkgs, lib, ... }: { + + services.nginx = { + enable = true; + statusPage = true; + virtualHosts = { + "prometheus.workhorse.private" = { + locations."/" = { proxyPass = "http://workhorse.private:9090"; }; + }; + }; + }; + + services.prometheus = { + enable = true; + # keep data for 30 days + extraFlags = [ "--storage.tsdb.retention.time=30d" ]; + scrapeConfigs = [ + { + job_name = "nginx"; + scrape_interval = "8s"; + static_configs = [ + { + targets = [ "sputnik.private:9113" ]; + labels = { + service = "nginx"; + server = "sputnik"; + }; + } + { + targets = [ "sputnik.private:9113" ]; + labels = { + service = "nginx"; + server = "sputnik"; + }; + } + { + targets = [ "workhorse.private:9113" ]; + labels = { + service = "nginx"; + server = "sputnik"; + }; + } + ]; + } + { + job_name = "netdata"; + metrics_path = "/api/v1/allmetrics"; + params.format = [ "prometheus" ]; + scrape_interval = "5s"; + static_configs = [ + { + targets = [ "pepe.private:19999" ]; + labels = { + service = "netdata"; + server = "pepe"; + }; + } + { + targets = [ "sputnik.private:19999" ]; + labels = { + service = "netdata"; + server = "sputnik"; + }; + } + { + targets = [ "workhorse.private:19999" ]; + labels = { + service = "netdata"; + server = "workhorse"; + }; + } + ]; + } + { + job_name = "gogs"; + metrics_path = "/-/metrics"; + params.format = [ "prometheus" ]; + scrape_interval = "10s"; + static_configs = [{ + targets = [ "workhorse.private:3000" ]; + labels = { + service = "gogs"; + server = "kruck"; + }; + }]; + } + #{ + # job_name = "home-assistant"; + # scrape_interval = "60s"; + # metrics_path = "/api/prometheus"; + # # you can create this token on your user profile page + # # http://pepe.private:8123/profile + # bearer_token = + # lib.fileContents ; + # static_configs = [{ + # targets = [ "pepe.private:8123" ]; + # labels = { + # service = "hass"; + # server = "pepe"; + # city = "essen"; + # }; + # }]; + #} + ]; + }; +} diff --git a/nixos/configs/robi/property.nix b/nixos/configs/robi/property.nix new file mode 100644 index 0000000..169f2c2 --- /dev/null +++ b/nixos/configs/robi/property.nix @@ -0,0 +1,43 @@ +{ lib, pkgs, config, ... }: { + + users.users.property = { isSystemUser = true; }; + + systemd.services.property = { + enable = true; + wantedBy = [ "multi-user.target" ]; + path = [ + (pkgs.python3.withPackages (ps: + with ps; [ + flask + selenium + beautifulsoup4 + urllib3 + sqlalchemy + mysqlclient + pytest + dateparser + geopy + nltk + click + ])) + ]; + + serviceConfig = { User = "property"; }; + script = '' + FLASK_APP=${}/server.py \ + FLASK_RUN_PORT=7888 \ + flask run --host 0.0.0.0 \ + "$@" + ''; + }; + + services.nginx = { + enable = true; + virtualHosts = { + "property.workhorse.private" = { + locations."/" = { proxyPass = "http://localhost:7888"; }; + }; + }; + }; + +} diff --git a/nixos/configs/robi/syncthing.nix b/nixos/configs/robi/syncthing.nix new file mode 100644 index 0000000..c7a369a --- /dev/null +++ b/nixos/configs/robi/syncthing.nix @@ -0,0 +1,140 @@ +{ config, pkgs, lib, ... }: { + + custom.samba-share = { + enable = true; + folders = { + movies = config.services.syncthing.declarative.folders.movies.path; + series = config.services.syncthing.declarative.folders.series.path; + samples = config.services.syncthing.declarative.folders.samples.path; + music = config.services.syncthing.declarative.folders.music-library.path; + books = config.services.syncthing.declarative.folders.books.path; + }; + }; + + + sops.secrets.syncthing_cert = { }; + sops.secrets.syncthing_key = { }; + + services.syncthing = { + enable = true; + openDefaultPorts = false; + dataDir = "/home/syncthing"; + configDir = "/home/syncthing"; + declarative = { + cert = toString config.sops.secrets.syncthing_cert.path; + key = toString config.sops.secrets.syncthing_key.path; + overrideFolders = true; + + folders = { + + # on encrypted hard drive + # ----------------------- + private = { + enable = true; + path = "/home/syncthing/private"; + }; + desktop = { + enable = true; + path = "/home/syncthing/desktop"; + }; + finance = { + enable = true; + path = "/home/syncthing/finance"; + }; + fotos = { + enable = true; + path = "/home/syncthing/fotos"; + }; + lost-fotos = { + enable = true; + path = "/home/syncthing/lost-fotos.ct"; + }; + zettlr = { + enable = true; + path = "/home/syncthing/zettlr"; + }; + + # on media hard drive (not encrypted) + # ----------------------------------- + borg-mirror = { + enable = true; + path = "/media/syncthing/borg"; + rescanInterval = 36 * 3600; + type = "sendonly"; + }; + video-material = { + enable = true; + path = "/home/syncthing/video-material"; + }; + music-library-free = { + enable = true; + path = "/media/syncthing/music-library-free"; + rescanInterval = 8 * 3600; + }; + books = { + enable = true; + path = "/media/syncthing/books"; + rescanInterval = 8 * 3600; + }; + samples = { + enable = true; + path = "/media/syncthing/samples"; + rescanInterval = 8 * 3600; + }; + movies = { + enable = true; + path = "/media/syncthing/movies"; + rescanInterval = 8 * 3600; + }; + # todo : no need to place it on encrypted drive + music-projects = { + enable = true; + path = "/home/syncthing/music-projects"; + }; + music-library = { + enable = true; + path = "/media/syncthing/music-library"; + rescanInterval = 8 * 3600; + }; + series = { + enable = true; + path = "/media/syncthing/series"; + rescanInterval = 8 * 3600; + }; + smartphone-folder = { + enable = true; + path = "/media/syncthing/smartphone-folder"; + rescanInterval = 8 * 3600; + }; + processing = { + enable = true; + path = "/media/syncthing/sketchbook"; + rescanInterval = 8 * 3600; + }; + + }; + }; + }; + + system.permown."/home/syncthing" = { + owner = "syncthing"; + group = "syncthing"; + umask = "0022"; + }; + system.permown."/media/syncthing" = { + owner = "syncthing"; + group = "syncthing"; + umask = "0022"; + }; + systemd.services."permown._media_syncthing" = { + bindsTo = [ "media.mount" ]; + after = [ "media.mount" ]; + }; + systemd.services."syncthing" = { + bindsTo = [ "media.mount" ]; + after = [ "media.mount" ]; + }; + + backup.dirs = [ "/home/syncthing/finance" ]; + +} diff --git a/nixos/configs/robi/taskserver.nix b/nixos/configs/robi/taskserver.nix new file mode 100644 index 0000000..c3c6e99 --- /dev/null +++ b/nixos/configs/robi/taskserver.nix @@ -0,0 +1,16 @@ +{ config, lib, pkgs, ... }: { + + services.taskserver = { + enable = true; + fqdn = "taskd.ingolf-wagner.de"; + listenHost = "0.0.0.0"; + requestLimit = 104857600; + trust = "strict"; + dataDir = "/var/lib/taskserver"; + organisations."1337".users = [ "palo" "beta" ]; + ciphers = "SECURE256"; + }; + + backup.dirs = [ config.services.taskserver.dataDir ]; + +} diff --git a/nixos/configs/robi/tinc.nix b/nixos/configs/robi/tinc.nix new file mode 100644 index 0000000..e4e99cb --- /dev/null +++ b/nixos/configs/robi/tinc.nix @@ -0,0 +1,14 @@ +{ config, lib, pkgs, ... }: { + + module.cluster.services.tinc = { + "private" = { + enable = true; + openPort = true; + connectTo = [ ]; + }; + }; + + #sops.secrets.tinc_retiolum_ed25519_key = { }; + #sops.secrets.tinc_retiolum_rsa_key = { }; + +} diff --git a/nixos/configs/robi/transmission.nix b/nixos/configs/robi/transmission.nix new file mode 100644 index 0000000..83031de --- /dev/null +++ b/nixos/configs/robi/transmission.nix @@ -0,0 +1,285 @@ +{ pkgs, config, ... }: +let + + hostAddress = "192.168.100.30"; + containerAddress = "192.168.100.31"; + +in +{ + + #users.users.transmission = { + # isSystemUser = true; + # uid = config.ids.uids.transmission; + #}; + + sops.secrets.nordvpn = { }; + + containers.torrent = { + + # mount host folders + bindMounts = { + #password = { + # hostPath = "/run/secrets/transmission_password"; + # mountPoint = "/run/secrets/transmission_password"; + # isReadOnly = true; + #}; + nordvpnPassword = { + hostPath = "/run/secrets/nordvpn"; + mountPoint = "/run/secrets/nordvpn"; + isReadOnly = true; + }; + home = { + hostPath = "/home/torrent"; + mountPoint = "/home/torrent"; + isReadOnly = false; + }; + media = { + hostPath = "/media"; + mountPoint = + "/home/torrent/downloads/media"; # must be here otherwise transmission can't see the folder + isReadOnly = false; + }; + lib = { + hostPath = "/home/torrent/.config"; + mountPoint = "/var/lib/transmission/.config"; + isReadOnly = false; + }; + }; + + # container network setup + # see also nating on host system. + privateNetwork = true; + hostAddress = hostAddress; + localAddress = containerAddress; + autoStart = true; + # needed for openvpn + enableTun = true; + + config = { config, pkgs, lib, ... }: { + + services.journalbeat = { + enable = true; + extraConfig = '' + journalbeat.inputs: + - paths: [] + # Position to start reading from journal. Valid values: head, tail, cursor + seek: cursor + # Fallback position if no cursor data is available. + cursor_seek_fallback: tail + output.logstash: + # Boolean flag to enable or disable the output module. + enabled: true + # Graylog host and the beats input + hosts: ["${hostAddress}:5044"] + + # If enabled only a subset of events in a batch of events is transferred per + # transaction. The number of events to be sent increases up to `bulk_max_size` + # if no error is encountered. + slow_start: true + + # The number of seconds to wait before trying to reconnect to Graylog + # after a network error. After waiting backoff.init seconds, the Beat + # tries to reconnect. If the attempt fails, the backoff timer is increased + # exponentially up to backoff.max. After a successful connection, the backoff + # timer is reset. The default is 1s. + backoff.init: 1s + + # The maximum number of seconds to wait before attempting to connect to + # Graylog after a network error. The default is 60s. + backoff.max: 60s + ''; + }; + + services.journald.extraConfig = "SystemMaxUse=1G"; + + services.transmission = { + enable = true; + settings = { + download-dir = "/home/torrent/downloads"; + incomplete-dir = "/home/torrent/incomplete"; + incomplete-dir-enabled = true; + message-level = 1; + umask = "002"; + rpc-whitelist-enabled = false; + rpc-host-whitelist-enabled = false; + rpc-port = 9091; + rpc-enable = true; + rpc-bind-address = "0.0.0.0"; + + # "normal" speed limits + speed-limit-down-enabled = false; + speed-limit-down = 800; + speed-limit-up-enabled = true; + speed-limit-up = 50; + upload-slots-per-torrent = 8; + # Queuing + # When true, Transmission will only download + # download-queue-size non-stalled torrents at once. + download-queue-enabled = true; + download-queue-size = 3; + + # When true, torrents that have not shared data for + # queue-stalled-minutes are treated as 'stalled' + # and are not counted against the queue-download-size + # and seed-queue-size limits. + queue-stalled-enabled = true; + queue-stalled-minutes = 60; + + # When true. Transmission will only seed seed-queue-size + # non-stalled torrents at once. + seed-queue-enabled = false; + seed-queue-size = 10; + + # Enable UPnP or NAT-PMP. + peer-port = 51413; + port-forwarding-enabled = false; + # Start torrents as soon as they are added + + start-added-torrents = true; + + # notify me when download finished + script-torrent-done-enabled = true; + #script-torrent-done-filename = + # (pkgs.writers.writeBash "torrent-finished" '' + # JSON_STRING=$( ${pkgs.jq}/bin/jq -n --arg torrent_name "$TR_TORRENT_NAME" \ + # '{text: ":tada: finished : \($torrent_name)", channel: "torrent"}' ) + # ${pkgs.curl}/bin/curl \ + # --include \ + # --request POST \ + # --data-urlencode \ + # "payload=$JSON_STRING" \ + # + # ''); + + }; + }; + + networking.firewall = { + allowedTCPPorts = [ 51413 ]; + allowedUDPPorts = [ 51413 ]; + interfaces.eth0 = { + allowedTCPPorts = [ 9091 ]; + allowedUDPPorts = [ 9091 ]; + }; + }; + + # bind transmission to openvpn + systemd.services.transmission = { + bindsTo = [ "openvpn-nordvpn.service" ]; + after = [ "openvpn-nordvpn.service" ]; + serviceConfig.Restart = "always"; + }; + services.openvpn.servers.nordvpn.updateResolvConf = true; + services.openvpn.servers.nordvpn.config = '' + client + dev tun + proto udp + remote 152.89.163.99 1194 + dhcp-option DNS 8.8.8.8 + remote-random + nobind + tun-mtu 1500 + tun-mtu-extra 32 + mssfix 1450 + persist-key + persist-tun + ping 15 + ping-restart 0 + ping-timer-rem + reneg-sec 0 + comp-lzo no + + remote-cert-tls server + + auth-user-pass /run/secrets/nordvpn + + verb 3 + pull + resolv-retry infinite + fast-io + cipher AES-256-CBC + auth SHA512 + + + -----BEGIN CERTIFICATE----- + MIIFCjCCAvKgAwIBAgIBATANBgkqhkiG9w0BAQ0FADA5MQswCQYDVQQGEwJQQTEQ + MA4GA1UEChMHTm9yZFZQTjEYMBYGA1UEAxMPTm9yZFZQTiBSb290IENBMB4XDTE2 + MDEwMTAwMDAwMFoXDTM1MTIzMTIzNTk1OVowOTELMAkGA1UEBhMCUEExEDAOBgNV + BAoTB05vcmRWUE4xGDAWBgNVBAMTD05vcmRWUE4gUm9vdCBDQTCCAiIwDQYJKoZI + hvcNAQEBBQADggIPADCCAgoCggIBAMkr/BYhyo0F2upsIMXwC6QvkZps3NN2/eQF + kfQIS1gql0aejsKsEnmY0Kaon8uZCTXPsRH1gQNgg5D2gixdd1mJUvV3dE3y9FJr + XMoDkXdCGBodvKJyU6lcfEVF6/UxHcbBguZK9UtRHS9eJYm3rpL/5huQMCppX7kU + eQ8dpCwd3iKITqwd1ZudDqsWaU0vqzC2H55IyaZ/5/TnCk31Q1UP6BksbbuRcwOV + skEDsm6YoWDnn/IIzGOYnFJRzQH5jTz3j1QBvRIuQuBuvUkfhx1FEwhwZigrcxXu + MP+QgM54kezgziJUaZcOM2zF3lvrwMvXDMfNeIoJABv9ljw969xQ8czQCU5lMVmA + 37ltv5Ec9U5hZuwk/9QO1Z+d/r6Jx0mlurS8gnCAKJgwa3kyZw6e4FZ8mYL4vpRR + hPdvRTWCMJkeB4yBHyhxUmTRgJHm6YR3D6hcFAc9cQcTEl/I60tMdz33G6m0O42s + Qt/+AR3YCY/RusWVBJB/qNS94EtNtj8iaebCQW1jHAhvGmFILVR9lzD0EzWKHkvy + WEjmUVRgCDd6Ne3eFRNS73gdv/C3l5boYySeu4exkEYVxVRn8DhCxs0MnkMHWFK6 + MyzXCCn+JnWFDYPfDKHvpff/kLDobtPBf+Lbch5wQy9quY27xaj0XwLyjOltpiST + LWae/Q4vAgMBAAGjHTAbMAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQDAgEGMA0GCSqG + SIb3DQEBDQUAA4ICAQC9fUL2sZPxIN2mD32VeNySTgZlCEdVmlq471o/bDMP4B8g + nQesFRtXY2ZCjs50Jm73B2LViL9qlREmI6vE5IC8IsRBJSV4ce1WYxyXro5rmVg/ + k6a10rlsbK/eg//GHoJxDdXDOokLUSnxt7gk3QKpX6eCdh67p0PuWm/7WUJQxH2S + DxsT9vB/iZriTIEe/ILoOQF0Aqp7AgNCcLcLAmbxXQkXYCCSB35Vp06u+eTWjG0/ + pyS5V14stGtw+fA0DJp5ZJV4eqJ5LqxMlYvEZ/qKTEdoCeaXv2QEmN6dVqjDoTAo + k0t5u4YRXzEVCfXAC3ocplNdtCA72wjFJcSbfif4BSC8bDACTXtnPC7nD0VndZLp + +RiNLeiENhk0oTC+UVdSc+n2nJOzkCK0vYu0Ads4JGIB7g8IB3z2t9ICmsWrgnhd + NdcOe15BincrGA8avQ1cWXsfIKEjbrnEuEk9b5jel6NfHtPKoHc9mDpRdNPISeVa + wDBM1mJChneHt59Nh8Gah74+TM1jBsw4fhJPvoc7Atcg740JErb904mZfkIEmojC + VPhBHVQ9LHBAdM8qFI2kRK0IynOmAZhexlP/aT/kpEsEPyaZQlnBn3An1CRz8h0S + PApL8PytggYKeQmRhl499+6jLxcZ2IegLfqq41dzIjwHwTMplg+1pKIOVojpWA== + -----END CERTIFICATE----- + + key-direction 1 + + # + # 2048 bit OpenVPN static key + # + -----BEGIN OpenVPN Static key V1----- + e685bdaf659a25a200e2b9e39e51ff03 + 0fc72cf1ce07232bd8b2be5e6c670143 + f51e937e670eee09d4f2ea5a6e4e6996 + 5db852c275351b86fc4ca892d78ae002 + d6f70d029bd79c4d1c26cf14e9588033 + cf639f8a74809f29f72b9d58f9b8f5fe + fc7938eade40e9fed6cb92184abb2cc1 + 0eb1a296df243b251df0643d53724cdb + 5a92a1d6cb817804c4a9319b57d53be5 + 80815bcfcb2df55018cc83fc43bc7ff8 + 2d51f9b88364776ee9d12fc85cc7ea5b + 9741c4f598c485316db066d52db4540e + 212e1518a9bd4828219e24b20d88f598 + a196c9de96012090e333519ae18d3509 + 9427e7b372d348d352dc4c85e18cd4b9 + 3f8a56ddb2e64eb67adfc9b337157ff4 + -----END OpenVPN Static key V1----- + + ''; + + }; + }; + + # give containers internet access + networking.nat.enable = true; + networking.nat.internalInterfaces = [ "ve-torrent" ]; + networking.nat.externalInterface = "enp2s0f1"; + + # open ports for logging + networking.firewall.interfaces."ve-torrent".allowedTCPPorts = + [ 5044 12304 12305 ]; + networking.firewall.interfaces."ve-torrent".allowedUDPPorts = + [ 5044 12304 12305 ]; + + # host nginx setup + services.nginx = { + enable = true; + recommendedProxySettings = true; + virtualHosts = { + "transmission.workhorse.private" = { + locations."/" = { proxyPass = "http://${containerAddress}:9091"; }; + }; + }; + }; + +} diff --git a/nixos/configs/robi/weechat.nix b/nixos/configs/robi/weechat.nix new file mode 100644 index 0000000..f008033 --- /dev/null +++ b/nixos/configs/robi/weechat.nix @@ -0,0 +1,38 @@ +{ config, pkgs, lib, ... }: + +# how to setup a relay +# * ssh on the maching +# * sudo -u weechat screen -r +# /set relay.network.password "mypassword" +# /relay add weechat 10000 + +{ + + # configure weechat + services.weechat = { enable = true; }; + + # configure bitlbee + services.bitlbee = { + enable = true; + libpurple_plugins = [ + #pkgs.pidgin-otr + #pkgs.purple-facebook + #pkgs.purple-discord + #pkgs.purple-matrix + #pkgs.purple-hangouts + #pkgs.pidgin-latex + #pkgs.pidgin-opensteamworks + #pkgs.pidgin-skypeweb + pkgs.telegram-purple + #pkgs.purple-lurch + ]; + plugins = + [ pkgs.bitlbee-facebook pkgs.bitlbee-steam pkgs.bitlbee-mastodon ]; + }; + + # otherwise xterm is the only thing that works + environment.systemPackages = [ pkgs.rxvt_unicode ]; + + backup.dirs = [ config.services.weechat.root ]; + +} diff --git a/nixos/configs/sterni/tinc.nix b/nixos/configs/sterni/tinc.nix index 0b0c31f..4161fc2 100644 --- a/nixos/configs/sterni/tinc.nix +++ b/nixos/configs/sterni/tinc.nix @@ -8,7 +8,7 @@ with lib; "private" = { enable = true; openPort = true; - connectTo = [ "sputnik" ]; + connectTo = [ "sputnik" "robi" ]; }; "retiolum" = { enable = true; diff --git a/nixos/configs/workhorse/configuration.nix b/nixos/configs/workhorse/configuration.nix index e6a3cb9..cb2c257 100644 --- a/nixos/configs/workhorse/configuration.nix +++ b/nixos/configs/workhorse/configuration.nix @@ -5,7 +5,7 @@ ./hardware-configuration.nix ./mail-fetcher.nix - ./transmission.nix + #./transmission.nix ./nextcloud.nix ./borg.nix @@ -14,7 +14,7 @@ ./grafana.nix ./graylog.nix ./jenkins.nix - ./kibana.nix + #./kibana.nix ./mysql.nix ./packages.nix ./prometheus.nix diff --git a/nixos/flake.nix b/nixos/flake.nix index 63bed89..7d6c279 100644 --- a/nixos/flake.nix +++ b/nixos/flake.nix @@ -106,6 +106,7 @@ pepe = serverConfiguration ./configs/pepe/configuration.nix; workhorse = serverConfiguration ./configs/workhorse/configuration.nix; sputnik = serverConfiguration ./configs/sputnik/configuration.nix; + robi = serverConfiguration ./configs/robi/configuration.nix; }; }; } diff --git a/nixos/krops.nix b/nixos/krops.nix index 106b82e..744bbbb 100644 --- a/nixos/krops.nix +++ b/nixos/krops.nix @@ -120,4 +120,8 @@ in (server { name = "sputnik"; host = "sputnik.private"; +}) // +(server { + name = "robi"; + host = "robi"; }) diff --git a/nixos/system/all/default.nix b/nixos/system/all/default.nix index 93c073b..dc0aa25 100644 --- a/nixos/system/all/default.nix +++ b/nixos/system/all/default.nix @@ -4,6 +4,8 @@ ../../modules + ./defaults.nix + # needed # @@ -28,45 +30,10 @@ ]; - # how much configurations should be kept? - boot.loader.systemd-boot.configurationLimit = lib.mkDefault 5; # default backup excludes backup.exclude = [ ".git" ".stfolder" ".stversions" ]; - # provide overlays - # ----------------- - nixpkgs.overlays = [ (import ../../pkgs) ]; - - # allow un-free - # ------------- - nixpkgs.config.allowUnfree = true; - environment.variables.NIXPKGS_ALLOW_UNFREE = "1"; - - # some system stuff - # ----------------- - time.timeZone = lib.mkDefault "Europe/Berlin"; - #time.timeZone = lib.mkDefault "Pacific/Auckland"; - #time.timeZone = lib.mkDefault "Asia/Singapore"; - #time.timeZone = lib.mkDefault "Asia/Makassar"; - - # keyboard fiddling - i18n.defaultLocale = lib.mkDefault "en_US.UTF-8"; - console.font = "Lat2-Terminus16"; - console.keyMap = lib.mkDefault "us"; - services.xserver.layout = lib.mkDefault "us"; - - # swappiness - # ---------- - # 0 = only when running out of RAM - # 100 = always swapp - boot.kernel.sysctl."vm.swappiness" = 0; - - # rewire NIX_PATH - # --------------- - #environment.variables.NIX_PATH = lib.mkForce "/var/src"; - nix.nixPath = [ "nixpkgs=${pkgs.path}" ]; - # Shell configuration # ------------------- programs.custom = { @@ -74,18 +41,10 @@ zsh.enable = true; }; - # Machines should be fast by default - # ---------------------------------- - powerManagement.cpuFreqGovernor = lib.mkDefault "ondemand"; - - # set vim to the default editor - # ----------------------------- - programs.vim.defaultEditor = true; - # This value determines the NixOS release with which your system is to be # compatible, in order to avoid breaking some software such as database # servers. You should change this only after NixOS release notes say you # should. - system.stateVersion = "19.03"; # Did you read the comment? + system.stateVersion = lib.mkDefault "19.03"; # Did you read the comment? } diff --git a/nixos/system/all/defaults.nix b/nixos/system/all/defaults.nix new file mode 100644 index 0000000..3e0953c --- /dev/null +++ b/nixos/system/all/defaults.nix @@ -0,0 +1,48 @@ +{ config, lib, pkgs, ... }: +{ + + # provide overlays + # ----------------- + nixpkgs.overlays = [ (import ../../pkgs) ]; + + # allow un-free + # ------------- + nixpkgs.config.allowUnfree = true; + environment.variables.NIXPKGS_ALLOW_UNFREE = "1"; + + # some system stuff + # ----------------- + time.timeZone = lib.mkDefault "Europe/Berlin"; + #time.timeZone = lib.mkDefault "Pacific/Auckland"; + #time.timeZone = lib.mkDefault "Asia/Singapore"; + #time.timeZone = lib.mkDefault "Asia/Makassar"; + + # keyboard fiddling + i18n.defaultLocale = lib.mkDefault "en_US.UTF-8"; + console.font = "Lat2-Terminus16"; + console.keyMap = lib.mkDefault "us"; + services.xserver.layout = lib.mkDefault "us"; + + # swappiness + # ---------- + # 0 = only when running out of RAM + # 100 = always swapp + boot.kernel.sysctl."vm.swappiness" = 0; + + # rewire NIX_PATH + # --------------- + #environment.variables.NIX_PATH = lib.mkForce "/var/src"; + nix.nixPath = [ "nixpkgs=${pkgs.path}" ]; + + # how much configurations should be kept? + boot.loader.systemd-boot.configurationLimit = lib.mkDefault 5; + + # Machines should be fast by default + # ---------------------------------- + powerManagement.cpuFreqGovernor = lib.mkDefault "ondemand"; + + # set vim to the default editor + # ----------------------------- + programs.vim.defaultEditor = true; + +} diff --git a/nixos/system/all/hosts.nix b/nixos/system/all/hosts.nix index eeb2c9a..20e0c02 100644 --- a/nixos/system/all/hosts.nix +++ b/nixos/system/all/hosts.nix @@ -1,5 +1,6 @@ { networking.extraHosts = '' 192.168.0.24 scanner + 144.76.13.147 robi ''; } diff --git a/nixos/system/all/sshd-known-hosts-private.nix b/nixos/system/all/sshd-known-hosts-private.nix index f5f6154..81e63ce 100644 --- a/nixos/system/all/sshd-known-hosts-private.nix +++ b/nixos/system/all/sshd-known-hosts-private.nix @@ -2,13 +2,19 @@ { config, lib, ... }: { services.openssh.knownHosts = { + "robi" = { + hostNames = [ + "robi" + "144.76.13.147" + ]; + publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK2PGX6cZuBUGX4VweMzi0aRh4uQ61yngCzZGcK3w5XV"; + }; "sternchen.secret" = { hostNames = [ "sternchen.secret" config.module.cluster.services.tinc.secret.hosts.sternchen.tincIp ]; - publicKey = - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILriD/0+65L1mkbjKENwpvB3wUMXz/rEf9J8wuJjJa0q"; + publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILriD/0+65L1mkbjKENwpvB3wUMXz/rEf9J8wuJjJa0q"; }; "sterni.private" = { hostNames = [ @@ -17,8 +23,7 @@ config.module.cluster.services.tinc.private.hosts.sterni.tincIp config.module.cluster.services.tinc.secret.hosts.sterni.tincIp ]; - publicKey = - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDyHmHJy2Va45p9mn+Hj3DyaY5yxnQIKvXeACHjzgSKt"; + publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDyHmHJy2Va45p9mn+Hj3DyaY5yxnQIKvXeACHjzgSKt"; }; "workout.private" = { hostNames = [ @@ -26,8 +31,7 @@ "workout.lan" config.module.cluster.services.tinc.private.hosts.workout.tincIp ]; - publicKey = - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICjotuQJHDaL0fPY7yA2dIBVWRYOkp7/ablY60psMQ6w"; + publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICjotuQJHDaL0fPY7yA2dIBVWRYOkp7/ablY60psMQ6w"; }; "sputnik.private" = { hostNames = [ diff --git a/nixos/system/all/tinc.nix b/nixos/system/all/tinc.nix index 2a25e91..2365026 100644 --- a/nixos/system/all/tinc.nix +++ b/nixos/system/all/tinc.nix @@ -86,8 +86,7 @@ in extraConfig = '' LocalDiscovery = yes ''; - privateEd25519KeyFile = - toString config.sops.secrets.tinc_ed25519_key.path; + privateEd25519KeyFile = toString config.sops.secrets.tinc_ed25519_key.path; privateRsaKeyFile = toString config.sops.secrets.tinc_rsa_key.path; hosts = { workout = { @@ -114,6 +113,11 @@ in tincIp = "10.23.42.21"; publicKey = lib.fileContents ../../assets/tinc/workhorse_host_file; }; + robi = { + realAddress = ["144.76.13.147"]; + tincIp = "10.23.42.111"; + publicKey = lib.fileContents ../../assets/tinc/robi_host_file; + }; sputnik = { realAddress = [ "195.201.134.247" diff --git a/nixos/system/desktop/wtf.nix b/nixos/system/desktop/wtf.nix index c2a1b3a..7aa6ebd 100644 --- a/nixos/system/desktop/wtf.nix +++ b/nixos/system/desktop/wtf.nix @@ -351,7 +351,7 @@ let left = 1; height = 1; width = 3; - refreshInterval = 60; + refreshInterval = 7; }; uptime = cmdRunner {