at master 7.4 kB view raw
1{ pkgs, ... }: 2let 3 4 ca_key = mailerCerts.ca.key; 5 ca_pem = mailerCerts.ca.cert; 6 7 bundle = 8 pkgs.runCommand "bundle" 9 { 10 nativeBuildInputs = [ pkgs.minica ]; 11 } 12 '' 13 minica -ca-cert ${ca_pem} -ca-key ${ca_key} \ 14 -domains localhost 15 install -Dm444 -t $out localhost/{key,cert}.pem 16 ''; 17 18 mailerCerts = import ../common/acme/server/snakeoil-certs.nix; 19 mailerDomain = mailerCerts.domain; 20 registrationSharedSecret = "unsecure123"; 21 testUser = "alice"; 22 testPassword = "alicealice"; 23 testEmail = "alice@example.com"; 24 25 listeners = [ 26 { 27 port = 8448; 28 bind_addresses = [ 29 "127.0.0.1" 30 "::1" 31 ]; 32 type = "http"; 33 tls = true; 34 x_forwarded = false; 35 resources = [ 36 { 37 names = [ 38 "client" 39 ]; 40 compress = true; 41 } 42 { 43 names = [ 44 "federation" 45 ]; 46 compress = false; 47 } 48 ]; 49 } 50 ]; 51 52in 53{ 54 55 name = "matrix-synapse"; 56 meta = { 57 inherit (pkgs.matrix-synapse.meta) maintainers; 58 }; 59 60 nodes = { 61 # Since 0.33.0, matrix-synapse doesn't allow underscores in server names 62 serverpostgres = 63 { 64 pkgs, 65 nodes, 66 config, 67 ... 68 }: 69 let 70 mailserverIP = nodes.mailserver.networking.primaryIPAddress; 71 in 72 { 73 services.matrix-synapse = { 74 enable = true; 75 settings = { 76 inherit listeners; 77 database = { 78 name = "psycopg2"; 79 args.password = "synapse"; 80 }; 81 redis = { 82 enabled = true; 83 host = "localhost"; 84 port = config.services.redis.servers.matrix-synapse.port; 85 }; 86 tls_certificate_path = "${bundle}/cert.pem"; 87 tls_private_key_path = "${bundle}/key.pem"; 88 registration_shared_secret = registrationSharedSecret; 89 public_baseurl = "https://example.com"; 90 email = { 91 smtp_host = mailerDomain; 92 smtp_port = 25; 93 require_transport_security = true; 94 notif_from = "matrix <matrix@${mailerDomain}>"; 95 app_name = "Matrix"; 96 }; 97 }; 98 }; 99 services.postgresql = { 100 enable = true; 101 102 # The database name and user are configured by the following options: 103 # - services.matrix-synapse.database_name 104 # - services.matrix-synapse.database_user 105 # 106 # The values used here represent the default values of the module. 107 initialScript = pkgs.writeText "synapse-init.sql" '' 108 CREATE ROLE "matrix-synapse" WITH LOGIN PASSWORD 'synapse'; 109 CREATE DATABASE "matrix-synapse" WITH OWNER "matrix-synapse" 110 TEMPLATE template0 111 LC_COLLATE = "C" 112 LC_CTYPE = "C"; 113 ''; 114 }; 115 116 services.redis.servers.matrix-synapse = { 117 enable = true; 118 port = 6380; 119 }; 120 121 networking.extraHosts = '' 122 ${mailserverIP} ${mailerDomain} 123 ''; 124 125 security.pki.certificateFiles = [ 126 mailerCerts.ca.cert 127 ca_pem 128 ]; 129 130 environment.systemPackages = 131 let 132 sendTestMailStarttls = pkgs.writeScriptBin "send-testmail-starttls" '' 133 #!${pkgs.python3.interpreter} 134 import smtplib 135 import ssl 136 137 ctx = ssl.create_default_context() 138 139 with smtplib.SMTP('${mailerDomain}') as smtp: 140 smtp.ehlo() 141 smtp.starttls(context=ctx) 142 smtp.ehlo() 143 smtp.sendmail('matrix@${mailerDomain}', '${testEmail}', 'Subject: Test STARTTLS\n\nTest data.') 144 smtp.quit() 145 ''; 146 147 obtainTokenAndRegisterEmail = 148 let 149 # adding the email through the API is quite complicated as it involves more than one step and some 150 # client-side calculation 151 insertEmailForAlice = pkgs.writeText "alice-email.sql" '' 152 INSERT INTO user_threepids (user_id, medium, address, validated_at, added_at) VALUES ('${testUser}@serverpostgres', 'email', '${testEmail}', '1629149927271', '1629149927270'); 153 ''; 154 in 155 pkgs.writeScriptBin "obtain-token-and-register-email" '' 156 #!${pkgs.runtimeShell} 157 set -o errexit 158 set -o pipefail 159 set -o nounset 160 su postgres -c "psql -d matrix-synapse -f ${insertEmailForAlice}" 161 curl --fail -XPOST 'https://localhost:8448/_matrix/client/r0/account/password/email/requestToken' -d '{"email":"${testEmail}","client_secret":"foobar","send_attempt":1}' -v 162 ''; 163 in 164 [ 165 sendTestMailStarttls 166 pkgs.matrix-synapse 167 obtainTokenAndRegisterEmail 168 ]; 169 }; 170 171 # test mail delivery 172 mailserver = args: { 173 security.pki.certificateFiles = [ 174 mailerCerts.ca.cert 175 ]; 176 177 networking.firewall.enable = false; 178 179 services.postfix = { 180 enable = true; 181 enableSubmission = true; 182 183 # blackhole transport 184 transport = "example.com discard:silently"; 185 186 settings.main = { 187 myhostname = "${mailerDomain}"; 188 # open relay for subnet 189 mynetworks_style = "subnet"; 190 debug_peer_level = "10"; 191 smtpd_relay_restrictions = [ 192 "permit_mynetworks" 193 "reject_unauth_destination" 194 ]; 195 196 # disable obsolete protocols, something old versions of twisted are still using 197 smtpd_tls_protocols = "TLSv1.3, TLSv1.2, !TLSv1.1, !TLSv1, !SSLv2, !SSLv3"; 198 smtpd_tls_mandatory_protocols = "TLSv1.3, TLSv1.2, !TLSv1.1, !TLSv1, !SSLv2, !SSLv3"; 199 smtpd_tls_chain_files = [ 200 "${mailerCerts.${mailerDomain}.key}" 201 "${mailerCerts.${mailerDomain}.cert}" 202 ]; 203 }; 204 }; 205 }; 206 207 serversqlite = args: { 208 services.matrix-synapse = { 209 enable = true; 210 settings = { 211 inherit listeners; 212 database.name = "sqlite3"; 213 tls_certificate_path = "${bundle}/cert.pem"; 214 tls_private_key_path = "${bundle}/key.pem"; 215 }; 216 }; 217 }; 218 }; 219 220 testScript = '' 221 start_all() 222 mailserver.wait_for_unit("postfix.service") 223 serverpostgres.succeed("send-testmail-starttls") 224 serverpostgres.wait_for_unit("matrix-synapse.service") 225 serverpostgres.wait_until_succeeds( 226 "curl --fail -L --cacert ${ca_pem} https://localhost:8448/" 227 ) 228 serverpostgres.wait_until_succeeds( 229 "journalctl -u matrix-synapse.service | grep -q 'Connected to redis'" 230 ) 231 serverpostgres.require_unit_state("postgresql.target") 232 serverpostgres.succeed("REQUESTS_CA_BUNDLE=${ca_pem} register_new_matrix_user -u ${testUser} -p ${testPassword} -a -k ${registrationSharedSecret} https://localhost:8448/") 233 serverpostgres.succeed("obtain-token-and-register-email") 234 serversqlite.wait_for_unit("matrix-synapse.service") 235 serversqlite.wait_until_succeeds( 236 "curl --fail -L --cacert ${ca_pem} https://localhost:8448/" 237 ) 238 serversqlite.succeed("[ -e /var/lib/matrix-synapse/homeserver.db ]") 239 ''; 240 241}