{ config, lib, pkgs, ... }: { imports = [ ../common.nix ./hardware-configuration.nix ]; boot.kernelParams = [ "consoleblank=60" #TPM fix "memmap=0x4000%0xbfb76000-4" "memmap=0x4000%0xbfb7a000-4" ]; users = { groups = { php.gid = 1568; vmail.gid = 1819; }; users = { nginx.extraGroups = [ "acme" ]; dovecot2.extraGroups = [ "secrets" ]; root.openssh.authorizedKeys.keys = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB+wc+3rahpNa+OMS9gaWgMQIxXIKHy4Beku5LBDt+Ow" ]; php = { uid = 1568; group = "php"; isSystemUser = true; }; vmail = { uid = 1819; group = "vmail"; isSystemUser = true; }; }; }; networking = { hostName = "nixos-server"; firewall = { allowedTCPPorts = [ 25 443 587 993 ]; allowedUDPPorts = [ 443 ]; }; networkmanager.ensureProfiles.profiles.home-wifi = { wifi.ssid = "bogale_2.4"; wifi-security.psk = "$BOGALE_2_4_PSK"; ipv4 = { method = "manual"; gateway = "10.1.0.1"; addresses = "10.1.0.2/16"; }; ipv6 = { method = "manual"; gateway = "fc01::1"; addresses = "fc01::2/64"; }; }; }; security.acme = { acceptTerms = true; defaults.email = "letsencrypt@bogaledev.ru"; certs."bogaledev.ru" = { validMinDays = 3; dnsProvider = "cloudflare"; extraDomainNames = [ "*.bogaledev.ru" ]; credentialFiles = { "CF_DNS_API_TOKEN_FILE" = "/secrets/cf-token"; }; reloadServices = [ "nginx.service" "dovecot.service" "postfix.service" ]; }; }; systemd = { tmpfiles.rules = [ "d /var/spool/postfix 0755 postfix postfix -" "d /var/spool/postfix/private 0755 postfix postfix -" ]; timers = { tgbot-send = { wantedBy = [ "timers.target" ]; timerConfig = { OnCalendar = "*-*-01 16:00:00"; Persistent = true; }; }; network-watchdog = { wantedBy = [ "timers.target" ]; timerConfig = { OnBootSec = 30; AccuracySec = 1; OnUnitActiveSec = 10; }; }; }; services = { tgbot-send = { serviceConfig.Type = "oneshot"; script = '' . /secrets/tgbot.env ${pkgs.curl}/bin/curl "https://api.telegram.org/$BOT/sendMessage" \ -X POST -d "chat_id=$CHAT_ID" -d "text=$TEXT" 2> /dev/null | \ ${pkgs.jq}/bin/jq '.result.date |= strftime("%Y-%m-%d %H:%M:%S")' ''; }; network-watchdog = { serviceConfig = { Type = "oneshot"; LogLevelMax = "notice"; }; script = '' if [ ! -e /run/network.failures ] || \ ${pkgs.iputils}/bin/ping -c 1 -W 3 1.1.1.1 &> /dev/null; then failures=0 else failures=$((1+$(cat /run/network.failures))) fi if [ $failures -gt 0 ]; then echo "<5>failures = $failures" fi if [ $failures -ge 3 ]; then echo "<4>restarting NetworkManager" systemctl restart NetworkManager.service failures=0 fi echo $failures > /run/network.failures ''; }; }; }; services = let mailBase = "/var/spool/mail/vmail"; saslSocket = "/var/spool/postfix/private/auth"; sslCertDir = config.security.acme.certs."bogaledev.ru".directory; in { openssh = { enable = true; settings.PasswordAuthentication = false; }; postgresql.enable = true; forgejo = { enable = true; database.type = "postgres"; settings = { service.DISABLE_REGISTRATION = true; server = { HTTP_PORT = 8039; ROOT_URL = "https://bogaledev.ru/git/"; }; }; }; phpfpm.pools.default = { user = "php"; group = "php"; settings = { "pm" = "ondemand"; "pm.max_children" = 8; "listen.owner" = "nginx"; "listen.group" = "nginx"; }; }; vaultwarden = { enable = true; dbBackend = "postgresql"; configurePostgres = true; package = pkgs.vaultwarden-postgresql; environmentFile = "/secrets/vw-token.env"; config = { ROCKET_PORT = 8032; SIGNUPS_ALLOWED = false; TRASH_AUTO_DELETE_DAYS = 90; PASSWORD_HINTS_ALLOWED = false; EMERGENCY_ACCESS_ALLOWED = false; DOMAIN = "https://bogaledev.ru/vw/"; }; }; nginx.virtualHosts."bogaledev.ru" = let phpPool = pool: '' location ~ \.php$ { fastcgi_pass unix:${config.services.phpfpm.pools.${pool}.socket}; } ''; localNetworks = '' allow fc00::/64; allow fc01::/64; allow fc02::/64; allow 10.0.0.0/16; allow 10.1.0.0/16; allow 10.2.0.0/16; deny all; ''; in { quic = true; default = true; forceSSL = true; root = "/srv/http"; useACMEHost = "bogaledev.ru"; extraConfig = ''add_header Alt-Svc 'h3=":443"; ma=86400' always;''; locations = { "/app/".extraConfig = phpPool "default"; "/git/".proxyPass = "http://127.0.0.1:8039/"; "/priv/".extraConfig = ''${localNetworks} ${phpPool "default"}''; "/vw/" = { proxyWebsockets = true; extraConfig = localNetworks; proxyPass = "http://127.0.0.1:8032"; }; }; }; redis.servers.rspamd = { enable = true; user = "rspamd"; }; rspamd = { enable = true; postfix.enable = true; locals = { "classifier-bayes.conf".text = "autolearn = true;"; "redis.conf".text = '' servers = "${config.services.redis.servers.rspamd.unixSocket}"; ''; }; }; dovecot2 = { enable = true; settings = { ssl = "required"; mail_gid = "vmail"; mail_uid = "vmail"; mail_path = mailBase; protocols.imap = true; mail_driver = "maildir"; auth_mechanisms = [ "plain" ]; dovecot_config_version = "2.4.5"; dovecot_storage_version = "2.4.5"; ssl_server_key_file = "${sslCertDir}/key.pem"; ssl_server_cert_file = "${sslCertDir}/fullchain.pem"; "passdb passwd-file".passwd_file_path = "/secrets/dovecot-pw"; "service auth"."unix_listener ${saslSocket}" = { mode = "0660"; user = "postfix"; group = "postfix"; }; }; }; postfix = { enable = true; enableSubmission = true; virtualMapType = "regexp"; virtual = "/.*@bogaledev.ru/ mail@bogaledev.ru"; mapFiles = { smtp_passwd = "/secrets/smtp_passwd"; mailbox = pkgs.writeText "mailbox" "mail@bogaledev.ru /"; }; settings.main = { smtpd_sasl_type = "dovecot"; smtpd_sasl_path = saslSocket; smtp_sasl_auth_enable = "yes"; smtpd_sasl_auth_enable = "yes"; virtual_mailbox_base = mailBase; virtual_uid_maps = "static:1819"; virtual_gid_maps = "static:1819"; smtp_tls_security_level = "encrypt"; smtpd_tls_security_level = "encrypt"; relayhost = [ "smtp.resend.com:2587" ]; virtual_mailbox_domains = "bogaledev.ru"; smtp_sasl_tls_security_options = "noanonymous"; virtual_mailbox_maps = "hash:/etc/postfix/mailbox"; smtp_sasl_password_maps = "hash:/etc/postfix/smtp_passwd"; smtpd_tls_chain_files = [ "${sslCertDir}/key.pem" "${sslCertDir}/fullchain.pem" ]; }; }; }; }