{ config, lib, pkgs, ... }: with lib; let domaine = "nyanlout.re"; riot_port = 52345; pgmanage_port = 52347; max_port = 52348; musique_port = 52349; factorio_port = 52351; airsonic_port = 4040; wkd_port = 52352; jellyfin_backend = '' http-request set-header X-Forwarded-Port %[dst_port] http-request add-header X-Forwarded-Proto https if { ssl_fc } ''; sonarr_acl = '' acl API path_beg /api ''; sonarr_auth = '' !AUTH_OK !API ''; sendMail = to: subject: message: pkgs.writeShellScriptBin "mail.sh" '' ${pkgs.system-sendmail}/bin/sendmail ${to} <<EOF From: root@nyanlout.re Subject: ${subject} ${message} EOF ''; login_mail_alert = pkgs.writeShellScriptBin "mail_alert.sh" '' if [ "$PAM_TYPE" != "close_session" ]; then ${sendMail "paul@nyanlout.re" "SSH Login: $PAM_USER from $PAM_RHOST" "`env`"}/bin/mail.sh fi ''; backup_mail_alert = sendMail "paul@nyanlout.re" "ERREUR: Sauvegarde Borg" "Impossible de terminer la sauvegarde. Merci de voir les logs"; in { imports = [ ../../services/haproxy-acme.nix ../../services/mail-server.nix ../../services/site-musique.nix ../../services/site-max.nix ../../services/auto-pr.nix ../../services/python-ci.nix ../../services/sdtdserver.nix ../../containers/vsftpd.nix /mnt/secrets/factorio_secrets.nix ]; nixpkgs.overlays = [ (import ../../overlays/dogetipbot-telegram.nix) ]; services = { fail2ban.enable = true; smartd = { enable = true; defaults.monitored = "-a -o on -s (S/../.././02|L/../../1/04)"; notifications.mail = { enable = true; recipient = "paul@nyanlout.re"; }; }; fstrim.enable = true; haproxy-acme = { enable = true; domaine = domaine; services = { "grafana.${domaine}" = { ip = "127.0.0.1"; port = 3000; auth = true; }; "emby.${domaine}" = { ip = "127.0.0.1"; port = 8096; auth = false; extraBackend = jellyfin_backend; }; "radarr.${domaine}" = { ip = "127.0.0.1"; port = 7878; auth = true; extraAcls = sonarr_acl; aclBool = sonarr_auth; }; "sonarr.${domaine}" = { ip = "127.0.0.1"; port = 8989; auth = true; extraAcls = sonarr_acl; aclBool = sonarr_auth; }; "transmission.${domaine}" = { ip = "127.0.0.1"; port = 9091; auth = true; }; "syncthing.${domaine}" = { ip = "127.0.0.1"; port = 8384; auth = true; }; "jackett.${domaine}" = { ip = "127.0.0.1"; port = 9117; auth = true; }; "searx.${domaine}" = { ip = "127.0.0.1"; port = 8888; auth = false; }; "riot.${domaine}" = { ip = "127.0.0.1"; port = riot_port; auth = false; }; "matrix.${domaine}" = { ip = "127.0.0.1"; port = 8008; auth = false; }; "pgmanage.${domaine}" = { ip = "127.0.0.1"; port = pgmanage_port; auth = true; }; "gitea.${domaine}" = { ip = "127.0.0.1"; port = 3001; auth = false; }; "ci.${domaine}" = { ip = "127.0.0.1"; port = 52350; auth = false; }; "factorio.${domaine}" = { ip = "127.0.0.1"; port = factorio_port; auth = false; }; "airsonic.${domaine}" = { ip = "127.0.0.1"; port = airsonic_port; auth = false; }; "${domaine}" = { ip = "127.0.0.1"; port = wkd_port; auth = false; }; }; }; mailserver = { enable = true; domaine = domaine; }; influxdb = { enable = true; dataDir = "/var/db/influxdb"; }; telegraf = { enable = true; extraConfig = { inputs = { zfs = { poolMetrics = true; }; net = { interfaces = [ "eno1" "eno2" "eno3" "eno4" ]; }; netstat = {}; cpu = { totalcpu = true; }; kernel = {}; mem = {}; processes = {}; system = {}; disk = {}; ipmi_sensor = { path = "${pkgs.ipmitool}/bin/ipmitool"; }; smart = { path = "${pkgs.writeShellScriptBin "smartctl" "/run/wrappers/bin/sudo ${pkgs.smartmontools}/bin/smartctl $@"}/bin/smartctl"; }; exec= [ { commands = [ "${pkgs.python}/bin/python ${ pkgs.fetchgit { url = "https://gitlab.com/nyanloutre/tplink-smartplug.git"; rev = "a0996112fc451b76448589698de440ad5fd6ea79"; sha256 = "1f1625g7rfsddgk428g76p8fr7vz5gfhq3f452q17bjni3rf2pj3"; } }/tplink_smartplug.py -t 10.30.50.7 -c energy" ]; data_format = "json"; name_suffix = "_tplink-smartplug"; } { commands = [ "${pkgs.python3}/bin/python ${pkgs.writeText "zpool.py" '' import json from subprocess import check_output columns = ["NAME", "SIZE", "ALLOC", "FREE", "EXPANDSZ", "FRAG", "CAP", "DEDUP", "HEALTH", "ALTROOT"] health = {'ONLINE':0, 'DEGRADED':11, 'OFFLINE':21, 'UNAVAIL':22, 'FAULTED':23, 'REMOVED':24} stdout = check_output(["${pkgs.zfs}/bin/zpool", "list", "-Hp"],encoding='UTF-8').split('\n') parsed_stdout = list(map(lambda x: dict(zip(columns,x.split('\t'))), stdout))[:-1] for pool in parsed_stdout: for item in pool: if item in ["SIZE", "ALLOC", "FREE", "FRAG", "CAP"]: pool[item] = int(pool[item]) if item in ["DEDUP"]: pool[item] = float(pool[item]) if item == "HEALTH": pool[item] = health[pool[item]] print(json.dumps(parsed_stdout)) ''}" ]; tag_keys = [ "NAME" ]; data_format = "json"; name_suffix = "_python_zpool"; } ]; }; outputs = { influxdb = { database = "telegraf"; urls = [ "http://localhost:8086" ]; }; }; }; }; udev.extraRules = '' KERNEL=="ipmi*", MODE="660", OWNER="telegraf" ''; grafana = { enable = true; addr = "127.0.0.1"; dataDir = "/var/lib/grafana"; extraOptions = { SERVER_ROOT_URL = "https://grafana.${domaine}"; SMTP_ENABLED = "true"; SMTP_FROM_ADDRESS = "grafana@${domaine}"; SMTP_SKIP_VERIFY = "true"; AUTH_DISABLE_LOGIN_FORM = "true"; AUTH_DISABLE_SIGNOUT_MENU = "true"; AUTH_ANONYMOUS_ENABLED = "true"; AUTH_ANONYMOUS_ORG_ROLE = "Admin"; AUTH_BASIC_ENABLED = "false"; }; }; jellyfin.enable = true; slimserver = { enable = true; dataDir = "/var/lib/slimserver"; }; syncthing = { enable = true; dataDir = "/var/lib/syncthing"; openDefaultPorts = true; }; nfs.server = { enable = true; exports = '' /mnt/medias 10.30.0.0/16(ro,no_root_squash) /exports/steam 10.30.0.0/16(rw,async,no_root_squash) /var/lib/minecraft 10.30.0.0/16(rw,no_root_squash) ''; statdPort = 4000; lockdPort = 4001; mountdPort = 4002; }; transmission = { enable = true; home = "/var/lib/transmission"; settings = { rpc-bind-address = "127.0.0.1"; rpc-host-whitelist = "*"; rpc-whitelist-enabled = false; }; }; radarr.enable = true; sonarr.enable = true; jackett.enable = true; searx.enable = true; nginx = { enable = true; virtualHosts = { "riot" = { listen = [ { addr = "127.0.0.1"; port = riot_port; } ]; locations = { "/" = { root = pkgs.riot-web; }; }; }; "factorio" = { listen = [ { addr = "127.0.0.1"; port = factorio_port; } ]; locations = { "/" = { root = "/var/www/factorio"; }; }; }; "wkd" = { listen = [ { addr = "127.0.0.1"; port = wkd_port; } ]; locations = { "/.well-known/openpgpkey/" = { alias = "/var/lib/gnupg/wks/nyanlout.re"; extraConfig = '' add_header Access-Control-Allow-Origin * always; ''; }; }; }; }; }; postgresql.enable = true; matrix-synapse = { enable = true; enable_registration = true; server_name = "nyanlout.re"; listeners = [ { # federation bind_address = ""; port = 8448; resources = [ { compress = true; names = [ "client" "webclient" ]; } { compress = false; names = [ "federation" ]; } ]; tls = true; type = "http"; x_forwarded = false; } { # client bind_address = "127.0.0.1"; port = 8008; resources = [ { compress = true; names = [ "client" "webclient" ]; } ]; tls = false; type = "http"; x_forwarded = true; } ]; max_upload_size = "100M"; database_type = "psycopg2"; database_args = { database = "matrix-synapse"; }; tls_private_key_path = "/var/lib/acme/${domaine}/key.pem"; tls_certificate_path = "/var/lib/acme/${domaine}/fullchain.pem"; url_preview_enabled = true; logConfig = '' version: 1 formatters: journal_fmt: format: '%(name)s: [%(request)s] %(message)s' filters: context: (): synapse.util.logcontext.LoggingContextFilter request: "" handlers: journal: class: systemd.journal.JournalHandler formatter: journal_fmt filters: [context] SYSLOG_IDENTIFIER: synapse root: level: WARNING handlers: [journal] disable_existing_loggers: False ''; app_service_config_files = [ "/var/lib/matrix-synapse/mautrix-telegram-registration.yaml" ]; }; mautrix-telegram = { enable = true; settings = { homeserver = { address = "https://matrix.nyanlout.re"; domain = "nyanlout.re"; }; appservice = { bot_username = "loutrebot"; }; bridge = { relaybot.authless_portals = false; permissions = { "@nyanloutre:nyanlout.re" = "admin"; }; }; }; environmentFile = "/mnt/secrets/mautrix-telegram.env"; serviceDependencies = [ "matrix-synapse.service" ]; }; pgmanage = { enable = true; port = pgmanage_port; connections = { localhost = "hostaddr=127.0.0.1 port=5432 dbname=postgres"; }; }; borgbackup.jobs = { loutre = { paths = [ "/var/certs" "/var/dkim" "/var/lib/jellyfin" "/var/lib/gitea" "/var/lib/grafana" "/var/lib/jackett" "/var/lib/matrix-synapse" "/var/lib/postgresql/.zfs/snapshot/borgsnap" "/var/lib/radarr" "/var/lib/sonarr" "/var/lib/syncthing" "/var/lib/transmission" "/mnt/medias/musique" "/mnt/medias/torrent/lidarr" "/mnt/medias/torrent/musique" "/var/sieve" "/var/vmail" ]; repo = "/mnt/backup/borg"; encryption = { mode = "repokey-blake2"; passCommand = "cat /mnt/secrets/borgbackup_loutre_encryption_pass"; }; startAt = "weekly"; prune.keep = { within = "1d"; weekly = 4; monthly = 12; }; preHook = "${pkgs.zfs}/bin/zfs snapshot loutrepool/var/postgresql@borgsnap"; postHook = '' ${pkgs.zfs}/bin/zfs destroy loutrepool/var/postgresql@borgsnap if [[ $exitStatus == 0 ]]; then ${pkgs.rclone}/bin/rclone --config /mnt/secrets/rclone_loutre.conf sync -v $BORG_REPO BackupStorage:loutre else ${backup_mail_alert}/bin/mail.sh fi ''; }; }; borgbackup.repos = { diskstation = { authorizedKeys = [ "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDllbxON66dBju7sMnhX8/E0VRo3+PDYvDsHP0/FK+h8JHol4+pouLmI7KIDKYOJmSuom283OqnyZOMqk+RShTwWIFm9hOd2R9aj45Zrd9jPW2APOCec/Epgogj0bwBnc0l2v6qxkxaBMgL5DnAQ+E00uvL1UQpK8c8j4GGiPlkWJD6Kf+pxmnfH1TIm+J2XCwl0oeCkSK/Frd8eM+wCraMSzoaGiEcfMz2jK8hxDWjDxX7epU0ELF22BVCuyN8cYRoFTnV88E38PlaqsOqD5ePkxk425gDh7j/C06f8QKgnasVH2diixo92kYSd7i/RmfeXDDwAD5xqUvODczEuIdt root@DiskStation" ]; path = "/mnt/backup_loutre/diskstation_borg"; user = "synology"; }; }; gitea = { enable = true; cookieSecure = true; httpPort = 3001; rootUrl = "https://gitea.nyanlout.re/"; database = { type = "postgres"; port = 5432; passwordFile = "/var/lib/gitea/custom/conf/database_password"; }; log.level = "Warn"; extraConfig = '' [ui] DEFAULT_THEME = arc-green [service] DISABLE_REGISTRATION = true ''; }; site-musique = { enable = true; port = musique_port; domaine = "musique-meyenheim.fr"; }; site-max = { enable = true; port = max_port; domaine = "maxspiegel.fr"; }; auto-pr.enable = true; python-ci.enable = true; sdtdserver.enable = false; factorio = { enable = true; autosave-interval = 10; game-name = "Shame"; public = true; username = "nyanloutre"; }; airsonic = { enable = true; maxMemory = 500; }; minecraft-server = { enable = false; jvmOpts = "-Xms512m -Xmx3072m"; eula = true; declarative = true; openFirewall = true; whitelist = { nyanloutre = "db0669ea-e332-4ca3-8d50-f5d1458f5822"; Hautension = "f05677f4-be5a-47df-ad77-21c739180aa2"; LordDarkKiwi = "79290cfc-0b00-484f-9c94-ab0786402de6"; Madahin = "f5f747e3-fac2-43e8-9b9b-a67dc2f368ff"; Hopegcx = "4497f759-2210-48db-8764-307d33011442"; wyrd68 = "127a3021-cdc1-419f-9010-4651df9ae3af"; sparsyateloutre = "d2ff63c1-4e9f-4b21-9bfc-decce5d987b3"; }; serverProperties = { difficulty = 2; gamemode = 0; max-players = 50; motd = "Hi Mark !"; white-list = true; }; }; }; systemd.services.dogetipbot-telegram = { after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; script = "${pkgs.dogetipbot-telegram}/bin/dogetipbot-telegram --block-io-api-key $BLOCK_IO_API_KEY --block-io-pin $BLOCK_IO_PIN --telegram-api-key $TELEGRAM_API_KEY --network DOGE"; enable = true; serviceConfig = { EnvironmentFile = "/mnt/secrets/dogetipbot-telegram_env"; DynamicUser = true; }; }; systemd.services.matrix-synapse = { serviceConfig = { MemoryHigh = "3G"; MemoryMax = "5G"; }; }; users.groups.acme.members = [ "matrix-synapse" ]; security = { sudo.extraRules = [ { commands = [ { command = "${pkgs.smartmontools}/bin/smartctl"; options = [ "NOPASSWD" ]; } ]; users = [ "telegraf" ]; } ]; pam.services.sshd.text = pkgs.lib.mkDefault( pkgs.lib.mkAfter "session optional ${pkgs.pam}/lib/security/pam_exec.so seteuid ${login_mail_alert}/bin/mail_alert.sh" ); }; networking = { wireguard.interfaces = { wg0 = { ips = [ "192.168.20.1/24" ]; privateKeyFile = "/mnt/secrets/wireguard/wg0.privatekey"; listenPort = 51820; allowedIPsAsRoutes = true; peers = [ { allowedIPs = [ "192.168.20.2/32" ]; publicKey = "b/SXiqo+GPdNOc54lyEVeUBc6B5AbVMKh+g5EZPGzlE="; } ]; }; }; nat.internalInterfaces = [ "wg0" ]; nat.internalIPs = [ "192.168.20.0/24" ]; firewall.allowedTCPPorts = [ 51413 # Transmission 8448 # Matrix federation 20 21 # FTP ]; firewall.allowedTCPPortRanges = [ { from = 64000; to = 65535; } # FTP ]; firewall.allowedUDPPorts = [ 51413 # Transmission 51820 # Wireguard ]; }; }