diff --git a/flake.lock b/flake.lock index 073cb907..1b88150c 100644 --- a/flake.lock +++ b/flake.lock @@ -127,11 +127,11 @@ }, "secrets": { "locked": { - "lastModified": 1634323852, - "narHash": "sha256-I1lEPlHhSPURU8InOR7zZ7xDXj40HG/TnP4fa5N7hKc=", + "lastModified": 1634413351, + "narHash": "sha256-iLtQVQSiwdHxSvOWEP54qRuJTs9E96SZULZzp7OXxS8=", "ref": "master", - "rev": "909211887311b6319b68384749abe430b0d8d532", - "revCount": 104, + "rev": "aa6b2921ff392ea8ce546d098d5fb1fe8dd52066", + "revCount": 105, "type": "git", "url": "ssh://gitea@gitea.c3d2.de/c3d2-admins/secrets.git" }, @@ -216,11 +216,11 @@ "zentralwerk-network-key": "zentralwerk-network-key" }, "locked": { - "lastModified": 1634222813, - "narHash": "sha256-bn8G0GFn9+vS676MsqIkxF10qhV8XPCHjHvcmmim/GI=", + "lastModified": 1634418596, + "narHash": "sha256-oaNeQBgbPW1SGuMEdQ9mGPsD7Kfz2QWJg55ExT/p0dU=", "ref": "master", - "rev": "2459cea80e8c7df3d24bfd22337984e8e146ed5f", - "revCount": 1197, + "rev": "739d6fefaa0243bdd47354a5d09331ba52577601", + "revCount": 1209, "type": "git", "url": "https://gitea.c3d2.de/zentralwerk/network.git" }, diff --git a/flake.nix b/flake.nix index c973f274..520397d1 100644 --- a/flake.nix +++ b/flake.nix @@ -449,6 +449,19 @@ system = "x86_64-linux"; }; + jabber = nixosSystem' { + modules = [ + ({ ... }: { + nixpkgs.overlays = with secrets.overlays; [ + jabber + ]; + }) + ./lib/lxc-container.nix + ./hosts/containers/jabber + ]; + system = "x86_64-linux"; + }; + }; nixosModule = import ./lib; diff --git a/hosts/containers/c3d2-web/default.nix b/hosts/containers/c3d2-web/default.nix index 7ab192e9..021a4fd9 100644 --- a/hosts/containers/c3d2-web/default.nix +++ b/hosts/containers/c3d2-web/default.nix @@ -39,7 +39,7 @@ in "/status.png".proxyPass = "http://[${hostRegistry.hosts.spaceapi.ip6}]:3000/status.png"; "/spaceapi.json".proxyPass = "http://[${hostRegistry.hosts.spaceapi.ip6}]:3000/spaceapi.json"; # Jabber - "/http-bind".proxyPass = "http://jabber.c3d2.de:5280/http-bind"; + "/http-bind".proxyPass = "https://jabber.c3d2.de/http-bind"; }; }; diff --git a/hosts/containers/jabber/default.nix b/hosts/containers/jabber/default.nix new file mode 100644 index 00000000..7a2c1f5b --- /dev/null +++ b/hosts/containers/jabber/default.nix @@ -0,0 +1,199 @@ +{ hostRegistry, config, pkgs, lib, ... }: + +let + domain = "jabber.c3d2.de"; + publicIPv4 = "81.201.149.152"; + + inherit (pkgs.jabber-secrets) + c3d2DynDns + coturnUser coturnPassword; + prosodyFirewall = pkgs.writeText "antispam.pfw" '' + %ZONE spam: creep.im, default.rs, sj.ms, anonym.im, xmpp.jp, safetyjabber.com, im.hot-chilli.net, jabb3r.org, draugr.de, laba.im, xmpp.sh, jabber.bitactive.com, 404.city, jabber.cd, jabber.jc-otto.de, jabster.pl, jabber.no, anoxinon.me, ubuntu-jabber.net, anonarchy.im, jabber.freenet.de, exploit.im, 616.pub, omemo.im, rsocks.net, chatwith.xyz, jabber.cz, jabbim.cz, blabber.im, jabber.root.cz, jabb.im, jabber.infos.ru, jabbim.pl, jabbim.com, linuxlovers.at, jabbim.ru, jabber.sk, njs.netlab.cz, jabba.biz + + IN ROSTER? + PASS. + + LEAVING: spam + BOUNCE=policy-violation (Your domain has been blacklisted due to spam.) + ''; +in +{ + networking = { + hostName = "jabber"; + useNetworkd = true; + interfaces.eth0.ipv4.addresses = [{ + address = hostRegistry.hosts.${config.networking.hostName}.ip4; + prefixLength = 26; + }]; + defaultGateway = "172.20.73.1"; + firewall.allowedTCPPorts = [ + # Prosody + 5222 5223 5269 + 80 5280 443 5281 + # Coturn + 3478 3479 + ]; + firewall.allowedUDPPorts = [ + # Coturn + 3478 3479 + ]; + # TODO: allowedSCTPPorts + }; + + security.acme.certs."${domain}" = { + extraDomainNames = [ + "chat.c3d2.de" + "*.${domain}" + ]; + # DynDNS method + dnsProvider = "rfc2136"; + credentialsFile = builtins.toFile "creds" (with c3d2DynDns; '' + RFC2136_NAMESERVER=ns.c3d2.de + RFC2136_TSIG_KEY=${tsigKey} + RFC2136_TSIG_ALGORITHM=${tsigAlg}. + RFC2136_TSIG_SECRET=${tsigSecret} + ''); + # Make keys accessible by putting them in prosody's group + inherit (config.services.prosody) group; + }; + + services.postgresql = { + enable = true; + package = pkgs.postgresql_13; + ensureDatabases = [ + "prosody" + ]; + ensureUsers = [ { + name = "prosody"; + ensurePermissions = { + "DATABASE prosody" = "ALL PRIVILEGES"; + }; + } ]; + }; + #TODO: candy? + #TODO: txt records? + services.prosody = { + enable = true; + allowRegistration = false; + admins = [ "astro@spaceboyz.net" "0@jabber.c3d2.de" "nek0@c3d2.de" ]; + package = pkgs.prosody.override { + withCommunityModules = [ "smacks" "csi" "cloud_notify" "extdisco" "firewall" ]; + withExtraLibs = [ pkgs.luaPackages.luadbi-postgresql ]; + }; + + modules = { + # HTTP stuff + bosh = true; + websocket = true; + http_files = true; + + announce = true; + mam = true; + carbons = true; + }; + ssl = { + key = "/var/lib/acme/${domain}/key.pem"; + cert = "/var/lib/acme/${domain}/fullchain.pem"; + # Some TLS hardening we've had on the old setup, probably to + # defend against downgrading attacks. + extraOptions.options = [ + "no_sslv2" "no_sslv3" + "no_ticket" "no_compression" + "cipher_server_preference" + "single_dh_use" "single_ecdh_use" + ]; + }; + + c2sRequireEncryption = true; + s2sRequireEncryption = true; + + virtualHosts = { + "${domain}" = { + enabled = true; + inherit domain; + }; + "anon.${domain}" = { + enabled = true; + domain = "anon.${domain}"; + extraConfig = '' + authentication = "anonymous" + ''; + }; + }; + muc = [ { + domain = "chat.c3d2.de"; + name = "Group chats"; + } ]; + + httpPorts = [ 80 5280 ]; + httpsPorts = [ 443 5281 ]; + uploadHttp = { + domain = "upload.${domain}"; + uploadFileSizeLimit = "10 * 1024 * 1024"; + userQuota = 512 * 1024 * 1024; + uploadExpireAfter = "2 * 60 * 60"; + }; + + extraConfig = '' + legacy_ssl_ports = { 5223 } + legacy_ssl_ssl = { + key = "/var/lib/acme/${domain}/key.pem", + certificate = "/var/lib/acme/${domain}/fullchain.pem", + } + certificates = "/var/lib/acme" + + storage = "sql" + sql = { driver = "PostgreSQL", database = "prosody", username = "prosody", password = "" } + log = { info = "*syslog"; } + + firewall_scripts = { "${prosodyFirewall}" } + + trusted_proxies = { "127.0.0.1", "::1", "${hostRegistry.hosts.public-access-proxy.ip4}", "${hostRegistry.hosts.public-access-proxy.ip4}", } + http_default_host = "${domain}" + http_host = "${domain}" + http_external_url = "https://${domain}/" + http_upload_file_size_limit = 10 * 1024 * 1024 + http_upload_expire_after = 60 * 60 * 24 * 7 -- a week in seconds + cross_domain_bosh = true -- Allow access from scripts on any site with no proxy (requires a modern browser) + + external_services = { + ["turn.${domain}"] = { + username = "${coturnUser}"; + password = "${coturnPassword}"; + port = "3478"; + transport = "udp"; + type = "turn"; + }; + ["${publicIPv4}"] = { + username = "${coturnUser}"; + password = "${coturnPassword}"; + port = "3478"; + transport = "udp"; + type = "turn"; + }; + } + + -- -- File-transfer proxies are an outdated technology + -- Component "proxy65.${domain}" "proxy65" + -- proxy65_address = "proxy.${domain}" + -- proxy65_acl = { "${domain}" } + -- proxy65_interfaces = { "*", "::" } + -- proxy65_ports = { 5000 } + ''; + }; + # Allow binding ports <1024 + systemd.services.prosody.serviceConfig.AmbientCapabilities = "CAP_NET_BIND_SERVICE"; + + services.coturn = { + enable = true; + realm = "turn.${domain}"; + lt-cred-mech = true; + extraConfig = '' + external-ip=${publicIPv4}/${(builtins.head config.networking.interfaces.eth0.ipv4.addresses).address} + + user=${coturnUser}:${coturnPassword} + ''; + }; + + system.stateVersion = "21.05"; +} diff --git a/hosts/containers/public-access-proxy/default.nix b/hosts/containers/public-access-proxy/default.nix index 4609511a..21e4531d 100644 --- a/hosts/containers/public-access-proxy/default.nix +++ b/hosts/containers/public-access-proxy/default.nix @@ -25,6 +25,15 @@ proxyTo.host = "172.20.73.51"; matchArg = "-m end"; } + { + hostNames = [ "jabber.c3d2.de" ]; + proxyTo = { + host = hostRegistry.hosts.jabber.ip4; + httpPort = 5820; + httpsPort = 5821; + }; + matchArg = "-m end"; + } ] ++ # Generated forwarding configurations from other nixosConfigurations map (host: diff --git a/secrets b/secrets index 90921188..aa6b2921 160000 --- a/secrets +++ b/secrets @@ -1 +1 @@ -Subproject commit 909211887311b6319b68384749abe430b0d8d532 +Subproject commit aa6b2921ff392ea8ce546d098d5fb1fe8dd52066