From e1b05d65451cce58205a2c4b3d84f706b04fb17e Mon Sep 17 00:00:00 2001 From: John Bargman Date: Sat, 30 Nov 2024 13:15:05 +0000 Subject: reorg and update; add cgit --- services/cgit.nix | 103 ++++++++++++++++++++ services/ejabberd.nix | 243 ++++++++++++++++++++++++++++++++++++++++++++++++ services/mailserver.nix | 17 ++++ services/website.nix | 14 +++ 4 files changed, 377 insertions(+) create mode 100644 services/cgit.nix create mode 100644 services/ejabberd.nix create mode 100644 services/mailserver.nix create mode 100644 services/website.nix (limited to 'services') diff --git a/services/cgit.nix b/services/cgit.nix new file mode 100644 index 0000000..a7795ac --- /dev/null +++ b/services/cgit.nix @@ -0,0 +1,103 @@ +{ pkgs, fqdn, ... }: +{ + services.uwsgi = { + enable = true; + user = "public"; + group = "users"; + plugins = [ "cgi" ]; + + instance = { + type = "emperor"; + vassals = { + cgit = { + type = "normal"; + master = "true"; + socket = "/run/uwsgi/cgit.sock"; + procname-master = "uwsgi cgit"; + plugins = [ "cgi" ]; + cgi = "${pkgs.cgit}/cgit/cgit.cgi"; + }; + }; + }; + }; + + services.gitolite = { + enable = true; + user = "git"; + group = "git"; + adminPubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILhzz/CAb74rLQkDF2weTCb0DICw1oyXNv6XmdLfEsT5 crash@crashoverburn.com"; + extraGitoliteRc = '' + $RC{UMASK} = 0027; + $RC{GIT_CONFIG_KEYS} = '.*'; + ''; + }; + + users.extraUsers.public = + { + isSystemUser = true; + group = "git"; + }; + + services.nginx.virtualHosts."code.${fqdn}" = { + addSSL = true; + enableACME = true; + root = "${pkgs.cgit}/cgit"; + locations = { + "/" = { + extraConfig = '' + try_files $uri @cgit; + ''; + }; + "@cgit" = { + extraConfig = '' + uwsgi_pass unix:/run/uwsgi/cgit.sock; + include ${pkgs.nginx}/conf/uwsgi_params; + uwsgi_modifier1 9; + ''; + }; + }; + }; + + systemd.services.create-cgit-cache = { + description = "Create cache directory for cgit"; + enable = true; + wantedBy = [ "uwsgi.service" ]; + serviceConfig = { + type = "oneshot"; + }; + script = '' + mkdir /run/cgit + chown -R public:users /run/cgit + ''; + }; + + environment.etc."cgitrc".text = '' + virtual-root=/ + + cache-size=1000 + cache-root=/run/cgit + + root-title=~/projects + root-desc=code.${fqdn} + footer= + + enable-index-owner=0 + enable-http-clone=1 + noplainemail=1 + + max-atom-items=50 + + enable-git-config=1 + enable-gitweb-owner=1 + remove-suffix=1 + + snapshots=all + readme=master:README.md + + source-filter=${pkgs.cgit}/lib/cgit/filters/syntax-highlighting.py + about-filter=${pkgs.cgit}/lib/cgit/filters/about-formatting.sh + + project-list=/var/lib/gitolite/projects.list + scan-path=/var/lib/gitolite/repositories + ''; +} diff --git a/services/ejabberd.nix b/services/ejabberd.nix new file mode 100644 index 0000000..f18cfe6 --- /dev/null +++ b/services/ejabberd.nix @@ -0,0 +1,243 @@ +{ fqdn }: { config, lib, pkgs, ... }: +let + inherit (builtins) toJSON; + inherit (pkgs) writeText; + inherit (pkgs.lib.lists) foldl'; + inherit (pkgs.lib.attrsets) mapAttrs' nameValuePair; + inherit (config.networking) domain; + + certs = config.security.acme.certs; + certDirectory = certs.${fqdn}.directory; +in { + services.ejabberd = { + enable = true; + imagemagick = true; + configFile = let + toPaths = s: mapAttrs' (n: v: nameValuePair "/${n}" v) s; + dhfile = config.security.dhparams.params.nginx.path; + toACLs = map (x: { acl = x; }); + in writeText "ejabberd.yml" (toJSON { + hosts = [ fqdn ]; + loglevel = 4; + s2s_cafile = "/etc/ssl/certs/ca-certificates.crt"; + ca_file = "/etc/ssl/certs/ca-certificates.crt"; + certfiles = [ "${certDirectory}/*.pem" ]; + listen = map (x: x // { ip = "10.0.1.30"; }) [ + { + inherit dhfile; + port = 5222; + module = "ejabberd_c2s"; + max_stanza_size = 262144; + shaper = "c2s_shaper"; + access = "c2s"; + starttls_required = true; + } + { + inherit dhfile; + port = 5223; + tls = true; + module = "ejabberd_c2s"; + max_stanza_size = 262144; + shaper = "c2s_shaper"; + access = "c2s"; + starttls_required = true; + } + { + inherit dhfile; + port = 5269; + module = "ejabberd_s2s_in"; + max_stanza_size = 524288; + } + { + inherit dhfile; + port = 5443; + module = "ejabberd_http"; + tls = true; + request_handlers = toPaths { + admin = "ejabberd_web_admin"; + api = "mod_http_api"; + bosh = "mod_bosh"; + captcha = "ejabberd_captcha"; + upload = "mod_http_upload"; + ws = "ejabberd_http_ws"; + }; + } + { + inherit dhfile; + port = 5280; + module = "ejabberd_http"; + request_handlers = toPaths { + admin = "ejabberd_web_admin"; + ".well-known/acme-challenge" = "ejabberd_acme"; + }; + } + { + port = 3478; + transport = "udp"; + module = "ejabberd_stun"; + use_turn = true; + turn_ipv4_address = "193.16.42.36"; + } + { + port = 1883; + module = "mod_mqtt"; + backlog = 1000; + } + ]; + s2s_use_starttls = "required"; + acl = { + local.user_regexp = ""; + loopback.ip = [ + "127.0.0.1/8" + "::1/128" + ]; + admin.user = [ "crash@${fqdn}" ]; + }; + access_rules = { + c2s = { + deny = "blocked"; + allow = "all"; + }; + } // mapAttrs' (n: v: nameValuePair n { allow = v; }) { + local = "local"; + announce = "admin"; + configure = "admin"; + muc_create = "local"; + pubsub_createnode = "local"; + trusted_network = "loopback"; + }; + api_permissions = { + "console commands" = { + from = [ "ejabberd_ctl" ]; + who = "all"; + what = "*"; + }; + "admin access" = { + who = { + access.allow = toACLs [ + "local" + "admin" + ]; + oauth = { + scope = "ejabberd:admin"; + access.allow = toACLs [ + "loopback" + "admin" + ]; + }; + }; + what = [ + "*" + "!stop" + "!start" + ]; + }; + "public commands" = { + who.ip = "127.0.0.1/8"; + what = [ + "status" + "connected_users_number" + ]; + }; + }; + shaper = { + normal = { + rate = 3000; + burst_size = 20000; + }; + fast = 100000; + }; + shaper_rules = { + max_user_sessions = 10; + max_user_offline_messages = { + "5000" = "admin"; + "100" = "all"; + }; + c2s_shaper = { + none = "admin"; + normal = "all"; + }; + s2s_shaper = "fast"; + }; + modules = mapAttrs' (n: v: nameValuePair "mod_${n}" v) ({ + announce.access = "announce"; + http_upload = { + put_url = "https://@HOST@:5443/upload"; + custom_headers = { + Access-Control-Allow-Origin = "https://@HOST@"; + Access-Control-Allow-Methods = "GET,HEAD,PUT,OPTIONS"; + Access-Control-Allow-Headers = "Content-Type"; + }; + }; + mam = { + assume_mam_usage = true; + default = "always"; + }; + muc = { + access = [ "allow" ]; + access_admin = [ { allow = "admin"; } ]; + access_create = "muc_create"; + access_persistent = "muc_create"; + access_mam = [ "allow" ]; + default_room_options.mam = true; + }; + offline.access_max_user_messages = "max_user_offline_messages"; + proxy65 = { + access = "local"; + max_connections = 5; + }; + pubsub = { + access_createnode = "pubsub_createnode"; + plugins = [ + "flat" + "pep" + ]; + force_node_config."storage:bookmarks".access_model = "whitelist"; + }; + register.ip_access = "trusted_network"; + roster.versioning = true; + stream_mgmt.resend_on_timeout = "if_offline"; + version.show_os = false; + } // foldl' (a: x: a // { ${x} = {}; }) {} [ + "adhoc" "admin_extra" "avatar" + "blocking" "bosh" + "caps" "carboncopy" "client_state" "configure" + "disco" + "fail2ban" + "http_api" + "last" + "mqtt" "muc_admin" + "ping" "privacy" "private" "push" "push_keepalive" + "s2s_dialback" "shared_roster" "stun_disco" + "vcard" "vcard_xupdate" + ]); + }); + package = pkgs.ejabberd.override { + withZlib = true; + withTools = true; + }; + }; + security.acme.certs.${fqdn} = { + extraDomainNames = map (x: "${x}.${fqdn}") [ + "pubsub" + "proxy" + "upload" + "conference" + ]; + group = "ejabberd-cert"; + postRun = "systemctl restart ejabberd.service"; + }; + users.groups.ejabberd-cert.members = [ "ejabberd" "nginx" ]; + security.dhparams = { + enable = true; + params.nginx = {}; + }; + networking.firewall.allowedTCPPorts = [ + 5222 # xmpp-client + 5223 # xmpp-client + 5269 # xmpp-server + 5280 # xmpp-bosh + 5443 # https + 3478 # xmpp-stun + ]; +} diff --git a/services/mailserver.nix b/services/mailserver.nix new file mode 100644 index 0000000..7d6f1d8 --- /dev/null +++ b/services/mailserver.nix @@ -0,0 +1,17 @@ +{ pkgs, hashedPasswordFile, ... }: +{ + mailserver = { + fqdn = "mail.crashoverburn.com"; + domains = [ "mail.crashoverburn.com" "crashoverburn.com" ]; + enable = true; + # A list of all login accounts. To create the password hashes, use + # nix-shell -p mkpasswd --run 'mkpasswd -sm bcrypt' + loginAccounts = { + "crash@crashoverburn.com" = { + inherit hashedPasswordFile; + aliases = [ "postmaster@mail.crashoverburn.com" "overburn@crashoverburn.com" ]; + }; + }; + certificateScheme = "acme-nginx"; + }; +} \ No newline at end of file diff --git a/services/website.nix b/services/website.nix new file mode 100644 index 0000000..d36f538 --- /dev/null +++ b/services/website.nix @@ -0,0 +1,14 @@ +{ webroot }: { config, lib, pkgs, ... }: +{ + services.nginx.enable = true; + services.nginx.virtualHosts."crashoverburn.com" = { + addSSL = true; + enableACME = true; + root = webroot; + }; + services.nginx.virtualHosts."crashoverburn.online" = { + addSSL = true; + enableACME = true; + root = webroot; + }; +} -- cgit v1.2.3