From 1d0dd013b0707de09f1ca041c88222436b7fcba1 Mon Sep 17 00:00:00 2001 From: "forgejo-actions[bot]" Date: Sun, 18 Jan 2026 17:38:37 +0000 Subject: [PATCH] Update dist for stage --- dist/404.html | 56 + ...astro_type_script_index_0_lang.C181hMzK.js | 1 + ...astro_type_script_index_0_lang.cjYDvRdi.js | 1 + ...astro_type_script_index_0_lang.Ci91lVEa.js | 6 + ...astro_type_script_index_0_lang.CKWWgpjV.js | 1 + .../_astro/adminer-login.C4T6LB13_11qlyK.webp | Bin 0 -> 7866 bytes .../_astro/adminer-main.CZ4pvrKT_Z29utJV.webp | Bin 0 -> 36248 bytes .../big-picture-relaying.eF0nKwB__2tQxza.webp | Bin 0 -> 23424 bytes ...re-user-connects-imap.DyhbQIdO_2fqzBW.webp | Bin 0 -> 10148 bytes ...user-connects-webmail.CIQwpfDL_ZixA2A.webp | Bin 0 -> 12448 bytes ...-spam-rspamd-dashboard.D8rZNTOO_oLqvg.webp | Bin 0 -> 17162 bytes ...spam-rspamd-dashboard.DTy1Y_zE_2jRE5g.webp | Bin 0 -> 42090 bytes ...n-packages-too-old-pdo.exqzDQPK_JEBOy.webp | Bin 0 -> 41430 bytes dist/_astro/ec.0vx5m.js | 3 + dist/_astro/ec.v4551.css | 1 + ...nderbird-account-setup.Dewox1Al_lehT3.webp | Bin 0 -> 22976 bytes dist/_astro/index.DpSp7KkT.css | 1 + dist/_astro/large-pingu.DNBynEPa.jpg | Bin 0 -> 45856 bytes dist/_astro/large-pingu.DNBynEPa_26vQty.webp | Bin 0 -> 13742 bytes dist/_astro/logo-dark.DlBk_-6-.svg | 118 ++ dist/_astro/logo.DfR9nmxN.svg | 122 ++ dist/_astro/lvm-diagram.Nevr3lkR_Z2rxy4U.webp | Bin 0 -> 17454 bytes .../_astro/managing-ima.CUdNEzFs_Z1q25WK.webp | Bin 0 -> 43956 bytes dist/_astro/mutt-inbox.D8HRyATa_nTter.webp | Bin 0 -> 16546 bytes dist/_astro/page.B1D-nYk3.js | 1 + ...tabase-adminer-login.01ShyyPj_Z2axosv.webp | Bin 0 -> 7208 bytes ...-mailserver-database.1f3EMpj4_Z152tht.webp | Bin 0 -> 23178 bytes ...kim-validation-failed.D_c973hl_1NU9vT.webp | Bin 0 -> 5672 bytes ...spoofing-without-dkim.BYdLtHn4_2llzdK.webp | Bin 0 -> 5140 bytes dist/_astro/print.DNXP8c50.css | 1 + ...uthenticated-relaying.D-QXvHmY_ZDn7Cs.webp | Bin 0 -> 8640 bytes ...laying-incoming-email.DZJIOHqZ_29Vv5S.webp | Bin 0 -> 9018 bytes ...ube-selecting-identity.DAlNSaQW_kYpJu.webp | Bin 0 -> 4326 bytes ...cated-relaying-denied.Luyv3w4j_2eyNO1.webp | Bin 0 -> 6376 bytes ...oundcube-login-dialog.BP0-utAA_ZXQDm2.webp | Bin 0 -> 4356 bytes .../roundcube-login.Dvep_9wD_Bo6mk.webp | Bin 0 -> 4574 bytes .../roundcube-password.BOBXKVth_Z2sCal6.webp | Bin 0 -> 11518 bytes ...ecords-mx-big-picture.y_PGYrNz_2lkkbj.webp | Bin 0 -> 16290 bytes dist/_astro/splide_min.BRKXMWAJ.css | 1 + dist/_astro/stdinouterr.D_fTYlSf_ZgmOAW.webp | Bin 0 -> 7440 bytes ...ivery-mutt-one-email.j1wHExqE_Z2kGLUj.webp | Bin 0 -> 11286 bytes ...ry-roundcube-one-email.e2rvRGU4_LgfWT.webp | Bin 0 -> 15814 bytes ...imap-mutt-empty-inbox.oBHkPD7U_27Uutu.webp | Bin 0 -> 8874 bytes ...utt-inbox-quota-mails.ZumKAfWA_1SYpAq.webp | Bin 0 -> 42094 bytes .../tls-browser-bar.Czwy_9Iz_Z1DnMs5.webp | Bin 0 -> 14282 bytes dist/_astro/ui-core.D_Lfcn_I.js | 2 + ...l-roundcube-db-setup1.Cb-g6XRP_1FOiAw.webp | Bin 0 -> 35292 bytes ...-roundcube-db-setup2.CrtFh7Aq_Z25abMs.webp | Bin 0 -> 14336 bytes ...oundcube-sieve-editor.CsDSURc3_1MiegR.webp | Bin 0 -> 11814 bytes .../index.html | 108 ++ dist/bacula-cheatsheet/index.html | 184 +++ dist/big-picture-receive/01.svg | 3 + dist/big-picture-receive/02.svg | 3 + dist/big-picture-receive/03.svg | 3 + dist/big-picture-receive/04.svg | 3 + dist/big-picture-receive/05.svg | 3 + dist/big-picture-receive/06.svg | 3 + dist/big-picture-receive/07.svg | 3 + dist/big-picture-receive/08.svg | 3 + dist/big-picture-receive/09.svg | 3 + dist/big-picture-receive/10.svg | 3 + dist/big-picture-receive/11.svg | 3 + dist/big-picture-receive/12.svg | 3 + dist/big-picture-receive/13.svg | 3 + dist/big-picture-receive/14.svg | 3 + dist/big-picture-receive/15.svg | 3 + dist/big-picture-receive/16.svg | 3 + dist/big-picture-receive/17.svg | 3 + dist/big-picture-receive/18.svg | 3 + dist/big-picture-receive/19.svg | 3 + dist/big-picture-receive/20.svg | 3 + dist/big-picture-receive/21.svg | 3 + dist/big-picture-receive/22.svg | 3 + dist/big-picture-receive/23.svg | 3 + dist/big-picture-receive/24.svg | 3 + dist/debian-packages-are-so-old/index.html | 118 ++ dist/favicon.svg | 78 ++ dist/getting-help-on-irc/index.html | 137 ++ dist/imapsieve/imapsieve-learn-spam.svg | 3 + dist/index.html | 158 +++ .../index.html | 93 ++ dist/ispmail-bookworm/big-picture/index.html | 165 +++ .../catchall-aliases/index.html | 149 +++ .../catching-spam-with-rspamd/index.html | 286 ++++ .../index.html | 292 +++++ .../faq-frequently-asked-questions/index.html | 137 ++ dist/ispmail-bookworm/index.html | 124 ++ .../index.html | 137 ++ .../install-the-software-packages/index.html | 177 +++ .../index.html | 118 ++ .../index.html | 126 ++ .../index.html | 115 ++ .../index.html | 139 ++ .../monitoring-and-backup/index.html | 129 ++ .../prepare-the-database/index.html | 242 ++++ .../prevent-spoofing-using-dkim/index.html | 168 +++ dist/ispmail-bookworm/quotas/index.html | 188 +++ .../index.html | 267 ++++ .../setting-dns-records/index.html | 111 ++ .../setting-up-dovecot/index.html | 221 ++++ .../success-stories/index.html | 90 ++ .../testing-email-delivery/index.html | 176 +++ dist/ispmail-bookworm/testing-imap/index.html | 104 ++ .../types-of-email-domains/index.html | 334 +++++ .../webmail-using-roundcube/index.html | 161 +++ dist/ispmail-bookworm/whats-new/index.html | 110 ++ .../anti-spoofing-dkim-spf/index.html | 316 +++++ .../automated-installation/index.html | 99 ++ dist/ispmail-trixie/catch-all/index.html | 151 +++ .../catching-spam-with-rspamd/index.html | 330 +++++ dist/ispmail-trixie/database/index.html | 303 +++++ dist/ispmail-trixie/dns-records/index.html | 121 ++ dist/ispmail-trixie/dovecot/index.html | 184 +++ dist/ispmail-trixie/going-live/index.html | 99 ++ dist/ispmail-trixie/imap/index.html | 113 ++ dist/ispmail-trixie/index.html | 164 +++ dist/ispmail-trixie/install-debian/index.html | 104 ++ .../install-the-software-packages/index.html | 138 ++ dist/ispmail-trixie/lmtp/index.html | 142 ++ .../index.html | 146 +++ dist/ispmail-trixie/overview/index.html | 92 ++ dist/ispmail-trixie/postfix/index.html | 153 +++ dist/ispmail-trixie/quotas/index.html | 195 +++ dist/ispmail-trixie/relaying/index.html | 407 ++++++ .../ispmail-trixie/tls-certificate/index.html | 144 ++ dist/ispmail-trixie/upgrading/index.html | 200 +++ .../ispmail-trixie/virtual-domains/index.html | 104 ++ dist/ispmail-trixie/webmail/index.html | 198 +++ .../anti-spoofing-dkim-spf/index.html | 1 + dist/ispmail-trxie/catch-all/index.html | 1 + dist/ispmail-trxie/going-live/index.html | 1 + dist/ispmail-trxie/imap/index.html | 1 + dist/ispmail-trxie/quotas/index.html | 1 + dist/ispmail.sh | 1164 +++++++++++++++++ dist/large-pingu.jpg | Bin 0 -> 45856 bytes dist/linux/renaming-multiple-files/index.html | 97 ++ dist/linuxtip/pipes/index.html | 159 +++ dist/pagefind/fragment/en_1e55a7e.pf_fragment | Bin 0 -> 4812 bytes dist/pagefind/fragment/en_1fe6967.pf_fragment | Bin 0 -> 3636 bytes dist/pagefind/fragment/en_24d7d48.pf_fragment | Bin 0 -> 2444 bytes dist/pagefind/fragment/en_26eddc6.pf_fragment | Bin 0 -> 3533 bytes dist/pagefind/fragment/en_38c9179.pf_fragment | Bin 0 -> 2098 bytes dist/pagefind/fragment/en_3dd5273.pf_fragment | Bin 0 -> 3860 bytes dist/pagefind/fragment/en_4272b66.pf_fragment | Bin 0 -> 7023 bytes dist/pagefind/fragment/en_4f8af64.pf_fragment | Bin 0 -> 3921 bytes dist/pagefind/fragment/en_4f8ce9a.pf_fragment | Bin 0 -> 7619 bytes dist/pagefind/fragment/en_502bf76.pf_fragment | Bin 0 -> 2825 bytes dist/pagefind/fragment/en_522bb3c.pf_fragment | Bin 0 -> 1463 bytes dist/pagefind/fragment/en_52c8caf.pf_fragment | Bin 0 -> 4454 bytes dist/pagefind/fragment/en_54f0a06.pf_fragment | Bin 0 -> 2948 bytes dist/pagefind/fragment/en_59ca778.pf_fragment | Bin 0 -> 2241 bytes dist/pagefind/fragment/en_5b29cf4.pf_fragment | Bin 0 -> 3604 bytes dist/pagefind/fragment/en_60b4bbb.pf_fragment | Bin 0 -> 2466 bytes dist/pagefind/fragment/en_64d01b8.pf_fragment | Bin 0 -> 3430 bytes dist/pagefind/fragment/en_6aabecf.pf_fragment | Bin 0 -> 1940 bytes dist/pagefind/fragment/en_6c539a2.pf_fragment | Bin 0 -> 9843 bytes dist/pagefind/fragment/en_6e67dbf.pf_fragment | Bin 0 -> 2057 bytes dist/pagefind/fragment/en_6fbc73b.pf_fragment | Bin 0 -> 1394 bytes dist/pagefind/fragment/en_73e850f.pf_fragment | Bin 0 -> 6134 bytes dist/pagefind/fragment/en_745fe5a.pf_fragment | Bin 0 -> 1204 bytes dist/pagefind/fragment/en_7c62247.pf_fragment | Bin 0 -> 377 bytes dist/pagefind/fragment/en_7f34c53.pf_fragment | Bin 0 -> 11972 bytes dist/pagefind/fragment/en_82e0d6b.pf_fragment | Bin 0 -> 780 bytes dist/pagefind/fragment/en_8889943.pf_fragment | Bin 0 -> 4067 bytes dist/pagefind/fragment/en_89d3afe.pf_fragment | Bin 0 -> 4301 bytes dist/pagefind/fragment/en_8c3b667.pf_fragment | Bin 0 -> 3056 bytes dist/pagefind/fragment/en_8c89f0d.pf_fragment | Bin 0 -> 2213 bytes dist/pagefind/fragment/en_8edefe1.pf_fragment | Bin 0 -> 1205 bytes dist/pagefind/fragment/en_9536fae.pf_fragment | Bin 0 -> 2711 bytes dist/pagefind/fragment/en_984315b.pf_fragment | Bin 0 -> 2131 bytes dist/pagefind/fragment/en_998fc06.pf_fragment | Bin 0 -> 411 bytes dist/pagefind/fragment/en_9afb713.pf_fragment | Bin 0 -> 1252 bytes dist/pagefind/fragment/en_9cff5e3.pf_fragment | Bin 0 -> 862 bytes dist/pagefind/fragment/en_9ebe26a.pf_fragment | Bin 0 -> 3693 bytes dist/pagefind/fragment/en_a57835d.pf_fragment | Bin 0 -> 675 bytes dist/pagefind/fragment/en_abb8175.pf_fragment | Bin 0 -> 4388 bytes dist/pagefind/fragment/en_accdb73.pf_fragment | Bin 0 -> 3881 bytes dist/pagefind/fragment/en_c1a850b.pf_fragment | Bin 0 -> 544 bytes dist/pagefind/fragment/en_c7199fe.pf_fragment | Bin 0 -> 1993 bytes dist/pagefind/fragment/en_c97d34d.pf_fragment | Bin 0 -> 2995 bytes dist/pagefind/fragment/en_cd59df5.pf_fragment | Bin 0 -> 3776 bytes dist/pagefind/fragment/en_d2a9db4.pf_fragment | Bin 0 -> 1027 bytes dist/pagefind/fragment/en_d35c9e5.pf_fragment | Bin 0 -> 4570 bytes dist/pagefind/fragment/en_d6e847b.pf_fragment | Bin 0 -> 2396 bytes dist/pagefind/fragment/en_d6e92f3.pf_fragment | Bin 0 -> 4131 bytes dist/pagefind/fragment/en_d7b6edb.pf_fragment | Bin 0 -> 4855 bytes dist/pagefind/fragment/en_e15b3e8.pf_fragment | Bin 0 -> 7831 bytes dist/pagefind/fragment/en_e25a032.pf_fragment | Bin 0 -> 2703 bytes dist/pagefind/fragment/en_e7bbd4a.pf_fragment | Bin 0 -> 2833 bytes dist/pagefind/fragment/en_e85dca9.pf_fragment | Bin 0 -> 784 bytes dist/pagefind/fragment/en_ee8a811.pf_fragment | Bin 0 -> 399 bytes dist/pagefind/fragment/en_f141255.pf_fragment | Bin 0 -> 3038 bytes dist/pagefind/fragment/en_f255c55.pf_fragment | Bin 0 -> 8744 bytes dist/pagefind/fragment/en_f82cb79.pf_fragment | Bin 0 -> 2455 bytes dist/pagefind/fragment/en_f93aada.pf_fragment | Bin 0 -> 722 bytes dist/pagefind/fragment/en_ff9d571.pf_fragment | Bin 0 -> 798 bytes dist/pagefind/index/en_0e9e51a.pf_index | Bin 0 -> 37893 bytes dist/pagefind/index/en_43a54fb.pf_index | Bin 0 -> 38598 bytes dist/pagefind/index/en_8c40ad9.pf_index | Bin 0 -> 19529 bytes dist/pagefind/index/en_b2f539f.pf_index | Bin 0 -> 38256 bytes dist/pagefind/index/en_d41cd62.pf_index | Bin 0 -> 37448 bytes dist/pagefind/index/en_e7357f7.pf_index | Bin 0 -> 38166 bytes dist/pagefind/index/en_fba5f9f.pf_index | Bin 0 -> 37205 bytes dist/pagefind/pagefind-entry.json | 1 + dist/pagefind/pagefind-highlight.js | 1064 +++++++++++++++ dist/pagefind/pagefind-modular-ui.css | 214 +++ dist/pagefind/pagefind-modular-ui.js | 8 + dist/pagefind/pagefind-ui.css | 1 + dist/pagefind/pagefind-ui.js | 2 + dist/pagefind/pagefind.en_16e9ffcaaf.pf_meta | Bin 0 -> 662 bytes dist/pagefind/pagefind.js | 6 + dist/pagefind/wasm.en.pagefind | Bin 0 -> 55619 bytes dist/pagefind/wasm.unknown.pagefind | Bin 0 -> 52427 bytes dist/reference/example/index.html | 93 ++ dist/robots.txt | 93 ++ dist/rsnapshot-and-usb-drives/index.html | 148 +++ dist/sitemap-0.xml | 1 + dist/sitemap-index.xml | 1 + dist/squid-acls/index.html | 132 ++ dist/understanding-lvm/index.html | 175 +++ 220 files changed, 12799 insertions(+) create mode 100644 dist/404.html create mode 100644 dist/_astro/MobileTableOfContents.astro_astro_type_script_index_0_lang.C181hMzK.js create mode 100644 dist/_astro/Search.astro_astro_type_script_index_0_lang.cjYDvRdi.js create mode 100644 dist/_astro/Splide.astro_astro_type_script_index_0_lang.Ci91lVEa.js create mode 100644 dist/_astro/TableOfContents.astro_astro_type_script_index_0_lang.CKWWgpjV.js create mode 100644 dist/_astro/adminer-login.C4T6LB13_11qlyK.webp create mode 100644 dist/_astro/adminer-main.CZ4pvrKT_Z29utJV.webp create mode 100644 dist/_astro/big-picture-relaying.eF0nKwB__2tQxza.webp create mode 100644 dist/_astro/big-picture-user-connects-imap.DyhbQIdO_2fqzBW.webp create mode 100644 dist/_astro/big-picture-user-connects-webmail.CIQwpfDL_ZixA2A.webp create mode 100644 dist/_astro/catching-spam-rspamd-dashboard.D8rZNTOO_oLqvg.webp create mode 100644 dist/_astro/catching-spam-rspamd-dashboard.DTy1Y_zE_2jRE5g.webp create mode 100644 dist/_astro/debian-packages-too-old-pdo.exqzDQPK_JEBOy.webp create mode 100644 dist/_astro/ec.0vx5m.js create mode 100644 dist/_astro/ec.v4551.css create mode 100644 dist/_astro/imap-thunderbird-account-setup.Dewox1Al_lehT3.webp create mode 100644 dist/_astro/index.DpSp7KkT.css create mode 100644 dist/_astro/large-pingu.DNBynEPa.jpg create mode 100644 dist/_astro/large-pingu.DNBynEPa_26vQty.webp create mode 100644 dist/_astro/logo-dark.DlBk_-6-.svg create mode 100644 dist/_astro/logo.DfR9nmxN.svg create mode 100644 dist/_astro/lvm-diagram.Nevr3lkR_Z2rxy4U.webp create mode 100644 dist/_astro/managing-ima.CUdNEzFs_Z1q25WK.webp create mode 100644 dist/_astro/mutt-inbox.D8HRyATa_nTter.webp create mode 100644 dist/_astro/page.B1D-nYk3.js create mode 100644 dist/_astro/prepare-database-adminer-login.01ShyyPj_Z2axosv.webp create mode 100644 dist/_astro/prepare-database-adminer-mailserver-database.1f3EMpj4_Z152tht.webp create mode 100644 dist/_astro/prevent-spoofing-dkim-spoofing-dkim-validation-failed.D_c973hl_1NU9vT.webp create mode 100644 dist/_astro/prevent-spoofing-dkim-spoofing-without-dkim.BYdLtHn4_2llzdK.webp create mode 100644 dist/_astro/print.DNXP8c50.css create mode 100644 dist/_astro/relaying-authenticated-relaying.D-QXvHmY_ZDn7Cs.webp create mode 100644 dist/_astro/relaying-incoming-email.DZJIOHqZ_29Vv5S.webp create mode 100644 dist/_astro/relaying-roundcube-selecting-identity.DAlNSaQW_kYpJu.webp create mode 100644 dist/_astro/relaying-unauthenticated-relaying-denied.Luyv3w4j_2eyNO1.webp create mode 100644 dist/_astro/roundcube-login-dialog.BP0-utAA_ZXQDm2.webp create mode 100644 dist/_astro/roundcube-login.Dvep_9wD_Bo6mk.webp create mode 100644 dist/_astro/roundcube-password.BOBXKVth_Z2sCal6.webp create mode 100644 dist/_astro/setting-dns-records-mx-big-picture.y_PGYrNz_2lkkbj.webp create mode 100644 dist/_astro/splide_min.BRKXMWAJ.css create mode 100644 dist/_astro/stdinouterr.D_fTYlSf_ZgmOAW.webp create mode 100644 dist/_astro/testing-email-delivery-mutt-one-email.j1wHExqE_Z2kGLUj.webp create mode 100644 dist/_astro/testing-email-delivery-roundcube-one-email.e2rvRGU4_LgfWT.webp create mode 100644 dist/_astro/testing-imap-mutt-empty-inbox.oBHkPD7U_27Uutu.webp create mode 100644 dist/_astro/testing-imap-mutt-inbox-quota-mails.ZumKAfWA_1SYpAq.webp create mode 100644 dist/_astro/tls-browser-bar.Czwy_9Iz_Z1DnMs5.webp create mode 100644 dist/_astro/ui-core.D_Lfcn_I.js create mode 100644 dist/_astro/webmail-roundcube-db-setup1.Cb-g6XRP_1FOiAw.webp create mode 100644 dist/_astro/webmail-roundcube-db-setup2.CrtFh7Aq_Z25abMs.webp create mode 100644 dist/_astro/webmail-roundcube-sieve-editor.CsDSURc3_1MiegR.webp create mode 100644 dist/article/updating-the-bios-on-lenovo-laptops-from-linux-using-a-usb-flash-stick/index.html create mode 100644 dist/bacula-cheatsheet/index.html create mode 100644 dist/big-picture-receive/01.svg create mode 100644 dist/big-picture-receive/02.svg create mode 100644 dist/big-picture-receive/03.svg create mode 100644 dist/big-picture-receive/04.svg create mode 100644 dist/big-picture-receive/05.svg create mode 100644 dist/big-picture-receive/06.svg create mode 100644 dist/big-picture-receive/07.svg create mode 100644 dist/big-picture-receive/08.svg create mode 100644 dist/big-picture-receive/09.svg create mode 100644 dist/big-picture-receive/10.svg create mode 100644 dist/big-picture-receive/11.svg create mode 100644 dist/big-picture-receive/12.svg create mode 100644 dist/big-picture-receive/13.svg create mode 100644 dist/big-picture-receive/14.svg create mode 100644 dist/big-picture-receive/15.svg create mode 100644 dist/big-picture-receive/16.svg create mode 100644 dist/big-picture-receive/17.svg create mode 100644 dist/big-picture-receive/18.svg create mode 100644 dist/big-picture-receive/19.svg create mode 100644 dist/big-picture-receive/20.svg create mode 100644 dist/big-picture-receive/21.svg create mode 100644 dist/big-picture-receive/22.svg create mode 100644 dist/big-picture-receive/23.svg create mode 100644 dist/big-picture-receive/24.svg create mode 100644 dist/debian-packages-are-so-old/index.html create mode 100644 dist/favicon.svg create mode 100644 dist/getting-help-on-irc/index.html create mode 100644 dist/imapsieve/imapsieve-learn-spam.svg create mode 100644 dist/index.html create mode 100644 dist/ispmail-bookworm/automatic-installation-with-ansible/index.html create mode 100644 dist/ispmail-bookworm/big-picture/index.html create mode 100644 dist/ispmail-bookworm/catchall-aliases/index.html create mode 100644 dist/ispmail-bookworm/catching-spam-with-rspamd/index.html create mode 100644 dist/ispmail-bookworm/creating-a-tls-encryption-key-and-certificate/index.html create mode 100644 dist/ispmail-bookworm/faq-frequently-asked-questions/index.html create mode 100644 dist/ispmail-bookworm/index.html create mode 100644 dist/ispmail-bookworm/install-debian-bookworm-on-your-server/index.html create mode 100644 dist/ispmail-bookworm/install-the-software-packages/index.html create mode 100644 dist/ispmail-bookworm/let-postfix-send-emails-to-dovecot/index.html create mode 100644 dist/ispmail-bookworm/making-postfix-get-its-information-from-the-mariadb-database/index.html create mode 100644 dist/ispmail-bookworm/managing-users-aliases-and-domains/index.html create mode 100644 dist/ispmail-bookworm/migrating-from-a-bullseye-to-a-bookworm-server/index.html create mode 100644 dist/ispmail-bookworm/monitoring-and-backup/index.html create mode 100644 dist/ispmail-bookworm/prepare-the-database/index.html create mode 100644 dist/ispmail-bookworm/prevent-spoofing-using-dkim/index.html create mode 100644 dist/ispmail-bookworm/quotas/index.html create mode 100644 dist/ispmail-bookworm/relaying-outgoing-emails-through-postfix/index.html create mode 100644 dist/ispmail-bookworm/setting-dns-records/index.html create mode 100644 dist/ispmail-bookworm/setting-up-dovecot/index.html create mode 100644 dist/ispmail-bookworm/success-stories/index.html create mode 100644 dist/ispmail-bookworm/testing-email-delivery/index.html create mode 100644 dist/ispmail-bookworm/testing-imap/index.html create mode 100644 dist/ispmail-bookworm/types-of-email-domains/index.html create mode 100644 dist/ispmail-bookworm/webmail-using-roundcube/index.html create mode 100644 dist/ispmail-bookworm/whats-new/index.html create mode 100644 dist/ispmail-trixie/anti-spoofing-dkim-spf/index.html create mode 100644 dist/ispmail-trixie/automated-installation/index.html create mode 100644 dist/ispmail-trixie/catch-all/index.html create mode 100644 dist/ispmail-trixie/catching-spam-with-rspamd/index.html create mode 100644 dist/ispmail-trixie/database/index.html create mode 100644 dist/ispmail-trixie/dns-records/index.html create mode 100644 dist/ispmail-trixie/dovecot/index.html create mode 100644 dist/ispmail-trixie/going-live/index.html create mode 100644 dist/ispmail-trixie/imap/index.html create mode 100644 dist/ispmail-trixie/index.html create mode 100644 dist/ispmail-trixie/install-debian/index.html create mode 100644 dist/ispmail-trixie/install-the-software-packages/index.html create mode 100644 dist/ispmail-trixie/lmtp/index.html create mode 100644 dist/ispmail-trixie/managing-users-aliases-and-domains/index.html create mode 100644 dist/ispmail-trixie/overview/index.html create mode 100644 dist/ispmail-trixie/postfix/index.html create mode 100644 dist/ispmail-trixie/quotas/index.html create mode 100644 dist/ispmail-trixie/relaying/index.html create mode 100644 dist/ispmail-trixie/tls-certificate/index.html create mode 100644 dist/ispmail-trixie/upgrading/index.html create mode 100644 dist/ispmail-trixie/virtual-domains/index.html create mode 100644 dist/ispmail-trixie/webmail/index.html create mode 100644 dist/ispmail-trxie/anti-spoofing-dkim-spf/index.html create mode 100644 dist/ispmail-trxie/catch-all/index.html create mode 100644 dist/ispmail-trxie/going-live/index.html create mode 100644 dist/ispmail-trxie/imap/index.html create mode 100644 dist/ispmail-trxie/quotas/index.html create mode 100755 dist/ispmail.sh create mode 100644 dist/large-pingu.jpg create mode 100644 dist/linux/renaming-multiple-files/index.html create mode 100644 dist/linuxtip/pipes/index.html create mode 100644 dist/pagefind/fragment/en_1e55a7e.pf_fragment create mode 100644 dist/pagefind/fragment/en_1fe6967.pf_fragment create mode 100644 dist/pagefind/fragment/en_24d7d48.pf_fragment create mode 100644 dist/pagefind/fragment/en_26eddc6.pf_fragment create mode 100644 dist/pagefind/fragment/en_38c9179.pf_fragment create mode 100644 dist/pagefind/fragment/en_3dd5273.pf_fragment create mode 100644 dist/pagefind/fragment/en_4272b66.pf_fragment create mode 100644 dist/pagefind/fragment/en_4f8af64.pf_fragment create mode 100644 dist/pagefind/fragment/en_4f8ce9a.pf_fragment create mode 100644 dist/pagefind/fragment/en_502bf76.pf_fragment create mode 100644 dist/pagefind/fragment/en_522bb3c.pf_fragment create mode 100644 dist/pagefind/fragment/en_52c8caf.pf_fragment create mode 100644 dist/pagefind/fragment/en_54f0a06.pf_fragment create mode 100644 dist/pagefind/fragment/en_59ca778.pf_fragment create mode 100644 dist/pagefind/fragment/en_5b29cf4.pf_fragment create mode 100644 dist/pagefind/fragment/en_60b4bbb.pf_fragment create mode 100644 dist/pagefind/fragment/en_64d01b8.pf_fragment create mode 100644 dist/pagefind/fragment/en_6aabecf.pf_fragment create mode 100644 dist/pagefind/fragment/en_6c539a2.pf_fragment create mode 100644 dist/pagefind/fragment/en_6e67dbf.pf_fragment create mode 100644 dist/pagefind/fragment/en_6fbc73b.pf_fragment create mode 100644 dist/pagefind/fragment/en_73e850f.pf_fragment create mode 100644 dist/pagefind/fragment/en_745fe5a.pf_fragment create mode 100644 dist/pagefind/fragment/en_7c62247.pf_fragment create mode 100644 dist/pagefind/fragment/en_7f34c53.pf_fragment create mode 100644 dist/pagefind/fragment/en_82e0d6b.pf_fragment create mode 100644 dist/pagefind/fragment/en_8889943.pf_fragment create mode 100644 dist/pagefind/fragment/en_89d3afe.pf_fragment create mode 100644 dist/pagefind/fragment/en_8c3b667.pf_fragment create mode 100644 dist/pagefind/fragment/en_8c89f0d.pf_fragment create mode 100644 dist/pagefind/fragment/en_8edefe1.pf_fragment create mode 100644 dist/pagefind/fragment/en_9536fae.pf_fragment create mode 100644 dist/pagefind/fragment/en_984315b.pf_fragment create mode 100644 dist/pagefind/fragment/en_998fc06.pf_fragment create mode 100644 dist/pagefind/fragment/en_9afb713.pf_fragment create mode 100644 dist/pagefind/fragment/en_9cff5e3.pf_fragment create mode 100644 dist/pagefind/fragment/en_9ebe26a.pf_fragment create mode 100644 dist/pagefind/fragment/en_a57835d.pf_fragment create mode 100644 dist/pagefind/fragment/en_abb8175.pf_fragment create mode 100644 dist/pagefind/fragment/en_accdb73.pf_fragment create mode 100644 dist/pagefind/fragment/en_c1a850b.pf_fragment create mode 100644 dist/pagefind/fragment/en_c7199fe.pf_fragment create mode 100644 dist/pagefind/fragment/en_c97d34d.pf_fragment create mode 100644 dist/pagefind/fragment/en_cd59df5.pf_fragment create mode 100644 dist/pagefind/fragment/en_d2a9db4.pf_fragment create mode 100644 dist/pagefind/fragment/en_d35c9e5.pf_fragment create mode 100644 dist/pagefind/fragment/en_d6e847b.pf_fragment create mode 100644 dist/pagefind/fragment/en_d6e92f3.pf_fragment create mode 100644 dist/pagefind/fragment/en_d7b6edb.pf_fragment create mode 100644 dist/pagefind/fragment/en_e15b3e8.pf_fragment create mode 100644 dist/pagefind/fragment/en_e25a032.pf_fragment create mode 100644 dist/pagefind/fragment/en_e7bbd4a.pf_fragment create mode 100644 dist/pagefind/fragment/en_e85dca9.pf_fragment create mode 100644 dist/pagefind/fragment/en_ee8a811.pf_fragment create mode 100644 dist/pagefind/fragment/en_f141255.pf_fragment create mode 100644 dist/pagefind/fragment/en_f255c55.pf_fragment create mode 100644 dist/pagefind/fragment/en_f82cb79.pf_fragment create mode 100644 dist/pagefind/fragment/en_f93aada.pf_fragment create mode 100644 dist/pagefind/fragment/en_ff9d571.pf_fragment create mode 100644 dist/pagefind/index/en_0e9e51a.pf_index create mode 100644 dist/pagefind/index/en_43a54fb.pf_index create mode 100644 dist/pagefind/index/en_8c40ad9.pf_index create mode 100644 dist/pagefind/index/en_b2f539f.pf_index create mode 100644 dist/pagefind/index/en_d41cd62.pf_index create mode 100644 dist/pagefind/index/en_e7357f7.pf_index create mode 100644 dist/pagefind/index/en_fba5f9f.pf_index create mode 100644 dist/pagefind/pagefind-entry.json create mode 100644 dist/pagefind/pagefind-highlight.js create mode 100644 dist/pagefind/pagefind-modular-ui.css create mode 100644 dist/pagefind/pagefind-modular-ui.js create mode 100644 dist/pagefind/pagefind-ui.css create mode 100644 dist/pagefind/pagefind-ui.js create mode 100644 dist/pagefind/pagefind.en_16e9ffcaaf.pf_meta create mode 100644 dist/pagefind/pagefind.js create mode 100644 dist/pagefind/wasm.en.pagefind create mode 100644 dist/pagefind/wasm.unknown.pagefind create mode 100644 dist/reference/example/index.html create mode 100644 dist/robots.txt create mode 100644 dist/rsnapshot-and-usb-drives/index.html create mode 100644 dist/sitemap-0.xml create mode 100644 dist/sitemap-index.xml create mode 100644 dist/squid-acls/index.html create mode 100644 dist/understanding-lvm/index.html diff --git a/dist/404.html b/dist/404.html new file mode 100644 index 0000000..4020ebc --- /dev/null +++ b/dist/404.html @@ -0,0 +1,56 @@ + 404 | ISPmail Guide + Skip to content

404

Page not found. Check the URL or try using the search bar.
\ No newline at end of file diff --git a/dist/_astro/MobileTableOfContents.astro_astro_type_script_index_0_lang.C181hMzK.js b/dist/_astro/MobileTableOfContents.astro_astro_type_script_index_0_lang.C181hMzK.js new file mode 100644 index 0000000..c628d52 --- /dev/null +++ b/dist/_astro/MobileTableOfContents.astro_astro_type_script_index_0_lang.C181hMzK.js @@ -0,0 +1 @@ +import{S as r}from"./TableOfContents.astro_astro_type_script_index_0_lang.CKWWgpjV.js";class c extends r{set current(e){super.current=e;const t=this.querySelector(".display-current");t&&(t.textContent=e.textContent)}constructor(){super();const e=this.querySelector("details");if(!e)return;const t=()=>{e.open=!1};e.querySelectorAll("a").forEach(s=>{s.addEventListener("click",t)}),window.addEventListener("click",s=>{e.contains(s.target)||t()}),window.addEventListener("keydown",s=>{if(s.key==="Escape"&&e.open){const o=e.contains(document.activeElement);if(t(),o){const n=e.querySelector("summary");n&&n.focus()}}})}}customElements.define("mobile-starlight-toc",c); diff --git a/dist/_astro/Search.astro_astro_type_script_index_0_lang.cjYDvRdi.js b/dist/_astro/Search.astro_astro_type_script_index_0_lang.cjYDvRdi.js new file mode 100644 index 0000000..2a727bd --- /dev/null +++ b/dist/_astro/Search.astro_astro_type_script_index_0_lang.cjYDvRdi.js @@ -0,0 +1 @@ +const y="modulepreload",w=function(f){return"/"+f},g={},S=function(m,l,c){let h=Promise.resolve();if(l&&l.length>0){let o=function(n){return Promise.all(n.map(a=>Promise.resolve(a).then(r=>({status:"fulfilled",value:r}),r=>({status:"rejected",reason:r}))))};document.getElementsByTagName("link");const t=document.querySelector("meta[property=csp-nonce]"),u=t?.nonce||t?.getAttribute("nonce");h=o(l.map(n=>{if(n=w(n),n in g)return;g[n]=!0;const a=n.endsWith(".css"),r=a?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${n}"]${r}`))return;const e=document.createElement("link");if(e.rel=a?"stylesheet":y,a||(e.as="script"),e.crossOrigin="",e.href=n,u&&e.setAttribute("nonce",u),document.head.appendChild(e),a)return new Promise((i,s)=>{e.addEventListener("load",i),e.addEventListener("error",()=>s(new Error(`Unable to preload CSS for ${n}`)))})}))}function d(o){const t=new Event("vite:preloadError",{cancelable:!0});if(t.payload=o,window.dispatchEvent(t),!t.defaultPrevented)throw o}return h.then(o=>{for(const t of o||[])t.status==="rejected"&&d(t.reason);return m().catch(d)})},E={ranking:{pageLength:.1,termFrequency:.1,termSaturation:2,termSimilarity:9}};class v extends HTMLElement{constructor(){super();const m=this.querySelector("button[data-open-modal]"),l=this.querySelector("button[data-close-modal]"),c=this.querySelector("dialog"),h=this.querySelector(".dialog-frame"),d=e=>{("href"in(e.target||{})||document.body.contains(e.target)&&!h.contains(e.target))&&t()},o=e=>{c.showModal(),document.body.toggleAttribute("data-search-modal-open",!0),this.querySelector("input")?.focus(),e?.stopPropagation(),window.addEventListener("click",d)},t=()=>c.close();m.addEventListener("click",o),m.disabled=!1,l.addEventListener("click",t),c.addEventListener("close",()=>{document.body.toggleAttribute("data-search-modal-open",!1),window.removeEventListener("click",d)}),window.addEventListener("keydown",e=>{(e.metaKey===!0||e.ctrlKey===!0)&&e.key==="k"&&(c.open?t():o(),e.preventDefault())});let u={};try{u=JSON.parse(this.dataset.translations||"{}")}catch{}const r=this.dataset.stripTrailingSlash!==void 0?e=>e.replace(/(.)\/(#.*)?$/,"$1$2"):e=>e;window.addEventListener("DOMContentLoaded",()=>{(window.requestIdleCallback||(i=>setTimeout(i,1)))(async()=>{const{PagefindUI:i}=await S(async()=>{const{PagefindUI:s}=await import("./ui-core.D_Lfcn_I.js");return{PagefindUI:s}},[]);new i({...E,element:"#starlight__search",baseUrl:"/",bundlePath:"/".replace(/\/$/,"")+"/pagefind/",showImages:!1,translations:u,showSubResults:!0,processResult:s=>{s.url=r(s.url),s.sub_results=s.sub_results.map(p=>(p.url=r(p.url),p))}})})})}}customElements.define("site-search",v);export{S as _}; diff --git a/dist/_astro/Splide.astro_astro_type_script_index_0_lang.Ci91lVEa.js b/dist/_astro/Splide.astro_astro_type_script_index_0_lang.Ci91lVEa.js new file mode 100644 index 0000000..9eff126 --- /dev/null +++ b/dist/_astro/Splide.astro_astro_type_script_index_0_lang.Ci91lVEa.js @@ -0,0 +1,6 @@ +function Jn(e,n){for(var t=0;t-1}function at(e,n){return e.push.apply(e,Ze(n)),e}function fe(e,n,t){e&&ne(n,function(r){r&&e.classList[t?"add":"remove"](r)})}function oe(e,n){fe(e,me(n)?n.split(" "):n,!0)}function Je(e,n){ne(n,e.appendChild.bind(e))}function Ft(e,n){ne(e,function(t){var r=(n||t).parentNode;r&&r.insertBefore(t,n)})}function We(e,n){return hn(e)&&(e.msMatchesSelector||e.matches).call(e,n)}function mn(e,n){var t=e?_e(e.children):[];return n?t.filter(function(r){return We(r,n)}):t}function Qe(e,n){return n?mn(e,n)[0]:e.firstElementChild}var He=Object.keys;function Ie(e,n,t){return e&&(t?He(e).reverse():He(e)).forEach(function(r){r!=="__proto__"&&n(e[r],r)}),e}function Ye(e){return _e(arguments,1).forEach(function(n){Ie(n,function(t,r){e[r]=n[r]})}),e}function he(e){return _e(arguments,1).forEach(function(n){Ie(n,function(t,r){Mt(t)?e[r]=t.slice():Be(t)?e[r]=he({},Be(e[r])?e[r]:{},t):e[r]=t})}),e}function nn(e,n){ne(n||He(e),function(t){delete e[t]})}function ue(e,n){ne(e,function(t){ne(n,function(r){t&&t.removeAttribute(r)})})}function x(e,n,t){Be(n)?Ie(n,function(r,a){x(e,a,r)}):ne(e,function(r){Vt(t)||t===""?ue(r,n):r.setAttribute(n,String(t))})}function Pe(e,n,t){var r=document.createElement(e);return n&&(me(n)?oe(r,n):x(r,n)),t&&Je(t,r),r}function re(e,n,t){if(je(t))return getComputedStyle(e)[n];Vt(t)||(e.style[n]=""+t)}function Xe(e,n){re(e,"display",n)}function An(e){e.setActive&&e.setActive()||e.focus({preventScroll:!0})}function ie(e,n){return e.getAttribute(n)}function rn(e,n){return e&&e.classList.contains(n)}function ee(e){return e.getBoundingClientRect()}function Ne(e){ne(e,function(n){n&&n.parentNode&&n.parentNode.removeChild(n)})}function _n(e){return Qe(new DOMParser().parseFromString(e,"text/html").body)}function ce(e,n){e.preventDefault(),n&&(e.stopPropagation(),e.stopImmediatePropagation())}function yn(e,n){return e&&e.querySelector(n)}function kt(e,n){return n?_e(e.querySelectorAll(n)):[]}function ve(e,n){fe(e,n,!1)}function Ot(e){return e.timeStamp}function Le(e){return me(e)?e:e?e+"px":""}var et="splide",zt="data-"+et;function Ge(e,n){if(!e)throw new Error("["+et+"] "+(n||""))}var Ae=Math.min,ct=Math.max,ft=Math.floor,Ke=Math.ceil,Q=Math.abs;function Sn(e,n,t){return Q(e-n)0)-+(e<0)}function Ct(e,n){return ne(n,function(t){e=e.replace("%s",""+t)}),e}function Gt(e){return e<10?"0"+e:""+e}var an={};function nr(e){return""+e+Gt(an[e]=(an[e]||0)+1)}function Tn(){var e=[];function n(i,s,u,f){a(i,s,function(o,h,d){var g="addEventListener"in o,c=g?o.removeEventListener.bind(o,h,u,f):o.removeListener.bind(o,u);g?o.addEventListener(h,u,f):o.addListener(u),e.push([o,h,d,u,c])})}function t(i,s,u){a(i,s,function(f,o,h){e=e.filter(function(d){return d[0]===f&&d[1]===o&&d[2]===h&&(!u||d[3]===u)?(d[4](),!1):!0})})}function r(i,s,u){var f,o=!0;return typeof CustomEvent=="function"?f=new CustomEvent(s,{bubbles:o,detail:u}):(f=document.createEvent("CustomEvent"),f.initCustomEvent(s,o,!1,u)),i.dispatchEvent(f),f}function a(i,s,u){ne(i,function(f){f&&ne(s,function(o){o.split(" ").forEach(function(h){var d=h.split(".");u(f,d[0],d[1])})})})}function l(){e.forEach(function(i){i[4]()}),de(e)}return{bind:n,unbind:t,dispatch:r,destroy:l}}var ye="mounted",Pt="ready",ge="move",Fe="moved",Ut="click",Ln="active",In="inactive",Nn="visible",Rn="hidden",K="refresh",Z="updated",Me="resize",dt="resized",bn="drag",On="dragging",Dn="dragged",gt="scroll",be="scrolled",rr="overflow",Bt="destroy",Cn="arrows:mounted",Pn="arrows:updated",wn="pagination:mounted",pn="pagination:updated",Wt="navigation:mounted",Ht="autoplay:play",Mn="autoplay:playing",Yt="autoplay:pause",Xt="lazyload:loaded",Vn="sk",xn="sh",vt="ei";function H(e){var n=e?e.event.bus:document.createDocumentFragment(),t=Tn();function r(l,i){t.bind(n,Ze(l).join(" "),function(s){i.apply(i,Mt(s.detail)?s.detail:[])})}function a(l){t.dispatch(n,l,_e(arguments,1))}return e&&e.event.on(Bt,t.destroy),Ye(t,{bus:n,on:r,off:U(t.unbind,n),emit:a})}function Et(e,n,t,r){var a=Date.now,l,i=0,s,u=!0,f=0;function o(){if(!u){if(i=e?Ae((a()-l)/e,1):1,t&&t(i),i>=1&&(n(),l=a(),r&&++f>=r))return d();s=tn(o)}}function h(A){A||c(),l=a()-(A?i*e:0),u=!1,s=tn(o)}function d(){u=!0}function g(){l=a(),i=0,t&&t(i)}function c(){s&&cancelAnimationFrame(s),i=0,s=0,u=!0}function v(A){e=A}function _(){return u}return{start:h,rewind:g,pause:d,cancel:c,set:v,isPaused:_}}function ir(e){var n=e;function t(a){n=a}function r(a){return xt(Ze(a),n)}return{set:t,is:r}}function ar(e,n){var t=Et(0,e,null,1);return function(){t.isPaused()&&t.start()}}function or(e,n,t){var r=e.state,a=t.breakpoints||{},l=t.reducedMotion||{},i=Tn(),s=[];function u(){var c=t.mediaQuery==="min";He(a).sort(function(v,_){return c?+v-+_:+_-+v}).forEach(function(v){o(a[v],"("+(c?"min":"max")+"-width:"+v+"px)")}),o(l,en),h()}function f(c){c&&i.destroy()}function o(c,v){var _=matchMedia(v);i.bind(_,"change",h),s.push([c,_])}function h(){var c=r.is(st),v=t.direction,_=s.reduce(function(A,m){return he(A,m[1].matches?m[0]:{})},{});nn(t),g(_),t.destroy?e.destroy(t.destroy==="completely"):c?(f(!0),e.mount()):v!==t.direction&&e.refresh()}function d(c){matchMedia(en).matches&&(c?he(t,l):nn(t,He(l)))}function g(c,v,_){he(t,c),v&&he(Object.getPrototypeOf(t),c),(_||!r.is(Ce))&&e.emit(Z,t)}return{setup:u,destroy:f,reduce:d,set:g}}var ht="Arrow",mt=ht+"Left",At=ht+"Right",Fn=ht+"Up",kn=ht+"Down",on="rtl",_t="ttb",Lt={width:["height"],left:["top","right"],right:["bottom","left"],x:["y"],X:["Y"],Y:["X"],ArrowLeft:[Fn,At],ArrowRight:[kn,mt]};function ur(e,n,t){function r(l,i,s){s=s||t.direction;var u=s===on&&!i?1:s===_t?0:-1;return Lt[l]&&Lt[l][u]||l.replace(/width|left|right/i,function(f,o){var h=Lt[f.toLowerCase()][u]||f;return o>0?h.charAt(0).toUpperCase()+h.slice(1):h})}function a(l){return l*(t.direction===on?1:-1)}return{resolve:r,orient:a}}var le="role",we="tabindex",sr="disabled",ae="aria-",tt=ae+"controls",zn=ae+"current",un=ae+"selected",te=ae+"label",Kt=ae+"labelledby",Gn=ae+"hidden",$t=ae+"orientation",$e=ae+"roledescription",sn=ae+"live",cn=ae+"busy",fn=ae+"atomic",qt=[le,we,sr,tt,zn,te,Kt,Gn,$t,$e],se=et+"__",Se="is-",It=et,vn=se+"track",cr=se+"list",yt=se+"slide",Un=yt+"--clone",fr=yt+"__container",jt=se+"arrows",St=se+"arrow",Bn=St+"--prev",Wn=St+"--next",Tt=se+"pagination",Hn=Tt+"__page",vr=se+"progress",lr=vr+"__bar",dr=se+"toggle",gr=se+"spinner",Er=se+"sr",hr=Se+"initialized",Re=Se+"active",Yn=Se+"prev",Xn=Se+"next",wt=Se+"visible",pt=Se+"loading",Kn=Se+"focus-in",$n=Se+"overflow",mr=[Re,wt,Yn,Xn,pt,Kn,$n],Ar={slide:yt,clone:Un,arrows:jt,arrow:St,prev:Bn,next:Wn,pagination:Tt,page:Hn,spinner:gr};function _r(e,n){if(En(e.closest))return e.closest(n);for(var t=e;t&&t.nodeType===1&&!We(t,n);)t=t.parentElement;return t}var yr=5,ln=200,qn="touchstart mousedown",Nt="touchmove mousemove",Rt="touchend touchcancel mouseup click";function Sr(e,n,t){var r=H(e),a=r.on,l=r.bind,i=e.root,s=t.i18n,u={},f=[],o=[],h=[],d,g,c;function v(){E(),w(),m()}function _(){a(K,A),a(K,v),a(Z,m),l(document,qn+" keydown",function(S){c=S.type==="keydown"},{capture:!0}),l(i,"focusin",function(){fe(i,Kn,!!c)})}function A(S){var O=qt.concat("style");de(f),ve(i,o),ve(d,h),ue([d,g],O),ue(i,S?O:["style",$e])}function m(){ve(i,o),ve(d,h),o=M(It),h=M(vn),oe(i,o),oe(d,h),x(i,te,t.label),x(i,Kt,t.labelledby)}function E(){d=b("."+vn),g=Qe(d,"."+cr),Ge(d&&g,"A track/list element is missing."),at(f,mn(g,"."+yt+":not(."+Un+")")),Ie({arrows:jt,pagination:Tt,prev:Bn,next:Wn,bar:lr,toggle:dr},function(S,O){u[O]=b("."+S)}),Ye(u,{root:i,track:d,list:g,slides:f})}function w(){var S=i.id||nr(et),O=t.role;i.id=S,d.id=d.id||S+"-track",g.id=g.id||S+"-list",!ie(i,le)&&i.tagName!=="SECTION"&&O&&x(i,le,O),x(i,$e,s.carousel),x(g,le,"presentation")}function b(S){var O=yn(i,S);return O&&_r(O,"."+It)===i?O:void 0}function M(S){return[S+"--"+t.type,S+"--"+t.direction,t.drag&&S+"--draggable",t.isNavigation&&S+"--nav",S===It&&Re]}return Ye(u,{setup:v,mount:_,destroy:A})}var Ve="slide",ke="loop",nt="fade";function Tr(e,n,t,r){var a=H(e),l=a.on,i=a.emit,s=a.bind,u=e.Components,f=e.root,o=e.options,h=o.isNavigation,d=o.updateOnMove,g=o.i18n,c=o.pagination,v=o.slideFocus,_=u.Direction.resolve,A=ie(r,"style"),m=ie(r,te),E=t>-1,w=Qe(r,"."+fr),b;function M(){E||(r.id=f.id+"-slide"+Gt(n+1),x(r,le,c?"tabpanel":"group"),x(r,$e,g.slide),x(r,te,m||Ct(g.slideLabel,[n+1,e.length]))),S()}function S(){s(r,"click",U(i,Ut,p)),s(r,"keydown",U(i,Vn,p)),l([Fe,xn,be],L),l(Wt,k),d&&l(ge,P)}function O(){b=!0,a.destroy(),ve(r,mr),ue(r,qt),x(r,"style",A),x(r,te,m||"")}function k(){var C=e.splides.map(function(T){var D=T.splide.Components.Slides.getAt(n);return D?D.slide.id:""}).join(" ");x(r,te,Ct(g.slideX,(E?t:n)+1)),x(r,tt,C),x(r,le,v?"button":""),v&&ue(r,$e)}function P(){b||L()}function L(){if(!b){var C=e.index;I(),N(),fe(r,Yn,n===C-1),fe(r,Xn,n===C+1)}}function I(){var C=F();C!==rn(r,Re)&&(fe(r,Re,C),x(r,zn,h&&C||""),i(C?Ln:In,p))}function N(){var C=Y(),T=!C&&(!F()||E);if(e.state.is([xe,qe])||x(r,Gn,T||""),x(kt(r,o.focusableNodes||""),we,T?-1:""),v&&x(r,we,T?-1:0),C!==rn(r,wt)&&(fe(r,wt,C),i(C?Nn:Rn,p)),!C&&document.activeElement===r){var D=u.Slides.getAt(e.index);D&&An(D.slide)}}function V(C,T,D){re(D&&w||r,C,T)}function F(){var C=e.index;return C===n||o.cloneStatus&&C===t}function Y(){if(e.is(nt))return F();var C=ee(u.Elements.track),T=ee(r),D=_("left",!0),z=_("right",!0);return ft(C[D])<=Ke(T[D])&&ft(T[z])<=Ke(C[z])}function W(C,T){var D=Q(C-n);return!E&&(o.rewind||e.is(ke))&&(D=Ae(D,e.length-D)),D<=T}var p={index:n,slideIndex:t,slide:r,container:w,isClone:E,mount:M,destroy:O,update:L,style:V,isWithin:W};return p}function Lr(e,n,t){var r=H(e),a=r.on,l=r.emit,i=r.bind,s=n.Elements,u=s.slides,f=s.list,o=[];function h(){d(),a(K,g),a(K,d)}function d(){u.forEach(function(L,I){v(L,I,-1)})}function g(){b(function(L){L.destroy()}),de(o)}function c(){b(function(L){L.update()})}function v(L,I,N){var V=Tr(e,I,N,L);V.mount(),o.push(V),o.sort(function(F,Y){return F.index-Y.index})}function _(L){return L?M(function(I){return!I.isClone}):o}function A(L){var I=n.Controller,N=I.toIndex(L),V=I.hasFocus()?1:t.perPage;return M(function(F){return ot(F.index,N,N+V-1)})}function m(L){return M(L)[0]}function E(L,I){ne(L,function(N){if(me(N)&&(N=_n(N)),hn(N)){var V=u[I];V?Ft(N,V):Je(f,N),oe(N,t.classes.slide),O(N,U(l,Me))}}),l(K)}function w(L){Ne(M(L).map(function(I){return I.slide})),l(K)}function b(L,I){_(I).forEach(L)}function M(L){return o.filter(En(L)?L:function(I){return me(L)?We(I.slide,L):xt(Ze(L),I.index)})}function S(L,I,N){b(function(V){V.style(L,I,N)})}function O(L,I){var N=kt(L,"img"),V=N.length;V?N.forEach(function(F){i(F,"load error",function(){--V||I()})}):I()}function k(L){return L?u.length:o.length}function P(){return o.length>t.perPage}return{mount:h,destroy:g,update:c,register:v,get:_,getIn:A,getAt:m,add:E,remove:w,forEach:b,filter:M,style:S,getLength:k,isEnough:P}}function Ir(e,n,t){var r=H(e),a=r.on,l=r.bind,i=r.emit,s=n.Slides,u=n.Direction.resolve,f=n.Elements,o=f.root,h=f.track,d=f.list,g=s.getAt,c=s.style,v,_,A;function m(){E(),l(window,"resize load",ar(U(i,Me))),a([Z,K],E),a(Me,w)}function E(){v=t.direction===_t,re(o,"maxWidth",Le(t.width)),re(h,u("paddingLeft"),b(!1)),re(h,u("paddingRight"),b(!0)),w(!0)}function w(p){var C=ee(o);(p||_.width!==C.width||_.height!==C.height)&&(re(h,"height",M()),c(u("marginRight"),Le(t.gap)),c("width",O()),c("height",k(),!0),_=C,i(dt),A!==(A=W())&&(fe(o,$n,A),i(rr,A)))}function b(p){var C=t.padding,T=u(p?"right":"left");return C&&Le(C[T]||(Be(C)?0:C))||"0px"}function M(){var p="";return v&&(p=S(),Ge(p,"height or heightRatio is missing."),p="calc("+p+" - "+b(!1)+" - "+b(!0)+")"),p}function S(){return Le(t.height||ee(d).width*t.heightRatio)}function O(){return t.autoWidth?null:Le(t.fixedWidth)||(v?"":P())}function k(){return Le(t.fixedHeight)||(v?t.autoHeight?null:P():S())}function P(){var p=Le(t.gap);return"calc((100%"+(p&&" + "+p)+")/"+(t.perPage||1)+(p&&" - "+p)+")"}function L(){return ee(d)[u("width")]}function I(p,C){var T=g(p||0);return T?ee(T.slide)[u("width")]+(C?0:F()):0}function N(p,C){var T=g(p);if(T){var D=ee(T.slide)[u("right")],z=ee(d)[u("left")];return Q(D-z)+(C?0:F())}return 0}function V(p){return N(e.length-1)-N(0)+I(0,p)}function F(){var p=g(0);return p&&parseFloat(re(p.slide,u("marginRight")))||0}function Y(p){return parseFloat(re(h,u("padding"+(p?"Right":"Left"))))||0}function W(){return e.is(nt)||V(!0)>L()}return{mount:m,resize:w,listSize:L,slideSize:I,sliderSize:V,totalSize:N,getPadding:Y,isOverflow:W}}var Nr=2;function Rr(e,n,t){var r=H(e),a=r.on,l=n.Elements,i=n.Slides,s=n.Direction.resolve,u=[],f;function o(){a(K,h),a([Z,Me],g),(f=_())&&(c(f),n.Layout.resize(!0))}function h(){d(),o()}function d(){Ne(u),de(u),r.destroy()}function g(){var A=_();f!==A&&(fz)&&(L(),O(P(V(),T>z),!0)),i(xe),l(ge,D,z,T),E.start(D,function(){i(pe),l(Fe,D,z,T),q&&q()})}function S(T){O(N(T,!0))}function O(T,D){if(!e.is(nt)){var z=D?T:k(T);re(A,"transform","translate"+c("X")+"("+z+"px)"),T!==z&&l(xn)}}function k(T){if(e.is(ke)){var D=I(T),z=D>n.Controller.getEnd(),q=D<0;(q||z)&&(T=P(T,z))}return T}function P(T,D){var z=T-W(D),q=d();return T-=v(q*(Ke(Q(z)/q)||1))*(D?1:-1),T}function L(){O(V(),!0),E.cancel()}function I(T){for(var D=n.Slides.get(),z=0,q=1/0,$=0;$=0:D<=A[c("scrollWidth")]-ee(m)[c("width")]}function C(T,D){D=je(D)?V():D;var z=T!==!0&&v(D)v(W(!0));return z||q}return{mount:w,move:M,jump:S,translate:O,shift:P,cancel:L,toIndex:I,toPosition:N,getPosition:V,getLimit:W,exceededLimit:C,reposition:b}}function Or(e,n,t){var r=H(e),a=r.on,l=r.emit,i=n.Move,s=i.getPosition,u=i.getLimit,f=i.toPosition,o=n.Slides,h=o.isEnough,d=o.getLength,g=t.omitEnd,c=e.is(ke),v=e.is(Ve),_=U(V,!1),A=U(V,!0),m=t.start||0,E,w=m,b,M,S;function O(){k(),a([Z,K,vt],k),a(dt,P)}function k(){b=d(!0),M=t.perMove,S=t.perPage,E=p();var y=Oe(m,0,g?E:b-1);y!==m&&(m=y,i.reposition())}function P(){E!==p()&&l(vt)}function L(y,G,J){if(!Ee()){var X=N(y),j=W(X);j>-1&&(G||j!==m)&&(z(j),i.move(X,j,w,J))}}function I(y,G,J,X){n.Scroll.scroll(y,G,J,function(){var j=W(i.toIndex(s()));z(g?Ae(j,E):j),X&&X()})}function N(y){var G=m;if(me(y)){var J=y.match(/([+\-<>])(\d+)?/)||[],X=J[1],j=J[2];X==="+"||X==="-"?G=F(m+ +(""+X+(+j||1)),m):X===">"?G=j?C(+j):_(!0):X==="<"&&(G=A(!0))}else G=c?y:Oe(y,0,E);return G}function V(y,G){var J=M||($()?1:S),X=F(m+J*(y?-1:1),m,!(M||$()));return X===-1&&v&&!Sn(s(),u(!y),1)?y?0:E:G?X:W(X)}function F(y,G,J){if(h()||$()){var X=Y(y);X!==y&&(G=y,y=X,J=!1),y<0||y>E?!M&&(ot(0,y,G,!0)||ot(E,G,y,!0))?y=C(T(y)):c?y=J?y<0?-(b%S||S):b:y:t.rewind?y=y<0?E:0:y=-1:J&&y!==G&&(y=C(T(G)+(y0;)if(f(b-1,!0)!==f(y,!0)){y++;break}return Oe(y,0,b-1)}function C(y){return Oe($()?y:S*y,0,E)}function T(y){return $()?Ae(y,E):ft((y>=E?b-1:y)/S)}function D(y){var G=i.toIndex(y);return v?Oe(G,0,E):G}function z(y){y!==m&&(w=m,m=y)}function q(y){return y?w:m}function $(){return!je(t.focus)||t.isNavigation}function Ee(){return e.state.is([xe,qe])&&!!t.waitForTransition}return{mount:O,go:L,scroll:I,getNext:_,getPrev:A,getAdjacent:V,getEnd:p,setIndex:z,getIndex:q,toIndex:C,toPage:T,toDest:D,hasFocus:$,isBusy:Ee}}var Dr="http://www.w3.org/2000/svg",Cr="m15.5 0.932-4.3 4.38 14.5 14.6-14.5 14.5 4.3 4.4 14.6-14.6 4.4-4.3-4.4-4.4-14.6-14.6z",rt=40;function Pr(e,n,t){var r=H(e),a=r.on,l=r.bind,i=r.emit,s=t.classes,u=t.i18n,f=n.Elements,o=n.Controller,h=f.arrows,d=f.track,g=h,c=f.prev,v=f.next,_,A,m={};function E(){b(),a(Z,w)}function w(){M(),E()}function b(){var I=t.arrows;I&&!(c&&v)&&k(),c&&v&&(Ye(m,{prev:c,next:v}),Xe(g,I?"":"none"),oe(g,A=jt+"--"+t.direction),I&&(S(),L(),x([c,v],tt,d.id),i(Cn,c,v)))}function M(){r.destroy(),ve(g,A),_?(Ne(h?[c,v]:g),c=v=null):ue([c,v],qt)}function S(){a([ye,Fe,K,be,vt],L),l(v,"click",U(O,">")),l(c,"click",U(O,"<"))}function O(I){o.go(I,!0)}function k(){g=h||Pe("div",s.arrows),c=P(!0),v=P(!1),_=!0,Je(g,[c,v]),!h&&Ft(g,d)}function P(I){var N='

Updating the BIOS on Lenovo laptops from Linux using a USB flash stick

Aren’t hardware manufacturers funny? They either require an old-fashioned operating system (Windows) or museum hardware (floppy drives) to update a BIOS. Apparently they never learn and are instead busy adding features like DRM and UEFI to make our lives even more miserable.

+

However updating the BIOS on my Lenovo X230 laptop was surprisingly easy once I learned how to do that (kudos to a G+ post I stumbled upon).

+
    +
  1. Go to support.lenovo.com (or better use a search engine becaues the Lenovo website is beautiful but technically pretty broken and slow) and search for the BIOS upgrade of your laptop model.
  2. +
  3. Download the most recent ISO file. Look for “BIOS bootable update CD”.
  4. +
  5. Convert the ISO image using the geteltorito utility (if you don’t have it: apt-get install genisoimage).
    +Example:
    +geteltorito -o bios.img g2uj18us.iso
  6. +
  7. Insert any USB stick into your laptop that you have lying around. The image file is just 50 MB in size so even USB sticks with low capacity will work. Keep in mind that the stick will be completely overwritten.
  8. +
  9. If you are in a graphical environment then unmount the USB stick again.
  10. +
  11. Find out the device name of the stick. Enter a terminal window and enter “dmesg | tail”. You are looking for something like:[ 2101.614860] sd 6:0:0:0: [sdb] Attached SCSI disk
    +The “sdb” tells you that your USB stick is available on /dev/sdb. Don’t just assume it’s sdb. If it’s on another device on your laptop then you will destroy your data.
  12. +
  13. Copy the image to the USB stick:
    +dd if=bios.img of=/dev/sdb bs=1M
  14. +
  15. Reboot your laptop.
  16. +
  17. After the Lenovo logo appears press ENTER.
  18. +
  19. Press F12 to make your laptop boot from something else than your harddisk.
  20. +
  21. Select the USB stick.
  22. +
  23. Make sure your laptop has its power supply plugged in. (It will refuse to update otherwise.)
  24. +
  25. Follow the instructions.
  26. +
\ No newline at end of file diff --git a/dist/bacula-cheatsheet/index.html b/dist/bacula-cheatsheet/index.html new file mode 100644 index 0000000..158d820 --- /dev/null +++ b/dist/bacula-cheatsheet/index.html @@ -0,0 +1,184 @@ + Bareos/Bacula Cheat Sheet | ISPmail Guide + Skip to content

Bareos/Bacula Cheat Sheet

Bacula is a nifty backup software that is network-capable and stores data in the database for faster retrieval in case you need a certain file back. As a big fan of cheat sheets I created this cheat sheet.

+ +
Which files shall be backed up?show filesetsI=Included, E=Excluded
What’s the server doing?status dir
What’s the status of a certain job?status jobid=xx
What’s the client doing?status client
What’s the streamer doing?status storage
Anything new?messages
+ +
Start a backuprun…and choose the backup job
Label a new tapelabel…and run mount afterwards
+ +

The common way (a user accidentally removed a file and wants the newest version back from the tapes:

+
    +
  • Use the restore command.
  • +
  • Choose option 5 (Select the most recent backup for a client).
  • +
  • cd / ls / dir / mark / markdir / unmark / unmarkdir / lsmark / estimate / pwd / count / find
  • +
  • done
  • +
+ +
Last jobslist jobs…or list jobid=xx’ for a specific job
Statistics about last jobslist jobtotal
Which files were backed up?list files jobid=xx
+ +
Statusmeans…
TTerminated normally
CCreated but not yet running
RRunning
BBlocked
ETerminated in Error
eNon-fatal error
fFatal error
DVerify Differences
ACanceled by the user
FWaiting on the File daemon
SWaiting on the Storage daemon
mWaiting for a new Volume to be mounted
MWaiting for a Mount
sWaiting for Storage resource
jWaiting for Job resource
cWaiting for Client resource
dWating for Maximum jobs
tWaiting for Start Time
pWaiting for higher priority job to finish
WTerminated with warnings
+ +
Which tapes are in the pool?list media
Remove a tapedelete media
Which pools are defined?list pools
Which tapes are/were used for a certain job?list jobmedia
Assign a tape to a certain pooladd
Change parameters of a tapeupdate volume
+ +
Erase a label on the tapemt rewind && mt weof && mt rewind
+ + +

It is data in a SQL database running on the Bareos server. The catalog stores information about all assets like jobs, clients and media. Without the catalog Bareos had no idea which files were backed up and cannot restore them. In case of a disastrous loss of the catalog you need to take the latest bootstrap and start restoring the catalog first using that information. So the catalog itself is also backed up because without it the system is useless.

+ +

Volumes (also called “media”) are either files on disk or physical tapes. When backups run they save their data to volumes. Bareos keeps track in the catalog which data can be found on each volume. Usually multiple backups run in parallel leading to a multiplexed stream of data written to volumes. A volume always belongs to exactly one pool. Volumes have names/labels – tapes have the name that is printed on the barcode sticker if the library have a barcode scanner.

+ +

A set of volumes. The pool can define a maximum number of volumes, the type of volumes (e.g. disk or tape) and the retention period. For example you can have short-lived disk pools for small frequent backups. On the other hand you may have long-lived tape pools that store data for several weeks or months.

+ +

A specific action like a backup, restore or copy (e.g. from disk to tape). Jobs are usually started automatically by the director following a pre-defined schedule. Multiple jobs can run in parallel and share their resources. The catalog keeps track of which jobs have run in the past in order to know which volumes would be required to restore data from them.

+

In the bconsole you can see the running, past and scheduled jobs by running “stat dir”.

+ +

The definition of a job. It is not stored in the catalog but in text files in /etc/bareos.

+ +

A server to be backed up. Usually a file-daemon runs on the client. The director will talk to the client to run jobs.

+ +

Defines which files or directories to backup from a certain server. A job defines which fileset to use for a backup.

+ +

A small text file usually sent out via email frequently. It is required in case of a catalog loss to find the volume that contains the last backup of the catalog.

+

The upstream documents reads: “The bootstrap file contains ASCII information that permits precise specification of what files should be restored, what volume they are on, and where they are on the volume. It is a relatively compact form of specifying the information, is human readable, and can be edited with any text editor.”

+

The bootstrap data is not confidential and should be forwarded to an external location in case of a disaster.

+ +

Bareos can send messages to the console or via email. Results of jobs are sent via email.

+ +

A definition of how often and at what time a job can be run.

+ +

Defines a way to write volumes. It is used by the storage daemon. A storage can be a path on the local disks or the name of the tape device. Autochangers (aka “tape libraries”) are also supported.

+
+ +

A volume is locked after being written to. The retention period defines when the volume can be overwritten again.

+ +

This applies to tape volumes only. New tapes can be introduced into the “Scratch” pool. If a pool is out of volumes to use then Bareos will take a volume from the Scratch pool and take it into its own pool.

+ +

Backups can happen in three different levels: Full, Differential and Incremental. Only Full backups are required. The other levels can be used to save space on volumes.

+
    +
  • Full: every single file defined in assigned fileset is saved to the volume
  • +
  • Differential: only new files that were not contained in the last Full backup are backed up
  • +
  • Incremental: only new files that were not contained in the last Differential or Incremental backup are backed up
  • +
+

Using only Full backups is secure because if you lose a full backup then you take the full backup before it. However you are stubbornly backing up the same files time and again thus wasting space on the volumes. Complete restores are fastest though because only the last full backup has to be considered.

+

Using Full and Differential backups saves some space. During restores the last Full and last Differential backup are considered. However multiple Differential backups may store files redundantly thus wasting a little space.

+

Using Full and Incremental backups saves most space. However for a restore all Incremental backups since the last Full backup need to be working. If one Incremental backup is broken in the chain then only the last Full backup can be restored.

+

Using Full + Differential + Incremental backups saves most space while still keeping the risk of losing data low. A restore requires the Incremental backups back up to the last Differential backup + the last Full backup. This could look like:

+
    +
  • Full +
      +
    • Differential +
        +
      • Incremental
      • +
      • Incremental
      • +
      • Incremental
      • +
      • Incremental
      • +
      +
    • +
    • Differential +
        +
      • Incremental
      • +
      • Incremental
      • +
      • Incremental «««
      • +
      • Incremental
      • +
      +
    • +
    +
  • +
  • Full +
      +
    • +
    +
  • +
+

To restore the highlighted Incremental backup you would need the previous Differential and Full backups printed in bold letters.

+

Which mode to use depends on the type of data to backup. Database directories usually change in its entirety so a Full backup is the best solution. File servers with millions of files gain some advantage from using Full, Differential and Incremental backups.

+

Dangerous configurations:

+
    +
  • Using a rare Full backup and rely on many intermediate Incremental backups. If any of the many Incremental backups were faulty you would lose all data back to that time.
  • +
  • Losing the Full backup and only keeping Incremental backups. This may occur if the retention periods are not adequately configured for Full backups.
  • +
\ No newline at end of file diff --git a/dist/big-picture-receive/01.svg b/dist/big-picture-receive/01.svg new file mode 100644 index 0000000..b81ca4c --- /dev/null +++ b/dist/big-picture-receive/01.svg @@ -0,0 +1,3 @@ + + +
Other
mail server
Other...
I would like to send an email to john@example.com
I would like to send an email to j...
\ No newline at end of file diff --git a/dist/big-picture-receive/02.svg b/dist/big-picture-receive/02.svg new file mode 100644 index 0000000..6831ec9 --- /dev/null +++ b/dist/big-picture-receive/02.svg @@ -0,0 +1,3 @@ + + +
Name server
(DNS)
Name server...
Other
mail server
Other...
What is the MX record for the domain example.com?
What is the MX re...
\ No newline at end of file diff --git a/dist/big-picture-receive/03.svg b/dist/big-picture-receive/03.svg new file mode 100644 index 0000000..b4c8b40 --- /dev/null +++ b/dist/big-picture-receive/03.svg @@ -0,0 +1,3 @@ + + +
Name server
(DNS)
Name server...
Other
mail server
Other...
smtp01.example.net
smtp01.example.net
\ No newline at end of file diff --git a/dist/big-picture-receive/04.svg b/dist/big-picture-receive/04.svg new file mode 100644 index 0000000..203357b --- /dev/null +++ b/dist/big-picture-receive/04.svg @@ -0,0 +1,3 @@ + + +
Name server
(DNS)
Name server...
Other
mail server
Other...
What are the A and AAAAA records for smtp01.example.net?
What are the A and AA...
\ No newline at end of file diff --git a/dist/big-picture-receive/05.svg b/dist/big-picture-receive/05.svg new file mode 100644 index 0000000..d04d3e4 --- /dev/null +++ b/dist/big-picture-receive/05.svg @@ -0,0 +1,3 @@ + + +
Name server
(DNS)
Name server...
Other
mail server
Other...
A: 100.17.195.84
AAAA: 2001:876:18:5::ce
A: 100.17.195.84...
\ No newline at end of file diff --git a/dist/big-picture-receive/06.svg b/dist/big-picture-receive/06.svg new file mode 100644 index 0000000..af43a7e --- /dev/null +++ b/dist/big-picture-receive/06.svg @@ -0,0 +1,3 @@ + + +
SMTP
(TCP port 25)
SMTP...
Postfix
mail server
Postfix...
Other
mail server
Other...
\ No newline at end of file diff --git a/dist/big-picture-receive/07.svg b/dist/big-picture-receive/07.svg new file mode 100644 index 0000000..e248e60 --- /dev/null +++ b/dist/big-picture-receive/07.svg @@ -0,0 +1,3 @@ + + +
220 smtp01.example.net
ESMTP Postfix
220 smtp01.example.net...
Postfix
mail server
Postfix...
Other
mail server
Other...
Nice to see you.
Nice to see you.
\ No newline at end of file diff --git a/dist/big-picture-receive/08.svg b/dist/big-picture-receive/08.svg new file mode 100644 index 0000000..4eb096c --- /dev/null +++ b/dist/big-picture-receive/08.svg @@ -0,0 +1,3 @@ + + +
EHLO remoteserver
EHLO remoteserver
Postfix
mail server
Postfix...
Other
mail server
Other...
Hi, my name is "remoteserver"
Hi, my name is "remot...
\ No newline at end of file diff --git a/dist/big-picture-receive/09.svg b/dist/big-picture-receive/09.svg new file mode 100644 index 0000000..6c79fc9 --- /dev/null +++ b/dist/big-picture-receive/09.svg @@ -0,0 +1,3 @@ + + +
250-smtp01.example.com
250-SIZE 40000000
250-STARTTLS
250-ENHANCEDSTATUSCODES
250-8BITMIME
250-smtp01.example.com...
Postfix
mail server
Postfix...
Other
mail server
Other...
These are the features that I support.
These are the features...
\ No newline at end of file diff --git a/dist/big-picture-receive/10.svg b/dist/big-picture-receive/10.svg new file mode 100644 index 0000000..a5fc61f --- /dev/null +++ b/dist/big-picture-receive/10.svg @@ -0,0 +1,3 @@ + + +
STARTTLS
STARTTLS
Postfix
mail server
Postfix...
Other
mail server
Other...
Let us switch to encrypted communication
Let us switch to encr...
\ No newline at end of file diff --git a/dist/big-picture-receive/11.svg b/dist/big-picture-receive/11.svg new file mode 100644 index 0000000..96e7d27 --- /dev/null +++ b/dist/big-picture-receive/11.svg @@ -0,0 +1,3 @@ + + +
MAIL FROM: <someone@else.com>
MAIL FROM: <someone@else.com>
Postfix
mail server
Postfix...
Other
mail server
Other...
I have an email from someone@else.com
I have an email from...
\ No newline at end of file diff --git a/dist/big-picture-receive/12.svg b/dist/big-picture-receive/12.svg new file mode 100644 index 0000000..5f4a28a --- /dev/null +++ b/dist/big-picture-receive/12.svg @@ -0,0 +1,3 @@ + + +
Ok
Ok
Postfix
mail server
Postfix...
Other
mail server
Other...
\ No newline at end of file diff --git a/dist/big-picture-receive/13.svg b/dist/big-picture-receive/13.svg new file mode 100644 index 0000000..4ea1440 --- /dev/null +++ b/dist/big-picture-receive/13.svg @@ -0,0 +1,3 @@ + + +
RCPT TO: <john@example.org>
RCPT TO: <john@example.org>
Postfix
mail server
Postfix...
Other
mail server
Other...
That email is meant for john@example.org
That email is meant f...
\ No newline at end of file diff --git a/dist/big-picture-receive/14.svg b/dist/big-picture-receive/14.svg new file mode 100644 index 0000000..3d44682 --- /dev/null +++ b/dist/big-picture-receive/14.svg @@ -0,0 +1,3 @@ + + +
Postfix
mail server
Postfix...
Other
mail server
Other...
MariaDB
database
MariaDB...
Is example.org our domain?
Is example.org o...
\ No newline at end of file diff --git a/dist/big-picture-receive/15.svg b/dist/big-picture-receive/15.svg new file mode 100644 index 0000000..4c93635 --- /dev/null +++ b/dist/big-picture-receive/15.svg @@ -0,0 +1,3 @@ + + +
Postfix
mail server
Postfix...
Other
mail server
Other...
MariaDB
database
MariaDB...
Yes, I found it in my virtual_domains table
Yes, I found it in...
\ No newline at end of file diff --git a/dist/big-picture-receive/16.svg b/dist/big-picture-receive/16.svg new file mode 100644 index 0000000..470b01b --- /dev/null +++ b/dist/big-picture-receive/16.svg @@ -0,0 +1,3 @@ + + +
Postfix
mail server
Postfix...
Other
mail server
Other...
MariaDB
database
MariaDB...
And is john@example.org a known user?
And is john@example.or...
\ No newline at end of file diff --git a/dist/big-picture-receive/17.svg b/dist/big-picture-receive/17.svg new file mode 100644 index 0000000..33bca2a --- /dev/null +++ b/dist/big-picture-receive/17.svg @@ -0,0 +1,3 @@ + + +
Postfix
mail server
Postfix...
Other
mail server
Other...
MariaDB
database
MariaDB...
Yes, I found it in my virtual_users table
Yes, I found it in my...
\ No newline at end of file diff --git a/dist/big-picture-receive/18.svg b/dist/big-picture-receive/18.svg new file mode 100644 index 0000000..74d239b --- /dev/null +++ b/dist/big-picture-receive/18.svg @@ -0,0 +1,3 @@ + + +
Ok
Ok
Postfix
mail server
Postfix...
Other
mail server
Other...
Looks good.
Looks good.
\ No newline at end of file diff --git a/dist/big-picture-receive/19.svg b/dist/big-picture-receive/19.svg new file mode 100644 index 0000000..a91c7ab --- /dev/null +++ b/dist/big-picture-receive/19.svg @@ -0,0 +1,3 @@ + + +
DATA
DATA
Postfix
mail server
Postfix...
Other
mail server
Other...
Let me send you the email now
Let me send you t...
\ No newline at end of file diff --git a/dist/big-picture-receive/20.svg b/dist/big-picture-receive/20.svg new file mode 100644 index 0000000..fd0f66f --- /dev/null +++ b/dist/big-picture-receive/20.svg @@ -0,0 +1,3 @@ + + +
TCP port 11332
TCP port 11332
Postfix
mail server
Postfix...
Other
mail server
Other...
rspamd
Spam check
rspamd...
Do you think this email is spam?
Do you think this...
\ No newline at end of file diff --git a/dist/big-picture-receive/21.svg b/dist/big-picture-receive/21.svg new file mode 100644 index 0000000..4316f8d --- /dev/null +++ b/dist/big-picture-receive/21.svg @@ -0,0 +1,3 @@ + + +
Postfix
mail server
Postfix...
Other
mail server
Other...
rspamd
Spam check
rspamd...
A few minor issues but the email seems legit
A few minor issues...
\ No newline at end of file diff --git a/dist/big-picture-receive/22.svg b/dist/big-picture-receive/22.svg new file mode 100644 index 0000000..1302dd3 --- /dev/null +++ b/dist/big-picture-receive/22.svg @@ -0,0 +1,3 @@ + + +
250 2.0.0 Ok: queued as 7855B7FD86
250 2.0.0 Ok: queued as 7855B7FD86
Postfix
mail server
Postfix...
Other
mail server
Other...
Thanks. I will deliver it.
Thanks. I will d...
\ No newline at end of file diff --git a/dist/big-picture-receive/23.svg b/dist/big-picture-receive/23.svg new file mode 100644 index 0000000..07935e8 --- /dev/null +++ b/dist/big-picture-receive/23.svg @@ -0,0 +1,3 @@ + + +
LMTP
LMTP
Postfix
mail server
Postfix...
Please save this new email for john@example.org
Please save this new e...
Dovecot
IMAP server
Dovecot...
\ No newline at end of file diff --git a/dist/big-picture-receive/24.svg b/dist/big-picture-receive/24.svg new file mode 100644 index 0000000..8a5c994 --- /dev/null +++ b/dist/big-picture-receive/24.svg @@ -0,0 +1,3 @@ + + +
Postfix
mail server
Postfix...
Dovecot
IMAP server
Dovecot...
/var/vmail
/var/vmail
Alright. Saving to disk.
Alright. Saving...
\ No newline at end of file diff --git a/dist/debian-packages-are-so-old/index.html b/dist/debian-packages-are-so-old/index.html new file mode 100644 index 0000000..add8d32 --- /dev/null +++ b/dist/debian-packages-are-so-old/index.html @@ -0,0 +1,118 @@ + Debian packages are so old | ISPmail Guide + Skip to content

Debian packages are so old

Debian comes with tens of thousands of software packages that you can easily install on your system. But Debian only publishes a new “stable” release every 2-3 years. That creates the impression that Debian packages must always be up to 3 years old. And who wants to work with a three year old piece of software? Are the package maintainers lazy? Should I download my software from its own project website instead?

+

I feel obliged to briefly discuss this topic because it is a common source of trouble and surprises. And it may make you say…

+

“What’s the deal? Shouldn’t we just use Debian packages where we find it comfortable and install any other software in a newer version? Just look at the shiny new Roundcube version. Oh, and rspamd has some new features to filter out spam mails. Why don’t we use that? Even their developers urge me to take their updated packages.”

+

So… why are the packages in the “stable” version of Debian so old? Actually that question is pretty funny when you think about it. “stable” means “stay on the same versions if possible”. You might say that it means “old by design”. The idea is that your system will not surprise you with an unexpected update that breaks a service for many users on a monday morning.

+ +

No. “stable” relates to the version. I does not necessarily mean more “robust”. The Debian developers do not pick a certain version that they think is especially good or bug-free. The version that made it into a new stable release of Debian was just there when it was about time to create a new release.

+

And what about security issues? Software developer usually fix issues in a newer version. How does Debian deal with that?

+

That is true. Developers hardly ever fix issues in old software. That’s just not fun. Developers like to go forward. While they implement new features they also fix issues on their way. I totally understand that motivation. But that way they force users to accept their changes and new features even if the users just want to fix the security issues. And new versions come with new bugs.

+

Debian however always tries to backport bug fixes. A Debian package maintainer will try to apply the fix to the stable version in Debian. So you get the benefit of staying on a certain version but at the same time get security updates. That makes it the best possible way to deal with security issues for server administrators. They can rely on their systems without having to fear breaking changes. Only when a new stable version arrives they are forced to consider upgrading.

+

See also the Debian FAQ on security.

+ +

Aside from stable packages there are also unstable packages. Let’s take a look at packages.debian.org/vlc to see which package versions of the famous VLC software are available. This is just a screenshot so you will get different versions:

+

Screenshot of packages.debian.org

+

As you can see there are the different releases like “jessie” (very old), “stretch” (old), “buster” (the stable version when this was written), “bullseye” (the upcoming stable release) and “sid”. By default your system will install the current stable version. If you are on Debian “buster” then it will be 3.0.12-0.

+

If you wanted newer software you could just replace “buster” by “sid” in your /etc/apt/sources.list and upgrade your system. Done. That way every “apt upgrade” will give you the newest packages that Debian has to offer. And in many cases that is very close to the newest version of the actual (upstream) software. Just be aware that sid/unstable is a moving target. It is impossible to coordinate all updated packages. So it may occur that a new package cannot be properly installed, does not work or even breaks something else on your system. I know people who have sid/unstable on their laptops. But those are the kind of people who know a lot about Debian and do not despair when something breaks.

+

As a middle ground you might use the “testing” variant. Only packages without any serious bugs will be copied to “testing” so you rule out the worst problems. Still this is not failsafe. There are also backported packages that try to make newer software work on an otherwise “stable” system. But this may give you security issues that are not fixed as quickly as needed. Every choice comes with its own compromises.

+

So as you see Debian’s packages are not old at all. Just when you do a fresh installation you are usually on a “stable” installation. And that’s for a reason. On a server nobody cares if a piece of software is 2 years old. The focus there is on reliability. And “stable” gives you that.

+ +

A lot of software is available directly by its developers through their own APT repositories. Can’t I just use them?

+

Of course. I also pick specific pieces of software from their third-party APT repositories. But those are very rare exceptions and I keep track of what software I get from there. Common problems are:

+
    +
  • unexpected updates that break your system
  • +
  • broken packages because building proper Debian packages is not trivial
  • +
  • uninstallable packages the first weeks after a new Debian release because the software was not properly tested with it
  • +
  • conflicts with other packages in your system because a package did not properly specify that
  • +
  • missing integration with other software (e.g. Apache configuration, logrotate or systemd)
  • +
  • no security support like in Debian. To stay safe you are required to run every update. That in turn means adopting any breaking changes.
  • +
  • files of third-party software should go to /opt but quite often they are scattered in the wrong places
  • +
  • expired APT keys because the developers didn’t care about expiry dates
  • +
+

However not all is bad. Some third-party packages are very good. Your mileage may vary though.

\ No newline at end of file diff --git a/dist/favicon.svg b/dist/favicon.svg new file mode 100644 index 0000000..932dba3 --- /dev/null +++ b/dist/favicon.svg @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/dist/getting-help-on-irc/index.html b/dist/getting-help-on-irc/index.html new file mode 100644 index 0000000..7ab4689 --- /dev/null +++ b/dist/getting-help-on-irc/index.html @@ -0,0 +1,137 @@ + Getting help on IRC | ISPmail Guide + Skip to content

Getting help on IRC

IRC (Internet Relay Chat) is a real-time chat where you can talk to other people from around the planet. Although many channels deal with smalltalk about the weather, girl-friends and politics there are IRC networks and channels that are dedicated to a piece of software or an operating system. irc.freenode.net for example exists to support open-source projects. In case you need urgent help or just don’t want to use a mailing list then you are welcome on IRC. IRC has been there for ages and has evolved with the time. So it may appear like a hot tub of completely mad people at first. This article is meant to help you understand how to IRC works socially and how to get the most out of it.

+ +

Do not start your conversion with “May I ask a question?” or “Can anyone help me?”. Although that may be polite in normal human interaction it does not work that way on IRC. You are supposed to just ask your question right away.

+ +

There is nothing worse than “My printer doesn’t work.” or “My mail server doesn’t work.”. How are others supposed to help you if you don’t give them any details? Make sure you include at least this information:

+

What did you try to accomplish? (I wanted to fetch my mails via POP3.) +What has happened (wrongly) instead? (But my inbox remains empty.) +What environment are you using? (I am using kmail 1.8 in KDE 3.4.) +What did you try to find the cause? (I already checked my POP3 account setup.) +Are there error messages or log files? (The error message reads: “SSL negotiation failed.”) +Has it ever worked? What did you change? (I switched accounts to a new provider. It worked before with another provider.)

+

If all this information is included then you will have a high chance of getting a useful reply.

+ +

Others only know what you tell them. If you change things silently then nobody will know about it. The worst thing you can do is say: “I changed something. Now I have another problem.” It will make others give up instantly. If you expect help you need to work with the supporters.

+ +

Your IRC client will likely show you the “topic” of a channel when you enter it. You should find some useful information about how this channel is supposed to work. Often the topic even lists URLs for FAQs and documentation. Asking something that is clearly answered in the topic is considered stupid. If there are FAQ URLs listed in the topic first check if you find your question answered there.

+ +

Do not expect a single person to stay online until your problem is fixed. IRC is a stateless medium. Anyone can quit at any time. People stay there because they like staying there. Nobody is paid for helping you.

+ +

You can either talk to others in a channel publicly or /msg them privately. However the latter is considered rude if done without being asked. Don’t occupy a single person for your purpose. Others may as well be interested in a solution to your problem, too.

+ +

Sometimes you may feel that others are rude. You may get a response like “Reinstall the package. Restart the service. Read the /usr/share/doc/mysoftware/README.” Although this is a very brief reply it is likely not meant to be rude. IRC is often like human interaction without all the friendly bits. Other people have probably answered your question a dozen times today and they just want to help you solve the problem - not become close friends with you. Don’t be offended by it.

+ +

Asking the same question every minute is annoying. If anyone in the channel isn’t paying attention then they will neither read you the second and third time. And those who came back from lunch or sleep will likely see in their “lastlog” what has happened lately.

+ +

In most channels the only language spoken is English. There are certain local channels like #debian-fr which are specifically for frenchmen. But everywhere else you must not write anything but English. It doesn’t matter if you consider your English language skills bad. Most people in the world speak something different than English, too. And if you find another person that speaks your language then do not start to talk in your local language. Nobody else can follow you and it’s considered rude.

+ +

If people tell you to read the documentation then you should do so. Never say: “I’m too lazy. Come on. You all know what I need to do. Just tell me the solution.” This will get you ignored for all eternity. However you can expect to be told where to find the documentation. If you get a URL then follow it and read it. If the documentation is too technical or you don’t understand certain sections then be more specific like: “I have now read chapter 3.1 of the URL you gave me and I understand how virtual domains work in general. But how would I use both virtual and non-virtual domains together?”

+ +

Even if you are in a hurry you should allow other participants some time to answer. Sometimes you are lucky and a helpful reply appears within a few seconds. But it is not uncommon that you will have to wait 10-20 minutes until the right person who is familiar with your problem talks to you. The pattern looks something like this:

+

10:07 Foo joins +10:07 Foo> How can I install the shripdibble module? +10:09 Foo quit

+

Then at 10:14 an expert on shripdibble joins but can’t help you any more because you gave up too quickly.

+ +

Using IRC is a matter of give and take. At the beginning you will surely have more questions than answers. Just ask them and be grateful if you get attention and replies. Others do not expect more than a “Thank you.” for their help.

+

If you can, please consider staying online in the channel. The more knowledge you gain the more you can help other people. And you probably get to know people you like to hang out with - even if it’s just virtually.

+ +

It may sometimes be hard to follow all the conversation on IRC. But if people are trying to help you and need to ask you a few questions please answer them all. If you get asked three questions and only answer one or keep asking the same question time and again (showing that you don’t read what you get asked) you risk to be ignored. Show some initiative and stay focused. Then your problem will likely be fixed within a few minutes.

+ +

It doesn’t help anyone if you just say “Nevermind, found it.” and quit the channel. Please tell the others what the solution to your problem was so everybody can learn from it. You will not look stupid - trust me.

+ +

When getting responses be careful who you trust. Some people just want to feel important and reply to you although they have no more clue than you do. Perhaps even an “educated guess” might help - just make clear if it’s something that was tried and worked. Some people are even jokers who want to be funny by telling you how to erase your harddisk. So verify others’ proposals instead of applying them blindly.

+ +

Sometimes you need to show others more than one line. Perhaps parts of your configuration files or a log file. Never just copy and paste larger amounts of text right into the channel. Always use a pastebin. Pastebins are public services (web sites) where you can paste your text and everybody can access them as a URL. Just paste your contents there and send the URL into the channel. That should allow everybody who’s interested to take a look. Just don’t paste it without any comment. Rather say: “Emails seem to get lost since I installed program foobar. Please take a look at my logs: http://…”

+

Related links

+

See also:

+
\ No newline at end of file diff --git a/dist/imapsieve/imapsieve-learn-spam.svg b/dist/imapsieve/imapsieve-learn-spam.svg new file mode 100644 index 0000000..e5b14a6 --- /dev/null +++ b/dist/imapsieve/imapsieve-learn-spam.svg @@ -0,0 +1,3 @@ + + +
mailbox Junk {
sieve_script spam {
type = before
cause = copy
path = /etc/dovecot/sieve/learn-spam.sieve
}
}
require ["vnd.dovecot.pipe", "copy", "imapsieve"];
pipe :copy "rspamd-learn-spam.sh";
#!/bin/sh
exec /usr/bin/rspamc learn_spam
IMAP sieve
Sieve
Shell
Page 1
https://webmail.example.org
Inbox
Junk
Trash
The blue pill for your hardest night. Buy now.
MOVE
From: wienermeds@gmail.com
Watch this folder
\ No newline at end of file diff --git a/dist/index.html b/dist/index.html new file mode 100644 index 0000000..7ca71a6 --- /dev/null +++ b/dist/index.html @@ -0,0 +1,158 @@ + Welcome to ISPmail – a free guide to your own mail server | ISPmail Guide + Skip to content
The guide has been updated for Debian 13! +

Welcome to ISPmail – a free guide to your own mail server

ISPmail is a free but extensive do-it-yourself guide to help you build a fully-functional mail server from 100% open-source components. It is based on Debian GNU/Linux. Light enough for your friends and family. Or powerful enough for professional use.
+

Educational

This is not a simple copy/paste walkthrough. You will learn the technical details of email exchange on the internet. +And you will understand how the different pieces of software work and interact.

Free

This guide is a not-for-profit fun project. You only need to get an internet domain and a cheap virtual server +(~5€/$ per month). Powered by the desire to make the internet a bit more decentralized.

Since 2003

This guide has been maintained for over 20 years. Made for nerds who want a boring stable mail server that just +works with little maintenance. But with all the features that make it fun.

You’re not alone

You won’t get stuck. Every page of this guide has a comment section to ask questions and discuss the topic. For +real-time help you can join our support chat on Matrix.

Open source

All software that is used is completely open-source. No costs. Your new friends are Debian, Postfix, Dovecot, +Roundcube, MariaDB, Apache and rspamd.

Standards

Only standard protocols are used. IMAP, POP3, SMTP and HTTPS. No proprietary protocols. No vendor lock-in. No public +cloud.

+ +
    +
  • +

    Kostja:

    +

    I have been using the workaround.org ISPMAIL tutorials for many years and still do it every time I upgrade my +mailserver. It is a neat and straightforward approach and saves me a lot of time I otherwise would have to spend +reading manuals, finding new packages and trying things out. Everything is on the point and I get the information I +need, that’s perfect. Thank you very much for you great work.

    +
  • +
  • +

    David:

    +

    I just finished setting up my ~fifth ispmail server (squeeze, 2x stretch, now bullseye) and this time I didn’t even +bother to do the recommended checks after each step because I knew that after following (and unterstanding) your +tutorial, the server would go like a Swiss watch. I wasn’t disappointed. Everything works and again I learned a lot. +Thank you for putting that much effort into the tutorials!

    +
  • +
  • +

    Yannis:

    +

    Just wanted to say thanks for your amazing work. Not only proved up to date and accurate technically, but it is also +presented in a very educational way. It really is high-quality learning material.

    +
  • +
  • +

    Ezerotszaz:

    +

    I’m finally done setting up two of these mail servers – for myself and also for a friend. I struggled a lot when I was +doing it for the first time, but after days of work it is done, it is working properly, I can send(and receive..) from +four different addresses and I could not be happier! Thank you so much for the insane amount of work that you put into +this awesome guide.

    +
  • +
  • +

    Impli:

    +

    It had been a long time since I had installed a mail server and the few tutorials I could find were not explicit. But +your guide is very well done. Complete and very detailed. With even some technical information as a bonus for the +curious.

    +
  • +
  • +

    Niko:

    +

    I really like this guide. I was able to learn some new stuff and setup a nice configured server. I now have a server +running 2 domains and several user accounts. It took me a few evenings of my spare time and i think it was worth it. +Thank you very much for your guidance!

    +
  • +
  • +

    Michael:

    +

    Great guide! Thanks! Very structured and clear! It took me about 2 hours to have a fully funktional email server +including ISPmail on a Raspberry Pi 3 Model B Rev 1.2 with Raspbian GNU/Linux 11.

    +
  • +
  • +

    David:

    +

    Thank you so very much Christoph. I now have a successful mail server running on Linode, and it has all the pieces you +have detailed here. It works very well. Best of all, I understand how the pieces hang together.

    +
  • +
  • +

    Shukuru:

    +

    This guide is pure gold. As a professional developer with some sysadmin skills I was able to set up my first email +server in a week. I learn a lot about how emails works and I can now take control on my privacy. Thanks.

    +
  • +
  • +

    Panos:

    +

    I am proud to be able to thank the author of this series of Guides publicly, for all the unbelievable work he has +done, all these years. To anyone wishing to truly understand what running a mail server is about, this is the proper +place to be.

    +
  • +
  • +

    Cody:

    +

    Seen this guide a few times before and found it to be the most comprehensive one available.

    +
  • +
  • +

    Anthony:

    +

    Thanks again for such a comprehensive guide. I’ve been using it for several years and I appreciate the updates for the +new versions. I just did a “speed run” on a test mail server/domain and it took about 2 hours. TLS/DKIM/SPF are all +passing too! I’ve gotten a lot of practice with your guide over the last few versions, so I would hope that I can +complete it quickly.

    +
  • +
  • +

    James:

    +

    Thanks Christoph, For your work running this site and the ISPmail guides. I’ve been following them for each Debian +release since Wheezy. I use my mail server primarily for my personal email address and also have a handful of friends +using it. Works great.

    +
  • +
  • +

    Robbert:

    +

    I have been using this guide for 10 years now with great success. I truly appreciate how you explain each step you do. +This makes it very easy to follow, and also easy to deviate from the guide if desired. Thanks a lot.

    +
  • +
  • +

    Nicole:

    +

    I used this guide already with my first mail servers I set up 15 years ago (round about, I’m not quite sure). It +always worked fine and is a very big help! I have Debian servers with 5 – 30 users only, including one community +project where also newsletters (i.e. many mails) are sent. Today I set up my newest mail server and all works fine. I +want to thank Christoph for his great work and support and hope the guide will never end 🙂

    +
  • +
  • +

    Francisco:

    +

    Thank you Christoph. I’ve just setup my mail server and i’m very happy with it. I’ve learned a lot.

    +
  • +

Last updated:

+This guide is maintained by Christoph Haas since 2003. All content on workaround.org can be used under the terms of + the +Creative Commons BY-NC-SA license. + Penguin image based on AI art because I suck at drawing. +
\ No newline at end of file diff --git a/dist/ispmail-bookworm/automatic-installation-with-ansible/index.html b/dist/ispmail-bookworm/automatic-installation-with-ansible/index.html new file mode 100644 index 0000000..babe74f --- /dev/null +++ b/dist/ispmail-bookworm/automatic-installation-with-ansible/index.html @@ -0,0 +1,93 @@ + Automatic installation with Ansible | ISPmail Guide + Skip to content
+⚠️ This page is part of the ISPmail guide for Debian Bookworm. Please use the newer guide for Debian Trixie. +

Automatic installation with Ansible

If you want to set up multiple mail servers then automation is your friend. Nowadays Ansible is commonly used for that purpose. If you are dealing with system administration you should have such a tool in your toolbox.

+

I have created an Ansible playbook on Github that you can download and use. Using it is pretty simple:

+
apt install ansible git
git clone https://github.com/Signum/ispmail-bookworm-ansible.git
cd ispmail-bookworm-ansible/ansible
ansible-playbook ispmail.yml -c local
+

Please follow the hints in the README.md within the repository.

\ No newline at end of file diff --git a/dist/ispmail-bookworm/big-picture/index.html b/dist/ispmail-bookworm/big-picture/index.html new file mode 100644 index 0000000..909c603 --- /dev/null +++ b/dist/ispmail-bookworm/big-picture/index.html @@ -0,0 +1,165 @@ + The big picture | ISPmail Guide + Skip to content
+⚠️ This page is part of the ISPmail guide for Debian Bookworm. Please use the newer guide for Debian Trixie. +

The big picture

The mail server that you are about to set up uses several software components. Let me first explain briefly what the purpose of each software is:

+
    +
  • Debian “Bookworm” – the operating system
  • +
  • Postfix receives incoming emails from the internet and sends out outgoing emails to other mail servers. It is the software that speaks SMTP.
  • +
  • rspamd runs sanity checks on an incoming email to determine whether it is spam.
  • +
  • Dovecot stores emails on your hard disk, applies filters and lets your users fetch their emails using the POP3 and IMAP protocols
  • +
  • Roundcube is a webmail interface so users can read their emails using a web browser, manage their email rules and change their password
  • +
  • MariaDB (formerly known as MySQL) is a database that stores information about your domains, email aliases and email accounts
  • +
+

What happens when someone sends you an email?

Section titled “What happens when someone sends you an email?”
+

Let us assume that you are responsible for the email domain example.org and someone on the internet sends an email to john@example.org. This is what happens step by step:

+
    +
  1. REMOTE: Hey, DNS server. I have an email for someone in the example.org domain. Can you tell me the name of the responsible mail server?
    +DNS: According to the DNS zone of example.org it is mx.example.org.
  2. +
  3. REMOTE: Nice. Do you have an an IP address for mx.example.org?
    +DNS: I have an IPv4 address here. It is 85.25.72.76.
  4. +
  5. REMOTE connects to that IP address on TCP port 25 which is by definition used for SMTP – the simple mail transport protocol.
    +POSTFIX: Welcome. I am Postfix. Who is there? (“220 mx.example.org ESMTP Postfix”)
    +REMOTE: Hi, I am remote server. (“EHLO remoteserver”)
    +POSTFIX: Nice to meet you. I can offer a few features like pipelining and encryption by the way. (“STARTTLS, PIPELINING, SIZE 4000000, …”)
    +REMOTE: Let’s switch to an encrypted connection. (“STARTTLS”)
    +(The connection is now using TLS encryption.)
    +REMOTE: I have an email from donald@duck.com here. (“MAIL FROM:<donald@duck.com>”)
    +POSTFIX: I see. (“Ok”)
    +REMOTE: The email is meant for john@example.org. (“RCPT TO:<john@example.org>”)
  6. +
  7. POSTFIX: Hey database. (Connects to TCP port 3306 on the local host to talk to MariaDB.) Could you check if example.org is one of our mail domains? (“SELECT … from virtual_domains …”)
    +MariaDB: Yes, I have a domain like that.
    +POSTFIX: Oh, good. And do you have a mailbox or forwarding for someone called john@example.org? (“SELECT … from virtual_aliases/virtual_users …”)
    +MariaDB: Yes, there is a mailbox for that address.
    +POSTIFX: Hey, remote server. The recipient looks good. (“Ok”)
    +REMOTE: Roger. Then here’s the actual email. (“DATA”)
    +(The remote server sends the email header and body.)
  8. +
  9. (POSTFIX connects to port 11332 on the local host to reach the rspamd.)
    +POSTFIX: Hey, rspamd. I have a new email here. Could you give it a look for, you know, spam and stuff?
    +RSPAMD: Sure. Well, there are a few minor issues. But generally the mail looks good. I suggest you accept it.
    +POSTFIX: Hey, remote server. Your email is fine.
  10. +
  11. (Postfix uses a socket file at /var/spool/postfix/private/dovecot-lmtp to talk to Dovecot.)
    +POSTFIX: Hey, Dovecot. Here is a new email for john@example.org. +DOVECOT: Got it.
  12. +
  13. (Dovecot checks for additional Sieve rules and then stores the email on disk at /var/vmail/example.org/john/Maildir/INBOX)
  14. +
+

Phew, that was a lot. I hope it helps to understand though how the different components are involved until an email gets delivered.

+

The next situation I would like to explain is…

+

What happens if a user fetches their email using IMAP/POP3?

Section titled “What happens if a user fetches their email using IMAP/POP3?”
+

This process is way simpler. It looks like this:

+

Diagram showing how a user connects via IMAP

+

User connects through IMAP

+
    +
  1. The user usually has a mail client (also called a mail user agent) that can use the POP3 or IMAP protocol to fetch emails from the mail server. I prefer Thunderbird for example. That mail client connects to the POP3 (TCP 110) or IMAP (TCP 143) port, sends the STARTTLS command that initiates an encrypted connection and sends the user’s username (which equals the email address in our case) and their password. The client may as well use the secure TLS-encrypted ports directly – 995 for POPs and 993 for IMAPs. If possible users should use IMAP. POP3 is pretty much deprecated nowadays and lacks support for multiple folders on the server.
  2. +
  3. Dovecot sends a query to the MySQL database and verifies that the username and password belong to a known user. The password is not stored in plain text in the database. Instead it computes the password hash and compares it to the hash in the database. If the password is wrong then Dovecot will refuse the login.
  4. +
  5. We have a fixed scheme how emails are stored on disk. So if the user is called jane@example.org then Dovecot will look for email files in /var/vmail/example.org/jane/Maildir/… and send the user the requested emails.
  6. +
+

Nowadays many users seem to prefer webmail to a mail client installed on their computers. As an email power user I honestly do not understand that trend. But who am I to judge. So let’s take a look how webmail works technically:

+

What happens if a user reads their email using web mail?

Section titled “What happens if a user reads their email using web mail?”
+

The Roundcube software that provides the web mail interface is basically a PHP software that is a gateway between HTML pages and a built-in IMAP client. So when a user uses their browser to connect to the web mail interface…

+

Diagram showing a user connecting via Webmail

+

User connects through webmail

+
    +
  1. The user points the browser to the HTTPS URL of the webmail interface. Apache web server receives the connection and runs the PHP scripts of Roundcube. Roundcube shows a login form for the username and password. The user enters the username (that equals the email address) and the password and submits the login form.
  2. +
  3. Roundcube connects to Dovecot using IMAP and forwards the username and password to check if they are valid.
  4. +
  5. Dovecot treats this connection similar to a mail client connection. It queries the MariaDB database to verify the username (=email address) and password.
  6. +
  7. If the authentication was successful Dovecot fetches the mail files from disk and sends them through IMAP to Roundcube. Roundcube then renders the emails as HTML and the user can read it.
  8. +
+

So you see that the web mail access also works through IMAP. The user does not realize that though.

+

Okay, the final scenario I would like to explain is…

+

What happens if the user wants to send an email to the internet?

Section titled “What happens if the user wants to send an email to the internet?”
+

Of course your users also want to send emails to other internet users. But they cannot send the email directly to the destination mail server. First their mail client does not know which destination server is responsible for the recipient (hint: DNS) – that functionality just is not built in. And second the user is likely assigned a dynamic IP address which is blocked by most mail servers because they tend to get abused by infected Windows PCs that send out spam. So the correct way to send an email to the internet is through your mail server. This is called relaying because your mail server acts as a relay. In this example your user wants to send an email to fred@example.net.

+

Diagram showing a user sending an email

+

Relaying/sending email via the mail server

+
    +
  1. The user writes the email in their mail client and clicks on “Send”. The mail client establishes an SMTP connection to Postfix. To make sure that the user is allowed to send email through your system it requires a username and password along with the email. This information is sent in an encrypted way.
  2. +
  3. Postfix could now check the password in the database directly. But as Dovecot already knows how to handle authentication it is easier to ask Dovecot to verify the username and password. (SMTP authentication in Postfix is surprisingly ugly.)
  4. +
  5. Dovecot now sends a query to the MariaDB database to check if the username and password (hash) are correct and tells Postfix the result.
  6. +
  7. Postftix knows now that it is authorized to send the email on behalf of the user. It tells the user that it successfully accepted the email. The email is put into Postfix’s mail queue for further processing. Postfix will now query a DNS (name server) to determine the responsible destination mail server. As the recipient has an “…@example.net” address it checks the MX record of the “example.net” domain and then gets the respective IP address.
  8. +
  9. Postfix now knows which mail server to send the email to. It opens an SMTP connection and delivers the email.
  10. +
\ No newline at end of file diff --git a/dist/ispmail-bookworm/catchall-aliases/index.html b/dist/ispmail-bookworm/catchall-aliases/index.html new file mode 100644 index 0000000..83b680b --- /dev/null +++ b/dist/ispmail-bookworm/catchall-aliases/index.html @@ -0,0 +1,149 @@ + Catch-all aliases | ISPmail Guide + Skip to content
+⚠️ This page is part of the ISPmail guide for Debian Bookworm. Please use the newer guide for Debian Trixie. +

Catch-all aliases

+

As explained earlier in the tutorial there is way to forward all email addresses in a domain to a certain destination email address. This is called a catch-all alias. Those aliases catch all emails for a domain if there is no specific virtual user for that email address. Catchalls are considered a bad idea. It is tempting to generally forward all email addresses to one person if e.g. your marketing department requests a new email alias every week. But the drawback is that you will get more spam because spammers will send their stuff to any address of your domain. Or perhaps a sender mixed up the proper spelling of a recipient but the mail server will forward the email instead of rejecting it for a good reason. So think twice before using catchalls.

+

You still want to use catch-all addresses? Well, okay. Let’s do it then. A catchall alias looks like “@example.org” and forwards email for the whole domain to other addresses. We have created the john@example.org user and would like to forward all other email on the domain to kerstin@example.com. So we would add a catchall alias like:

+ + + + + + + + + + + + + +
sourcedestination
@example.orgkerstin@example.com
+

But there is a small catch. Postfix always checks the virtual_alias_maps mapping before looking up a user in the virtual_mailbox_maps. Imagine what happens when Postfix receives an email for ‘john@example.org’. Postfix checks the aliases in the virtual_alias_maps table. It finds the catchall entry as above and since there is no more specific alias the catchall account matches and the email is redirected to ‘kerstin@example.com’.

+

In other words: the aliases are always processed first. So a catch-all alias will steal the email. John will never get any email. This is not what you want.

+

But imagine that the aliases would contain a second entry like this:

+ + + + + + + + + + + + + + + + + +
emaildestination
@example.orgkerstin@example.com
john@example.orgjohn@example.org
+

So any email address on the example.org domain will be forwarded to kerstin’s address. But what is that second line? Why should we forward john’s emails to himself? That doesn’t make any sense.

+

Actually it does. Postfix will consider more specific aliases first. And john@example.org is more specific than @example.org. +Consider that someone is trying to reach john@example.org’s mailbox. +If Postfix read this table just from top to bottom, then it would see @example.org first, which would be a match. It would then redirect that email to kerstin. John would never again get an email.

+

So to make a mixture of catch-all addresses and specific addresses work, we need this little trickery.

+

Postfix will lookup all these mappings for each of:

+
    +
  • john@example.org (most specific)
  • +
  • @example.org (catchall – least specific)
  • +
+

This is outlined in the virtual(5) man page in the TABLE SEARCH ORDER section.

+

We do not want to add that “more specific” entry for each email address manually. Fortunately we can easily automate that. For that “john-to-himself” mapping you need to create another “.cf” file /etc/postfix/mysql-email2email.cf for the latter mapping:

+
user = mailserver
password = x893dNj4stkHy1MKQq0USWBaX4ZZdq
hosts = 127.0.0.1
dbname = mailserver
query = SELECT email FROM virtual_users WHERE email='%s'
+

Check that you get John’s email address back when you ask Postfix if there are any aliases for him:

+
postmap -q john@example.org mysql:/etc/postfix/mysql-email2email.cf
+

The result should be the same address:

+
john@example.org
+

Now you need to tell Postfix that it should check both the aliases and the “john-to-himself”:

+

postconf virtual_alias_maps=mysql:/etc/postfix/mysql-virtual-alias-maps.cf,mysql:/etc/postfix/mysql-email2email.cf

+

The order of the two mappings is not important here. Postfix will check all ‘cf’ files anyway and merges what it finds.

+

You did it! All mappings are set up and the database is generally ready to be filled with domains and users. Make sure that only ‘root’ and the ‘postfix’ user can read the “.cf” files – after all your database password is stored there:

+
chgrp postfix /etc/postfix/mysql-*.cf
chmod u=rw,g=r,o= /etc/postfix/mysql-*.cf
\ No newline at end of file diff --git a/dist/ispmail-bookworm/catching-spam-with-rspamd/index.html b/dist/ispmail-bookworm/catching-spam-with-rspamd/index.html new file mode 100644 index 0000000..9bbef5c --- /dev/null +++ b/dist/ispmail-bookworm/catching-spam-with-rspamd/index.html @@ -0,0 +1,286 @@ + Catching spam with rspamd | ISPmail Guide + Skip to content
+⚠️ This page is part of the ISPmail guide for Debian Bookworm. Please use the newer guide for Debian Trixie. +

Catching spam with rspamd

+

You have come a long way in this guide and your mail server is already fully functional. Now it’s time to deal with the dark side: spam. And there will be lots of it. So we need to detect spam emails and filter them out. I found that rspamd is a well-performing choice for that purpose both in speed and detection. rspamd keeps a permanent process running on your mail server that listens to connections from Postfix using the milter (=mail filter) protocol. Every time an email enters your system, Postfix will send it to rspamd to have its content checked. rspamd runs a lot of checks on the email and computes a total score. The higher the score – the more likely the email should be considered unsolicited.

+ +

rspamd is quite effective against spam thanks to its many kinds of checks that incoming emails run through. Several of these checks rely on services provided by the rspamd project. There are web sites like email.rspamd.com, uribl.rspamd.com and maps.rspamd.com that provide information used by the default rspamd installation. That data is not freely available and there are no public mirrors.

+

You are only allowed to use their data under certain conditions described in rspamd’s usage policy. Spoiler: heavy or commercial usage will get you blocked. So it may be wise to disable all features that include his email and URL blacklists and the “fuzzy” feature.

+

rspamd is being packaged and shipped by the Debian project. However the rspamd principal developer builds and endorses his own packages and has a history of getting angry and offensive against anyone using the packages shipped by Debian. I find that attitude a bit suspicious and rather stay with the Debian packages that have been built by a process that I trust.

+ +

Let’s tell Postfix to send all incoming email through rspamd. Run these commands on the shell:

+
postconf smtpd_milters=inet:127.0.0.1:11332
postconf non_smtpd_milters=inet:127.0.0.1:11332
postconf milter_mail_macros="i {mail_addr} {client_addr} {client_name} {auth_authen}"
+

Postfix will connect to rspamd that is listening to TCP port 11332 on localhost (127.0.0.1) and send the email through that connection. The smtpd_milters setting defines that connection for emails that came into the system from the internet via the SMTP protocol. The non_smtpd_milters setting is optional – it makes Postfix have all emails checked that originate from the system itself. Finally the milter_mail_macros setting defines several variables that rspamd expects for better spam detection. rspamd then runs its checks and tells Postfix whether the email should pass or get rejected.

+ +

For testing we can use a sample spam email that comes with SpamAssassin. It is called GTUBE (Generic Test for Unsolicited Bulk Email). It contains a certain artificial pattern that is recognized as spam by SpamAssassin. Do you know EICAR.COM to test virus scanners? This is the same thing for spam.

+

I suggest that you download the file on the server:

+
wget http://spamassassin.apache.org/gtube/gtube.txt
+

…and send that email to our test user John…

+
sendmail john@example.org < gtube.txt
+

Check your /var/log/mail.log. You will find something like this:

+
Jan 13 09:21:01 mail postfix/cleanup[19945]: 95B7A42212: milter-reject: END-OF-MESSAGE from localhost[127.0.0.1]: 5.7.1 Gtube pattern; from=<root@mail.example.org> to=<john@example.org>
+
Jan 13 09:21:01 jen postfix/cleanup[19945]: 95B7A42212: to=<john@example.org>, relay=none, delay=0.18, delays=0.18/0/0/0, dsn=5.7.1, status=bounced (Gtube pattern)
+

“milter-reject” tells that the milter (rspamd) recommended to Postfix to reject the email. It gave the reason “5.7.1 Gtube pattern”. In mail communication you often find these three digit codes. They are defined in RFC 3463. The first digit is most important:

+
    +
  • 2 = Success
  • +
  • 4 = Transient failure (temporary problem – come back later)
  • +
  • 5 = Permanent failure (do not try again in this way)
  • +
+

So 5.7.1 tells us that the result code is a permanent failure in delivery. If you looked up the RFC you would find that the 7 stands for an issue regarding the security policy. So it’s not a technical failure but instead a security-relevant component on the system has rejected the email. That’s what rspamd did. It even told us the reason: “Gtube pattern”. So you see that rspamd knows about the Gtube spam test pattern and reacts as expected.

+

Accordingly you won’t see this email in John’s inbox. This is a great advantage of using milters. Imagine Postfix receiving a spam email and confirm its reception. What should it do when it finds out that it’s unwanted email? According to the SMTP protocol it must not throw away any emails. Would you create a bounce message telling the sender that you did not accept the email? That would be a bad idea because the sender address in spam emails is very likely forged. You would send the bounce to an innocent person thus creating so called backscatter and make it even worse. So the better approach is to check the email while the sending server is still connected to your Postfix. This allows Postfix to reject the email with a 5.x.x error code and let the other side figure out what to do.

+ +

rspamd will however not reject all spam email. It computes a score that tells how likely a certain email is spam. You can tell it which scores you would accept, flag as spam or make the incoming email get rejected. Rspamd has a large ruleset that checks incoming emails in various ways and adds to the score. Take a look at the /etc/rspamd/actions.conf file:

+
actions {
reject = 15;
add_header = 6;
greylist = 4;
}
+

These are the default actions. If rspamd computes a score of at least 15 then the email will get rejected at the doorstep just like the Gtube pattern in the previous test. Any other score above 6 will add a line “X-Spam: Yes” so that your mail software can detect them and maybe file the email to a different folder. And any other score above 4 will trigger greylisting which is a mechanism that temporarily rejects the email with a 4.x.x code and waits if the sending server will try again. After a waiting time of a few minutes greylisting will accept the email. The idea is to reject email from systems that do not have a sending queue. Malware like on infected Wind*ws computers used to try sending an email just once which triggered greylisting and successfully rejected the spammer. But even malware programmers have learned and may try again after a few minutes thus circumventing greylisting. Your mileage may vary. The problem with greylisting is that the recipient has to wait a couple of minutes for the email to be delivered which is often bothering the users.

+

If you like to change these defaults then create a new file in /etc/rspamd/local.d/actions.conf containing your desired limits:

+
reject = 150;
add_header = 6;
greylist = 4;
+

This would virtually never reject an email. The other two values are pretty sane defaults. I personally use this setting all the time so that users can find spam in their Junk folder but don’t have to ask me if the mail server rejected it.

+

Please take a moment to understand how to change rspamd defaults. You can either create files in /etc/rspamd/override.d/… which will replace entire sections; or create files in /etc/rspamd/local.d/… which will change only parts of the configuration. There is a helpful page in the rspamd documentation that contains examples. Whatever you do – never change the /etc/rspamd/* files directly because a software update will try to replace them.

+

Restart rspamd after any configuration changes:

+
systemctl restart rspamd
+

To check if rspamd has picked up your configuration use this command to see the current configuration:

+
rspamadm configdump
+

You may test your configuration using

+
rspamadm configtest
+

Alternatively you may check if all required rspamd processes are running…

+
pgrep -a rspam
+
141693 rspamd: main process
141694 rspamd: rspamd\_proxy process (localhost:11332)
141695 rspamd: controller process (localhost:11334)
104965 rspamd: normal process (localhost:11333)
104966 rspamd: normal process (localhost:11333)
+ +

As you may know an email consists of the headers and the body. Your users will usually only see common header information like the subject, the sender, the recipient and the date and time the email was sent. But there is way more information like the route the email traveled or extended headers added by the various mail server on the way to the destination. Such extended headers begin with an “X-“. rspamd can add such headers to help you filter out spam. For that purpose create a new configuration override file at /etc/rspamd/override.d/milter_headers.conf with this content:

+
extended_spam_headers = true;
+

Again restart rspamd:

+
systemctl restart rspamd
+

As documented it will add these headers:

+
X-Rspamd-Server: mail
Authentication-Results: dmarc=fail reason="No valid SPF, No valid DKIM" …
X-Rspamd-Queue-Id: C22E55A005B3
X-Spamd-Result: default: False [11.55 / 15.00]
R_PARTS_DIFFER(0.27)[63.4%]
FROM_NO_DN(0.00)[]
RCVD_COUNT_ZERO(0.00)[0]
R_DKIM_NA(0.00)[]
FUZZY_DENIED(12.00)[1:19305c7fdd:1.00:bin,1:35699594fd:0.91:txt]
RBL_SENDERSCORE(2.00)[55.181.23.94.bl.score.senderscore.com]
ARC_NA(0.00)[]
RCPT_COUNT_ONE(0.00)[1]
RCVD_TLS_ALL(0.00)[]
FROM_EQ_ENVFROM(0.00)[]
R_SPF_SOFTFAIL(0.00)[~all]
BAYES_HAM(-2.71)[98.75%]
TO_MATCH_ENVRCPT_ALL(0.00)[]
MIME_GOOD(-0.10)[multipart/related,multipart/alternative,text/plain]
MID_RHS_MATCH_FROM(0.00)[]
ASN(0.00)[asn:16276, ipnet:94.23.0.0/16, country:FR]
TO_DN_NONE(0.00)[]
DMARC_POLICY_SOFTFAIL(0.10)[Chronopost.fr : No valid SPF, No valid DKIM,none]
SUBJECT_ENDS_EXCLAIM(0.00)[]
X-Spam: Yes
+ +

Each of the uppercase symbols like FROM_HAS_DN means that a certain detection rule of rspamd was triggered. It does not necessarily mean something bad about the email. For example R_SPF_ALLOW has a negative score that lowers the total score because it is something good about the email. There are a several symbols with a 0.00 score. These do not change the score but show you what rspamd has found. But if you consider certain criteria good or bad then you can define your own scores for them.

+

The last line here is especially interesting because next on our list is…

+ +

Your users will not realize that their spam emails have an added “X-Spam: Yes” header. It is not actively shown in their mail client. Nor does it move the email out of the inbox into their spam folder. Such emails just appear like normal in their inbox. So let’s aid them by moving spam to a separate Junk folder beneath their inbox automatically. Dovecot has support for Sieve filters which are scripts that run automatically whenever an email comes in.

+

John could create a new Sieve filter (e.g. using the Roundcube webmail interface) for himself that would save any emails to his “Junk” folder if the header line “X-Spam: Yes” was found. This rule would be useful for all your users though so let’s find a more general solution.

+

Dovecot supports global Sieve filters that apply to all users. Edit the file /etc/dovecot/conf.d/90-sieve.conf. Look for the “sieve_after” lines. They are commented out. Add a new line there:

+
sieve_after = /etc/dovecot/sieve-after
+

And restart Dovecot:

+
systemctl restart dovecot
+

The “sieve after” filters are executed after the users’ filters. John can define his own filter rules. And after that Dovecot will run any filter rules it finds in files in /etc/dovecot/sieve-after. That is just an arbitrary directory that you create:

+
mkdir /etc/dovecot/sieve-after
+

And add a new file /etc/dovecot/sieve-after/spam-to-folder.sieve reading:

+
require ["fileinto"];
+
if header :contains "X-Spam" "Yes" {
fileinto "Junk";
stop;
}
+

The “require” lines include functionality to move emails into certain folders (fileinto) and to create folders if they don’t exist yet (mailbox). Then if rspamd marked an email as spam it gets moved into the INBOX.Junk folder which just appears as “Junk” to the user underneath their inbox.

+

Dovecot cannot deal with such human-readable files though. So we need to compile it:

+
sievec /etc/dovecot/sieve-after/spam-to-folder.sieve
+

That generated a machine-readable file /etc/dovecot/sieve-after/spam-to-folder.svbin.

+

Now all your users will automatically get spam emails moved to their Junk folder. Nice – isn’t it?

+ +

Many features in Rspamd use Redis to persist their data. Let me give you a quick explanation what Redis is.

+

Redis is a kind of database system. It is way more limited than a traditional SQL database because it just stores keys and values. There aren’t several fields/columns like in SQL. But it is lightning fast the way it works. On my aged server it handles around 50,000 requests per second. It gets it speed from its simplicity and from keeping the data in RAM. So it doesn’t access the disk to fetch information. (But it copies its data to disk frequently to prevent data loss.) People use Redis as a cache or for very fast lookups of simple data structures. And so does rspamd.

+

You installed the “redis-server” package earlier. And that’s all you needed to do. It started automatically and listens ton incoming connections on TCP port 6379 on localhost. In Rspamd the Redis backend is enabled by default. You just have to tell it the IP address of your Redis server. Add a file /etc/rspamd/override.d/redis.conf and insert:

+
servers = "127.0.0.1";
+

Restart rspamd and you are done.

+
systemctl restart rspamd
+

Feel free to use Redis for other lookups, too.

+ +

One of rspamd’s features is analyzing word patterns using probability theory. That functionality is contained in its “statistical module“. (Yes, the name is pretty misleading.) Essentially you show rspamd lots of ham (good) and spam (bad) emails and its detection gets better over time.

+ + +

You can start with an empty training database. This is not as bad as it sounds. rspamd has way more functionality to determine if an email is ham or spam. Autolearning takes email that are likely ham or spam and uses them to train the spam filter. The rspamd documentation has further examples how to fine-tune auto learning. After a few hundred emails the training will contribute towards a better detection rate.

+

If you want to use autolearning just create a new file /etc/rspamd/override.d/classifier-bayes.conf and make it contain:

+
autolearn = [-5, 10];
+

That will train emails with a spam score of less than -5 as ham (good). And emails with a spam score of more than 10 as spam (unwanted). Feel free to chose other values.

+

(b) Migrating training data from previous mail server

Section titled “(b) Migrating training data from previous mail server”
+

Have you used the old SQLite-based training file on the old server? Look for files like /var/lib/rspamd/*.sqlite on the old server. In that case please follow these simple instructions from the rspamd documentation to convert them to data in Redis.

+

If instead you have used Redis already then you just need to copy over the Redis database from the old server. Stop Redis on the new server. Copy over the /var/lib/redis/dump.rdb from the old server to the new server. Start Redis again. And restart rspamd. So on the new server run:

+
systemctl stop redis
scp root@old-server:/var/lib/redis/dump.rdb /var/lib/redis
systemctl start redis
systemctl restart rspamd
+

To check if that worked you can ask Rspamd using “rspamc stat” and look for…

+
Statfile: BAYES_SPAM type: redis; length: 0; free blocks: 0;
total blocks: 0; free: 0.00%; learned: 21164; users: 214; languages: 0
Statfile: BAYES_HAM type: redis; length: 0; free blocks: 0;
total blocks: 0; free: 0.00%; learned: 1411; users: 62; languages: 0
+

(c) Training from your existing ham and spam emails

Section titled “(c) Training from your existing ham and spam emails”
+

Have you been running a mail server with mailboxes in a Malidir structure before but without rspamd? Then you probably have a good amount of ham and spam emails. Let’s use those to train rspamd. It is important to train both ham and spam emails. The rspamc command will allow you to feed entire directories/folders of emails to the learning process. An example to train spam:

+
rspamc learn\_spam /var/vmail/example.org/john/Maildir/.Junk/cur
+

And this would be an example to train ham from John’s inbox:

+
rspamc learn\_ham /var/vmail/example.org/john/Maildir/cur
+

Of course the quality of spam detection will depend on how good the source data is. If users put emails in their Junk folder which are not typical spam they will soil the detection.

+

Check the number of emails you learned by running…

+
rspamc stat
+

Bayes spam checking will not work before it learned at least 200 spam and ham emails. Teaching rspamd fewer emails or just spam emails will not work. This is defined by the min_learns variable defined in /etc/rspamd/statistic.conf.

+

In the output you will find lines beginning with “Statfile” like these…

+
Statfile: BAYES_SPAM type: redis; length: 0; free blocks: 0;
total blocks: 0; free: 0.00%; learned: 21164;
users: 214; languages: 0
+
Statfile: BAYES_HAM type: redis; length: 0; free blocks: 0;
total blocks: 0; free: 0.00%; learned: 1411;
users: 62; languages: 0
+

This is what you usually start with. The more emails you feed into the training process the better the detection rate will be. Some emails however may not be long enough or too similar to previously trained emails. So don’t worry if you are training 1000 emails but just get a count of 500 emails here.

+ +

rspamd allows you to train the spam detection per user. It would not keep a global training database that applies to all users. Instead each user gets their own training.

+

Advantage: users work differently. Some have subscribed to a sales newsletter and now believe that marking it as spam gets them unsubscribed. Yes, that’s stupid but can thoroughly confuse the spam detection. Also you might be very interested in viagr* product information while others do not.

+

Disadvantage: training still requires many ham and spam mails before it has any effect. So unless a user gets 200 samples of good and evil emails the spam detection cannot work. Many users will not get that many emails so due to the lack of spam training the detection will not be improved.

+

If you decide you want to use per-user spam training then add/edit the file /etc/rspamd/local.d/classifier-bayes.conf and insert:

+
users_enabled = true;
+ +

Andi Olsen pointed out that Dovecot has introduced a feature to automatically delete emails in a folder that reach a certain age. This is especially useful for the “Trash” and “Junk” folders. To enable this feature just edit the /etc/dovecot/conf.d/15-mailboxes.conf file and add the autoexpunge parameter where desired. Example:

+
mailbox Junk {
special_use = \Junk
auto = subscribe
autoexpunge = 30d
}
mailbox Trash {
special_use = \Trash
auto = subscribe
autoexpunge = 30d
}
+

The “auto = subscribe” makes sure that the “Junk” and “Trash” folders are automatically created for every user. Otherwise spam emails cannot be moved to the “Junk” folder later.

+ +

Now we are getting to something really cool. Let’s tell Dovecot that moving emails into the Junk folder teaches rspamd instantly that the email is spam. And train an email as ham if it is moved out of the Junk folder. We will add triggers (actually “sieve scripts“) to the action of moving emails via IMAP.

+

The currently recommended way is to use the “IMAPSieve” plugin instead. There is nothing to install – it comes with the Dovecot packages. We just need to configure it.

+

First order of business is enabling the IMAPSieve plugin for the IMAP protocol/service in Dovecot. Edit the /etc/dovecot/conf.d/20-imap.conf file and look for the line reading “mail_plugins”. Turn it into:

+
mail_plugins = $mail_plugins quota imap_sieve
+

We also need to edit Dovecot’s Sieve configuration to enable two plugins that are required for our task. Sieve is a scripting language that automates things in conjunction with emails and folders. Edit the file /etc/dovecot/conf.d/90-sieve.conf and put these lines into the plugin {…} section:

+
# From elsewhere to Junk folder
imapsieve_mailbox1_name = Junk
imapsieve_mailbox1_causes = COPY
imapsieve_mailbox1_before = file:/etc/dovecot/sieve/learn-spam.sieve
+
# From Junk folder to elsewhere
imapsieve_mailbox2_name = *
imapsieve_mailbox2_from = Junk
imapsieve_mailbox2_causes = COPY
imapsieve_mailbox2_before = file:/etc/dovecot/sieve/learn-ham.sieve
+
sieve_pipe_bin_dir = /etc/dovecot/sieve
sieve_global_extensions = +vnd.dovecot.pipe
sieve_plugins = sieve_imapsieve sieve_extprograms
+

The first rule tells Dovecot to run the Sieve rules as defined in the /etc/dovecot/sieve/learn-spam.sieve file whenever an email is moved into a user’s “Junk” folder. We will create that Sieve script in a minute.

+

The second rule sets the other way. Whenever an email is moved from the “Junk” folder to any (*) folder then the /etc/dovecot/sieve/learn-ham.sieve Sieve script is called.

+

The “sieve_pipe_bin_dir” setting defines where executable scripts are allowed to reside. We will put our simple learning scripts there. And finally the “sieve_global_extensions” setting enables the pipe plugin that allows sending email to external commands.

+

Next up let’s create the Sieve scripts that we told Dovecot about. Create a new directory /etc/dovecot/sieve to put our new files in:

+
mkdir /etc/dovecot/sieve
+

Then create the file /etc/dovecot/sieve/learn-spam.sieve and let it contain:

+
require ["vnd.dovecot.pipe", "copy", "imapsieve"];
pipe :copy "rspamd-learn-spam.sh";
+

Let’s do the same for /etc/dovecot/sieve/learn-ham.sieve

+
require ["vnd.dovecot.pipe", "copy", "imapsieve", "variables"];
if string "${mailbox}" "Trash" {
stop;
}
pipe :copy "rspamd-learn-ham.sh";
+

The above Sieve script avoids training an email as ham if the user moves it to the Trash folder. After all if you clear your Junk folder you do not want to train your spam as regular emails.

+

Restart Dovecot:

+
systemctl restart dovecot
+

These two scripts need to be compiled – that is turning them into machine-readable code:

+
sievec /etc/dovecot/sieve/learn-spam.sieve
sievec /etc/dovecot/sieve/learn-ham.sieve
+

This creates two new files “learn-ham.svbin” and “learn-spam.svbin” that look like gibberish inside but are now in a format that Dovecot’s Sieve plugin can understand.

+

Let’s fix the permissions of these files, too, while we are at it:

+
chmod u=rw,go= /etc/dovecot/sieve/learn-{spam,ham}.{sieve,svbin}
chown vmail:vmail /etc/dovecot/sieve/learn-{spam,ham}.{sieve,svbin}
+

And the last step is to create the simple shell scripts that do the actual spam/ham training. The first file is /etc/dovecot/sieve/rspamd-learn-spam.sh which contains:

+
#!/bin/sh
exec /usr/bin/rspamc learn_spam
+

That looks simple, doesn’t it? Nothing more is actually needed. The spam email is piped to this script and rspamd learns it as a spam email and adjusts its spam detection database accordingly.

+

The second script teaches ham and is called /etc/dovecot/sieve/rspamd-learn-ham.sh. Make it contain:

+
#!/bin/sh
exec /usr/bin/rspamc learn_ham
+

These two shell scripts must be made executable:

+
chmod u=rwx,go= /etc/dovecot/sieve/rspamd-learn-{spam,ham}.sh
chown vmail:vmail /etc/dovecot/sieve/rspamd-learn-{spam,ham}.sh
+

I hope you haven’t lost your mind yet. It’s really just a chain of things to happen. Let’s reiterate how this process works:

+
    +
  1. a user moves a spam email into their “Junk” folder
  2. +
  3. Dovecot realizes that this triggers the Sieve rule “imapsieve_mailbox1” so it calls the Sieve script /etc/dovecot/sieve/learn-spam.sieve (in fact the *.svbin version of the script)
  4. +
  5. Sieve will take the email and send (“pipe”) it to the executable rspamd-learn-spam.sh shell script
  6. +
  7. the script in turn runs the email through the “/usr/bin/rspamc learn_spam” command
  8. +
+

This works equally for the other way or learning ham emails of course.

+

I am sure you are eager to try it out. However to see that it actually works I suggest you edit the /etc/dovecot/conf.d/10-logging.conf file and set “mail_debug=yes”. That will add a lot more detail to the /var/log/mail.log file but on a busy server may also lead to headaches. 🙂

+

Restart Dovecot…

+
systemctl restart dovecot
+

…and watch the /var/log/mail.log file…

+
tail -f /var/log/mail.log
+

Now open your IMAP client (Thunderbird, Evolution, Roundcube, mutt or whatever you prefer) and drag an email to your Junk folder. The mail log will show a lot of things that are going on. I tried to compact the output so that you better understand that it worked:

+
imapsieve: Static mailbox rule [1]: mailbox=`Junk' from=`*' causes=(COPY) => before=`file:/etc/dovecot/sieve/learn-spam.sieve' after=(none)
imapsieve: Static mailbox rule [2]: mailbox=`*' from=`Junk'
causes=(COPY) => before=`file:/etc/dovecot/sieve/learn-ham.sieve'
after=(none)
+
imapsieve: Matched static mailbox rule [1]
+
sieve: file storage: script: Opened script `learn-spam'
from `/etc/dovecot/sieve/learn-spam.sieve'
+
sieve: action pipe: running program: rspamd-learn-spam.sh
+
program exec:/etc/dovecot/sieve/rspamd-learn-spam.sh:
Pass environment: USER=john@example.org
+
program exec:/etc/dovecot/sieve/rspamd-learn-spam.sh:
Pass environment: HOME=/var/vmail/example.org/john
+
program exec:/etc/dovecot/sieve/rspamd-learn-spam.sh:
Pass environment: HOST=narnia
+
Mailbox Junk: UID 1: Opened mail because: mail stream
+
sieve: uid=1: Execute storing into mailbox 'Junk'
+

Dovecot finds two Sieve rules: [1] and [2]. And it finds that rule [1] matches your current action and runs it. That in turn calls the “rspamd-learn-spam.sh” script to train that email as spam. And at the very end the email is actually moved to the “Junk” folder.

+

And if you pull an email out of the “Junk” folder you should see mailbox rule [2] be called and the email being learned as ham.

+

Don’t forget to switch off “mail_debug” again or your users’ actions will quickly fill your log file.

+ +

rspamd keeps a verbose log of its actions in /var/log/rspamd/rspamd.log. If a user complains that a certain email got blocked or at least flagged as spam then take a look at this log. You can match the /var/log/mail.log with it by comparing the Postfix queue ID. Those are the 12-digit hexadecimal number like “95CE05A00547“. Those IDs can be found in the rspamd.log, too:

+
<40985d>; task; rspamd_task_write_log: id: <undef>, qid: <**95CE05A00547**>, ip: 12.13.51.194, from: <…>, (default: F (no action): [3.40/15.00] [MISSING_MID(2.50){},MISSING_DATE(1.00){},MIME_GOOD(-0.10){text/plain;},ARC_NA(0.00){},ASN(0.00){asn:8220, ipnet:212.123.192.0/18, country:GB;},FROM_EQ_ENVFROM(0.00){},FROM_NO_DN(0.00){},RCPT_COUNT_ONE(0.00){1;},RCVD_COUNT_ZERO(0.00){0;},RCVD_TLS_ALL(0.00){},TO_DN_NONE(0.00){},TO_DOM_EQ_FROM_DOM(0.00){},TO_MATCH_ENVRCPT_ALL(0.00){}]), len: 181, time: 16.000ms real, 6.385ms virtual, dns req: 0, digest: <69b289a82827c11f759837c033cd800a>, rcpts: <…>, mime_rcpt: <…>
+ +

rspamd comes with a neat bonus feature: a web interface. It allows you to check emails for spam, get statistics and fine-tune scores. It is already installed and enabled by default and expects HTTP requests on port 11334 on the localhost interface. I suggest you add a simple proxy configuration to your already working HTTPS-enabled web mail configuration to get access.

+

rspamd dashboard

+

First you need to enable Apache’s modules for HTTP proxying and rewriting:

+
a2enmod proxy_http
a2enmod rewrite
+

You can either create a new virtual host configuration or just edit the /etc/apache2/sites-available/webmail.example.org-https.conf file. Anywhere within the VirtualHost tags add:

+
<Location /rspamd>
Require all granted
</Location>
+
RewriteEngine On
RewriteRule ^/rspamd$ /rspamd/ \[R,L\]
RewriteRule ^/rspamd/(.\*) http://localhost:11334/$1 \[P,L\]
+

This piece of configuration will forward any requests to https://webmail.example.org/rspamd to localhost:11334 and thus give you access to the rspamd web interface.

+

The interface is password protected. Let’s generate a new access password:

+
pwgen 15 1
+

This gives you a password like “eiLi1lueTh9mia4”. You could put that password in an rspamd configuration file. But cleartext passwords in configuration files are not quite elegant. Let’s create a hash of the password:

+
rspamadm pw
Enter passphrase: …
$2$icoahes75e7g9wxapnrbmqnpuzjoq7z…
+

Feed it the password that pwgen created for you and you will get a long hashed password. This procedure by the way is also documented on the rspamd pages.

+

Create a new configuration file /etc/rspamd/local.d/worker-controller.inc and put your hashed password in there:

+
password = "$2$icoahes75e7g9wxapnrbmqnpuzjoq7z…"
+

That’s it for the configuration. Finally restart both rspamd and Apache to load your changed configuration:

+
systemctl restart rspamd
systemctl restart apache2
+

If everything went as expected you should now be able to access the rspamd web interface at https://webmail.example.org/rspamd

\ No newline at end of file diff --git a/dist/ispmail-bookworm/creating-a-tls-encryption-key-and-certificate/index.html b/dist/ispmail-bookworm/creating-a-tls-encryption-key-and-certificate/index.html new file mode 100644 index 0000000..b3675b4 --- /dev/null +++ b/dist/ispmail-bookworm/creating-a-tls-encryption-key-and-certificate/index.html @@ -0,0 +1,292 @@ + TLS certificate | ISPmail Guide + Skip to content
+⚠️ This page is part of the ISPmail guide for Debian Bookworm. Please use the newer guide for Debian Trixie. +

TLS certificate

+

The internet is not a friendly place where you can trust people. If you send data over the internet there is a pretty +good chance someone intercepts it. You don’t want that. Our best weapon against that is transport encryption. All you +need is to create an encryption key and a certificate for Postfix (SMTP), Dovecot (IMAP/POP3) and Apache (HTTPS). If +you are confused why that requires a key and certificate then please consider reading the Wikipedia about +public-key cryptography. The single most important detail here: +nobody but you must have access to the private key.

+ +

What makes mail clients trust a certificate?

Section titled “What makes mail clients trust a certificate?”
+

Your client’s operating system contains a list of “trusted” certificate authorities. Sometimes that list is located in a +central location for all applications. And sometimes a browser comes with its own list. A certificate signed by any of +those organization is fully trusted. Yes, your browser trusts companies you probably have never heard of. And so does +your mail client if you use software like Thunderbird instead of using web mail. The tricky part is not the technology. +Everyone with some knowledge about certificates can create their own authority. Mathematically your certificates are +just as good as anyone else’s. The tricky part is to convince browser manufacturers to trust them and add your +certificates to their trust list.

+

Those organization claim to do checks (in exchange for money) whether you are the righteous owner of a certain domain. +These checks have sometimes failed so badly that they popped up in the news. Ten years ago a nerd +requested to get trusted by Firefox with his “Honest Achmed’s +Used Cars and Certificates” authority. It was fun to watch the developers struggle with arguments why Achmed would be +any worse than authorities like +Türktrust +or Verisign (who failed so hard one +must wonder why they are still in business).

+

In 2012 two Mozilla employees decided to do something about +that. They came up with the idea of a non-profit certificate authority. The world needed encryption everywhere and +people should no longer shy away from it because getting certificates cost money. Two years later the service was ready +and everyone could get a free certificate valid for 90 days. An automated process renewed the certificate in time so +there was no hassle. (They surely deserve a donation for the many years of service to +the internet community.)

+ +

You guessed it, we will need our own certificate. It will be used in three places:

+
    +
  1. the webmail interface (driven by the Apache web server)
  2. +
  3. Postfix (to encrypt SMTP communication where possible)
  4. +
  5. Dovecot (to encrypt IMAP/POP3 communication and deny any unencrypted traffic)
  6. +
+

A single certificate (per domain) can and should be used by all three pieces of software.

+ +

Your mail server will be able to serve emails in many domains. But a certificate is usually issued for a single +fully-qualified domain name like “mail.example.org”. The +common name is an important part of the certificate. That attribute must correspond to the host name you use during +communication or else the certificate is rejected. Hmmm, many domains but only one name is allowed on a certificate? How +do we deal with that?

+

Option 1: a generic name and a single certificate

Section titled “Option 1: a generic name and a single certificate”
+

The simple solution is to take a generic name. The German ISP Hetzner for example uses the name “mail.your-server.de” +for all customers and their domains. And there are many examples of such an approach. Experience shows that most users +do not care about the hostname as long as they get their emails. So I would generally recommend this approach due to its +simplicity.

+

Option 2: multiple names/certificates & SNI

Section titled “Option 2: multiple names/certificates & SNI”
+

Some people however want to give their mail server as many names as they have domains. Suppose that you have three +domains: example.org, example.net and example.com. Users of example.org can use mail.example.org while users of +example.net use mail.example.net. As you can imagine this would not work if you had a single certificate. After all +which name would you use as a common name there? If you used “mail.example.org” then talking to your server by the +name “mail.example.net” would lead to a certificate error.

+

So your mail server needs multiple certificates – one for each host name. And depending on how a user connects to your +server you need to send the matching certificate. If the user wants to speak to “mail.example.org” then your server +needs to send the certificate for “mail.example.org”. Fortunately that problem has been addressed by a technique called +Server Name Indication (SNI). A client talks to the server and +even before the encrypted connection is established it tells the server that it expects a certificate for the intended +host name. The server can then load the matching certificate and initiate the encryption process.

+

SNI has long been a problem for mail servers. The mail user agent (e.g. Thunderbird) needs to support it as well as +Postfix and Dovecot. Postfix has finally added SNI in version 3.4 so that we can use it.

+

While adding multiple host names needs extra work, it also has a benefit. If you want to move domains to other servers +(e.g. when upgrading your server) you can move one domain at a time.

+ + +

Let’s start with the web server. As an example I will assume that you want to offer a host name webmail.example.org +to your users. Of course your server will have another name in a domain that you control. I will use that example +throughout the tutorial though and keep that name printed in bold letters to remind you that you have to use your +own host name.

+

Do you just want to play around with your new server and not use any real domain yet? No problem. Then use +nip.io. If your IP address is 1.2.3.4 then you can use 1.2.3.4.nip.io as a domain name that points to +your server. (There used to be another domain xip.io for that purpose but it died in mid-2021.) Another service like +that which also supports IPv6 is sslip.io.

+

If you have an actual domain then set up a DNS “A” and “AAAA” (if you use IPv6) record for that host name pointing to +your server’s IP address.

+

First you need a web root directory for that host name:

+
mkdir /var/www/webmail.example.org
chown www-data:www-data /var/www/webmail.example.org
+

Next you need to create a virtual host configuration file. Apache on Debian uses a neat system to manage virtual hosts:

+
    +
  • /etc/apache2/sites-available/*.conf contains the actual configuration files for each virtual host. Putting a file +here does not enable that host though. That’s done in the next step. There are two configuration files by default. +“000-default.conf” is a HTTP virtual host and “default-ssl.conf” is a HTTPS virtual host.
  • +
  • /etc/apache2/sites-enabled/*.conf contains symbolic links (“symlinks”) pointing to configuration files in the +/etc/apache2/sites-available directory. Only *.conf links in this directory will be loaded by Apache.
  • +
+

This technique allows you to enable and disable virtual hosts without having to destroy any configuration. Debian ships +with the “a2ensite” (short for “apache2 enable site”) and “a2dissite” commands. In addition to some sanity checks those +commands essentially create or remove symlinks between “sites-available” and “sites-enabled”.

+ +

You may remove the default symlinks in /etc/apache2/sites-enabled/* unless you use them already.

+

Create a new virtual host configuration file /etc/apache2/sites-available/webmail.example.org-http.conf and make it +contain:

+

<VirtualHost *:80> ServerName webmail.example.org DocumentRoot /var/www/webmail.example.org +</VirtualHost>

+

The simple configuration makes Apache handle HTTP requests (on the standard TCP port 80) if a certain line in the +request header from the browser reads “Host: webmail.example.org”. So the browser actually tells your Apache web server +which server name it is looking for. That allows for multiple web sites on a single IP address. (Thanks to +Server Name Indication as explained earlier this works well for +HTTPS, too.)

+

Enable the site:

+
a2ensite webmail.example.org-http
+

You will be told:

+
To activate the new configuration, you need to run:
systemctl reload apache2
+

Do that.

+ +

Let’s check if the configuration works. Put a test file into your web root directory:

+
echo “Just a test” > /var/www/webmail.example.org/test
+

Now when you open the URL http://webmail.example.org/test in your browser you should see the text “Just a test”.

+

This is enough setup to make LetsEncrypt issue a certificate for you.

+ +

Now you can use the certbot tool to request an encryption certificate from LetsEncrypt. What will happen?

+
    +
  • certbot creates a private key and a certificate request. It sends the certificate request to the LetsEncrypt +server.
  • +
  • the LetsEncrypt server replies with a challenge/token.
  • +
  • certbot puts that token into a file in the /var/www/webmail.example.org/.well-known/acme-challenge directory.
  • +
  • the LetsEncrypt server does an HTTP connection to http://webmail.example.org/.well-known/acme-challenge/… and +expects to find that token. This verifies that you are in charge of the domain and the web server.
  • +
  • If all works well the LetsEncrypt server signs your certificate request and thus creates the actual certificate.
  • +
  • certbot receives the certificate and puts it into /etc/letsencrypt/archive/webmail.example.org/
  • +
+

To get a certificate for your domain run:

+

certbot certonly --webroot --webroot-path /var/www/webmail.example.org -d webmail.example.org

+

You can use multiple occurences of “-d” here to get a certificate valid for multiple domains. For example: “-d +webmail.example.org -d something-else.example.org”. (See also: +https://eff-certbot.readthedocs.io/en/stable/using.html#webroot)

+

The first time you do that you will get asked for your email address so LetsEncrypt can send you reminders if your +certificate would expire. You will also have to agree to their terms of service.

+

If everything worked well you should get output like:

+
Requesting a certificate for webmail.example.org Successfully received certificate. Certificate is saved at:
/etc/letsencrypt/live/webmail.example.org/fullchain.pem Key is saved at:
/etc/letsencrypt/live/webmail.example.org/privkey.pem This certificate expires on 2024-01-02. These files will be
updated when the certificate renews. Certbot has set up a scheduled task to automatically renew this certificate in
the background.
+

In /etc/letsencrypt/live/webmail.example.org you will find a couple of files now:

+
    +
  • cert.pem: the certificate file
  • +
  • chain.pem: the chaining or intermediate certificate. This certificate provides information how the LetsEncrypt +certificates are linked to other known certificate authorities. It is generally a good idea to always send this +certificate along with your own for clients who may not know LetsEncrypt properly yet.
  • +
  • fullchain.pem: this file contains a concatenation of the cert.pem and the chain.pem. This is the preferred file to +use when a piece of software asks where to find the certificate.
  • +
  • privkey.pem: the private key file. Keep it secret.
  • +
+ + +

Now that you have a valid certificate you can finally enable HTTPS for your web server. Create a new file +/etc/apache2/sites-available/webmail.example.org-https.conf containing:

+

<VirtualHost *:443> ServerName webmail.example.org DocumentRoot /var/www/webmail.example.org SSLEngine +on SSLCertificateFile /etc/letsencrypt/live/webmail.example.org/fullchain.pem SSLCertificateKeyFile +/etc/letsencrypt/live/webmail.example.org/privkey.pem </VirtualHost>

+

This virtual host configuration looks suspiciously similar to the HTTP virtual host above. It just listens on port 443 +(standard port for HTTPS) instead of port 80. And it uses the “SSLEngine” that handles encryption and gets information +about the certificate for your web server (that is shown to your users) and the private key (that the web servers uses +to decrypt the user’s communication).

+

Enable the SSL module in Apache:

+
a2enmod ssl
+

Then enable the virtual host for HTTPS:

+
a2ensite webmail.example.org-https
+

And restart the web server. A reload is not sufficient this time because you added a module.

+

systemctl restart apache2

+

Now when you point your web browser to webmail.example.org, your browser should tell you that it trusts the web +site’s certificate:

+

Browser bar showing successful encryption

+

(Yes, sorry, this is not webmail.example.org. But I do not own the example.org domain and thus cannot get a valid +certificate for it. This is my own site.)

+

So should you keep the HTTP virtual host? Yes. First for the HTTP->HTTPS redirection. And second to keep certbot +working.

+ +

Sometimes users forget to enter https://… when accessing your webmail service. So they access the HTTP web site. We +obviously don’t want them to send their password over HTTP. So we should redirect all HTTP connections to HTTPS.

+

One exception though. Let’s Encrypt will use HTTP to verify your challenge token. So we need to serve files at +http://webmail.example.org/.well-known/acme-challenge/… directly while redirecting all other requests to HTTPS. You +can accomplish that by putting these lines inside the <VirtualHost> section of your +/etc/apache2/sites-available/webmail.example.org-http.conf file:

+
RewriteEngine On
RewriteCond %{REQUEST_URI} !.well-known/acme-challenge
RewriteRule ^(.*)$ https://%{SERVER_NAME}$1 \[R=301,L\]
+

This requires the rewrite module to be enabled in Apache. That is simple though:

+
a2enmod rewrite
systemctl restart apache2
+

So now entering http://webmail.example.org will redirect you to https://webmail.example.org.

+ +

The certbot package automatically adds a timed job that runs twice a day at random times. The random part is important +to avoid millions of server hammering the LetsEncrypt service at the same second.

+ +

So the renewal already happens automatically. Should it fail then LetsEncrypt start sending you reminder emails that +your certificate should be renewed. That’s a clear sign that something went wrong with the automatic renewal.

+

There is one puzzle piece missing though. Even if the renewal worked it will only update the certificate files. But the +software components – Postfix, Dovecot and Apache – will not notice the change. So we need to add a so called +post-hook to certbot that triggers a restart of all processes thereafter.

+

For that purpose edit the /etc/letsencrypt/cli.ini file and add:

+
post-hook = systemctl restart postfix dovecot apache2
+

Well done. You have implemented Let’s Encrypt for all your services now. Let’s go on.

\ No newline at end of file diff --git a/dist/ispmail-bookworm/faq-frequently-asked-questions/index.html b/dist/ispmail-bookworm/faq-frequently-asked-questions/index.html new file mode 100644 index 0000000..6f4bbd2 --- /dev/null +++ b/dist/ispmail-bookworm/faq-frequently-asked-questions/index.html @@ -0,0 +1,137 @@ + FAQ (frequently asked questions) | ISPmail Guide + Skip to content
+⚠️ This page is part of the ISPmail guide for Debian Bookworm. Please use the newer guide for Debian Trixie. +

FAQ (frequently asked questions)

+

Previously I claimed a copyright on the documentation. However let’s make things simpler. This Bullseye guide is using +the Creative Commons BY-NC-SA license. Which means:

+
    +
  • BY = Attribution — You must give appropriate credit, provide a link to the license, and indicate if changes were made. +You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use.
  • +
  • NC = NonCommercial — You may not use the material for commercial purposes. Do what you want with your mail server. But +let’s keep the knowledge free.
  • +
  • SA = ShareAlike — If you remix, transform, or build upon the material, you must distribute your contributions under +the same license as the original.
  • +
+

Besides that this guide has been a team effort. Many readers have contributed to it. I may spend the time to turn it +into a guide but a lot of good ideas were not mine alone.

+ +

No. There is no financial motivation. I just strive for freeing the world of email services once again.

+ +

I personally prefer that software, too. Just go for it. But for the sake of consistency let’s keep Apache and MySQL as +default choices in this guide so that readers upgrading from previous versions don’t have to switch.

+ +

Generally, yes. Aside from my day job, I am a sysadmin freelancer. If you are just stuck at some point you may want to +ask in the chat first though. You can find me there as well.

+ +

I understand the need for it. If your users are using low-security operating systems (e.g. those that run EXE files) +they are threatened by a lot of security problems. From the perspective of an email provider I would not want to take +responsibility for filtering emails. That is only working on symptoms and not addressing the actual issues. Security is +a fundamental concept and not something you slap on top of something inherently broken. I would not want to be blamed +for a crypto trojan infection because the user relied on me saving them from bad things to happen. Client security in +non-free systems is a topic on its own.

+ +

If you use a Debian stable release you have chosen to stay on a specific software version. “Stable” means “a version +that will not change”. That’s the best choice for a server. Those software packages are by no means less secure though +because they also get security updates. Debian also has up-to-date packages but you surely don’t want to use them for a +mail server unless you feel adventurous or have an intense hatred for your users. For a detailed discussion see +this separate article.

+ +

Unfortunately there is no easy way to accomplish that. Especially with interactive components like tabs of quizzes. The +reasons are technical – not malice.

+

Your guide looks cool. How did you make it?

Section titled “Your guide looks cool. How did you make it?”
+

The site is generated using Starlight. Discussions at the bottom of each page are +powered by a self-hosted instance of Comentario. Diagrams have been created using +Inkscape. User tracking is handled by a self-hosted instance of Rybbit. +Everything here has been generated using open-source software and is not using any public cloud services.

+ +

That is very kind to offer help. I understand the motivation to give back something. But trust me: you will lose +interest quickly and regret your offer. The guide is huge. It may not appear like much but once you start typing you +realize just how many months of work went into it. Even translating will take 1-2 weeks of your time. And after that +someone would have to maintain both the original version and your translation. We tried that a couple of times and it +did not turn out well.

\ No newline at end of file diff --git a/dist/ispmail-bookworm/index.html b/dist/ispmail-bookworm/index.html new file mode 100644 index 0000000..c24a709 --- /dev/null +++ b/dist/ispmail-bookworm/index.html @@ -0,0 +1,124 @@ + Start here | ISPmail Guide + Skip to content
+⚠️ This page is part of the ISPmail guide for Debian Bookworm. Please use the newer guide for Debian Trixie. +

Start here

Once upon a time there were many mail servers on the internet. If your organisation wanted to receive and send emails then you would have your system administrator set up a mail server. He would add a DNS record and create a cryptic Sendmail configuration file.

+

Fast forward a few decades and suddenly we have arrived in a monopolistic dystopy. The world of internet services is dominated by a few companies. Having worked in IT for 25 years I feel frustrated about the ignorance and laziness of decision makers. Cloud providers rip obscene profits and lock clueless customers in, while their IT staff is evolving into dumb victims instead of doing their actual job.

+

If you are like me then you want to stay as independent as possible. And that includes being in charge of your own email service. Maybe not for your employer but at least for yourself, your friends and family. Become your own internet service provider (ISP) for email. Hence the name: ISPmail.

+

This is a complete and free guide that teaches you how to set up and run your own mail server. At the end of the guide you will have your own fully featured mail server based on open-source software using a cheap virtual server for a few bucks per month. And you will have learned all about the various components, protocols and technologies. This guide has been battle-tested by thousands of other sysadmins and constantly evolved over the last 20 years. I am publishing this guide without any commercial motives, so all you would have to invest is your time.

+ +
    +
  • Receive emails on your domains.
  • +
  • Filter out spam. (We will not deal with detection of Wind*ws malware though.)
  • +
  • Send emails out to any other servers/domains on the internet. Connections will be encrypted when possible.
  • +
  • Add automatic cryptographic signatures (DKIM / Domain Keys) to outgoing emails to prove that you are the owner of your domain.
  • +
  • Store as many emails for as many email addresses as you have disk space. Set limits (“quotas”) per user. The only limit is the size of your disk.
  • +
  • Let your users fetch email using IMAP or POP3 and send email through your servers using SMTP.
  • +
  • Allow users to manage server-based filter rules. Distribute incoming emails to different folders. Forward copies. Or send out-of-office notifications.
  • +
  • Provide a webmail interface so users can access their emails securely from any location using a web browser.
  • +
  • Mitigate brute force attacks.
  • +
+ +
    +
  • Linux experience. Preferably a Debian-derivative. No godlike skills required. But know your basics: navigating through the file system, editing files, watching log files. Have some basic understanding of DNS. Bonus points if you have played with an SQL database and know about SELECT, INSERT, rows, columns.
  • +
  • Time. 2 hours to 2 days.
  • +
  • server that runs Debian Bookworm. 1 GB of RAM and a 20 GB disk/SSD is fine for your friends and family. Rent a cheap virtual server. Or use a decommissioned laptop. Other Linux distributions likely come with other versions of the software and have different configurations and paths on disk. It will work but you will need to deviate from this guide.
  • +
  • The provider providing you with the server needs to allow SMTP send and receive. These providers are known to be troublesome: +
      +
    • Hetzner (DE, FI, US): Will allow SMTP after a month of paying for their service and per a request issued at https://console.hetzner.cloud/limits
    • +
    • DigitalOcean (US): Blocks SMTP and tells you that running your own mail server is a bad idea. Avoid.
    • +
    +
  • +
  • Your server needs to have a public IP address that does not belong to a range of typical ISP customers. You usually can’t operate the mail server from a dialup IP address at home because those IP ranges are blacklisted by most other mail servers. Make sure that your IP address is not blacklisted before you start. If you rent a virtual server from your favorite hosting company you probably won’t have any problems.
  • +
  • An internet domain (or several) to receive emails for. You need to be able to set A, MX and TXT records for that domain. You should also be able to set PTR records for your IP address because some mail servers on the internet require you to have matching forward and reverse DNS records.
  • +
  • Patience. We will proceed slowly and after every step ensure that are still on track. Don’t hurry and skip parts even if they appear confusing at first. If you get lost just submit your question at the bottom of any page throughout this guide and help is on the way. Or join the chat channel.
  • +
+ +

If you just want to have a working mail server and do not care how it works then this guide is not for you. Check out ready solutions like mailinabox or iRedMail. Running a mail server requires technical understanding. And that’s what the ISPmail guide is for. Experience from giving support to other sysadmins shows that most problems appear because some detail in a complex setup goes wrong and they have no idea how to fix it. Email has evolved a lot over the past 40 years. Go with ready solutions if you like. But I have a feeling that we meet again. And you will probably not save time either taking the supposedly easy route.

+ +

The entire tutorial is split into several pages. You can find the different chapters on the left. The navigation within a chapter can be found on the right. Let’s go.

\ No newline at end of file diff --git a/dist/ispmail-bookworm/install-debian-bookworm-on-your-server/index.html b/dist/ispmail-bookworm/install-debian-bookworm-on-your-server/index.html new file mode 100644 index 0000000..6777a04 --- /dev/null +++ b/dist/ispmail-bookworm/install-debian-bookworm-on-your-server/index.html @@ -0,0 +1,137 @@ + Installing Debian | ISPmail Guide + Skip to content
+⚠️ This page is part of the ISPmail guide for Debian Bookworm. Please use the newer guide for Debian Trixie. +

Installing Debian

Option 1: Get a server with Debian Bookworm pre-installed

Section titled “Option 1: Get a server with Debian Bookworm pre-installed”
+

If you rent a virtual server at your favorite hosting company it often comes with Debian pre-installed. If you have a chance to change the partitioning then consider the schema shown below. Otherwise feel free to skip this page.

+

Option 2: Get a server with the older Debian Bullseye

Section titled “Option 2: Get a server with the older Debian Bullseye”
+

Your hosting company does not offer Debian Bookworm yet but just Debian Bullseye? No big deal. Just change your /etc/apt/sources.list file to:

+
deb http://deb.debian.org/debian bookworm main
deb http://deb.debian.org/debian bookworm-updates main
deb http://security.debian.org/debian-security bookworm-security main
+

Run “apt update” and “apt dist-upgrade” and you are ready.

+ +

You have a blank computer or virtual machine? Then simply install Debian Bookworm yourself. Get a boot medium from the Debian website. The smaller network installer is sufficient – it will download all required packages directly from the internet. Make sure you choose ‘English’ as the installation language even if it is not your native language. If you have trouble with the server you will more likely find help when searching for English error messages on the internet.

+

Most of the installation is pretty straightforward. You don’t need me holding your hand. I strongly recommend that you use the logical volume manager (LVM) for your partitions to stay flexible if your server grows. See my article on LVM if you want some help understanding its concept.

+ +

The only part that takes some patience is when it comes to partitioning your disk. Throughout this tutorial you will store your users’ emails in the /var/vmail partition. The MariaDB database will live in /var/lib/mysql and is usually pretty small even for a large number of email accounts – so that usually does not require a separate partition. Log files go to /var/log.

+

So my recommendation for partitioning:

+
    +
  • Boot partition, 300 MB, first partition of your disk (e.g. /dev/sda1), mounted at “/boot”
  • +
  • All the rest of the disk goes into one large LVM physical volume, second partition of your disk (e.g. /dev/sda2) +
      +
    • LVM volume group consisting of that one physical volume +
        +
      • LVM logical volume for “/”, 20 GB, formatted as ext4
      • +
      • LVM logical volume for “/tmp”, 5 GB, formatted as ext4
      • +
      • LVM logical volume for “/var/vmail”, formatted as ext4, as much space for mailboxes as you want to start with
      • +
      +
    • +
    +
  • +
+

LVM is very flexible. You can enlarge your root partition or “/var/vmail”. You can even add another physical disk and join it into the volume group to get more space. So just start small.

+

The Debian installer helps you set up LVM. In a nutshell these are the major steps:

+
    +
  • Partitioning method: “Manual”
  • +
  • Select your disk
  • +
  • Create a new partition table if you get asked
  • +
  • Create a new partition of “max” size as a Primary partition
  • +
  • Set the partition to “Use as: physical volume for LVM”
  • +
  • Choose “Configure the Logical Volume Manager”
  • +
  • Create a volume group (call it “vg0” if you like)
  • +
  • Select the partition you created before (e.g. /dev/sda1)
  • +
  • Create the logical volumes for “root”, “tmp” and “mail”.
  • +
  • Edit each LV. Set its type to “ext4”. Set the mount points to +
      +
    • / for root
    • +
    • /tmp for tmp
    • +
    • /var/vmail for mail
    • +
    +
  • +
  • Do not add swap space – your server will need very little RAM. You will get asked if you are serious. Yes, you are.
  • +
+

Write the changes to disk and continue with the rest of the installation. Just make sure that you install the “SSH server” component so that you can login from remote after the installation.

\ No newline at end of file diff --git a/dist/ispmail-bookworm/install-the-software-packages/index.html b/dist/ispmail-bookworm/install-the-software-packages/index.html new file mode 100644 index 0000000..7428f35 --- /dev/null +++ b/dist/ispmail-bookworm/install-the-software-packages/index.html @@ -0,0 +1,177 @@ + Install software packages | ISPmail Guide + Skip to content
+⚠️ This page is part of the ISPmail guide for Debian Bookworm. Please use the newer guide for Debian Trixie. +

Install software packages

After the basic installation your server will reboot and allow you to login. You can either login at the console (if you have physical access to the system) or using SSH (secure shell).

+ +

Unless you just installed the server it is a good idea to install all missing updates first:

+
apt update
apt upgrade
+ +

Let us install the necessary Debian packages to make it an actual mail server. Take a moment to read through this list of package – we will do the installation afterwards:

+
    +
  • mariadb-server
    +The database service that will store information about your email accounts and domains. (If you haven’t heard of MariaDB yet, it is a fork of MySQL after being acquired by Oracle.)
  • +
  • postfix
    +The MTA (mail transport agent) that speaks SMTP to receive and send emails.
  • +
  • postfix-mysql
    +An extension that allows Postfix to get its information from a MySQL/MariaDB database.
  • +
  • dovecot-mysql
    +The IMAP/POP3 mail server including an extension to query information from a MySQL/MariaDB database.
  • +
  • dovecot-pop3d (optional)
    +An extension to Dovecot that allows users to fetch emails using the POP3 protocol. (This is optional. Only few users nowadays still use POP3.)
  • +
  • dovecot-imapd
    +An extension to Dovecot that allows users to access emails using the IMAP protocol.
  • +
  • dovecot-lmtpd
    +Enables Dovecot to receive LMTP connections. We will need it later for the internal transfer of emails from Postfix to Dovecot.
  • +
  • dovecot-managesieved (optional)
    +An extension to Dovecot that allows users to define filter rules that are automatically run on the server when a new email arrives.
  • +
  • apache2 and php8.2
    +The web server that powers the webmail interface. PHP is the scripting language that the Roundcube webmail software is written in.
  • +
  • adminer (optional)
    +A web interface to manage your SQL database if you are not comfortable crafting SQL queries by hand.
  • +
  • rspamd
    +A third-party software that deals with spam and handles automatic domain key (DKIM) signing.
  • +
  • redis-server
    +A key-value store. It is a simple but fast kind of database service where Rspamd stores training data about spam and ham.
  • +
  • pwgen
    +A tool to create random passwords.
  • +
  • swaks
    +The SWiss Army Knife of Smtp. A utility to send emails through SMTP for testing purposes.
  • +
  • mutt
    +A console-based program that can speak IMAP and also read Maildirs directly. Very helpful for testing the functionality of your mail server.
  • +
  • certbot
    +A tool that talks to the LetsEncrypt certificate service to request and renew certificates. You will not need it if you have bought a certificate for your webmail server.
  • +
  • ca-certificates
    +A set of certificates from common certificate authorities on the internet. It is required for the proper function of wget for example.
  • +
  • fail2ban (optional)
    +A daemon that tracks log files to recognize brute force attacks. It can block IP addresses of attackers. We will use it to defend against evil people trying to get into our mail server.
  • +
+ +

Let’s start with the pwgen utility. It helps you create secure passwords. Unless you already have a tool for that…

+
apt install -y pwgen
+

You will need a random passwords later to create a database user for the mail server. Just as an example: to create a secure password having a length of 20 characters you would run:

+
pwgen -s 20 1
+

That gets you a string like “W2EzNUFJzjEmA8tQT7A0”.

+ +

If you used MySQL before you may remember that you were forced to specify a password for the ‘root’ database user. That has changed with MariaDB in Debian – for the better. Now you can access the database server without any password if you are logged in as ‘root’ on the server. You might as well set a password but it is not necessary.

+

Go install the MariaDB server package:

+
apt install -y mariadb-server
+

If all went well you can now run “mysql” and get a connection to your MySQL database:

+
root@buster:~# mysql
Welcome to the MariaDB monitor. Commands end with ; or \\g.
Your MariaDB connection id is 30
Server version: 10.3.18-MariaDB-0+deb10u1 Debian 10
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or 'h' for help. Type 'c' to clear the current input statement.
MariaDB [(none)]>
+

Exit the SQL shell by typing “exit” or pressing CTRL-D.

+ +

Now on to the Postfix packages:

+
apt install -y postfix postfix-mysql
+

When you get asked for the mail server configuration type please choose “Internet site”. Enter your own mail server name (the fully qualified domain name) or just press enter. The host name and domain does not need to match any of your email domains.

+ +

To provide a webmail service you need the Apache web server software and the PHP scripting language support:

+
apt install -y apache2 php8.2
+ + +

Just like in previous versions of this guide we will deal with spam using rspamd. (The rspamd principal developer endorses his own software packages but in this guide we will use the packages in Debian for stability.)

+ +

We also install Redis as a storage backend for Rspamd to store its training data about spam and ham.

+
apt install -y rspamd redis-server
+ +

A very useful tool to test email delivery later is SWAKS (the SWiss Army Knife for Smtp):

+
apt install -y swaks
+ +

This is a full-featured IMAP mail client. Think of it as the vi of mail clients. It cannot display HTML but it is very helpful to test IMAP mail servers. And some hardcore users still prefer it over any other mail client.

+
apt install -y mutt
+ +

You will want to use encrypted connections where possible. So you need a certificate for your services. The certbot software helps you to request and manage Let’s Encrypt certificates automatically.

+
apt install -y certbot
+ +

In addition to Postfix (that handles SMTP communication) you will need Dovecot to store received emails and provide IMAP (and optionally POP3) access for your users:

+
apt install -y dovecot-mysql dovecot-pop3d dovecot-imapd dovecot-managesieved dovecot-lmtpd
+ +

SQL databases are called like that because SQL (structured query language) is the way you talk to it. But as we are just puny humans let’s have a more user-friendly way to manage the database. I suggest Adminer which is a tool similar to phpMyAdmin.

+
apt install -y adminer
+ +

To avoid errors when downloading files using wget you should install the default set of certificates of common certificate authorities on the internet:

+
apt install -y ca-certificates
\ No newline at end of file diff --git a/dist/ispmail-bookworm/let-postfix-send-emails-to-dovecot/index.html b/dist/ispmail-bookworm/let-postfix-send-emails-to-dovecot/index.html new file mode 100644 index 0000000..61c8509 --- /dev/null +++ b/dist/ispmail-bookworm/let-postfix-send-emails-to-dovecot/index.html @@ -0,0 +1,118 @@ + Let Postfix send emails to Dovecot | ISPmail Guide + Skip to content
+⚠️ This page is part of the ISPmail guide for Debian Bookworm. Please use the newer guide for Debian Trixie. +

Let Postfix send emails to Dovecot

I hope you haven’t lost your mind yet. If you are unsure how Postfix and Dovecot work together take a moment and go back to the big picture page.

+

In a previous chapter we made sure that Postfix knows which emails it is allowed to receive. Now what to do with the email? It has to be saved to disk into the mailbox of the mail user who is eagerly waiting for it. You could let Postfix handle that using its built-in mail delivery agent (MDA) called “virtual“. However compared to the capabilities that Dovecot provides like server-based sieve rules or quotas the Postfix delivery agent is pretty basic. We are using Dovecot anyway to provide the IMAP (and optionally POP3) service. So let’s use its delivery agent.

+

How can we make Postfix hand over the email to Dovecot? There are generally two ways to establish that link.

+
    +
  1. Using the dovecot-lda (local delivery agent) process. It can process one email at a time. And it starts up a new process for every email. This was for long the default way. But as you can imagine that it does not scale well.
  2. +
  3. The better option is to use LMTP (local mail transport protocol) that was conceived for this purpose. It can handle multiple recipients at the same time and has a permanently running process which provides a better performance than using the LDA. In short, LMTP is a variant of SMTP with fewer features. It is meant for email communication between internal services that trust each other.
  4. +
+

You guessed it already – we will go for the second option. You installed the dovecot-lmtpd package earlier. So let’s configure it.

+

Tell Dovecot where to listen for LMTP connections from Postfix

Section titled “Tell Dovecot where to listen for LMTP connections from Postfix”
+

Edit Dovecot’s configuration file that deals with the LMTP daemon – you can find it at /etc/dovecot/conf.d/10-master.conf. Look for the “service lmtp” section and edit it so that it looks like:

+
service lmtp {
unix_listener /var/spool/postfix/private/dovecot-lmtp {
group = postfix
mode = 0600
user = postfix
}
}
+

This makes Dovecot’s lmtp daemon create a UNIX socket at /var/spool/postfix/private/dovecot-lmtp. Just like in the section dealing with setting up Dovecot we make it put a socket into the /var/spool/postfix chroot directory because Postfix is restricted to that directory and cannot access anything outside of it. So from Postfix’s point of view the socket is located at “/private/dovecot-lmtp”.

+

Restart Dovecot…

+
systemctl restart dovecot
+

Check if dovecot accepted that change:

+
systemctl status dovecot
+

The output should contain “Active: active (running)”.

+

Tell Postfix to deliver emails to Dovecot using LMTP

Section titled “Tell Postfix to deliver emails to Dovecot using LMTP”
+

This is even easier. The “virtual_transport” in Postfix defines the service to use for delivering emails to the local system. Dovecot has created a socket file and is ready to listen to incoming LMTP connections. We just need to tell Postfix to send emails there:

+
postconf virtual_transport=lmtp:unix:private/dovecot-lmtp
+

The syntax looks crazy, but it’s actually simple. You just told Postfix to use the LMTP protocol. And that we want to use a UNIX socket on the same system (instead of a TCP connection). And the socket file is located at /var/spool/postfix/private/dovecot-lmtp.

+

(You will find further information on these steps in the Dovecot configuration on Postfix integration.)

+ +

One of my favorite features of Dovecot are automatic rules for incoming email that are processed on the server. You can sort away your mailing list emails into special folders. You can reject certain senders. Or you can set up vacation auto-responders. No need to have a mail client running – it all happens automatically on the server even when your mail users are not connected.

+

The open standard (RFC 5228) for such rules is called Sieve. Basically, Sieve is a way to manage server-side email rules. A rule consists of conditions and actions. For example if the sender address matches steve@example.org you could tell Dovecot to move such emails to your “steve” folder automatically. These rules are stored on the Dovecot server and executed automatically. Whether you connect from your smartphone your laptop or use the webmail access – the rules always work and require no configuration on the client side.

+

As we use LMTP that’s where we need to tell the lmtp service that we want to use Dovecot’s “sieve” plugin. Edit the file /etc/dovecot/conf.d/20-lmtp.conf and within the “protocol lmtp” section change the “mail_plugins” line to:

+
mail_plugins = $mail_plugins sieve
+

Restart Dovecot and you are done:

+
systemctl restart dovecot
\ No newline at end of file diff --git a/dist/ispmail-bookworm/making-postfix-get-its-information-from-the-mariadb-database/index.html b/dist/ispmail-bookworm/making-postfix-get-its-information-from-the-mariadb-database/index.html new file mode 100644 index 0000000..168b1d1 --- /dev/null +++ b/dist/ispmail-bookworm/making-postfix-get-its-information-from-the-mariadb-database/index.html @@ -0,0 +1,126 @@ + Let Postfix access MariaDB | ISPmail Guide + Skip to content
+⚠️ This page is part of the ISPmail guide for Debian Bookworm. Please use the newer guide for Debian Trixie. +

Let Postfix access MariaDB

In the previous chapter you have created the SQL database schema and inserted some data to play with. Let’s start with the entry point for all email on your system: Postfix. So we need to tell Postfix how to get the information from the database. First let’s tell it how to find out if a certain domain is a valid email domain.

+ +

As described earlier a mapping in Postfix is just a table that contains a left-hand side (LHS) and a right-hand side (RHS). To make Postfix get information about virtual domains from the database we need to create a ‘cf’ file (configuration file). Start by creating a file called /etc/postfix/mysql-virtual-mailbox-domains.cf for the virtual_mailbox_domains mapping. Make it contain:

+
user = mailserver
password = x893dNj4stkHy1MKQq0USWBaX4ZZdq
hosts = 127.0.0.1
dbname = mailserver
query = SELECT 1 FROM virtual_domains WHERE name='%s'
+

Please enter your own password for the mailserver database user here. It is the first one you created before.

+

Imagine that Postfix receives an email for somebody@example.org and wants to find out if example.org is a virtual mailbox domain. It will run the above SQL query and replace ‘%s’ by ‘example.org’. If it finds such a row in the virtual_domains table it will return a ‘1’. Actually it does not matter what exactly is returns as long as there is a result. Remember the puppies and kittens?

+

Now you need to make Postfix use this database mapping:

+
Terminal window
postconf virtual_mailbox_domains=mysql:/etc/postfix/mysql-virtual-mailbox-domains.cf
```sh
+
The “postconf” command conveniently adds configuration lines to your `/etc/postfix/main.cf` file. It also activates the new setting instantly so you do not have to reload the Postfix process.
+
The test data you created earlier added the domain “example.org” as one of your mailbox domains. Let’s ask Postfix if it recognizes that domain:
+
```sh
postmap -q example.org mysql:/etc/postfix/mysql-virtual-mailbox-domains.cf
```sh
+
<Aside type="tip" title="Access denied?">
If you get an error like “postmap: warning: connect to mysql server 127.0.0.1: Access denied for user ‘mailserver’@’localhost'” then please double check the password of the ‘mailserver’ database user. It is either wrong in the CF file or you did not create the database user correctly using the GRANT query on the previous page.
</Aside>
+
You should get ‘1’ as a result. That means your first mapping is working. Feel free to try that with other domains after the `-q` in that line. You should not get a response.
+
## virtual\_mailbox\_maps
+
You will now define the _virtual\_mailbox\_maps_. It will map a recipient’s email address (left-hand side) to the location of the user’s mailbox on your hard disk (right-hand side). Postfix has a built-in transport service called “virtual” that can receive the email and store it into the recipient’s email directory. That service is pretty limited, so we will delegate that to Dovecot as it allows us better control.
+
Postfix will forward all emails to Dovecot for further delivery. But we need to make sure that the recipient actually exists before we do that. So Postfix needs to check whether an email address belongs to a valid mailbox. That simplifies things a bit because we just need the left-hand side of the mapping.
+
Similar to the above virtual\_domains mapping you need an SQL query that searches for an email address and returns “1” if it is found.
+
To accomplish that please create another configuration file at `/etc/postfix/mysql-virtual-mailbox-maps.cf`:
+

user = mailserver +password = x893dNj4stkHy1MKQq0USWBaX4ZZdq +hosts = 127.0.0.1 +dbname = mailserver +query = SELECT 1 FROM virtual_users WHERE email=‘%s’

+
Again please use your actual password for the ‘mailserver’ database user.
+
Tell Postfix that this mapping file is supposed to be used for the virtual\_mailbox\_maps mapping:
+
```sh
postconf virtual_mailbox_maps=mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf
+

Test if Postfix is happy with this mapping by asking it where the mailbox directory of our john@example.org user would be:

+ +

The virtual_alias_maps mapping is used for forwarding emails from one email address to one or more others. In the database multiple targets are achieved by using multiple rows.

+

Create another “.cf” file at /etc/postfix/mysql-virtual-alias-maps.cf:

+
user = mailserver
password = **x893dNj4stkHy1MKQq0USWBaX4ZZdq**
hosts = 127.0.0.1
dbname = mailserver
query = SELECT destination FROM virtual\_aliases WHERE source='%s'
+

Make Postfix use this database mapping:

+
postconf virtual_alias_maps=mysql:/etc/postfix/mysql-virtual-alias-maps.cf
+

Test if the mapping file works as expected:

+
postmap -q jack@example.org mysql:/etc/postfix/mysql-virtual-alias-maps.cf
+

You should see the expected destination:

+

john@example.org

\ No newline at end of file diff --git a/dist/ispmail-bookworm/managing-users-aliases-and-domains/index.html b/dist/ispmail-bookworm/managing-users-aliases-and-domains/index.html new file mode 100644 index 0000000..17b6f4c --- /dev/null +++ b/dist/ispmail-bookworm/managing-users-aliases-and-domains/index.html @@ -0,0 +1,115 @@ + Managing users, aliases and domains | ISPmail Guide + Skip to content
+⚠️ This page is part of the ISPmail guide for Debian Bookworm. Please use the newer guide for Debian Trixie. +

Managing users, aliases and domains

Maybe you already know what you have to do to create mail domains and mail users. After all I tried to explain the database schema in the section that dealt with preparing the database. But if that wasn’t clear enough let me explain what you need to do to manage your mail accounts.

+ +

The following sections explain the changes and SQL queries you can use for common management tasks:

+ +

Insert a new row into the virtual_domains table and set the “name” to the name of the new domain. (Do not forget to set up SPF and DKIM.)

+ +

Delete the row from the virtual_domains table that has the right “name”. All aliases and users will automatically be deleted, too. However the mailboxes will stay on disk at /var/vmail/… and you need to delete them manually.

+ +

Find out the “id” of the right domain from the virtual_domains table. The insert a new row into the virtual_users table. Set the domain_id to the value you just looked up in the virtual_domains table. Set the “email” field to the complete email address of the new user. Create a new password in a shell using the “dovecot pw -s BLF-CRYPT” command and insert the result into the “password” field.

+ +

Find the row in the virtual_users table by looking for the right “email” field. Create a new password in a shell using the “dovecot pw -s BLF-CRYPT” command and insert the result into the “password” field.

+ +

Find the row in the virtual_users table by looking for the right “email” field and delete it. The mailbox will stay on disk at /var/vmail/… and you need to delete it manually

+ +

You can forward emails from one (source) email to other addresses (destinations) – even outside of your mail server. Find out the “id” of the right domain (the part after the “@” of the source email address) from the virtual_domains table. Create a new row in the virtual_aliases table for each destination (if you have multiple destination addresses). Set the “source” field to the complete source email address. And set the “destination” field to the respective complete destination email address.

+ +

Find all rows in the virtual_aliases table by looking for the right “source” email address. Remove all rows that you lead to “destination” addresses you don’t want to forward email to.

+ +

If you don’t like using SQL queries to manage your mail server you may like to install a web-based management software. Several developers contributed web interfaces for earlier versions of this guide and they will probably still work because the database schema has not changed. Your experience with these projects, or links to further projects, is very welcome in the comments.

+ +

Homepage: http://ima.jungclaussen.com/
+Demo: http://ima.jungclaussen.com/demo/

+

ISPmail Admin screenshot

+ +

Christian G. has created a text-based program to help you manage your mail accounts. You may like it if you just want a little help adding accounts and setting passwords but not provide a full blown web interface.

+

You can find his Python script at Github.

\ No newline at end of file diff --git a/dist/ispmail-bookworm/migrating-from-a-bullseye-to-a-bookworm-server/index.html b/dist/ispmail-bookworm/migrating-from-a-bullseye-to-a-bookworm-server/index.html new file mode 100644 index 0000000..e0bfdd0 --- /dev/null +++ b/dist/ispmail-bookworm/migrating-from-a-bullseye-to-a-bookworm-server/index.html @@ -0,0 +1,139 @@ + Migrating from your old (Bullseye) server | ISPmail Guide + Skip to content
+⚠️ This page is part of the ISPmail guide for Debian Bookworm. Please use the newer guide for Debian Trixie. +

Migrating from your old (Bullseye) server

+

I recommend that you set up a new server and make sure that the new mail server is working correctly before you start migrating existing email users to it. You may argue that Debian can be upgraded easily using “apt-get dist-upgrade” but that is very dangerous on a live mail server. Automatic configuration changes may have evil side effects and you risk losing emails. At least you are causing a downtime for your users.

+

If you follow my advice then get a new server and install Debian Bookworm on it. Once the user mailboxes are migrated and all works well you can tear down the old server.

+

Once your new server is installed come back here.

+ +

Follow this guide to the end. Only then start attempting a migration. Inform your users about the migration and set a time when you intend to move email accounts to the new server. The change will require a DNS change which takes a while to be visible worldwide so your users will have a period when incoming email is delayed. If you proceed careful though not a single email will be lost.

+

So you have your new server up and running and did everything to make it a working mail server? You really read all the pages in this guide and did what they told you? Okay, then let’s start.

+ +

The DNS “MX” record for your domain contains the hostname of your mail server. When switching to the new server you need to change the MX record. Every DNS record has a TTL (time-to-live) that defines the period of time that a record will stay valid even after you change it. Usually that TTL is rather high like 86400 seconds (=1 day). This information is used by caching name servers that they can use the cached values for a day. Turn that TTL down temporarily to 60 seconds so that the rest of the internet will pick up your change quicker. However it will take a day until everyone else on the internet picks up your TTL change.

+ +

You need to copy the database that contains the control data about your email domains and accounts. Log into the old (Bullseye) server as root and back up the mailserver database. That is as easy as running…

+
mysqldump mailserver > mailserver.sql
+

Copy that file to the new server (using scp) and import it there:

+
mysql mailserver < mailserver.sql
+

Obviously any database changes on the old server from now on will have to be done on the new server as well until the migration is done.

+ +

If your users are using Roundcube as a webmail interface then you should migrate their data like their contact lists. Dump the SQL from the old server:

+
mysqldump roundcube > roundcube.sql
+

Copy that file to the new server and import it:

+
mysql roundcube < roundcube.sql
+

One caveat though. To distinguish multiple mail servers Roundcube stores the server’s name in the mail_host column of the users table. So as a last step change that column if your new mail server has a new FQDN/hostname by running this SQL query on the new roundcube database:

+
UPDATE users SET mail_host='new.mail.server';
+ +

If you have been using rspamd with the Redis backend then copy over the Redis database from your previous server. Details are found in the rspamd chapter.

+ +

Fortunately Dovecot uses the maildir format that stores emails as plain files on disk. Login to the new (Bookworm) server and use rsync to copy over the mails from the old (Bullseye) mail server:

+
rsync -va oldserver:/var/vmail/ /var/vmail/
+

(Note the trailing slashes. Type them exactly as shown above or your files will end up in wrong places.)

+

There is no need to shut down Dovecot on your production Bullseye server. Copying the files while Dovecot is running will not break anything. This is called a “hot copy”. It may not be consistent but it will save time during the final synchronization.

+ +

Copy over everything in /etc/letsencrypt and /var/lib/rspamd/dkim from your old to the new server.

+
rsync -va oldserver:/etc/letsencrypt/ /etc/letsencrypt/
rsync -va oldserver:/var/lib/rspamd/dkim/ /var/lib/rspamd/dkim/
+ +

You told your users about the downtime, right? The time has come? Okay. Shut down Dovecot on both servers.

+ +

Let’s synchronize again. rsync will only copy those files that have changed which makes it much faster than the first sync. On your new server run:

+
rsync -va --delete oldserver:/var/vmail/ /var/vmail/
+

(The “--delete” option makes sure that files that have been removed from the old server will also be deleted from the new server. So if a user has deleted an email it will be deleted on the new server as well.)

+

The new Dovecot version uses a slightly different indexing mechanism. So force rebuilding the users’ indices:

+
doveadm force-resync -A '*'
+ +

For all your domains you will have to change the DNS “MX” or “A” record to point to your new server.

+ +

Accidents happen. And you don’t want to lose emails. So run this command to enable your safety net on the new server:

+
postconf soft_bounce=yes
+

This makes Postfix always keep emails in the queue that it would otherwise reject. So you can fix any errors and the queue will empty. Start Postfix and Dovecot on the new server. Watch your /var/log/mail.log and run “mailq” from time to time to see what emails get stuck in the queue. If you are certain that emails can be removed from the queue then use “postsuper -d QUEUE-ID” (as shown in the “mailq” output).

+

Once you are certain that emails are properly received and sent you can switch off the soft_bounce mode again:

+
postconf soft_bounce=no
+ +

If possible do a final backup of the old server. If users are not complaining then dismiss the old system after a week.

\ No newline at end of file diff --git a/dist/ispmail-bookworm/monitoring-and-backup/index.html b/dist/ispmail-bookworm/monitoring-and-backup/index.html new file mode 100644 index 0000000..b8cbb84 --- /dev/null +++ b/dist/ispmail-bookworm/monitoring-and-backup/index.html @@ -0,0 +1,129 @@ + Monitoring and Backup | ISPmail Guide + Skip to content
+⚠️ This page is part of the ISPmail guide for Debian Bookworm. Please use the newer guide for Debian Trixie. +

Monitoring and Backup

You have come a long way. Glad you made it. So many weird things complicated the journey that evolved from the very beginning of using email roughly 35 years ago. But before you take your much deserved break from these adventures let’s take care of some final tasks.

+ +

For me there is nothing more awkward than having your users tell me that my systems are not working properly. As a good sysadmin I should notice outages in advance. The most frequent cause for mail server issues is a disk that is running full. Users are pretty bad with cleaning their mess up. For them the space of their mailbox is infinite. So one way is to use quotas where possible. But at least you should get notified of error conditions on your mail server.

+

I will not dive into monitoring deeply here. Setting up proper monitoring will easily fill a guide similar to the size of the one you are currently reading. But you should either have your own monitoring system set up or at least use an internet service to check if emails are getting through.

+

Things I suggest you check frequently:

+
    +
  • Is there enough space on disk? Especially /var/vmail?
  • +
  • Are the SMTP, Submission, POP and IMAP ports responding from other servers?
  • +
  • Is your mail server’s IP address blacklisted? There are several services you can use.
  • +
  • Are any emails coming through? (I just do a simple count like “grep -c relay= /var/log/mail.log“)
  • +
  • Number of emails in the mail queue? (mailq)
  • +
  • Are your backups restoreable? A propos backups…
  • +
+ +

No matter if you are running your family mail server or are in charge for an organisation – nobody likes to lose email. There are many different backup tools for different purposes. Just to name my open-source favorites that ship with Debian:

+
    +
  • rsnapshot. A simple solution if you want to send backups to other servers using SSH/SCP. You can also keep backups for different points in time on your local server. But if your disk crashes then all would be lost. Also rsnapshot can become slow with many emails because every file is copied as a link. But you can access the files directly without any restore procedure. It’s basically a frontend for rsync which is very reliable.
  • +
  • borg. This tools needs to be installed both on the client and the server. Setting up an archive (where backups live) on the server feels a bit weird. But you are rewarded by compression, encryption and deduplication. Also data is stored in chunks which takes less I/O than rsnapshot. It is very efficient.
  • +
  • restic. Similar to Borg in a way. It also offers deduplication, compression and encryption. It’s main advantage is to be able to store backups in S3 buckets. Consider cheap storage providers like Wasabi or Backblaze. However purging old data through S3 is a very resource-intensive job. And Restic generally eats a lot of RAM and disk cache.
  • +
  • Bareos. Formerly known as Bacula until its author started to have crazy ideas and these guys forked it. This is a full-fledged system to handle many servers in parallel and store things on different media – for example LTO magnetic tapes in a big tape library.
  • +
  • Snapshots. If your mail server is running on a virtual server then check if your ISP is offering snapshot backups. My favorite ISP charges 20% extra costs for the service but it is totally worth it. If you break your server for any reason you can just restore it to the old glory without fiddling with configuration files. It does not replace a file-based backup though. So if a user accidentally deletes an email and wants to get it back then this kind of backup will not be right.
  • +
+

If you cannot backup your entire disk then at least include these directories:

+
    +
  • /etc (configuration)
  • +
  • /var/vmail (the actual emails)
  • +
  • /var/log (in case the system breaks you may be able to figure out what happened last)
  • +
  • /var/backups (for general backups)
  • +
  • /var/lib/rspamd/dkim/ (private part of the DKIM keys)
  • +
+

Also make sure to exclude:

+
    +
  • /var/lib/mysql
  • +
+

Instead run…

+
mysqldump mailserver > /var/backups/mailserver.sql
+

…daily to get a proper database backup that can be restored later.

+

I also like to backup the output of these files because they help me figure out the specific layout of a server:

+
fdisk -l
lshw
lsb_release -a
dpkg --get-selections
+

If one of your users just accidentally deleted an email and wants it back then simply get the files from /var/vmail/domain/user/Maildir/… from the backup and put them into the original location. Dovecot will handle everything else. You don’t need to restart anything.

\ No newline at end of file diff --git a/dist/ispmail-bookworm/prepare-the-database/index.html b/dist/ispmail-bookworm/prepare-the-database/index.html new file mode 100644 index 0000000..427a446 --- /dev/null +++ b/dist/ispmail-bookworm/prepare-the-database/index.html @@ -0,0 +1,242 @@ + Preparing the database | ISPmail Guide + Skip to content
+⚠️ This page is part of the ISPmail guide for Debian Bookworm. Please use the newer guide for Debian Trixie. +

Preparing the database

Now it’s time to prepare the MariaDB database that stores the information that controls your mail server. In the process you will have to enter SQL queries – the language of relational database servers. You may enter them in a terminal window using the ‘mysql’ command. But if you are less experienced with SQL you may prefer using a web interface. That’s what you installed Adminer for.

+ + +

Basically Adminer is just a couple of PHP files served from your Apache web server. The setup is simple. Edit your /etc/apache2/sites-available/webmail.example.org-https.conf file and put this line anywhere between the <VirtualHost> and the </VirtualHost> tags:

+
Alias /adminer /usr/share/adminer/adminer
+

Reload the Apache process:

+
systemctl reload apache2
+ +

You will not be able to login yet. The only available database user is ‘root’, but it is only usable from the shell by default – not over a network.

+ +

In this section you will create the basic database “mailserver” and two users. One user (“mailadmin”) will be able to change the data in the database and is meant for you. The other user (“mailserver”) can only read from the database and is meant for the server processes.

+

Use the pwgen tool to create two random passwords for these users:

+
pwgen -s1 30 2
+

Take a note of the passwords or store them somewhere safe.

+ +

This step is simple. Connect to the database using the ‘mysql’ command:

+
mysql
+

You should see the MariaDB prompt that allows you to enter further SQL commands:

+
MariaDB [(none)]>
+

Now you are expected to speak SQL. To create a new database for our needs enter:

+
CREATE DATABASE mailserver;
+

You will be told that your query was OK and that one new row was added.

+ +

Now you have an empty database. Let us give the “mailadmin” database user the required privileges to manage it.

+

You are still connected to the database, right? To create a user with full permissions enter this SQL command. Please use the first password you just generated instead of mine:

+
grant all privileges on mailserver.* to 'mailadmin'@'localhost' identified by 'gefk6lA2brMOeb8eR5WYaMEdKDQfnF';
+

Also create the read-only user that will grant Postfix and Dovecot database access later (use your second random password here).

+
grant select on mailserver.* to 'mailserver'@'127.0.0.1' identified by 'x893dNj4stkHy1MKQq0USWBaX4ZZdq';
+ +

Now you can use Adminer to log in using the mailadmin account and the first password:

+

Login to Adminer

+

You should get logged in and see the “mailserver” database:

+

Create a database in Adminer

+ +

Do you remember that I introduced three Postfix mappings earlier? One for virtual domains, one for virtual aliases and another for virtual users? Each of the mappings needs a database table that you will create now. Feel free to use Adminer. I will however also show the SQL statement to create the tables that you can enter on the ‘mysql’ command-line tool. Below you can click on either [Adminer] or [SQL] to choose.

+

The first table to create is…

+ +

This table just holds the list of domains that you will use as virtual_mailbox_domains in Postfix.

+
+ + + + + + + + + + + + + + + + +
ColumnPurpose
idA unique number identifying each row. It is added by the database automatically.
nameThe name of the domain you want to receive email for.
+ +

The next table contains information about your users. Each mail account takes up one row.

+
+ + + + + + + + + + + + + + + + + + + + + + + + +
ColumnPurpose
domain_idContains the number of the domain’s id in the virtual_domains table. This is called a foreign key. A “delete cascade” makes sure that if a domain is deleted that all user accounts in that domain are also deleted to avoid orphaned rows.
emailThe email address of the mail account.
passwordThe hashed password of the mail account. It is prepended by the password scheme. By default it is {BLF-CRYPT} also known as bcrypt which is considered very secure. Previous ISPmail guides used {SHA256-CRYPT} or even older crypt schemes. Prepending the password field the hashing algorithm in curly brackets allows you to have different kinds of hashes. So you can easily migrate your old passwords without locking out users. Users with older schemes should get a new password if possible to increase security.
quotaThe number of bytes that this mailbox can store. You can use this value to limit how much space a mailbox can take up. The default value is 0 which means that there is no limit.
+ +

The last table contains forwardings from an email address to other email addresses.

+
+ + + + + + + + + + + + + + + + + + + + + + + + +
FieldPurpose
idA unique number identifying each row. It is added by the database automatically.
domain_idContains the number of the domain’s id in the virtual_domains table again.
sourceThe email address that the email was actually sent to. In case of catch-all addresses (that accept any address in a domain) the source looks like “@example.org”.
destinationThe email address that the email should instead be sent to.
+

As described in the section about domain types there can be multiple targets for one source email address. You just would need to insert several rows with the same source address and different destination addresses that will get copies of an email. Postfix will consider all matching rows.

+ +

Too much theory so far? I can imagine. Let’s populate the database with an example.org domain, a john@example.org email account and a forwarding of jack@example.org to john@example.org. We will use that information in the next chapter to play with.

+

To add that sample data just run these SQL queries:

+
REPLACE INTO mailserver.virtual\_domains (id,name) VALUES ('1','example.org');
+
REPLACE INTO mailserver.virtual\_users (id,domain\_id,password,email)
VALUES ('1', '1',
'{BLF-CRYPT}$2y$05$.WedBCNZiwxY1CG3aleIleu6lYjup2CIg0BP4M4YCZsO204Czz07W',
'john@example.org');
+
REPLACE INTO mailserver.virtual\_aliases (id,domain\_id,source,destination)
VALUES ('1', '1', 'jack@example.org', 'john@example.org');
+

Do you wonder how I got the long cryptic password? I ran…

+
doveadm pw -s BLF-CRYPT
+

…to create a secure hash of the simple password “summersun”. Once you have installed Dovecot you can try that yourself but you will get a different output. The reason is that the passwords are salted to increase their security.

+

Remember to remove that sample data before you go live with your mail server. Thanks to the delete cascade you just need to remove the virtual_domain. The alias and the mailbox will be deleted automatically. This would be the SQL query you should run before taking your mail server into production:

+
DELETE FROM mailserver.virtual_domains WHERE name='example.org';
\ No newline at end of file diff --git a/dist/ispmail-bookworm/prevent-spoofing-using-dkim/index.html b/dist/ispmail-bookworm/prevent-spoofing-using-dkim/index.html new file mode 100644 index 0000000..b0ae429 --- /dev/null +++ b/dist/ispmail-bookworm/prevent-spoofing-using-dkim/index.html @@ -0,0 +1,168 @@ + Prevent spoofing using DKIM | ISPmail Guide + Skip to content
+⚠️ This page is part of the ISPmail guide for Debian Bookworm. Please use the newer guide for Debian Trixie. +

Prevent spoofing using DKIM

Email sender spoofing is the act of pretending to be in control of someone else’s email address. This is a common problem with phishing. Often scammers send emails with a sender address of something@paypal.com and hope that the recipient falls for it and trusts them. In fact SMTP does not care which sender address you send. Many mail service providers enforce that you send emails only using your own email address. But some do not. And spammer and scammers obviously could not care less.

+

Spoofing case without DKIM

+

So roughly ten years ago a new method was conceived that added a cryptographic signature to the header of an email that the recipient could check to verify the authenticity of the sender and the integrity of the email. The signature is created using a private key that only the sending mail server has. It can then be verified by the recipient by downloading the corresponding public key from the DNS zone of the sending domain and running a signature check. This works very similar to PGP or S/MIME signing – just on a domain level. Your mail server can sign all outgoing emails automatically. The method used nowadays is called Domain Keys Identified Mail – or short: DKIM.

+

Let’s take an example. I have just sent an email from GMail to my personal email account on my own mail server. Google uses DKIM signing so the email got this additional header from Google’s mail servers:

+
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=gmail.com; s=20161025;
h=mime-version:from:date:message-id:subject:to;
bh=/FpkZfBuKR0WWcH2fFcr9M4qgX4Z4+/0dX4dpqycK28=;
b=fZ4Efy1TuXAl1ho2twkEuNiVP8k5GRKqlol/f/dTawaxciAv1bwinkbu…
+

I need Google’s DKIM public key to verify that signature. It is stored in their DNS zone as a TXT record of “20161025._domainkey.google.com”. The “20161025” is the key selector that is mentioned in the signature as “s=20161025“. You can use any number of keys as long as you create the signatures with the matching private key.  The “_domainkey” part is the standard subdomain for DKIM keys. So let’s get that TXT record:

+
dig +short 20161025._domainkey.google.com txt
+

This returns…

+
"k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwXNZF1j8sJPDleRjf9SPBNem0ik58kF1ilC1nUgKAttl9v7FX9hXJXPmLNhVtSKVZ8yruaeOZLeIxtgtk1s81zzIE5Mj0AiGn2wlFt4kYfqlDfYe95YLQHjynu4i7vj1Tj" "ksf62btcCbL+3XhbK+oD5PlqYhXHWuzoKoEp5L4lCihgkONvU/oy7NNeE6quqfF/y0YSLwF2WVA2Kd8L6R0Ar2dYT/3wZCFknI7xhvPqh9HNcIWBELGPwtXcsHbX1wvBlCgNQAUcdJrf2YWzAwqmZ564/1ipL1IMk1nafPJk75ktumVNz6ORuIn3jbZWp9rRpnaeI9cu/8KfSKH2EY9QIDAQAB"
+

That is the public key that I can use to verify the signature. An automated check can be done using the “opendkim-testmsg” tool as described later. I can run it and paste the entire email including headers and body into it. If it doesn’t complain with an error message then the signature is correct.

+

Sounds good? Then let’s implement that for your email domain, too.

+ +

As explained above you need a private key that your mail server will use and a public key that gets added to your DNS zone. rspamd can create DKIM keys already. You may want to install “dig” though which allows to query DNS records. It works similar to “nslookup” but is more versatile.

+
apt install dnsutils
+

rspamd has its built-in DKIM signing module enabled by default.

+

If you put your key file into /var/lib/rspamd/dkim/ using a certain naming scheme it will pick it up automatically. Create that directory to store keys in:

+
mkdir /var/lib/rspamd/dkim
chown _rspamd:_rspamd /var/lib/rspamd/dkim
+

Create your keypair:

+
rspamadm dkim_keygen -d example.org -s 2019122401
+

The selector (-s) I chose is 2019122401 because that’s the day I created it. The first (01) key on 2019-12-24. It doesn’t matter though – you can name it anything you want. If you are lazy and unconcerned you could even use “dkim” as the selector and later spare some work by not needing DKIM maps that define which key is supposed to be used for each domain. “dkim” is the default selector if you do not use maps. But you will probably some day want or need to replace the key so I recommend you rather use maps as explained further below. It gives you more flexibility and is pretty easy to do.

+

The output will look like this:

+
-----BEGIN PRIVATE KEY-----
MIICdwIBADANBgkqhkiG9w0BAQE…
-----END PRIVATE KEY-----
2019122401._domainkey IN TXT ( "v=DKIM1; k=rsa; " "p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCZ8e4RtsvuvsgXyo3Jr63twdx3Zm2RtnYPf87wba5ZnFP0sQIagjJ0R3WL+djKhM5EteBeboTeaflLR+AUKWJdQnL5jzGil+yWThH5C+ixhkdFZPdabkxBji+3r6uRxJKBsN0gy2/+Gp4sGs7lmFgioki9OLgQnzzFh2nE/MSACwIDAQAB" ) ;
+

The first part is the private key. And that includes the “…BEGIN…” and “…END…” lines. This key must be kept secret and will only be used by your mail server to sign outgoing emails.

+

The second part is the DNS record you need to add to your domain’s DNS zone. Let’s start with that.

+ +

Before you start signing your emails you must make sure that the public key is properly present in your DNS zone for the domain you are sending emails from. Otherwise the recipient will be unable to verify the signature and may incorrectly assume that the email was spoofed.

+

Take a look at the TXT record. It will look something like this:

+
2019122401._domainkey IN TXT ( "v=DKIM1; h=sha256; k=rsa; " "p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCxenHupkYLPmFMbJjV9dQICKUl2xH/aexSRUwCuw7TJ9dkddqIN+6tyw4VKhnW8R0/UlbzlSFLmVgMU0uUkwTtVqyDHhtSU7LV/SkVYmUst4dTUF1r+8PvhAm7vobMYKdwvRsOq27ABtZc8P4oU2XXHqqa6LU8s4sNxs12hLW9swIDAQAB" ) ;
+

If you are running your own DNS server you should be able to copy this entire file and put it into your DNS zone. However if your internet provider offers you just a web interface to manage your domains then create a new TXT record with a host name of “2019122401._domainkey” in your domain and put the string within the double-quotes into it as the value. In my example:

+
2019122401._domainkey ➠p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCxenHupkYLPmFMbJjV9dQICKUl2xH/aexSRUwCuw7TJ9dkddqIN+6tyw4VKhnW8R0/UlbzlSFLmVgMU0uUkwTtVqyDHhtSU7LV/SkVYmUst4dTUF1r+8PvhAm7vobMYKdwvRsOq27ABtZc8P4oU2XXHqqa6LU8s4sNxs12hLW9swIDAQAB
+

Be aware that the string you got contains two strings “…” + “…” that must be merged into one to work. (The syntax with quotes is meant for a DNS zone file if you run your own name server like bind.) There must usually not be any quotes in the record data. Depending on your ISP it may take a while until the new record is visible on the internet. You can use dig to verify that:

+
dig +trace 2019122401._domainkey.example.org txt
+

If you get the TXT entry like as follows then you are ready to enable DKIM signing in rspamd for that domain:

+
TXT "p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCxenHupkYLPmFMbJjV9dQICKUl2xH/aexSRUwCuw7TJ9dkddqIN+6tyw4VKhnW8R0/UlbzlSFLmVgMU0uUkwTtVqyDHhtSU7LV/SkVYmUst4dTUF1r+8PvhAm7vobMYKdwvRsOq27ABtZc8P4oU2XXHqqa6LU8s4sNxs12hLW9swIDAQAB" "" from server foo.bar in 24 ms.
+ +

As explained above it is advised to use DKIM maps. It’s nothing fancy. Just a simple file defining which selector you want to use for a certain domain. rspamd will assume that your selector is always “dkim” unless specified otherwise in a map. If you used “dkim” then you may get into trouble when you later want to replace your key. DNS is a sluggish system and propagating a new DKIM public key may take a day. Emails signed with a newer key may get rejected while the DNS record is not yet known everywhere in the world.

+

Using maps is simple. First we need to change the selector_map setting of the dkim_signing module. To do that create a new file in /etc/rspamd/local.d/dkim_signing.conf and make it contain just these two lines:

+
path = "/var/lib/rspamd/dkim/$domain.$selector.key";
selector_map = "/etc/rspamd/dkim_selectors.map";
+

The configuration is pretty self-explaining. rspamd will look for the domain-to-key mapping in the dkim_selectors.map file. Create that file and make it contain this line:

+
example.org 2019122401
+

That’s all really. rspamd now knows that whenever it sees an outgoing email from anyone@example.org it will get the DKIM private key from /var/lib/rspamd/dkim/example.org.2018022301.key and use it to sign the email.

+

Reload the configuration:

+
systemctl restart rspamd
+

This method works well if you just have a few domains that virtually never change. If you are rather serving random customer domains you should consider putting the keys into a Redis database instead as described in the documentation. There is not yet a way to manage DKIM keys in a database like MySQL.

+ + +

Take the private key that was created earlier (the multi-line string including “…BEGIN PRIVATE KEY…” and “…END PRIVATE KEY…“) and put it into a file at the location where rspamd will look for it:

+
/var/lib/rspamd/dkim/example.org.2019122401.key
+

The name of the file has to be  DOMAIN + dot + SELECTOR + “.key” like above. If you name the file incorrectly you will get an error in your rspamd.log file like “lua_dkim_sign_handler: cannot load dkim key /var/lib/rspamd/dkim/example.org.dkim.key“.

+

Make sure that only _rspamd can read it:

+
chown _rspamd /var/lib/rspamd/dkim/*
chmod u=r,go= /var/lib/rspamd/dkim/*
+

rspamd will automatically pick up the files and does not need to be restarted.

+ +

If you have another email account at another location then you could just send a test email there via your mail server. If you take a look at the received email it should have a DKIM header now like:

+
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=example.org; s=2019122401; t=1519400838 h=from:subject:date:message-id:to:mime-version:content-type:content-transfer-encoding; bh=kpYel1IlDvqXEUc0SyIpXbMte3XpQOCXHl+zTyHQvGc=; b=NEUyWUoeKE…
+

DKIM signature verification failed

+

To verify the signature install the opendkim-tools package, copy the entire test email (including headers and body), run opendkim-testmsg in your shell and paste the email (finish with CTRL-D).

+

If you get no output then the signature verified correctly. But if you get something like “opendkim-testmsg: dkim_eom(): Unable to verify” then double-check your DNS record.

+

You can also use websites like dkimvalidator.com, isnotspam.com or mail-tester.com service to verify that your signatures are working well.

+ +

Adding DKIM signatures is a good first step. But you can take it further by telling receiving mail servers that they should not accept any email from your domain without a valid signature or from servers that you do no operate. There are two concepts that aim to help. The older SPF and the newer DMARC. Either of them means creating a machine-readable string in a predefined format and adding a TXT record to your DNS zone. Receiving mail servers can check those records and take your advice (as the domain owner) what to do if the criteria of the email are not met. It could accept the email anyway or flag it as spam or reject it altogether.

+

Let’s take a look at a typical SPF record:

+
"v=spf1 ip4:157.97.194.11 mx ~all"
+

What it means:

+
    +
  1. this is an SPF record of version 1 of the standard (there is currently no other version)
  2. +
  3. please accept emails from the IP address 157.97.194.11
  4. +
  5. alternatively accept emails from any server that is mentioned in our domain’s MX record (the server(s) that receive email for your domain)
  6. +
  7. any other email should be considered suspicious – it might be spam or worse
  8. +
+

There are websites that help you create your SPF string to add to your DNS domain. Keep in mind though:

+
    +
  • You should know which mail servers send email from your domain. Do not forget to include mailing list or newsletter services that send in your name.
  • +
  • Start with “~all” to mark emails as spam that do not meet the criteria. If all goes well switch to “-all” after a few weeks if you like.
  • +
  • Note that forwarding emails from your domain may break SPF because suddenly the email appears to be coming from an IP address that is not authorized. This has been a common problem for mailing lists and is gradually being fixed by resending the email from the domain of the mailing list service.
  • +
+

I mentioned that DMARC is the newer standard. So why use SPF anyway? Because some email providers value your effort if you use SPF, too. Technically it’s sufficient to specify a DMARC entry. In my opinion restricting the IP addresses allowed to send is a little dangerous and a little inflexible. It is far more interesting to require that emails from your domain have a valid DKIM signature. Such a record may look like:

+
"v=DMARC1; p=reject; adkim=s; ruf=postmaster@example.org"
+

However to create a proper DMARC entry I suggest you use one of the web sites that aid you there and explain the restrictions and extra features.

\ No newline at end of file diff --git a/dist/ispmail-bookworm/quotas/index.html b/dist/ispmail-bookworm/quotas/index.html new file mode 100644 index 0000000..61ae6be --- /dev/null +++ b/dist/ispmail-bookworm/quotas/index.html @@ -0,0 +1,188 @@ + Quotas | ISPmail Guide + Skip to content
+⚠️ This page is part of the ISPmail guide for Debian Bookworm. Please use the newer guide for Debian Trixie. +

Quotas

+

Quotas are size limits for users. You can make sure that users do not waste arbitrary amounts of disk space but are +forced to clean up old emails every now and then.

+

The magic happens in two places:

+
    +
  1. Postfix needs to reject new emails if the user’s mailbox is over quota.
  2. +
  3. Dovecot needs to keep track of the quota and how much the user has already used up of it.
  4. +
+ +

Let’s start with Dovecot. Find the file /etc/dovecot/conf.d/90-quota.conf and edit it. There are several plugin {} +sections. Take one and make it look like:

+
plugin {
quota = count:User quota
quota_vsizes = yes
+
quota_status_success = DUNNO
quota_status_nouser = DUNNO
quota_status_overquota = "452 4.2.2 Mailbox is full and cannot receive any more emails"
}
+

The first line defines that you want to calculate the used space in a user’s maildir. There are several +backends like that but the +count is the best choice in +this context. (Previous guides used maildir here.) The string “User quota” is just an arbitrary string that may be +queried from a mail user agent.

+

The lines starting with “quota_status_…” set return values for the service that you will set up in a minute. It will +tell Postfix that it will not interfere (DUNNO – colloquial way to say “I don’t know”). And it will return a string +with a return code 452 if the user is over quota. Codes starting with “4” mean temporary errors. It will tell the +sending party that it is worth retrying at a later time. However if the user does not resolve the issue it will lead to +a bounce error email after three days.

+

In the same file (90-quota.conf) add another section:

+
service quota-status {
executable = /usr/lib/dovecot/quota-status -p postfix
unix_listener /var/spool/postfix/private/quota-status {
user = postfix
}
}
+

This creates a new Dovecot service responding to +requests from other processes. You surely recognize that we put it into the jail that Postfix runs in +(/var/spool/postfix), so that Postfix can access it.

+

Time to restart Dovecot:

+
systemctl restart dovecot
+

Take a look at the /var/spool/postfix/private directory. If all went as intended you will find a socket file called +quota-status there. Otherwise please check the /var/log/mail.log file for errors.

+ +

If we stopped here, then Dovecot would reject emails for users who have no space left. However Postfix would still +happily receive new emails and attempt to forward them to Dovecot via LMTP. Dovecot however will deny that. It will then +keep the email in its queue and retry for a while. In the end it will send a bounce back to the sender telling them +about the problem. So why is this bad?

+
    +
  1. The sender will assume that the email was delivered while it is stuck in the queue for up to three days.
  2. +
  3. Spam emails use forged senders. So at the time that Postfix generates the bounce email it will likely send it to an +innocent person. This is called backscatter and considered a mail server misconfiguration. Such a problem may get +your mail server blacklisted. You don’t want that.
  4. +
+

So the next logical step is to make Postfix check whether a mailbox is over quota whenever a new email arrives. Let’s +hook up into the “RCPT TO” phase of the SMTP dialog when a new email comes in. Postfix checks its +smtpd_recipient_restrictions configuration at this stage. Run this command in the shell:

+
postconf smtpd_recipient_restrictions=reject_unauth_destination, \
"check_policy_service unix:private/quota-status"
+

This adds two checks:

+
    +
  1. reject_unauth_destination checks whether the mail server is the final destination for the recipient’s email +address. This is pretty much the default behavior if you do not define any restrictions.
  2. +
  3. check_policy_service connects to the socket file at /var/spool/postfix/private/quota-status that was put there by +Dovecot. It will use it to ask Dovecot whether the user is over quota in which case the email would get rejected.
  4. +
+ +

If you are curious to see this working, then set John’s mailbox quota to 5 KB:

+
# mariadb mailserver
mysql> update virtual_users set quota=4000 where email='john@example.org';
+

Send him a few emails using the ‘swaks’ tool:

+
swaks --server localhost --to john@example.org
+

After a few emails you will see the rejection message:

+
-> RCPT TO:john@example.org
<** 452 4.2.2 john@example.org: Recipient address rejected: Mailbox is full and cannot receive any more emails
+ +

These are things you should consider if quotas do not seem to work properly:

+
    +
  • Check if you have enabled “quota” in the “mail_plugins” in the 10-mail.conf file.
  • +
  • Your users may complain that they have deleted many emails but are still over quota. Let them check if they actually +emptied the Trash folder. Of course emails in that folder also contribute to the disk space usage. Once the Trash +folder is expunged the problem should be gone. You may also allow your users more space in the Trash folder. That’s +explained in the Dovecot documentation.
  • +
  • If you directly remove files from a user’s Maildir instead of properly accessing the mailbox using IMAP then you will +screw up the quota calculation. In that case let Dovecot recalculate the quota:
    +doveadm quota recalc -u john@example.org
  • +
+ +

The last step is to inform the poor users if they accidentally went over quota. After all they do not necessarily +recognize that on their own. Let’s do that by sending them an email with a warning. Yes, we will make sure that the +email gets through even if the quota is reached.

+

Edit the 90-quota.conf file again. Add this section to the file (derived from the +Dovecot documentation):

+
plugin {
quota_warning = storage=95%% quota-warning 95 %u
quota_warning2 = storage=80%% quota-warning 80 %u
}
service quota-warning {
executable = script /usr/local/bin/quota-warning.sh
unix_listener quota-warning {
user = vmail
group = vmail
mode = 0660
}
}
+

This section defines two automatic quota warnings. The first (quota_warning) is triggered if the user reaches 95% of the +quota. The second (quota_warning2) at 80%. These lines follow this schema:

+
    +
  • Trigger (e.g. “storage=95%”). The “%” sign needs to be used twice if you want to emit a literal percent sign. So +this is not a typo.
  • +
  • The socket you want to call in that case. Our socket is the “service quota-warning” that calls a shell script.
  • +
  • Additional parameters that are passed to the shell script in our case. They tell the script the percentage that +has been reached (e.g. 95) and the address of the user who should get the warning.
  • +
+

Apparently we need the script to run. So please create a new file at /usr/local/bin/quota-warning.sh and put these +lines into it:

+
#!/bin/sh
PERCENT=$1
USER=$2
cat << EOF | /usr/lib/dovecot/dovecot-lda -d $USER -o "plugin/quota=maildir:User quota:noenforcing"
From: postmaster@webmail.example.org
Subject: Quota warning - $PERCENT% reached
+
Your mailbox can only store a limited amount of emails.
Currently it is $PERCENT% full. If you reach 100% then
new emails cannot be stored. Thanks for your understanding.
EOF
+

Make this file executable:

+
chmod +x /usr/local/bin/quota-warning.sh
+

Time to restart Dovecot again:

+
systemctl restart dovecot
+

Dovecot’s quota limits can be configured in many ways. If you have special needs then give +their documentation a look.

\ No newline at end of file diff --git a/dist/ispmail-bookworm/relaying-outgoing-emails-through-postfix/index.html b/dist/ispmail-bookworm/relaying-outgoing-emails-through-postfix/index.html new file mode 100644 index 0000000..a3e496b --- /dev/null +++ b/dist/ispmail-bookworm/relaying-outgoing-emails-through-postfix/index.html @@ -0,0 +1,267 @@ + Relaying outgoing emails through Postfix | ISPmail Guide + Skip to content
+⚠️ This page is part of the ISPmail guide for Debian Bookworm. Please use the newer guide for Debian Trixie. +

Relaying outgoing emails through Postfix

+

Your mail server is almost ready for use. But one puzzle piece is missing. Your users can receive emails but they cannot send them yet.

+

Please note that there is a difference on how users send emails versus how servers send emails. For comparison:

+
    +
  • A mail server fetches the MX record for the domain name of the recipient’s email address. That tells it which mail server to talk to. Then it opens an SMTP connection (TCP port 25) and sends the email.
  • +
  • An end user with a mail client like Thunderbird, Evolution or Mutt cannot do it this way. The mail clients have no functionality built in for that MX record fetching magic. And the user is most likely on a dynamic IP address that other mail servers do not trust and reject. End users are meant to send emails to their provider’s (your!) mail server, send login information to authenticate themselves and then send the email. This is called relaying because your mail server acts as a relay between the user and other mail servers on the internet. For security reasons the user also has to authenticate to be allowed to send emails.
  • +
+

I created a couple of illustrations to explain it.

+ +

When someone on the internet sends an email to john@example.org, some other mail server will deliver the email using SMTP to your mail server. Postfix will determine that it’s responsible for email addresses in the example.org domain and accept the email. John can then get the email from your server.

+

Diagram that shows an email coming into Postfix

+ +

John is on the internet somewhere and wants to send an email to lisa@example.com. Your mail server is not responsible for the “example.com” domain so it receives John’s email and would have to forward (relay) it to the actual mail server that is responsible for …@example.com email addresses. This may seem like a harmless scenario but your mail server must deny that:

+

Diagram that shows an outgoing unauthenticated email getting rejected

+

Why? Because anyone can claim to be John and make your mail server forward mail. If an attacker (like a spammer) would send millions of spam emails in John’s name through your server then other organisations will accuse you as the operator of the mail server of spamming. Your mail server would be what people call an open relay. That is not what you want because your mail server would get blacklisted and you will not be able to send out mail to most other servers. So without any proof that the sender is indeed John, your server must reject the email.

+ +

So how does John prove his identity? He needs to use authenticated SMTP. This is similar to the previous case but John’s email program will also send his username and password.

+

Diagram that shows an outgoing authenticated email getting relayed

+

We are making sure that his authentication happens over an encrypted connection so John’s password is safe.

+ +

In addition to using SMTP authentication you can tell Postfix to always allow relaying for certain IP addresses. The mynetworks setting contains the list of IP networks or IP addresses that you trust. Usually you define your own local network here. The reason John had to authenticate in the above example is because his IP address is not part of mynetworks.

+

Make Postfix use Dovecot for authentication

Section titled “Make Postfix use Dovecot for authentication”
+

Enabling SMTP authentication in Postfix is surprisingly easy. You already configured Dovecot so it knows all about your users from the SQL database. So let’s just make Postfix use that by telling it to ask the Dovecot server to verify the username and password. Postfix just needs some extra configuration. Run these commands on the shell:

+
postconf smtpd_sasl_type=dovecot
postconf smtpd_sasl_path=private/auth
postconf smtpd_sasl_auth_enable=yes
+

This enables SMTP authentication and tells Postfix that it can talk to Dovecot through a socket file located at /var/spool/postfix/private/auth. Do you remember that Postfix runs in a sandboxed chroot directory? That’s at /var/spool/postfix. It cannot access any files outside of that directory. But fortunately in a previous section you edited the /etc/dovecot/conf.d/10-master.conf file and made Dovecot place a socket file into /var/spool/postfix/private/auth to allow communication from Postfix.

+ +

The following settings enable encryption, set the key and certificate paths for Postfix. Just run these commands:

+
postconf smtpd_tls_security_level=may
postconf smtpd_tls_auth_only=yes
postconf smtpd_tls_cert_file=/etc/letsencrypt/live/webmail.example.org/fullchain.pem
postconf smtpd_tls_key_file=/etc/letsencrypt/live/webmail.example.org/privkey.pem
postconf smtp_tls_security_level=may
+ +

The above settings allow encrypted incoming (smtpd_) and outgoing (smtp_) connections. But they do not enforce it. If a remote mail server does not have encryption enabled we will still accept their emails. You may be tempted to enforce encryption but that would reject email communication with servers who have been configured without encryption.

+

However the smtpd_tls_auth_only=yes setting makes sure that the user’s authentication information (email address and password) are always encrypted between the user and your mail server.

+ + +

Are you curious how SMTP authentication looks on a low level? You probably are not. But let’s do it anyway. Just once, so that you get the idea.

+

In previous versions of this guide we used “telnet” to connect to TCP port 25 and speak SMTP. But now we enforce encryption and can’t do SMTP authentication unencrypted. Let’s try it anyway:

+
telnet localhost smtp
+

The server will let you in:

+
Trying 127.0.0.1…
Connected to localhost.
Escape character is '^\]'.
220 webmail ESMTP Postfix (Debian/GNU)
+

Say hello:

+
ehlo example.com
+

Postfix will present a list of features that are available for you:

+
250-mailtest
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-STARTTLS
250-ENHANCEDSTATUSCODES
250-8BITMIME
250-DSN
250-SMTPUTF8
250 CHUNKING
+

Let me briefly explain what these lines mean:

+
    +
  • PIPELINING
    +This is a feature to speed up SMTP communication. Usually the remote system has to wait for a response to every command it sends. Pipelining allows the remote server to send several commands in a batch without waiting for a response. Postfix will just store these commands and execute them one by one. If you told Postfix to forbid pipelining it would disconnect the remote server when it tries to send bulks of commands without waiting for the proper reply. It is mainly a feature against rogue senders.
  • +
  • SIZE 10240000
    +The remote server is allowed to send emails up to 10 MB large. This has long been a common maximum size for emails. However nowadays 40 MB or even more are more common sizes because emails have grown larger. Some mail servers even allow 100 MB.
  • +
  • VRFY
    +Allows remote servers to verify a given name or email address. For example the remote server could send “VRFY john” and your server might respond 250 John Doe <john@example.org>. It can be used to verify that a certain recipient email address is deliverable
  • +
  • ETRN
    +A command that a remote system can send to flush the Postfix queue of mails for a certain domain. It can be used if the remote system had technical problems and failed to receive email for a while. Then it could send an ETRN command to make your server start sending outstanding emails for that domain. It is rarely used.
  • +
  • STARTTLS
    +This tells the remote system that it might start switching from this unencrypted to an encrypted connection by sending the “STARTTLS” command. It will then start negotiating a TLS-encrypted connection. You could compare it to an HTTP connection that suddenly switches over to an encrypted HTTPS connection. The advantage is that you can start talking SMTP on TCP port 25 and don’t have to open up a second TCP port like 465 which is the “SSMTP” (secure SMTP) port and only accepts encrypted connections.
  • +
  • ENHANCEDSTATUSCODES
    +This enables more three-digit return codes for various conditions. See the RFC2034 if you are curious.
  • +
  • 8BITMIME
    +In ancient times SMTP only processed 7-bit characters. You couldn’t transfer special characters like “Ä” or “ß” without special encoding. 8BITMIME allows a transmission of emails using 8-bit characters. Still many emails are specially encoded using ISO8859-1 or UTF-8.
  • +
  • DSN
    +It enables DSNs (delivery status notofications) that allows the sender to control the messages that Postfix creates when an email could not be delivered as intended.
  • +
  • SMTPUTF8
    +In addition to 8BITMIME you can use UTF8 encoded characters in header fields.
  • +
  • CHUNKING
    +This feature (described in RFC 3030) makes sending of large emails more efficient.
  • +
+

However one important line is missing here that would allow us to send our username and password:

+
250-AUTH PLAIN LOGIN
+

We told Postfix to only allow authentication when the connection is encrypted. So we are not offered authentication over this plain text connection. That’s what we want.

+

Are you still connected? Okay, good. So we need an encrypted connection using TLS. Using the STARTTLS feature we can switch over from unencrypted to encrypted without having to reconnect. Enter…

+
STARTTLS
+

And the server replies:

+
220 2.0.0 Ready to start TLS
+

However now it’s getting weird because you would have to speak TLS encryption which is not a language that humans speak. So let’s quit this using the “QUIT” command and do that differently:

+
QUIT
+

We can use OpenSSL to help us with the decryption. Run:

+
openssl s_client -connect localhost:25 -starttls smtp
+

You will see a lot of output. OpenSSL has connected to TCP port 25 and issued a STARTTLS command to switch to an encrypted connection. So whatever you type now will get encrypted. Enter:

+
EHLO example.com
+

And Postfix will send a list of capabilities that will look like this:

+
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-AUTH PLAIN LOGIN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
+

And now that we are using an encrypted connection Postfix offers us to authenticate. So let us send the authentication string with a Base64-encoded password:

+
AUTH PLAIN AGpvaG5AZXhhbXBsZS5vcmcAc3VtbWVyc3Vu
+

Unless you have changed John’s password to something else than “summersun” the server should accept that authentication:

+
235 2.7.0 Authentication successful
+

Excellent. You are logged in through SMTP. You could now send an email to be forwarded to another mail server. I just wanted to show that authentication works if you use an encrypted connection.

+

Disconnect from Postfix:

+
QUIT
+

Authentication works. Well done.

+ +

Wait a minute. What was that crazy cryptic string? There was no username and password in it. Was it encrypted?

+

No, that was no encryption. It was merely an encoded version of the username and password. Why that? Well usually in SMTP you can only transfer ASCII characters. But the password may contain special characters which are not covered by ASCII. So in the PLAIN method that information is Base64 encoded.

+

What is actually converted to Base64…

+
NULL-BYTE + USERNAME + NULL-BYTE + PASSWORD
+

So for John’s case you can easily create the Base64 string using:

+
printf '\0john@example.org\0summersun' | base64
+

As a result you will get the exact same string you used above with “AUTH PLAIN”.

+ +

Although I have been talking about SMTP on port 25 to relay mails, it is actually not the proper way. End users should not use port 25 but rather the submission service on TCP port 587 (as described in RFC 4409). The idea is to use port 25 for transporting email (MTA = mail transport agent) from server to server and port 587 for submitting (MSA = mail submission agent) email from a user to a mail server.

+

For comparison:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TCP Port25587
Service nameSMTPSubmission
EncryptionOptionalMandatory
AuthenticationOptionalMandatory
Meant forServer-to-ServerUser-to-Server
Your ISPmay block this portshould allows this port
+

I hope that makes the distinction a bit clearer. So let’s enable the submission service. All Postfix services are declared in the /etc/postfix/master.cf file. Please edit the file and look for the submission section that is commented out by default. Turn that section into the following. Basically I removed the ‘#’ character on all lines of this section and removed the lines with the mua_* variables.

+
submission inet n - y - - smtpd
-o syslog_name=postfix/submission
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
-o smtpd_tls_auth_only=yes
-o smtpd_reject_unlisted_recipient=no
-o smtpd_client_restrictions=
-o smtpd_helo_restrictions=
-o smtpd_sender_restrictions=
-o smtpd_relay_restrictions=
-o smtpd_recipient_restrictions=permit_sasl_authenticated,reject
-o milter_macro_daemon_name=ORIGINATING
+

Make sure to start the first line in the first column and indent the following lines.

+

This service uses the “smtpd” daemon (see the last word of the first line) which is the piece of software that responds if you open an SMTP connection on TCP port 25. But it gets a few extra options set…

+
    +
  • in the /var/log/mail.log log file you will see the connections to the submission port as “postfix/submission” (the syslog_name setting above)
  • +
  • enforce encryption on this port (smtpd_tls_security_level)
  • +
  • enable authentication (smtpd_sasl_auth_enable)
  • +
  • enforce encryption during authentication (smtpd_tls_auth_only)
  • +
  • allow sending emails to recipients outside of this mail server (smtpd_reject_unlisted_recipient)
  • +
  • remove special restrictions (smtpd_*_restrictions)
  • +
  • allow relaying if the sender was authenticated (smtpd_recipient_restrictions)
  • +
  • send the string ORIGINATING to milter services (milter_macro_daemon_name) – you can just leave it like that
  • +
+

Restart the Postfix server:

+
systemctl restart postfix
+

Your users can now use the submission port to send email. They just use the port 587 in their mail clients instead of port 25.

+

Feel free to send a test mail using the submission port and encryption. You will need to install the libnet-ssleay-perl package first, so that SWAKS can speak TLS:

+
apt install -y libnet-ssleay-perl
swaks --server localhost --to john@example.org \
--port 587 -tls \
--auth-user john@example.org \
--auth-password summersun
+ +

Protecting against forged sender addresses

Section titled “Protecting against forged sender addresses”
+

A “forged” sender address means that someone claims to be someone else. Let’s say that John has authenticated and the mail server trusts him. Nothing keeps John from impersonating someone else and sending email in his name? Most email service providers have restrictions that you can only send emails if the sender matches your actual email address. Let’s do that, too.

+

Postfix provides a setting called smtpd_sender_login_maps for that purpose. From the “maps” part you can deduce that it expects a mapping again. This time the two columns mean…

+
    +
  • Left column: who you claim to be (email’s sender address)
  • +
  • Right column: who you logged in as (user name after authentiation)
  • +
+

As we use the email address also as a user name we simply need a mapping where the email address is listed on both sides. Fortunately we already have a mapping like that: our email2email mapping that we used earlier as a workaround for catchall forwardings. Let’s reuse it. Please run…

+
postconf smtpd_sender_login_maps=mysql:/etc/postfix/mysql-email2email.cf
+

This sets the parameter both for the SMTP port (25) and the submission port (587). Defining these maps is not enough though. You also need to make Postfix act on this. Edit the /etc/postfix/master.cf again and in the submission section add the following option. Make sure the line is indented like all other options:

+
-o smtpd_sender_restrictions=reject_sender_login_mismatch,permit_sasl_authenticated,reject
+

Restart Postfix after this change:

+
systemctl restart postfix
+

You can now try to send email as a different user than you are logged in. Let’s us swaks again to send a spoofed email:

+
swaks --server localhost --from john@example.com \
--to john@example.org --port 587 -tls \
--auth-user john@example.org \
--auth-password summersun
+

Please note that John’s actual email address is not john@example.com but john@example.org. So it must be rejected. The server should tell you:

+
~> MAIL FROM:john@example.com
<~ 250 2.1.0 Ok
~> RCPT TO:john@example.org
<~ * 553 5.7.1 john@example.com: Sender address rejected: not owned by user john@example.org
+

Sorry if the mixture of example.org and example.com in my examples makes this guide less readable. But I can’t use any real world domains here. Please just note that sometimes it’s “.com” and sometimes “.org”.

+

Of course you can test your new security feature in the Roundcube web mail interface as well. In Settings/Identities you can create another sender email address as in:

+

Selecting another identity in Roundcube

+

With this wrong sender address any email should get rejected. Your mail.log would read something like:

+
NOQUEUE: reject: RCPT from foo.bar\[…\]:
553 5.7.1 <someoneelse@example.com>:
Sender address rejected:
not owned by user john@example.org;
from=<someoneelse@example.com> to=<…>
+
\ No newline at end of file diff --git a/dist/ispmail-bookworm/setting-dns-records/index.html b/dist/ispmail-bookworm/setting-dns-records/index.html new file mode 100644 index 0000000..90fa670 --- /dev/null +++ b/dist/ispmail-bookworm/setting-dns-records/index.html @@ -0,0 +1,111 @@ + Setting DNS records | ISPmail Guide + Skip to content
+⚠️ This page is part of the ISPmail guide for Debian Bookworm. Please use the newer guide for Debian Trixie. +

Setting DNS records

+

So now you have your working mail server. But how do other mail servers get to know you? The answer lies in the most important service on the internet: DNS – the Domain Name System. Assume that a mail server somewhere on the other end of the internet wants to send an email to john@example.org. The server must find out the name (and IP address) of the mail server responsible for the example.org domain. This is how that works:

+

Big picture of how MX records work

+

The remote server queries its DNS server for the MX (Mail eXchanger) record of the “example.org” domain. (If no MX record was found it tries again and asks for A (address) records. That’s a fallback solution.) Let’s run a query for a real domain to get an idea. Let’s ask which servers receive email for …@gmail.com.

+
$> host -t MX gmail.com
gmail.com mail is handled by 10 alt1.gmail-smtp-in.l.google.com.
gmail.com mail is handled by 20 alt2.gmail-smtp-in.l.google.com.
gmail.com mail is handled by 30 alt3.gmail-smtp-in.l.google.com.
gmail.com mail is handled by 40 alt4.gmail-smtp-in.l.google.com.
gmail.com mail is handled by 5 gmail-smtp-in.l.google.com.
+

So as a result we get 5 different MX records. Each of them consists of a numeric priority and the host name of the mail server. A mail server would pick the entry with the highest priority (=the lowest number) and establish an SMTP connection to that host. In this example that would be the priority 5 server gmail-smtp-in.l.google.com. If that server could not be reached then the next best server with priority 10 would be used and so on. So all you have to do in your own DNS zone is add an MX entry pointing to your mail server. If you want to run a backup mail server (which is outside of the scope of this tutorial) then you can add a second entry with a an equal or lower priority.

+

A mistake some people make is using an IP address in MX records. That is not allowed. An MX record always points to a host name. You will have to add an A record for your MX record to point to the actual IP address of your mail server.

+ + +

It is advised to explicitly name mail servers for your domain in the MX records. If you can’t do that for whatever reason then the remote mail server will just do an A record lookup for the IP address and then send email there. If you just run one server for both the web service and the email service then you can do that. But if the web server for your domain is located at another IP address than your mail server then this won’t work.

+ +

Many mail servers check that your forward (name to IP) and reverse (IP to name) lead to the same results. This is how it should look:

+

example.org —(MX)–> mx.example.org
+mx.example.org —(A)–> 1.2.3.4
+1.2.3.4 —(PTR)–> mx.example.org

+

(1.2.3.4 in a PTR record is actually 4.3.2.1.in-addr.arpa.)

+ +

Fortunately many ISPs finally start to offer IPv6 in their networks. So if you rent a virtual server from a provider then check if you also got an IPv6 address assigned. In that case you also need to have proper DNS records for that as well. Like:

+

example.org —(MX)–> mx.example.org
+mx.example.org —(AAAA)–> fdeb:37d7:ef39:e063::1
+fdeb:37d7:ef39:e063 —(PTR)–> mx.example.org

+

Chances are that you haven’t dealt with IPv6 yet. Give it a try. IP addresses may look different at first but you will never again have to deal with odd subnet sizes or NAT. Thank me later. 🙂

\ No newline at end of file diff --git a/dist/ispmail-bookworm/setting-up-dovecot/index.html b/dist/ispmail-bookworm/setting-up-dovecot/index.html new file mode 100644 index 0000000..950c21f --- /dev/null +++ b/dist/ispmail-bookworm/setting-up-dovecot/index.html @@ -0,0 +1,221 @@ + Setting up Dovecot | ISPmail Guide + Skip to content
+⚠️ This page is part of the ISPmail guide for Debian Bookworm. Please use the newer guide for Debian Trixie. +

Setting up Dovecot

This chapter of our journey leads us to Dovecot – the software that…

+
    +
  • gets emails destined to your users from Postfix and saves them to disk
  • +
  • executes user-based sieve filter rules (can be used to e.g. move emails to different folders based on certain +criteria or to send automated vacation responses)
  • +
  • allows the user to fetch emails using POP3 or IMAP
  • +
+

Before we get to the actual configuration for security reasons I recommend that you create a new system user that will +own all virtual mailboxes. The following shell commands will create a system group “vmail” with GID (group ID) 5000 and +a system user “vmail” with UID (user ID) 5000. (Make sure that UID and GID are not yet used or choose another – the +number can be anything between 1000 and 65000 that is not yet used):

+
groupadd -g 5000 vmail
useradd -g vmail -u 5000 vmail -d /var/vmail -m
+

If the /var/vmail directory was already there because you assigned it a dedicated mount point then you should make sure +that the permissions are set correctly:

+
chown -R vmail:vmail /var/vmail
+

The configuration files for Dovecot are found in /etc/dovecot/conf.d. All these files are loaded by Dovecot. This is +done by this magical line at the end of the /etc/dovecot/dovecot.conf file:

+
!include conf.d/*.conf
+

It loads all files in /etc/dovecot/conf.d/ that end in “.conf” in alphanumerical order. So “10-auth.conf” is loaded +first and “90-sieve-extprograms.conf” is loaded last. The big advantage is that you can edit or replace parts of the +configuration without having to overwrite the entire configuration. The main /etc/dovecot/dovecot.conf file does not +require any changes. Those other files in conf.d/ however do.

+ + +

The most common +authentication mechanism +is called PLAIN. However if you have Outl**k users then you may need to add the LOGIN mechanism, too.:

+
auth_mechanisms = plain login
+

These two mechanisms would ask for a password without enforcing encryption to secure the password. But don’t worry. By +default Dovecot sets disable_plaintext_auth = yes which ensures that authentication is only accepted over +TLS-encrypted connections.

+

At the end of this file you will find various authentication backends that Dovecot ships with. By default it will use +system users (those from the /etc/passwd). But we want to use the MariaDB database backend so go ahead and change this +block to:

+
#!include auth-system.conf.ext
!include auth-sql.conf.ext
#!include auth-ldap.conf.ext
#!include auth-passwdfile.conf.ext
#!include auth-checkpassword.conf.ext
#!include auth-static.conf.ext
+ +

Change the mail_location setting to:

+
mail_location = maildir:~/Maildir
+

This is the directory where Dovecot will look for the emails of a specific user. The tilde character (~) means the +user’s home directory. That does not make sense yet. But further down on this page we will tell Dovecot what the home +directory is supposed to mean. For example john@example.org will have his home directory in +/var/vmail/example.org/john.

+

Further down in the 10-mail.conf file you will find sections defining the +namespaces. Those are folder structures that your email +program sees when connecting to the mail server. If you use POP3 you can only access the “inbox” – which is where all +incoming email is stored. Using the IMAP protocol you get access to a hierarchy of folders and subfolders. And you can +even share folders between users. Or use a public folder that can be accessed by anyone – even anonymously. So IMAP is +generally to be preferred.

+

Also edit the “mailplugins” line to enable the _quota plugin we will configure later and turn it into:

+
mail_plugins = quota
+ + +

This configuration file deals with typical service ports like IMAP or POP3.

+ +

So most settings are sane here and do not have to be changed. However one change is required in the “service auth” +section because we want Postfix to allow Dovecot as an authentication service. Make it look like this:

+
# Postfix smtp-auth
unix_listener /var/spool/postfix/private/auth {
mode = 0660
user = postfix
group = postfix
}
+

Well, Postfix runs in a chroot environment located at /var/spool/postfix. It can’t access anything outside of that +directory. So to allow communication with Postfix we tell Dovecot to place a communication socket into that chroot.

+ +

Earlier in this guide you created both a key and a certificate file to encrypt the communication with POP3, IMAPs and +HTTPS between the users and your mail server. You need to tell Dovecot where to find these files:

+
ssl\_cert = \</etc/letsencrypt/live/webmail.example.org/fullchain.pem
ssl\_key = \</etc/letsencrypt/live/webmail.example.org/privkey.pem
+

And enforce TLS encryption by setting:

+
ssl = required
+

See the Dovecot documentation on SSL encryption for more information.

+

Next let’s take a look at how Dovecot knows about users and their passwords:

+ +

Dovecot reads the auth-sql.conf.ext which defines how to find user information in your database. Open the file. There +are two sections:

+
    +
  • userdb: where to find a user’s mailbox in the file system
  • +
  • passdb: where to find the user’s hashed password
  • +
+

By default Dovecot will run two queries at your database. One for the userdb that gets information like the user ID, +group ID, home directory and quota. And another for the passdb that gets the hashed password.

+

The “userdb” section already reads:

+
userdb {
driver = sql
args = /etc/dovecot/dovecot-sql.conf.ext
}
+

As you can see Dovecot uses an SQL database lookup to get that information. And it refers to the dovecot-sql.conf.ext +file for more information. Let’s see…

+ +

(This configuration file is one level up and not in “conf.d”.)

+

You will find this file well documented although all configuration directives are commented out. Add these lines at the +bottom of the file:

+
driver = mysql
+
connect = \
host=127.0.0.1 \
dbname=mailserver \
user=mailserver \
password=x893dNj4stkHy1MKQq0USWBaX4ZZdq
+
user_query = SELECT email as user, \
concat('*:bytes=', quota) AS quota_rule, \
'/var/vmail/%d/%n' AS home, \
5000 AS uid, 5000 AS gid \
FROM virtual_users WHERE email='%u'
+
password_query = SELECT password FROM virtual_users WHERE email='%u'
+
iterate_query = SELECT email AS user FROM virtual_users
+ +

What these lines mean:

+
    +
  • driver: the kind of database. MariaDB is the same kind as MySQL.
  • +
  • connect: where to find the MySQL database and how to access it (username, password)
  • +
  • user_query: an SQL query that returns the user name (=the email address), the quota, the home directory, user ID and +group ID.
  • +
  • password_query: this SQL query just gets the password hash from the database
  • +
  • iterate_query: ‘doveadm’ uses this query to get a list of all users. That allows you to use the “doveadm user ‘*’” +command later.
  • +
+

The user_query gets several pieces of information from the database. Let’s look at it one by one:

+
    +
  • email AS user
    +It gets the the email field from the database which corresponds to the user name. Dovecot expects it in the user +field so we set an alias to “user”.
  • +
  • userdb_quota_rule
    +This is the user’s quota in bytes. Think of it as the maximum possible space on disk that the user can occupy. As +documented Dovecot expects the quota in a +special format like “*:bytes=10000” if the user should not be able to store more than 10,000 bytes. That’s why we +begin the string with ‘*:bytes=’.
  • +
  • userdb_home
    +This leads to the directory where all emails and various control files for this user are located. The placeholder +‘%d’ replaces the domain and ‘%n’ the user part. So for John that makes it “/var/vmail/example.org/john”.
  • +
  • userdbuid and userdb_gid
    +Those are the user ID and group ID of _vmail
    user – 5000 for both. Dovecot uses it to set the permissions of files +it creates. As all users share the same system user “vmail” this is just a static number.s
  • +
+ +

Make sure that only root can access the SQL configuration file so nobody else is reading your database access passwords:

+
chown root:root /etc/dovecot/dovecot-sql.conf.ext
chmod go= /etc/dovecot/dovecot-sql.conf.ext
+

Restart Dovecot from the shell:

+
systemctl restart dovecot
+

Look at your /var/log/mail.log logfile. You should see:

+
... Dovecot v2.3.13 (f79e8e7e4) starting up for imap, lmtp, sieve, pop3 (core dumps disabled)
+

If you get any error messages please double-check your configuration files.

\ No newline at end of file diff --git a/dist/ispmail-bookworm/success-stories/index.html b/dist/ispmail-bookworm/success-stories/index.html new file mode 100644 index 0000000..d0934cd --- /dev/null +++ b/dist/ispmail-bookworm/success-stories/index.html @@ -0,0 +1,90 @@ + Success stories | ISPmail Guide + Skip to content
+⚠️ This page is part of the ISPmail guide for Debian Bookworm. Please use the newer guide for Debian Trixie. +

Success stories

I would appreciate if you leave a comment here telling others if your mail server is running. Perhaps even a word about the purpose of the mail server and the number of users you have. That allows others to see that their time is well-spent and indeed leads to a working mail server. Thanks for your feedback.

\ No newline at end of file diff --git a/dist/ispmail-bookworm/testing-email-delivery/index.html b/dist/ispmail-bookworm/testing-email-delivery/index.html new file mode 100644 index 0000000..0f5b9f4 --- /dev/null +++ b/dist/ispmail-bookworm/testing-email-delivery/index.html @@ -0,0 +1,176 @@ + Testing email delivery | ISPmail Guide + Skip to content
+⚠️ This page is part of the ISPmail guide for Debian Bookworm. Please use the newer guide for Debian Trixie. +

Testing email delivery

So far you have spent considerable time with theory and configuration. Are you worried whether all you did actually leads to a working mail server? Before we do the final steps let’s take a break and verify that everything you did so far works as expected.

+

At this point the /var/vmail directory should be empty or maybe contain an “example.org” directory if you played with the john@example.org account previously. You can get a list of all files and directories within by running:

+
find /var/vmail
+

Although there are not actually any emails on the server yet, you may still get something along the lines of:

+
/var/vmail
/var/vmail/example.org
/var/vmail/example.org/john
/var/vmail/example.org/john/.dovecot.sieve
/var/vmail/example.org/john/sieve
/var/vmail/example.org/john/sieve/roundcube.sieve
/var/vmail/example.org/john/sieve/tmp
/var/vmail/example.org/john/Maildir
/var/vmail/example.org/john/Maildir/subscriptions
/var/vmail/example.org/john/Maildir/maildirfolder
/var/vmail/example.org/john/Maildir/new
/var/vmail/example.org/john/Maildir/cur
/var/vmail/example.org/john/Maildir/.INBOX.test
/var/vmail/example.org/john/Maildir/.INBOX.test/maildirfolder
/var/vmail/example.org/john/Maildir/.INBOX.test/new
/var/vmail/example.org/john/Maildir/.INBOX.test/dovecot.index.log
/var/vmail/example.org/john/Maildir/.INBOX.test/cur
/var/vmail/example.org/john/Maildir/.INBOX.test/dovecot-uidlist
/var/vmail/example.org/john/Maildir/.INBOX.test/tmp
/var/vmail/example.org/john/Maildir/dovecot-uidvalidity.5ddc842b
/var/vmail/example.org/john/Maildir/tmp
+

Basically the schema you see here is /var/vmail/DOMAIN/USER/Maildir/…

+

Eeach IMAP mail folder has three subdirectories:

+
    +
  • new – every file here is an email that was stored in this mail folder but not yet read
  • +
  • cur – the same but for email that has been read already
  • +
  • tmp – for temporary files from the mail server
  • +
+

Nested folders (folders within folders) will be separated by a dot like this:

+
    +
  • …/Maildir/new/… – the main inbox
  • +
  • …/Maildir/.INBOX.reddit/new/… – the “reddit” mail folder below the inbox
  • +
  • …/Maildir/.INBOX.servers.inga/new/… – the “servers”/”inga” mail folder below the inbox
  • +
+ +

To check for obvious configuration error in Postfix please run:

+
postfix check
+

Did you get the error…
+“error: open database /etc/aliases.db: No such file or directory“? Don’t worry. Just run the “newaliases” command to create a new machine-readable file from what aliases were defined in the /etc/aliases.

+

Very likely you will get this error: “postfix/postfix-script: warning: symlink leaves directory: /etc/postfix/./makedefs.out“. That is a harmless bug of the Debian package that can safely be ignored.

+ +

It is time to send a new email into the system. Open a new terminal window and run

+
tail -f /var/log/mail.log
+

to see what the mail server is doing. Now let’s send an email to John. My favorite tool for mail tests is swaks that you installed earlier. In a second terminal run:

+
swaks --to john@example.org --server localhost
+

If all works as expected, your mail.log will show a lot of technical information about the email delivery. Let me explain what happens at each stage.

+
    +
  • postfix/smtpd[29225]: connect from localhost.localdomain[127.0.0.1]
    +Postfix receives an incoming SMTP connection.
  • +
  • postfix/smtpd[29225]: 8BA46A0A3A: client=localhost.localdomain[127.0.0.1]
    +Postfix assigns a unique identifier (8BA46A0A3A) to this connection so that you see which log lines belong together. This is especially important with busy mail servers where multiple mails are handled in parallel.
  • +
  • postfix/cleanup[29233]: 8BA46A0A3A: *message-id=20191126153053.029243@webmail.example.org
    +swaks created a unique message id to the email which helps you identify specific mails in the log file.
  • +
  • postfix/qmgr[13667]: 8BA46A0A3A: from=root@webmail.example.org, size=485, nrcpt=1 (queue active)
    +The sender was root@webmail.example.org. This is logged after swaks sent the “MAIL FROM” line during the SMTP dialog.
  • +
  • postfix/smtpd[29225]: disconnect from localhost.localdomain[127.0.0.1] ehlo=1 mail=1 rcpt=1 data=1 quit=1 commands=5
    +The SMTP communication ends. Postfix has now received and queued the email.
  • +
  • dovecot: lmtp(29237): Connect from local
    +Postfix connects to Dovecot to hand over the email via the LMTP interface.
  • +
  • dovecot: lmtp(john@example.org)<29237><2PJTIh033V01cgAARGEcaw>: sieve: msgid=20191126153053.029243@webmail.example.org: stored mail into mailbox 'INBOX.test'
    +Dovecot received the email and even evaluated John’s sieve rule which made the email get stored to the ‘test’ folder of his mailbox.
  • +
  • dovecot: lmtp(29237): Disconnect from local: Client has quit the connection (state=READY)
    +The LMTP connection between Postfix and Dovecot is closed.
  • +
  • postfix/lmtp[29236]: 8BA46A0A3A: to=john@example.org, relay=webmail.example.org[private/dovecot-lmtp], delay=0.01, delays=0/0/0/0.01, dsn=2.0.0, status=sent (250 2.0.0 john@example.org 2PJTIh033V01cgAARGEcaw Saved)
    +This is the one of the most interesting lines in your mail log. It tells you what happened with a certain email. In this case it says that it was handed over to dovecot-lmtp and that the delivery was successful (status=sent). The status codes like 2.0.0 are defined in RFC 3463 and work similar to status codes in HTTP. Codes beginning with ‘2’ are good. Those with ‘4’ are temporary errors. And ‘5’ stands for a permanent failure.
  • +
+

Your output may look slightly differently. Just focus on the parts that are printed in bold letters. If everything worked as expected Postfix has accepted the email and forwarded it to Dovecot which in turn wrote the email in John’s maildir. If you get any errors in the log file then try to understand the error message and find the cause of the problem before you proceed.

+

Look again:

+

find /var/vmail

+

Dovecot has now created a directory structure for John and created a new file:

+
/var/vmail/
[…]
/var/vmail/example.org/john/Maildir/new/1515485447.M404984P2636.mail,S=510,W=522
[…]
+

The file will have a different name on your system – that’s okay. It is the only file in the “new” folder.

+ +

The file just contains the email:

+
Return-Path: <root@mail.example.org>
Delivered-To: john@example.org
Received: from mail.example.org
by mail.example.org (Dovecot) with LMTP id iHHHEwd5VFpMCgAA3BOsLQ
for <john@example.org>; Tue, 09 Jan 2018 09:10:47 +0100
Received: by mail.example.org (Postfix, from userid 0)
id 30B4B41A98; Tue, 9 Jan 2018 09:10:47 +0100 (CET)
Message-Id: <20180109081047.30B4B41A98@mail.example.org>
Date: Tue, 9 Jan 2018 09:10:47 +0100 (CET)
From: root@mail.example.org (root)
+
Di 9. Jan 09:10:47 CET 2018
+

The advantage of this is that backups are easy and you can even restore single files if a user has accidentally removed an email.

+

If anything went wrong then carefully check the last lines of your /var/log/mail.log. It will very likely point you to the problem. Or read the troubleshooting section. Or just add a comment to this page and ask other readers for help.

+

You can also use a slightly more comfortable tool to access Maildirs that will come handy for you as a mail server administrator: “mutt”.

+
mutt -f /var/vmail/example.org/john/Maildir
+

(You may get asked to create /root/Mail – this is standard procedure. Just press Enter.)

+

What you see now are the contents of John’s mailbox:

+

Mutt showing an email in the inbox

+

Using mutt is a nice way to check mailboxes while you are logged in to the mail server.

+

To reiterate what happens when you receive an email:

+
    +
  1. Postfix receives the email (using the “swaks” command in this example – but usually through the network using the SMTP protocol from other servers)
  2. +
  3. Postfix asks Dovecot if the user is over quota
  4. +
  5. Postfix talks to Dovecot via LMTP and hands over the email
  6. +
  7. Dovecot runs through the user’s Sieve rules
  8. +
  9. Dovecot writes the email file to disk
  10. +
+ +

Now that the email has been delivered you can talk to Dovecot using the IMAP protocol to retrieve your email again. Are you still logged in via the Roundcube webmail interface? Then just reload and you will see the email:

+

Roundcube showing an email in the inbox

+

Access the email through IMAP (desktop client)

Section titled “Access the email through IMAP (desktop client)”
+

Your users are not likely to use “mutt” to read their email – unless they are immortal console nerds. So of course you can use a graphical mail client to access John’s emails. If you use Thunderbird, Evolution, Apple Mail or some other IMAP client then feel free to configure a new IMAP account and connect to the server. Remember that the user name and email address are both john@example.org and the password is “summersun”.

+ +

Aside from talking IMAP Dovecot also knows how to speak POP3. But let’s face it – POP3 is dead. I do not even offer it to my users any more. But as your users may ask let’s quickly review the differences of the two protocols:

+
    +
  • POP3 (Post Office Protocol) is a simple protocol that lets you fetch email from a single mailbox. You can’t create multiple folders on the server to organize your mails. It saves space on the mail server because the email usually gets moved to the user’s hard disk on their computer. This variant is pretty antiquated.
  • +
  • IMAP (Internet Messaging Application Protocol) is predominantly focused upon leaving your mail on the server. The inbox is where your incoming emails are stored but users can also maintain folders and move emails to them. But users can move emails to different sub-folders. IMAP is useful when you want to access your email from different locations without losing mail because you fetched it from another location. The drawback is that lazy users leave their mail on the server thus filling up your server’s hard disk – for which quotas are a good solution.
  • +
\ No newline at end of file diff --git a/dist/ispmail-bookworm/testing-imap/index.html b/dist/ispmail-bookworm/testing-imap/index.html new file mode 100644 index 0000000..deab9e3 --- /dev/null +++ b/dist/ispmail-bookworm/testing-imap/index.html @@ -0,0 +1,104 @@ + Testing IMAP | ISPmail Guide + Skip to content
+⚠️ This page is part of the ISPmail guide for Debian Bookworm. Please use the newer guide for Debian Trixie. +

Testing IMAP

You have already completed the configuration of Dovecot. So fetching emails via IMAP should already work. Let’s give it +a try using a simple-looking but powerful IMAP client: mutt.

+
mutt -f imaps://john@example.org@webmail.example.org
+

The connection URL may look a little confusing because of the two “@” characters. Usually mutt expects the format +imaps://user@server. And as we use the email address as the “user” part you get this look.

+

You should get prompted for the password which we set to “summersun”. If you get any certificate warnings then check if +you used the correct server name to connect to and if you completed the certificate/LetsEncrypt part earlier in this +guide.

+

After logging in you will see an empty inbox:

+

The mutt mail client showing an empty inbox

+

Or if you have played around with quotas in the previous section you will see a couple of emails plus the quota +warnings:

+

The mutt mail client showing quota warning emails

+

Very good – IMAP connections and authentication works. That’s all we wanted to test. Exit mutt by pressing “q”.

+

Congratulations. At this point your server can already receive emails.

\ No newline at end of file diff --git a/dist/ispmail-bookworm/types-of-email-domains/index.html b/dist/ispmail-bookworm/types-of-email-domains/index.html new file mode 100644 index 0000000..f1018f1 --- /dev/null +++ b/dist/ispmail-bookworm/types-of-email-domains/index.html @@ -0,0 +1,334 @@ + Types of email domains | ISPmail Guide + Skip to content
+⚠️ This page is part of the ISPmail guide for Debian Bookworm. Please use the newer guide for Debian Trixie. +

Types of email domains

This is the pretty boring but at the same time very important part of the tutorial. Do not skip it. Most problems that +readers have with their mail servers are caused by a misunderstanding of the different types of email domains. There is +nothing you need to do on your server right now. Just lean back and relax and make sure that you read and fully +understand this page. It will spare you frustration.

+

As explained on the previous page Postfix is the software component that speaks SMTP. It receives emails from other +server and sends email out. Of course you will only want to receive emails for your domains only.

+

Postfix will accept emails for any of these classes of domains:

+
    +
  1. Canonical domains (also called local domains)
  2. +
  3. Hosted domains +
      +
    • Virtual mailbox domains
    • +
    • Virtual alias domains
    • +
    +
  4. +
  5. Relay domains
  6. +
+

Let us look at the first two in detail. The third one – relay domains – is not needed in this context.

+ +

Once upon a time users logged into servers using Telnet or +SSH to read their email in basic text-based mail clients. Their email +addresses were often just a combination of their login name and the server name. Something like +mpauls@server17.biology.example.net.

+

At least that made things pretty simple for the server administrator. He just accepted emails for any valid login user +on that server. The mail server knew what to do. It checked if “mpauls” is found in /etc/passwd and then stored emails +in “/var/mail/mpauls”.

+

If you wanted to do it that way…

+
    +
  1. You would need to create system accounts for all users who want to receive email. Every system user is a potential +security risk because they can login to the server using a shell. If the user chooses a weak password you are +essentially inviting attackers to harm your server.
  2. +
  3. If you want to host many email accounts this becomes impractical.
  4. +
  5. Postfix cannot distinguish the local domains. If you have three local domains “example.org”, “example.com” and +“example.net” then all these email addresses would lead to the same mailbox: john@example.org, john@example.com +and john@example.net. So you cannot use different domains for different purposes.
  6. +
+

To tell Postfix which domain you consider local you list them in the “mydestination” configuration setting in your +main.cf configuration file. Example:

+
mydestination = example.org, example.com, example.net
+ +

It is common however to use the server’s hostname as a local domain. If your server is called “scully.example.com” you +could set “mydestination = scully.example.com”. Or you just set it to “mydestination = localhost” if you rather want to +use “scully.example.com” as a virtual domain. Some parts of your system may send emails to root@localhost so this is a +sane setting.

+ +

This is the class of domains that will be our workhorse. Postfix allows us to add an unlimited number of domains that +can receive emails. That’s what an ISP does and so will we.

+

Where do we put the list of domains? Postfix is pretty flexible. We could put it in a huge text file. We might use LDAP +if we have some kind of user directory in our organization. But in this guide we will store that information in a simple +MariaDB database.

+

Postfix handles hosted email addresses by checking two mappings:

+
    +
  • Virtual Aliases (“redirect this email address to another address”)
  • +
  • Virtual Mailboxes (“accept email for this email address”)
  • +
+

So much terminology. Time for an example, isn’t it? Let’s tell Postfix we want to have three email addresses:

+
    +
  • john@example.org
  • +
  • jack@example.org
  • +
  • jack@example.com (note that this is another domain than example.org)
  • +
+

Postfix only understands mappings. They are much easier than they sound. A mapping is just a table that has a left and +a right column. Postfix always looks for stuff in the left column (key) to find more information in the right column +(value). Like this:

+ + + + + + + + + + + + + + + + + + + + + +
Virtual mailbox (key)Virtual mailbox location on disk (value)
john@example.org/var/vmail/example.org/john/Maildir
jack@example.org/var/vmail/example.org/jack/Maildir
jack@example.com/var/vmail/example.com/jack/Maildir
+

So the left column lists the valid email addresses. And the right column is apparently some path on disk. Right, that’s +all the magic. If an email for jack@example.org is received then Postfix will find the entry in the left column and +can figure out where Jack’s mails are stored on disk.

+

Before checking if a specific email address is valid Postfix first checks if it is responsible for the domain at all. +That’s done by this mapping:

+ + + + + + + + + + + + + + + + + +
Virtualdomain (key)Whateve (value)
example.orgKittens
example.comPuppies
+

So there are two domains in the left column. But what is that in the right column? Kittens? Really? Well, the truth is: +it doesn’t matter. It can be anything. So why is that column there at all? The reason is that mappings always have two +columns. Postfix wants a list of domains but it has no concepts for one-dimensional lists. So it uses this format and +ignores the right column.

+

Essentially these two mappings are all we need. Add a little configuration and you can already receive emails. However +Postfix provides another useful feature: aliases. An alias is a redirection (or forwarding) of one email address to +one or more other addresses. Possible uses:

+
    +
  • forward postmaster@… for all your domains to one mailbox
  • +
  • create an email distribution list for a team or department
  • +
  • forward copies of all your emails to another address
  • +
  • redirect emails meant for a coworker who has left the organisation
  • +
+

As usual, Postfix expects a mapping for aliases. Time for another example:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
StepVirtual email address (left)Redirect to (right)
1postmaster@example.orgjack@example.com
2abuse@example.orgjack@example.com
3jack@example.comjack@example.com,jacky@workaround.org
4sophie@example.nethr@example.net
5hr@example.netrick@example.net
hr@example.nettina@example.net
6@example.orgjack@example.com (DANGEROUS)
+

Quite a lot happens here. How does Postfix interpret this table?

+
    +
  1. Redirect emails for postmaster@example.org to jack@example.com
  2. +
  3. Redirect emails for abuse@example.org also to jack@example.com
  4. +
  5. Keep a copy of an incoming email for jack@example.com in his mailbox and send another copy to +jacky@workaround.org. Yes, you can use multiple email addresses seperated by commas.
  6. +
  7. Sophie has left the organisation so her address is forwarded to HR.
  8. +
  9. The HR team consists of two members: rick@example.net and tina@example.net. Every email to hr@example.net will +be forwarded to each of them. This works similar to (3) but this time the target addresses are not seperated by +commas but stored in different rows.
  10. +
  11. Forward any email address of the example.org domain to jack@example.com. We call this a catch-all address. +This is dangerous for two reasons. First it will send the poor Jack anything that is sent to the example.org +domain if there is no user account for that address. (Yes, spammers guess addresses.) And second it disables a +security check in Postfix that the destination address jack@example.com actually exists. Postfix may first receive +the email and then be confused if the recipient is not reachable. That leads to backscatter and harms your +reputation. But don’t worry. I will show you the proper way to use catch-all addresses later.
  12. +
+

So basically this is the way that Postfix handles aliases:

+
    +
  1. Is the domain of the email address defined as a virtual domain?
  2. +
  3. Get all rows of the table where the email address is found in the left column. Send a copy of the email to everyone +mentioned in the right column. If the right column contains multiple email addresses separated by commas then split +them first.
  4. +
  5. If there was no such row then check again if there is an @domain row.
  6. +
  7. Still nothing found? Then reject the email.
  8. +
+ + +

Did you get the idea of mappings? Two columns in a table? Keys and values? Good. Now how do those mappings work when we +want to put the information into an SQL database?

+

Basically a relational database works in rows and columns, too. So we can take the format of the tables shown above and +put them into database tables. Let’s call these tables…

+
    +
  • virtual_domains (for the list of domains)
  • +
  • virtual_aliases (for the aliases mapping)
  • +
  • virtual_users (for the email users and their mailboxes respectively)
  • +
+

I won’t bore you with the SQL stuff right now. We will deal with that in a later chapter. Let’s just briefly cover how +Postfix can get data from the database. We provide Postfix with configuration files for that purpose. These files +often have a “.cf” suffix (configuration file).

+

Let’s take the virtual_users table for example. This is the content of a file that is located at +/etc/postfix/mysql-virtual-mailbox-maps.cf:

+
# Information on how to connect to your MySQL server
user = someone
password = some_password
hosts = 127.0.0.1
dbname = mailserver
+
# The SQL query string
query = SELECT mailbox_path FROM virtual_users WHERE email_address='%s'
+

The first four lines describe how the database can be connected to. You provide a database user and database password as +well as the IP address or hostname of the SQL server and the name of the database.

+

A more interesting bit is the query that is defined in the last line. Postfix still thinks in left and right columns. +So it will run this query and replace the %s by the email address it is looking for – that’s what is expected in the +left column. The database will then get all rows from the database table that match this criterion. If one row matches +the query then the “SELECT mailbox_path” will return just the value of what Postfix would expect to be in the right +column.

+

That’s all the magic that Postfix needs to talk to your SQL database. You tell Postfix how to connect to the database +and how the data in the database table corresponds to the left and right columns.

+

Note that a lookup here must only return just one row from the database. Postfix must uniquely know where the mailbox +path for a given user is. There are other mappings though where it’s allowed to have multiple right-hand side items for +one left-hand side item – for example in virtual aliases.

+

To use the above configuration file you have to configure it in Postfix’s main.cf file:

+
virtual_mailbox_maps = mysql:/etc/postfix/mysql-virtual_mailbox_maps.cf
+

If you find that this mapping is not working as you expected then the “postmap -q” command is your friend. You can ask +Postfix what the right-hand side value for a given left-side value is. Say that you are interested in the mailbox_path +for the email_address john@example.org:

+
postmap -q john@example.org mysql:/etc/postfix/mysql-virtual_mailbox_maps.cf
+

Postfix will then run the above SQL query with your “john@example.org” argument:

+
SELECT mailbox_path FROM virtual_users WHERE email_address='john@example.org'
+

The result should be:

+
/var/vmail/example.org/john/Maildir
+

In this guide we will use a slight variation of that SQL query:

+
query = SELECT 1 FROM virtual_users WHERE email='%s'
+

Postfix does not need to know where the mailbox is located on disk. We will not use Postfix to store the email to disk. +Instead we will make Postfix hand over the email to Dovecot which stores the email. Dovecot has a couple of nice extra +features (like server-side scripts) that we want to use. So Postfix just needs to know whether an email address is valid +or not. We just return “1” because actually the right column is not considered anyway. Postfix just needs to know +whether there is a database row or not.

\ No newline at end of file diff --git a/dist/ispmail-bookworm/webmail-using-roundcube/index.html b/dist/ispmail-bookworm/webmail-using-roundcube/index.html new file mode 100644 index 0000000..15075e8 --- /dev/null +++ b/dist/ispmail-bookworm/webmail-using-roundcube/index.html @@ -0,0 +1,161 @@ + Webmail using Roundcube | ISPmail Guide + Skip to content
+⚠️ This page is part of the ISPmail guide for Debian Bookworm. Please use the newer guide for Debian Trixie. +

Webmail using Roundcube

+

Power users may still want to use a mail client like Thunderbird. But most users nowadays seem to prefer reading their emails in the web browser. Let us install a web application for that purpose: Roundcube. Roundcube is the software that was also used in the previous versions of this guide. So if your users are used to it… just stay with it.

+ +

Start by installing the software packages:

+
apt install -y roundcube roundcube-plugins \
roundcube-plugins-extra roundcube-mysql
+

Roundcube stores user settings in the database. So you will get asked to set up database access:

+

Debconf asking whether you want to have the database set up for you

+

Choose Yes.

+

When asked for a password just press ENTER.

+

Debconf asking for the database password

+ +

Do you remember that earlier in this guide I asked you how want to name your mail server? Whether you want to use one common name like “webmail.example.org” for all your domains? Or if you prefer different host names for each domain like “webmail.domain1.com” and “webmail.domain2.com”? If you want to use just more then you will have to create one virtual host configuration per domain. The following instructions will just deal with one common host name.

+

To get Apache to serve the Roundcube application you need to edit the /etc/apache2/sites-available/webmail.example.org-https.conf file. I suggest you change the DocumentRoot line to:

+
DocumentRoot /var/lib/roundcube/public_html
+

All URLs are relative to that directory. So if you go to https://webmail.example.com/ then files are looked up in that directory.

+

Also add this line within the same VirtualHost section to add a couple of prepared security settings:

+
Include /etc/roundcube/apache.conf
+

And as usual Apache needs to be restarted after the configuration change:

+
systemctl restart apache2
+

Check that Apache is running properly:

+
systemctl status apache2
+

In case of a problem run “apache2ctl configtest” to find the cause.

+ +

The main configuration file of Roundcube is located at /etc/roundcube/config.inc.php. Feel free to customize the file. Fortunately nowadays the basic settings are already as we need them. However these two settings need to be changed by you:

+
$config['imap_host'] = "tls://webmail.example.org:143";
$config['smtp_host'] = 'tls://webmail.example.org:587';
+

So now when your users enter https://webmail.example.org/ in their browser they should get the Roundcube login form:

+

Roundcube login dialog

+

Keep in mind that we are using the email address as the account name of the user. So when logging in please enter the email address as the user name. E.g. ‘john@example.org’ and password ‘summersun’.

+ + +

Roundcube comes with various plugins that you can offer your users. I recommend at least these two:

+
    +
  • password: Let the user change their access password.
  • +
  • managesieve: Let the user manage rules that apply to incoming email. They can move mails to specific folders automatically for example.
  • +
+

Again edit the /etc/roundcube/config.inc.php file and look for the plugins configuration. To enable the recommended plugins change it to:

+
$config['plugins'] = array(
'managesieve',
'password',
);
+ +

Plugins are configured through files located in the /etc/roundcube/plugins directory. Let’s begin with the password plugin. Edit the /etc/roundcube/plugins/password/config.inc.php file.

+

Oops, that file looks pretty empty. But it refers us to an example file at /usr/share/roundcube/plugins/password/config.inc.php.dist. There are many different methods to let users change their passwords. As we store that information in the SQL database, that is the part we need to set up.

+ +

Remove the empty definition line of $config from your config.inc.php file. Let’s go through the required settings one by one:

+
    +
  • $config['password_driver'] = 'sql';
    +Simple. Use SQL as a backend.
  • +
  • $config['password_minimum_length'] = 12;
    +Allow no passwords shorter than 12 characters. I consider longer passwords more secure than short passwords with weird characters. You can even choose a larger minimum.
  • +
  • $config['password_force_save'] = true;
    +This will overwrite the password in the database even if it hasn’t changed. It helps us improve the strength of the password hash by re-encoding it with a better algorithm even if the user chooses to keep his old password.
  • +
  • $config['password_algorithm'] = 'blowfish-crypt';
    +The cryptographic algorithm to encode the password. This one is considered very secure and supported by Dovecot.
  • +
  • $config['password_algorithm_prefix'] = '{CRYPT}';
    +Prepend every password with this string so that Dovecot knows how we encrypted the password.
  • +
  • $config['password_db_dsn'] = 'mysql://mailadmin:gefk6lA2brMOeb8eR5WYaMEdKDQfnF@localhost/mailserver';
    +Connection information for the local database. Use your own password for the mailadmin (!) database user here. We cannot use the restricted mailserver user because we have to write to the database if the user changes his password.
  • +
  • $config['password_query'] = "UPDATE virtual_users SET password=%P WHERE email=%u";
    +The SQL query that is run to write the new password hash into the database. %P is a placeholder for the new password hash. And %u is the logged-in user and conveniently matches the email address.
  • +
+

Make sure that this config file is not world-readable:

+
chown root:www-data /etc/roundcube/plugins/password/config.inc.php
chmod u=rw,g=r,o= /etc/roundcube/plugins/password/config.inc.php
+

Try it. Log into Roundcube as john@example.org with password ‘summersun’. Go to the Settings. Choose Password. Enter a new password twice. You should get a success message at the bottom right. Now logout and login with the new password. Does it work? Great.

+ +

Sieve is a simple programming language to be used for server-side rules. Dovecot executes these rules every time a new email comes in. There are global rules that are executed for every email. And of course every user/mailbox can have its own rules. To manage sieve rules Dovecot offers the managesieve interface that you enabled earlier. So we just need to tell Roundcube how to access it.

+

The configuration file for Roundcube’s managesieve plugin is found at /etc/roundcube/plugins/managesieve/config.inc.php. Edit the file and again remove the empty or comment the $config line. You can again find all possible configuration options in the /usr/share/roundcube/plugins/managesieve/config.inc.php.dist file.

+

This time just one setting is required to tell Roundcube which server to talk to:

+
$config['managesieve_host'] = 'localhost';
+

Sieve rules are stored in a special syntax on the server. This is an example that moves all incoming emails to the test folder that have “test” in the subject:

+
require ["fileinto"];
if header :contains "subject" "test"
{
fileinto "INBOX/test";
}
+

You do not need to learn this syntax though. Roundcube’s sieve rule editor is way more user-friendly.

+

Try adding a sieve rule for john@example.org in Roundcube. That feature is located in Settings/Filters. You will find the machine-readable sieve code at /var/vmail/example.org/john/sieve/roundcube.sieve.

+

The rule editor looks like this:

+

Roundcube's sieve rule editor

\ No newline at end of file diff --git a/dist/ispmail-bookworm/whats-new/index.html b/dist/ispmail-bookworm/whats-new/index.html new file mode 100644 index 0000000..c706805 --- /dev/null +++ b/dist/ispmail-bookworm/whats-new/index.html @@ -0,0 +1,110 @@ + What's new | ISPmail Guide + Skip to content
+⚠️ This page is part of the ISPmail guide for Debian Bookworm. Please use the newer guide for Debian Trixie. +

What's new

I try to keep as many parts of the setup unchanged. Many of us are happy with their mail servers and want to change as little as possible. Email is a boring matter anyway and we do our jobs best if our users don’t even realize that we are there.

+

A few things though that are new in this version of the ISPmail guide:

+
    +
  • Newer software versions – it is a new Debian release after all. There are no breaking changes. Just business as usual. If you want to check the changelogs here are the version changes: +
      +
    • Postfix 3.5.18 -> 3.7.6
    • +
    • Dovecot 2.3.13 -> 2.3.19
    • +
    • PHP 7.4 -> 8.2
    • +
    • rspamd 2.7.1 -> 3.4.1
    • +
    • Apache 2.4.56 -> 2.4.57
    • +
    • Roundcube 1.4.13 -> 1.6.1
    • +
    • MariaDB 1.21 -> 1.22
    • +
    • Adminer 4.7.9 -> 4.8.1
    • +
    +
  • +
  • An improved Ansible playbook to help you automate all the steps of this guide if you want to set up multiple servers without repeating all steps manually.
  • +
  • Clearer explanations. I have reworded complex parts of the configuration.
  • +
  • Fixed links. The Dovecot wiki has moved around quote a lot of pages and I didn’t notice earlier because it did not lead to a 404 or a redirect.
  • +
  • Dovecot now uses the “count” backend to compute a user’s quota. Previous guides still used “maildir”.
  • +
  • Two chapters are currently not published: the part about Thunderbird auto-configuration because there seem to be problems with the newest versions of Thunderbird. And the part about firewalling and fail2ban because there seems to be a bug with firewalld and fail2ban. These pages deal with optional features and are not a showstopper.
  • +
\ No newline at end of file diff --git a/dist/ispmail-trixie/anti-spoofing-dkim-spf/index.html b/dist/ispmail-trixie/anti-spoofing-dkim-spf/index.html new file mode 100644 index 0000000..d61f28a --- /dev/null +++ b/dist/ispmail-trixie/anti-spoofing-dkim-spf/index.html @@ -0,0 +1,316 @@ + Prevent spoofing using DKIM and SPF | ISPmail Guide + Skip to content

Prevent spoofing using DKIM and SPF

+

Email sender spoofing means pretending to be in control of someone else’s email address. This is a common problem with +phishing. Often scammers send emails with a sender address of +something@paypal.com and hope that the recipient falls for it and trusts them. SMTP does not care which sender address +you use. Most mail service providers enforce that you send emails only using your own email address. But some do not. +And bad guys obviously don’t care.

+

On this page I will help you set up the three common measures to prevent spoofing:

+
    +
  • SPF (Sender Policy Framework)
  • +
  • DKIM (DomainKeys Identified Mail)
  • +
  • DMARC (Domain-based Message Authentication, Reporting and Conformance)
  • +
+ +

Each email that you receive actually contains two different sender addresses. Understanding the difference is important +when it comes to DKIM and DMARC.

+

The envelope sender is used by SMTP for delivery and bounce messages. It is not usually shown to the user. It +corresponds to the MAIL FROM command in SMTP. If during the transmission the sending server sent +MAIL FROM:<bounce@example.net> then this is the envelope sender. It will be added to the header part as +Return-Path: <bounce@example.net>. If you think of a written letter, then this is the sender which is written onto the +envelope. The postman will not look inside the envelope. So if the delivery fails, this is the address that the letter +will be sent back to as undeliverable.

+

The visible sender (this is not an official term) is what the recipient sees in their email software. In an actual +email this is the From: John <john@example.org> header. If you think of a written letter, then this is the sender as +found in the actual letter within the envelope.

+ +

SPF defines which servers (IP addresses) are allowed to send emails on behalf of a specific domain.

+

SPF is essentially a TXT record in your DNS zone that provides machine-readable information for other mail servers. When +an email is received, the receiving server can (and usually does) check for an SPF record for your domain to determine +which IP addresses are authorized to send emails on its behalf.

+

Let’s take a look at a typical SPF record:

+
"v=spf1 ip4:157.97.194.11 mx ~all"
+

What it means:

+
    +
  1. this is an SPF record of version 1 of the standard (there is currently no other version)
  2. +
  3. please accept emails from the IP address 157.97.194.11
  4. +
  5. also accept emails from any server that is mentioned in our domain’s MX record (the server(s) that receive email for +your domain)
  6. +
  7. any other email should be considered suspicious – proceed with caution
  8. +
+

There are websites like EasyDMARC that help you create your SPF +string to add to your DNS domain. Keep in mind:

+
    +
  • You must know which mail servers send email from your domain. Do not forget to include mailing list or newsletter +services that send in your name.
  • +
  • Start with “~all” to mark emails as spam that do not meet the criteria. If all goes well switch to “-all” after a few +weeks.
  • +
  • Note that forwarding emails from your domain may break SPF because suddenly the email appears to be coming from an IP +address that is not authorized.
  • +
+

Of course SPF not only helps other mail servers. Rspamd on your mail server will check for other domains’ SPF records, +too.

+ +

DKIM can prove that an email has not been tampered with on its journey from the sender to the recipient.

+

DKIM uses public key cryptography to automatically add a cryptographic signature into the header of each outgoing +email. It also uses a TXT record in your domain’s DNS zone to publish the public key.

+

If you run the sending mail server, you need to:

+
    +
  1. Create a public key and a private key for each domain.
  2. +
  3. Publish the public key through a DNS record of your domain. As only an administrator of the sending domain has +access to the DNS zone, this proves the authenticity.
  4. +
  5. Give your mail server the private key so it can sign all emails automatically.
  6. +
+

On the other hand the receiving mail server needs to:

+
    +
  1. Check if there is a signature in an incoming email.
  2. +
  3. Fetch the public key from the DNS zone of the sending domain.
  4. +
  5. Make a cryptographic check if the signature matches the public key.
  6. +
+

I don’t want to dive deeper into public key cryptography. Take a look at the +Wikipedia article for a decent explanation.

+

Obviously your mail server will both receive and send emails. So if you want to use DKIM (which I recommend) then +you need to take care of both parts. But luckily that’s not too hard. The rspamd software on your mail server can take +care of both signing outgoing emails and validating incoming signatures.

+ +

Let’s take a look at such a signature in real life. I have just sent an email from GMail to my personal email account on +my own mail server. Google uses DKIM signing so the email got this additional header from Google’s mail servers:

+
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=gmail.com; s=20230601; t=1760017775; x=1760622575; darn=workaround.org;
h=to:subject:message-id:date:from:mime-version:from:to:cc:subject
:date:message-id:reply-to;
bh=HmztzLfHhgZON2788h5cwCX7liAbwFqnFGISA15M18Q=;
b=OKu5D/Ejp7tGy3uxydb7qDccK03OxrdD9vxEKiAXk/y9T5WViCqpg3HrdeB5Izkzdq
MXvQ+SgGVzJmy9ZgV1A930RRqUIoR2wmlr3GDXPDyRfagJMRV/3v9J71lfSduOFE8q7t
AIw4oWBm91QAnC5gW+XS7h4lNmRd4pVILkoe09qkLz+7WrU5Xp/WGIKHRK0ST5+EAR25…
+

I need Google’s DKIM public key to verify that signature. It is stored in their DNS zone as a TXT record of +“20230601._domainkey.google.com”. The “20230601” is the key selector that is mentioned in the signature as +“s=20230601”. You can use multiple keys as long as you create the signatures with the matching private key. The +“_domainkey” part is the standard subdomain for DKIM keys. So let’s get that TXT record:

+
Run this on your server
dig +short 20230601._domainkey.google.com txt
+

This returns…

+
"v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4zd3nfUoLHWFbfoPZzAb8bvjsFIIFsNypweLuPe4M+vAP1YxObFxRnpvLYz7Z+bORKLber5aGmgFF9iaufsH1z0+aw8Qex7uDaafzWoJOM/6lAS5iI0JggZiUkqNpRQLL7H6E7HcvOMC61nJcO4r0PwLDZKwEaCs8gUHiqRn/SS3wqEZX29v/VOUVcI4BjaOz" "OCLaz7V8Bkwmj4Rqq4kaLQQrbfpjas1naScHTAmzULj0Rdp+L1vVyGitm+dd460PcTIG3Pn+FYrgQQo2fvnTcGiFFuMa8cpxgfH3rJztf1YFehLWwJWgeXTriuIyuxUabGdRQu7vh7GrObTsHmIHwIDAQAB"
+

That is the public key that I can use to verify the signature. An automated check can be done using the +opendkim-testmsg tool as described later. I can run it and paste the entire email including headers and body into it. +If it doesn’t complain with an error message then the signature is correct.

+ + +

Sounds good? Then let’s implement that for your email domains, too.

+

If you have skipped the previous section on detecting and filtering out spam emails, then just run these two commands to +tell Postfix to send all emails through rspamd:

+
Run this on your server
postconf smtpd_milters=inet:127.0.0.1:11332
postconf non_smtpd_milters=inet:127.0.0.1:11332
+

As explained above you need a private key that your mail server will use for signing and a public key that gets +added to your DNS zone.

+

If you put your key file into /var/lib/rspamd/dkim/ using a certain naming scheme, rspamd will pick it up +automatically:

+
Run this on your server – but use your own domain here
# Create the directory
mkdir /var/lib/rspamd/dkim
+
# Fix permissions
chown _rspamd:_rspamd /var/lib/rspamd/dkim
+
# Create a new keypair (use your own domain here)
cd /var/lib/rspamd/dkim
rspamadm dkim_keygen -d example.org -s 2025100901
+

The selector (-s) I chose is 2025100901 because that’s the day I created it. The first (01) key on 2025-10-09. +It doesn’t matter though – you can name it anything you want. If you are lazy and unconcerned you could even use “dkim” +as the selector and later save some work by not needing DKIM maps that define which key is supposed to be used for each +domain. “dkim” is the default selector if you do not use maps. But some day you may want to add new keys so I recommend +you stay flexible and use a custom selector.

+

The output will contain you both the private key…

+
-----BEGIN PRIVATE KEY-----
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALhyevPohneucRGQ
LXgqtajXhDgOr9kvoX5igRuChC+j7Fxvwh4SuUphMKLynabAvcUUF951BgVB4PXU
Qoxae7cEkjWATNSiv+Eq0w+AKErdC+BFNDSTk74GZDBBhlroxyudk7QMCZ2nhiOA
/rY1LypaDQzBiRSV8zjcHC8E2Z5lAgMBAAECgYEAodSn9isVGBrwz8Udb+qhOoPl
WT3hogA9hGMu/hEUo6wCrNPNkI9DDXSatM2D7xP7LNhFXQR2BNTZaTcUMIsPMXZ9
157tBVUAcnoRES6BbPyKC7k4dgSXxh687jhSgQWy+OZIU8IbJcoDXXsGjx+6Sb4W
Ilo9NMCF/QqxRFIne70CQQDhNC4YasFOdJyWACxIbFBt+/HhO5+UboUIrZU5nde7
N5HEfnP3Ow2C6vdNnGWiv4YpobN7zjz+lFj19rlWvmHDAkEA0auDQVfIiLEUrKvW
TdhbscpEoYHP+AlM48C+QltKVk+eAnJJHNbBYMVmCmXafgMzFh8QhgG5WXKSlvtz
G/+UtwJAS4QL0PQ7TeucdlAoiUCI19icC0LLCCLnSTmryF49cPH5V0Jv8H9E0Jmp
w8Sl8CT5AAzQ+rr1iQiFrDTHgWblsQJBAJGEtSMrts1QAaZZ2PHMQM+jL4DcZKek
ZM4JXsMVMwG2XlcaVK4EStBMEKcUy9D7jYBD7SbkmWyAPUc2m0yKVP8CQB1zxjA0
Z700vkWGKhwY4DznuDGjpU9rvQw7pyCJ3TYDT3ACQePmGmVeCtyETJ5XvFV2jSqf
o9J+GsdbljSnnSw=
-----END PRIVATE KEY-----
+

…and the public key – in the format of a DNS record:

+
2025100901._domainkey IN TXT ( "v=DKIM1; k=rsa;"
"p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC4cnrz6IZ3rnERkC14KrWo14Q4Dq/ZL6F+YoEbgoQvo+xcb8IeErlKYTCi8p2mwL3FFBfedQYFQeD11EKMWnu3BJI1gEzUor/hKtMPgChK3QvgRTQ0k5O+BmQwQYZa6McrnZO0DAmdp4YjgP62NS8qWg0MwYkUlfM43BwvBNmeZQIDAQAB" ) ;
+ +

Before you start signing your emails you must make sure that the public key is properly present in your DNS zone for the +domain you are sending emails from. Otherwise the recipient will be unable to verify the signature and may incorrectly +assume that the email was spoofed.

+

Take a look at the TXT record. It will look something like this:

+
2019122401._domainkey IN TXT v=DKIM1; k=rsa;
+

If you are running your own DNS server you should be able to copy this entire file and put it into your DNS zone. +However if your internet provider offers you just a web interface to manage your domains then create a new TXT record +with a host name of “2019122401._domainkey” in your domain and put the string within the double-quotes into it as +the value. In my example:

+
2025100901._domainkey IN TXT ( "v=DKIM1; k=rsa;"
"p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC4cnrz6IZ3rnERkC14KrWo14Q4Dq/ZL6F+YoEbgoQvo+xcb8IeErlKYTCi8p2mwL3FFBfedQYFQeD11EKMWnu3BJI1gEzUor/hKtMPgChK3QvgRTQ0k5O+BmQwQYZa6McrnZO0DAmdp4YjgP62NS8qWg0MwYkUlfM43BwvBNmeZQIDAQAB" ) ;
+

Be aware that the string you got contains two strings ”…” + ”…” that must be merged into one to work. If you are running +your own name server with bind then you can just take that record as is. Other software or your favorite DNS provider +may expect a different syntax. In the end the value of the TXT record needs to be one long string. You can use dig to +verify that:

+
Run this on your server
dig +short 2025100901._domainkey.example.org txt
+

If you get the TXT entry like as follows then you are ready to enable DKIM signing in rspamd for that domain:

+
"p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC4cnrz6IZ3rnERkC14KrWo14Q4Dq/ZL6F+YoEbgoQvo+xcb8IeErlKYTCi8p2mwL3FFBfedQYFQeD11EKMWnu3BJI1gEzUor/hKtMPgChK3QvgRTQ0k5O+BmQwQYZa6McrnZO0DAmdp4YjgP62NS8qWg0MwYkUlfM43BwvBNmeZQIDAQAB"
+ +

Take the private key that was created earlier (the multi-line string including “…BEGIN PRIVATE KEY…” and +“…END PRIVATE KEY…”) and put it into a file at the location where rspamd will look for it:

+
/var/lib/rspamd/dkim/example.org.2025100901.key
+

The name of the file has to be  DOMAIN + dot + SELECTOR + “.key” like above. If you name the file incorrectly you will +get an error in your rspamd.log file like “lua_dkim_sign_handler: cannot load dkim key +/var/lib/rspamd/dkim/example.org.dkim.key”.

+

Make sure that only the _rspamd user can read it:

+
Run this on your server
chown _rspamd /var/lib/rspamd/dkim/*
chmod u=r,go= /var/lib/rspamd/dkim/*
+

rspamd will automatically pick up the files and does not need to be restarted when you add new keys for further domains.

+ +

As explained above it is advised to use DKIM maps. It’s nothing fancy. Just a simple file defining which selector +you want to use for signing for a certain domain. rspamd will assume that your selector is always dkim unless +specified otherwise in a map. Always use a specific selector so that you can later add new keys to DNS without getting +into trouble.

+

Using maps is simple. First we need to change the selector_map setting of the dkim_signing module. Create a new rspamd +configuration file:

+
Run this on your server
# Tell rspamd to look up selectors in our mapping file
cat > /etc/rspamd/local.d/dkim_signing.conf << 'EOF'
path = "/var/lib/rspamd/dkim/$domain.$selector.key";
selector_map = "/etc/rspamd/dkim_selectors.map";
EOF
+
# Restart rspamd
systemctl restart rspamd
+

The configuration is simple. rspamd will look for the domain-to-key mapping in the dkim_selectors.map file. Create +that file for your own domain and selector:

+
Run this on your server
# Add the mapping of domain/selector (use your own domain here)
echo example.org 2025100901 > /etc/rspamd/dkim_selectors.map
+

That’s all. rspamd now knows that whenever it sees an outgoing email from anyone@example.org it will get the DKIM +private key from /var/lib/rspamd/dkim/example.org.2025100901.key and use it to sign the email.

+ +

You could either just send an email from your mail client (or Roundcube) through your mail server to another email +address. Or you could use swaks. Use your own addresses and password of course:

+
Run this on your server
swaks --server localhost:587 \
--from some.address@example.org \
--to some.external.address@example.net \
-tls \
--auth-user some.address@example.org \
--auth-password your_secreet_password
+

If you take a look at the received email it should have a DKIM header now like:

+
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=example.org; s=2019122401; t=1519400838
h=from:subject:date:message-id:to:mime-version:content-type:content-transfer-encoding;
bh=kpYel1IlDvqXEUc0SyIpXbMte3XpQOCXHl+zTyHQvGc=; b=NEUyWUoeKE…
+

To verify the signature install the opendkim-tools package, copy the entire test email (including headers and body), +run opendkim-testmsg in your shell and paste the email (finish with CTRL-D).

+

If you get no output then the signature verified correctly. But if you get something like “opendkim-testmsg: dkim_eom(): +Unable to verify” then double-check your DNS record.

+

You can also use websites like dkimvalidator.com or +mail-tester.com to verify that your signatures are working well.

+
Click here if you do not get a DKIM signature…

Enable logging:

Run this on your server
cat > /etc/rspamd/local.d/logging.inc << 'EOF'
debug_modules = ["dkim", "dkim_signing"];
EOF
+
systemctl restart rspamd
+
tail -f /var/log/rspamd/rspamd.log

Look for any errors. And check that the correct key from /var/lib/rspamd/dkim is chosen and used. This is what it +should look like:

2025-10-19 10:23:40 #1806716(normal) <ec2f11>; dkim_signing; lua_dkim_tools.lua:185: user is authenticated
2025-10-19 10:23:40 #1806716(normal) <ec2f11>; dkim_signing; lua_dkim_tools.lua:407: use domain(header) for signature: example.org
2025-10-19 10:23:40 #1806716(normal) <ec2f11>; dkim_signing; lua_dkim_tools.lua:427: final DKIM domain: example.org
2025-10-19 10:23:40 #1806716(normal) <ec2f11>; dkim_signing; lua_dkim_tools.lua:48: add selector "2025100901" using selector_map
2025-10-19 10:23:40 #1806716(normal) <ec2f11>; dkim_signing; lua_dkim_tools.lua:53: set key to "/var/lib/rspamd/dkim/$domain.$selector.key" using default path
2025-10-19 10:23:40 #1806716(normal) <ec2f11>; dkim_signing; lua_dkim_tools.lua:53: set domain to "example.org" using dkim_domain
2025-10-19 10:23:40 #1806716(normal) <ec2f11>; dkim_signing; dkim_signing.lua:130: using key "/var/lib/rspamd/dkim/example.org.2025100901.key", use selector "2025100901" for domain "example.org"

One caveat is the handling of subdomains. example.org is a second-level domain. But you may want to use +service.example.org for your domain. That’s totally fine. But rspamd will strip it down to example.org and use the +DKIM key for example.org. If that’s not what you want, then add this line to /etc/rspamd/local.d/dkim_signing.conf:

use_esld = false;

eSLD is a rarely used acronym that stands for effective second-level domain. In layman’s terms: the part of a +domain that only consists of the rightmost two parts. For mails.hawkeye.example.com the eSLD is example.com.

+ + +

Let’s take an example header of a spoofed mail:

+
Return-Path: <noreply@evil-spammer.com>
DKIM-Signature: d=evil-spammer.com
From: <service@paypal.com>
+

In this example a bad guy just sent you this email. The SPF check for the evil-spammer.com domain was successful. (You +can’t see that from these headers though.) He even added a DKIM signature from his domain. So everything looks right. +But in your mail program you see service@paypal.com. So nobody checks that the envelop sender and the visible +sender “align”.

+ +

That’s what DMARC is supposed to solve. It works like this:

+
    +
  • (A) SPF +
      +
    • Run a normal SPF check (on the envelope sender’s domain as usual)
    • +
    • Make sure that the domain of this envelope sender aligns with (matches) the domain of the visible sender
    • +
    +
  • +
  • (B) DKIM +
      +
    • Look for a valid DKIM signature (also of the envelope sender’s domain)
    • +
    • Make sure that the domain of the envelope sender aligns with (matches) the domain of the visible sender
    • +
    +
  • +
  • Make sure that at least one of (A) or (B) are true
  • +
+

There are also two flavors of that alignment:

+
    +
  • strict means that the domains need to match exactly
  • +
  • relaxed means that it can be a subdomain
  • +
+

You can find more examples about the alignment in the RFC 7489 in Appendix +B.1.

+ +

Another feature of DMARC is reporting. You may want to know whether your emails had delivery problems. DMARC has two +tags for that purpose:

+
    +
  • ruf stands for “Reporting URI for Failure data”. The email address you use in the “ruf” tag will get +machine-readable information on every mail that failed the DMARC test. If the receiving mail server supports DMARC, it +may automatically generate and send that email to this address. However most internet providers just ignore “ruf” +because it contains sensible information on email addresses.
  • +
  • rua stands for “Reporting URI for Aggregated data”. The email address you use in the “rua” tag will +get statistical data usually once a day. If you want to know if your emails deliver properly, you can use this.
  • +
+

There are commercial offers that allow you to point your “rua” record to their service and show you human-readable +information. Or you can use the tools dmarc-cat or dmarcts-report-parser that can be installed as Debian packages on +your system.

+ +

If you want to use DMARC (and I suggest that you do), just add a DNS record to your domain. These web sites help you +craft a valid record:

+ +

Please note that the DMARC record is a TXT record like _dmarc.example.com. That _dmarc host name is important.

\ No newline at end of file diff --git a/dist/ispmail-trixie/automated-installation/index.html b/dist/ispmail-trixie/automated-installation/index.html new file mode 100644 index 0000000..24630fc --- /dev/null +++ b/dist/ispmail-trixie/automated-installation/index.html @@ -0,0 +1,99 @@ + Automated installation | ISPmail Guide + Skip to content

Automated installation

I have spent an extra couple of days to provide you with a shell script that does all the steps of this guide +automatically on a fresh Debian Trixie system. The previous Bookworm guide contained an Ansible playbook for that +purpose. But although I know Ansible quite well, I have realized that it can make simple tasks very complicated. So I +thought that a shell script is the simplest way.

+ +

To use the automated installer:

+
Terminal window
wget https://workaround.org/ispmail.sh
chmod +x ispmail.sh
./ispmail.sh -f example.org
+

Use your main FQDN instead of example.org. It will become the main host name for Roundcube, rspamd, SMTP, IMAP and +will be taken as the common name for the Let’s Encrypt certificate.

+

This script is something new. So please report your experience while using it down in the comments.

\ No newline at end of file diff --git a/dist/ispmail-trixie/catch-all/index.html b/dist/ispmail-trixie/catch-all/index.html new file mode 100644 index 0000000..6c66657 --- /dev/null +++ b/dist/ispmail-trixie/catch-all/index.html @@ -0,0 +1,151 @@ + Catch-all addresses | ISPmail Guide + Skip to content

Catch-all addresses

+

As explained earlier in the tutorial there is way to forward all undefined email addresses in a domain to a certain +destination email address. This is called a catch-all alias. Those aliases catch all emails for a domain if there is +no specific virtual user or virtual alias for that email address. The drawback is that you will get more spam +because spammers will send their stuff to any address of your domain. Or perhaps a sender mixed up the proper spelling +of a recipient but the mail server will forward the email instead of rejecting it for a good reason.

+

You still want to use catch-all addresses? Well, okay. Let’s do it then. A catchall alias looks like “@example.org” and +forwards email for the whole domain to other addresses. We have created the john@example.org user and would like to +forward all other email on the domain to kerstin@example.com. So we would add a catchall alias like:

+ + + + + + + + + + + + + +
sourcedestination
@example.orgkerstin@example.com
+

But there is a small catch. Postfix will apply the aliases (virtual_alias_maps) before delivering an email. So the +catch-all alias will “steal” all emails. But we can add this to the aliases table to prevent that:

+ + + + + + + + + + + + + + + + + +
emaildestination
@example.orgkerstin@example.com
john@example.orgjohn@example.org
+

Postfix will consider more specific aliases first. And john@example.org is more specific than @example.org. Consider +that someone is trying to reach john@example.org’s mailbox. So to make a mixture of catch-all addresses and specific +addresses work, we need this little trickery.

+

Postfix will lookup all these mappings for each of:

+
    +
  • john@example.org (most specific)
  • +
  • @example.org (catchall – least specific)
  • +
+

This is outlined in the virtual(5) man page in the TABLE SEARCH +ORDER section.

+

We do not want to add that “more specific” entry for each email address manually. Fortunately we can easily automate +that. For that “john-to-himself” mapping you need to create another “.cf” file /etc/postfix/mysql-email2email.cf:

+
Run this on your server
# Create the john-to-himself mapping
cat > /etc/postfix/mariadb-email2email.cf << EOF
user = mailserver
password = MAILSERVER-PASSWORD-HERE
hosts = 127.0.0.1
dbname = mailserver
query = SELECT email FROM virtual_users WHERE email='%s'
EOF
+
# Fix the permissions of that file
chgrp postfix /etc/postfix/mariadb-*.cf
chmod u=rw,g=r,o= /etc/postfix/mariadb-*.cf
+
# Add the new mapping to the virtual_alias_maps
# (The order is not important. Postfix will check all mapping files.)
postconf virtual_alias_maps=mysql:/etc/postfix/mariadb-virtual-alias-maps.cf,mysql:/etc/postfix/mariadb-email2email.cf
+

Check that you get John’s email address back when you ask Postfix if there are any aliases for him:

+
Run this on your server
postmap -q john@example.org mysql:/etc/postfix/mariadb-email2email.cf
+

The result should be the same address:

+
john@example.org
+

Now you are ready to add catch-all aliases.

\ No newline at end of file diff --git a/dist/ispmail-trixie/catching-spam-with-rspamd/index.html b/dist/ispmail-trixie/catching-spam-with-rspamd/index.html new file mode 100644 index 0000000..ce9d884 --- /dev/null +++ b/dist/ispmail-trixie/catching-spam-with-rspamd/index.html @@ -0,0 +1,330 @@ + Catching spam with rspamd | ISPmail Guide + Skip to content

Catching spam with rspamd

+

You have come a long way in this guide and your mail server is already fully functional. Now it’s time to deal with +filtering out incoming spam emails. I found that rspamd is well-performing choice for that +purpose both in speed and detection. rspamd keeps a permanent process running on your mail server that listens to +connections from Postfix using the milter (=mail filter) protocol. +Every time an email enters your system, Postfix will send it to rspamd to have its content checked. rspamd runs a lot of +checks on the email and computes a total score. The higher the score – the more likely it it spam. And the best thing +about milters: the check happens in parallel while Postfix is still in the process of receiving the email. If the score +is high enough, Postfix can still reject the email right at the doorstep.

+ +

Let’s tell Postfix to send all incoming email through rspamd:

+
Run this on your server
postconf smtpd_milters=inet:127.0.0.1:11332
postconf non_smtpd_milters=inet:127.0.0.1:11332
+

For testing we can use a sample spam email that comes with SpamAssassin. It is called GTUBE (Generic Test +for Unsolicited Bulk Email). It contains a certain artificial pattern that is recognized as spam by +SpamAssassin. Do you know EICAR.COM to test virus scanners? This is the same thing for spam.

+

Get the GTUBE file, send it to John and let’s see what happens:

+
Run this on your server
wget http://spamassassin.apache.org/gtube/gtube.txt
sendmail john@example.org < gtube.txt
journalctl -fu postfix
+

You will find something like this at the end of the log file:

+
postfix/cleanup[1386519]: 2B72320126: message-id=<GTUBE1.1010101@example.net>
postfix/cleanup[1386519]: 2B72320126: milter-reject: END-OF-MESSAGE from localhost[127.0.0.1]: 5.7.1 Gtube pattern; from=<root@mailserver> to=<john@example.org>
postfix/cleanup[1386519]: 2B72320126: to=<john@example.org>, relay=none, delay=0.16, delays=0.16/0/0/0, dsn=5.7.1, status=bounced (Gtube pattern)
+

milter-reject tells that the rspamd recommended to reject the email. It gave the reason 5.7.1 Gtube pattern. SMTP +and LMTP always uses such three digit codes. They are defined in RFC 3463. The +first digit is most important:

+
    +
  • 2 = Success
  • +
  • 4 = Temporary failure (come back later)
  • +
  • 5 = Permanent failure (do not try again in this way)
  • +
+

So 5.7.1 tells us that the result code is a permanent failure in delivery. If you looked up the RFC you would find +that the 7 stands for an issue regarding the security policy. So it’s not a technical failure but instead a +security-relevant component on the system has rejected the email. That’s what rspamd did. It even told us the reason: +Gtube pattern. So you see that rspamd knows about the Gtube spam test pattern and reacts as expected.

+

That email will not be delivered to John. Instead Postfix will reject it at the doorstep – while it is still in the SMTP +communication with the sending server. It just hung up the phone and now it’s the sending server’s problem to deal with.

+

It is important to either reject an email right away or to deliver it to a user. Never accept an email and later decide +to complain about it to the alleged sender. Trust me: the sender you see on a spam email is never the bad guy who sent +it. You would complain to the wrong person which is called +backscatter.

+ +

rspamd will however not reject all spam email. It computes a score that tells how likely a certain email is spam. You +can tell it which scores you would accept, flag as spam or make the incoming email get rejected. Rspamd checks incoming +emails in various ways. Take a look at the /etc/rspamd/actions.conf file:

+
actions {
reject = 15;
add_header = 6;
greylist = 4;
}
+

These are the default actions. If rspamd computes a score of at least 15 then the email will get rejected right away +just like the Gtube pattern in the previous test. Any other score above 6 will add a line “X-Spam: Yes” so that your +mail software can detect them and maybe file the email to a different folder. And any other score above 4 will trigger +greylisting which is a mechanism that temporarily rejects the +email with a 4.x.x code and waits if the sending server will try again. After a waiting time of a few minutes +greylisting will accept the email. The idea is to reject email from systems that do not have a sending queue. Malware +like on infected Wind*ws computers used to try sending an email just once which triggered greylisting and successfully +rejected the spammer. But even malware programmers have learned and may try again after a few minutes thus circumventing +greylisting. Your mileage may vary. The problem with greylisting is that the recipient has to wait a couple of minutes +for the email to be delivered which may be bothering the users.

+ +

An email consists of headers and the actual body. Your users will usually only see common header information +like the subject, the sender, the recipient and the time the email was sent. But there is way more information +like the route the email travelled. Mail software can even add arbitrary extended headers that start with X-. +There is one specific header that rspamd adds for us if it finds a spam email:

+
X-Spam: Yes
+
Click here to dive deeper into rspamd’s scores…

rspamd can add an X-Spamd-Result header containing the various criteria that added to the total score:

X-Rspamd-Server: mailserver
X-Rspamd-Queue-Id: C22E55A005B3
X-Spamd-Result: default: False [11.55 / 15.00]
R_PARTS_DIFFER(0.27)[63.4%]
FROM_NO_DN(0.00)[]
RCVD_COUNT_ZERO(0.00)[0]
R_DKIM_NA(0.00)[]
FUZZY_DENIED(12.00)[1:19305c7fdd:1.00:bin,1:35699594fd:0.91:txt]
RBL_SENDERSCORE(2.00)[55.181.23.94.bl.score.senderscore.com]
ARC_NA(0.00)[]
RCPT_COUNT_ONE(0.00)[1]
RCVD_TLS_ALL(0.00)[]
FROM_EQ_ENVFROM(0.00)[]
R_SPF_SOFTFAIL(0.00)[~all]
BAYES_HAM(-2.71)[98.75%]
TO_MATCH_ENVRCPT_ALL(0.00)[]
MIME_GOOD(-0.10)[multipart/related,multipart/alternative,text/plain]
MID_RHS_MATCH_FROM(0.00)[]
ASN(0.00)[asn:16276, ipnet:94.23.0.0/16, country:FR]
TO_DN_NONE(0.00)[]
DMARC_POLICY_SOFTFAIL(0.10)[Chronopost.fr : No valid SPF, No valid DKIM,none]
SUBJECT_ENDS_EXCLAIM(0.00)[]
X-Spam: Yes

Enable those additonal headers:

Run this on your server
# Enable rspamd's extended headers
cat > /etc/rspamd/local.d/milter_headers.conf << EOF
extended_spam_headers = true;
EOF
+
# Restart rspamd
systemctl reload rspamd
+
# Send a normal (non-spam) test email. Do not use "localhost" here because rspamd
# will only add extended headers for emails coming from the internet.
swaks --server mailserver.example.org --to john@example.org

Each of the uppercase symbols like FROM_HAS_DN means that a certain detection rule of rspamd was triggered. It does +not necessarily mean something bad about the email. For example R_SPF_ALLOW has a negative score that lowers the total +score because it is something good about the email. There are a several symbols with a 0.00 score. These do not change +the score but show you what rspamd has found. But if you consider certain criteria good or bad then you can +define your own scores for them.

+ +

Your users will not realize that their spam emails have an added X-Spam: Yes header. It is not shown in their mail +client. Nor does it move the email out of the inbox into their spam folder. Such emails just appear in their inbox. So +let’s be nice and move spam emails to the user’s Junk folder automatically. Dovecot has support +for Sieve filtering rules that are if-then scripts +that get run whenever an email arrives.

+

John could create such a Sieve script for himself (using the Roundcube webmail interface). But let’s find a solution +that applies to all your users. Create a new config file (/etc/dovecot/conf.d/99-ispmail-sieve.conf) that tells +Dovecot:

+
    +
  • whenever an email is delivered to our users, run an additional Sieve script +(/etc/dovecot/sieve/spam-to-junk-folder.sieve)
  • +
  • the Sieve functionality is enabled during LMTP (when an email is passed on from Postfix to Dovecot)
  • +
  • the user gets a Junk folder created in his mailbox and is subscribed to it so that it appears in their mail program
  • +
+
Run this on your server
# Create a new config file for spam handling
cat > /etc/dovecot/conf.d/99-ispmail-sieve-movetojunk.conf << 'EOF'
sieve_script spam-to-junk-folder {
driver = file
type = after
path = /etc/dovecot/sieve/spam-to-junk-folder.sieve
}
+
# Enable the execution of Sieve rules when Postfix sends an email to Dovecot over LMTP
protocol lmtp {
mail_plugins {
sieve = yes
}
}
+
# Make sure that every user has a Junk folder and is subscribed to it
namespace inbox {
mailbox Junk {
special_use = \Junk
auto = subscribe
}
}
EOF
+
# Restart Dovecot
systemctl reload dovecot
+

Now we need to create that Sieve script (/etc/dovecot/sieve/spam-to-junk-folder.sieve) that is run on each delivery. +Its job is to check if the X-Spam: yes header is present. If it is, the email is filed into the user’s Junk folder.

+
Run this on your server
# Create the directory for Sieve files
mkdir -p /etc/dovecot/sieve
+
# Create the Sieve script to move Spam mails to the user's Junk folder
cat > /etc/dovecot/sieve/spam-to-junk-folder.sieve << 'EOF'
require ["fileinto"];
+
if header :contains "X-Spam" "Yes" {
fileinto "Junk";
stop;
}
EOF
+
# Make the sieve script machine-readable
sievec /etc/dovecot/sieve/spam-to-junk-folder.sieve
+

Let’s give it a test using Swaks. This time we impersonate Postfix and inject an email with an X-Spam: yes header +directly into Dovecot using the LMTP socket:

+
Run this on your server
swaks --to john@example.org --header-X-Spam "yes" --socket /var/spool/postfix/private/dovecot-lmtp --protocol LMTP
journalctl -fu dovecot
+

It should read:

+
dovecot[1434406]: lmtp(john@example.org)<1436598><kh4lDNl26Wi26xUA5ANL0g>: sieve: msgid=<20251010211257.1436597@mailserver>: fileinto action: stored mail into mailbox 'Junk'
+

The alleged spam email has been moved to the Junk folder just like we wanted.

+
Click here to get more detailed logs…

If you find that the delivery to the Junk folder did not work, you may want to increase the log level. Uncomment the +line

log_debug=category=sieve

in the 99-ispmail-sieve.conf file.

That will give you a much deeper insight of what Dovecot has been doing. Restart Dovecot, send another email with +swaks and check the logs again:

Run this on your server
systemctl reload dovecot
journalctl -eu dovecot
+ +

One of rspamd’s features is analyzing word patterns using probability theory. That functionality is contained in its +statistical module. (Yes, the name is misleading.) Essentially +you show rspamd lots of ham (good) and spam (bad) emails and its detection gets better over time.

+

Rspamd stores that training data (among other information) in a local Redis database.

+
Click here to learn more about Redis…

Redis is a kind of database system. It is way more limited than a traditional SQL database because it just stores keys +and values. There aren’t several fields/columns like in SQL. But it is lightning fast the way it works. On my aged +server it handles around 50,000 requests per second. It gets it speed from its simplicity and from keeping the data in +RAM. So it doesn’t access the disk to fetch information. (But it copies its data to disk frequently to prevent data +loss.) People use Redis as a cache or for very fast lookups of simple data structures. And so +does rspamd.

+

You have already installed the “redis-server” package earlier. It has started automatically and listens to incoming +connections on TCP port 6379 on localhost. You just need to tell rspamd to use it:

+
Run this on your server
# Create a config file to enable automatic spam training
cat > /etc/rspamd/local.d/classifier-bayes.conf << 'EOF'
# Store training data in the Redis database
servers = "127.0.0.1:6379";
backend = "redis";
+
# Enable automatic training
autolearn = true; # if rspamd is sure that an email is spam, it will be learned
min_learns = 200; # do not trust the data before at least 200 mails have been learned
EOF
+
# Restart rspamd
systemctl restart rspamd
+

You will start with an empty training database. But that is not as bad as it sounds, because rspamd checks many +properties of an email to determine if an email is ham or spam. If there is enough evidence that an email is likely ham +or spam, then autolearning adds it to its training database. +The rspamd documentation has further examples how to fine-tune +auto learning. After a few hundred emails the training will contribute towards a better detection rate.

+

The defaults for auto-learning are:

+
    +
  • score < -0.5 ➞ learn as ham/good
  • +
  • score > 4.0 ➞ learn as spam/bad
  • +
+

See rspamd’s documentation if you want to +fine-tune that.

+
Run this on your server
rspamc stat
+

Bayes spam checking will not work before it learned at least 200 spam and ham emails. Teaching rspamd fewer emails or +just spam emails will not work. This is defined by the min_learns variable defined in /etc/rspamd/statistic.conf.

+

In the output you will find lines beginning with “Statfile” like these…

+
Statfile: BAYES_SPAM type: redis; length: 0; free blocks: 0;
total blocks: 0; free: 0.00%; learned: 21164;
users: 214; languages: 0
+
Statfile: BAYES_HAM type: redis; length: 0; free blocks: 0;
total blocks: 0; free: 0.00%; learned: 1411;
users: 62; languages: 0
+

(Don’t worry about the length: 0. That seems to be a bug that has been +ignored since 2019. Checking the actual contents of the Redis database reveals that there is actually data stored.)

+ +

Usually the training database applies to all incoming emails for all users. But you split it up so that each +recipient gets their own training.

+

Advantage: users work differently. Some have subscribed to a sales newsletter and now believe that marking it as +spam gets them unsubscribed. Yes, that’s stupid but can thoroughly confuse the spam detection. Also you might not be +very interested in “blue pills” while others are. So the training data of one user does not affect that of the others.

+

Disadvantage: training still requires many ham and spam mails before it has any effect. So unless a user gets 200 +samples of good and bad emails, spam detection cannot work. Many users will not get that many emails so due to the lack +of spam training the detection will not be improved. For a friends-and-family server I would suggest not to use it.

+

If you decide you want to use per-user spam training then add/edit the file /etc/rspamd/local.d/classifier-bayes.conf +and insert:

+
users_enabled = true;
+ +

Now we are getting to something really cool. Imagine you receive a spam email in your inbox that Rspamd didn’t catch. +You could just move it to your Junk folder — but that wouldn’t help Rspamd learn to recognize that kind of spam in the +future. Luckily, we can change that.

+

Let’s tell Dovecot that moving emails into the Junk folder teaches rspamd instantly that the email is spam. And +if the email is moved out of the Junk folder, then learn it as ham. That can be done using another sieve +script. Sieve scripts not only apply when an email is delivered. Thanks to Dovecot’s +IMAPSieve plugin, such +scripts can also be triggered if a user moves a mail between folders.

+

The setup requires three parts:

+
    +
  1. Tap into the IMAP connection to know when an email is moved out of or into the Junk folder.
  2. +
  3. Create Sieve scripts that call Shell scripts.
  4. +
  5. Create Shell scripts that actually call rspamd learn_ham or rspamd learn_spam.
  6. +
+

Or as a diagram:

+Diagram showing how to learn ham/spam when moving mails +

Create a new Dovecot configuration file (99-ispmail-imapsieve.conf) to enable the required functionality and add +triggers on the Junk folder:

+
Run this on your server
cat > /etc/dovecot/conf.d/99-ispmail-imapsieve.conf << 'EOF'
# Enable the imap_sieve plugin
protocol imap {
mail_plugins {
imap_sieve = yes
}
}
+
# Allow the use of the pipe plugin to send mails to shell scripts
sieve_plugins {
sieve_extprograms = yes
sieve_imapsieve = yes
}
+
sieve_global_extensions {
vnd.dovecot.pipe = yes
}
+
# Where to look for Sieve scripts that use the Pipe functionality
sieve_pipe_bin_dir = /etc/dovecot/sieve
+
# Moved into Junk? -> Learn as spam.
mailbox Junk {
sieve_script spam {
type = before
cause = copy
path = /etc/dovecot/sieve/learn-spam.sieve
}
}
+
# Moved out of Junk? -> Learn as ham.
imapsieve_from Junk {
sieve_script ham {
type = before
cause = copy
path = /etc/dovecot/sieve/learn-ham.sieve
}
}
EOF
+
systemctl reload dovecot
+

The first rule tells Dovecot to run a Sieve script at /etc/dovecot/sieve/learn-spam.sieve whenever an email is moved +into a user’s “Junk” folder. We will create that Sieve script in a minute.

+

The second rule works the other way. Whenever an email is moved out of the “Junk” folder to any other folder, then +the /etc/dovecot/sieve/learn-ham.sieve Sieve script is called.

+

Let’s create both Sieve scripts:

+
Run this on your server
# Create spam learning script
cat > /etc/dovecot/sieve/learn-spam.sieve << 'EOF'
require ["vnd.dovecot.pipe", "copy", "imapsieve"];
pipe :copy "rspamd-learn-spam.sh";
EOF
+
# Create ham learning script
cat > /etc/dovecot/sieve/learn-ham.sieve << 'EOF'
require ["vnd.dovecot.pipe", "copy", "imapsieve", "variables"];
pipe :copy "rspamd-learn-ham.sh";
EOF
+
# Compile the Sieve scripts
sievec /etc/dovecot/sieve/learn-spam.sieve
sievec /etc/dovecot/sieve/learn-ham.sieve
+
# Fix permissions
chmod u=rw,go= /etc/dovecot/sieve/learn-{spam,ham}.{sieve,svbin}
chown vmail:vmail /etc/dovecot/sieve/learn-{spam,ham}.{sieve,svbin}
+

By the way: the sievec comment compiles the *.sieve file into *.svbin files that Dovecot can work with. If you are +not doing this step, Dovecot will do that during runtime. However then you need to make sure that Dovecot has proper +write permissions to the target directory. The sievec command is also useful because it scans a *.sieve file for +errors. So if your changes do not seem to work it might be worth compiling them and looking for errors.

+

And the last step is to create the simple shell scripts that do the actual spam/ham training:

+
Run this on your server
# Create the shell script for learning spam
cat > /etc/dovecot/sieve/rspamd-learn-spam.sh << 'EOF'
#!/bin/sh
# Receives an email from Dovecot's Sieve script and pipe it into rspamc
exec /usr/bin/rspamc learn_spam
EOF
+
# Create the shell script for learning ham
cat > /etc/dovecot/sieve/rspamd-learn-ham.sh << 'EOF'
#!/bin/sh
# Receives an email from Dovecot's Sieve script and pipe it into rspamc
exec /usr/bin/rspamc learn_ham
EOF
+
# Fix permissions of the shell scripts
chmod u=rwx,go= /etc/dovecot/sieve/rspamd-learn-{spam,ham}.sh
chown vmail:vmail /etc/dovecot/sieve/rspamd-learn-{spam,ham}.sh
+

I am sure you are eager to try it out. Of course we don’t blindly believe that it works. We want to see it do its job. +Usually you will not see much unless you increase the log level to debug. Let’s do that:

+
Terminal window
cat > /etc/dovecot/conf.d/99-ispmail-sieve-debug.conf << 'EOF'
# Enable detailed logging of Sieve scripts
log_debug=category=sieve
EOF
+
# Restart Dovecot
systemctl reload dovecot
+
# Follow Dovecot's logs
journalctl -fu dovecot
+

Now open your IMAP client (Thunderbird, Evolution, Roundcube, mutt or whatever you prefer) and drag an email to John’s +Junk folder. The mail log will show a lot of things that are going on. You will see a whole screen full of things that +are going on. Some relevant lines:

+
imap(john@example.org)<1737478><FnGIR2BBA/5bar5M>: Debug: Mailbox Junk: imapsieve: storage spam: file: Using Sieve script path: /etc/dovecot/sieve/learn-spam.sieve
imap(john@example.org)<1737478><FnGIR2BBA/5bar5M>: Debug: Mailbox Junk: imapsieve: storage spam: file: script 'learn-spam': Opened from 'spam'
imap(john@example.org)<1737478><FnGIR2BBA/5bar5M>: Debug: sieve: Opening script 1 of 1 from 'spam/learn-spam'
imap(john@example.org)<1737478><FnGIR2BBA/5bar5M>: Debug: sieve: Executing script from '/etc/dovecot/sieve/learn-spam.svbin'
imap(john@example.org)<1737478><FnGIR2BBA/5bar5M>: Debug: sieve: action pipe: running program: rspamd-learn-spam.sh
imap(john@example.org)<1737478><FnGIR2BBA/5bar5M>: Debug: sieve: uid=19: Finalize pipe action (status=ok, action_status=ok, commit_status=ok, pre-commit=yes)
imap(john@example.org)<1737478><FnGIR2BBA/5bar5M>: Debug: sieve: execute exec:/etc/dovecot/sieve/rspamd-learn-spam.sh (1737484): Connected to program
imap(john@example.org)<1737478><FnGIR2BBA/5bar5M>: Debug: sieve: uid=19: pipe action: piped message to program 'rspamd-learn-spam.sh'
+

Something similar should happen when you drag the email back from the Junk folder to the Inbox.

+

The /var/log/rspamd/rspamd.log file will also show that training:

+
rspamd_controller_learn_fin_task: <127.0.0.1> learned message as spam: GTUBE1.1010101@example.net
rspamd_controller_learn_fin_task: <127.0.0.1> learned message as ham: 20251101173211.068172@mailserver
+

If you are happy and see no errors (they are highlighted in red), then switch off the debugging again.

+ +

rspamd keeps a verbose log of its actions in /var/log/rspamd/rspamd.log. If a user complains that a certain email got +blocked or at least flagged as spam then take a look at this log. You can match the /var/log/mail.log with it by +comparing the Postfix queue ID. Those are the 12-digit hexadecimal number like “95CE05A00547”. Those IDs can be +found in the rspamd.log, too:

+
<40985d>; task; rspamd_task_write_log: id: <undef>, qid: <95CE05A00547>, ip: 12.13.51.194, from: <…>, (default: F (no action): [3.40/15.00] [MISSING_MID(2.50){},MISSING_DATE(1.00){},MIME_GOOD(-0.10){text/plain;},ARC_NA(0.00){},ASN(0.00){asn:8220, ipnet:212.123.192.0/18, country:GB;},FROM_EQ_ENVFROM(0.00){},FROM_NO_DN(0.00){},RCPT_COUNT_ONE(0.00){1;},RCVD_COUNT_ZERO(0.00){0;},RCVD_TLS_ALL(0.00){},TO_DN_NONE(0.00){},TO_DOM_EQ_FROM_DOM(0.00){},TO_MATCH_ENVRCPT_ALL(0.00){}]), len: 181, time: 16.000ms real, 6.385ms virtual, dns req: 0, digest: <69b289a82827c11f759837c033cd800a>, rcpts: <…>, mime_rcpt: <…>
+ +

Andi Olsen pointed out that Dovecot has introduced an +autoexpunge feature to automatically +delete emails in a folder that reach a certain age. This is especially useful for the “Trash” and “Junk” folders. To +enable this feature, create yet another configuration file:

+
Run this on your server
cat > /etc/dovecot/conf.d/99-ispmail-autoexpunge.conf << 'EOF'
# Remove mails from the Junk and Trash folders after 30 days
mailbox Junk {
special_use = \Junk
auto = subscribe
mailbox_autoexpunge = 30d
}
mailbox Trash {
special_use = \Trash
auto = subscribe
mailbox_autoexpunge = 30d
}
+
# Make expunging more efficient
mailbox_list_index = yes
mail_always_cache_fields = date.save
EOF
+
# Restart Dovecot
systemctl reload dovecot
+ +

rspamd comes with a neat bonus feature: a web interface. It allows you to check emails for spam, get statistics and +fine-tune scores. It is already installed and enabled by default and expects HTTP (not HTTPS!) requests on port 11334 on +the localhost interface. I suggest you add a simple proxy configuration to your already working HTTPS-enabled web mail +configuration to get access.

+

rspamd dashboard

+

You can either create a new virtual host configuration or just edit the +/etc/apache2/sites-enabled/000-default-le-ssl.conf file. Anywhere within the VirtualHost tags add:

+
<Location /rspamd>
Require all granted
</Location>
+
RewriteEngine On
RewriteRule ^/rspamd$ /rspamd/ [R,L]
RewriteRule ^/rspamd/(.*) http://localhost:11334/$1 [P,L]
+

You also need to enable Apache’s modules for HTTP proxying and rewriting:

+
Run this on your server
# Enable the required Apache modules
a2enmod proxy_http
a2enmod rewrite
+
# Restart Apache
systemctl restart apache2
+

This piece of configuration will forward any requests to https://webmail.example.org/rspamd to localhost:11334 and +thus give you access to the rspamd web interface.

+

The web interface is password protected. Let’s generate a new access password, hash it and add it to rspamd’s +configuration:

+
Run this on your server
# Generate a random password that is 15 characters long
PW=$(pwgen 15 1)
+
# Create a hash of that password
HASH=$(rspamadm pw -p $PW)
+
# Add the hashed password to rspamd's configuration
echo "password = \"$HASH\"" > /etc/rspamd/local.d/worker-controller.inc
+
# Restart rspamd
systemctl restart rspamd
+
# Show the password
echo "Please note the password for the web interface: $PW"
+

This gives you a password like “sae8thaoTaengeo”. If everything went as expected you should now be able to access the +rspamd web interface at https://mail.example.org/rspamd (of course you will use your own server name here).

+

You may miss the detailed history in the web interface. /etc/rspamd/local.d/redis.conf The content is: servers = +“127.0.0.1”;

\ No newline at end of file diff --git a/dist/ispmail-trixie/database/index.html b/dist/ispmail-trixie/database/index.html new file mode 100644 index 0000000..43fdd37 --- /dev/null +++ b/dist/ispmail-trixie/database/index.html @@ -0,0 +1,303 @@ + Database setup | ISPmail Guide + Skip to content

Database setup

Now it’s time to prepare the MariaDB database that stores the information that controls your mail server. In the process +you will have to enter SQL queries – the language of relational database servers. +You may enter them in a terminal window using the ‘mariadb’ command.

+ + +

This step is simple. Connect to the database using the mariadb command in your shell:

+
Run this on your server
mariadb
+

You should see the MariaDB prompt that allows you to enter further SQL commands:

+
MariaDB [(none)]>
+

To create the new database, send this SQL command:

+
CREATE DATABASE mailserver;
+ +

In this section you will create the basic database called mailserver and two users:

+ + + + + + + + + + + + + + + + + + + + +
UserPermissionsPurpose
mailserverreadUsed by Postfix/Dovecot
mailadminread/writeUsed by you
Used by Roundcube (for password changes)
+ +

Create the database users:

+
grant all privileges on mailserver.* to 'mailadmin'@'localhost' identified by 'MAILADMIN-PASSWORD-HERE';
grant select on mailserver.* to 'mailserver'@'127.0.0.1' identified by 'MAILSERVER-PASSWORD-HERE';
+ + +

By now you have an empty database and two user accounts to access it. Now you need three tables:

+
    +
  • virtual_domains
  • +
  • virtual_aliases
  • +
  • virtual_users
  • +
+

Let’s create the entire database schema in one go:

+ +
USE mailserver;
+
CREATE TABLE IF NOT EXISTS `virtual_domains` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(50) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY (`name`)
);
+
CREATE TABLE IF NOT EXISTS `virtual_aliases` (
`id` int(11) NOT NULL auto_increment,
`domain_id` int(11) NOT NULL,
`source` varchar(100) NOT NULL,
`destination` varchar(100) NOT NULL,
PRIMARY KEY (`id`),
FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE
);
+
CREATE TABLE IF NOT EXISTS `virtual_users` (
`id` int(11) NOT NULL auto_increment,
`domain_id` int(11) NOT NULL,
`email` varchar(100) NOT NULL,
`password` varchar(150) NOT NULL,
`quota` bigint(11) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`),
UNIQUE KEY `email` (`email`),
FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE
);
+ + +

The first table keeps the list of domains that your mail server will be responsible for. Each row in this table +represents a domain.

+
    +
  • id: A unique number identifying each row. It is set automatically.
  • +
  • name: Domain name.
  • +
+ + +

The second table contains information about your users – or rather: your mailboxes. Each mail account requires one row +in this table.

+
    +
  • id: A unique number identifying each row. It is set automatically.
  • +
  • domain_id: A reference to the domain in the virtual_domains table. +So each domain can have many mailboxes.
  • +
  • email: The email address of the mailbox.
  • +
  • password: The hashed password of the mail account. It is prepended by the +password scheme. By default it is +{BLF-CRYPT} also known as bcrypt which is considered very secure. Older ISPmail guides used {SHA256-CRYPT} or +even older crypt schemes. Prepending the password field the hashing algorithm in curly brackets allows you to have +different kinds of hashes. So you can easily migrate your old passwords without locking out users. Users with older +schemes should get a new password if possible to increase security.
  • +
  • quota: The number of bytes that this mailbox can store. You can use this value to limit how much space a mailbox +can take up. The default value is 0 which applies the default quota. This is an optional feature that is discussed +later.
  • +
+ + +

The third table contain optional forwardings from one email address to another – or several other – addresses.

+
    +
  • id: A unique number identifying each row. It is set automatically.
  • +
  • domain_id: References the domain in the virtual_domains table.
  • +
  • source: The alias email address.
  • +
  • destination: The email address where this alias gets forwarded to.
  • +
+ + +

Too much theory so far? I can imagine. Let’s populate the database with an example.org domain, a john@example.org +email account and a forwarding of jack@example.org to john@example.org. We will use that information in the next +chapter to play with.

+

To add that sample data just run these SQL queries:

+ +
REPLACE INTO virtual_domains
(id, name)
VALUES (10,'example.org');
+
REPLACE INTO virtual_users
(id, domain_id, password, email)
VALUES (
1,
10,
'{BLF-CRYPT}$2y$05$.WedBCNZiwxY1CG3aleIleu6lYjup2CIg0BP4M4YCZsO204Czz07W',
'john@example.org');
+
REPLACE INTO virtual_aliases
(id, domain_id, source, destination)
VALUES (
1,
10,
'jack@example.org',
'john@example.org');
+ +

Do you wonder how I got the long cryptic password? I ran…

+
doveadm pw
+

…to create a secure hash of the simple password “summersun”. Once you have installed Dovecot you can try that yourself +but you will get a different output. The reason is that the passwords are +salted. Every time you will get a different hash. That prevents +reverse-engineering the original password.

\ No newline at end of file diff --git a/dist/ispmail-trixie/dns-records/index.html b/dist/ispmail-trixie/dns-records/index.html new file mode 100644 index 0000000..8da71c9 --- /dev/null +++ b/dist/ispmail-trixie/dns-records/index.html @@ -0,0 +1,121 @@ + DNS records | ISPmail Guide + Skip to content

DNS records

Todo list for receiving emails
  1. 1

    DNS records point to your server

  2. 2

    Get a certificate from Let's Encrypt

  3. 3

    Postfix fetches information from MariaDB

  4. 4

    Dovecot fetches information from MariaDB

  5. 5

    Postfix hands over emails to Dovecot

  6. 6

    Dovecot saves the email to disk

+

As shown in the slideshow, you need to have proper DNS records set up. Say that you want to receive emails for the +example.com domain. If some other mail server on the internet wants to send an email to your server, it looks for two +records:

+
    +
  • +

    MX record (example.com)
    +The MX (Mail Exchange) record tells other mail servers where to deliver emails for the domain example.com.
    +Instead of pointing directly to an IP address, it points to a hostname (for example, smtp.example.com).
    +MX records also include a priority value. If multiple mail servers are listed, the one with the lowest priority +number is tried first. Others are used as fallback if the first is unavailable.

    +
  • +
  • +

    A / AAAA record (smtp.example.com)
    +The hostname specified in the MX record (smtp.example.com) must resolve to an IP address so that other mail servers +know how to reach it.

    +
      +
    • An A record maps the hostname to an IPv4 address.
    • +
    • An AAAA record maps the hostname to an IPv6 address.
    • +
    +

    Once resolved, the sending mail server connects to that IP address on TCP port 25, which is the standard port for +email delivery (SMTP).

    +
  • +
+ + +

In zone syntax you would create something like:

+
@ IN MX 10 smtp
smtp IN A 100.64.17.3
smtp IN AAAA fd7a:115c:a1e0::17
+

If possible, also add a PTR record that makes the IP addresses point back to the name smtp.example.com. Other mail +servers may be more likely so flag your sent emails as spam if you do not have a PTR record. Preferable the forward +(A/AAAA) and reverse (PTR) records match.

+
\ No newline at end of file diff --git a/dist/ispmail-trixie/dovecot/index.html b/dist/ispmail-trixie/dovecot/index.html new file mode 100644 index 0000000..e4d8301 --- /dev/null +++ b/dist/ispmail-trixie/dovecot/index.html @@ -0,0 +1,184 @@ + Dovecot | ISPmail Guide + Skip to content

Dovecot

Todo list for receiving emails
  1. 1

    DNS records point to your server

  2. 2

    Get a certificate from Let's Encrypt

  3. 3

    Postfix fetches information from MariaDB

  4. 4

    Dovecot fetches information from MariaDB

  5. 5

    Postfix hands over emails to Dovecot

  6. 6

    Dovecot saves the email to disk

+

In this chapter we will configure Dovecot so that it knows how to deliver incoming emails.

+ +

On your disk all the mailboxes will live in the directory /var/vmail. To separate the mailboxes from the rest of your +system, let’s create a new user and group that will own the mailboxes:

+
Run this on your server
groupadd --system vmail
useradd --system --gid vmail vmail
mkdir -p /var/vmail
chown -R vmail:vmail /var/vmail
chmod u=rwx,g=rx,o= /var/vmail
+ +

The configuration files for Dovecot are found in /etc/dovecot/conf.d. All these files are loaded by Dovecot. This is +done by this magical line at the end of the /etc/dovecot/dovecot.conf file:

+
!include conf.d/*.conf
+

It loads all files in /etc/dovecot/conf.d/ that end in “.conf” in alphanumerical order. Let’s edit a couple of files +for our purpose.

+ +

The /etc/dovecot/conf.d/10-auth.conf file is dealing with authentication. At the end of this file you will find a list +of authentication backends that Dovecot ships with. By default it will use system users (those from /etc/passwd). But +we want to use the MariaDB database backend. Please comment out all include statements:

+
Edit your /etc/dovecot/conf.d/10-auth.conf
#!include auth-system.conf.ext
#!include auth-sql.conf.ext
#!include auth-ldap.conf.ext
#!include auth-passwdfile.conf.ext
#!include auth-checkpassword.conf.ext
#!include auth-static.conf.ext
+

Every line starting with # is disabled. Only lines starting with ! are considered.

+ +

The file at /etc/dovecot/conf.d/10-mail.conf contains many settings regarding mailboxes, like where they are located, +who owns them and what is their layout? Create a new file /etc/dovecot/conf.d/99-ispmail-mail.conf that overrides +these defaults:

+
Run this on your server
cat > /etc/dovecot/conf.d/99-ispmail-mail.conf << EOF
mail_driver = maildir
mail_home = /var/vmail/%{user | domain}/%{user | username}
mail_path = ~/Maildir
mail_uid = vmail
mail_gid = vmail
mail_inbox_path = ~/Maildir/
EOF
+

This looks more sophisticated than with versions of Dovecot before 2.4. What it means:

+
    +
  • mail_driver: Mailboxes are stored in +maildir format.
  • +
  • mail_home: Every mail user gets their own home directory in /var/vmail/DOMAIN/USER. The user variable +contains the email address like john@example.org. The expression user | domain splits off the domain part from +the email address. Similarly user | username takes the part before the @ sign.
  • +
  • mail_path: Within the home directory the actual mailbox will live in a subdirectory called Maildir. The reason +is that we will store other data in the user’s home directory as well that should not conflict with the mailbox +directory.
  • +
  • mail_uid/mail_gid: All mailboxes will be owned be the user and group vmail.
  • +
  • mail_inbox_path: A user’s main inbox consists of the directories cur and new inside the Maildir directory. We +used that schema in previous guides and make sure you can migrate your mailboxes from other mail servers. This +overrides the setting in in 10-mail.conf.
  • +
+ +

This configuration file at /etc/dovecot/conf.d/10-master.conf deals with Dovecot’s services. A service is a part +of Dovecot that listens on a TCP port or a UNIX socket so that other parts of your system can use it. We want Postfix to +use Dovecot for authentication. So we need to change the service auth section:

+
Run this on your server
cat > /etc/dovecot/conf.d/99-ispmail-master.conf << EOF
service auth {
unix_listener /var/spool/postfix/private/dovecot-auth {
mode = 0660
user = postfix
group = postfix
}
}
EOF
+

That way Dovecot will put a communication socket into /var/spool/postfix/private/dovecot-auth. It will allow Postfix +to authenticate your users which is relevant later when we set up relaying.

+ +

Earlier in this guide you created both a key and a certificate file to encrypt the communication with IMAPS and HTTPS +between the users and your mail server. You need to tell Dovecot where to find these files. Also set +ssl=required to prevent +that someone sends their password without encryption. Again we will create a new file 99-ispmail-ssl.conf to override +the defaults.

+ +
Run this on your server
cat > /etc/dovecot/conf.d/99-ispmail-ssl.conf << EOF
ssl = required
ssl_server_cert_file = /etc/letsencrypt/live/mail.example.org/fullchain.pem
ssl_server_key_file = /etc/letsencrypt/live/mail.example.org/privkey.pem
EOF
+ +

There is one setting in the /etc/dovecot/conf.d/20-lmtp.conf that will mess up the recipient’s email address in our +setup: auth_username_format. So let’s override it:

+
Run this on your server
cat > /etc/dovecot/conf.d/99-ispmail-lmtp-username-format.conf << EOF
protocol lmtp {
auth_username_format =
}
EOF
+ +

Let’s tell Dovecot where to find information on an valid users (userdb) and their passwords (passdb). There are +suggestions in the auth-sql.conf.ext file but we will add our own file:

+
Run this on your server
cat > /etc/dovecot/conf.d/99-ispmail-sql.conf << EOF
sql_driver = mysql
+
mysql /var/run/mysqld/mysqld.sock {
user = mailserver
password = 'MAILSERVER-PASSWORD-HERE'
dbname = mailserver
host = 127.0.0.1
}
+
userdb sql {
query = SELECT email as user, \
IF(quota > 0, CONCAT(quota, 'B'), NULL) AS quota_storage_size \
FROM virtual_users WHERE email='%{user}'
iterate_query = SELECT email as user FROM virtual_users
}
+
passdb sql {
query = SELECT password FROM virtual_users where email='%{user}'
}
EOF
+
# fix permissions
chown root:root /etc/dovecot/conf.d/99-ispmail-sql.conf
chmod go= /etc/dovecot/conf.d/99-ispmail-sql.conf
+

That configuration file defines how to get a user’s data from the database. The two lookups are:

+
    +
  • userdb sql: get information on the user; e.g. if the user exists and what the quota is
  • +
  • passdb sql: authenticate the user / validate the password
  • +
+

The quota logic is explained and used later in this guide. Quota is the amount of space that a user can use to store +their emails. If the quota is reached then further incoming emails will get rejected until the user removes mails to +make some space.

+

Dovecot can also read the path to a user’s home directory and the user-ID and group-ID from the database. Our setup has +a fixed schema for the home directory (/var/vmail/DOMAIN/USER) (as defined by mail_home) and the user and group are +always vmail and vmail.

+ +

Later, we will implement server-side automation using Sieve rules. By default, Dovecot exposes two TCP ports to the +internet: 2000 and 4190. Port 2000 is deprecated anyway and can be safely disabled, while port 4190 is the one we will +use. However, unless you have a compelling reason, it is recommended not to make this port publicly accessible. So let +us restrict it to the localhost interface:

+
Run this on your server
cat > /etc/dovecot/conf.d/99-ispmail-managesieve.conf << EOF
service managesieve-login {
# Listen only on localhost
inet_listener sieve {
listen= 127.0.0.1
port = 4190
}
+
# Disable the deprecated listener
inet_listener sieve_deprecated {
port = 0
}
}
EOF
+

(Thanks to Thomas Gauweiler for spotting that.)

+ +

Restart Dovecot from the shell:

+
Run this on your server
systemctl restart dovecot
+

Check your logs:

+
Run this on your server
journalctl -fu dovecot
+

You should see:

+
dovecot[13309]: master: Dovecot v2.4.1-4 (7d8c0e5759) starting up for imap, lmtp, sieve (core dumps disabled)
systemd[1]: Started dovecot.service - Dovecot IMAP/POP3 email server.
+

If you get any error messages please double-check your configuration files.

+ +
\ No newline at end of file diff --git a/dist/ispmail-trixie/going-live/index.html b/dist/ispmail-trixie/going-live/index.html new file mode 100644 index 0000000..81b5b37 --- /dev/null +++ b/dist/ispmail-trixie/going-live/index.html @@ -0,0 +1,99 @@ + Going live | ISPmail Guide + Skip to content

Going live

Before you take your new mail server into production, please replace the dummy database passwords by some actual random +passwords:

+
Run this on your server
# Create two random passwords
PW_MAILADMIN=$(pwgen -s 32 1)
PW_MAILSERVER=$(pwgen -s 32 1)
+
# Replace the dummy passwords
sed -i "s|MAILADMIN-PASSWORD-HERE|$PW_MAILADMIN|g" /etc/roundcube/plugins/password/config.inc.php
+
sed -i "s|MAILSERVER-PASSWORD-HERE|$PW_MAILSERVER|g" \
/etc/dovecot/conf.d/99-ispmail-sql.conf \
/etc/postfix/mariadb-virtual-mailbox-maps.cf \
/etc/postfix/mariadb-virtual-mailbox-domains.cf \
/etc/postfix/mariadb-virtual-alias-maps.cf \
/etc/postfix/mariadb-email2email.cf
+
# Restart the services
systemctl restart postfix dovecot
+
# Update MariaDB user passwords
mariadb <<EOF
ALTER USER 'mailadmin'@'localhost' IDENTIFIED BY '${PW_MAILADMIN}';
ALTER USER 'mailserver'@'127.0.0.1' IDENTIFIED BY '${PW_MAILSERVER}';
FLUSH PRIVILEGES;
EOF
+
# Delete example data
mariadb <<EOF
DELETE FROM virtual_domains where name='example.org';
EOF
+
+
# Print the passwords for us to write down
echo "mailadmin password: $PW_MAILADMIN"
echo "mailserver password: $PW_MAILSERVER"
+

Now you are ready to go live. Congratulations on making it this far. And please drop a comment at the bottom if you want +to proudly report that you have your new server up and running.

\ No newline at end of file diff --git a/dist/ispmail-trixie/imap/index.html b/dist/ispmail-trixie/imap/index.html new file mode 100644 index 0000000..cb6c8d5 --- /dev/null +++ b/dist/ispmail-trixie/imap/index.html @@ -0,0 +1,113 @@ + IMAP | ISPmail Guide + Skip to content

IMAP

Your mail server relies on two primary protocols. We’ve already covered SMTP in detail, which handles the transfer +of emails between servers. The other important protocol is +IMAP – the Internet Message Access Protocol.

+

Email clients such as Thunderbird, Roundcube, mutt or the mail apps on your smartphone use IMAP to retrieve and manage +messages. The good news is that you don’t need to configure anything new on the server — it’s already set up. In fact, +even Roundcube (your webmail application) communicates with the server via IMAP to access emails.

+ +

You may not have heard of mutt before. It’s like the VIM editor but for mails. Very powerful but it only has a +text-based user interface. For testing IMAP on mail servers it’s still a good way because you do not have to set up a +complete account as in Thunderbird.

+

Give it a try – and as usual replace webmail.example.org by your mail server’s host name:

+
Run this on your server
mutt -f imaps://john@example.org@webmail.example.org
+

The connection URL may look a little confusing because of the two “@” characters. Usually mutt expects the format +imaps://user@server. The user is john@example.org on your server so you get this syntax.

+

You should get prompted for the password which we set to summersun. If you get any certificate warnings then check if +you used the correct server name. If the authentication has succeeded, you will see John’s inbox:

+

Mutt showing an email in the inbox

+

These are test emails that you sent earlier using swaks. You open an email by pressing Enter and get back using q. +Mainly we wanted to check that IMAP access works.

+ +

Mutt can not only speak IMAP – it can access an inbox (or maildir) on your disk directly as well:

+
Run this on your server
mutt -f /var/vmail/example.org/john/Maildir/
+

That way you will not be forced to authenticate as you are working with the file system.

+ +

A typical account setup in Thunderbird looks like:

+

Thunderbird account setup

\ No newline at end of file diff --git a/dist/ispmail-trixie/index.html b/dist/ispmail-trixie/index.html new file mode 100644 index 0000000..b8e7705 --- /dev/null +++ b/dist/ispmail-trixie/index.html @@ -0,0 +1,164 @@ + Start here | ISPmail Guide + Skip to content

Start here

Good to have you here. This is the 12th edition of the ISPmail guide. A free guide to setting up a mail server for +friends and family using open-source software. Email on the internet nowadays is in the hands of few huge companies. +Take back control and host your own mail server. Get a cheap virtual server and read along. This guide is comprehensive +and will walk you through everything you need to know. I am publishing this guide without any commercial motives. All +you need to invest is your time. And thanks to Debian you will get automatic security updates and do not have to worry +about anything until the next stable release comes out in 2-3 years. And perhaps you come back then to upgrade your +server.

+ +
    +
  • Receive emails on (multiple) domains.
  • +
  • Filter out spam.
  • +
  • Send emails out to the internet. Connections will be encrypted when possible.
  • +
  • Store as many emails for as many email addresses as you have disk space. Set limits (“quotas”) per user. The only +limit is the size of your disk.
  • +
  • Have a webmail interface so users can access their emails securely from any location using a web browser.
  • +
  • Let your users fetch email using IMAP and send email through your servers using SMTP.
  • +
  • Add automatic cryptographic signatures using DKIM to outgoing emails to prove that you are the owner of your +domain.
  • +
  • Allow users to manage server-based filter rules. Distribute incoming emails to different folders. Forward copies. +Or send out-of-office notifications.
  • +
  • Mitigate brute force attacks.
  • +
+ +
    +
  • Linux experience. Preferably a Debian-derivative. No godlike skills required. But know your basics: navigating the +file system, editing files, watching log files. Have some basic understanding of DNS. Bonus points if you have played +with an SQL database and know about SELECT, INSERT, rows, columns.
  • +
  • Time. 2 hours to get the basic service running. Maybe a day if you are not an everyday Debian user.
  • +
  • server that runs Debian Trixie. 1 GB of RAM and a 20 GB disk/SSD is +fine for your friends and family. Just rent a cheap virtual server. Other distributions than Debian come with other +versions of the software and have different configurations and paths on disk. It will work but you will need to +deviate from this guide and do some research. So for the smoothest ride go with Debian.
  • +
  • The hosting provider you chose to run your server on needs to allow SMTP send and receive. These providers are +known to be troublesome: +
      +
    • Hetzner (DE, FI, US): Will allow SMTP after a month of paying for their service and per a request issued at +https://console.hetzner.cloud/limits
    • +
    • DigitalOcean (US): Blocks SMTP and tells you that running your own mail server is a bad idea. Avoid.
    • +
    +
  • +
  • Your server needs to have a public IP address that does not belong to a range of typical ISP customers. You +usually can’t operate the mail server from a residential IP address at home because those IP ranges are blacklisted by +most other mail servers. Make sure that your IP address is not blacklisted before you +start. If you rent a virtual server from your favorite hosting company you probably won’t have any problems. But if +you want to run the service from your home, this is something you need to check.
  • +
  • An internet domain (or several) to receive emails for. You need to be able to set A, MX and TXT records for that +domain. You should also be able to set PTR records for your IP address because some mail servers on the internet +require you to have matching forward and reverse DNS records.
  • +
  • Patience. We will proceed slowly and after every step ensure that you are still on track. Don’t hurry and skip +parts even if they appear confusing at first. If you get lost just submit your question at the bottom of any page +throughout this guide and help is on the way. Or join the +chat channel.
  • +
+ +

If you just want to have a working mail server and do not care how it works then this guide may not be for you. There is +an automated installation script that does all the steps of this guide +automatically for you. But that is no replacement for reading this guide and understanding how the server works. It is +merely meant to help you save time if you want to set up multiple servers.

+

Be aware that running a mail server requires some technical understanding. And that’s what the ISPmail guide is for. +Experience from giving support to other sysadmins shows that most problems appear because some detail in a complex setup +goes wrong and they have no idea how to fix it. Email has evolved a lot over the past 40 years. Go with ready solutions +if you like. But I have a feeling that we meet again. And you will probably not save time either taking the supposedly +easy route.

+

There are also other projects that give you a ready solution like mailinabox, +iRedMail or Mailcow.

+ +

The last updates to this guide – up to Debian Bookworm – were mainly minor changes. However this time I have spent many +weeks to improve the guide. Most sections are completely rewritten. Explanations about SMTP versus submission were +added. I dived deep into RFCs and reference documentation. I have used more features of the +Astro/Starlight framework (the software that is used to render this guide) to add +visual guides like task lists or image galleries or foldout sections to help you understand what’s going on on a mail +server without getting lost. And I have replaced all my configuration examples with blocks that you can copy/paste into +your shell. So this guide is supposed to be shorter and faster to follow while at the same time trying to be more +comprehensive. Please leave your feedback in the comment sections whether this approach appeals to you.

+ +

The entire tutorial is split into several pages. You can find the different chapters on the left. The navigation within +a chapter can be found on the right. Let’s go.

\ No newline at end of file diff --git a/dist/ispmail-trixie/install-debian/index.html b/dist/ispmail-trixie/install-debian/index.html new file mode 100644 index 0000000..7f0102b --- /dev/null +++ b/dist/ispmail-trixie/install-debian/index.html @@ -0,0 +1,104 @@ + Installing Debian | ISPmail Guide + Skip to content

Installing Debian

+

You have a blank computer or virtual machine? Then simply install Debian Trixie yourself. Get a boot medium from the +Debian website. The smaller network installer is sufficient – it will +download all required packages directly from the internet. Make sure you choose ‘English’ as the installation language +even if it is not your native language. If you have trouble with the server you will more likely find help when +searching for English error messages on the internet.

+

Most of the installation is pretty straightforward. You don’t need me holding your hand. However I strongly recommend +that you use the logical volume manager (LVM) for your partitions to stay flexible if your server grows. See my +article on LVM if you want some help understanding its concept.

+ +

These are the relevant paths and the minimum amount of space I would suggest. If you use LVM, enlarging partitions later +is very simple.

+
  • Directory/ (operating system – 5 GB) +
    • Directoryvar/ +
      • Directoryvmail/ (actual emails will be stored here – 10 GB)
      • Directorylog/ +
        • Directoryjournal/ (systemd saves logs here – 5 GB)
    • Directorytmp/ (temporary storage – 1 GB)
\ No newline at end of file diff --git a/dist/ispmail-trixie/install-the-software-packages/index.html b/dist/ispmail-trixie/install-the-software-packages/index.html new file mode 100644 index 0000000..430a704 --- /dev/null +++ b/dist/ispmail-trixie/install-the-software-packages/index.html @@ -0,0 +1,138 @@ + Install software packages | ISPmail Guide + Skip to content

Install software packages

Let’s install the necessary Debian packages. Run this command as root on your server as root:

+
Run this on your server
apt update
DEBIAN_FRONTEND=noninteractive \
apt -y install postfix-mysql dovecot-mysql \
dovecot-imapd dovecot-lmtpd dovecot-managesieved \
apache2 python3-certbot-apache libapache2-mod-php \
php-intl php-mbstring php-xml unzip certbot \
roundcube-mysql roundcube roundcube-plugins swaks libnet-ssleay-perl \
mutt unattended-upgrades mariadb-server \
rspamd redis-server opendkim-tools bind9-dnsutils pwgen
+

While the server is downloading and installing the packages, let me give you a quick explanation of each package:

+
    +
  • postfix / postfix-mysql
    +Postfix is the MTA (mail transport agent) that speaks SMTP to send and receive emails. This package installs Postfix +with support for MariaDB databases.
  • +
  • dovecot
    +Dovecot manages the emails on disk and lets users access them via IMAP. +
      +
    • -lmtpd
      +LMTP (Local Mail Transfer Protocol) provides the glue between Postfix and Dovecot.
    • +
    • -managesieved
      +Lets you configure automatic processing rules on the server. Like out-of-office emails or filtering incoming emails +to folders.
    • +
    • -mysql
      +Makes Dovecot able to query MariaDB databases.
    • +
    +
  • +
  • apache
    +Web server. Needed for webmail.
  • +
  • php-*
    +PHP is the programming language that Roundcube (the webmail software) is written in.
  • +
  • mariadb-server
    +Database server that helps us store control data in a MariaDB database on the mail server.
  • +
  • roundcube / roundcube-mysql
    +Webmail software that lets you access your emails in any web browser. Roundcube speaks to Dovecot to fetch emails. And +to Postfix to send emails.
  • +
  • swaks / libnet-ssleay-perl
    +The SWiss Army Knife of Smtp. Helpful command-line tool to send test emails to a mail server. The additional SSL +package is needed to test encrypted connections.
  • +
  • certbot
    +Gets a free TLS certificate from Let’s Encrypt for encrypting network communication.
  • +
  • mutt
    +A console-based program that can speak IMAP and also read Maildirs directly. Very helpful for testing the +functionality of your mail server. Think of it as a text-based Thunderbird.
  • +
  • unattended-upgrades
    +Installs security updates automatically.
  • +
  • rspamd
    +It reliably detects and blocks spam. Also handles adding DKIM signature to outgoing email to prevent spoofing your +domains.
  • +
  • redis-server
    +Rspamd requires a Redis server as its storage of learned spam +emails.
  • +
  • opendkim-tools
    +Not strictly necessary. But a nice tool to verify DKIM signatures. You know, for science.
  • +
  • bind9-dnsutils
    +Provides the infamous dig command for an easy way to do DNS lookups.
  • +
  • pwgen
    +A password generator.
  • +
\ No newline at end of file diff --git a/dist/ispmail-trixie/lmtp/index.html b/dist/ispmail-trixie/lmtp/index.html new file mode 100644 index 0000000..a191655 --- /dev/null +++ b/dist/ispmail-trixie/lmtp/index.html @@ -0,0 +1,142 @@ + LMTP | ISPmail Guide + Skip to content

LMTP

Todo list for receiving emails
  1. 1

    DNS records point to your server

  2. 2

    Get a certificate from Let's Encrypt

  3. 3

    Postfix fetches information from MariaDB

  4. 4

    Dovecot fetches information from MariaDB

  5. 5

    Postfix hands over emails to Dovecot

  6. 6

    Dovecot saves the email to disk

+

Glad to see that you are still with me. We are very close to receiving our first email. If you feel lost, please review +the slideshow from earlier in this guide.

+

As explained in the previous section, Postfix speaks SMTP and receives the email from the internet. Postfix could even +save the email to a mailbox on disk. But instead we will use Dovecot for the final delivery. Actually Dovecot’s main +purpose is to let users fetch their email using the IMAP protocol. But it provides additional features we can use as +well.

+

So we need tell Postfix to hand over the incoming email to Dovecot. The communication between Postfix and Dovecot will +happens using LMTP – the local mail transfer protocol. +LMTP is a lightweight variant of SMTP. It is meant for email communication between internal services that trust each +other.

+ +

First we need to add a UNIX socket where Dovecot listens for incoming LMTP connections:

+
Run this on your server
# Add an LMTP listening socket in Dovecot
cat > /etc/dovecot/conf.d/99-ispmail-lmtp-listener.conf << EOF
service lmtp {
# Used internally by Dovecot
unix_listener lmtp {
}
+
# Listen to LMTP connections from Postfix
unix_listener /var/spool/postfix/private/dovecot-lmtp {
mode = 0600
user = postfix
group = postfix
}
}
EOF
+
# Restart Dovecot
systemctl restart dovecot
+

The first unix_listener lmtp is just used internally by Dovecot and does not concern us. The second part is what you +will be adding. It makes Dovecot create a socket file at /var/spool/postfix/private/dovecot-lmtp. As Postfix has its +home in /var/spool/postfix it can access that socket to speak LMTP with Dovecot.

+

A socket is similar to a TCP port but it’s only available for other processes running on same system. That’s why you +also set the access mode, user and group so that Postfix can actually use it.

+ +

The “virtual_transport” in Postfix defines the service to use for delivering emails to the local system. Dovecot has +created a socket file and is ready to listen to incoming LMTP connections. We just need to tell Postfix to send emails +there. So please run:

+
Run this on your server
postconf virtual_transport=lmtp:unix:private/dovecot-lmtp
+

The syntax looks crazy, but it’s actually simple. You just told Postfix to use the LMTP protocol. And that we want to +use a UNIX socket on the same system (instead of a TCP connection). And the socket file is located at +/var/spool/postfix/private/dovecot-lmtp – because /var/spool/postfix is the Postfix’s home directory.

+ +
Todo list for receiving emails
  1. 1

    DNS records point to your server

  2. 2

    Get a certificate from Let's Encrypt

  3. 3

    Postfix fetches information from MariaDB

  4. 4

    Dovecot fetches information from MariaDB

  5. 5

    Postfix hands over emails to Dovecot

  6. 6

    Dovecot saves the email to disk

+

Finally we are ready for our first email. Using the swaks command you can create a test email to john@example.org +and send it to Postfix:

+
Run this on your server
swaks --server localhost --to john@example.org
+

If all goes as planned, you will see an SMTP dialog like this:

+
=== Trying localhost:25...
=== Connected to localhost.
<- 220 mail ESMTP Postfix (Debian)
-> EHLO mail
<- 250-mail
<- 250-PIPELINING
<- 250-SIZE 10240000
<- 250-VRFY
<- 250-ETRN
<- 250-STARTTLS
<- 250-ENHANCEDSTATUSCODES
<- 250-8BITMIME
<- 250-DSN
<- 250-SMTPUTF8
<- 250 CHUNKING
-> MAIL FROM:<root@mail>
<- 250 2.1.0 Ok
-> RCPT TO:<john@example.org>
<- 250 2.1.5 Ok
-> DATA
<- 354 End data with <CR><LF>.<CR><LF>
-> Date: Sun, 24 Aug 2025 21:08:59 +0000
-> To: john@example.org
-> From: root@mail
-> Subject: test Sun, 24 Aug 2025 21:08:59 +0000
-> Message-Id: <20250824210859.021444@mail>
-> X-Mailer: swaks v20240103.0 jetmore.org/john/code/swaks/
->
-> This is a test mailing
->
->
-> .
<- 250 2.0.0 Ok: queued as 2742B221FA
-> QUIT
<- 221 2.0.0 Bye
=== Connection closed with remote host.
+

If you see a `250 2.0.0 Ok: queued as…” near the end of this dialog, then Postfix has received the email successfully.

+

Check if Postfix managed to pass the email to Dovecot:

+
Run this on your server
journalctl -n 10 -u dovecot
+

The line you are looking for looks like:

+
Aug 24 21:36:22 mail dovecot[23214]: lmtp(john@example.org)<…><…>: msgid=<20250824213622.023221@mail>: saved mail to INBOX
+

Does it say saved mail to INBOX? Awesome. The email should be visible in John’s home directory. Check it:

+
Run this on your server
find /var/vmail/example.org/john
+

Does it look like this?

+
/var/vmail/
/var/vmail/example.org
/var/vmail/example.org/john
/var/vmail/example.org/john/Maildir
/var/vmail/example.org/john/Maildir/maildirfolder
/var/vmail/example.org/john/Maildir/new
/var/vmail/example.org/john/Maildir/new/1756071382.M198387P23222.mail,S=635,W=655
/var/vmail/example.org/john/Maildir/cur
/var/vmail/example.org/john/Maildir/tmp
/var/vmail/example.org/john/Maildir/dovecot-uidvalidity.68ab85d6
/var/vmail/example.org/john/Maildir/dovecot.index.log
/var/vmail/example.org/john/Maildir/dovecot-uidvalidity
/var/vmail/example.org/john/Maildir/dovecot.index.cache
/var/vmail/example.org/john/Maildir/dovecot-uidlist
/var/vmail/example.org/john/Maildir/dovecot.list.index.log
+

The important file here is …/Maildir/new/1756071382.M198387P23222.mail,S=635,W=655. The numbers will look differently +on your system. But this is the actual mail that got delivered. You can view it with cat and will find the test email +you just sent using swaks.

+

Don’t worry about the other files like maildirfolder or the files that sound like dovecot…. Those help Dovecot keep +track of the mailbox. You can safely ignore them.

+ +

Obviously the previous examples dealt with the example.org domain which is not your actual domain. Feel free to add +your own domain to the database and create a test user. The later +section on managing users will explain that in detail.

\ No newline at end of file diff --git a/dist/ispmail-trixie/managing-users-aliases-and-domains/index.html b/dist/ispmail-trixie/managing-users-aliases-and-domains/index.html new file mode 100644 index 0000000..6abd669 --- /dev/null +++ b/dist/ispmail-trixie/managing-users-aliases-and-domains/index.html @@ -0,0 +1,146 @@ + Managing users, aliases and domains | ISPmail Guide + Skip to content

Managing users, aliases and domains

Maybe you already know what you have to do to create mail domains and mail users. After all I tried to explain the +database schema in the section that dealt with preparing the database. But if that wasn’t clear enough let me explain +what you need to do to manage your mail accounts.

+ +

The following sections explain the changes and SQL queries you can use for common management tasks:

+ +

Insert a new row into the virtual_domains table and set the name to the name of the new domain. (Do not forget to set +up SPF and DKIM.)

+
INSERT INTO virtual_domains (name) VALUES ("example.org");
+ +

Delete the row from the virtual_domains table that has the right name. All aliases and users will automatically be +deleted, too. However the mailboxes will stay on disk at /var/vmail/… and you need to delete them manually.

+
DELETE FROM virtual_domains where name='example.org';
+ +

Find out the id of the right domain from the virtual_domains table. The insert a new row into the virtual_users table. +Set the domain_id to the value you just looked up in the virtual_domains table. Set the email field to the complete +email address of the new user. Create a new password in a shell using the dovecot pw command and insert the result +into the password field.

+
INSERT INTO virtual_users
(domain_id, email, password)
VALUES
((SELECT id FROM virtual_domains WHERE name='example.org'), 'john@example.org','{CRYPT}$2y$05$.We…');
+ +

Find the row in the virtual_users table by looking for the right email field. Create a new password in a shell using +the dovecot pw command and insert the result into the password field.

+
UPDATE virtual_users SET password='{CRYPT}$2y$05$.We…' WHERE email='email@address';
+ +

Find the row in the virtual_users table by looking for the right email field and delete it. The mailbox will stay on +disk at /var/vmail/… and you need to delete it manually

+
DELETE FROM virtual_users WHERE email='john@example.org';
+ +

You can forward emails from one (source) email to other addresses (destinations) – even outside of your mail +server. Find out the id of the right domain (the part after the @ of the source email address) from the +virtual_domains table. Create a new row in the virtual_aliases table for each destination (if you have multiple +destination addresses). Set the source field to the complete source email address. And set the destination field to +the respective complete destination email address.

+
INSERT INTO virtual_aliases
(domain_id, source, destination)
VALUES
(
(SELECT id FROM virtual_domains WHERE name='example.org'),
'melissa@example.org',
'juila@example.net'
);
+ +

Find all rows in the virtual_aliases table by looking for the right source email address. Remove all rows that you +lead to destination addresses you don’t want to forward email to.

+
DELETE FROM virtual_aliases WHERE source='melissa@example.org';
+ +

If you don’t like using SQL queries to manage your mail server you may like to install a web-based management software. +Several developers contributed web interfaces for earlier versions of this guide and they will probably still work +because the database schema has not changed. Your experience with these projects, or links to further projects, is very +welcome in the comments.

+ +

Homepage: http://ima.jungclaussen.com/
+Demo: http://ima.jungclaussen.com/demo/

+

ISPmail Admin screenshot

+ +

Christian G. has created a text-based program to help you manage your mail accounts. You may like it if you just want a +little help adding accounts and setting passwords but not provide a full blown web interface.

+

You can find his Python script at Github.

+ +

You can also use a basic tool like Adminer to manage the tables if you don’t want to type +out SQL. To set it up:

+
Run this on your server
apt install -y adminer
a2enconf adminer
systemctl reload apache2
+

Now Adminer is available as https://mailserver.example.org/adminer and allows you to login:

+

Adminer login screen

+

After login this is how the interface looks like:

+

Adminer main screen

\ No newline at end of file diff --git a/dist/ispmail-trixie/overview/index.html b/dist/ispmail-trixie/overview/index.html new file mode 100644 index 0000000..71bbcc0 --- /dev/null +++ b/dist/ispmail-trixie/overview/index.html @@ -0,0 +1,92 @@ + Big picture | ISPmail Guide + Skip to content

Big picture

I have created a slideshow to help you understand the process of receiving an email from a remote mail server. Hopefully +it helps to get a better understanding of the steps involved in receiving email. We will prepare the necessary +configuration in the next chapters.

+

Use the arrows to navigate between slides:

+
  • Slide 1
  • Slide 2
  • Slide 3
  • Slide 4
  • Slide 5
  • Slide 6
  • Slide 7
  • Slide 8
  • Slide 9
  • Slide 10
  • Slide 11
  • Slide 12
  • Slide 13
  • Slide 14
  • Slide 15
  • Slide 16
  • Slide 17
  • Slide 18
  • Slide 19
  • Slide 20
  • Slide 21
  • Slide 22
  • Slide 23
  • Slide 24
\ No newline at end of file diff --git a/dist/ispmail-trixie/postfix/index.html b/dist/ispmail-trixie/postfix/index.html new file mode 100644 index 0000000..551cc39 --- /dev/null +++ b/dist/ispmail-trixie/postfix/index.html @@ -0,0 +1,153 @@ + Postfix | ISPmail Guide + Skip to content

Postfix

Todo list for receiving emails
  1. 1

    DNS records point to your server

  2. 2

    Get a certificate from Let's Encrypt

  3. 3

    Postfix fetches information from MariaDB

  4. 4

    Dovecot fetches information from MariaDB

  5. 5

    Postfix hands over emails to Dovecot

  6. 6

    Dovecot saves the email to disk

+

Now that other mail servers can locate your mail server, the next step is to make sure it can receive and process +incoming emails. This task is handled by Postfix, which communicates using the SMTP protocol.

+

Postfix knows if an email address is valid by checking for…

+
    +
  • Virtual Domains (am I responsible for this domain?)
  • +
  • Virtual Aliases (do I have to redirect this address to another address?)
  • +
  • Virtual Mailboxes (do I have a valid mailbox to store the email to?)
  • +
+ +

There are different ways for Postfix to get that information. From text files, LDAP, MongoDB or PostgreSQL. Or via +MariaDB – which is what we will use. But whatever kind of data source you configure, Postfix needs the information as a +mapping. Consider it as a question and an answer.

+
    +
  • Question: is example.org one of our virtual domains?
  • +
  • Answer: yes
  • +
+

If the information is not available you just get no answer:

+
    +
  • Question: is example.net one of our virtual domains?
  • +
  • Answer: (no answer)
  • +
+

In SQL language Postfix has to ask MariaDB the question:

+
SELECT "yes" FROM virtual_domains WHERE name='example.net';
+

Run the following code in your shell to create a configuration file creating that mapping:

+
Run this on your server
cat > /etc/postfix/mariadb-virtual-mailbox-domains.cf << EOF
user = mailserver
password = MAILSERVER-PASSWORD-HERE
hosts = 127.0.0.1
dbname = mailserver
query = SELECT 1 FROM virtual_domains WHERE name='%s'
EOF
+

This has created a configuration file called /etc/postfix/virtual-mailbox-domains.cf. The user, password, hosts +and dbname definitions tell Postfix how to connect to the database. And the query asks the question if a certain +domain is present in the database table virtual_domains. Using SELECT 1 we return just the number 1 if such an entry +was found. In fact it does not matter what we return. Any answer is fine.

+ +

Now let’s deal with aliases. As shown earlier an alias redirects an email to another email address. So the question +and answer game goes like this:

+
    +
  • Question: is there an alias for jack@example.org?
  • +
  • Answer: john@example.org
  • +
+

Postfix would then check if there are further aliases:

+
    +
  • Question: is there an alias for john@example.org?
  • +
  • Answer: (no answer)
  • +
+

Apparently, there aren’t any more. So the email will go to john@example.org.

+

Run this code to create the appropriate mapping file:

+
Run this on your server
cat > /etc/postfix/mariadb-virtual-alias-maps.cf << EOF
user = mailserver
password = MAILSERVER-PASSWORD-HERE
hosts = 127.0.0.1
dbname = mailserver
query = SELECT destination FROM virtual_aliases WHERE source='%s'
EOF
+

The query now gets all the destination email addresses from the database for a certain source email address.

+ +

The last mapping we need is a query to find valid mailboxes. Without further ado:

+
Run this on your server
cat > /etc/postfix/mariadb-virtual-mailbox-maps.cf << EOF
user = mailserver
password = MAILSERVER-PASSWORD-HERE
hosts = 127.0.0.1
dbname = mailserver
query = SELECT 1 FROM virtual_users WHERE email='%s'
EOF
+

Just the same story as with virtual domains. The database returns 1 if there is a virtual_users record matching that +specific email address.

+

Actually the answer is usually not 1 but the path to the mailbox on disk. But that applies only if Postfix would be +saving the email to disk on its own. In our setup the email will be passed on to Dovecot in a later step. Dovecot will +then handle the files on disk. Postfix just has to know is whether a mailbox exists. And that’s why any answer is +sufficient here.

+ +

You have created the config files for the three mappings. Now you just need to tell Postfix to use them:

+
Run this on your server
postconf virtual_mailbox_domains=mysql:/etc/postfix/mariadb-virtual-mailbox-domains.cf
postconf virtual_mailbox_maps=mysql:/etc/postfix/mariadb-virtual-mailbox-maps.cf
postconf virtual_alias_maps=mysql:/etc/postfix/mariadb-virtual-alias-maps.cf
+
chown root:postfix /etc/postfix/mariadb-*.cf
chmod o= /etc/postfix/mariadb-*.cf
+

postconf is a command that changes configuration in /etc/postfix/main.cf and applies them instantly. You don’t have +to restart Postfix.

+

The last two lines set the owner of the config files (user=root, group=postfix) and make sure that others have no +access. After all a database password is found in these files.

+
\ No newline at end of file diff --git a/dist/ispmail-trixie/quotas/index.html b/dist/ispmail-trixie/quotas/index.html new file mode 100644 index 0000000..0660887 --- /dev/null +++ b/dist/ispmail-trixie/quotas/index.html @@ -0,0 +1,195 @@ + Quotas | ISPmail Guide + Skip to content

Quotas

+ +

Quotas are size limits for users. You can make sure that users do not waste arbitrary amounts of disk space but are +forced to clean up old emails every now and then.

+

The magic happens in two places:

+
    +
  1. Dovecot needs to keep track of the quota and how much the user has already used up of it.
  2. +
  3. Postfix needs to reject new emails if the user’s mailbox is over quota.
  4. +
+ + +

As usual we need a new piece of configuration to enable the quota plugin and define how we want it to behave:

+
Run this on your server
cat > /etc/dovecot/conf.d/99-ispmail-quota.conf << 'EOF'
# Enable the quota plugin
mail_plugins {
quota = yes
}
+
# Set global defaults. Keep this outside of a "quota {}" section so that it
# can be overriden with data from the virtual_users table.
# Allow 5 GB of space per default.
quota_storage_size = 5G
+
# It is important to allow it so that Postfix can deliver an email to
# bring the user above 100% of quota usage. Otherwise you risk that the user
# is at 99.99% of quota but the last email cannot be delivered and gets stuck
# between Postfix and Dovecot. No email should be larger than this.
quota_storage_grace = 50M
+
# Define two warnings at 80% and 95% of quota usage.
quota "User quota" {
# Set one warning level to 100%
warning warn-100 {
quota_storage_percentage = 100
execute quota-warning {
args = 100 %{user}
}
}
+
# Set another warning level to 80% for early warnings
warning warn-80 {
quota_storage_percentage = 80
execute quota-warning {
args = 80 %{user}
}
}
+
# User is no longer over quota
warning warn-under {
quota_storage_percentage = 100
threshold = under
execute quota-warning {
args = below %{user}
}
}
}
+
# Define what happens if the user goes over quota. Point to a script that
# creates a warning email to the user. The name "quota-warning" corresponds
# to the "execute" statement in the warning definitions.
service quota-warning {
executable = script /usr/local/bin/ispmail-quota-warning.sh
unix_listener quota-warning {
mode = 0660
user = vmail
group = vmail
}
}
+
# Add a new service so that Postfix can check if a user is over quota.
# It listens on TCP port 13373.
service quota-status {
executable = quota-status -p postfix
inet_listener quota-status {
listen = 127.0.0.1
port = 13373
}
client_limit = 1
}
+
# Enable the IMAP QUOTA extension, allowing IMAP clients to ask for the
# current quota usage. Roundcube displays the current space usage in
# the lower left corner.
protocol imap {
mail_plugins {
imap_quota = yes
}
}
EOF
+
# Apply the configuration
systemctl reload dovecot
+

The script that is launched by the quota-warning service is pretty simple. It sends an email to the affected user. It +uses the special way of dovecot-lda -o quota_enforce=no though so that the warning email itself is always delivered +even if the user is over quota.

+
Run this on your server
cat > /usr/local/bin/ispmail-quota-warning.sh << 'EOF'
#!/bin/bash
#
# This script is part of the ISPmail configuration.
# It is called from /etc/dovecot/conf.d/99-ispmail-quota.conf
# and sends an email to the user if the quota is at 80%, over 100%
# or back below 100%.
#
# Christoph Haas <ispmail@christoph-haas.de>
# Version 1.0 – 2025-12-30
+
LEVEL=$1
USER=$2
MAIL="From: postmaster@${USER#*@}"
MAIL+="\nSubject: Quota information"
MAIL+="\nX-Priority: 1"
MAIL+="\n\nThis is an automatic email from your friendly mail server.\n\n"
+
if [ $LEVEL = "below" ]; then
MAIL+="Thanks for making some space. You will now be able to receive emails again."
elif [ $LEVEL -eq 80 ]; then
MAIL+="Your mailbox is currently using up 80% of the maximum space."
MAIL+="\nPlease consider deleting some emails. If your used space reached"
MAIL+="\n100% then you would not be able to receive further emails. I will"
MAIL+="\nhowever send you another email in that case."
MAIL+="\n"
MAIL+="\nThanks for your attention."
elif [ $LEVEL -eq 100 ]; then
MAIL+="I am afraid to tell you that your mailbox is now 100% full."
MAIL+="\nNew emails to your address will be rejected by the server."
MAIL+="\nPlease delete some emails immediately. I will send you another"
MAIL+="\nemail once you have made some space."
MAIL+="\n"
MAIL+="\nThanks for your attention."
fi
+
echo -e $MAIL | /usr/lib/dovecot/dovecot-lda -d $USER -o quota_enforce=no
EOF
+
chmod u=rwx,g=rx,o= /usr/local/bin/ispmail-quota-warning.sh
chown vmail:vmail /usr/local/bin/ispmail-quota-warning.sh
+ +

By default you will probably allow all users to use a certain amount of disk space for their emails. That would be the +global value that you set using quota_storage_size = ….

+

But maybe you have some special users that need a different value. For a power user you could allow more space than for +other users. Then set the quota field in his record in the virtual_users table to a value larger than 0.

+

So the logic for the quota field in the database is:

+
    +
  • 0 means: take the global setting of quota_storage_size
  • +
  • anything else: override by this value (in bytes)
  • +
+

We added that logic into the userdb sql section earlier:

+
IF(quota > 0, CONCAT(quota, 'B'), NULL) AS quota_storage_size
+

That’s the SQL way of saying: if “quota” is 0, then return NULL. NULL tells Dovecot to fall back to the global value. +Otherwise add a “B” (for “bytes” – Dovecot requires that) and return that.

+ +

Now that quota restrictions are in place, you can ask Dovecot for the current status of all mailboxes:

+
Run this on your server
doveadm quota get -A
+

You will get output like this:

+
Username Quota name Type Value Limit %
john@example.org User quota STORAGE 22856 1048576 2
john@example.org User quota MESSAGE 19 - 0
+

John is shown twice because Dovecot keeps track of:

+
    +
  • the amount of storage John uses (STORAGE)
  • +
  • the number of emails that John has (MESSAGE)
  • +
+

The current configuration just cares about the space that is used on disk. So in the above example he has 22,856 KB used +of the 1 GB limit – which is 2%. And he has a total of 19 messages but there is no limit to that.

+ +

You may wonder why there is a quota-status service. If a user is over quota then it would reject an more incoming +emails. But Postfix – which sits in front front of Dovecot – would still happily accept more emails. For a sender on a +remote server it looks like the email was delivered. But it’s now stuck between Postfix and Dovecot until the user makes +some space.

+

The obvious solution: Postfix needs to know if a user is over quota so that it can reject further emails. That’s the +purpose of the quota-status service which is now listening on TCP port 13373 (on the local interface) for such +queries. The protocol is very simple and you can even play with it as a human:

+
Terminal window
echo -e "recipient=john@example.org\n" | nc localhost 13373
+

And the service will respond with:

+
action=OK
+

The response tells you whether the user is over quota:

+
    +
  • action=OK or
  • +
  • action=554 5.2.2 Quota exceeded (mailbox for user is full)
  • +
+ +

Telling Postfix to use the quota-status service is suprisingly simple:

+
Run this on your server
postconf smtpd_recipient_restrictions="check_policy_service inet:localhost:13373"
+
+ +

If you are curious to see this working, then set John’s mailbox quota to 5 KB:

+
# mariadb mailserver
mysql> update virtual_users set quota=5120 where email='john@example.org';
+

Verify that he now has a limit of 5 KB:

+
Terminal window
doveadm quota get -u john@example.org
+

Send him a few emails using the ‘swaks’ tool:

+
swaks --server localhost --to john@example.org -tls
+

After a few emails you will see the rejection message:

+
-> RCPT TO:john@example.org
<** 452 4.2.2 john@example.org: Recipient address rejected: Mailbox is full and cannot receive any more emails
+ +

These are things you should consider if quotas do not seem to work properly:

+
    +
  • Check that your /etc/dovecot/conf.d/99-ispmail-sql.conf file looks as +described. Earlier version of this Trixie guide did not contain the +quota_storage_size field in the userdb sql query.
  • +
  • Run tcpdump -Ai lo port 13373 on the server to see if Postfix talks to the quota-status service.
  • +
  • Your users may complain that they have deleted many emails but are still over quota. Let them check if they actually +emptied the Trash folder. Of course emails in that folder also contribute to the disk space usage. Once the Trash +folder is expunged the problem should be gone. You may also allow your users more space in the Trash folder. That’s +explained in the Dovecot documentation.
  • +
  • If you directly remove files from a user’s Maildir instead of properly accessing the mailbox using IMAP then you will +screw up the quota calculation. In that case let Dovecot recalculate the quota:
    +doveadm quota recalc -u john@example.org
  • +
+ +
\ No newline at end of file diff --git a/dist/ispmail-trixie/relaying/index.html b/dist/ispmail-trixie/relaying/index.html new file mode 100644 index 0000000..ccada23 --- /dev/null +++ b/dist/ispmail-trixie/relaying/index.html @@ -0,0 +1,407 @@ + Sending / Relaying | ISPmail Guide + Skip to content

Sending / Relaying

Your mail server is almost ready for use. But one puzzle piece is missing. Your users can receive emails but they cannot +send them yet. This part of the guide is a bit longer than others because forwarding emails has security implications.

+

Let’s begin with the difference of how users send emails versus how mail servers send emails.

+
    +
  • A mail server fetches the MX record for the destination domain of the recipient’s email address from DNS. That +tells it which mail server to talk to. Then it opens an SMTP connection (TCP port 25) and sends the email. A mail +server will not relay an email meant for someone else. It will only accept emails for its own users.
  • +
  • An end user with a mail client such as Thunderbird or Roundcube cannot do that. Mail clients do not include any +functionality for fetching MX records. In addition, the user is usually on a dynamic IP address that other mail +servers will not trust and will likely reject. Instead, end users are expected to send their emails through their +provider’s (=your) mail server: they authenticate with their login credentials and then send the message. This process +is called relaying, because your mail server acts as an intermediary between the user and other mail servers on the +internet. For security reasons, authentication is required before the user is allowed to send emails. Users are also +expected to use the TCP port 587 which is called the submission port. More on that later.
  • +
+

Postfix must only accept an email from a user, if…

+
    +
  • The user uses the submission port (and not the standard SMTP port)
  • +
  • The user authenticates with the username (in our setup: the email address) and the password
  • +
  • The connection is encrypted so that the password can be safely transmitted
  • +
  • The sender address of the email matches the user’s account
  • +
+ +

Let’s compare those services and ports side-by-side:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Service nameSMTPSubmissionSubmissionS (S=secure)
TCP Port25587465
Meant forOther mail serversOur usersOur users
Used byMail transport agent (MTA)Mail user agent (MUA)Mail user agent (MUA)
Transport encryptionOff. STARTTLS optional.Off. STARTTLS mandatory.TLS all the time
AuthenticationOptional 1MandatoryMandatory
Accepted senderAnyoneOur own usersOur own users
Accepted receiversOur own usersAnyoneAnyone
Your home ISPmay block this portwill allow this portwill allow this port
+

I hope this helps clarify the distinction. Human users must use the submission service on either port 587 or 465. The +key difference is that connections on port 587 start unencrypted, and the email client must issue the STARTTLS command +to enable encryption. In contrast, port 465 requires the email client to use TLS encryption right from the first byte of +communication.

+ +

All Postfix services are declared in the /etc/postfix/master.cf file. Most of them are used by Postfix internally, +like pickup, cleanup, rewrite or bounce. But submission is not configured by default. Let’s fix that.

+
Run this on your server
postconf -M submission/inet="submission inet n - y - - smtpd"
postconf -P "submission/inet/syslog_name=postfix/submission"
postconf -P "submission/inet/smtpd_tls_security_level=encrypt"
postconf -P "submission/inet/smtpd_sasl_auth_enable=yes"
postconf -P "submission/inet/smtpd_sasl_type=dovecot"
postconf -P "submission/inet/smtpd_sasl_path=private/dovecot-auth"
postconf -P "submission/inet/smtpd_recipient_restrictions=permit_sasl_authenticated,reject"
postconf -P "submission/inet/smtpd_sender_restrictions=reject_sender_login_mismatch,permit_sasl_authenticated,reject"
+
postfix reload
+

These commands added a submission service to the /etc/postfix/master.cf file. You could have achieved the same thing +by editing that file and adding the following section, but I wanted to make it simpler for you to just copy/paste the +commands into your shell.

+
What it did…
submission inet n - y - - smtpd
-o syslog_name=postfix/submission
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
-o smtpd_sasl_type=dovecot
-o smtpd_sasl_path=private/dovecot-auth
-o smtpd_recipient_restrictions=permit_sasl_authenticated,reject
+

Some notes on that:

+
    +
  • Lines with options (-o) need to be indented so that Postfix understands that they belong to the same service.
  • +
  • The word submission refers to the definition of the service in the /etc/services file. So it translates to TCP +port 587.
  • +
  • The smtpd in the last column of the first row tells Postfix that connections should be handled as incoming SMTP +connections.
  • +
  • syslog_name is adding postfix/submission to log files so that you can distinguish it from other connections.
  • +
  • smtpd_tls_security_level enabled and enforces the use of STARTTLS. The connection starts without encryption but +the remote party is required to send the STARTTLS command to switch to an encrypted connection.
  • +
  • smtpd_sasl_auth_enable enables authentication on this port. SASL is short for Simple Authentication and Security +Layer. That way only our own users can use this service.
  • +
  • smtpd_sasl_type tells Postfix to use Dovecot’s service to authentication a uaser.
  • +
  • smtpd_sasl_path tells Postfix that it should talk to Dovecot through the socket file +/var/spool/postfix/private/dovecot-auth. Earlier in this guide you told Dovecot to create that socket at that +location.
  • +
  • smtpd_recipient_restrictions define that only authenticated connections are permitted. Without a username and a +password your connection will be rejected. The recipient keyword tells us that this restricts who the recipient +can be.
  • +
  • smtpd_sender_restrictions restricts who the sender may be. I will explain that +later.
  • +
+

While you are at it, create the submissions (with an “s” at the end) service as well:

+
Run this on your server
postconf -M submissions/inet="submissions inet n - y - - smtpd"
postconf -P "submissions/inet/syslog_name=postfix/submissions"
postconf -P "submissions/inet/smtpd_tls_wrappermode=yes"
postconf -P "submissions/inet/smtpd_sasl_auth_enable=yes"
postconf -P "submissions/inet/smtpd_sasl_type=dovecot"
postconf -P "submissions/inet/smtpd_sasl_path=private/dovecot-auth"
postconf -P "submissions/inet/smtpd_recipient_restrictions=permit_sasl_authenticated,reject"
postconf -P "submissions/inet/smtpd_sender_restrictions=reject_sender_login_mismatch,permit_sasl_authenticated,reject"
postfix reload
+

The only difference to the submission (without the “s” at the end) is the smtpd_tls_wrappermode that switches on TLS +encryption right from the start of a connection.

+ +

Whenever possible we should encrypt our traffic. For our users’ passwords we make it mandatory. But even for +server-to-server connections we should encourage it. Do not confuse it with end-to-end encryption of emails. That +required using PGP or S/MIME. What we are dealing here is transport encryption. It encrypts the communication between +a peer server and your mail server. What the peer server does with our email is beyond our control.

+ +
Run this on your server
postconf smtp_tls_security_level=encrypt
postconf smtpd_tls_security_level=encrypt
postconf smtp_tls_mandatory_protocols=">=TLSv1.2"
postconf smtpd_tls_mandatory_protocols=">=TLSv1.2"
postconf smtp_tls_mandatory_ciphers=high
postconf smtpd_tls_mandatory_ciphers=high
postconf smtpd_tls_cert_file=/etc/letsencrypt/live/mail.example.org/fullchain.pem
postconf smtpd_tls_key_file=/etc/letsencrypt/live/mail.example.org/privkey.pem
+

What it means:

+
    +
  • smtp_tls_security_level:
    +Enforce encrypted outgoing SMTP connections.
  • +
  • smtpd_tls_security_level:
    +Enforce encrypted incoming SMTP connections.
  • +
  • smtp_tls_mandatory_protocols / smtpd_tls_mandatory_protocols:
    +Only allow recommended versions of TLS. Version 1.2 has been +introduced 2008. Version 1.3 is from 2018.
  • +
  • smtp_tls_mandatory_ciphers / smtpd_tls_mandatory_ciphers:
    +The list of encryption algorithms that you allow for communnication. Default is medium.
  • +
  • smtpd_tls_cert_file and smtpd_tls_key_file:
    +Where to find the private key and certificate for encryption.
  • +
+ +

Please note that configuration in main.cf applies to all Postfix services. So the above configuration enabled +encryption for both server-to-server and human-to-server (submission) services. The smtpd_sasl_auth_enable will only +be set for the submission service to enable authentication there.1

+ +

Protecting against forged sender addresses

Section titled “Protecting against forged sender addresses”
+

Before we can actually test the setup, there is another security issue we need to address. While Postfix is configured +to relay emails only after a successful login with a valid username and password, it does not prevent an authenticated +user from impersonating another sender. For example, someone could log in as john@example.org but send an email +appearing to come from brunhilde@example.net.

+

We should fix that. For that purpose Postfix provides a setting called +smtpd_sender_login_maps. From the “maps” part you can +deduce that it expects a mapping again:

+
    +
  • Question: who you claim to be (email’s sender address)
  • +
  • Answer: who you logged in as (user name after authentiation)
  • +
+

If you think of it, the mapping is simple. The question must match the answer. If john@example.org wants to be the +sender, he must also authenticate as john@example.org.

+

As we use the email address also as a user name we simply need a mapping where the email address is listed on both +sides. Let’s create it:

+
Run this on your server
# Create a mapping configuration from the user to themself
cat > /etc/postfix/mariadb-email2email.cf << EOF
user = mailserver
password = MAILSERVER-PASSWORD-HERE
hosts = 127.0.0.1
dbname = mailserver
query = SELECT email FROM virtual_users WHERE email='%s'
EOF
+
# Fix permissions
chown root:postfix /etc/postfix/mariadb-email2email.cf
chmod u=rw,g=r,o= /etc/postfix/mariadb-email2email.cf
+
# Tell Postfix to use this mapping
postconf smtpd_sender_login_maps=mysql:/etc/postfix/mariadb-email2email.cf
+

What you accomplished:

+
    +
  1. Create the mapping file
  2. +
  3. Fix the permissions of it so that only Postfix can read it (there is a password in it)
  4. +
  5. Make Postfix use that mapping for its smtpd_sender_login_maps setting
  6. +
  7. Add smtpd_sender_restrictions=reject_sender_login_mismatch to the submission and submissions services
  8. +
+

You can now try to send email as a different user than you are logged in. Let’s us swaks again to send a spoofed email:

+
Run this on your server
swaks --server localhost:587 \
--from brunhilde@example.org \
--to list@example.com \
--tls \
--auth-user john@example.org \
--auth-password summersun
+

The server should rightfully reject that wrong sender:

+
~> MAIL FROM:john@example.com
<~ 250 2.1.0 Ok
~> RCPT TO:john@example.org
<~ * 553 5.7.1 john@example.com: Sender address rejected: not owned by user john@example.org
+

Now let’s send a proper email from John:

+
Run this on your server
swaks --server localhost:587 \
--from john@example.org \
--to list@example.com \
--tls \
--auth-user john@example.org \
--auth-password summersun
+

That will work:

+
<~ 250 2.0.0 Ok: queued as AFFF12292A
+ + + + +

So far you have set up the submission service(s), enabled encryption and connected Postfix to Dovecot for +authentication. Let’s try it. Our first test email will be sent without encryption and authentication:

+
Run this on your server
swaks --server localhost:587 \
--from john@example.org \
--to lisa@example.com
+

Postfix should tell you that it will not accept an email without encryption:

+
<** 530 5.7.0 Must issue a STARTTLS command first
+ +

Our second attempt will enable (STARTTLS) encryption – but still no authentication:

+
Run this on your server
swaks --server localhost:587 \
--from john@example.org \
--to lisa@example.com \
-tls
+

Postfix will still reject the email because we refused to authenticate:

+
~> MAIL FROM:<john@example.org>
<~ 250 2.1.0 Ok
~> RCPT TO:<lisa@example.com>
<~* 553 5.7.1 <john@example.org>: Sender address rejected: not logged in
+ +
Run this on your server
swaks --server localhost:587 \
--from john@example.org \
--to lisa@example.com \
-tls \
--auth-user john@example.org \
--auth-password summersun
+

Also give the submissions service a try:

+
Run this on your server
swaks --server localhost:465 \
--from john@example.org \
--to lisa@example.com \
--tls-on-connect \
--auth-user john@example.org \
--auth-password summersun
+

Did you notice the difference? The second time we used port 465 and instead of the -tls option (which uses +STARTTLS to switch to encryption) we use --tls-on-connect that uses TLS right from from the start.

+

Put simply, a mail server will accept an email if…

+
    +
  • it is responsible for handling mail for the recipient’s domain (the domain is listed as a virtual domain), or
  • +
  • the sender has authenticated successfully with a valid username and password.
  • +
+

I have created two illustrations to explain it.

+ + +
telnet localhost submission
+

The server will let you in:

+
Trying 127.0.0.1…
Connected to localhost.
Escape character is '^]'.
220 webmail ESMTP Postfix (Debian)
+

Say hello:

+
ehlo example.com
+

Postfix will present a list of features that are available for you:

+
250-mailtest
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-STARTTLS
250-ENHANCEDSTATUSCODES
250-8BITMIME
250-DSN
250-SMTPUTF8
250 CHUNKING
+

Let me briefly explain what these lines mean:

+
    +
  • PIPELINING
    +This is a feature to speed up SMTP communication. Usually the remote system has to wait for a response to every +command it sends. Pipelining allows the remote server to send several commands in a batch without waiting for a +response. Postfix will just store these commands and execute them one by one. If you told Postfix to forbid pipelining +it would disconnect the remote server when it tries to send bulks of commands without waiting for the proper reply. It +is mainly a feature against rogue senders.
  • +
  • SIZE 10240000
    +The remote server is allowed to send emails up to 10 MB large. This has long been a common maximum size for emails. +However nowadays 40 MB or even more are more common sizes because emails have grown larger. Some mail servers even +allow 100 MB.
  • +
  • VRFY
    +Allows remote servers to verify a given name or email address. For example the remote server could send “VRFY john” +and your server might respond 250 Jo You can skip it for now.hn Doe <john@example.org>. It can be used to verify +that a certain recipient email address is deliverable
  • +
  • ETRN
    +A command that a remote system can send to flush the Postfix queue of mails for a certain domain. It can be used if +the remote system had technical problems and failed to receive email for a while. Then it could send an ETRN command +to make your server start sending outstanding emails for that domain. It is rarely used.
  • +
  • STARTTLS
    +This tells the remote system that it might start switching from this unencrypted to an encrypted connection by +sending the “STARTTLS” command. It will then start negotiating a TLS-encrypted connection. You could compare it to an +HTTP connection that suddenly switches over to an encrypted HTTPS connection. The advantage is that you can start +talking SMTP on TCP port 25 and don’t have to open up a second TCP port like 465 which is the “SSMTP” (secure SMTP) +port and only accepts encrypted connections.
  • +
  • ENHANCEDSTATUSCODES
    +This enables more three-digit return codes for various conditions. See the +RFC2034 if you are curious.
  • +
  • 8BITMIME
    +In ancient times SMTP only processed 7-bit characters. You couldn’t transfer special characters like “Ä” or “ß” +without special encoding. 8BITMIME allows a transmission of emails using 8-bit characters. Still many emails are +specially encoded using ISO8859-1 or UTF-8.
  • +
  • DSN
    +It enables DSNs (delivery status notofications) that allows the sender to control the messages that Postfix creates +when an email could not be delivered as intended.
  • +
  • SMTPUTF8
    +In addition to 8BITMIME you can use UTF8 encoded characters in header fields.
  • +
  • CHUNKING
    +This feature (described in RFC 3030) makes sending of large emails more +efficient.
  • +
+

However one important line is missing here that would allow us to send our username and password:

+
250-AUTH PLAIN LOGIN
+

We told Postfix to only allow authentication when the connection is encrypted. So we are not offered authentication over +this plain text connection. That’s what we want.

+

Are you still connected? Okay, good. So we need an encrypted connection using TLS. Using the STARTTLS feature we can +switch over from unencrypted to encrypted without having to reconnect. Enter…

+
STARTTLS
+

And the server replies:

+
220 2.0.0 Ready to start TLS
+

However now it’s getting weird because you would have to speak TLS encryption which is not a language that humans speak. +So let’s quit this using the “QUIT” command and do that differently:

+
QUIT
+

We can use OpenSSL to help us with the decryption. Run:

+
openssl s_client -connect localhost:submission -starttls smtp
+

You will see a lot of output. OpenSSL has connected to TCP port 25 and issued a STARTTLS command to switch to an +encrypted connection. So whatever you type now will get encrypted. Enter:

+
EHLO example.com
+

And Postfix will send a list of capabilities that will look like this:

+
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-AUTH PLAIN LOGIN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
+

And now that we are using an encrypted connection Postfix offers us to authenticate. So let us send the authentication +string with a Base64-encoded password:

+
AUTH PLAIN AGpvaG5AZXhhbXBsZS5vcmcAc3VtbWVyc3Vu
+

Unless you have changed John’s password to something else than “summersun” the server should accept that authentication:

+
235 2.7.0 Authentication successful
+

Excellent. You are logged in through SMTP. You could now send an email to be forwarded to another mail server. I just +wanted to show that authentication works if you use an encrypted connection.

+

Disconnect from Postfix:

+
QUIT
+

Authentication works. Well done.

+

Wait a minute. What was that crazy cryptic string? There was no username and password in it. Was it encrypted?

+

No, that was no encryption. It was merely an encoded version of the username and password. Why that? Well usually in +SMTP you can only transfer ASCII characters. But the password may contain special characters which are not covered by +ASCII. So in the PLAIN method that information is Base64 encoded.

+

What is actually converted to Base64…

+
NULL-BYTE + USERNAME + NULL-BYTE + PASSWORD
+

So for John’s case you can easily create the Base64 string using:

+
printf '\0john@example.org\0summersun' | base64
+

As a result you will get the exact same string you used above with “AUTH PLAIN”.

+
+
    +
  1. +

    In previous guides I recommended to set smtpd_sasl_auth_enable=yes globally in the main.cf. That would indeed +enable authentication on port 25. For a clearer separation I now rather suggest to leave it out (default is no) +and just enable authentication on the submission service in the master.cf file. A possible scenario that +required this setting to be on would be if your server were a relay (smarthost) for other servers using +authentication.. 2

    +
  2. +
+
\ No newline at end of file diff --git a/dist/ispmail-trixie/tls-certificate/index.html b/dist/ispmail-trixie/tls-certificate/index.html new file mode 100644 index 0000000..8e53f8e --- /dev/null +++ b/dist/ispmail-trixie/tls-certificate/index.html @@ -0,0 +1,144 @@ + TLS certificate | ISPmail Guide + Skip to content

TLS certificate

Todo list for receiving emails
  1. 1

    DNS records point to your server

  2. 2

    Get a certificate from Let's Encrypt

  3. 3

    Postfix fetches information from MariaDB

  4. 4

    Dovecot fetches information from MariaDB

  5. 5

    Postfix hands over emails to Dovecot

  6. 6

    Dovecot saves the email to disk

+

Your mail server can’t work properly without a valid TLS certificate. It will be used in three places:

+
    +
  1. the webmail interface (driven by the Apache web server)
  2. +
  3. Postfix (to encrypt SMTP communication with other mail servers on the internet where possible)
  4. +
  5. Dovecot (to encrypt IMAP/POP3 communication)
  6. +
+

Your mail server will be able to host email addresses for many domains. But a TLS certificate is usually issued for a +single FQDN like mail.example.org. That common name is +an important part of the certificate. It must match the name your users use to talk to the server.

+

Correct: Your mail server is addressed as mail.example.org. The TLS certificate was also issued to +mail.example.org.

+

Wrong: Your mail server is addressed as smtp01.example.com. But the TLS certificate was issued to +mail.example.org.

+

So choose an FQDN for your mail server. For example I use webmail.workaround.org for my personal server.

+ +

You already have the certbot software and the apache2 web server installed. Requesting a certificate from Let’s +Encrypt is as simple as running the next command.

+ +
Run this on your server
certbot --apache --register-unsafely-without-email --agree-tos -d mail.example.org
+
Click here to learn what the options mean…
    +
  • --apache: Use the HTTP challenge to verify that you are actually +in control of the FQDN. The certbot plugin will add some configuration to intercept HTTP requests to +/.well-known/acme-challenge/… on your web server. This is a fully automatic process that does not even have to stop +your web server.
  • +
  • --register-unsafely-without-email: Do not ask for an email address to send to Let’s Encrypt. Before June 2025 +Let’s Encrypt used that address to inform you if your certificate is about to expire and the automatic renewal failed. +Nowadays they do not need an email any more. But for historical reasons they still ask for it by default.
  • +
  • --agree-tos: Confirm that you have read Let’s Encrypt’s terms and conditions. Let’s be honest – nobody reads that.
  • +
  • -d: The domain that the certificate will be issued to. This has to be the exact FQDN of your server.
  • +
+

The output should look like:

+
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Requesting a certificate for mail.example.org
+
Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/mail.example.org/fullchain.pem
Key is saved at: /etc/letsencrypt/live/mail.example.org/privkey.pem
This certificate expires on 2025-11-22.
These files will be updated when the certificate renews.
Certbot has set up a scheduled task to automatically renew this certificate in the background.
+
Deploying certificate
Successfully deployed certificate for mail.example.org to /etc/apache2/sites-available/000-default-le-ssl.conf
Congratulations! You have successfully enabled HTTPS on https://mail.example.org
+
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
If you like Certbot, please consider supporting our work by:
* Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
* Donating to EFF: https://eff.org/donate-le
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
Click here to learn which files have been created…

In /etc/letsencrypt/live/mail.example.org you will find a couple of files now:

    +
  • cert.pem: the certificate file
  • +
  • chain.pem: the chaining or intermediate certificate. This certificate provides information how the LetsEncrypt +certificates are linked to other known certificate authorities. It is generally a good idea to always send this +certificate along with your own for clients who may not know LetsEncrypt properly yet.
  • +
  • fullchain.pem: this file contains a concatenation of the cert.pem and the chain.pem. This is the preferred +file to use when a piece of software asks where to find the certificate.
  • +
  • privkey.pem: the private key file. Keep it secret.
  • +

Well, actually those are not files but symbolic links pointing to the “archive” directory. But don’t worry about that.

+ +

Your new certificate is only valid for 3 months. Fortunately the renewal is happening automatically. A systemd timer +checks your certificate frequently and triggers a renewal one month before it expires.

+

It is important that services that use the certificate load the new certificate after an automatic renewal. This shell +command will create a file /etc/letsencrypt/cli.ini that handles it:

+
Run this on your server
cat > /etc/letsencrypt/cli.ini << 'EOF'
# Restart services after renewing a certificate
post-hook = systemctl reload postfix dovecot apache2
+
# Because we are using logrotate for greater flexibility, disable the
# internal certbot logrotation.
max-log-backups = 0
+
# Adjust interactive output regarding automated renewal
preconfigured-renewal = True
EOF
+

Perfect. You won’t have to worry about the certificate again.

+
Click here to learn how the renewal works…

These commands will show you the definition and status of the timer and the renewal service:

Run this on your server
systemctl status certbot.timer
systemctl cat certbot.timer
systemctl status certbot.service
systemctl cat certbot.service

Systemd timers are similar to cron jobs. They require more work to set up but have some nice features and make you +look cooler.

\ No newline at end of file diff --git a/dist/ispmail-trixie/upgrading/index.html b/dist/ispmail-trixie/upgrading/index.html new file mode 100644 index 0000000..a0ec1d4 --- /dev/null +++ b/dist/ispmail-trixie/upgrading/index.html @@ -0,0 +1,200 @@ + Upgrading from Debian Bookworm | ISPmail Guide + Skip to content

Upgrading from Debian Bookworm

+

Did you follow the ISPmail guide for Debian Bookworm to install your mail server? Then let’s take it to Debian Trixie.

+ +

I always try to keep things similar to previous versions of this guide. Most of us are happy with their mail servers and +want to change as little as possible when a new Debian release comes along. Just a few changes that come with the newer +software versions:

+
    +
  • rsyslogd was a classic choice to write log files like /var/log/mail.log. As Debian is using systemd we no longer +need rsyslogd and logrotate. The logs can be read using journalctl instead. If you miss log files, just +apt install rsyslog.
  • +
  • smtpd_tls_security_level is now only enabled for the submission service. That disables authentication for SMTP +connections on port 25. This emphasizes the separation of TCP 25 for server-to-server connections (without +authentication) and TCP 587 for human-to-server connections (with authentication – for relaying).
  • +
  • certbot is now using the python3-certbot-apache package. Getting and renewing certificates is now handled +magically by Apache without any downtime or additional configuration.
  • +
+ +

A new Debian stable release comes with newer software versions. So I checked the changelogs to determine what we will +have to change:

+
    +
  • Postfix 3.7.6 -> 3.10.3. No breaking changes.
  • +
  • Dovecot 2.3.19 -> 2.4.1. Various deprecations of the configuration. This guide uses the new syntax.
  • +
  • PHP 8.2 -> 8.4. Roundcube has no issues with the newer PHP version.
  • +
  • rspamd 3.4.1 -> 3.12.1. No breaking changes.
  • +
  • Roundcube 1.6.1 -> 1.6.11. No breaking changes.
  • +
+ +

Do not try to upgrade your existing server using apt-get dist-upgrade. There are too many changes especially with +Dovecot. Start with a fresh installation on another server and then migrate.

+ +

At some point during the migration, you need switch your DNS record to point to the new server. There are a couple of +options:

+
    +
  1. Lower the TTL of your MX record. The TTL (time-to-live) defines how long your record can be cached. If you lower that +value to 60 seconds, you can change the MX record and other servers will pick it up quickly.
  2. +
  3. If your data center allows it, move your IP address over. Some offer reserved addresses that you can assign to a +server. That way there will be no delay in the switch-over. And other servers on the internet will recognize your +server as a mail server already, because some companies attach a reputation to an IP address.
  4. +
  5. Add a second MX record pointing to your new server. Assign the same priority. That way you can safely switch off your +old server and later remove its MX record.
  6. +
+ +

You need to copy the database that contains the control data about your email domains and accounts. Log into the old +(Bookworm) server as root and back up the mailserver database. That is as easy as running…

+
mariadb-dump mailserver > mailserver.sql
+

Copy that file to the new server (using scp) and import it there:

+
mariadb mailserver < mailserver.sql
+

Obviously any database changes on the old server from now on will have to be done on the new server as well until the +migration is done.

+ +

Please check if any of your users have hashed passwords that are considered +weak by Dovecot. Those passwords using a PLAIN-MD5 +scheme are not accepted by Dovecot by default. But you can enable them again using:

+
Terminal window
cat > 99-ispmail-weak-schemes.conf << EOF
auth_allow_weak_schemes = yes
EOF
+

Your users should change their passwords using Roundcube. That way a new hash with a more secure schema is created.

+ +

If your users are using Roundcube as a webmail interface then you should migrate their data like their contact lists. +Dump the SQL from the old server:

+
Terminal window
mariadb-dump roundcube > roundcube.sql
+

Copy that file to the new server and import it:

+
Terminal window
mariadb roundcube < roundcube.sql
+

One caveat though. To distinguish multiple mail servers Roundcube stores the server’s name in the mail_host column of +the users table. So as a last step change that column if your new mail server has a new FQDN/hostname by running this +SQL query on the new roundcube database:

+
UPDATE users SET mail_host='new.mail.server';
+ +

If you have been using rspamd with the Redis backend then copy over the Redis database from your previous server.

+

Stop rspamd on both the old and the new server. Then:

+
Terminal window
rsync -va oldserver:/var/lib/redis/ /var/lib/redis/
+

Once the redis database is started again on the new server, rspamc stat should show you that the training data is +found.

+ +

(Hot means: copy the files why they are still in use and potentially change while you do that.) Fortunately Dovecot +uses the maildir format that stores emails as plain files on disk. Login to the new (Trixie) server and use rsync to +copy over the mails from the old (Bookworm) mail server:

+
rsync -va oldserver:/var/vmail/ /var/vmail/
+

(Note the trailing slashes. Type them exactly as shown above or your files will end up in wrong places.)

+

There is no need to shut down Dovecot on your production Bookworm server. Copying the files while Dovecot is running +will not break anything. This is called a “hot copy”. It may not be consistent but it will save time during the final +synchronization.

+

Another way to copy over the emails is using Dovecot’s +doveadm-sync command. It may be especially handy if you +need to copy emails from another server where you only have IMAP access but cannot access the files directly.

+ +

Copy over everything in /etc/letsencrypt and /var/lib/rspamd/dkim from your old to the new server.

+
Terminal window
rsync -va oldserver:/etc/letsencrypt/archive/ /etc/letsencrypt/archive/
rsync -va oldserver:/var/lib/rspamd/dkim/ /var/lib/rspamd/dkim/
rsync -v oldserver:/etc/rspamd/dkim_selectors.map /etc/rspamd
+ +

You told your users about the downtime, right? The time has come? Okay. Shut down Dovecot on both servers.

+ +

(Cold means: the processes have stopped or you made sure that there is no user activity so that the files can be +copied consistently.) Let’s synchronize again. rsync will only copy those files that have changed which makes it much +faster than the first sync. On your new server run:

+
Terminal window
rsync -va --delete oldserver:/var/vmail/ /var/vmail/
+

(The “--delete” option makes sure that files that have been removed from the old server will also be deleted from the +new server. So if a user has deleted an email it will be deleted on the new server as well.)

+ +

For all your domains you will have to change the DNS “MX” or “A” record to point to your new server.

+ +

Accidents happen. And you don’t want to lose emails. So run this command to enable your safety net on the new server:

+
postconf soft_bounce=yes
+

This makes Postfix always keep emails in the queue that it would otherwise reject. So you can fix any errors and the +queue will empty. Start Postfix and Dovecot on the new server. Watch your /var/log/mail.log and run “mailq” from time to +time to see what emails get stuck in the queue. If you are certain that emails can be removed from the queue then use +“postsuper -d QUEUE-ID” (as shown in the “mailq” output).

+

Once you are certain that emails are properly received and sent you can switch off the soft_bounce mode again:

+
postconf soft_bounce=no
+ +

If possible do a final backup of the old server. If users are not complaining then dismiss the old system after a week.

+ +

You may see error messages like:

+
Error: sieve: binary /var/vmail/example.org/user/.dovecot.svbin: read: binary stored with different major version 2.0 (!= 3.0; automatically fixed when re-compiled)
+

You may need to run sievec on those files.

\ No newline at end of file diff --git a/dist/ispmail-trixie/virtual-domains/index.html b/dist/ispmail-trixie/virtual-domains/index.html new file mode 100644 index 0000000..a987c51 --- /dev/null +++ b/dist/ispmail-trixie/virtual-domains/index.html @@ -0,0 +1,104 @@ + Virtual domains | ISPmail Guide + Skip to content

Virtual domains

Your mail server will have one fully qualified domain name — for example, postbox.example.com. In this case, the base +domain is example.com. If someone visits https://example.com/, they might be greeted by the Roundcube webmail login +page.

+

But your server doesn’t have to handle only one domain. You can have mailboxes on multiple domains like:

+
    +
  • jack@example.com
  • +
  • lucy@example.com
  • +
  • tina@example.org
  • +
  • jeff@example.net
  • +
+

These are three different domains, and your server can handle them all.

+

This is what virtual domains are for. You give your mail server a list of domains and email addresses and it will +receive emails for them. Your users will also have passwords that they need to type in to retrieve their emails. You can +even set up mailing lists that take messages sent to one address and forward them to several mailboxes at once.

+

To make all this work, we’ll store the configuration in a small MariaDB database. Postfix, Dovecot, and Roundcube will +all read from this database to know which domains exist, which mailboxes they have, and where each email should go. You +will create that simple database on the next page.

\ No newline at end of file diff --git a/dist/ispmail-trixie/webmail/index.html b/dist/ispmail-trixie/webmail/index.html new file mode 100644 index 0000000..b5c0bb0 --- /dev/null +++ b/dist/ispmail-trixie/webmail/index.html @@ -0,0 +1,198 @@ + Webmail using Roundcube | ISPmail Guide + Skip to content

Webmail using Roundcube

+

Now that the email has arrived, our valued user surely wants to read it. Most humans nowadays seem to prefer reading +their email in the web browser, because it’s the simplest way. (Don’t worry. Power users who prefer mail clients like +Thunderbird will also get what they want.) So let’s prepare Roundcube for them.

+
Click here to learn more about virtual hosts…

A web server like Apache has the job of answering HTTP or HTTPS requests from people’s browsers. Running just a single +website per server (or per IP address) would be both inefficient and limiting, so the idea of virtual hosts was +introduced. With virtual hosts, one server can host many different websites. The browser helps by sending a +Host: mail.example.org header with each request, which tells the server which website it should serve. This works fine +for HTTP—though plain HTTP is rarely used anymore.

With HTTPS, things get trickier. Browsers expect the server to present a TLS certificate that matches the domain being +requested. If you try to open mail.example.org but the server responds with a certificate for shop.example.org, the +browser will block the connection. That means the server needs to know which domain the browser is asking for before the +encrypted connection is set up.

The solution is a feature called SNI (Server Name Indication). When establishing an HTTPS connection, the browser +includes the domain name it wants in the handshake. This allows the server to pick the correct TLS certificate right +from the start.

Fortunately you do not have to worry about it that much because Apache is doing the heavy lifting for you. A virtual +host configuration essentially looks like:

<VirtualHost *:443>
ServerName mail.example.org
SSLCertificateFile /etc/letsencrypt/live/mail.example.org/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/mail.example.org/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>

There are two directories dealing with virtual hosts:

    +
  • /etc/apache2/sites-available
  • +
  • /etc/apache2/sites-enabled
  • +

The actual file containing the configuration lives in sites-available. If that configuration should be active, then a +symbolic link (symlink) is added to the sites-enabled directory pointing to the file in the sites-available +directory. That way you can switch sites on and off without deleting the actual configuration file. You can enable a +site using the a2ensite (apache2 enable config) command or disable it using a2dissite.

+

Since you ran certbot earlier to create a TLS certificate for your site, the default configuration files for HTTP and +HTTPS have been adapted already:

+
    +
  • 000-default.conf: This is the virtual host configuration for HTTP requests. It uses a RewriteRule to redirect +users to the HTTPS site. So if user accidentally forget to type https://, we will add it for them.
  • +
  • 000-default-le-ssl.conf: This is the HTTPS virtual host.
  • +
+

So to get Apache to serve the Roundcube application you need to edit the +/etc/apache2/sites-available/000-default-le-ssl.conf file.

+ +

Set this:

+
Edit /etc/apache2/sites-available/000-default-le-ssl.conf
ServerName mail.example.org
DocumentRoot /var/lib/roundcube/public_html
Include /etc/roundcube/apache.conf
+

Meaning:

+
    +
  • ServerName sets the domain name that a user’s browser will request.
  • +
  • DocumentRoot points the entire web site to the directory where Roundcube is installed.
  • +
  • Include loads additional security settings that the Roundcube package provides.
  • +
+

And as usual Apache needs to be restarted after the configuration change:

+
Terminal window
systemctl restart apache2
+

Check that Apache is running properly:

+
Terminal window
systemctl status apache2
+

In case of a problem run apache2ctl configtest to find the cause.

+ +

The main configuration file of Roundcube is located at /etc/roundcube/config.inc.php. Feel free to customize the file. +Fortunately nowadays the basic settings are already as we need them. However these two settings need to be changed by +you.

+ +
Edit /etc/roundcube/config.inc.php
$config['imap_host'] = 'tls://mail.example.org:143';
$config['smtp_host'] = 'tls://mail.example.org:587';
+

So now when your users enter https://webmail.example.org/ in their browser they should get the Roundcube login form:

+

Roundcube login dialog

+

Keep in mind that we are using the email address as the account name of the user. So when logging in please enter the +email address as the user name. E.g. john@example.org and password summersun.

+

If the login fails, check /var/log/roundcube/errors.log.

+ + +

Roundcube comes with various plugins that you can offer your users. I suggest that you enable at least

+
    +
  • the password plugin so that your users can change their access password
  • +
  • the managesieve plugin so that your users can create server-based filtering rules
  • +
+

Again edit the /etc/roundcube/config.inc.php file and look for the plugins configuration. To enable the recommended +plugins change it to:

+
$config['plugins'] = array(
'password',
'managesieve',
);
+

Plugins are configured through files located in the /etc/roundcube/plugins directory.

+ +

Let’s quickly set up the password plugin:

+
Run this on your server
cat > /etc/roundcube/plugins/password/config.inc.php << 'EOF'
<?php
$config['password_driver'] = 'sql';
$config['password_minimum_length'] = 12;
$config['password_force_save'] = true;
$config['password_algorithm'] = 'blowfish-crypt';
$config['password_algorithm_prefix'] = '{CRYPT}';
$config['password_db_dsn'] = 'mysql://mailadmin:MAILADMIN-PASSWORD-HERE@localhost/mailserver';
$config['password_query'] = "UPDATE virtual_users SET password=%P WHERE email=%u";
?>
EOF
+
chown root:www-data /etc/roundcube/plugins/password/config.inc.php
chmod u=rw,g=r,o= /etc/roundcube/plugins/password/config.inc.php
+

What these settings mean:

+
    +
  • $config['password_driver'] = 'sql';
    +Use SQL as a backend.
  • +
  • $config['password_minimum_length'] = 12;
    +New passwords must be at least 12 characters long.
  • +
  • $config['password_force_save'] = true;
    +This will overwrite the password in the database even if it hasn’t changed. It helps us improve the strength of the +password hash by re-encoding it with a better algorithm even if the user chooses to keep his old password.
  • +
  • $config['password_algorithm'] = 'blowfish-crypt';
    +The cryptographic algorithm to encode the password. This one is considered very secure and supported by Dovecot.
  • +
  • $config['password_algorithm_prefix'] = '{CRYPT}';
    +Prepend every password with this string so that Dovecot knows how we encrypted the password.
  • +
  • $config['password_db_dsn'] = 'mysql://mailadmin:MAILADMIN-PASSWORD-HERE@localhost/mailserver';
    +Connection information for the local database. Use your own password for the mailadmin (!) database user here. We +cannot use the restricted mailserver user because we have to write the new password to the database.
  • +
  • $config['password_query'] = "UPDATE virtual_users SET password=%P WHERE email=%u";
    +The SQL query that is run to write the new password hash into the database. %P is a placeholder for the new password +hash. %u is the logged-in user and conveniently matches the email address.
  • +
+

For a complete reference please see /usr/share/roundcube/plugins/password/config.inc.php.dist.

+

The last two lines make sure that this config file is only accessible to everyone.

+

Roundcube password dialog

+

Try it. Log into Roundcube as john@example.org with password ‘summersun’. Go to the Settings. Choose Password. +Enter a new password twice. You should get a success message at the bottom right. Now logout and login with the new +password. Does it work? Great.

+ +

Sieve is a simple programming language to be used for +server-side rules. Dovecot executes these rules every time a new email comes in. There are global rules that are +executed for every email. And of course every user/mailbox can have its own rules. To manage sieve rules Dovecot offers +the managesieve interface that you enabled earlier. So we just need to tell Roundcube how to access it.

+

The configuration file for Roundcube’s managesieve plugin is found at +/etc/roundcube/plugins/managesieve/config.inc.php. But the defaults are fine so you do not need to change it.

+

Sieve rules are stored in a special syntax on the server. This is an example that moves all incoming emails to the +test folder that have “test” in the subject:

+
require ["fileinto"];
if header :contains "subject" "test"
{
fileinto "INBOX/test";
}
+

You do not need to learn this syntax though. Roundcube’s sieve rule editor is way more user-friendly.

+

Try adding a sieve rule for john@example.org in Roundcube. That feature is located in Settings/Filters. You will find +the machine-readable sieve code at /var/vmail/example.org/john/sieve/roundcube.sieve.

+

The rule editor looks like this:

+

Roundcube's sieve rule editor

\ No newline at end of file diff --git a/dist/ispmail-trxie/anti-spoofing-dkim-spf/index.html b/dist/ispmail-trxie/anti-spoofing-dkim-spf/index.html new file mode 100644 index 0000000..ce7a934 --- /dev/null +++ b/dist/ispmail-trxie/anti-spoofing-dkim-spf/index.html @@ -0,0 +1 @@ +Redirecting to: /ispmail-trixie/anti-spoofing-dkim-spf Redirecting from /ispmail-trxie/anti-spoofing-dkim-spf/ to /ispmail-trixie/anti-spoofing-dkim-spf \ No newline at end of file diff --git a/dist/ispmail-trxie/catch-all/index.html b/dist/ispmail-trxie/catch-all/index.html new file mode 100644 index 0000000..b4e4faf --- /dev/null +++ b/dist/ispmail-trxie/catch-all/index.html @@ -0,0 +1 @@ +Redirecting to: /ispmail-trixie/catch-all Redirecting from /ispmail-trxie/catch-all/ to /ispmail-trixie/catch-all \ No newline at end of file diff --git a/dist/ispmail-trxie/going-live/index.html b/dist/ispmail-trxie/going-live/index.html new file mode 100644 index 0000000..3f712bc --- /dev/null +++ b/dist/ispmail-trxie/going-live/index.html @@ -0,0 +1 @@ +Redirecting to: /ispmail-trixie/going-live Redirecting from /ispmail-trxie/going-live/ to /ispmail-trixie/going-live \ No newline at end of file diff --git a/dist/ispmail-trxie/imap/index.html b/dist/ispmail-trxie/imap/index.html new file mode 100644 index 0000000..31dc817 --- /dev/null +++ b/dist/ispmail-trxie/imap/index.html @@ -0,0 +1 @@ +Redirecting to: /ispmail-trixie/imap/ Redirecting from /ispmail-trxie/imap/ to /ispmail-trixie/imap/ \ No newline at end of file diff --git a/dist/ispmail-trxie/quotas/index.html b/dist/ispmail-trxie/quotas/index.html new file mode 100644 index 0000000..b60330e --- /dev/null +++ b/dist/ispmail-trxie/quotas/index.html @@ -0,0 +1 @@ +Redirecting to: /ispmail-trixie/quotas Redirecting from /ispmail-trxie/quotas/ to /ispmail-trixie/quotas \ No newline at end of file diff --git a/dist/ispmail.sh b/dist/ispmail.sh new file mode 100755 index 0000000..75b6efa --- /dev/null +++ b/dist/ispmail.sh @@ -0,0 +1,1164 @@ +#!/bin/bash -e +# +# Installer for ISPmail servers +# Copyright © 2025 Christoph Haas +# +# License: Creative Commons BY-NC-SA license +# +# Please report bugs at https://github.com/Signum/ispmail-workaround-org/issues +# +# Version 0.1 / 2025-12-14 +# First release. +# +# Version 0.2 / 2025-12-28 +# Enable plugins (managesieve, password) in Roundcube +# +# Version 0.3 / 2025-12-30 +# Add quota setup +# + +usage() { + echo "Usage: $0 -f fqdn" + exit 1 +} + +FQDN="" + +while getopts "f:h" opt; do + case "$opt" in + f) FQDN="$OPTARG" ;; + h) usage ;; + *) usage ;; + esac +done + + + +############ pre flight check ############ + +pre_flight() { + # Check for root + if [[ $EUIA -ne 0 ]]; then + echo "❌ You must run this script as root." + exit 1 + fi + + # Check for Trixie + DEBIAN_VERSION=$(cut -d'.' -f1 /etc/debian_version) + if [[ "$DEBIAN_VERSION" -ne 13 ]]; then + echo "❌ Sorry, this installer only works on Debian 13/Trixie." + exit 10 + fi + + # FQDN needs to be given as an option + if [[ $FQDN = "" ]]; then + echo "❌ You must specify your FQDN using the '-f' option." + exit 1 + fi +} + + +############## Intro ############## + +intro() { +cat < /etc/letsencrypt/cli.ini << 'EOF' +# Restart services after renewing a certificate +post-hook = systemctl reload postfix dovecot apache2 + +# Because we are using logrotate for greater flexibility, disable the +# internal certbot logrotation. +max-log-backups = 0 + +# Adjust interactive output regarding automated renewal +preconfigured-renewal = True +EOF +} + +############# Postfix ############### + +postfix_config() { + cat > /etc/postfix/mariadb-virtual-mailbox-domains.cf << EOF +user = mailserver +password = MAILSERVER-PASSWORD-HERE +hosts = 127.0.0.1 +dbname = mailserver +query = SELECT 1 FROM virtual_domains WHERE name='%s' +EOF + + cat > /etc/postfix/mariadb-virtual-alias-maps.cf << EOF +user = mailserver +password = MAILSERVER-PASSWORD-HERE +hosts = 127.0.0.1 +dbname = mailserver +query = SELECT destination FROM virtual_aliases WHERE source='%s' +EOF + + cat > /etc/postfix/mariadb-virtual-mailbox-maps.cf << EOF +user = mailserver +password = MAILSERVER-PASSWORD-HERE +hosts = 127.0.0.1 +dbname = mailserver +query = SELECT 1 FROM virtual_users WHERE email='%s' +EOF + + postconf virtual_mailbox_domains=mysql:/etc/postfix/mariadb-virtual-mailbox-domains.cf + postconf virtual_mailbox_maps=mysql:/etc/postfix/mariadb-virtual-mailbox-maps.cf + postconf virtual_alias_maps=mysql:/etc/postfix/mariadb-virtual-alias-maps.cf + + chown root:postfix /etc/postfix/mariadb-*.cf + chmod o= /etc/postfix/mariadb-*.cf + + # Postfix check + RES=$(postmap -q example.org mysql:/etc/postfix/mariadb-virtual-mailbox-domains.cf) + if [[ $RES -ne 1 ]]; then + echo "❌ The mariadb-virtual-mailbox-domains.cf mapping failed." + exit 10 + fi + + RES=$(postmap -q jack@example.org mysql:/etc/postfix/mariadb-virtual-alias-maps.cf) + if [[ $RES != 'john@example.org' ]]; then + echo "❌ The mariadb-virtual-alias-maps.cf mapping failed." + exit 10 + fi + + RES=$(postmap -q john@example.org mysql:/etc/postfix/mariadb-virtual-mailbox-maps.cf) + if [[ $RES -ne 1 ]]; then + echo "❌ The mariadb-virtual-mailbox-maps.cf mapping failed." + exit 10 + fi + + echo "✅ Mappings work." +} + +############# Dovecot ############### + +dovecot_config() { + groupadd -f --system vmail + id -a vmail 2>/dev/null >/dev/null || useradd --system --gid vmail vmail + mkdir -p /var/vmail + chown -R vmail:vmail /var/vmail + chmod u=rwx,g=rx,o= /var/vmail + + sed -i '/!include/s/^/#/' /etc/dovecot/conf.d/10-auth.conf + + cat > /etc/dovecot/conf.d/99-ispmail-mail.conf << EOF +mail_driver = maildir +mail_home = /var/vmail/%{user | domain}/%{user | username} +mail_path = ~/Maildir +mail_uid = vmail +mail_gid = vmail +mail_inbox_path = ~/Maildir/ +EOF + + cat > /etc/dovecot/conf.d/99-ispmail-master.conf << EOF +service auth { + unix_listener /var/spool/postfix/private/dovecot-auth { + mode = 0660 + user = postfix + group = postfix + } +} +EOF + + cat > /etc/dovecot/conf.d/99-ispmail-ssl.conf << EOF +ssl = required +ssl_server_cert_file = /etc/letsencrypt/live/$FQDN/fullchain.pem +ssl_server_key_file = /etc/letsencrypt/live/$FQDN/privkey.pem +EOF + + cat > /etc/dovecot/conf.d/99-ispmail-lmtp-username-format.conf << EOF +protocol lmtp { + auth_username_format = +} +EOF + + cat > /etc/dovecot/conf.d/99-ispmail-sql.conf << EOF +sql_driver = mysql + +mysql /var/run/mysqld/mysqld.sock { + user = mailserver + password = 'MAILSERVER-PASSWORD-HERE' + dbname = mailserver + host = 127.0.0.1 +} + +userdb sql { + query = SELECT email as user, \ + IF(quota > 0, CONCAT(quota, 'B'), NULL) AS quota_storage_size \ + FROM virtual_users WHERE email='%{user}' + iterate_query = SELECT email as user FROM virtual_users +} + +passdb sql { + query = SELECT password FROM virtual_users where email='%{user}' +} +EOF + + # fix permissions + chown root:root /etc/dovecot/conf.d/99-ispmail-sql.conf + chmod go= /etc/dovecot/conf.d/99-ispmail-sql.conf + + cat > /etc/dovecot/conf.d/99-ispmail-managesieve.conf << EOF +service managesieve-login { + # Listen only on localhost + inet_listener sieve { + listen= 127.0.0.1 + port = 4190 + } + + # Disable the deprecated listener + inet_listener sieve_deprecated { + port = 0 + } +} +EOF + + systemctl restart dovecot + + # Check if running + systemctl is-active --quiet dovecot.service + if [[ $? -ne 0 ]]; then + echo "❌ Dovecot failed to start properly." + exit 10 + fi + echo "✅ Dovecot is running fine." + + # Check query + JOHNS_MAILDIR=$(doveadm user john@example.org | grep ^mail_path | cut -f2) + if [[ $JOHNS_MAILDIR != '/var/vmail/example.org/john/Maildir' ]]; then + echo "❌ Could not find John's mail_path." + exit 10 + fi + echo "✅ Lookup works." +} + +############# LMTP ############### + +lmtp_config() { +# Add an LMTP listening socket in Dovecot + cat > /etc/dovecot/conf.d/99-ispmail-lmtp-listener.conf << EOF +service lmtp { + # Used internally by Dovecot + unix_listener lmtp { + } + + # Listen to LMTP connections from Postfix + unix_listener /var/spool/postfix/private/dovecot-lmtp { + mode = 0600 + user = postfix + group = postfix + } +} +EOF + + # Restart Dovecot + systemctl restart dovecot + + postconf virtual_transport=lmtp:unix:private/dovecot-lmtp + + # Testing delivery + echo Testing email delivery internally. + if [[ -d /var/vmail/example.org/john/Maildir/new/ ]]; then + rm -f /var/vmail/example.org/john/Maildir/new/* + fi + swaks --server localhost --to john@example.org --tls --silent + + DELIVERY=0 + for i in $(seq 1 50); do + NUM_FILES=$(ls -1 /var/vmail/example.org/john/Maildir/new/ | wc -l) + if [[ $NUM_FILES -eq 1 ]]; then + DELIVERY=1 + break + fi + + sleep 0.2 + done + + if [[ $DELIVERY -eq 0 ]]; then + echo "❌ Mail delivery to john@example.org failed." + exit 10 + fi + echo "✅ Test successful." +} + +############ APACHE ############# + +apache_config() { + cat > /etc/apache2/sites-available/000-default-le-ssl.conf << EOF + + ServerAdmin postmaster@$FQDN + ServerName $FQDN + DocumentRoot /var/lib/roundcube/public_html + + ErrorLog \${APACHE_LOG_DIR}/error.log + CustomLog \${APACHE_LOG_DIR}/access.log combined + + SSLCertificateFile /etc/letsencrypt/live/$FQDN/fullchain.pem + SSLCertificateKeyFile /etc/letsencrypt/live/$FQDN/privkey.pem + Include /etc/letsencrypt/options-ssl-apache.conf + Include /etc/roundcube/apache.conf + + + Require all granted + + + RewriteEngine On + RewriteRule ^/rspamd$ /rspamd/ [R,L] + RewriteRule ^/rspamd/(.*) http://localhost:11334/\$1 [P,L] + +EOF + + # Enable the required Apache modules + a2enmod proxy_http -q + a2enmod rewrite -q + + # Restart Apache + systemctl restart apache2 + # Check if running + systemctl is-active --quiet apache2.service + if [[ $? -ne 0 ]]; then + echo "❌ Apache has not started properly." + exit 10 + fi + echo "✅ Apache is running fine." + + # Set imap_host and smtp_host in /etc/roundcube/config.inc.php + sed -i "s|^\s*\$config\['imap_host'\]\s*=.*|\$config['imap_host'] = 'tls://$FQDN:143';|" /etc/roundcube/config.inc.php + sed -i "s|^\s*\$config\['smtp_host'\]\s*=.*|\$config['smtp_host'] = 'tls://$FQDN:587';|" /etc/roundcube/config.inc.php + + # Enable plugins + sed -i "/\$config\['plugins'\] = \[/,/\];/c\\ + \$config['plugins'] = [\\ + 'managesieve',\\ + 'password',\\ + ];" /etc/roundcube/config.inc.php + + # Check if web interface is loading + curl -s https://$FQDN | grep title | grep -q "Roundcube Webmail" + if [[ $? -ne 0 ]]; then + echo "❌ Webmail interface is not reachable at https://$FQDN" + exit 10 + fi +} + +############ Relaying ############# + +relaying_setup() { + postconf -M submission/inet="submission inet n - y - - smtpd" + postconf -P "submission/inet/syslog_name=postfix/submission" + postconf -P "submission/inet/smtpd_tls_security_level=encrypt" + postconf -P "submission/inet/smtpd_sasl_auth_enable=yes" + postconf -P "submission/inet/smtpd_sasl_type=dovecot" + postconf -P "submission/inet/smtpd_sasl_path=private/dovecot-auth" + postconf -P "submission/inet/smtpd_recipient_restrictions=permit_sasl_authenticated,reject" + postconf -P "submission/inet/smtpd_sender_restrictions=reject_sender_login_mismatch,permit_sasl_authenticated,reject" + + postconf -M submissions/inet="submissions inet n - y - - smtpd" + postconf -P "submissions/inet/syslog_name=postfix/submissions" + postconf -P "submissions/inet/smtpd_tls_wrappermode=yes" + postconf -P "submissions/inet/smtpd_sasl_auth_enable=yes" + postconf -P "submissions/inet/smtpd_sasl_type=dovecot" + postconf -P "submissions/inet/smtpd_sasl_path=private/dovecot-auth" + postconf -P "submissions/inet/smtpd_recipient_restrictions=permit_sasl_authenticated,reject" + postconf -P "submissions/inet/smtpd_sender_restrictions=reject_sender_login_mismatch,permit_sasl_authenticated,reject" + + postfix reload 2>/dev/null + + postconf smtp_tls_security_level=encrypt + postconf smtpd_tls_security_level=encrypt + postconf smtp_tls_mandatory_protocols=">=TLSv1.2" + postconf smtpd_tls_mandatory_protocols=">=TLSv1.2" + postconf smtp_tls_mandatory_ciphers=high + postconf smtpd_tls_mandatory_ciphers=high + postconf smtpd_tls_cert_file=/etc/letsencrypt/live/$FQDN/fullchain.pem + postconf smtpd_tls_key_file=/etc/letsencrypt/live/$FQDN/privkey.pem + + # Create a mapping configuration from the user to themself + cat > /etc/postfix/mariadb-email2email.cf << EOF +user = mailserver +password = MAILSERVER-PASSWORD-HERE +hosts = 127.0.0.1 +dbname = mailserver +query = SELECT email FROM virtual_users WHERE email='%s' +EOF + + # Fix permissions + chown root:postfix /etc/postfix/mariadb-email2email.cf + chmod u=rw,g=r,o= /etc/postfix/mariadb-email2email.cf + + # Tell Postfix to use this mapping + postconf smtpd_sender_login_maps=mysql:/etc/postfix/mariadb-email2email.cf + + # Test spoofing + set +e + swaks --server localhost:587 \ + --from brunhilde@example.org \ + --to list@example.com \ + --tls \ + --auth-user john@example.org \ + --auth-password summersun \ + --silent 3 + + if [[ $? -ne 24 ]]; then + echo "❌ Forged sender spoofing test failed." + exit 10 + fi + set -e + echo "✅ Forged sender spoofing successfully rejected." + + # Test with proper email + set +e + swaks --server localhost:587 \ + --from john@example.org \ + --to list@example.com \ + --tls \ + --auth-user john@example.org \ + --auth-password summersun \ + --silent 3 + + if [[ $? -ne 0 ]]; then + echo "❌ Relaying of proper email failed." + exit 10 + fi + set -e + echo "✅ Relay test okay." + + # Submission plaintext test + set +e + swaks --server localhost:587 \ + --from john@example.org \ + --to lisa@example.com \ + --silent 3 + if [[ $? -ne 23 ]]; then + echo "❌ Relaying over submission without STARTTLS was accepted." + exit 10 + fi + set -e + echo "✅ Plaintext auth refused via submission port." + + # Submission encryption but no auth test + set +e + swaks --server localhost:587 \ + --from john@example.org \ + --to lisa@example.com \ + -tls \ + --silent 3 + if [[ $? -ne 24 ]]; then + echo "❌ Relaying over submission with STARTTLS but without auth was accepted." + exit 10 + fi + set -e + echo "✅ Encrypted non-auth refused via submission port." + + # Test encryption and auth over submission + set +e + swaks --server localhost:587 \ + --from john@example.org \ + --to lisa@example.com \ + -tls \ + --auth-user john@example.org \ + --auth-password summersun \ + --silent 3 + if [[ $? -ne 0 ]]; then + echo "❌ Relaying over submission with STARTTLS and auth failed." + exit 10 + fi + set -e + echo "✅ Encrypted and authenticated relaying over submission works." + + # Test encryption and auth over submissions + set +e + swaks --server localhost:465 \ + --from john@example.org \ + --to lisa@example.com \ + --tls-on-connect \ + --auth-user john@example.org \ + --auth-password summersun \ + --silent 3 + if [[ $? -ne 0 ]]; then + echo "❌ Relaying over submissions with STARTTLS and auth failed." + exit 10 + fi + set -e + echo "✅ Encrypted and authenticated relaying over submissions works." +} + +############ IMAP ############## + +imap_test() { + # Test IMAP access + apt-get -qq install fetchmail + cat > ~/.fetchmailrc </dev/null + rm ~/.fetchmailrc + if [[ $? -ne 0 ]]; then + echo "❌ IMAP connection failed" + exit 10 + fi + set -e + echo "✅ IMAP connection test successful." +} + +############ rspamd ############# + +rspamd_config() { + postconf smtpd_milters=inet:127.0.0.1:11332 + postconf non_smtpd_milters=inet:127.0.0.1:11332 + postconf inet_protocols=all + systemctl restart postfix + + cat > /tmp/gtube.txt < /etc/dovecot/conf.d/99-ispmail-sieve-movetojunk.conf << 'EOF' +sieve_script spam-to-junk-folder { + driver = file + type = after + path = /etc/dovecot/sieve/spam-to-junk-folder.sieve +} + +# Enable the execution of Sieve rules when Postfix sends an email to Dovecot over LMTP +protocol lmtp { + mail_plugins { + sieve = yes + } +} + +# Make sure that every user has a Junk folder and is subscribed to it +namespace inbox { + mailbox Junk { + special_use = \Junk + auto = subscribe + } +} +EOF + + # Restart Dovecot + systemctl reload dovecot + + # Create the directory for Sieve files + mkdir -p /etc/dovecot/sieve + + # Create the Sieve script to move Spam mails to the user's Junk folder + cat > /etc/dovecot/sieve/spam-to-junk-folder.sieve << 'EOF' +require ["fileinto"]; + +if header :contains "X-Spam" "Yes" { + fileinto "Junk"; + stop; +} +EOF + + # Make the sieve script machine-readable + sievec /etc/dovecot/sieve/spam-to-junk-folder.sieve 2>/dev/null + + # Create a config file to enable automatic spam training + cat > /etc/rspamd/local.d/classifier-bayes.conf << 'EOF' +# Store training data in the Redis database +servers = "127.0.0.1:6379"; +backend = "redis"; + +# Enable automatic training +autolearn = true; # if rspamd is sure that an email is spam, it will be learned +min_learns = 200; # do not trust the data before at least 200 mails have been learned +EOF + + # Restart rspamd + #systemctl restart rspamd + + cat > /etc/dovecot/conf.d/99-ispmail-imapsieve.conf << 'EOF' +# Enable the imap_sieve plugin +protocol imap { + mail_plugins { + imap_sieve = yes + } +} + +# Allow the use of the pipe plugin to send mails to shell scripts +sieve_plugins { + sieve_extprograms = yes + sieve_imapsieve = yes +} + +sieve_global_extensions { + vnd.dovecot.pipe = yes +} + +# Where to look for Sieve scripts that use the Pipe functionality +sieve_pipe_bin_dir = /etc/dovecot/sieve + +# Moved into Junk? -> Learn as spam. +mailbox Junk { + sieve_script spam { + type = before + cause = copy + path = /etc/dovecot/sieve/learn-spam.sieve + } +} + +# Moved out of Junk? -> Learn as ham. +imapsieve_from Junk { + sieve_script ham { + type = before + cause = copy + path = /etc/dovecot/sieve/learn-ham.sieve + } +} +EOF + + # Create spam learning script + cat > /etc/dovecot/sieve/learn-spam.sieve << 'EOF' +require ["vnd.dovecot.pipe", "copy", "imapsieve"]; +pipe :copy "rspamd-learn-spam.sh"; +EOF + + # Create ham learning script + cat > /etc/dovecot/sieve/learn-ham.sieve << 'EOF' +require ["vnd.dovecot.pipe", "copy", "imapsieve", "variables"]; +pipe :copy "rspamd-learn-ham.sh"; +EOF + + # Compile the Sieve scripts + systemctl reload dovecot + sievec /etc/dovecot/sieve/learn-spam.sieve 2>/dev/null + sievec /etc/dovecot/sieve/learn-ham.sieve 2>/dev/null + + # Fix permissions + chmod u=rw,go= /etc/dovecot/sieve/learn-{spam,ham}.{sieve,svbin} + chown vmail:vmail /etc/dovecot/sieve/learn-{spam,ham}.{sieve,svbin} + + # Create the shell script for learning spam + cat > /etc/dovecot/sieve/rspamd-learn-spam.sh << 'EOF' +#!/bin/sh +# Receives an email from Dovecot's Sieve script and pipe it into rspamc +exec /usr/bin/rspamc learn_spam +EOF + + # Create the shell script for learning ham + cat > /etc/dovecot/sieve/rspamd-learn-ham.sh << 'EOF' +#!/bin/sh +# Receives an email from Dovecot's Sieve script and pipe it into rspamc +exec /usr/bin/rspamc learn_ham +EOF + + # Fix permissions of the shell scripts + chmod u=rwx,go= /etc/dovecot/sieve/rspamd-learn-{spam,ham}.sh + chown vmail:vmail /etc/dovecot/sieve/rspamd-learn-{spam,ham}.sh + + cat > /etc/dovecot/conf.d/99-ispmail-sieve-debug.conf << 'EOF' +# Enable detailed logging of Sieve scripts +log_debug=category=sieve +EOF + + cat > /etc/dovecot/conf.d/99-ispmail-autoexpunge.conf << 'EOF' +# Remove mails from the Junk and Trash folders after 30 days +mailbox Junk { + special_use = \Junk + auto = subscribe + mailbox_autoexpunge = 30d +} +mailbox Trash { + special_use = \Trash + auto = subscribe + mailbox_autoexpunge = 30d +} + +# Make expunging more efficient +mailbox_list_index = yes +mail_always_cache_fields = date.save +EOF + + # Restart Dovecot + systemctl restart dovecot + + # Generate a random password that is 15 characters long + RSPAMD_PW=$(pwgen 15 1) + + # Create a hash of that password + HASH=$(rspamadm pw -p $RSPAMD_PW) + + # Add the hashed password to rspamd's configuration + echo "password = \"$HASH\"" > /etc/rspamd/local.d/worker-controller.inc + + # Restart rspamd + systemctl reload rspamd + + echo "✅ rspamd set up" +} + +############ Show summary at the end ############# + +dkim_config() { + postconf smtpd_milters=inet:127.0.0.1:11332 + postconf non_smtpd_milters=inet:127.0.0.1:11332 + + # Create the directory + mkdir -p /var/lib/rspamd/dkim + + # Fix permissions + chown _rspamd:_rspamd /var/lib/rspamd/dkim + + # Tell rspamd to look up selectors in our mapping file + cat > /etc/rspamd/local.d/dkim_signing.conf << 'EOF' +path = "/var/lib/rspamd/dkim/$domain.$selector.key"; +selector_map = "/etc/rspamd/dkim_selectors.map"; +EOF + + # TODO: create a key for $FQDN and test it + + # Restart rspamd + systemctl restart rspamd + + echo "✅ DKIM signing ready to use" +} + +############ Catch-all aliases ############# + +catchall_config() { + # Create the john-to-himself mapping + cat > /etc/postfix/mariadb-email2email.cf << EOF +user = mailserver +password = MAILSERVER-PASSWORD-HERE +hosts = 127.0.0.1 +dbname = mailserver +query = SELECT email FROM virtual_users WHERE email='%s' +EOF + + # Fix the permissions of that file + chgrp postfix /etc/postfix/mariadb-*.cf + chmod u=rw,g=r,o= /etc/postfix/mariadb-*.cf + + # Add the new mapping to the virtual_alias_maps + # (The order is not important. Postfix will check all mapping files.) + postconf virtual_alias_maps=mysql:/etc/postfix/mariadb-virtual-alias-maps.cf,mysql:/etc/postfix/mariadb-email2email.cf + + result=$(postmap -q john@example.org mysql:/etc/postfix/mariadb-email2email.cf) + + if [[ $result != "john@example.org" ]]; then + echo "❌ email2email mapping for catch-all aliases do not work properly" + exit 10 + fi + set -e + echo "✅ Catch-all aliases ready to use." +} + +############ Quota config ############# + +quota_config() { + cat > /etc/dovecot/conf.d/99-ispmail-quota.conf << 'EOF' +# Enable the quota plugin +mail_plugins { + quota = yes +} + +# Set global defaults. Keep this outside of a "quota {}" section so that it +# can be overriden with data from the virtual_users table. +# Allow 5 GB of space per default. +quota_storage_size = 5G + +# It is important to allow it so that Postfix can deliver an email to +# bring the user above 100% of quota usage. Otherwise you risk that the user +# is at 99.99% of quota but the last email cannot be delivered and gets stuck +# between Postfix and Dovecot. No email should be larger than this. +quota_storage_grace = 50M + +# Define two warnings at 80% and 95% of quota usage. +quota "User quota" { + # Set one warning level to 100% + warning warn-100 { + quota_storage_percentage = 100 + execute quota-warning { + args = 100 %{user} + } + } + + # Set another warning level to 80% for early warnings + warning warn-80 { + quota_storage_percentage = 80 + execute quota-warning { + args = 80 %{user} + } + } + + # User is no longer over quota + warning warn-under { + quota_storage_percentage = 100 + threshold = under + execute quota-warning { + args = below %{user} + } + } +} + +# Define what happens if the user goes over quota. Point to a script that +# creates a warning email to the user. The name "quota-warning" corresponds +# to the "execute" statement in the warning definitions. +service quota-warning { + executable = script /usr/local/bin/ispmail-quota-warning.sh + unix_listener quota-warning { + mode = 0660 + user = vmail + group = vmail + } +} + +# Add a new service so that Postfix can check if a user is over quota. +# It listens on TCP port 13373. +service quota-status { + executable = quota-status -p postfix + inet_listener quota-status { + listen = 127.0.0.1 + port = 13373 + } + client_limit = 1 +} + +# Enable the IMAP QUOTA extension, allowing IMAP clients to ask for the +# current quota usage. Roundcube displays the current space usage in +# the lower left corner. +protocol imap { + mail_plugins { + imap_quota = yes + } +} +EOF + +# Apply the configuration +systemctl reload dovecot + +cat > /usr/local/bin/ispmail-quota-warning.sh << 'EOF' +#!/bin/bash +# +# This script is part of the ISPmail configuration. +# It is called from /etc/dovecot/conf.d/99-ispmail-quota.conf +# and sends an email to the user if the quota is at 80%, over 100% +# or back below 100%. +# +# Christoph Haas +# Version 1.0 – 2025-12-30 + +LEVEL=$1 +USER=$2 +MAIL="From: postmaster@${USER#*@}" +MAIL+="\nSubject: Quota information" +MAIL+="\nX-Priority: 1" +MAIL+="\n\nThis is an automatic email from your friendly mail server.\n\n" + +if [ $LEVEL = "below" ]; then + MAIL+="Thanks for making some space. You will now be able to receive emails again." +elif [ $LEVEL -eq 80 ]; then + MAIL+="Your mailbox is currently using up 80% of the maximum space." + MAIL+="\nPlease consider deleting some emails. If your used space reached" + MAIL+="\n100% then you would not be able to receive further emails. I will" + MAIL+="\nhowever send you another email in that case." + MAIL+="\n" + MAIL+="\nThanks for your attention." +elif [ $LEVEL -eq 100 ]; then + MAIL+="I am afraid to tell you that your mailbox is now 100% full." + MAIL+="\nNew emails to your address will be rejected by the server." + MAIL+="\nPlease delete some emails immediately. I will send you another" + MAIL+="\nemail once you have made some space." + MAIL+="\n" + MAIL+="\nThanks for your attention." +fi + +echo -e $MAIL | /usr/lib/dovecot/dovecot-lda -d $USER -o quota_enforce=no +EOF + + chmod u=rwx,g=rx,o= /usr/local/bin/ispmail-quota-warning.sh + chown vmail:vmail /usr/local/bin/ispmail-quota-warning.sh + + # Apply the configuration + systemctl reload dovecot + + # Check if Dovecot tells us quota information + lines=$(doveadm quota get -A | grep -c john@example.org) + if [ $lines -ne 2 ]; then + echo "❌ The quota setup is not working. Check 'doveadm quota get -A'." + exit 1 + fi + + mariadb mailserver -Bse 'update virtual_users set quota=0 where email="john@example.org";' + quota_storage_check=$(dovecot quota get -u john@example.org | grep STORAGE | awk '{print $5}') + if [ $quota_storage_check -ne 5242880 ]; then + echo "❌ The quota storage value for John should be 5 GB. But it's not." + exit 1 + fi + + mariadb mailserver -Bse 'update virtual_users set quota=1024000 where email="john@example.org";' + quota_storage_check=$(dovecot quota get -u john@example.org | grep STORAGE | awk '{print $5}') + if [ $quota_storage_check -ne 1000 ]; then + echo "❌ The overriden quota storage value for John should be 1000 KB. But it's not." + exit 1 + fi + + echo "✅ Quotas are ready to use." +} + +############ Going-live ############# + +going_live() { + # Create two random passwords + PW_MAILADMIN=$(pwgen -s 32 1) + PW_MAILSERVER=$(pwgen -s 32 1) + + # Replace the dummy passwords + sed -i "s|MAILADMIN-PASSWORD-HERE|$PW_MAILADMIN|g" /etc/roundcube/plugins/password/config.inc.php + + sed -i "s|MAILSERVER-PASSWORD-HERE|$PW_MAILSERVER|g" \ + /etc/dovecot/conf.d/99-ispmail-sql.conf \ + /etc/postfix/mariadb-virtual-mailbox-maps.cf \ + /etc/postfix/mariadb-virtual-mailbox-domains.cf \ + /etc/postfix/mariadb-virtual-alias-maps.cf \ + /etc/postfix/mariadb-email2email.cf + + # Restart the services + systemctl restart postfix dovecot + + # Update MariaDB user passwords + mariadb <>KAASEFw9fHy#{5D?i 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 literal 0 HcmV?d00001 diff --git a/dist/linux/renaming-multiple-files/index.html b/dist/linux/renaming-multiple-files/index.html new file mode 100644 index 0000000..fe9e9d9 --- /dev/null +++ b/dist/linux/renaming-multiple-files/index.html @@ -0,0 +1,97 @@ + Renaming multiple files | ISPmail Guide + Skip to content

Renaming multiple files

If you need to rename a larger number of files following a certain pattern then you will long for an automated solution. The ‘rename’ command helps you here that is (at least on my Debian installation) part of the Perl installation. All you need to know is the basics of regular expressions to define how the renaming should happen.

+

Say you want to add a ‘.old’ to every file in your current directory. At the end of each expression ($) a ‘.old’ will be set:

+
rename 's/$/.old' *
+

Or you want to make the filenames lowercase:

+
rename 'tr/A-Z/a-z/' *
+

Or you want to remove all double characters:

+
rename 'tr/a-zA-Z//s' *
+

Or you have many JPEG files that look like “img0000154.jpg” but you want the first five zeros removed as you don’t need them:

+
rename 's/img00000/img/' *.jpg
+

In fact you can use any Perl operator as an argument. The actual documentation for the ‘s’ and ‘y’/’tr’ operators are found in the ‘perlop’ manpage.

\ No newline at end of file diff --git a/dist/linuxtip/pipes/index.html b/dist/linuxtip/pipes/index.html new file mode 100644 index 0000000..e6dd1df --- /dev/null +++ b/dist/linuxtip/pipes/index.html @@ -0,0 +1,159 @@ + Pipes and redirection | ISPmail Guide + Skip to content

Pipes and redirection

Many system administrators seem to have problems with the concepts of pipes and redirection in a shell. A coworker recently asked me how to deal with log files. How to find the information he was looking for. This article tries to shed some light on it.

+ +

Many of the basic Linux/UNIX shell commands work in a similar way. Every command that you start from the shell gets three channels assigned:

+
    +
  • STDIN (channel 0):
    +Where your command draws the input from. If you don’t specify anything special this will be your keyboard input.
  • +
  • STDOUT (channel 1):
    +Where your command’s output is sent to. If you don’t specify anything special the output is displayed in your shell.
  • +
  • STDERR (channel 2):
    +If anything wrong happens the command will send error message here. By default the output is also displayed in your shell.
  • +
+

Try it yourself. The most basic command that just passes everything through from STDIN to STDOUT is the ‘cat’ command. Just open a shell and type ‘cat’ and press Enter. Nothing seems to happen. But actually ‘cat’ is waiting for input. Type something like “hello world”. Every time you press ‘Enter’ after a line ‘cat’ will output your input. So you will get an echo of everything you type. To let ‘cat’ know that you are done with the input send it an ‘end-of-file’ (EOF) signal by pressing Ctrl-D on an empty line.

+ +

A more interesting application of the STDIN/STDOUT is to chain commands together. The output of the first command becomes the input of the second command. Imagine the following chain:

+

Diagram of STDIN, STDOUT and STDERR

+

The contents of the file /var/log/syslog are sent (as input) to the grep command. grep will filter the stream for lines containing the word ‘postfix’ and output that. Now the next grep picks up what was filtered and filter it further for the word ‘removed’. So now we have only lines containing both ‘postfix’ and ‘removed’. And finally these lines are sent to ‘wc -l’ which is a shell command counting the lines of some input. In my case it found 27 of such lines and printed that number to my shell. In shell syntax this reads:

+
cat /var/log/syslog | grep 'postfix' | grep 'removed' | wc -l
+

The ‘|’ character is called pipe. A sequence of such commands joined together with pipes are called pipeline.

+ +

Actually ‘cat’ is supposed to be used for concatenating files. Like “cat file1 file2”. But some administrators abuse the command to put something into a pipeline. That’s bad style and the reason why Randal L. Schwartz (a seasoned programmer) used to hand out virtual “Useless use of cat” awards. Shell commands usually can take a filename as the last argument as an input. So this would be right:

+
grep something /var/log/syslog | wc -l
+

While this works but is considered bad style:

+
cat /var/log/syslog | grep something | wc
+

Or if you knew that grep even has a “-c” option to count lines the whole task could be done with just grep:

+
grep -c something /var/log/syslog
+ + +

Instead of using the console for input and the screen for output you can use files instead. While

+
date
+

shows you the current date on the console you can use

+
date >currentdatefile
+

to redirect the output of the command (STDOUT) to the file named ‘currentdatefile’.

+ +

This also works as input. The command

+
grep something
+

will search for the word ‘something’ in what you type on your keyboard. But if you want to look for ‘something’ in a file called ‘somefile’ you could run

+
grep something <somefile
+ +

You can also redirect both input and output in the same command. A politically incorrect way to copy a file would be

+
cat <oldfile >newfile
+

Of course you would use cp for that purpose in real life.

+ +

So far this covers STDIN (<) and STDOUT (>) but you also redirect the STDERR channel by using (2>). An example would be

+
grep something <somefile >resultfile 2>errorfile
+ +

Many admins stumble when it comes to redirecting one channel to another. Say you want to redirect both STDOUT and STDERR to the same file. Then you cannot do

+
grep something >resultfile 2>resultfile
+

It will only redirect the STDOUT (>) there and keep the ‘resultfile’ open so “2>” fails to write to it. Instead you need to do

+
grep something >resultfile 2>&1
+

This redirects STDOUT (1) to the ‘resultfile’ and tells STDERR (2) to send the output to what STDOUT is set to (also ‘resultfile’).

+

What does not work is this order:

+
grep something 2>&1 >resultfile
+

It may look right to us humans but in fact does not redirect STDERR to the ‘resultfile’. The explanation: the shell interprets this line from left to right. So first the “2>&1” is evaluated which means “send STDERR to the same that STDOUT is currently set to”. As STDOUT is usually just printed to the shell it will send STDERR also to the shell. Next the shell finds “>resultfile” which sends STDOUT to the ‘resultfile’ but does not touch the previous destination of STDERR. So STDERR output will still end up in the shell.

+ +
    +
  • grep
    +Filters out lines with certain search words. “grep -v” searches for all lines that do not contain the search word.
  • +
  • sort
    +Sort the output alphabetically (needs to wait until EOF before doing its work). “sort -n” sorts numerically. “sort -u” filters out duplicate lines.usel
  • +
  • wc
    +Word count. Counts the bytes, words and lines. “wc -l” just outputs how many lines were counted.
  • +
  • awk
    +A sophisticated language (similar to Perl) that can be used to do something with every line. awk ‘{print $3}' outputs the third column of every line.
  • +
  • sed (stream editor)
    +A search/replace tool to change something in every line.
  • +
  • less
    +Useful at the end of a pipe. Allows you to browse through the output one page at a time. (“less” refers to a similar but less capable tool called “more” that allowed you to see the first page and then press ‘Space’ to view ‘more’.)
  • +
  • head
    +Shows the first ten lines only. “head -50” shows the first 50 lines.
  • +
  • tail
    +Shows the last ten lines only. “tail -50” shows the last 50 lines. “tail -f” follows a certain file.
  • +
\ No newline at end of file diff --git a/dist/pagefind/fragment/en_1e55a7e.pf_fragment b/dist/pagefind/fragment/en_1e55a7e.pf_fragment new file mode 100644 index 0000000000000000000000000000000000000000..777dbe3abb7ae78e792cd7bcdc9878bb16d05665 GIT binary patch literal 4812 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 literal 0 HcmV?d00001 diff --git a/dist/pagefind/fragment/en_1fe6967.pf_fragment b/dist/pagefind/fragment/en_1fe6967.pf_fragment new file mode 100644 index 0000000000000000000000000000000000000000..44f7d2aa5182104e1b39c7f1d0bc22abd466f2a2 GIT binary patch literal 3636 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 GA^-pZW*r{@ literal 0 HcmV?d00001 diff --git a/dist/pagefind/fragment/en_24d7d48.pf_fragment b/dist/pagefind/fragment/en_24d7d48.pf_fragment new file mode 100644 index 0000000000000000000000000000000000000000..cfac500870504e2cab93fa520a5032f511730eaa GIT binary patch literal 2444 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 KS-_Oa6951u(6OQb literal 0 HcmV?d00001 diff --git a/dist/pagefind/fragment/en_26eddc6.pf_fragment b/dist/pagefind/fragment/en_26eddc6.pf_fragment new file mode 100644 index 0000000000000000000000000000000000000000..bd9b456e659a4f88fa7c38f0ca47412ec15c4b38 GIT binary patch literal 3533 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 H2O$6e>I~lK literal 0 HcmV?d00001 diff --git a/dist/pagefind/fragment/en_38c9179.pf_fragment b/dist/pagefind/fragment/en_38c9179.pf_fragment new file mode 100644 index 0000000000000000000000000000000000000000..66bdce9a201e2a1ac6caf5a11c9a149bfab42ec4 GIT binary patch literal 2098 zcmV-22+j8&iwFP!00002|D{;nZrer{ewBf+7dBuqv1L130o$#!*)0UD1Ecmuip9bh zl0#`Ca)zB5N>+jZ#=gK_v^OnUv{!wGK966ZeT07J3`tRmk^*UvAQEThn{&?hogb=} zb5&@Q-{x8VdepdbG#x$CzOJM$$Emf;wRP1auR_pfKF*CFJC#|N`$warQD#k0Cg8}! zcR&65%m2mALVHmIQtV?!VuzKHUExuB|Y3 zEjG3h3%OGC!3kKhBviK5E4NZE5l@>S7TB6wVPTmYu6i+7K?Ez7E!f`?10|&KWPORd zgf{F?WqlC3s;vvs1U{}aC2U;P2&6MAOxdA_`>*-wGmEQ?crGg?t~Wj?gz3WjrlJtZ zAmq>#;ccbXu&)P=)+&>CEOfVsHB9hiwx?BuRWT4AytE7RnYxozU8=;odBXm*H&hLL zAhigKm@rFZ+JVHA*_Dua?v(e3-E~9buuxm$by`L`X?<`Ff=jL@Q9<}i0cRhH5Q?bOxf34l?Oa;cBs7=xou;5%($$IY&YX>EZt8&*tvY(##z?PB8zutdzL=pbTkPIcK!cBHYS_t%|uW_~E3 zvm!#YTQf#7HV_(eBU>mAi)p*X9WD5NJNw#S2>JGwpuyzqn@2r2k+`zlHUfBsN{^)D zj$qe@tII2ExTzt*DHLrl*@)Vrs8Y+oF+Q+E3Va}3Dz~&DCOMUWrrx3JASN;JQCK~- zyq030*}DCL#n1%!Bg@0+I6-GHhHU~AsL6*^ORnr+HK-$~1H`WDL&AcA=;Tsy;}Es7 z#9BoUa8={UDV*Qdb&APQ!&KR5D{+Dd0zL=oU=N2WwRB1>TK`Emc8;jeT=~5D^Sxo+j!x*m&4>r8*tzxX!SjnzR8F?1a#aZ zL{`~+rBL#1mxmly9XRmZ-jM^uoK49R$$3i3;Y_M!RZ)|$MWDQKBv6XM#xY~MZgfOb4$kWv*T!GpT=}o@Uh#u@L^t^GLtdF|D?xX&aA@?PxJYnVdx$U7LgF6Y7QfnOSM7Q&?4Zb*VEP z+{EI)Gkx|c(hdskusKZAHoou^h6k!`>>Qn3mA9n2!Jrm(h?Iq z^w7;+gH&uAmx)tmJ7Us++8f1qR27N!!2p-qwo|QD+KF*10&d>tY9@ zh2DvlhxHj^kQ0s4#DRI>0W0?Ha?*tfr`I+Hm4?(rd_l29I-y_eqkOPTL|;m?*(DP# zjr(;cDVV#Ki0}dP4k^s8Vpn!8(g94xV_H5$4$8bs7f%P`B;t2xY9zB?a4RIgJ1mC>X4}T{JoiZ0kfslIKzm zm7ikANphTMGbSDq>1vrALNiyZ^L=rp=M+#B`Op}!SyEgPT)cErg)oeYR_C~FSenNe ztj!kfFg^r+&){i5M{V-VCdEoSZZVyN9EL-Qa$#3!)2$XFaqT%-Vz8Lo5Su4%>C?e` zJvY=OXKjJW=!LgGV^mCdZYj8+2K?alw#_gSDuk!X60ZShP=AU-{E2&uT&2^=ll;k4 z6_Zb<>hbwxIz8U^_`?MM0|}E+Q*f#mGCR~3AH37VavejnQOMQLsbOe}H9ArGI$jL}rPxay}(gy+g+xQ@k_vVM%CHz>Z$a$8O5)z|A+z(pvZU)=BvW0nHRQbISV z-@pC%?f>w@2E>rxV&bIVHl9o-N25ZQSofpp>o-TEN(G5eBVFN_4*I?1R-*ISeZP{7 ztGjWk=VMIb=>00$++KbDrF;JB_M}`c)0YW~Q;qu==@zj8+EYCj?RFYwC~3FloGT3u zu==ri&(9zuSO^jpmdyRn>yau|6@R2z9Me@fKHUaO*9J_@?*Ta)ab-lNjix7$-yH4W zoOC$wu5DdgwC&F5J%1mL cu2<(<0MhQx$@9tCoBzJ~9XJsR*Gv-t0M6waivR!s literal 0 HcmV?d00001 diff --git a/dist/pagefind/fragment/en_3dd5273.pf_fragment b/dist/pagefind/fragment/en_3dd5273.pf_fragment new file mode 100644 index 0000000000000000000000000000000000000000..2de1e55da4b6c7660ecce44b9dd4053d50f24459 GIT binary patch literal 3860 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 WW}D>Z_E)#R-Togwe`$v}DgXevig(xm literal 0 HcmV?d00001 diff --git a/dist/pagefind/fragment/en_4272b66.pf_fragment b/dist/pagefind/fragment/en_4272b66.pf_fragment new file mode 100644 index 0000000000000000000000000000000000000000..5156491be3f39f440f8ad1a7694bb0bedaf9abb0 GIT binary patch literal 7023 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 literal 0 HcmV?d00001 diff --git a/dist/pagefind/fragment/en_4f8ce9a.pf_fragment b/dist/pagefind/fragment/en_4f8ce9a.pf_fragment new file mode 100644 index 0000000000000000000000000000000000000000..cfe808b99fec88030110a2021ada401ecf9b81b7 GIT binary patch literal 7619 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 literal 0 HcmV?d00001 diff --git a/dist/pagefind/fragment/en_502bf76.pf_fragment b/dist/pagefind/fragment/en_502bf76.pf_fragment new file mode 100644 index 0000000000000000000000000000000000000000..45e5a8dcf4f57417529b97322aa62709dbe66f97 GIT binary patch literal 2825 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 bW$cV)@Et7v;`t|U|N8cS9k9aT8W;comAI!f literal 0 HcmV?d00001 diff --git a/dist/pagefind/fragment/en_522bb3c.pf_fragment b/dist/pagefind/fragment/en_522bb3c.pf_fragment new file mode 100644 index 0000000000000000000000000000000000000000..e5752136fc9eb781c0af8b6e02996d8c9714ea31 GIT binary patch literal 1463 zcmV;o1xWfIiwFP!00002|CLw&Y8yuoew9I?#3|A_2@M4iw^dx3v^aH;O-(7qtnT)7 z8{OTWclUe}#^878UxoJN{3QKm_wFpoN+8(S_hWv1GxN>NUL_VXRb_IO#L4ZTHu+#Y zI8?SOgvv+GsFjk3v2bxV5_x_&7!G1xI$1i19e0mOB#DvMN*mEx<&-W(PN@{GHj*wf zWvPM}!ha|#Bl9)sRxG0PrK(6dQYo!N}XZ;GXHe3KvyRSFJxTPX_3!EX%HFexa0%qe4M35|gK zjkMwQW)cAH(JNBeLr3(slCervOgGB78gbPY!9t~0@N>zedB4G36e5gglv zXPBAk_3#=6aj4F3`}L8rfO|ppMiV zLBq|MEGi$%&ED9A7VWqFE>t*B92_awsy83eM{QlIR-xjesxW03ZPz*nE$grRgR258 zdja02%;7}l3S{vErtMK52kY;2WH66nF@JJjrM?>jzJ_&5AG+iAc6tkk6Z70>xia#G zS<8Jj4i>&L8@u(~_hc(8nB7+St_q#o&W8?Ks^A1H1tFeL1%YfU0roD)Bg zm%dWYtU0#`8f?S>+qLc+rJvE9c#T_-QE>nJHG)Rn({i4?k8$*m8*P?Du0$ziTZUXY z$B8#8Ml#nsnc+snkYVE}mgN~zRlpp^qX(_i@zb;%6tL1GcoEU|+n)Ik_kUB4fwCpr zO@Cdx+^>{&5w%P`c=G}<%655%R~M6ar&BtgPG-mN>1_7%bcR6}GhuwoW7zQW>;_ff zAZh`=ZdH$Y3+|cqV|ZKBpZx+sjx?QUfB`3YYq!)!913>=`?A0b@4^fA&Nxpar$?D8 ztjtq(*Cy0&kWdxf4kr{bOc^Lfu@_DiN_8k*d{~7l9TsbQosT@o*P%gU)MHkcp}J@o zze?Jv|BQ}<>2B<8fa#D#Oep$c$Bn=VAerwtqPK5pdUg_pfqCSq8azd)j=XTMKpqmPsG^Gnoc^nN;!au2*ymAz_l!Zoh?j7ZM^$~ z{}v&$V1X@IADL#jI5Iq59{c&WZey$on?s{;fsO0<0{rQe>8me=H+mJ>fvy22jknj z;h>OC;A-F$#`FHKiUGt#8E2Yx{=6N?To&OIBzpz>D#6v2(-p3rTz%%#1TS+P``tPi Rzr6eF?te>DPj&hX008K~#C-q& literal 0 HcmV?d00001 diff --git a/dist/pagefind/fragment/en_52c8caf.pf_fragment b/dist/pagefind/fragment/en_52c8caf.pf_fragment new file mode 100644 index 0000000000000000000000000000000000000000..12b30453d0bb11e5842abd3eed02f48d0d6d1f06 GIT binary patch literal 4454 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 literal 0 HcmV?d00001 diff --git a/dist/pagefind/fragment/en_59ca778.pf_fragment b/dist/pagefind/fragment/en_59ca778.pf_fragment new file mode 100644 index 0000000000000000000000000000000000000000..a85b0ac6673c0442a2edbe77816267c8e64b3040 GIT binary patch literal 2241 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 P{r%m~7IPj-%M}0schq0k literal 0 HcmV?d00001 diff --git a/dist/pagefind/fragment/en_5b29cf4.pf_fragment b/dist/pagefind/fragment/en_5b29cf4.pf_fragment new file mode 100644 index 0000000000000000000000000000000000000000..bb1bd8254a4d450287d7efb4ee0c4a4caf066925 GIT binary patch literal 3604 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 aK$Wc*1A@oz+<*Pu>;D2$X+L|%A^-q5B>qwW literal 0 HcmV?d00001 diff --git a/dist/pagefind/fragment/en_60b4bbb.pf_fragment b/dist/pagefind/fragment/en_60b4bbb.pf_fragment new file mode 100644 index 0000000000000000000000000000000000000000..a2576ca539d291cf1ec8612c0c90234925ed736d GIT binary patch literal 2466 zcmV;T30?LdiwFP!00002|E*ZvjvKcXeic@|a8m4ycGq!`2uT6|rrX5M*6SiDio&3V z91WupIVCyL3Wfo{L$3<7w|y`_NxySAGn$chQ=geXeq zh1Z2PTVq#3lgN;Z3-RpL4Snyt3ZikwMiHIZyVi@K{Z{*2T#D~>6ml$Bl-_N`4>~>w z;<+vSzKOYbD6UYf-q(rnRJ>B19Gn2O$%85F5*qS*1nRb~pj6TnJ`a zYsl|IG?st$^6~Zj`p4^sQzf6@5wG5B327A83g&h}mP&aY0s>D^+eo_?%HbCam_6ZO z9)(eufatZdM#N1BE#gQwr3gSM#J~8{vsb|GTC)YYzLlG%*17X5;JT8Lt%bu@ZdjJI z!fYDnqXdW>>7#HZN8>nkn-)d`YDL9A^L<7xYJ~P5`i5~$~w5-f2cdX_>*^b^$9A&CN}36!(But1wP)R_?L9vI8jv2Argox zCxTM5KQbW~FYs-5QCxB4I@IS>QPR8CDw3Emu@|VX;H*3dcnYJIRJ}KdDW=(Atxd5OOb*CD z?DgOjswpzeHIxZpSQ9(`XHdKle-0`1e|STTR8d6jibcRsQ<7hhK|XOlir7`R71X1= ztNW59-&0BS-Zgc*GByzmV2!MzDsihctJWvdgBm8bLL)J3f={{RJ}}RBx~{Xebvrwk z#YSg?fphYrkLm#xWPk~rVo|nasBEL79#l{-0Fj5}kaA!(3nMkLcLJajA-d*NEa>t#L(*Kekqj%k#@eCxGRC#8!{QrRK_sF=ev(h=}Eq z8Xh%;+s2G*X^4o|R_{=`B}}C{dgXRf$vyX3qI&kpYT}~7A@qO^%uPH*z9Qbyd1$R6 zPXB;7!GHvO8IZ>5AZj=c1%E~!Hi5kXmXu*&=fg>K zvdUQ?2z>JoIIwge7?PC|57lbHC{3L#DLrZ_Lr)y|w8K>;Irhs`GAO?yrkZ!mGsqIPc0t#2W2BoAy#FWVKqUoq6T($DdEUh5dTE33O5u@N%kbIjQ22fC{AarCuisy+-l)NFbcggv<-D(3MUgYjrGg@Li`S-YbAe=5MAB8{!YxN z`^#c*Wn4%EH$^v*lBta6FJ2t3=&~FgMPz?{_wVl51~Y8JH0Nrm0ptP%22@keyRx5H zQyf|@3)(-4FI-C#52z}MM^{}i{HW>{C&faCaxv6)cYyxnRQS}mH(D7wJzY_civ+EA zi)2n$!piMfCUO?~RyVp7c;KjwU8jjQtwuZxOk|@nrZvAC!t7OwH2PNXMAV?gyJ@i0b*b?6pH z9A!M5Y*8Z$UUWLlmg0ghJ1~5&bwiyzXaEv!{)Fl5>@X9?inj|Wp%5jIEvWat~I0ksarF=AmTn6 zj+}+T=_!D6{18KpjaA_FC$?1bbsFjW8Hu}p(`ZKjq%-8=FB z<{Rnk%V! zq6?X}UWRf@PZu<$c^CU0z2YEvQP%p_EKP0V{*0cZ(i2LhNlbdLK}!2=s22gK=HQXr z3}0k4HndHEiRX0bvHF=FGWaga3MJ7`k=Q__S0n5J=|i#_dhJVVl~!4grEkR>-@+Ee z506lIuR@*h`wxmK6;;3XOp9xZ9=Rd{y0cgH1l}v8)*PrurNOMjO*fkbI!!H!ZYX*a z<;k530eOvW=s7UeP)~rp@Gk53Bk7RiPFxrGoaN=C-wAW~{&;k`Q+wa_;pdw%0i@Q2 z7Y2-Ip5j&Dy+{1)mVt-XJukVmlF=rWCK_H4c@ibYOj8=I%Xqm1<^Z>r24D)xMy_=l zn+V&5b2S{mlQG1ox9IWoYW&q#kIrVOP{1h67VqAl%{Dqpe3~&yo<1wja70?XTG08w zzMJVF~wj_Qls1 g_ucQnaJc_^_~LN?%dfw9|F`%51xm|O0eKey0HEQ*5C8xG literal 0 HcmV?d00001 diff --git a/dist/pagefind/fragment/en_64d01b8.pf_fragment b/dist/pagefind/fragment/en_64d01b8.pf_fragment new file mode 100644 index 0000000000000000000000000000000000000000..8273df0946812a61cadb4a9eb877a384ea87c6e0 GIT binary patch literal 3430 zcmV-s4Vm&EiwFP!00002|E*c;ZX3rHewBd`Kypj2NZE1{1!zJ^bV5{?6iJTj1c5c& z9g1Tuch)nzq8Y=0-=Y1{0?FS#n4hHIIWv19DaI~fB(O;C%(N|~KZ z8>u`87l{|3Ig^V(3Rh>4P)LDqGfh|Kuo_e@oz8BU^oRHVo{^Ht7)F5fvzg42s8*cF zmQFlfkXX-^Aj9~})rqOHDiS}Kxx(2FX$3;i$`z!WQ%cMh?sY0=kO^X|ge1yS83+Af zKcU{pS)P(Ly@iY`Ci+d+U(98E3*94eg-2FN2UFh|+#cfr*=?`a`?@3MQi3nrYyoS_PQ(7T-wA3m-#_Ah3mDf3eTB*rl29op^B!UlL zskjiZm53ozLA<;{Ag6(t@O&mFWtuL?s5x9VP8D-lh+CBxMB+{-WJxJfJ!W0wRKrU2 z)k?d7vx+IRa}uGM(Lcm+a6S?;_=I&>zD9=PK=fR7s*438Xn}xGnJdXGQn;BhMBK{E zY4S@)jA0lJl~QNmED3_d+WUZcyP|}_r8Oml`0)N;0tfGLH_^y*C9RlPGpo~z{&obc znR!?Fo0gnal#=YU6jyK>+qDT&o%%4RIISW-5|?lTC!a1-MPmK_Dfd3S{{vRi?EYNP zUrhnXk&=;PNnjADGptFNkS$fJP|R|wyQxak194GO41=PnerM*@HJ_qxYRWWWYqe1Z zAu-Dfk0Y>%nR}3^p)J_Afgb((A#mf1?158zW?DUhB~T&n)o*wx}G4 zql@9-YAB8eSA)aBg^%)ezVc7dLd=+>K!fP;TVm z6e#A#Q#}yR@aLT1%{h>C=cNUFsMdvuKm(A5gNYa~#JNY8-D7j7VpBwXR3^Yje{y$j zb)lN`BxLpZf?_`|$4cxFZspRsxv{{2DG*w@2ay;sz*G;Mc!Fb@nRi+$x>eKoM3){F zrzTBQi?l1_DX05jbTT-8Iy&v14=yjCpIsbxe;8g2BXOd*eh}76=K%&Njr>F+vTuPnT@e>AZ{!H5PXlM(04jjur8%k%dLN*#MrK#xBcCAY7i|` zxOZFVgv!lCd$(DHLc|o z&n2OyfcPba-1F&zz=)EZ!0Y$=CMA!~;3CPcz@wUmf8@&q;u*ebCHA*saMQbni|qLArr1<20Cx2g~mL2Nz_D^DKw5*S>IPTI-s-|I_B$clR69dO}j+zwYgetI8PC9xFGQ6IN>fGK2Rvpi{@;*8j&(65HJMn5fsyfA2NtUrnr5y zs$y{Hvt-})g`+!N)Kw^cDID{V`B7o!$P%4zfiXq8bTS1Y=& z_NetILos?HPS38y@E@bgt4ndcBGI+j5!X7o2DxIV-+#boPoJHf2#H$oQfCl^TKkT; zrY7-PAOuhh?9P6#IolEE7o(?xix=YW!xv(Q=soC&XQ!hdpAExLd>Qrg!KXRTt4-G2SLG=;ntW16W}L^&Ql z89Y0=61|T`MvUzPNmA8i{Pr64JFV3&t`R&0i zYGy{m$T+qO479#c!^xQ99McV`BLfy;K#0T{k36HxbCw9LB;b}Do`|=XKMeNvA6MjQ zS40~GKO=eSUM?8t+>2h7^ICB9=&4`ZkR5mkN^da66jR=gK?IB_Se;Pw;Z_E3_CnRD z6#}hZ!p3HcI(8g4k<=JqY678|#z=w6%%KT6Tk{Z&K@`tubGc`v&mm);HFKcXEofD( z3T`Ouc$BZzLjQ^;%i{+1Uj*uY83>KA^N9q5uaAHb*^qp^C{%zX&Vvv#tO74K{fdIV zmb~!9nLC-5%!GR_F-02jpy;rhqrSLJqo8S%R;%3NhCuNIK&cmk0UM%JhaGBlh{cWk zUIzbzmdV4WbAo24v|;^)>xb96yUj=$j#O9)KiCzhY?;ScT4ExmoL{;T z*ewGDb)=c^@B@ZATG--p^J6$ma(!M{yr@9YeL5uij?70d+hSQE&~I9@`w(%?Lo|o4 zzkWm69W2Eo%e_(K*|unlz7GW|OUtovkH_~mom~s0hdyeSPBMx0UmmprtSgJ|)XdcK ziLtuF9v8nM7Z49oZKHjEb@}vK_;be5$`=F4PXDiae|`8s4B42pa!kYAc|X>8=zUU)^o1?WCd+IX1Z$rxV_ATAC1 z@Z>~Vte&_Y=$S)zHoJ%Hix z{A6&10q*qbY<={=n9|`c9JBCGgOg_%WH5Ghwp&tfV`RCPNa!V)L=9-2x?|{gtF;J= zen)_~*lty-FZLE+^!C4qo~z{W==5hjfAgY$^!-Dbs!^)S$LWh#WxjVby6GLBKYIG; z#nI31Y_Ip|=(pc`Uq0UksZ|?ql(w#ctMdAM?X)4_KABe?yovd-Z_(x$HQ+z$T}D`n z_^nxL5G>qA;+;cfCyHEbg{fpGct?QkvdB^B@Vzk2F3|U`+z3_}bHN?Yp7a+obyY@bjhGJYcKzP8Vi)1XJN~Or*}`%UY2>yJ-oEQ>%~T=rX^Vko?d|*)PRJ~t8an>V+b!(qXZ|hzv=7=k!Kasn z$?>^Bimu=9Y|%oQ;%Doi_pY-1?Uo|NBgUs9#))IFsvcI{-B}vxVQf?dMg%L z{kcVJ|KZ1I1+ZDC);wtFeYL;Qa{*h}pxwfBsTOpp7BrMM*2?AR==HvS_v^d=0ny@N IAIc&C0F;HkRR910 literal 0 HcmV?d00001 diff --git a/dist/pagefind/fragment/en_6aabecf.pf_fragment b/dist/pagefind/fragment/en_6aabecf.pf_fragment new file mode 100644 index 0000000000000000000000000000000000000000..14753a28faa3b99900ba8ff5c286ff478485ec13 GIT binary patch literal 1940 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 ZddhX-MRWdL+UbYS{~u{y?E4dF004F?RSy6F literal 0 HcmV?d00001 diff --git a/dist/pagefind/fragment/en_6e67dbf.pf_fragment b/dist/pagefind/fragment/en_6e67dbf.pf_fragment new file mode 100644 index 0000000000000000000000000000000000000000..f4702222ea88c18b8b2167a3e8b7de61b3b891e1 GIT binary patch literal 2057 zcmV+k2=@0MiwFP!00002|GijkZ`(!^{woV1fMr0U68Z9S3IfDuD~-`4^;ymZx$D7L zkt=aylFM+HlGVUK{zE?%XutM{<(KrCUA|hBZJWx6r-3Yd?}OVFxMi}Lmo-41wNBt7$^uPdej^Ae3clH7@U7w z$TKTHV8sE31FSgUvA29P7i^<){G16MY}jR@)@&VeW1oh6C74k-K>zv>F@lj-r3$Og zKCosycDOJigSLpBFnBHkIw-Ev2-3`if(6|0IXq$74@Jyb@mLGrNJZaaIuJZEY%NX5 z(oCd0qd1y}J@&8MFu8EzYp#=TUw<*oj|9({NL0QIStJaLMP<8+DG|;o7n6n6LXf#Q zxbLexF$m?oCbP4DzhR$qfl%;hR(dH-1TEjb{<%!RPY6z^$e6F<7zUl2F;dG6*Oz+2j$AT0;#oIS(&gkXS@QKHLE=pDTZZJz z1h9~cE18*`M;B$P0evK_!y3?%M8acR9@TfXaNnV-^rnBTSfUICv!r9np3YM?JAGx9 z9e;oF*4y{k$-CL~>>MBGKWv%qllFb~pTjrrr!&_7u_vy0oJPWf(jR;K&)Km+x+%gt zkm!;l6pH8MJYlfNRD25tw(3HzoxEIz#)gmTN8L9Y%{B!JnI7i`I*jzu8ykkM3#`dt z07#U_UaPfOp>s$h`8HQqqByAy-!McGNPWp*c(mf#XhlM!Z(o16c3O2^g%VTQHh))i=WUr$gu*U z(q~=kZli*m`xPbw=klOBjsA1Z1*!fFwQ_V$IqNK!53i?Z(~ff4AF#boDokEB9}f1u z9G!hUJ->c1-aL5t_<{F9plJ8dvPYHy+c5w-zPrqBJ5W_z*}^xn+NcpW-`MOE=0ve| zRW@?`H)rkr>G2`jv+eC{dR_^>=*F=~hIJg-ppTbD9q!#^#a*~=Oa0Ygx}n3Fk;b)k zL2`eF;-tBQ;GCZ=h_(v!Cdna)HO~UXb2ru1vV_>j;_5D*I*ZzIoJs`iYYZ7at}%xU z;!r>s2(#z0 zts&|5Lf<7@Q3H+mNV~p0?>pI{J5gsM29?&jO*ynp*r+z37DXIr|{yMBpM@aKC#QXiM1XdeL$&l9!^mH=09#*B;{9+n$a=j`k$v zP!WdU;cPADL)wLc=5nCb!XRurx8OL(jEm1mr9_0Z9AS4Off)%pwVsIH&Et zV);R8w#;`u-JGEFI266W~ z&=R10y@s9?U`|+QOgb5jWX!!!d9w5)gr-H}LHh`u6sy}s0!WNlxx>>%2HnJI?~=7H{+%Gvdk=SqBcwjK>5G#*wtBl%3n`$7Uf(yF6F3u@isFbnBMe^Gr{X3`}9H+jQsQem%CG$q&ziMV-7dKuJE6aQQ9h5)KBzA8xbSVxNaf^PU9(VMKSi+ zJ6xfqzp%hpNS|A{wJkJ_O0xrnyY?H@G%B>)9C3Q<;206XL<+BfCdEq``-k%%|Anw; zCx$XZmZ-G_Zh|*Sl;8`S{NCj0qbGyjLPn6(y~&sBK`$1D<6954zZCSg>Vj*NsroGy zHO0~U;NA46SNh_=k3NqdfB4=*MWj$|4}p5=HC3wvsTPDtbf^r(Y}W7hCaVXRc;bhO z{QKXR9xkugy#@;(k--4pE{r1M)Is-DI_O2pw|7l%^6+}lQadiyS~ef*&(W}8^V-JN zyP=lG$Iou4JSbJVb|3N~MysJE2j@|(dDjb_mVsyET?X9z35#8tGaV{_$*QrPIJsj|{cm_SDm^@!g1&_nsxMT3L$^+PeOEaF?#) n4z0Cq|4{3D@^GiVf>3Kcht-3|`Ns#>|G)kN9w?+pyB7ceILrm< literal 0 HcmV?d00001 diff --git a/dist/pagefind/fragment/en_6fbc73b.pf_fragment b/dist/pagefind/fragment/en_6fbc73b.pf_fragment new file mode 100644 index 0000000000000000000000000000000000000000..9c2e5ec349028b377bbe8bbb801724806496356e GIT binary patch literal 1394 zcmV-&1&#V2iwFP!00002|9w{7Zre5#ew71XwL|1=>&37DyGY?~4Vq*|Y%CboA)v$~ zn=nPHBo#+13hXuZdV7+6hm!2nD+&a$_;dch^BuNo!?khxL09_YtP6H_F*`T0ZIrP^ z3g*f1xp6Tmi{+M!=iSERH3H@mqxi~*Y7%qD<)Fqn?^ZJDpK%1k$2SlE>Ps~$YI*PI0~FzXcKjq{*f!6#uaW) z8>UgMKCEn$o~_`#L}d7p^dlpv7FH`N}+_>@16BZOOR6gu^h6LixW!D$a12FX(QD`(Mi#V&Qv?%r`96x z$p8$#CPqRhsf($obbeCa<+u+A#LCV3l3qw3PzuV$)`vupcj+aLRifCkWNvk{UQ+V# zUO?(31r>`wEV4lIT0l7(pCX9|V|$af6uUO7uYI5!N$uh_0kNu7QF>v75-rBx5mMR9 z!HR$$iQi=hkd#OrvKdKL(qMA2p+}?W>gIAerxBso;`xhfUnvW#h;uD*)+oU;_~a{Z zUs4yV5 z-uXhd$40#8^5DxYGvJ@gv*%I_&2#g8L(8|z2`>l;-O*%c0KQEp_0CASJG9>mxj3pg zkmO6zun$JM4DrlQyK6D}HZ@4rxn=&edDuvXF6Iyd>l}lg=n-jFAu9}Vq zsyhD?S*;P->fXSi%h2@n&Y7B}^H)InoZcc?b!VqpQh-SW1IX88B5_R5Af!G|lW133 z8{rc)%W8FfZ0Lw7meB#RL5r(G-zMy!D41{}1m`Du{zVd~s1D4uzFy^h19)RVVbeE< zLHTCTlTkP76lfvxy$`z_OXoxm`sV{xUy8}-Ef-R8JwbA)T!s0XYmiwW_pP$ggRhj% z{jUue1OMQ%?dSBH^v8D0oH!xTO%z;rt{SpoQZI?lI51@vHSuKRstaOcnBnorAUKAXW5cnvw_Rw?Be66vsuGQ;cJ#mvi!9N*w A-T(jq literal 0 HcmV?d00001 diff --git a/dist/pagefind/fragment/en_73e850f.pf_fragment b/dist/pagefind/fragment/en_73e850f.pf_fragment new file mode 100644 index 0000000000000000000000000000000000000000..dc55f6bd7f5027a41fa9189a3b7c4a98d3e60272 GIT binary patch literal 6134 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 IW3V^?0KK*NU;qFB literal 0 HcmV?d00001 diff --git a/dist/pagefind/fragment/en_745fe5a.pf_fragment b/dist/pagefind/fragment/en_745fe5a.pf_fragment new file mode 100644 index 0000000000000000000000000000000000000000..6d0c2c5a245fffe9bdf203c6d3cf17e477a6176c GIT binary patch literal 1204 zcmV;l1WWrLiwFP!00002|BY7LZsRr({gr|Dp$Y0$Y{$v&>Z$2wQ3PnRM&kkniXvd7 zQB0U31(NcmL4f{7f3IKCLrRwAI9)Uki6YMJoH;X8C7!sDI)BKs{CQAYHAn|%(p9C9 z>b9NVR2Umxvs_92L>xlld`vxa zs*Kd0yrHeBEjhL;wh2w>C-x*LW9wxhGvS#EYfAc={dbPO=*(^_pU^qYjPr%uP{BT1 zup_CFwG>_&-FVyzE5-GX2~FwRtdQ0J58I0_?m}o(2}j!k2(`9>61wbSI)LC%y+1_qX5i4ECgn!3;iwi?+&@QBi}&PnJ!pk9lH zBt0o(mTlIx*;Smr8%mb9gfwd-7?eJQF9ih~t$d)9F7%5r?$6AXO@{31+pes6~ zEBtf~JHi;d))C?=&M=Qi(W<%E>tollMoKVj)QXQ-ha4M0ztQrgHftnZHyRh&0v$rJ znz}+uQ8m-nm9~q&n(i_*9zAs5aJt+(ebpK7s&0D{CLu_uKQ`EY8hVP7i8y-DFjDi+ zGib_snp_MaVHq$q$(_ea5hy1fM}@_>t-QB%a(_FYL0oqRTMxR?rbn|3!mo8(nB_7U z_3K(orO=&5|DEQ;sK#6(kchv1UN9vG)AL!>aVO3X8XUXXt?T`iK-<1K)TVE6(Cl3y zVKnK_pmDd=UTm6mW@?pFhE4-Z*iwEG*j94MDg8hVQttbvSX7gXV9TfUlieTh#4FXe!+5CY63hD$Z8CAzmyCuWeWAqDZl@x2yVfwft`cRK+rSO((m-px9{RN= zG_zc=4RhQKxUuV?s*|g;K*1>*ki$0Q$0CE{X}79ypG4df*pIux zb4LdkCX+WyjlMH&8u49y}{L?{eM*Yh9kbv)@aj1hIN6DwCQ*{928RFmUn~n z`DHl3oC!P)y!46>zv2cs7CJ*x*#7=JV8vzgskay-uFUcD;7x^R&zo1DfOx4)7C);7 S>FDK;mwy4jOgt=H3IG7hFIlMo literal 0 HcmV?d00001 diff --git a/dist/pagefind/fragment/en_7c62247.pf_fragment b/dist/pagefind/fragment/en_7c62247.pf_fragment new file mode 100644 index 0000000000000000000000000000000000000000..9aa602b8507ef7ad8d9c70bd7568c04e8abdf59a GIT binary patch literal 377 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 Wv&}_`CqKRW^#1_3=}y^regFUuavF{R literal 0 HcmV?d00001 diff --git a/dist/pagefind/fragment/en_82e0d6b.pf_fragment b/dist/pagefind/fragment/en_82e0d6b.pf_fragment new file mode 100644 index 0000000000000000000000000000000000000000..4b1a9f8285a7c306a9f282cdbca5e69738419b7d GIT binary patch literal 780 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 V?CJo~k-Go<{r^%sBb)*$000Ws=UD&% literal 0 HcmV?d00001 diff --git a/dist/pagefind/fragment/en_89d3afe.pf_fragment b/dist/pagefind/fragment/en_89d3afe.pf_fragment new file mode 100644 index 0000000000000000000000000000000000000000..dba2394f97f220dadf4219f35e1404e44580f27d GIT binary patch literal 4301 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 ykPQgFm%LxUjHTW^%0blH_O}RSb>ja3 literal 0 HcmV?d00001 diff --git a/dist/pagefind/fragment/en_8c89f0d.pf_fragment b/dist/pagefind/fragment/en_8c89f0d.pf_fragment new file mode 100644 index 0000000000000000000000000000000000000000..99a5589733501e5dd539e10f92db0718ab0ed44d GIT binary patch literal 2213 zcmV;W2wL|aiwFP!00002|IJwIZrjKeewBd`z&4<}CHWErNMg$yW0PIiavG%F!WfYw zabl9gaE6lAz(C%hKl-ah3-s4ML!ZYl&{ya=GrUS9MPPxVKN8C1xqjz1X9Bup3+~(Z zwq<{7MWNd|Z}qqgJj&h9T!@FY2)&+1eY)iSvJ*)b$_{lol?0Kyp1(>$&JfE z2LXke!)I$2?$Y0d{E@RR`4AgOw1I6BTS&k{5?hEwn>iyJ5y9t>QF}uke6c2LhbsNn zp({`(fC2xvfJ8B(?Tkfear%W;(t=p6l!mcu+s z;@6T{iVOS=s%=JHMb=z7BnTP6gns0iyX0-82wxcTHI@GJ_rED(0YV{RzKE6%ahW0> zOLeC{`OFw)eA02$5QN4LYFQ%k6}a+IqT1Q--jlBp16SbHEU}U+7oE0Pc;V`a_vJPRZJT~GH@SYLX%fKR1tOWlh8vbT&5k605wv8DxZ1`#l}4N zXOiM5FtPFQQV?G#ba9EyLd%E(GP}9bA}@cu{?I+@lIx#l)7v|E-2J>`z#&RMBENt0 z{^N8;4u5H}N9qMG>w?f+dG(UoBn)1fnn%pw$C4Kg}69V!hyUpguW z5L61(NWLg_0YTE^>qvnl#Vx3#4S@=^wPL#sK#4ASC)R8QRfclW;<>_ z%LfALdn+3DR!G!){{E}hQ>cN|ArDh5LVaCwIekC9o06;BpFixlwsu%(!uskU2lv6t zEFsf&P@9S=RTpfm>Ui9uJFBHx?R2K$(07H6}ObkFT1nOD?} zOt<_JNkv@f%-|FxZCuk8Cd{(xVCXfvvf#{3;g)4S>Iv?RZd+T`GiaQxT#m+gaZsb5bo zhMO1t@r&*!D6d~JA9aV-j-*%tq_jFU>liAtG-(D~IgraJGT-Q2!PsC+FSLVVM*P3T z_~Xsx8|VNIx5TpV{!E`DDwzT4aMVD zPS1`cUt?VhdzCbp}`gEvkD_L;2P`+gz^z2N7O4brsU3BDjgPN5Y(%Hi7I&13db913+ z;YE3aNh~+;8|z+`0{)VGVso4iEL>2leCa7tppDmyf^jZ?VDY5NFE?fTmgxqX+k@V! zIe`vxMIlI(tl7MSJD;6jf}~g|a9f|QfStmr9iFZTu#e)_9rAeuCuZc%nHraH=yFgA zd{Xaax`n_#Zgy#EhRVh?{2&x_i1r3LKmG}`?*R_v7EQMB?R6H<`?%Pc{SHRyXY>>{ zKSaQXde&PlZ~_a+{sP#-at>Cx+<(vrEuv6&*X%2p2DXAh%!NW`Nmk;7XL?gjE)U+= zUipGkAi#LN137pNaZVhig7aRFd$ju{@|Ttiu1V&1L3$6W%oFt_Hc<3Pay^1`%u;Td z30ov+#Dx=bfE6as4_ytMxnO|$BZ@t$IO>4IGNc|t0|%fW&Xmfn{c}E%xV|JvPwcv8 zD11_2m5~O;g;|>LC+n=jm&svA638VTRj_5Ha|EIU*)WF<-!G6*E%2epV|ev!$hv`B^~+I?Zmw# zQ?hddQxJJ_x+U^B5owaGLpw10J32LuNtxuTYmZvZZM*FcG*5>B88p~m$+#FS) zF>I8Z<0|gcNhOwgDtBOdc9Q1a5evX}3)Z@ufP${$eqFLn_9J{;i||P`!pDseo>X9T z+z8>5D(>;HS@joT-QDW9q@LD5aoPaONu7YR8Z0Mg4bV8PLgS?0fcvb1d(6-GFH@qDF&S2{kinG&pTCWvYhMXwW1ugQ_Vts_v@AJT1evYHKWL7;jf$ z5t#<#YCNo!P&2Q_!$uRlYG93rCr#L^Cf0bnTC>9%Zfx1kmGKwX#-g;zaaE*}#ew4C nH4|1i(-ve+j{Ey$#Y;#gZTCY?-l+fdr>Fk{Zw<0+7ajlru8Td| literal 0 HcmV?d00001 diff --git a/dist/pagefind/fragment/en_8edefe1.pf_fragment b/dist/pagefind/fragment/en_8edefe1.pf_fragment new file mode 100644 index 0000000000000000000000000000000000000000..c0779cc97cae32a18a406b47f8de266b3c25b920 GIT binary patch literal 1205 zcmV;m1WNlKiwFP!00002|E*TrZrnBy{guH!IcOw%-8Kyt2#Q?nbkVpe;sk9G1OZp1 zR*Wf*%F8Nh8X&(>p#8agNzYL0ThYhB50*so%$YN1hC8UOX|309b)!Ela&U{);!uTT z8)pvlpjEPdTcyra8_Tg`UpeD>$CXn<;vrUT;J$L!=l4~PvRC2%rfQvvT@`_Iak#j< zXxJy?6Tn~XF$tLTX#M=0*weFuNqbBZOnN4mR4_@=tMf-xFsWeH^e`Cz`O{yCIu-P& zf}vjd+^Qz!U;;3*_tW?EvNIDIi(r9*`8``~RG!%Bss);5Z#3~>!b~boF`1qYet{%B z#yiA;`W#K}uj3rFj)!3)9qi6vOJXWQ0k|XtZo`0$KDkMx_{bSR5|@DKsb@*tM)2P_Q_~MTmRR}! zRPLusp?^L8`e?5=|2YE(vs!hKJ8 zG@EFlu#H$%IoUQlNS7#?rt`K@4#bB5%!xLEFU%}-bUfafpXLZHB40_8hiy^MV{??6(iD!o+Olq8a1d!G9E3m89AW2e>7&0 z!#&z?jxI9I?8>%{As7jXB1xDP>W;`1BL*qWy3IWXZ=uFRCk}zVb~do@rHH`ulzopR zX7KCu)mB;HoJwrY^QtyGi-z#3FLt?N1Hrx6Siy(^Y!PKFqobJ4lr@+`_a<)XPfE(V z;)vh&3>_R)Iv*yA+?&+No3#JxH61UHmi4{mH}~%yy`iY--s-6Q(d(!;Z|Gr4s_D>f z=a0|Vq;0$?#XvYLBMK-v7mFB|1q?T<97*lKr}!1q;Sf0<;-ol#wp=NsiZS=%Jbc2S zkaZ}$e`RSiF2i-N5Wd`Yjwv7Js%aBb;A!5022s))Lm85L4<)``j1_53wtaAAUv3{< z5~WRiuso~jg^{+q85R?`73FUX5XV~#t6{(xh%zW*q?4asp1i2(=kjv8JieN-Hxnq( z7`rxs3nq3bLsBM~%iAp~D*iiI zr&+aNTA7m9*Gv(7#L%zN@Tcsgi;9Gp2q8BKms+fG>7tkP+eRF|Sbe?x?(PB|3R&V} z_2J{)1+r0iS|ppC`C=FI0?5iY9ZQ(k9~MxgpD+Gy2})Mu=`FDEoXq<#_k#d(Y*$4mt4qi&6 literal 0 HcmV?d00001 diff --git a/dist/pagefind/fragment/en_9536fae.pf_fragment b/dist/pagefind/fragment/en_9536fae.pf_fragment new file mode 100644 index 0000000000000000000000000000000000000000..ae8eaeecefbcf3d2c488e28a5499766699ea1b93 GIT binary patch literal 2711 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 J=#Rt}006H?EC2ui literal 0 HcmV?d00001 diff --git a/dist/pagefind/fragment/en_998fc06.pf_fragment b/dist/pagefind/fragment/en_998fc06.pf_fragment new file mode 100644 index 0000000000000000000000000000000000000000..218d48df914822e5bd93c7bb8a34f839ba02c2b7 GIT binary patch literal 411 zcmV;M0c8FkiwFP!00002|80^%P9rf8MXyrwI_b>JW;9uj*sw!_9YT@Yu1;HVyDYn$ z21PjodsZBS^Kb#KK-mcr0v4^VmVW(uzpA6&;^2baSYr>WB(K(L<#L>~^UI!SH&dEc zxfp{vFEdkem{)3{3Cridc*S F007~UzT5x+ literal 0 HcmV?d00001 diff --git a/dist/pagefind/fragment/en_9afb713.pf_fragment b/dist/pagefind/fragment/en_9afb713.pf_fragment new file mode 100644 index 0000000000000000000000000000000000000000..74421efdb7e1b72fb97be04d800600b17e113fba GIT binary patch literal 1252 zcmVY&OE}f-xw2^YC2`VSRj1B5Rd%aZyws*#ltuZFb*|24*;M4;k8)bzxfla`T>-p8qgnqW2Be_VP-90;UTx<4Z4TauP>k#O+_-%tN zZ0#rX6F)!wb!oE0ZPlB4BpZa-+Bs@buD{D(K+e)^MiK%C$6@6mtPPCy1NRS`x6EauP^y@=p@&UYQvx==w|^AaVSrZe&<6zX-T zj!WHZweL|SUXy5(#8c-5Vsg=2E+iub9cpy*{Pg$PmFK5_#A@JYOU4G+0)$npTq$OV zmvdfP$LJ%qSL-!LIPb6L#H9|ja7^%m*D4+Y+YajrZN zK`=N<>;jHZnvbTy??}dt8l)u&dw|cmP@;ZP@X!lLNNNgF|^nR7dzjn8m4M%0Nu$p;f<1<6YEx#Z<8O7@J6ha^>CAF zct*FKxJDm&H)$G)9xq9@fuBvMzuC%M9_7CLK)vK)xYGR4O52L4(Hh#u{m z^xjbfVdKVu7Mk4jzq@{!SW&RuL0#T4Yaa0tz>nksU^n?lR#|P?DCO&cUBI z>upqN1z92&ertl-#Fa69Rt%9%=g{vCsfZSH%9-jUFbqQ)t&F`@U`sHz zm89v#lb)G=00U8aZF0Mr2|M6jVTFjdcRO~!aXiuzW)9oX4YTQcwf2b;+XAjKDN0P% zI?TLWdLwfa{VDzC3Js;`-zPLzS_ZC{zD*c5S?oEMjk7gu4{*9ZT^>yOXU z^j^8?y=0pnnK6#mbe?KVp$y27{jt|i5a-eCMPltpcb4jMQ=}Byr2YMVK4I)+sr;9| zqhsOgio&)d7V&mAd-eMDC<6c);cWKsILaEl?(vji zTvsd~9t-7zvs0mG9NC_H^VRpa+p9aZFn5TXV8^sb8v_=qmT!@$BWALfM)w}n>D3pL zARu-%e7Iz&tV~f^f$_^j#x*zTv!?o7a+i2o1S@sqEwGCkWwlLnmCZhT9G%2n?BXKw zXt}ZMphJqYciKs|uP;6!9l9BddgG+t2Q!~3d{X4%%P;<~N;t@ONPBnk&qJP9uPz>c Oef$>=39gto3IG5^lVl_S literal 0 HcmV?d00001 diff --git a/dist/pagefind/fragment/en_9cff5e3.pf_fragment b/dist/pagefind/fragment/en_9cff5e3.pf_fragment new file mode 100644 index 0000000000000000000000000000000000000000..0b1629109a133873f98bb2d804cc93326db0c014 GIT binary patch literal 862 zcmV-k1EKsMiwFP!00002|7BD`Zrnx?{7QpoEjRMT$etue1|q;ggjfm?1i_-0Y?2cV zXXu%pc4U2MF+oqZUWOp%T27iPq1S)EjkcTA4u+sA+3fBf(lTn{F~Bv_FD2L|5(4+NKQ zuM`UUWLkpG2e_b(K?ko6*fm^P!bp(hr#BqU6u$lbI+&fI8m6?nh7q;~Gb+TvC)*w&h2?Dx zZ-^fs{)x~Vsb&}uIP8VA0w6@AWfxYO(ifY=FnQ^tOSWJ()`(y$7!yl%{R@i@RL{6t zF8}m{JEI*cNbN&^Hq%B))nB}m)=Ni@n%vIKFK=MPJ!ny(U=6b^Ef-cBYEVTzIKi`r z$A|yU9v}XPX25_AQ;0R(#Dv!F3n$u5f*$h)5r0HJauld=CciC(8qS^Q6Jh>rTNV+p zZ3D%qXZlj==`}5xL$MdTdSW?~m?-b!;6ZRbnSvOo_Nny>F=342KnwF=nn5c@1<1X` zG>+0ka#Em%%kGGePLe=@O=lWpf*FGoNir!X-BWW5rhG2^p0W~x^bVy(a5$2dIS8(g zC`})3eHF9MrIwPD_}VpLKXK`qFo^d7j4N&DWQ&5G$S)f7y?P~w3OgHXg@DA_iJ%kj z8WJWo7MOOX<8sO)Hj(k#wnTGrFvo2i+z$yxz$a z<R$~WfFimUIkn?HEh%iJcLK?U#p5Sz&xmy;BptZGE9r(qQfNhh?lRm-l@@T{d@ zU00{ypPp2mv6}p9b$5SKjl?KVm885U-F<6}9Q?D5w@{Xg?8hSeQTtav-db9Z?z%J^&0=e#hU*(*2M$n5H^FSc7H^w2efSFXR`Rb*)_ oOLsWcVy!%_*=u2@9e;iMq_Vy^QmtNmcmK!zCr)=`DC-3P0D(`SZ~y=R literal 0 HcmV?d00001 diff --git a/dist/pagefind/fragment/en_9ebe26a.pf_fragment b/dist/pagefind/fragment/en_9ebe26a.pf_fragment new file mode 100644 index 0000000000000000000000000000000000000000..2a97bd5efbc7d147cfc6c078edc0c820dd5c1b63 GIT binary patch literal 3693 zcmV-z4wCU7iwFP!00002|D9Ufjw81b{S`tF!7i-P?8SQQrf4eQj2@ zDZej^^2b^4tJ&G?bg7HJ(kI2*=q{{{=}u?!S>c+_G#%z&YHwUPeaWlTD_W&4Y1u-> zF&mUtja_v+1zDTERl%*gE%vEyjn$ZMOt*D@b5iJ5FDs*TQ>xH8Z-Ody2N4aH8veZ0 z!Kjt3!!xQLY>oXmi8L^8|7At-=+9r zL0zcA<16-dYg{XvTc|(auD|^Bx1jp=OLb|A&N|%6b`@6t^3&h*>0f^O2bSAn%?Afa z&{d_Das@0W31RKFGL3^5>f(!wrl|VTlymjwi#NCOIXji!AB?}jlS^ltYe?vH*F!

2aeKSBt*9(ax+h%*?;HRv)pu?}7J~;t$ITAIBSa2D!hLyh?I6~hg6tPHLLs7~`R*@NQL0l_1^fkn!QZv^oA@6Y=$kksA7ro! zaS)fWH39=4+bxMISdXWQ;9>zkXrS${+%gG}@#y(6)6FvMaKep}-wp~p*QY77NjGWzk6C&bz4o4l?z zy1~HD>T02`jIV9O*wHv&lQY0(_!9wTiR(75Q#;dHe+BGLD;9#YUjI9>xZT|iBLVahvUG3CsyISGtO+m4Dj;m;Vqz5f`>^0=Q z*bHT9+fn2>f!Vj@xuu3DBjhgcOkYZv4=d_%g&2+E?>krZH9Xl7>~YZ1yWa0FeNQtB z6{h3q1jK;reSug1FkL|A7$=MAFkfmQGBzwcQ$l@5!_{<%(kakYDk{m@XIt6lKPk@mlAq=&-dZ zttPl4fPv}+;Yt`3VHqby3T+Z8C8cvyMhQH=*gxu&!vnrhCd|lFMhdHVzyB;YY>CkmYKzMHnsq2lWOs@st zlVghfnoPe1EUDl8hQ4eK4wsKIo($zGcfC7!-Z)KXy`t!H2X7XqXw?N1nZ#DKy8QjS zk*~ynPZt%=6w~=a@`^}Gtj9Jh0ueq=ppF=X4n!7UlZ|2bokx5RoM(~`!1ZWDmr0EW zt~G&^LblRsdlVp9SfLw2tCWQx3}Jo|85Uc!v;pV~)8Ilbu!-{{2Nnh=>GVdDS_R9) zpO!Erw(2$#J&HM>GVMgl%6hEtgNzed92EnDxXEJM1yikZ6yaLje zbPc01lcMk2&@*kR`>L~TWhVEaphgJeb(N}&F4+ha@@e(0DI*so>+@+_U?VDn$#u`; zN0ypm4^Z%5BWkUqZg_quB7n@4Wm1qW zwJ%&rWYxkCyt3k-m0f!6cOpZNtH|Lg7{B3L+%-RqlkLwDwjDipc-~dSY1XtLF6k(y znWnFoIDOnO7p&T~CL2`u%mN6LT!fx^pMyiFAk|uQofe7R0l?m34OCZ?#VF9|WPT7Z z(sw77B?`*IBo`2{2jV24o955`NE31W--)^$JL{UxB#E_-Dk4)wfsFYgkaaH5z-H$I z4A2a2y)|YN=oMfG-8wL}I>M=6|_%qI2`rtqGJEUYhK%0gM$Q7UJCqPF<#d+ znqiW?aY8!E8b;Mr0+R7Zf|lsUIaAm2t|Y@(>SKRpEWKZ*bbYXDPm@t~j531-#z>?G zQ|`U7TA5ng5sIi#63Y&5Y;&TKtjjDz7`NbJ%qomU)R4j>L!=pDsDr1pL@Wc`ldM&` z0uqQo;cJQNo7f)($v{y4^RK^DW|V$@`Rd|g!p`{gmKbA4DF{f0do!Y8YoU_|Z)q6| zqju03x8lfinI9g6{7+Egnz?ik*2YhUv*#z>X$S+o0#HNSXd1KtQ?etcWR-{Ay~{Mob>B-X>5w1BDY{dnM*?n4jHLlJgkMBJIQig>+y?^6Gmrft zBxQ>W{&Pfwx~G6GQfvf3vZ`WoR*_V&6f)`!i_QxXFde{EYu_~nPE9PJvyx36PMGNi*mRlO_w zg268OdOS2*}YC&v%>$YSAUd!Ox^~;{R>hN&ct^!MiOXJL}C{0hAkdTs|QPu1|o{*s4VJ+3RH%L)?_^B&;#jAH)L>?ziYd zAC8CAFM`tP=Rj@;0syHwaKM-0q)YEMW+<7Ef#g%OXV?6UlxZXLnmqZlsWw0RRqrPT zU2&TM5~#jQEX#8-zoM9-A?8M?Gb!;V9Ytspk2rJ~|3pMl;f{oPeAQ`Q?8Xp#J?&`rmY(FT+2gxV+uS{q_p~C;EB7`h+4<|BBa8$?QQ# zs2_PJ%S^y6^@-psOGk<^9rdVFW4xwzP)x0*K~^h=>Mk{HQbR6j`E}~^=5<)Ae1sR# zX_R8=QXnP>Pimy)j%mdUmV{EEr@c@j{w+o-w;(LMhM!@IiK;|5BO~LDE^iRzMCmx| z_k(MHI`fXrpx4adNQX?{uY1pYoPU=TyzqoblO#sJtQzj&0e4U$kaj({LOXN#6e2ZP z7?~t*I^_JE?p7K|x68~eDG2AY6*xdRIwGM4cX1(w;Ql=s7E+8Jyc!1#!KW*b|5DR% zpGrzjp-ikxgfJe;MVDwS{*aRU++sGL0ny6u`DfGF*~7;#p3Y~m9y#9Z?8lGu8Gb0y z_%vgt^{IbXF~ef~kcUPecK-3l89LXs{8NneLmXpEeEPm~Ek0AR_DNCmS*o~ZXAeHk zC&C^jVN|PxlRgue|67NNjL#n)6B0B0M9lbu|3t|1XUBvLzY&ZwK4e3qh=&i4UW979 zar;;DE!+9*(caF-+0GOB4S2F&4P&E}M-Psk&sD%E;3|F{_db5`_~_p04`G>?jlXH5?^P_r^K4GTT^nKj@?6{}L zQfA!#b{NR^KYo5RWK&xwi`Z-^lkxQE3u5bKl<m(cj6<1>C!cr)SKj#}(m=NVczj5;J8plMzGt}g;NkO+fBN`e L@BaZt!Y2R#;u|9^ literal 0 HcmV?d00001 diff --git a/dist/pagefind/fragment/en_a57835d.pf_fragment b/dist/pagefind/fragment/en_a57835d.pf_fragment new file mode 100644 index 0000000000000000000000000000000000000000..c8f52a9519bff5bb1821783a80675d67243a5b70 GIT binary patch literal 675 zcmV;U0$lwciwFP!00002|9w>3Y7{{b{gq-6l1O$Z0pr8I1r*U2gZiXMsO_oQX}70) z=u0+}5XfgJ=+EU#Jl(U4yP(d?6f>tzovJ$B1Fxjjwz+Opb6+KIszp^BZPRV-#d5Fh zYSt$c^krinuIx1vBOoshRJlWJQ@pA2i zr`8$cHkpV?iI1!;4IHC*OR*DM$Tr#-G7g~Dd16bPqU$-LL~tfW?d+UBbwW>%-=~64 zk3UGczGvG|CuRtRrxPz=%6eW)sgQ+ac)-#&;uQz^!w`LaIs07m?5_SB ziI?8pz%Z!YxU@t^s$@@3$@ir0p&bKaCqQ4l^5YCCqWiH_kWL3P_yu^OqN=6{eV{UoGw*PODxb zBdVf~M*e*fRDiNooy&P&?kh3UPd7(*jvBf_bRFG*ILhsRZWI8FQ>Ei-arW@_;WzAA JyEnQ7004>yM&bYf literal 0 HcmV?d00001 diff --git a/dist/pagefind/fragment/en_abb8175.pf_fragment b/dist/pagefind/fragment/en_abb8175.pf_fragment new file mode 100644 index 0000000000000000000000000000000000000000..8ffb90b0d26a11813b10ec4a7687f524e6dd27a0 GIT binary patch literal 4388 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 literal 0 HcmV?d00001 diff --git a/dist/pagefind/fragment/en_accdb73.pf_fragment b/dist/pagefind/fragment/en_accdb73.pf_fragment new file mode 100644 index 0000000000000000000000000000000000000000..ad302d687ccea74b0ab97045d5792338547d4fa0 GIT binary patch literal 3881 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 literal 0 HcmV?d00001 diff --git a/dist/pagefind/fragment/en_d2a9db4.pf_fragment b/dist/pagefind/fragment/en_d2a9db4.pf_fragment new file mode 100644 index 0000000000000000000000000000000000000000..05fb947f4356f94422a1f60c5f001569d9b13a3b GIT binary patch literal 1027 zcmV+e1pNCSiwFP!00002|7}&xZX-nyewET(xFo%6$Ju0kK-wiBf&_{n5(k8$p6MD- z<8k-UKN*`SQr>_AClE+H2G5fh;1&3)$MJ61Jy`CUuAi^I`l@EoD{iebH>NRnRStc% ztX|kSY_#oi51SWbr&Bz3Jie%os>Zv-F2V5ekH7!@=U2M!Y@`8!sQiaSzNOSL zU4C~ZacGsTVQPJ#3$Cqp^mZRu(N)hnGG+Y411UIsXn!5-*0Q4Sf#Z`XR*Ehug&ieN zYvzG;q>XmFl0H7=kDT&A*)^SZD>jP0786|NNIEcedKh*z+SG};4OGxZ4!0a&;S7!1 zCCM>GkSx7TsV}F&$7t&wus$z-C|*Ty;K;WrSx-E6}y+Yf8XUgiS2I93;J~0&)eU(vR zouhReqwtku)^NLQY3K8M%yP3X04LAhqpU+@dH+<$KJt>Td`zv~(uq1%vvWHB6sI%w zO3{VC<;EwPs}nUlk&AMA4Vis;MQ3Uuug=w6QHX=y7+jyJ*%V-*X5e~@5KKDQBXoVD-gYJkDp+>p2pQ{jBF4HFRd78q-8 zwCoHh6(({^KyQQuO^cTc!tT%jZEWBsy;Fwsql{ZDs2?BxYycoVKKw6*cu^*q7YoSsAyj6kEMdiR~EaI5hF x@M8MIU4=EanLb|K3}LOo=>} literal 0 HcmV?d00001 diff --git a/dist/pagefind/fragment/en_d35c9e5.pf_fragment b/dist/pagefind/fragment/en_d35c9e5.pf_fragment new file mode 100644 index 0000000000000000000000000000000000000000..a9295373f108f59a3188b65335189629a4a85ba6 GIT binary patch literal 4570 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 E0Dx@f_y7O^ literal 0 HcmV?d00001 diff --git a/dist/pagefind/fragment/en_d6e847b.pf_fragment b/dist/pagefind/fragment/en_d6e847b.pf_fragment new file mode 100644 index 0000000000000000000000000000000000000000..675f0bac991680c934c47d52f645af2cdf489539 GIT binary patch literal 2396 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 literal 0 HcmV?d00001 diff --git a/dist/pagefind/fragment/en_e15b3e8.pf_fragment b/dist/pagefind/fragment/en_e15b3e8.pf_fragment new file mode 100644 index 0000000000000000000000000000000000000000..87c13dcdb9dd5c407003608e8231f7df2310fea6 GIT binary patch literal 7831 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 literal 0 HcmV?d00001 diff --git a/dist/pagefind/fragment/en_e25a032.pf_fragment b/dist/pagefind/fragment/en_e25a032.pf_fragment new file mode 100644 index 0000000000000000000000000000000000000000..9704d1f13f9c9cbc84459d42b23db9874e6184eb GIT binary patch literal 2703 zcmV;A3UKuwiwFP!00002|Fv1$ZrsQb{guu<$$*Etc-H~+rnR(K0gCO&Hj+g)7_`Wq zVMiP`-QCn^;u!EhQq%vqZejw>ta^q#ivQ@ ztI7G~IDBkvG1Yk$jwjD2xvQh8BVPRER_YzSQx~spf?7F$pQ#_6SCt7tna9R>YwFw- zX_YRPwzeU99i0y_<@`VceqLmO$!8f)jqE3FpZ z;O$D&H?$*qS5>rURXSyZ(pBYFI6OL~^PE&#l{PQc%G{|2cGCZ*&iLR=y)${Vu2#{; z3Y)%u`7eF{^~?X%k959TyH?dk#1-TtXlZ=ZwpO{f5vFQY*?W`Dg7mp}OEz+;{k@5# zSz#LO;}Y&ua8th$A{WjrDwE~df;Zhky2buF+FVDIsrRMvkncAq$9044o%80{8B6%2 zX?^2@?0{#MO=Y5ic45cSbJx}dIk}9nIX^yLtybBC4X%1%T_p7KdG=j6JrpJR35)Z+E3IcG>e`~!otfzR*l9Nvd&u4?@7b?p#b@ix8?lI0m1q)06D` zv+N{0IX-j@tKd`{Bsv_*jXQ!wlL8))F@OY=pWBK; zUK1d_Dzz_EVFMEH#>B5*{sY*D(8A?}*HS+KFMZ&}A*yr8hufQU0(&d?*Dw-81!p z87mnE_)<>IMEQOE^2BnYol8DvumYiRV4cE2^V$Iyd2A7_wYsZZeviCc$CB26{qk=p z&RFZPs=K)|;ExYQA&0atH6wkAYzw1mZ* z+}H0P@h3BiYT;+Q#Kpn|l>%Zfx$!3&%xa4#RT)G;qfi)*eqwK5ie zykc=poCP9jut2@WBgnwi1$n;9%3vbVgm}#xf+xLZ%LH_bn(|o|EKF^@uErEPRG#&+ zV}z(9PSk&q4$mk{PU+)}K1M7$-o$&hSdFVPOdYNxsUt2$j?^>GqNn5)ttWP@+Bz?z zU7CGDtBS0)Aq9OXfqc{#O;Jl7tq>3MU=m3XV^FYz)LMc%SoKcdRRk#FVp`ESTXVfl za0~5SZ6cL>%J5FOKoh{=ROYbM&l2!(;F^-nRG{V#Wh1YUZ1M`zXyPg2rGq$a7WF#-9zQ#86RYpa{7VS$jmQFj_dh5pUvCZQn7$F7y5 zL*BvFv7`)uS|g&Wj{pJ>*1)G^Nf48d} z*z!a(N3iM}(XQ@sLjN|avTx?~$k6u=Nw7o%WB&;qZqw)hyjsoV0?-LH4n_ z2$ctSM)_|eOo+mULC-`Bu5NE<7q4Djy?Zyiyn20ob(xAbjTKd!-`h$cO{FpQ_sr#P zg$93DVS)$xE>z4liC=E%*)`~0NRZG}13}1`ixM$YYqQhQ4kO(AL{6Tj#c9bdw{|by z!X#KRa0%#8n6N;}&Ec2zfDC_n|EHVORt{RtBSt1AF3Xv1cG`NoJ$T0M;7%VDI8>HX ztdCa2JQ#-a7^aOut}rvp8yga{v1C4OXbyr~A}|0SG^Tc>_x_Nts2=N`N;)Ww-;4lv zpIj?an~z36qaJ?~nzVmx^lsT>A>C_XwXKpeW=i%~&o$R?A))ZJs#ij6-f|(0y#hJZ zgp1H4Iv5C%c_4YH81$8_967oV8g{g(MLMn4lEFk>I!G0^11h5?P~TGltR=XZDkGah zAZnX5*CdyL5?t4yZo2P&5J}0W2R`ncl6;NhGj(gG7n|XV)JsF@KE^q?n8@ZskT#nA zsm1f;$HC~vBQj~gBV6ZIYQiDBa_IcpNTSGx-b{DKb`e@?27g{Tt}?vTHK``tdAFiP zD>S2cqJ=2$Xl%G)z)BoLQ5xtmAQj3&yJ)=_$I$BgqU{nxpkB%xIv7dS?bV+@T;E<@ z?yD@zZfxD(&%MTy$b3S6qcqR&!GUP#J33xzDk|`J(dNR*(#f9@lux+N=99!h5*rCf zp9~NUZI?~lcQry9BuL@rBiQ6N04FyC{&CyU!Ktz2si9lMEJnd;Fi4|AED|Y_OLOOm z1bYSeyguhDNYnM`mOKsyg$@Q*Q z%vGW@QDkZW3tQCCFs6pKzZ2mWt!sq?j>rWlGC+2BX~Au_pds0fLx+iuUg`2@X%}Ub z>mT2C%vo<+fZS~;Xe63&NR*RH%_Dy2o1Xq`YF=+HFW%y2)ZwC{<6a6=*QgKc&7G$4 zpWIXrw;h=blPeb^2_Lh!?pvC{(ou6uxkdAOx2~IR!m}+5lB!E;n%k$Hqx$ zEL}U(IsN27xkvFNZX^Eojs{573T%^PtP0&spH4?w!q!YXOUz>=8mQRPnOOSv_RU{^ zo?YDBy!p#EL$XW%(4TbZ<>-vP-MdW2htp2b_-#s~0g{8R7ZeAer!>c*WO63_NK`4P zBxPio#5FmX2-o;hH?nOtyeSk6gZF4Q+Kf-59^GMEJxv(mqCXrgarHyj=7NhITf3B^ zIS^^yF%Ex6IS+-(G~n;g{f!MW+AwjCd+*;19JH~(u(jrE2^*6Kb{ZxZZlnf;Abf+)iZ89C+DXpXD^;lFw!7aVRHWI^Yh8lM2)8j z_k{a@yP9B`#tn?4J%9T&F%{n!VsUwj18jjO4B-u)BVceq$nyzqW7&ks`N`+!BQa;4 z82T-3BZfAQ_PzN2&_*7?r*H)S95)>Vb|dbId*#t7r+<8T=$O2_B9dbeHRm@69JoN* zGU3HR;XF-GWn$uKdfK=8gF~LYBp99b-FF8K*{Lnl)Ld>3Iyf7Q&UpFap literal 0 HcmV?d00001 diff --git a/dist/pagefind/fragment/en_e7bbd4a.pf_fragment b/dist/pagefind/fragment/en_e7bbd4a.pf_fragment new file mode 100644 index 0000000000000000000000000000000000000000..25aad0bce8915bf9afc597efea049a510ac9a65c GIT binary patch literal 2833 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 j(h4GSH7E3wyI6mt0 z#x74Lj7H)&_&vUaXD8FsT4@h0In`CKUcGvDFee_Y@9+Dre`<1c&7s-b6eeTcjYj)u zd2h1HWR&|G>ysMij9T&gX4iD$mA#_o_9cg|b6R>&qj_LT0cm7B@uNmVo#fz{WT4(G ziBu>=d9XdxBAI5ZBN<8~J4dODHYn+6lzQPrz{VFKl|w2JI@(01T&g#wwnNfF;(;TZ3qM-UFqEJx(gAaSJ> zatxBVrMDULIUOaRMofM7GGEI6%2t_XjI(RGr=pFTbWZfZ zaRC)XFcZ{m>5~9rZL_KJnNkp=%2Q#I(rlKp28|gXMc&`=o6JH-G~p?fonZm#Y(p)? zqHN?BL48kumcm|U@5J;q60@(V*Q?&zzqYE}Nd@6EW8xA^lPd& zDHejBzW@2%kCg{wfAU!>beSz?Ix=jwlCMRhKyq&;uDbkEh;{kMJBlfoso&A34|gA7 z=MT3Zt0y)P`1Z`WcdH2jIl&qim=gPe^}m1qP4u1b;)1Pr9Mulh-sMKV+M%3432Vi2 zJkW^-@N&D*9_LddZ{@) zJ?|Q{G&nVC)$tdfwg#ETccYZD-=7+GJgraR_%&MC9;bVifV1M!`!de1anh~F!<*+n Op8p3@m8S8M1polQ5PzNk literal 0 HcmV?d00001 diff --git a/dist/pagefind/fragment/en_ee8a811.pf_fragment b/dist/pagefind/fragment/en_ee8a811.pf_fragment new file mode 100644 index 0000000000000000000000000000000000000000..80710c3ba56242bd22f40e667889da258831e7ca GIT binary patch literal 399 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 literal 0 HcmV?d00001 diff --git a/dist/pagefind/fragment/en_f255c55.pf_fragment b/dist/pagefind/fragment/en_f255c55.pf_fragment new file mode 100644 index 0000000000000000000000000000000000000000..472b24c6d994b7c5b9617ac330badcaf92be7581 GIT binary patch literal 8744 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 S{^P&?@xK9~@F8C3RR93&4h+Kp literal 0 HcmV?d00001 diff --git a/dist/pagefind/fragment/en_f82cb79.pf_fragment b/dist/pagefind/fragment/en_f82cb79.pf_fragment new file mode 100644 index 0000000000000000000000000000000000000000..5d719f73c5b97dddc768b22da03f6c364004bfed GIT binary patch literal 2455 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 E0FbF&2><{9 literal 0 HcmV?d00001 diff --git a/dist/pagefind/fragment/en_ff9d571.pf_fragment b/dist/pagefind/fragment/en_ff9d571.pf_fragment new file mode 100644 index 0000000000000000000000000000000000000000..6b913ec167af8bd74205eaa4c81b3f5807cbb4f4 GIT binary patch literal 798 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�(yG|^8CA*G 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 F000v<>tz4{ literal 0 HcmV?d00001 diff --git a/dist/pagefind/index/en_43a54fb.pf_index b/dist/pagefind/index/en_43a54fb.pf_index new file mode 100644 index 0000000000000000000000000000000000000000..7302f5a4d38b119d399144cf584385c2b6e4a528 GIT binary patch literal 38598 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 literal 0 HcmV?d00001 diff --git a/dist/pagefind/index/en_8c40ad9.pf_index b/dist/pagefind/index/en_8c40ad9.pf_index new file mode 100644 index 0000000000000000000000000000000000000000..d45cffa2c9413da137dc6f12264b62f193516b5e GIT binary patch literal 19529 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

Ax$pS@zxbLqZTFBW0 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 swh!7(3>xG>vG>TdAobm0JabZs2-9!%CmvJN9_ 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%0A3dW)ci7MdY zwKk~v1J`pZ@gEz`GUK>fpVZaLn&RJM-Db{NuO<$CGt?+^Auk~;H|kLqno)9i_j0vk z6@iyr!0ID{ylJ6pBaZfu2<3@x|AhqlAJ|Gu4;?v9~CFb7SGy z*?to_5kjrT80*$%c{@#*k5rBDt&dm6?<^cnb~d*)GKkoJ$tcPkRUj2%08cZ%r;I;9 z$Ni0F?Ly1mohf4!Wfbz^$j59U^UtecouA8Q=Rd4dj+H3P>5`oM6FLt%`2gNoRuCy2;B{O`n#lUCF&Qp!c>0LO<7@%K?T8ZJUX7HXDBMFEr#nQcvDR z3Njri%cF^PL=P!TpL88^i+W9HVRj>{Lj}QAF);3ZQ%BK;N<`{TDQNjjv-UM8q8|{< zJPcSPz);RQLA9I<1Kh4D~>fpD1H*nY0c46?vKP0lHGy^@L95LoWVisl`ww&`sJ217*@X?6-)P zZemH=+|&rGP1RVpvEkJ|x0i4$8EcQF>Q`z8hJ*QCBa_CBEZUwuGeJd?j!?DKk0{w4 zjBB{?E*6*nnf+qw&}|_%LGlWc8%H|ti-Jer1*vY&c@lwAlk(+gyZ0MaZYYI?`CC0c3-9-2i@t&^Q=ic z7;N5(j-GRvtvc3`Y;9_or+Z;}^%q4ZMd4?D<_@Isi3cGuGu}oWb$SHDRB8baV0Ody zKz=+nXWqXW5Owu7Ad1BoX!@%KAYxL*-iIi481_(jtnRlFI*k{5sKqF^IT{&z%Z?f&rP)ivzG!FEbZsxHT zA#@F6<>`Eeu_DffD2fHe9DA7QW#Ynq)xnFqHNzpthga$}IDSDzs*_m)v2&+lL7wUy zqiFfz!$wz0OtFOHwR4?^#j>~`^-*Zty1#(f@00I14%N+2o?|u$s%A>we2!#;{Os0Z zlH&EkIWSCf%+}yovaxEZG67!Y9VGD|-aRVsaA$>A1@$AF=Qu0#2&L$_~>}p@Ka3=n(EK>4rE7MvAWy z1^$R>--n`#7g1HPThs|SGg(colD@}3$gSeif%A9iiTF2Cv+ZK(0z6H!JdS5Hh7nc} zjiDsuGKm=9h$t2Z66|M%?fO&U)3$|Ddx#Xw?I9_H2XQ!BS}G>V*NR$%;ROQXu9ftN z1D(^I^BEJ{ggD2+(r>p&eBX-qko*y}!2R9gGs+LGtq2>SOba5gk%AF&4P*6r0$QP6|Et zEH@F4Rjtq>{7n%8W?3hiW49>3JW7Nj;mVStTd1+xF%2U4rCuJ=jP z*o=*J(nY8DP+dGWJ6RozH6>!R|4YZD^p~whjWyvCvy*C4N3-(uuEH%_=J5=SkY2wb z$`~LP@UE0Gfifmi#=el|`4q{=FW6>&9TVP?KoYHjjNv#A##mdDy#wpxCh@t+H7|v6 ztmqQnJ&)p1RZYzYvShx%YpR!%Th)tH)-kUSzGQ3i9G2MyJiQF|BJmc+_?v>E_Gc%7 zhc%F0=Bp`kFF#;`GuQ10Hm^MRTss3H?*jrThvpYJ#R_E}ypSW4U-H}L_uCUK6t3f; z{L8HvXo0-75pW)`(BB2?ae>sZE`|)rr_f^Y2k^EFff{_QBLgE1_w9a|oYrJ{sdgYE zm&oXD#{gAD2N*l%3S&nPULMXxXVEG{4$xy*;T@|z_elj$Tv z3@TsXA1ur+<@^Mq6v|*2?1loVYM+2Ubqd* zzbn}~vo_YCgDU6(DM25c_m|t;`+admQDwBE%*0-9Fwnry7#YrKZQg#7LHZ)N-{)+U z#Cv-_CD=ll`+shwL_E>>Ulg=8adrS(o9c~Q$ibNEc%r2XJ!EX{?Q3?~9KK(&r%2l| zlU1?CAANBcUXhO81VVqmz(bEAxyl~QdPb8*?4_d`qghwE zp(QGme6y&Sqoo@1Z?OfxMh1Tv_{APhOcIe!mAt*{*rFE~>Us&odr`B;aWi`_o!PrP zI-_K&R0U;G-6H9Q;Cb-QmR`KON)`|Y3eP3qVbXw;qsB`qV6)jzp=lHzNRhoLBTN~Y zZq8DbQg)ia?t2Q@_=*@gr$Tx7B5vQ+k_Yy>#KWIPNhJ`hxTx31$@e4qE2Kd^<8rT4 zU>6GSi(>D7s%){pWE4C>7XNAjx@`nbq~J6PZlK`z6l$f=GW5O3c!aVN?f~%IT ztRoWy6lg|kcr=Kvmu4M%A%_V~u3nQ;yQ4Vvc^m5rm-z8A1XV*c8qYW{Q8nAQTv5*yx(&%I^xCceU_{4>!rQ64*IUY=~*nN%{>b z22aKT>zm{S6+1ZYAUqQh4^G;5_$ zPSr|N-cQK?4+V0yAU#Iq?4k9$_bn;1?5Dlh+f-fwdlabqY?gY|N8lBp-}y9zDrbuD zkFFNRCr~tfDS?k?Wl9c_J{n7rUV*CSCsEam`q0ya*x^y*=|3Y2;W!rOSYavY(D@0X z_9(A^9;B|-ao{_M0+*?@=c;%z-n2cel8h%4u?9o;-lRUanbS|e@A)&@2npoAm>*2l zIDMxfgBO*0L#pjevW94|C`&3roLtPQb&pDdI>F6eD2a?upl&&EJOzKH@VPqb^^hv+ z^o~aMPWWoA9VhC}Y+s??*}s_r3n}8$eHs5jUD80U34_{MaBh`XAO_%BFeOyfP-ccB zM)vdMPig%M{<)#LgLPoB>2l4G_FE>hxfwlu6cH;J8b0Dsf=Pt!uZvYS>aN2aSV9|x z4h^AC(!BjhVQDqJL1t>8hs7w{^8Q1}Kc52sQ1*ILy0un^C((BONzDNKEW+LagHzmK zin}f~a6nwIv!jLYVx`#k?-~-u2gyE^?6hW0+DP^+dB05!ixk{;rFMzenBd`bV`Q{x z6~9^Ug_Cqt&;JC+q7BXg>o=KfT%$4c$+~P~v2L?B7>#vRciwDx=6wamnnCsuVb`b> zrc;TpPLkZ{!xcy}UA%^Icb}xr;c5W9B%Z)iXp=6TGTY zrB21R(1@@{<3#;+enAB~^9t1+$Nn!?JK#xG)BHYy1gaG9YPG=8;q6;+$b<_hyuYR= zEYqzGF63E&ixhP(W^CX*z0jvi>psbD+lbCes^I7^?dy~q7iXhsAu>{PUf<4vB+Vl1 zV@Vq{C57+ki7I4-8Rf*ID7%`nXXjC7gffS~AY%=D4@IstB(PWMC1Lp}kZnM`ENvgz zCm5dG``ymbGIL3UK$7W1RZ}}J!E|dX*`5@fnvFYrFu|Ve*=}dv|NRS?djI-KHQr85 zs&T1m$T?o8xYU#XE^QI+tebZf8>aqa4c>8pp0aUfD=!CE5|9Pe`TAnLY<$;J_(QY* zE{9;Ojn!A{ELaqKEHVM1DvYK!)~>oVIOm()bpt~rIG&QydIf>3z=i6iORFGNK~`NR z@i%g+eA(1kvsgRCU+7k@U8dCNNOSG==7rBSA}VY$iS9HFFMcq_tAzn_$ajHGey)<3 z;^}IsI0qV>^k}m-PStDUL+2}#1T>dT;$&koCS;u?S?r^r;{y< zRnGEY4Td%A9wQ4W@Q``+e;R__Pqb)etI0ZAxUMQGGJ>*?)y~u#&Yx!4KcH3PF?iZ^ z2g|>+MHcL=bMh=C*r*Kigc?DqrZQimXfn@tZc$=@_49MO$>185E3R|P+31%jF`He; z>wg=AR~=>_6<(&b^rrLJ zT-^slPT?PQ#9DfzN{?YqyCjMr>(6?RUt4uTqF3`qNQ&+eIFhXTPwLZnbz@blcD{ID zSH!F5lqRdYiqdVJvHGIgrs8x*U9zn))!rPfE30X#n_b^jUtN`E_`EZbinSNTJ5r5x z@is$P>w$BHGVJaVLXl(c2c620ai>s>>EtL(Wvuip_=ad#!b(U5&&+bap z6-RrAmF;$pi`UjR%t_Cwudc1FnbXu*ToH}dmL)n8ofY+|SiGZpc4Ku-sx?+r)=(6k zZJMUEyPXB`+PdbhWPMSpzN&q8XR<9(*xHq9?u<92lO>(avzro~we@q-UA42@YZAHw zU4|@6Ut+S9#82>YWY7VDG^WAEW#RPAV7Lk*|Q6lJ}ePg#dh z))@tqHI1@P1F*F#F!qZy;h zclH$C7!~$8mys|&p|Yy6mF;Q<1SEJUXC(QH*4lYW(3nwcX{mIG8W=x4Ebub)Bg`mp zR*7dc(W!H~P@==5Y^rZU0D7pKi@xUkxi!^LV{CH3fvNNo2Co=Td6z;zN!Umka;K@r zEI!7I9>+2nX%cXU8N=>IqaOO1Y@S0+;pP<@DLcbtj1IzFq?4v{hXY+awsb>Ef>Ruz zPOu!yr(gqs8kSG_$Z+vL&%>J)n`>}R{(z;pqfprHden6^%-T*=3}y>q!M?UPZpB07 z*y6Vg6V)@ST%T%9FVKb3K6!#c`km<{xXoIX|6+QmT`1{>>N$t<4eMhKcpRlwu8{+c zb*`$O7^zqMWjyBk>Uplc2nbNVP;?zd*0H=i-$ob{cu;{*^s?zWhGU1RNn^Pgc3SLiP_G$&madQZXMVR`6)&Rw$84qc*X3hM53;+q^Yx|s;aWR zGg+64b=GxNrpr3oQ;FHlH6^tzRmpf+YEIpps$NyofkD)>WK)@=vyAa@zp^LX*1^62!0(+O?4ejEe-4#dDS)wY0Z|iNXp_lMjDp(0at^k z6gQ8kUP2M)R0Q^AMMad)9#LC5qE=T#y|joD0RR>M>S7VKxg%=(M${IMkcVBpkxL7l zdCo#yGT&)*&U7}iqclWGx`^5l5%pps%0Z7Pu7HS|gNRxK5%qZd&u$A8tB!mqP{+oJ z8(6F?(TFlcBWf8(c-`q)XiX+0M`)y?)TlGZ+nTG)(Rp|eO&kmrsl#yhNVu;Y2v174 zM1h>(*pl?VE~mg$kl6M!G!Da9A@I**@p_{W=CF9=BdzHckfS(JF=THLM3^=GbfozG zp?;)-aw8EIX~8I3lJj(HiosH7D@JyiRs*Z$45%H2jI1Nib8-k=7z=d@e!i5puS4g8 zHhk5}4nb3cq0EsU2+FL)$!?RJ@~t9|WQ${_t4-v8s!mr652x@xMoC^|;`~3G z?VMpMaUN0W5Kaw+Po_R`Q=74?;?zNH20*-TSX1(&BoVcfdl%}hV=pqm&2e%{8d!|f zIxN@t!CKu;EYFmp?rZX@E-*4|vl(8i=^VKWF4k64n|6(0?PCP%k=WI3jfq8Cy#M6p zaC{BrRTJ1y*eyDhqf2hz1$oZaeB|dazS&$F&KtxWe3PGQo< z1xj+pven_8pX}2H&qBj!ryRkFJ@T0dRV|9xaf!y!XfG-ydt*`EOq4Oc$ z(S;3r2&d;220NOhLu!?JXY{tcVdYf5P%+CrAXV%)N&Wic7z*DnR->#*et|rIRI=KX zAl2do{#>70pyO?66K^}zOy(83>}HHH%i5KT>l`5$Yc$vXh+lb2Q(dyLw{q+~ZmO&zVSnO)N8jNKO_;%|~Iixg)S8v{#(3wDNcnsbSB9|Mq|OM*^=a#3HA z6gdITLH6srgM9aq|3G1hK1UO^9K9WmK=))M5j$s*b%{jnDs)4h+IUM_V=enUbH$28 zx9}lut2y|urK6ICC;a!fBA!%F;30U#wloVgrMyCB0JobRQOV+^rDIMnuT(tVI^X0( znPezqn({>EBP*aP-dfZ!*NEOM{!LnwRki&`r;tQEo!BAYO1rFZD)}O9i8>QA{gPi> z8&+#?%ETx9+qN2=8xuUlpf+V{(UB(;2ruu*h{S{unfE?~i_}z0Fu&Xs(Z}0(X7pk} z6nLyw;!^845DuJL6=$eZ(+dT8*Gbb1y-1Hn&%-K(z+;RN&+#gpUWfO{+Z2_b_8ML_ zxI_wzPa!A|8&~)f?J(9EC}JHZpuTRtUhxkqsOK%S@Gmqs`U@AWuWwCuaY)ILNY-uA zh3-WT$T|ACCTePmYNwS|{P9MZ9%*v%hO)|47fBjrCn@Xv$c>3w?a4T=;#Ms+_1hs1 z-yRrcOJnb6td_P`-lw93d>)-#Vwn6q4``1r<0i^>w0x-58*mI>PpdTiksJh|vZ~eI z0I5kqjJYk1dUouV*-pEP5%0!m4M=G?i1-^>#lqr!4B2hyu44n^pCh5d(?Ho^&sND^ zpTJ8C;>%iRu22|kB&$M~y$zFcseB1DPgYUkStw4MA!P73l2xYw>RZTOAS|5D#ZpC~ z+im3u*^JZb+{?Q@n`3;D0YdA&mn8RZM0Zc{F;Ax87>X=aoQ&QkiC2B*_JtHV8Me3W zNZQn)6zrhTIEk6w>Gs2YcLnCyf4Qp00~zvhl8?k;ntREAk3<2_z^{VqDYU!xKxViD z7739LN_DqMO*==%`jFkD1XI4lq10-y@^kPMy-F5SIHEKD4goul@IFfat)=97L9=|e zJ3SC{`%C8`;rN`)VPAB!lAeB}QNtD!zU_x4HaAO(&%QtbS0D*8>flD{Lvt2|w@~bwz1+#-B1ZL$vb6T*q%*vwtMawDJRM*FPR z9q^C#w%+8ESsKnX$z7`DalE7bKVZ{%ysM|c-HFHA$2r28q2$D+AUm@JQm};7qA%i+ zQqujU^BwpARGI%>i2He71i`TPb=AXmopT`?|J)|+0fGvK{u*p&%H;GbUW+Llm|_9L z(E*gjqQ3D-;R#~vyiS@U&l8^YB$Ws(%R4+S2l&@jX0TP2XV6vw{lyeGW%X9@MrQZ#$;S-N{4vRW7q8@xzD zDr}pBlOxbf!M!Q`0!4~cZ7iEEo@GM0af>P$(_6X%K@+RL2%mk>7u~;yQR%l~59d33 ztKHZvDd1g_p@v{GxTSWIa_&*WTjIPb-|`mAl_%U8tiYh2I!N*@UXYftwvdOjuReN_ z6xv=Z`2thHh3;n`@npT1x2Pg|P-+Y9^71;VXxvvZg8po3zBZeeWyNg67Z z@Ww?t$N^Fcc_SnaSYg*nvxHd`I1K5sI+@*R*QKIHd943;83Uc|K z-TFjvak8u|R#;dTFEM#>CX?Ftp&L)&sSDwmq17Nfy*J(3L@bd6&CXmccJbXi_<9w- zuHvt27xGMw#En&I#_8Mp{rR_2&)$V2xHuC+@)-f8S4a0R8~{S1PuC4cSjC2;dz}`?QOSrbmVO*LjSM0pIRA z)%{i_LterD32l*HA-OnH4%)WN%&9<2hfLS$WM)QE8se-BL<- zC56~#9f||zG7^IHZO}Q7)Z7v(xV~7(pjGtrC0$m@ie~I0#dpC1E3<~OIwa$jag+3My=l!Ef#Ua-k-yk5Nj#?$vLT?)R>WIUbkGA%6gwAl z+rTc-08Oo+Y}h-D#eD_dOGC1ymz&G})J-II=odJgJi97XuR>X-6P^1}M0>3e=CO%& zvvkdZ0`}e~ojgVh^IM5@P-&3bTuFu-DbyNU$sVLAmKF;0U>x<5*4`le4k!y_}7plnY}jZ^h3`AWcGh4`a3B- zoc1B#d*u6rf<+V>PN94X?Lnb~D0DS12?~qci!7kX%_?(ov7}8dlp^kTq%-0aq~iO+ z=z-gJjmntw9*(X>)&y~EUjb_$Xz+;q$CCe4slH8u<~FEOPwbryY4EqY-W{aA4b88D0DD|S}3%H!tYSVCdzo2GOyBBaDR8e*+?Yo z;aw<1DkR2bO1KVr^&XAq1`X2H z6bw>mFojkE|KVTkkI9%NMmDP;-adp0Do6E9SQ5>~N#^41Fon?=;daw=kOwtiZ7HV& z42O1)p$VZ_v3bA_s1YP&S ze^4YtQ8GCbgxSGZ3eMwzp=$Dd?D zfb`K-Xs(Fb{+}ffG(*aLrb{RLI2u{{;^=$sj9w`v&neFP@jcO>~v(wrG8xfC3$!Un~gqDLxG?uVi8+l&m` z0K+#wqxE@Y5oHafoP5feL^=0rT{KnmBwpa$>O2p=!y}D3H(T2WT}b0CL;jVWZ?Y+; zi2i>|I5(hYV99?b*|!f%f{`>PJP{3&t0imkPTBh%LUYXPc0Kv-Cf}3ff0q1zvyZ8b z{uP=d@qTb0p^euG%CpWv13grgRPYPRWFxf+MhkCUhSj1gwGhge;`uJgi#=FG<`UVv zPe}dzKVr!7i>QP|gA_YYw7?6}{wa@qP5cH_8$+~r!lIuF?2mn2mZA)4vUXFUtFLr2 z<#qB!V^bP!4(7>n^BtyBL+;dBDYvOq5a2ILfqkw6&p&BA=uIWGgPXKpx)DjU_H`-; z&M8I+61vBsr_2D+cY-+cz%I@GP<`++3#|HE5W%PkGl6hrrXpqV2y z-3s#xf1|-J|AQJFYsWMeL<|Z$5>wY4OPGkx^-#ktbG5!+fGKQ2?o^TH#i>+iG!7?M zD#MB0x{%IKLJ@R-=RgiopoMUeETq2D5JB>ohqFHL_0@DN@9L`N_f0}sT8Gg0F`-)x?rOwhw zowAzVz*Ds**J=`)dlCItFOJ0T?5jJ0>`!)rB3o3-=p=2s0f(O}7}9k8GFjdQmKl=y z>0;Fn(*?!aXn))Ea`@W>L{HWBQRo7bICqwPGv+$bJE0l1!1fo(=R8Eq542~@P1g&l#pd9uO@GgYx4dsMK zL-s{9rGj90zoXWIS9_KYFJ<$N4ErLTs9oS@Eh}K-a}gA? zO`iJ!j7)MKLS3409E1ubhiR831}4e6ZUIuiiB3oNzj+0sZ#V1Yq<7^FZ|E;W zOw`8e7ib^wTQ_T|n7NCbvz^=Z-3H@^a`_d~Gv`=#es6N_#sxQVaV;tSXwhyd7sfDb)<2wc4OZ&zC$!5p^F=>H2+<-P@Qi7D(!+Y zP$kCy<|MSeajX`Cr)hP%#$+L$#@nT;V|%j@T^yNARH^CHzltZ4$feDtj0Y&=c|2h* z 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 literal 0 HcmV?d00001 diff --git a/dist/pagefind/index/en_e7357f7.pf_index b/dist/pagefind/index/en_e7357f7.pf_index new file mode 100644 index 0000000000000000000000000000000000000000..4dbd484691a6183b7d33c3024bfb28229926c88a GIT binary patch literal 38166 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 S5)-sl`u_m=$u%{)1_1z*82i`& literal 0 HcmV?d00001 diff --git a/dist/pagefind/index/en_fba5f9f.pf_index b/dist/pagefind/index/en_fba5f9f.pf_index new file mode 100644 index 0000000000000000000000000000000000000000..63139d878cce7b255889ae55e17d4e38dd640a21 GIT binary patch literal 37205 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 t;6lXhA$n>zmXWRt(rUgg2 function __require() { + return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); + +// node_modules/mark.js/dist/mark.js +var require_mark = __commonJS({ + "node_modules/mark.js/dist/mark.js"(exports, module) { + (function(global, factory) { + typeof exports === "object" && typeof module !== "undefined" ? module.exports = factory() : typeof define === "function" && define.amd ? define(factory) : global.Mark = factory(); + })(exports, (function() { + "use strict"; + var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function(obj) { + return typeof obj; + } : function(obj) { + return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; + }; + var classCallCheck = function(instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } + }; + var createClass = /* @__PURE__ */ (function() { + function defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + return function(Constructor, protoProps, staticProps) { + if (protoProps) defineProperties(Constructor.prototype, protoProps); + if (staticProps) defineProperties(Constructor, staticProps); + return Constructor; + }; + })(); + var _extends = Object.assign || function(target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i]; + for (var key in source) { + if (Object.prototype.hasOwnProperty.call(source, key)) { + target[key] = source[key]; + } + } + } + return target; + }; + var DOMIterator = (function() { + function DOMIterator2(ctx) { + var iframes = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : true; + var exclude = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : []; + var iframesTimeout = arguments.length > 3 && arguments[3] !== void 0 ? arguments[3] : 5e3; + classCallCheck(this, DOMIterator2); + this.ctx = ctx; + this.iframes = iframes; + this.exclude = exclude; + this.iframesTimeout = iframesTimeout; + } + createClass(DOMIterator2, [{ + key: "getContexts", + value: function getContexts() { + var ctx = void 0, filteredCtx = []; + if (typeof this.ctx === "undefined" || !this.ctx) { + ctx = []; + } else if (NodeList.prototype.isPrototypeOf(this.ctx)) { + ctx = Array.prototype.slice.call(this.ctx); + } else if (Array.isArray(this.ctx)) { + ctx = this.ctx; + } else if (typeof this.ctx === "string") { + ctx = Array.prototype.slice.call(document.querySelectorAll(this.ctx)); + } else { + ctx = [this.ctx]; + } + ctx.forEach(function(ctx2) { + var isDescendant = filteredCtx.filter(function(contexts) { + return contexts.contains(ctx2); + }).length > 0; + if (filteredCtx.indexOf(ctx2) === -1 && !isDescendant) { + filteredCtx.push(ctx2); + } + }); + return filteredCtx; + } + }, { + key: "getIframeContents", + value: function getIframeContents(ifr, successFn) { + var errorFn = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : function() { + }; + var doc = void 0; + try { + var ifrWin = ifr.contentWindow; + doc = ifrWin.document; + if (!ifrWin || !doc) { + throw new Error("iframe inaccessible"); + } + } catch (e) { + errorFn(); + } + if (doc) { + successFn(doc); + } + } + }, { + key: "isIframeBlank", + value: function isIframeBlank(ifr) { + var bl = "about:blank", src = ifr.getAttribute("src").trim(), href = ifr.contentWindow.location.href; + return href === bl && src !== bl && src; + } + }, { + key: "observeIframeLoad", + value: function observeIframeLoad(ifr, successFn, errorFn) { + var _this = this; + var called = false, tout = null; + var listener = function listener2() { + if (called) { + return; + } + called = true; + clearTimeout(tout); + try { + if (!_this.isIframeBlank(ifr)) { + ifr.removeEventListener("load", listener2); + _this.getIframeContents(ifr, successFn, errorFn); + } + } catch (e) { + errorFn(); + } + }; + ifr.addEventListener("load", listener); + tout = setTimeout(listener, this.iframesTimeout); + } + }, { + key: "onIframeReady", + value: function onIframeReady(ifr, successFn, errorFn) { + try { + if (ifr.contentWindow.document.readyState === "complete") { + if (this.isIframeBlank(ifr)) { + this.observeIframeLoad(ifr, successFn, errorFn); + } else { + this.getIframeContents(ifr, successFn, errorFn); + } + } else { + this.observeIframeLoad(ifr, successFn, errorFn); + } + } catch (e) { + errorFn(); + } + } + }, { + key: "waitForIframes", + value: function waitForIframes(ctx, done) { + var _this2 = this; + var eachCalled = 0; + this.forEachIframe(ctx, function() { + return true; + }, function(ifr) { + eachCalled++; + _this2.waitForIframes(ifr.querySelector("html"), function() { + if (!--eachCalled) { + done(); + } + }); + }, function(handled) { + if (!handled) { + done(); + } + }); + } + }, { + key: "forEachIframe", + value: function forEachIframe(ctx, filter, each) { + var _this3 = this; + var end = arguments.length > 3 && arguments[3] !== void 0 ? arguments[3] : function() { + }; + var ifr = ctx.querySelectorAll("iframe"), open = ifr.length, handled = 0; + ifr = Array.prototype.slice.call(ifr); + var checkEnd = function checkEnd2() { + if (--open <= 0) { + end(handled); + } + }; + if (!open) { + checkEnd(); + } + ifr.forEach(function(ifr2) { + if (DOMIterator2.matches(ifr2, _this3.exclude)) { + checkEnd(); + } else { + _this3.onIframeReady(ifr2, function(con) { + if (filter(ifr2)) { + handled++; + each(con); + } + checkEnd(); + }, checkEnd); + } + }); + } + }, { + key: "createIterator", + value: function createIterator(ctx, whatToShow, filter) { + return document.createNodeIterator(ctx, whatToShow, filter, false); + } + }, { + key: "createInstanceOnIframe", + value: function createInstanceOnIframe(contents) { + return new DOMIterator2(contents.querySelector("html"), this.iframes); + } + }, { + key: "compareNodeIframe", + value: function compareNodeIframe(node, prevNode, ifr) { + var compCurr = node.compareDocumentPosition(ifr), prev = Node.DOCUMENT_POSITION_PRECEDING; + if (compCurr & prev) { + if (prevNode !== null) { + var compPrev = prevNode.compareDocumentPosition(ifr), after = Node.DOCUMENT_POSITION_FOLLOWING; + if (compPrev & after) { + return true; + } + } else { + return true; + } + } + return false; + } + }, { + key: "getIteratorNode", + value: function getIteratorNode(itr) { + var prevNode = itr.previousNode(); + var node = void 0; + if (prevNode === null) { + node = itr.nextNode(); + } else { + node = itr.nextNode() && itr.nextNode(); + } + return { + prevNode, + node + }; + } + }, { + key: "checkIframeFilter", + value: function checkIframeFilter(node, prevNode, currIfr, ifr) { + var key = false, handled = false; + ifr.forEach(function(ifrDict, i) { + if (ifrDict.val === currIfr) { + key = i; + handled = ifrDict.handled; + } + }); + if (this.compareNodeIframe(node, prevNode, currIfr)) { + if (key === false && !handled) { + ifr.push({ + val: currIfr, + handled: true + }); + } else if (key !== false && !handled) { + ifr[key].handled = true; + } + return true; + } + if (key === false) { + ifr.push({ + val: currIfr, + handled: false + }); + } + return false; + } + }, { + key: "handleOpenIframes", + value: function handleOpenIframes(ifr, whatToShow, eCb, fCb) { + var _this4 = this; + ifr.forEach(function(ifrDict) { + if (!ifrDict.handled) { + _this4.getIframeContents(ifrDict.val, function(con) { + _this4.createInstanceOnIframe(con).forEachNode(whatToShow, eCb, fCb); + }); + } + }); + } + }, { + key: "iterateThroughNodes", + value: function iterateThroughNodes(whatToShow, ctx, eachCb, filterCb, doneCb) { + var _this5 = this; + var itr = this.createIterator(ctx, whatToShow, filterCb); + var ifr = [], elements = [], node = void 0, prevNode = void 0, retrieveNodes = function retrieveNodes2() { + var _getIteratorNode = _this5.getIteratorNode(itr); + prevNode = _getIteratorNode.prevNode; + node = _getIteratorNode.node; + return node; + }; + while (retrieveNodes()) { + if (this.iframes) { + this.forEachIframe(ctx, function(currIfr) { + return _this5.checkIframeFilter(node, prevNode, currIfr, ifr); + }, function(con) { + _this5.createInstanceOnIframe(con).forEachNode(whatToShow, function(ifrNode) { + return elements.push(ifrNode); + }, filterCb); + }); + } + elements.push(node); + } + elements.forEach(function(node2) { + eachCb(node2); + }); + if (this.iframes) { + this.handleOpenIframes(ifr, whatToShow, eachCb, filterCb); + } + doneCb(); + } + }, { + key: "forEachNode", + value: function forEachNode(whatToShow, each, filter) { + var _this6 = this; + var done = arguments.length > 3 && arguments[3] !== void 0 ? arguments[3] : function() { + }; + var contexts = this.getContexts(); + var open = contexts.length; + if (!open) { + done(); + } + contexts.forEach(function(ctx) { + var ready = function ready2() { + _this6.iterateThroughNodes(whatToShow, ctx, each, filter, function() { + if (--open <= 0) { + done(); + } + }); + }; + if (_this6.iframes) { + _this6.waitForIframes(ctx, ready); + } else { + ready(); + } + }); + } + }], [{ + key: "matches", + value: function matches(element, selector) { + var selectors = typeof selector === "string" ? [selector] : selector, fn = element.matches || element.matchesSelector || element.msMatchesSelector || element.mozMatchesSelector || element.oMatchesSelector || element.webkitMatchesSelector; + if (fn) { + var match = false; + selectors.every(function(sel) { + if (fn.call(element, sel)) { + match = true; + return false; + } + return true; + }); + return match; + } else { + return false; + } + } + }]); + return DOMIterator2; + })(); + var Mark$1 = (function() { + function Mark3(ctx) { + classCallCheck(this, Mark3); + this.ctx = ctx; + this.ie = false; + var ua = window.navigator.userAgent; + if (ua.indexOf("MSIE") > -1 || ua.indexOf("Trident") > -1) { + this.ie = true; + } + } + createClass(Mark3, [{ + key: "log", + value: function log(msg) { + var level = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : "debug"; + var log2 = this.opt.log; + if (!this.opt.debug) { + return; + } + if ((typeof log2 === "undefined" ? "undefined" : _typeof(log2)) === "object" && typeof log2[level] === "function") { + log2[level]("mark.js: " + msg); + } + } + }, { + key: "escapeStr", + value: function escapeStr(str) { + return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"); + } + }, { + key: "createRegExp", + value: function createRegExp(str) { + if (this.opt.wildcards !== "disabled") { + str = this.setupWildcardsRegExp(str); + } + str = this.escapeStr(str); + if (Object.keys(this.opt.synonyms).length) { + str = this.createSynonymsRegExp(str); + } + if (this.opt.ignoreJoiners || this.opt.ignorePunctuation.length) { + str = this.setupIgnoreJoinersRegExp(str); + } + if (this.opt.diacritics) { + str = this.createDiacriticsRegExp(str); + } + str = this.createMergedBlanksRegExp(str); + if (this.opt.ignoreJoiners || this.opt.ignorePunctuation.length) { + str = this.createJoinersRegExp(str); + } + if (this.opt.wildcards !== "disabled") { + str = this.createWildcardsRegExp(str); + } + str = this.createAccuracyRegExp(str); + return str; + } + }, { + key: "createSynonymsRegExp", + value: function createSynonymsRegExp(str) { + var syn = this.opt.synonyms, sens = this.opt.caseSensitive ? "" : "i", joinerPlaceholder = this.opt.ignoreJoiners || this.opt.ignorePunctuation.length ? "\0" : ""; + for (var index in syn) { + if (syn.hasOwnProperty(index)) { + var value = syn[index], k1 = this.opt.wildcards !== "disabled" ? this.setupWildcardsRegExp(index) : this.escapeStr(index), k2 = this.opt.wildcards !== "disabled" ? this.setupWildcardsRegExp(value) : this.escapeStr(value); + if (k1 !== "" && k2 !== "") { + str = str.replace(new RegExp("(" + this.escapeStr(k1) + "|" + this.escapeStr(k2) + ")", "gm" + sens), joinerPlaceholder + ("(" + this.processSynomyms(k1) + "|") + (this.processSynomyms(k2) + ")") + joinerPlaceholder); + } + } + } + return str; + } + }, { + key: "processSynomyms", + value: function processSynomyms(str) { + if (this.opt.ignoreJoiners || this.opt.ignorePunctuation.length) { + str = this.setupIgnoreJoinersRegExp(str); + } + return str; + } + }, { + key: "setupWildcardsRegExp", + value: function setupWildcardsRegExp(str) { + str = str.replace(/(?:\\)*\?/g, function(val) { + return val.charAt(0) === "\\" ? "?" : ""; + }); + return str.replace(/(?:\\)*\*/g, function(val) { + return val.charAt(0) === "\\" ? "*" : ""; + }); + } + }, { + key: "createWildcardsRegExp", + value: function createWildcardsRegExp(str) { + var spaces = this.opt.wildcards === "withSpaces"; + return str.replace(/\u0001/g, spaces ? "[\\S\\s]?" : "\\S?").replace(/\u0002/g, spaces ? "[\\S\\s]*?" : "\\S*"); + } + }, { + key: "setupIgnoreJoinersRegExp", + value: function setupIgnoreJoinersRegExp(str) { + return str.replace(/[^(|)\\]/g, function(val, indx, original) { + var nextChar = original.charAt(indx + 1); + if (/[(|)\\]/.test(nextChar) || nextChar === "") { + return val; + } else { + return val + "\0"; + } + }); + } + }, { + key: "createJoinersRegExp", + value: function createJoinersRegExp(str) { + var joiner = []; + var ignorePunctuation = this.opt.ignorePunctuation; + if (Array.isArray(ignorePunctuation) && ignorePunctuation.length) { + joiner.push(this.escapeStr(ignorePunctuation.join(""))); + } + if (this.opt.ignoreJoiners) { + joiner.push("\\u00ad\\u200b\\u200c\\u200d"); + } + return joiner.length ? str.split(/\u0000+/).join("[" + joiner.join("") + "]*") : str; + } + }, { + key: "createDiacriticsRegExp", + value: function createDiacriticsRegExp(str) { + var sens = this.opt.caseSensitive ? "" : "i", dct = this.opt.caseSensitive ? ["a\xE0\xE1\u1EA3\xE3\u1EA1\u0103\u1EB1\u1EAF\u1EB3\u1EB5\u1EB7\xE2\u1EA7\u1EA5\u1EA9\u1EAB\u1EAD\xE4\xE5\u0101\u0105", "A\xC0\xC1\u1EA2\xC3\u1EA0\u0102\u1EB0\u1EAE\u1EB2\u1EB4\u1EB6\xC2\u1EA6\u1EA4\u1EA8\u1EAA\u1EAC\xC4\xC5\u0100\u0104", "c\xE7\u0107\u010D", "C\xC7\u0106\u010C", "d\u0111\u010F", "D\u0110\u010E", "e\xE8\xE9\u1EBB\u1EBD\u1EB9\xEA\u1EC1\u1EBF\u1EC3\u1EC5\u1EC7\xEB\u011B\u0113\u0119", "E\xC8\xC9\u1EBA\u1EBC\u1EB8\xCA\u1EC0\u1EBE\u1EC2\u1EC4\u1EC6\xCB\u011A\u0112\u0118", "i\xEC\xED\u1EC9\u0129\u1ECB\xEE\xEF\u012B", "I\xCC\xCD\u1EC8\u0128\u1ECA\xCE\xCF\u012A", "l\u0142", "L\u0141", "n\xF1\u0148\u0144", "N\xD1\u0147\u0143", "o\xF2\xF3\u1ECF\xF5\u1ECD\xF4\u1ED3\u1ED1\u1ED5\u1ED7\u1ED9\u01A1\u1EDF\u1EE1\u1EDB\u1EDD\u1EE3\xF6\xF8\u014D", "O\xD2\xD3\u1ECE\xD5\u1ECC\xD4\u1ED2\u1ED0\u1ED4\u1ED6\u1ED8\u01A0\u1EDE\u1EE0\u1EDA\u1EDC\u1EE2\xD6\xD8\u014C", "r\u0159", "R\u0158", "s\u0161\u015B\u0219\u015F", "S\u0160\u015A\u0218\u015E", "t\u0165\u021B\u0163", "T\u0164\u021A\u0162", "u\xF9\xFA\u1EE7\u0169\u1EE5\u01B0\u1EEB\u1EE9\u1EED\u1EEF\u1EF1\xFB\xFC\u016F\u016B", "U\xD9\xDA\u1EE6\u0168\u1EE4\u01AF\u1EEA\u1EE8\u1EEC\u1EEE\u1EF0\xDB\xDC\u016E\u016A", "y\xFD\u1EF3\u1EF7\u1EF9\u1EF5\xFF", "Y\xDD\u1EF2\u1EF6\u1EF8\u1EF4\u0178", "z\u017E\u017C\u017A", "Z\u017D\u017B\u0179"] : ["a\xE0\xE1\u1EA3\xE3\u1EA1\u0103\u1EB1\u1EAF\u1EB3\u1EB5\u1EB7\xE2\u1EA7\u1EA5\u1EA9\u1EAB\u1EAD\xE4\xE5\u0101\u0105A\xC0\xC1\u1EA2\xC3\u1EA0\u0102\u1EB0\u1EAE\u1EB2\u1EB4\u1EB6\xC2\u1EA6\u1EA4\u1EA8\u1EAA\u1EAC\xC4\xC5\u0100\u0104", "c\xE7\u0107\u010DC\xC7\u0106\u010C", "d\u0111\u010FD\u0110\u010E", "e\xE8\xE9\u1EBB\u1EBD\u1EB9\xEA\u1EC1\u1EBF\u1EC3\u1EC5\u1EC7\xEB\u011B\u0113\u0119E\xC8\xC9\u1EBA\u1EBC\u1EB8\xCA\u1EC0\u1EBE\u1EC2\u1EC4\u1EC6\xCB\u011A\u0112\u0118", "i\xEC\xED\u1EC9\u0129\u1ECB\xEE\xEF\u012BI\xCC\xCD\u1EC8\u0128\u1ECA\xCE\xCF\u012A", "l\u0142L\u0141", "n\xF1\u0148\u0144N\xD1\u0147\u0143", "o\xF2\xF3\u1ECF\xF5\u1ECD\xF4\u1ED3\u1ED1\u1ED5\u1ED7\u1ED9\u01A1\u1EDF\u1EE1\u1EDB\u1EDD\u1EE3\xF6\xF8\u014DO\xD2\xD3\u1ECE\xD5\u1ECC\xD4\u1ED2\u1ED0\u1ED4\u1ED6\u1ED8\u01A0\u1EDE\u1EE0\u1EDA\u1EDC\u1EE2\xD6\xD8\u014C", "r\u0159R\u0158", "s\u0161\u015B\u0219\u015FS\u0160\u015A\u0218\u015E", "t\u0165\u021B\u0163T\u0164\u021A\u0162", "u\xF9\xFA\u1EE7\u0169\u1EE5\u01B0\u1EEB\u1EE9\u1EED\u1EEF\u1EF1\xFB\xFC\u016F\u016BU\xD9\xDA\u1EE6\u0168\u1EE4\u01AF\u1EEA\u1EE8\u1EEC\u1EEE\u1EF0\xDB\xDC\u016E\u016A", "y\xFD\u1EF3\u1EF7\u1EF9\u1EF5\xFFY\xDD\u1EF2\u1EF6\u1EF8\u1EF4\u0178", "z\u017E\u017C\u017AZ\u017D\u017B\u0179"]; + var handled = []; + str.split("").forEach(function(ch) { + dct.every(function(dct2) { + if (dct2.indexOf(ch) !== -1) { + if (handled.indexOf(dct2) > -1) { + return false; + } + str = str.replace(new RegExp("[" + dct2 + "]", "gm" + sens), "[" + dct2 + "]"); + handled.push(dct2); + } + return true; + }); + }); + return str; + } + }, { + key: "createMergedBlanksRegExp", + value: function createMergedBlanksRegExp(str) { + return str.replace(/[\s]+/gmi, "[\\s]+"); + } + }, { + key: "createAccuracyRegExp", + value: function createAccuracyRegExp(str) { + var _this = this; + var chars = "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~\xA1\xBF"; + var acc = this.opt.accuracy, val = typeof acc === "string" ? acc : acc.value, ls = typeof acc === "string" ? [] : acc.limiters, lsJoin = ""; + ls.forEach(function(limiter) { + lsJoin += "|" + _this.escapeStr(limiter); + }); + switch (val) { + case "partially": + default: + return "()(" + str + ")"; + case "complementary": + lsJoin = "\\s" + (lsJoin ? lsJoin : this.escapeStr(chars)); + return "()([^" + lsJoin + "]*" + str + "[^" + lsJoin + "]*)"; + case "exactly": + return "(^|\\s" + lsJoin + ")(" + str + ")(?=$|\\s" + lsJoin + ")"; + } + } + }, { + key: "getSeparatedKeywords", + value: function getSeparatedKeywords(sv) { + var _this2 = this; + var stack = []; + sv.forEach(function(kw) { + if (!_this2.opt.separateWordSearch) { + if (kw.trim() && stack.indexOf(kw) === -1) { + stack.push(kw); + } + } else { + kw.split(" ").forEach(function(kwSplitted) { + if (kwSplitted.trim() && stack.indexOf(kwSplitted) === -1) { + stack.push(kwSplitted); + } + }); + } + }); + return { + "keywords": stack.sort(function(a, b) { + return b.length - a.length; + }), + "length": stack.length + }; + } + }, { + key: "isNumeric", + value: function isNumeric(value) { + return Number(parseFloat(value)) == value; + } + }, { + key: "checkRanges", + value: function checkRanges(array) { + var _this3 = this; + if (!Array.isArray(array) || Object.prototype.toString.call(array[0]) !== "[object Object]") { + this.log("markRanges() will only accept an array of objects"); + this.opt.noMatch(array); + return []; + } + var stack = []; + var last = 0; + array.sort(function(a, b) { + return a.start - b.start; + }).forEach(function(item) { + var _callNoMatchOnInvalid = _this3.callNoMatchOnInvalidRanges(item, last), start = _callNoMatchOnInvalid.start, end = _callNoMatchOnInvalid.end, valid = _callNoMatchOnInvalid.valid; + if (valid) { + item.start = start; + item.length = end - start; + stack.push(item); + last = end; + } + }); + return stack; + } + }, { + key: "callNoMatchOnInvalidRanges", + value: function callNoMatchOnInvalidRanges(range, last) { + var start = void 0, end = void 0, valid = false; + if (range && typeof range.start !== "undefined") { + start = parseInt(range.start, 10); + end = start + parseInt(range.length, 10); + if (this.isNumeric(range.start) && this.isNumeric(range.length) && end - last > 0 && end - start > 0) { + valid = true; + } else { + this.log("Ignoring invalid or overlapping range: " + ("" + JSON.stringify(range))); + this.opt.noMatch(range); + } + } else { + this.log("Ignoring invalid range: " + JSON.stringify(range)); + this.opt.noMatch(range); + } + return { + start, + end, + valid + }; + } + }, { + key: "checkWhitespaceRanges", + value: function checkWhitespaceRanges(range, originalLength, string) { + var end = void 0, valid = true, max = string.length, offset = originalLength - max, start = parseInt(range.start, 10) - offset; + start = start > max ? max : start; + end = start + parseInt(range.length, 10); + if (end > max) { + end = max; + this.log("End range automatically set to the max value of " + max); + } + if (start < 0 || end - start < 0 || start > max || end > max) { + valid = false; + this.log("Invalid range: " + JSON.stringify(range)); + this.opt.noMatch(range); + } else if (string.substring(start, end).replace(/\s+/g, "") === "") { + valid = false; + this.log("Skipping whitespace only range: " + JSON.stringify(range)); + this.opt.noMatch(range); + } + return { + start, + end, + valid + }; + } + }, { + key: "getTextNodes", + value: function getTextNodes(cb) { + var _this4 = this; + var val = "", nodes = []; + this.iterator.forEachNode(NodeFilter.SHOW_TEXT, function(node) { + nodes.push({ + start: val.length, + end: (val += node.textContent).length, + node + }); + }, function(node) { + if (_this4.matchesExclude(node.parentNode)) { + return NodeFilter.FILTER_REJECT; + } else { + return NodeFilter.FILTER_ACCEPT; + } + }, function() { + cb({ + value: val, + nodes + }); + }); + } + }, { + key: "matchesExclude", + value: function matchesExclude(el) { + return DOMIterator.matches(el, this.opt.exclude.concat(["script", "style", "title", "head", "html"])); + } + }, { + key: "wrapRangeInTextNode", + value: function wrapRangeInTextNode(node, start, end) { + var hEl = !this.opt.element ? "mark" : this.opt.element, startNode = node.splitText(start), ret = startNode.splitText(end - start); + var repl = document.createElement(hEl); + repl.setAttribute("data-markjs", "true"); + if (this.opt.className) { + repl.setAttribute("class", this.opt.className); + } + repl.textContent = startNode.textContent; + startNode.parentNode.replaceChild(repl, startNode); + return ret; + } + }, { + key: "wrapRangeInMappedTextNode", + value: function wrapRangeInMappedTextNode(dict, start, end, filterCb, eachCb) { + var _this5 = this; + dict.nodes.every(function(n, i) { + var sibl = dict.nodes[i + 1]; + if (typeof sibl === "undefined" || sibl.start > start) { + if (!filterCb(n.node)) { + return false; + } + var s = start - n.start, e = (end > n.end ? n.end : end) - n.start, startStr = dict.value.substr(0, n.start), endStr = dict.value.substr(e + n.start); + n.node = _this5.wrapRangeInTextNode(n.node, s, e); + dict.value = startStr + endStr; + dict.nodes.forEach(function(k, j) { + if (j >= i) { + if (dict.nodes[j].start > 0 && j !== i) { + dict.nodes[j].start -= e; + } + dict.nodes[j].end -= e; + } + }); + end -= e; + eachCb(n.node.previousSibling, n.start); + if (end > n.end) { + start = n.end; + } else { + return false; + } + } + return true; + }); + } + }, { + key: "wrapMatches", + value: function wrapMatches(regex, ignoreGroups, filterCb, eachCb, endCb) { + var _this6 = this; + var matchIdx = ignoreGroups === 0 ? 0 : ignoreGroups + 1; + this.getTextNodes(function(dict) { + dict.nodes.forEach(function(node) { + node = node.node; + var match = void 0; + while ((match = regex.exec(node.textContent)) !== null && match[matchIdx] !== "") { + if (!filterCb(match[matchIdx], node)) { + continue; + } + var pos = match.index; + if (matchIdx !== 0) { + for (var i = 1; i < matchIdx; i++) { + pos += match[i].length; + } + } + node = _this6.wrapRangeInTextNode(node, pos, pos + match[matchIdx].length); + eachCb(node.previousSibling); + regex.lastIndex = 0; + } + }); + endCb(); + }); + } + }, { + key: "wrapMatchesAcrossElements", + value: function wrapMatchesAcrossElements(regex, ignoreGroups, filterCb, eachCb, endCb) { + var _this7 = this; + var matchIdx = ignoreGroups === 0 ? 0 : ignoreGroups + 1; + this.getTextNodes(function(dict) { + var match = void 0; + while ((match = regex.exec(dict.value)) !== null && match[matchIdx] !== "") { + var start = match.index; + if (matchIdx !== 0) { + for (var i = 1; i < matchIdx; i++) { + start += match[i].length; + } + } + var end = start + match[matchIdx].length; + _this7.wrapRangeInMappedTextNode(dict, start, end, function(node) { + return filterCb(match[matchIdx], node); + }, function(node, lastIndex) { + regex.lastIndex = lastIndex; + eachCb(node); + }); + } + endCb(); + }); + } + }, { + key: "wrapRangeFromIndex", + value: function wrapRangeFromIndex(ranges, filterCb, eachCb, endCb) { + var _this8 = this; + this.getTextNodes(function(dict) { + var originalLength = dict.value.length; + ranges.forEach(function(range, counter) { + var _checkWhitespaceRange = _this8.checkWhitespaceRanges(range, originalLength, dict.value), start = _checkWhitespaceRange.start, end = _checkWhitespaceRange.end, valid = _checkWhitespaceRange.valid; + if (valid) { + _this8.wrapRangeInMappedTextNode(dict, start, end, function(node) { + return filterCb(node, range, dict.value.substring(start, end), counter); + }, function(node) { + eachCb(node, range); + }); + } + }); + endCb(); + }); + } + }, { + key: "unwrapMatches", + value: function unwrapMatches(node) { + var parent = node.parentNode; + var docFrag = document.createDocumentFragment(); + while (node.firstChild) { + docFrag.appendChild(node.removeChild(node.firstChild)); + } + parent.replaceChild(docFrag, node); + if (!this.ie) { + parent.normalize(); + } else { + this.normalizeTextNode(parent); + } + } + }, { + key: "normalizeTextNode", + value: function normalizeTextNode(node) { + if (!node) { + return; + } + if (node.nodeType === 3) { + while (node.nextSibling && node.nextSibling.nodeType === 3) { + node.nodeValue += node.nextSibling.nodeValue; + node.parentNode.removeChild(node.nextSibling); + } + } else { + this.normalizeTextNode(node.firstChild); + } + this.normalizeTextNode(node.nextSibling); + } + }, { + key: "markRegExp", + value: function markRegExp(regexp, opt) { + var _this9 = this; + this.opt = opt; + this.log('Searching with expression "' + regexp + '"'); + var totalMatches = 0, fn = "wrapMatches"; + var eachCb = function eachCb2(element) { + totalMatches++; + _this9.opt.each(element); + }; + if (this.opt.acrossElements) { + fn = "wrapMatchesAcrossElements"; + } + this[fn](regexp, this.opt.ignoreGroups, function(match, node) { + return _this9.opt.filter(node, match, totalMatches); + }, eachCb, function() { + if (totalMatches === 0) { + _this9.opt.noMatch(regexp); + } + _this9.opt.done(totalMatches); + }); + } + }, { + key: "mark", + value: function mark(sv, opt) { + var _this10 = this; + this.opt = opt; + var totalMatches = 0, fn = "wrapMatches"; + var _getSeparatedKeywords = this.getSeparatedKeywords(typeof sv === "string" ? [sv] : sv), kwArr = _getSeparatedKeywords.keywords, kwArrLen = _getSeparatedKeywords.length, sens = this.opt.caseSensitive ? "" : "i", handler = function handler2(kw) { + var regex = new RegExp(_this10.createRegExp(kw), "gm" + sens), matches = 0; + _this10.log('Searching with expression "' + regex + '"'); + _this10[fn](regex, 1, function(term, node) { + return _this10.opt.filter(node, kw, totalMatches, matches); + }, function(element) { + matches++; + totalMatches++; + _this10.opt.each(element); + }, function() { + if (matches === 0) { + _this10.opt.noMatch(kw); + } + if (kwArr[kwArrLen - 1] === kw) { + _this10.opt.done(totalMatches); + } else { + handler2(kwArr[kwArr.indexOf(kw) + 1]); + } + }); + }; + if (this.opt.acrossElements) { + fn = "wrapMatchesAcrossElements"; + } + if (kwArrLen === 0) { + this.opt.done(totalMatches); + } else { + handler(kwArr[0]); + } + } + }, { + key: "markRanges", + value: function markRanges(rawRanges, opt) { + var _this11 = this; + this.opt = opt; + var totalMatches = 0, ranges = this.checkRanges(rawRanges); + if (ranges && ranges.length) { + this.log("Starting to mark with the following ranges: " + JSON.stringify(ranges)); + this.wrapRangeFromIndex(ranges, function(node, range, match, counter) { + return _this11.opt.filter(node, range, match, counter); + }, function(element, range) { + totalMatches++; + _this11.opt.each(element, range); + }, function() { + _this11.opt.done(totalMatches); + }); + } else { + this.opt.done(totalMatches); + } + } + }, { + key: "unmark", + value: function unmark(opt) { + var _this12 = this; + this.opt = opt; + var sel = this.opt.element ? this.opt.element : "*"; + sel += "[data-markjs]"; + if (this.opt.className) { + sel += "." + this.opt.className; + } + this.log('Removal selector "' + sel + '"'); + this.iterator.forEachNode(NodeFilter.SHOW_ELEMENT, function(node) { + _this12.unwrapMatches(node); + }, function(node) { + var matchesSel = DOMIterator.matches(node, sel), matchesExclude = _this12.matchesExclude(node); + if (!matchesSel || matchesExclude) { + return NodeFilter.FILTER_REJECT; + } else { + return NodeFilter.FILTER_ACCEPT; + } + }, this.opt.done); + } + }, { + key: "opt", + set: function set$$1(val) { + this._opt = _extends({}, { + "element": "", + "className": "", + "exclude": [], + "iframes": false, + "iframesTimeout": 5e3, + "separateWordSearch": true, + "diacritics": true, + "synonyms": {}, + "accuracy": "partially", + "acrossElements": false, + "caseSensitive": false, + "ignoreJoiners": false, + "ignoreGroups": 0, + "ignorePunctuation": [], + "wildcards": "disabled", + "each": function each() { + }, + "noMatch": function noMatch() { + }, + "filter": function filter() { + return true; + }, + "done": function done() { + }, + "debug": false, + "log": window.console + }, val); + }, + get: function get$$1() { + return this._opt; + } + }, { + key: "iterator", + get: function get$$1() { + return new DOMIterator(this.ctx, this.opt.iframes, this.opt.exclude, this.opt.iframesTimeout); + } + }]); + return Mark3; + })(); + function Mark2(ctx) { + var _this = this; + var instance = new Mark$1(ctx); + this.mark = function(sv, opt) { + instance.mark(sv, opt); + return _this; + }; + this.markRegExp = function(sv, opt) { + instance.markRegExp(sv, opt); + return _this; + }; + this.markRanges = function(sv, opt) { + instance.markRanges(sv, opt); + return _this; + }; + this.unmark = function(opt) { + instance.unmark(opt); + return _this; + }; + return this; + } + return Mark2; + })); + } +}); + +// lib/highlight.ts +var import_mark = __toESM(require_mark(), 1); +var PagefindHighlight = class { + constructor(options = { + markContext: null, + highlightParam: "pagefind-highlight", + markOptions: { + className: "pagefind-highlight", + exclude: ["[data-pagefind-ignore]", "[data-pagefind-ignore] *"] + }, + addStyles: true + }) { + var _a, _b; + const { highlightParam, markContext, markOptions, addStyles } = options; + this.highlightParam = highlightParam ?? "pagefind-highlight"; + this.addStyles = addStyles ?? true; + this.markContext = markContext !== void 0 ? markContext : null; + this.markOptions = markOptions !== void 0 ? markOptions : { + className: "pagefind-highlight", + exclude: ["[data-pagefind-ignore]", "[data-pagefind-ignore] *"] + }; + (_a = this.markOptions).className ?? (_a.className = "pagefind__highlight"); + (_b = this.markOptions).exclude ?? (_b.exclude = [ + "[data-pagefind-ignore]", + "[data-pagefind-ignore] *" + ]); + this.markOptions.separateWordSearch = false; + this.highlight(); + } + getHighlightParams(paramName) { + const urlParams = new URLSearchParams(window.location.search); + return urlParams.getAll(paramName); + } + // Inline styles might be too hard to override + addHighlightStyles(className) { + if (!className) return; + const styleElement = document.createElement("style"); + styleElement.innerText = `:where(.${className}) { background-color: yellow; color: black; }`; + document.head.appendChild(styleElement); + } + createMarkInstance() { + if (this.markContext) { + return new import_mark.default(this.markContext); + } + const pagefindBody = document.querySelectorAll("[data-pagefind-body]"); + if (pagefindBody.length !== 0) { + return new import_mark.default(pagefindBody); + } else { + return new import_mark.default(document.body); + } + } + markText(instance, text) { + instance.mark(text, this.markOptions); + } + highlight() { + const params = this.getHighlightParams(this.highlightParam); + if (!params || params.length === 0) return; + this.addStyles && this.addHighlightStyles(this.markOptions.className); + const markInstance = this.createMarkInstance(); + this.markText(markInstance, params); + } +}; +window.PagefindHighlight = PagefindHighlight; +export { + PagefindHighlight as default +}; +/*! Bundled license information: + +mark.js/dist/mark.js: + (*!*************************************************** + * mark.js v8.11.1 + * https://markjs.io/ + * Copyright (c) 2014–2018, Julian Kühnel + * Released under the MIT license https://git.io/vwTVl + *****************************************************) +*/ diff --git a/dist/pagefind/pagefind-modular-ui.css b/dist/pagefind/pagefind-modular-ui.css new file mode 100644 index 0000000..9c6793e --- /dev/null +++ b/dist/pagefind/pagefind-modular-ui.css @@ -0,0 +1,214 @@ +:root { + --pagefind-ui-scale: 0.8; + --pagefind-ui-primary: #034AD8; + --pagefind-ui-fade: #707070; + --pagefind-ui-text: #393939; + --pagefind-ui-background: #ffffff; + --pagefind-ui-border: #eeeeee; + --pagefind-ui-tag: #eeeeee; + --pagefind-ui-border-width: 2px; + --pagefind-ui-border-radius: 8px; + --pagefind-ui-image-border-radius: 8px; + --pagefind-ui-image-box-ratio: 3 / 2; + --pagefind-ui-font: system, -apple-system, ".SFNSText-Regular", + "San Francisco", "Roboto", "Segoe UI", "Helvetica Neue", + "Lucida Grande", sans-serif; +} + +[data-pfmod-hidden] { + display: none !important; +} + +[data-pfmod-suppressed] { + opacity: 0 !important; + pointer-events: none !important; +} + +[data-pfmod-sr-hidden] { + -webkit-clip: rect(0 0 0 0) !important; + clip: rect(0 0 0 0) !important; + -webkit-clip-path: inset(100%) !important; + clip-path: inset(100%) !important; + height: 1px !important; + overflow: hidden !important; + overflow: clip !important; + position: absolute !important; + white-space: nowrap !important; + width: 1px !important; +} + +[data-pfmod-loading] { + color: var(--pagefind-ui-text); + background-color: var(--pagefind-ui-text); + border-radius: var(--pagefind-ui-border-radius); + opacity: 0.1; + pointer-events: none; +} + +/* Input */ + +.pagefind-modular-input-wrapper { + position: relative; +} + +.pagefind-modular-input-wrapper::before { + background-color: var(--pagefind-ui-text); + width: calc(18px * var(--pagefind-ui-scale)); + height: calc(18px * var(--pagefind-ui-scale)); + top: calc(23px * var(--pagefind-ui-scale)); + left: calc(20px * var(--pagefind-ui-scale)); + content: ""; + position: absolute; + display: block; + opacity: 0.7; + -webkit-mask-image: url("data:image/svg+xml,%3Csvg width='18' height='18' viewBox='0 0 18 18' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12.7549 11.255H11.9649L11.6849 10.985C12.6649 9.845 13.2549 8.365 13.2549 6.755C13.2549 3.165 10.3449 0.255005 6.75488 0.255005C3.16488 0.255005 0.254883 3.165 0.254883 6.755C0.254883 10.345 3.16488 13.255 6.75488 13.255C8.36488 13.255 9.84488 12.665 10.9849 11.685L11.2549 11.965V12.755L16.2549 17.745L17.7449 16.255L12.7549 11.255ZM6.75488 11.255C4.26488 11.255 2.25488 9.245 2.25488 6.755C2.25488 4.26501 4.26488 2.255 6.75488 2.255C9.24488 2.255 11.2549 4.26501 11.2549 6.755C11.2549 9.245 9.24488 11.255 6.75488 11.255Z' fill='%23000000'/%3E%3C/svg%3E%0A"); + mask-image: url("data:image/svg+xml,%3Csvg width='18' height='18' viewBox='0 0 18 18' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12.7549 11.255H11.9649L11.6849 10.985C12.6649 9.845 13.2549 8.365 13.2549 6.755C13.2549 3.165 10.3449 0.255005 6.75488 0.255005C3.16488 0.255005 0.254883 3.165 0.254883 6.755C0.254883 10.345 3.16488 13.255 6.75488 13.255C8.36488 13.255 9.84488 12.665 10.9849 11.685L11.2549 11.965V12.755L16.2549 17.745L17.7449 16.255L12.7549 11.255ZM6.75488 11.255C4.26488 11.255 2.25488 9.245 2.25488 6.755C2.25488 4.26501 4.26488 2.255 6.75488 2.255C9.24488 2.255 11.2549 4.26501 11.2549 6.755C11.2549 9.245 9.24488 11.255 6.75488 11.255Z' fill='%23000000'/%3E%3C/svg%3E%0A"); + -webkit-mask-size: 100%; + mask-size: 100%; + z-index: 9; + pointer-events: none; +} + +.pagefind-modular-input { + height: calc(64px * var(--pagefind-ui-scale)); + padding: 0 calc(70px * var(--pagefind-ui-scale)) 0 calc(54px * var(--pagefind-ui-scale)); + background-color: var(--pagefind-ui-background); + border: var(--pagefind-ui-border-width) solid var(--pagefind-ui-border); + border-radius: var(--pagefind-ui-border-radius); + font-size: calc(21px * var(--pagefind-ui-scale)); + position: relative; + appearance: none; + -webkit-appearance: none; + display: flex; + width: 100%; + box-sizing: border-box; + font-weight: 700; +} + +.pagefind-modular-input::placeholder { + opacity: 0.2; +} + +.pagefind-modular-input-clear { + position: absolute; + top: calc(2px * var(--pagefind-ui-scale)); + right: calc(2px * var(--pagefind-ui-scale)); + height: calc(60px * var(--pagefind-ui-scale)); + border-radius: var(--pagefind-ui-border-radius); + padding: 0 calc(15px * var(--pagefind-ui-scale)) 0 calc(2px * var(--pagefind-ui-scale)); + color: var(--pagefind-ui-text); + font-size: calc(14px * var(--pagefind-ui-scale)); + cursor: pointer; + background-color: var(--pagefind-ui-background); + border: none; + appearance: none; +} + +/* ResultList */ + +.pagefind-modular-list-result { + list-style-type: none; + display: flex; + align-items: flex-start; + gap: min(calc(40px * var(--pagefind-ui-scale)), 3%); + padding: calc(30px * var(--pagefind-ui-scale)) 0 calc(40px * var(--pagefind-ui-scale)); + border-top: solid var(--pagefind-ui-border-width) var(--pagefind-ui-border); +} + +.pagefind-modular-list-result:last-of-type { + border-bottom: solid var(--pagefind-ui-border-width) var(--pagefind-ui-border); +} + +.pagefind-modular-list-thumb { + width: min(30%, + calc((30% - (100px * var(--pagefind-ui-scale))) * 100000)); + max-width: calc(120px * var(--pagefind-ui-scale)); + margin-top: calc(10px * var(--pagefind-ui-scale)); + aspect-ratio: var(--pagefind-ui-image-box-ratio); + position: relative; +} + +.pagefind-modular-list-image { + display: block; + position: absolute; + left: 50%; + transform: translateX(-50%); + font-size: 0; + width: auto; + height: auto; + max-width: 100%; + max-height: 100%; + border-radius: var(--pagefind-ui-image-border-radius); +} + +.pagefind-modular-list-inner { + flex: 1; + display: flex; + flex-direction: column; + align-items: flex-start; + margin-top: calc(10px * var(--pagefind-ui-scale)); +} + +.pagefind-modular-list-title { + display: inline-block; + font-weight: 700; + font-size: calc(21px * var(--pagefind-ui-scale)); + margin-top: 0; + margin-bottom: 0; +} + +.pagefind-modular-list-link { + color: var(--pagefind-ui-text); + text-decoration: none; +} + +.pagefind-modular-list-link:hover { + text-decoration: underline; +} + +.pagefind-modular-list-excerpt { + display: inline-block; + font-weight: 400; + font-size: calc(16px * var(--pagefind-ui-scale)); + margin-top: calc(4px * var(--pagefind-ui-scale)); + margin-bottom: 0; + min-width: calc(250px * var(--pagefind-ui-scale)); +} + +/* FilterPills */ + +.pagefind-modular-filter-pills-wrapper { + overflow-x: scroll; + padding: 15px 0; +} + +.pagefind-modular-filter-pills { + display: flex; + gap: 6px; +} + +.pagefind-modular-filter-pill { + display: flex; + justify-content: center; + align-items: center; + border: none; + appearance: none; + padding: 0 calc(24px * var(--pagefind-ui-scale)); + background-color: var(--pagefind-ui-background); + color: var(--pagefind-ui-fade); + border: var(--pagefind-ui-border-width) solid var(--pagefind-ui-border); + border-radius: calc(25px * var(--pagefind-ui-scale)); + font-size: calc(18px * var(--pagefind-ui-scale)); + height: calc(50px * var(--pagefind-ui-scale)); + cursor: pointer; + white-space: nowrap; +} + +.pagefind-modular-filter-pill:hover { + border-color: var(--pagefind-ui-primary); +} + +.pagefind-modular-filter-pill[aria-pressed="true"] { + border-color: var(--pagefind-ui-primary); + color: var(--pagefind-ui-primary); +} \ No newline at end of file diff --git a/dist/pagefind/pagefind-modular-ui.js b/dist/pagefind/pagefind-modular-ui.js new file mode 100644 index 0000000..6caacd6 --- /dev/null +++ b/dist/pagefind/pagefind-modular-ui.js @@ -0,0 +1,8 @@ +(()=>{var w=Object.defineProperty;var b=(i,e)=>{for(var t in e)w(i,t,{get:e[t],enumerable:!0})};var f={};b(f,{FilterPills:()=>c,Input:()=>a,Instance:()=>p,ResultList:()=>o,Summary:()=>h});var r=class i{constructor(e){this.element=document.createElement(e)}id(e){return this.element.id=e,this}class(e){return this.element.classList.add(e),this}attrs(e){for(let[t,s]of Object.entries(e))this.element.setAttribute(t,s);return this}text(e){return this.element.innerText=e,this}html(e){return this.element.innerHTML=e,this}handle(e,t){return this.element.addEventListener(e,t),this}addTo(e){return e instanceof i?e.element.appendChild(this.element):e.appendChild(this.element),this.element}};var T=async(i=100)=>new Promise(e=>setTimeout(e,i)),a=class{constructor(e={}){if(this.inputEl=null,this.clearEl=null,this.instance=null,this.searchID=0,this.debounceTimeoutMs=e.debounceTimeoutMs??300,e.inputElement){if(e.containerElement){console.warn("[Pagefind Input component]: inputElement and containerElement both supplied. Ignoring the container option.");return}this.initExisting(e.inputElement)}else if(e.containerElement)this.initContainer(e.containerElement);else{console.error("[Pagefind Input component]: No selector supplied for containerElement or inputElement");return}this.inputEl.addEventListener("input",async t=>{if(this.instance&&typeof t?.target?.value=="string"){this.updateState(t.target.value);let s=++this.searchID;if(await T(this.debounceTimeoutMs),s!==this.searchID)return null;this.instance?.triggerSearch(t.target.value)}}),this.inputEl.addEventListener("keydown",t=>{t.key==="Escape"&&(++this.searchID,this.inputEl.value="",this.instance?.triggerSearch(""),this.updateState("")),t.key==="Enter"&&t.preventDefault()}),this.inputEl.addEventListener("focus",()=>{this.instance?.triggerLoad()})}initContainer(e){let t=document.querySelector(e);if(!t){console.error(`[Pagefind Input component]: No container found for ${e} selector`);return}if(t.tagName==="INPUT")console.warn(`[Pagefind Input component]: Encountered input element for ${e} when a container was expected`),console.warn("[Pagefind Input component]: Treating containerElement option as inputElement and proceeding"),this.initExisting(e);else{t.innerHTML="";let s=0;for(;document.querySelector(`#pfmod-input-${s}`);)s+=1;let n=new r("form").class("pagefind-modular-input-wrapper").attrs({role:"search","aria-label":"Search this site",action:"javascript:void(0);"});new r("label").attrs({for:`pfmod-input-${s}`,"data-pfmod-sr-hidden":"true"}).text("Search this site").addTo(n),this.inputEl=new r("input").id(`pfmod-input-${s}`).class("pagefind-modular-input").attrs({autocapitalize:"none",enterkeyhint:"search"}).addTo(n),this.clearEl=new r("button").class("pagefind-modular-input-clear").attrs({"data-pfmod-suppressed":"true"}).text("Clear").handle("click",()=>{this.inputEl.value="",this.instance.triggerSearch(""),this.updateState("")}).addTo(n),n.addTo(t)}}initExisting(e){let t=document.querySelector(e);if(!t){console.error(`[Pagefind Input component]: No input element found for ${e} selector`);return}if(t.tagName!=="INPUT"){console.error(`[Pagefind Input component]: Expected ${e} to be an element`);return}this.inputEl=t}updateState(e){this.clearEl&&(e&&e?.length?this.clearEl.removeAttribute("data-pfmod-suppressed"):this.clearEl.setAttribute("data-pfmod-suppressed","true"))}register(e){this.instance=e,this.instance.on("search",(t,s)=>{this.inputEl&&document.activeElement!==this.inputEl&&(this.inputEl.value=t,this.updateState(t))})}focus(){this.inputEl&&this.inputEl.focus()}};var g=i=>{if(i instanceof Element)return[i];if(Array.isArray(i)&&i.every(e=>e instanceof Element))return i;if(typeof i=="string"||i instanceof String){let e=document.createElement("div");return e.innerHTML=i,[...e.childNodes]}else return console.error(`[Pagefind ResultList component]: Expected template function to return an HTML element or string, got ${typeof i}`),[]},v=()=>{let i=(e=30)=>". ".repeat(Math.floor(10+Math.random()*e));return`
  • +
    +
    +

    ${i(30)}

    +

    ${i(40)}

    +
    +
  • `},y=(i,e)=>{let t=new r("li").class("pagefind-modular-list-result");if(e){let l=new r("div").class("pagefind-modular-list-thumb").addTo(t);i?.meta?.image&&new r("img").class("pagefind-modular-list-image").attrs({src:i.meta.image,alt:i.meta.image_alt||i.meta.title}).addTo(l)}let s=new r("div").class("pagefind-modular-list-inner").addTo(t),n=new r("p").class("pagefind-modular-list-title").addTo(s);return new r("a").class("pagefind-modular-list-link").text(i.meta?.title).attrs({href:i.meta?.url||i.url}).addTo(n),new r("p").class("pagefind-modular-list-excerpt").html(i.excerpt).addTo(s),t.element},E=i=>{if(!(i instanceof HTMLElement))return null;let e=window.getComputedStyle(i).overflowY;return e!=="visible"&&e!=="hidden"?i:E(i.parentNode)},d=class{constructor(e={}){this.rawResult=e.result,this.placeholderNodes=e.placeholderNodes,this.resultFn=e.resultFn,this.intersectionEl=e.intersectionEl,this.showImages=e.showImages,this.result=null,this.waitForIntersection()}waitForIntersection(){if(!this.placeholderNodes?.length)return;let e={root:this.intersectionEl,rootMargin:"0px",threshold:.01};new IntersectionObserver((s,n)=>{this.result===null&&s?.[0]?.isIntersecting&&(this.load(),n.disconnect())},e).observe(this.placeholderNodes[0])}async load(){if(!this.placeholderNodes?.length)return;this.result=await this.rawResult.data();let e=this.resultFn(this.result,this.showImages),t=g(e);for(;this.placeholderNodes.length>1;)this.placeholderNodes.pop().remove();this.placeholderNodes[0].replaceWith(...t)}},o=class{constructor(e){if(this.intersectionEl=document.body,this.containerEl=null,this.results=[],this.placeholderTemplate=e.placeholderTemplate??v,this.resultTemplate=e.resultTemplate??y,this.showImages=e.showImages??!0,e.containerElement)this.initContainer(e.containerElement);else{console.error("[Pagefind ResultList component]: No selector supplied for containerElement");return}}initContainer(e){let t=document.querySelector(e);if(!t){console.error(`[Pagefind ResultList component]: No container found for ${e} selector`);return}this.containerEl=t}append(e){for(let t of e)this.containerEl.appendChild(t)}register(e){e.on("results",t=>{this.containerEl&&(this.containerEl.innerHTML="",this.intersectionEl=E(this.containerEl),this.results=t.results.map(s=>{let n=g(this.placeholderTemplate());return this.append(n),new d({result:s,placeholderNodes:n,resultFn:this.resultTemplate,intersectionEl:this.intersectionEl,showImages:this.showImages})}))}),e.on("loading",()=>{this.containerEl&&(this.containerEl.innerHTML="")})}};var h=class{constructor(e={}){if(this.containerEl=null,this.defaultMessage=e.defaultMessage??"",this.term="",e.containerElement)this.initContainer(e.containerElement);else{console.error("[Pagefind Summary component]: No selector supplied for containerElement");return}}initContainer(e){let t=document.querySelector(e);if(!t){console.error(`[Pagefind Summary component]: No container found for ${e} selector`);return}this.containerEl=t,this.containerEl.innerText=this.defaultMessage}register(e){e.on("search",(t,s)=>{this.term=t}),e.on("results",t=>{if(!this.containerEl||!t)return;if(!this.term){this.containerEl.innerText=this.defaultMessage;return}let s=t?.results?.length??0;this.containerEl.innerText=`${s} result${s===1?"":"s"} for ${this.term}`}),e.on("loading",()=>{this.containerEl&&(this.containerEl.innerText=`Searching for ${this.term}...`)})}};var c=class{constructor(e={}){if(this.instance=null,this.wrapper=null,this.pillContainer=null,this.available={},this.selected=["All"],this.total=0,this.filterMemo="",this.filter=e.filter,this.ordering=e.ordering??null,this.alwaysShow=e.alwaysShow??!1,this.selectMultiple=e.selectMultiple??!1,!this.filter?.length){console.error("[Pagefind FilterPills component]: No filter option supplied, nothing to display");return}if(e.containerElement)this.initContainer(e.containerElement);else{console.error("[Pagefind FilterPills component]: No selector supplied for containerElement");return}}initContainer(e){let t=document.querySelector(e);if(!t){console.error(`[Pagefind FilterPills component]: No container found for ${e} selector`);return}t.innerHTML="";let s=`pagefind_modular_filter_pills_${this.filter}`,n=new r("div").class("pagefind-modular-filter-pills-wrapper").attrs({role:"group","aria-labelledby":s});this.alwaysShow||n.attrs({"data-pfmod-hidden":!0}),new r("div").id(s).class("pagefind-modular-filter-pills-label").attrs({"data-pfmod-sr-hidden":!0}).text(`Filter results by ${this.filter}`).addTo(n),this.pillContainer=new r("div").class("pagefind-modular-filter-pills").addTo(n),this.wrapper=n.addTo(t)}update(){let e=this.available.map(t=>t[0]).join("~");e==this.filterMemo?this.updateExisting():(this.renderNew(),this.filterMemo=e)}pushFilters(){let e=this.selected.filter(t=>t!=="All");this.instance.triggerFilter(this.filter,e)}pillInner(e,t){return this.total?`${e} (${t})`:`${e}`}renderNew(){this.available.forEach(([e,t])=>{new r("button").class("pagefind-modular-filter-pill").html(this.pillInner(e,t)).attrs({"aria-pressed":this.selected.includes(e),type:"button"}).handle("click",()=>{e==="All"?this.selected=["All"]:this.selected.includes(e)?this.selected=this.selected.filter(s=>s!==e):this.selectMultiple?this.selected.push(e):this.selected=[e],this.selected?.length?this.selected?.length>1&&(this.selected=this.selected.filter(s=>s!=="All")):this.selected=["All"],this.update(),this.pushFilters()}).addTo(this.pillContainer)})}updateExisting(){let e=[...this.pillContainer.childNodes];this.available.forEach(([t,s],n)=>{e[n].innerHTML=this.pillInner(t,s),e[n].setAttribute("aria-pressed",this.selected.includes(t))})}register(e){this.instance=e,this.instance.on("filters",t=>{if(!this.pillContainer)return;this.selectMultiple?t=t.available:t=t.total;let s=t[this.filter];if(!s){console.warn(`[Pagefind FilterPills component]: No possible values found for the ${this.filter} filter`);return}this.available=Object.entries(s),Array.isArray(this.ordering)?this.available.sort((n,l)=>{let m=this.ordering.indexOf(n[0]),_=this.ordering.indexOf(l[0]);return(m===-1?1/0:m)-(_===-1?1/0:_)}):this.available.sort((n,l)=>n[0].localeCompare(l[0])),this.available.unshift(["All",this.total]),this.update()}),e.on("results",t=>{this.pillContainer&&(this.total=t?.unfilteredResultCount||0,this.available?.[0]?.[0]==="All"&&(this.available[0][1]=this.total),this.total||this.alwaysShow?this.wrapper.removeAttribute("data-pfmod-hidden"):this.wrapper.setAttribute("data-pfmod-hidden","true"),this.update())})}};var P=async(i=50)=>await new Promise(e=>setTimeout(e,i)),u;try{document?.currentScript&&document.currentScript.tagName.toUpperCase()==="SCRIPT"&&(u=new URL(document.currentScript.src).pathname.match(/^(.*\/)(?:pagefind-)?modular-ui.js.*$/)[1])}catch{u="/pagefind/"}var p=class{constructor(e={}){this.__pagefind__=null,this.__initializing__=null,this.__searchID__=0,this.__hooks__={search:[],filters:[],loading:[],results:[]},this.components=[],this.searchTerm="",this.searchFilters={},this.searchResult={},this.availableFilters=null,this.totalFilters=null,this.options={bundlePath:e.bundlePath??u,mergeIndex:e.mergeIndex??[]},delete e.bundlePath,delete e.resetStyles,delete e.processResult,delete e.processTerm,delete e.debounceTimeoutMs,delete e.mergeIndex,delete e.translations,this.pagefindOptions=e}add(e){e?.register?.(this),this.components.push(e)}on(e,t){if(!this.__hooks__[e]){let s=Object.keys(this.__hooks__).join(", ");console.error(`[Pagefind Composable]: Unknown event type ${e}. Supported events: [${s}]`);return}if(typeof t!="function"){console.error(`[Pagefind Composable]: Expected callback to be a function, received ${typeof t}`);return}this.__hooks__[e].push(t)}triggerLoad(){this.__load__()}triggerSearch(e){this.searchTerm=e,this.__dispatch__("search",e,this.searchFilters),this.__search__(e,this.searchFilters)}triggerSearchWithFilters(e,t){this.searchTerm=e,this.searchFilters=t,this.__dispatch__("search",e,t),this.__search__(e,t)}triggerFilters(e){this.searchFilters=e,this.__dispatch__("search",this.searchTerm,e),this.__search__(this.searchTerm,e)}triggerFilter(e,t){this.searchFilters=this.searchFilters||{},this.searchFilters[e]=t,this.__dispatch__("search",this.searchTerm,this.searchFilters),this.__search__(this.searchTerm,this.searchFilters)}__dispatch__(e,...t){this.__hooks__[e]?.forEach(s=>s?.(...t))}async __clear__(){this.__dispatch__("results",{results:[],unfilteredTotalCount:0}),this.availableFilters=await this.__pagefind__.filters(),this.totalFilters=this.availableFilters,this.__dispatch__("filters",{available:this.availableFilters,total:this.totalFilters})}async __search__(e,t){this.__dispatch__("loading"),await this.__load__();let s=++this.__searchID__;if(!e||!e.length)return this.__clear__();let n=await this.__pagefind__.search(e,{filters:t});n&&this.__searchID__===s&&(n.filters&&Object.keys(n.filters)?.length&&(this.availableFilters=n.filters,this.totalFilters=n.totalFilters,this.__dispatch__("filters",{available:this.availableFilters,total:this.totalFilters})),this.searchResult=n,this.__dispatch__("results",this.searchResult))}async __load__(){if(this.__initializing__){for(;!this.__pagefind__;)await P(50);return}if(this.__initializing__=!0,!this.__pagefind__){let e;try{e=await import(`${this.options.bundlePath}pagefind.js`)}catch(t){console.error(t),console.error([`Pagefind couldn't be loaded from ${this.options.bundlePath}pagefind.js`,"You can configure this by passing a bundlePath option to PagefindComposable Instance"].join(` +`)),document?.currentScript&&document.currentScript.tagName.toUpperCase()==="SCRIPT"?console.error(`[DEBUG: Loaded from ${document.currentScript?.src??"bad script location"}]`):console.error("no known script location")}await e.options(this.pagefindOptions||{});for(let t of this.options.mergeIndex){if(!t.bundlePath)throw new Error("mergeIndex requires a bundlePath parameter");let s=t.bundlePath;delete t.bundlePath,await e.mergeIndex(s,t)}this.__pagefind__=e}this.availableFilters=await this.__pagefind__.filters(),this.totalFilters=this.availableFilters,this.__dispatch__("filters",{available:this.availableFilters,total:this.totalFilters})}};window.PagefindModularUI=f;})(); diff --git a/dist/pagefind/pagefind-ui.css b/dist/pagefind/pagefind-ui.css new file mode 100644 index 0000000..d7984a9 --- /dev/null +++ b/dist/pagefind/pagefind-ui.css @@ -0,0 +1 @@ +.pagefind-ui__result.svelte-j9e30.svelte-j9e30{list-style-type:none;display:flex;align-items:flex-start;gap:min(calc(40px * var(--pagefind-ui-scale)),3%);padding:calc(30px * var(--pagefind-ui-scale)) 0 calc(40px * var(--pagefind-ui-scale));border-top:solid var(--pagefind-ui-border-width) var(--pagefind-ui-border)}.pagefind-ui__result.svelte-j9e30.svelte-j9e30:last-of-type{border-bottom:solid var(--pagefind-ui-border-width) var(--pagefind-ui-border)}.pagefind-ui__result-thumb.svelte-j9e30.svelte-j9e30{width:min(30%,calc((30% - (100px * var(--pagefind-ui-scale))) * 100000));max-width:calc(120px * var(--pagefind-ui-scale));margin-top:calc(10px * var(--pagefind-ui-scale));aspect-ratio:var(--pagefind-ui-image-box-ratio);position:relative}.pagefind-ui__result-image.svelte-j9e30.svelte-j9e30{display:block;position:absolute;left:50%;transform:translate(-50%);font-size:0;width:auto;height:auto;max-width:100%;max-height:100%;border-radius:var(--pagefind-ui-image-border-radius)}.pagefind-ui__result-inner.svelte-j9e30.svelte-j9e30{flex:1;display:flex;flex-direction:column;align-items:flex-start;margin-top:calc(10px * var(--pagefind-ui-scale))}.pagefind-ui__result-title.svelte-j9e30.svelte-j9e30{display:inline-block;font-weight:700;font-size:calc(21px * var(--pagefind-ui-scale));margin-top:0;margin-bottom:0}.pagefind-ui__result-title.svelte-j9e30 .pagefind-ui__result-link.svelte-j9e30{color:var(--pagefind-ui-text);text-decoration:none}.pagefind-ui__result-title.svelte-j9e30 .pagefind-ui__result-link.svelte-j9e30:hover{text-decoration:underline}.pagefind-ui__result-excerpt.svelte-j9e30.svelte-j9e30{display:inline-block;font-weight:400;font-size:calc(16px * var(--pagefind-ui-scale));margin-top:calc(4px * var(--pagefind-ui-scale));margin-bottom:0;min-width:calc(250px * var(--pagefind-ui-scale))}.pagefind-ui__loading.svelte-j9e30.svelte-j9e30{color:var(--pagefind-ui-text);background-color:var(--pagefind-ui-text);border-radius:var(--pagefind-ui-border-radius);opacity:.1;pointer-events:none}.pagefind-ui__result-tags.svelte-j9e30.svelte-j9e30{list-style-type:none;padding:0;display:flex;gap:calc(20px * var(--pagefind-ui-scale));flex-wrap:wrap;margin-top:calc(20px * var(--pagefind-ui-scale))}.pagefind-ui__result-tag.svelte-j9e30.svelte-j9e30{padding:calc(4px * var(--pagefind-ui-scale)) calc(8px * var(--pagefind-ui-scale));font-size:calc(14px * var(--pagefind-ui-scale));border-radius:var(--pagefind-ui-border-radius);background-color:var(--pagefind-ui-tag)}.pagefind-ui__result.svelte-4xnkmf.svelte-4xnkmf{list-style-type:none;display:flex;align-items:flex-start;gap:min(calc(40px * var(--pagefind-ui-scale)),3%);padding:calc(30px * var(--pagefind-ui-scale)) 0 calc(40px * var(--pagefind-ui-scale));border-top:solid var(--pagefind-ui-border-width) var(--pagefind-ui-border)}.pagefind-ui__result.svelte-4xnkmf.svelte-4xnkmf:last-of-type{border-bottom:solid var(--pagefind-ui-border-width) var(--pagefind-ui-border)}.pagefind-ui__result-nested.svelte-4xnkmf.svelte-4xnkmf{display:flex;flex-direction:column;padding-left:calc(20px * var(--pagefind-ui-scale))}.pagefind-ui__result-nested.svelte-4xnkmf.svelte-4xnkmf:first-of-type{padding-top:calc(10px * var(--pagefind-ui-scale))}.pagefind-ui__result-nested.svelte-4xnkmf .pagefind-ui__result-link.svelte-4xnkmf{font-size:.9em;position:relative}.pagefind-ui__result-nested.svelte-4xnkmf .pagefind-ui__result-link.svelte-4xnkmf:before{content:"\2937 ";position:absolute;top:0;right:calc(100% + .1em)}.pagefind-ui__result-thumb.svelte-4xnkmf.svelte-4xnkmf{width:min(30%,calc((30% - (100px * var(--pagefind-ui-scale))) * 100000));max-width:calc(120px * var(--pagefind-ui-scale));margin-top:calc(10px * var(--pagefind-ui-scale));aspect-ratio:var(--pagefind-ui-image-box-ratio);position:relative}.pagefind-ui__result-image.svelte-4xnkmf.svelte-4xnkmf{display:block;position:absolute;left:50%;transform:translate(-50%);font-size:0;width:auto;height:auto;max-width:100%;max-height:100%;border-radius:var(--pagefind-ui-image-border-radius)}.pagefind-ui__result-inner.svelte-4xnkmf.svelte-4xnkmf{flex:1;display:flex;flex-direction:column;align-items:flex-start;margin-top:calc(10px * var(--pagefind-ui-scale))}.pagefind-ui__result-title.svelte-4xnkmf.svelte-4xnkmf{display:inline-block;font-weight:700;font-size:calc(21px * var(--pagefind-ui-scale));margin-top:0;margin-bottom:0}.pagefind-ui__result-title.svelte-4xnkmf .pagefind-ui__result-link.svelte-4xnkmf{color:var(--pagefind-ui-text);text-decoration:none}.pagefind-ui__result-title.svelte-4xnkmf .pagefind-ui__result-link.svelte-4xnkmf:hover{text-decoration:underline}.pagefind-ui__result-excerpt.svelte-4xnkmf.svelte-4xnkmf{display:inline-block;font-weight:400;font-size:calc(16px * var(--pagefind-ui-scale));margin-top:calc(4px * var(--pagefind-ui-scale));margin-bottom:0;min-width:calc(250px * var(--pagefind-ui-scale))}.pagefind-ui__loading.svelte-4xnkmf.svelte-4xnkmf{color:var(--pagefind-ui-text);background-color:var(--pagefind-ui-text);border-radius:var(--pagefind-ui-border-radius);opacity:.1;pointer-events:none}.pagefind-ui__result-tags.svelte-4xnkmf.svelte-4xnkmf{list-style-type:none;padding:0;display:flex;gap:calc(20px * var(--pagefind-ui-scale));flex-wrap:wrap;margin-top:calc(20px * var(--pagefind-ui-scale))}.pagefind-ui__result-tag.svelte-4xnkmf.svelte-4xnkmf{padding:calc(4px * var(--pagefind-ui-scale)) calc(8px * var(--pagefind-ui-scale));font-size:calc(14px * var(--pagefind-ui-scale));border-radius:var(--pagefind-ui-border-radius);background-color:var(--pagefind-ui-tag)}legend.svelte-1v2r7ls.svelte-1v2r7ls{position:absolute;clip:rect(0 0 0 0)}.pagefind-ui__filter-panel.svelte-1v2r7ls.svelte-1v2r7ls{min-width:min(calc(260px * var(--pagefind-ui-scale)),100%);flex:1;display:flex;flex-direction:column;margin-top:calc(20px * var(--pagefind-ui-scale))}.pagefind-ui__filter-group.svelte-1v2r7ls.svelte-1v2r7ls{border:0;padding:0}.pagefind-ui__filter-block.svelte-1v2r7ls.svelte-1v2r7ls{padding:0;display:block;border-bottom:solid calc(2px * var(--pagefind-ui-scale)) var(--pagefind-ui-border);padding:calc(20px * var(--pagefind-ui-scale)) 0}.pagefind-ui__filter-name.svelte-1v2r7ls.svelte-1v2r7ls{font-size:calc(16px * var(--pagefind-ui-scale));position:relative;display:flex;align-items:center;list-style:none;font-weight:700;cursor:pointer;height:calc(24px * var(--pagefind-ui-scale))}.pagefind-ui__filter-name.svelte-1v2r7ls.svelte-1v2r7ls::-webkit-details-marker{display:none}.pagefind-ui__filter-name.svelte-1v2r7ls.svelte-1v2r7ls:after{position:absolute;content:"";right:calc(6px * var(--pagefind-ui-scale));top:50%;width:calc(8px * var(--pagefind-ui-scale));height:calc(8px * var(--pagefind-ui-scale));border:solid calc(2px * var(--pagefind-ui-scale)) currentColor;border-right:0;border-top:0;transform:translateY(-70%) rotate(-45deg)}.pagefind-ui__filter-block[open].svelte-1v2r7ls .pagefind-ui__filter-name.svelte-1v2r7ls:after{transform:translateY(-70%) rotate(-225deg)}.pagefind-ui__filter-group.svelte-1v2r7ls.svelte-1v2r7ls{display:flex;flex-direction:column;gap:calc(20px * var(--pagefind-ui-scale));padding-top:calc(30px * var(--pagefind-ui-scale))}.pagefind-ui__filter-value.svelte-1v2r7ls.svelte-1v2r7ls{position:relative;display:flex;align-items:center;gap:calc(8px * var(--pagefind-ui-scale))}.pagefind-ui__filter-value.svelte-1v2r7ls.svelte-1v2r7ls:before{position:absolute;content:"";top:50%;left:calc(8px * var(--pagefind-ui-scale));width:0px;height:0px;border:solid 1px #fff;opacity:0;transform:translate(calc(4.5px * var(--pagefind-ui-scale) * -1),calc(.8px * var(--pagefind-ui-scale))) skew(-5deg) rotate(-45deg);transform-origin:top left;border-top:0;border-right:0;pointer-events:none}.pagefind-ui__filter-value.pagefind-ui__filter-value--checked.svelte-1v2r7ls.svelte-1v2r7ls:before{opacity:1;width:calc(9px * var(--pagefind-ui-scale));height:calc(4px * var(--pagefind-ui-scale));transition:width .1s ease-out .1s,height .1s ease-in}.pagefind-ui__filter-checkbox.svelte-1v2r7ls.svelte-1v2r7ls{margin:0;width:calc(16px * var(--pagefind-ui-scale));height:calc(16px * var(--pagefind-ui-scale));border:solid 1px var(--pagefind-ui-border);appearance:none;-webkit-appearance:none;border-radius:calc(var(--pagefind-ui-border-radius) / 2);background-color:var(--pagefind-ui-background);cursor:pointer}.pagefind-ui__filter-checkbox.svelte-1v2r7ls.svelte-1v2r7ls:checked{background-color:var(--pagefind-ui-primary);border:solid 1px var(--pagefind-ui-primary)}.pagefind-ui__filter-label.svelte-1v2r7ls.svelte-1v2r7ls{cursor:pointer;font-size:calc(16px * var(--pagefind-ui-scale));font-weight:400}.pagefind-ui--reset *:where(:not(html,iframe,canvas,img,svg,video):not(svg *,symbol *)){all:unset;display:revert;outline:revert}.pagefind-ui--reset *,.pagefind-ui--reset *:before,.pagefind-ui--reset *:after{box-sizing:border-box}.pagefind-ui--reset a,.pagefind-ui--reset button{cursor:revert}.pagefind-ui--reset ol,.pagefind-ui--reset ul,.pagefind-ui--reset menu{list-style:none}.pagefind-ui--reset img{max-width:100%}.pagefind-ui--reset table{border-collapse:collapse}.pagefind-ui--reset input,.pagefind-ui--reset textarea{-webkit-user-select:auto}.pagefind-ui--reset textarea{white-space:revert}.pagefind-ui--reset meter{-webkit-appearance:revert;appearance:revert}.pagefind-ui--reset ::placeholder{color:unset}.pagefind-ui--reset :where([hidden]){display:none}.pagefind-ui--reset :where([contenteditable]:not([contenteditable="false"])){-moz-user-modify:read-write;-webkit-user-modify:read-write;overflow-wrap:break-word;-webkit-line-break:after-white-space;-webkit-user-select:auto}.pagefind-ui--reset :where([draggable="true"]){-webkit-user-drag:element}.pagefind-ui--reset mark{all:revert}:root{--pagefind-ui-scale:.8;--pagefind-ui-primary:#393939;--pagefind-ui-text:#393939;--pagefind-ui-background:#ffffff;--pagefind-ui-border:#eeeeee;--pagefind-ui-tag:#eeeeee;--pagefind-ui-border-width:2px;--pagefind-ui-border-radius:8px;--pagefind-ui-image-border-radius:8px;--pagefind-ui-image-box-ratio:3 / 2;--pagefind-ui-font:system, -apple-system, "BlinkMacSystemFont", ".SFNSText-Regular", "San Francisco", "Roboto", "Segoe UI", "Helvetica Neue", "Lucida Grande", "Ubuntu", "arial", sans-serif}.pagefind-ui.svelte-e9gkc3{width:100%;color:var(--pagefind-ui-text);font-family:var(--pagefind-ui-font)}.pagefind-ui__hidden.svelte-e9gkc3{display:none!important}.pagefind-ui__suppressed.svelte-e9gkc3{opacity:0;pointer-events:none}.pagefind-ui__form.svelte-e9gkc3{position:relative}.pagefind-ui__form.svelte-e9gkc3:before{background-color:var(--pagefind-ui-text);width:calc(18px * var(--pagefind-ui-scale));height:calc(18px * var(--pagefind-ui-scale));top:calc(23px * var(--pagefind-ui-scale));left:calc(20px * var(--pagefind-ui-scale));content:"";position:absolute;display:block;opacity:.7;-webkit-mask-image:url("data:image/svg+xml,%3Csvg width='18' height='18' viewBox='0 0 18 18' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12.7549 11.255H11.9649L11.6849 10.985C12.6649 9.845 13.2549 8.365 13.2549 6.755C13.2549 3.165 10.3449 0.255005 6.75488 0.255005C3.16488 0.255005 0.254883 3.165 0.254883 6.755C0.254883 10.345 3.16488 13.255 6.75488 13.255C8.36488 13.255 9.84488 12.665 10.9849 11.685L11.2549 11.965V12.755L16.2549 17.745L17.7449 16.255L12.7549 11.255ZM6.75488 11.255C4.26488 11.255 2.25488 9.245 2.25488 6.755C2.25488 4.26501 4.26488 2.255 6.75488 2.255C9.24488 2.255 11.2549 4.26501 11.2549 6.755C11.2549 9.245 9.24488 11.255 6.75488 11.255Z' fill='%23000000'/%3E%3C/svg%3E%0A");mask-image:url("data:image/svg+xml,%3Csvg width='18' height='18' viewBox='0 0 18 18' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12.7549 11.255H11.9649L11.6849 10.985C12.6649 9.845 13.2549 8.365 13.2549 6.755C13.2549 3.165 10.3449 0.255005 6.75488 0.255005C3.16488 0.255005 0.254883 3.165 0.254883 6.755C0.254883 10.345 3.16488 13.255 6.75488 13.255C8.36488 13.255 9.84488 12.665 10.9849 11.685L11.2549 11.965V12.755L16.2549 17.745L17.7449 16.255L12.7549 11.255ZM6.75488 11.255C4.26488 11.255 2.25488 9.245 2.25488 6.755C2.25488 4.26501 4.26488 2.255 6.75488 2.255C9.24488 2.255 11.2549 4.26501 11.2549 6.755C11.2549 9.245 9.24488 11.255 6.75488 11.255Z' fill='%23000000'/%3E%3C/svg%3E%0A");-webkit-mask-size:100%;mask-size:100%;z-index:9;pointer-events:none}.pagefind-ui__search-input.svelte-e9gkc3{height:calc(64px * var(--pagefind-ui-scale));padding:0 calc(70px * var(--pagefind-ui-scale)) 0 calc(54px * var(--pagefind-ui-scale));background-color:var(--pagefind-ui-background);border:var(--pagefind-ui-border-width) solid var(--pagefind-ui-border);border-radius:var(--pagefind-ui-border-radius);font-size:calc(21px * var(--pagefind-ui-scale));position:relative;appearance:none;-webkit-appearance:none;display:flex;width:100%;box-sizing:border-box;font-weight:700}.pagefind-ui__search-input.svelte-e9gkc3::placeholder{opacity:.2}.pagefind-ui__search-clear.svelte-e9gkc3{position:absolute;top:calc(3px * var(--pagefind-ui-scale));right:calc(3px * var(--pagefind-ui-scale));height:calc(58px * var(--pagefind-ui-scale));padding:0 calc(15px * var(--pagefind-ui-scale)) 0 calc(2px * var(--pagefind-ui-scale));color:var(--pagefind-ui-text);font-size:calc(14px * var(--pagefind-ui-scale));cursor:pointer;background-color:var(--pagefind-ui-background);border-radius:var(--pagefind-ui-border-radius)}.pagefind-ui__drawer.svelte-e9gkc3{gap:calc(60px * var(--pagefind-ui-scale));display:flex;flex-direction:row;flex-wrap:wrap}.pagefind-ui__results-area.svelte-e9gkc3{min-width:min(calc(400px * var(--pagefind-ui-scale)),100%);flex:1000;margin-top:calc(20px * var(--pagefind-ui-scale))}.pagefind-ui__results.svelte-e9gkc3{padding:0}.pagefind-ui__message.svelte-e9gkc3{box-sizing:content-box;font-size:calc(16px * var(--pagefind-ui-scale));height:calc(24px * var(--pagefind-ui-scale));padding:calc(20px * var(--pagefind-ui-scale)) 0;display:flex;align-items:center;font-weight:700;margin-top:0}.pagefind-ui__button.svelte-e9gkc3{margin-top:calc(40px * var(--pagefind-ui-scale));border:var(--pagefind-ui-border-width) solid var(--pagefind-ui-border);border-radius:var(--pagefind-ui-border-radius);height:calc(48px * var(--pagefind-ui-scale));padding:0 calc(12px * var(--pagefind-ui-scale));font-size:calc(16px * var(--pagefind-ui-scale));color:var(--pagefind-ui-primary);background:var(--pagefind-ui-background);width:100%;text-align:center;font-weight:700;cursor:pointer}.pagefind-ui__button.svelte-e9gkc3:hover{border-color:var(--pagefind-ui-primary);color:var(--pagefind-ui-primary);background:var(--pagefind-ui-background)} diff --git a/dist/pagefind/pagefind-ui.js b/dist/pagefind/pagefind-ui.js new file mode 100644 index 0000000..44c2d5d --- /dev/null +++ b/dist/pagefind/pagefind-ui.js @@ -0,0 +1,2 @@ +(()=>{var Ur=Object.defineProperty;var A=(n,e)=>{for(var t in e)Ur(n,t,{get:e[t],enumerable:!0})};function U(){}function bt(n){return n()}function yn(){return Object.create(null)}function K(n){n.forEach(bt)}function at(n){return typeof n=="function"}function G(n,e){return n!=n?e==e:n!==e||n&&typeof n=="object"||typeof n=="function"}var lt;function ie(n,e){return lt||(lt=document.createElement("a")),lt.href=e,n===lt.href}function vn(n){return Object.keys(n).length===0}var Hn=typeof window<"u"?window:typeof globalThis<"u"?globalThis:global,de=class{constructor(e){this.options=e,this._listeners="WeakMap"in Hn?new WeakMap:void 0}observe(e,t){return this._listeners.set(e,t),this._getObserver().observe(e,this.options),()=>{this._listeners.delete(e),this._observer.unobserve(e)}}_getObserver(){var e;return(e=this._observer)!==null&&e!==void 0?e:this._observer=new ResizeObserver(t=>{var r;for(let s of t)de.entries.set(s.target,s),(r=this._listeners.get(s.target))===null||r===void 0||r(s)})}};de.entries="WeakMap"in Hn?new WeakMap:void 0;var wn=!1;function Dr(){wn=!0}function Ir(){wn=!1}function R(n,e){n.appendChild(e)}function S(n,e,t){n.insertBefore(e,t||null)}function k(n){n.parentNode&&n.parentNode.removeChild(n)}function Q(n,e){for(let t=0;tn.removeEventListener(e,t,r)}function m(n,e,t){t==null?n.removeAttribute(e):n.getAttribute(e)!==t&&n.setAttribute(e,t)}function Lr(n){return Array.from(n.childNodes)}function z(n,e){e=""+e,n.data!==e&&(n.data=e)}function Tt(n,e){n.value=e??""}function B(n,e,t){n.classList[t?"add":"remove"](e)}var ot=class{constructor(e=!1){this.is_svg=!1,this.is_svg=e,this.e=this.n=null}c(e){this.h(e)}m(e,t,r=null){this.e||(this.is_svg?this.e=Pr(t.nodeName):this.e=C(t.nodeType===11?"TEMPLATE":t.nodeName),this.t=t.tagName!=="TEMPLATE"?t:t.content,this.c(e)),this.i(r)}h(e){this.e.innerHTML=e,this.n=Array.from(this.e.nodeName==="TEMPLATE"?this.e.content.childNodes:this.e.childNodes)}i(e){for(let t=0;tn.indexOf(r)===-1?e.push(r):t.push(r)),t.forEach(r=>r()),se=e}var it=new Set,ee;function ae(){ee={r:0,c:[],p:ee}}function oe(){ee.r||K(ee.c),ee=ee.p}function D(n,e){n&&n.i&&(it.delete(n),n.i(e))}function P(n,e,t,r){if(n&&n.o){if(it.has(n))return;it.add(n),ee.c.push(()=>{it.delete(n),r&&(t&&n.d(1),r())}),n.o(e)}else r&&r()}function On(n,e){P(n,1,1,()=>{e.delete(n.key)})}function jn(n,e,t,r,s,l,i,a,o,f,c,d){let p=n.length,h=l.length,u=p,_={};for(;u--;)_[n[u].key]=u;let E=[],b=new Map,T=new Map,M=[];for(u=h;u--;){let H=d(s,l,u),F=t(H),O=i.get(F);O?r&&M.push(()=>O.p(H,e)):(O=f(F,H),O.c()),b.set(F,E[u]=O),F in _&&T.set(F,Math.abs(u-_[F]))}let y=new Set,X=new Set;function V(H){D(H,1),H.m(a,c),i.set(H.key,H),c=H.first,h--}for(;p&&h;){let H=E[h-1],F=n[p-1],O=H.key,W=F.key;H===F?(c=H.first,p--,h--):b.has(W)?!i.has(O)||y.has(O)?V(H):X.has(W)?p--:T.get(O)>T.get(W)?(X.add(O),V(H)):(y.add(W),p--):(o(F,i),p--)}for(;p--;){let H=n[p];b.has(H.key)||o(H,i)}for(;h;)V(E[h-1]);return K(M),E}var Kr=["allowfullscreen","allowpaymentrequest","async","autofocus","autoplay","checked","controls","default","defer","disabled","formnovalidate","hidden","inert","ismap","loop","multiple","muted","nomodule","novalidate","open","playsinline","readonly","required","reversed","selected"],Eo=new Set([...Kr]);function Un(n,e,t){let r=n.$$.props[e];r!==void 0&&(n.$$.bound[r]=t,t(n.$$.ctx[r]))}function ut(n){n&&n.c()}function me(n,e,t,r){let{fragment:s,after_update:l}=n.$$;s&&s.m(e,t),r||Rt(()=>{let i=n.$$.on_mount.map(bt).filter(at);n.$$.on_destroy?n.$$.on_destroy.push(...i):K(i),n.$$.on_mount=[]}),l.forEach(Rt)}function ue(n,e){let t=n.$$;t.fragment!==null&&(Wr(t.after_update),K(t.on_destroy),t.fragment&&t.fragment.d(e),t.on_destroy=t.fragment=null,t.ctx=[])}function Gr(n,e){n.$$.dirty[0]===-1&&(re.push(n),Br(),n.$$.dirty.fill(0)),n.$$.dirty[e/31|0]|=1<{let u=h.length?h[0]:p;return f.ctx&&s(f.ctx[d],f.ctx[d]=u)&&(!f.skip_bound&&f.bound[d]&&f.bound[d](u),c&&Gr(n,d)),p}):[],f.update(),c=!0,K(f.before_update),f.fragment=r?r(f.ctx):!1,e.target){if(e.hydrate){Dr();let d=Lr(e.target);f.fragment&&f.fragment.l(d),d.forEach(k)}else f.fragment&&f.fragment.c();e.intro&&D(n.$$.fragment),me(n,e.target,e.anchor,e.customElement),Ir(),zn()}fe(o)}var Jr;typeof HTMLElement=="function"&&(Jr=class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"})}connectedCallback(){let{on_mount:n}=this.$$;this.$$.on_disconnect=n.map(bt).filter(at);for(let e in this.$$.slotted)this.appendChild(this.$$.slotted[e])}attributeChangedCallback(n,e,t){this[n]=t}disconnectedCallback(){K(this.$$.on_disconnect)}$destroy(){ue(this,1),this.$destroy=U}$on(n,e){if(!at(e))return U;let t=this.$$.callbacks[n]||(this.$$.callbacks[n]=[]);return t.push(e),()=>{let r=t.indexOf(e);r!==-1&&t.splice(r,1)}}$set(n){this.$$set&&!vn(n)&&(this.$$.skip_bound=!0,this.$$set(n),this.$$.skip_bound=!1)}});var q=class{$destroy(){ue(this,1),this.$destroy=U}$on(e,t){if(!at(t))return U;let r=this.$$.callbacks[e]||(this.$$.callbacks[e]=[]);return r.push(t),()=>{let s=r.indexOf(t);s!==-1&&r.splice(s,1)}}$set(e){this.$$set&&!vn(e)&&(this.$$.skip_bound=!0,this.$$set(e),this.$$.skip_bound=!1)}};function I(n){let e=typeof n=="string"?n.charCodeAt(0):n;return e>=97&&e<=122||e>=65&&e<=90}function $(n){let e=typeof n=="string"?n.charCodeAt(0):n;return e>=48&&e<=57}function Z(n){return I(n)||$(n)}var Dn=["art-lojban","cel-gaulish","no-bok","no-nyn","zh-guoyu","zh-hakka","zh-min","zh-min-nan","zh-xiang"];var St={"en-gb-oed":"en-GB-oxendict","i-ami":"ami","i-bnn":"bnn","i-default":null,"i-enochian":null,"i-hak":"hak","i-klingon":"tlh","i-lux":"lb","i-mingo":null,"i-navajo":"nv","i-pwn":"pwn","i-tao":"tao","i-tay":"tay","i-tsu":"tsu","sgn-be-fr":"sfb","sgn-be-nl":"vgt","sgn-ch-de":"sgg","art-lojban":"jbo","cel-gaulish":null,"no-bok":"nb","no-nyn":"nn","zh-guoyu":"cmn","zh-hakka":"hak","zh-min":null,"zh-min-nan":"nan","zh-xiang":"hsn"};var Yr={}.hasOwnProperty;function ct(n,e={}){let t=In(),r=String(n),s=r.toLowerCase(),l=0;if(n==null)throw new Error("Expected string, got `"+n+"`");if(Yr.call(St,s)){let a=St[s];return(e.normalize===void 0||e.normalize===null||e.normalize)&&typeof a=="string"?ct(a):(t[Dn.includes(s)?"regular":"irregular"]=r,t)}for(;I(s.charCodeAt(l))&&l<9;)l++;if(l>1&&l<9){if(t.language=r.slice(0,l),l<4){let a=0;for(;s.charCodeAt(l)===45&&I(s.charCodeAt(l+1))&&I(s.charCodeAt(l+2))&&I(s.charCodeAt(l+3))&&!I(s.charCodeAt(l+4));){if(a>2)return i(l,3,"Too many extended language subtags, expected at most 3 subtags");t.extendedLanguageSubtags.push(r.slice(l+1,l+4)),l+=4,a++}}for(s.charCodeAt(l)===45&&I(s.charCodeAt(l+1))&&I(s.charCodeAt(l+2))&&I(s.charCodeAt(l+3))&&I(s.charCodeAt(l+4))&&!I(s.charCodeAt(l+5))&&(t.script=r.slice(l+1,l+5),l+=5),s.charCodeAt(l)===45&&(I(s.charCodeAt(l+1))&&I(s.charCodeAt(l+2))&&!I(s.charCodeAt(l+3))?(t.region=r.slice(l+1,l+3),l+=3):$(s.charCodeAt(l+1))&&$(s.charCodeAt(l+2))&&$(s.charCodeAt(l+3))&&!$(s.charCodeAt(l+4))&&(t.region=r.slice(l+1,l+4),l+=4));s.charCodeAt(l)===45;){let a=l+1,o=a;for(;Z(s.charCodeAt(o));){if(o-a>7)return i(o,1,"Too long variant, expected at most 8 characters");o++}if(o-a>4||o-a>3&&$(s.charCodeAt(a)))t.variants.push(r.slice(a,o)),l=o;else break}for(;s.charCodeAt(l)===45&&!(s.charCodeAt(l+1)===120||!Z(s.charCodeAt(l+1))||s.charCodeAt(l+2)!==45||!Z(s.charCodeAt(l+3)));){let a=l+2,o=0;for(;s.charCodeAt(a)===45&&Z(s.charCodeAt(a+1))&&Z(s.charCodeAt(a+2));){let f=a+1;for(a=f+2,o++;Z(s.charCodeAt(a));){if(a-f>7)return i(a,2,"Too long extension, expected at most 8 characters");a++}}if(!o)return i(a,4,"Empty extension, extensions must have at least 2 characters of content");t.extensions.push({singleton:r.charAt(l+1),extensions:r.slice(l+3,a).split("-")}),l=a}}else l=0;if(l===0&&s.charCodeAt(l)===120||s.charCodeAt(l)===45&&s.charCodeAt(l+1)===120){l=l?l+2:1;let a=l;for(;s.charCodeAt(a)===45&&Z(s.charCodeAt(a+1));){let o=l+1;for(a=o;Z(s.charCodeAt(a));){if(a-o>7)return i(a,5,"Too long private-use area, expected at most 8 characters");a++}t.privateuse.push(r.slice(l+1,a)),l=a}}if(l!==r.length)return i(l,6,"Found superfluous content after tag");return t;function i(a,o,f){return e.warning&&e.warning(f,o,a),e.forgiving?t:In()}}function In(){return{language:null,extendedLanguageSubtags:[],script:null,region:null,variants:[],extensions:[],privateuse:[],irregular:null,regular:null}}function Pn(n,e,t){let r=n.slice();return r[8]=e[t][0],r[9]=e[t][1],r}function Zr(n){let e,t,r,s,l,i=n[0]&&Ln(n);return{c(){i&&i.c(),e=v(),t=C("div"),r=C("p"),r.textContent=`${n[3](30)}`,s=v(),l=C("p"),l.textContent=`${n[3](40)}`,m(r,"class","pagefind-ui__result-title pagefind-ui__loading svelte-j9e30"),m(l,"class","pagefind-ui__result-excerpt pagefind-ui__loading svelte-j9e30"),m(t,"class","pagefind-ui__result-inner svelte-j9e30")},m(a,o){i&&i.m(a,o),S(a,e,o),S(a,t,o),R(t,r),R(t,s),R(t,l)},p(a,o){a[0]?i||(i=Ln(a),i.c(),i.m(e.parentNode,e)):i&&(i.d(1),i=null)},d(a){i&&i.d(a),a&&k(e),a&&k(t)}}}function Xr(n){let e,t,r,s,l=n[1].meta?.title+"",i,a,o,f,c=n[1].excerpt+"",d,p=n[0]&&qn(n),h=n[2].length&&Vn(n);return{c(){p&&p.c(),e=v(),t=C("div"),r=C("p"),s=C("a"),i=w(l),o=v(),f=C("p"),d=v(),h&&h.c(),m(s,"class","pagefind-ui__result-link svelte-j9e30"),m(s,"href",a=n[1].meta?.url||n[1].url),m(r,"class","pagefind-ui__result-title svelte-j9e30"),m(f,"class","pagefind-ui__result-excerpt svelte-j9e30"),m(t,"class","pagefind-ui__result-inner svelte-j9e30")},m(u,_){p&&p.m(u,_),S(u,e,_),S(u,t,_),R(t,r),R(r,s),R(s,i),R(t,o),R(t,f),f.innerHTML=c,R(t,d),h&&h.m(t,null)},p(u,_){u[0]?p?p.p(u,_):(p=qn(u),p.c(),p.m(e.parentNode,e)):p&&(p.d(1),p=null),_&2&&l!==(l=u[1].meta?.title+"")&&z(i,l),_&2&&a!==(a=u[1].meta?.url||u[1].url)&&m(s,"href",a),_&2&&c!==(c=u[1].excerpt+"")&&(f.innerHTML=c),u[2].length?h?h.p(u,_):(h=Vn(u),h.c(),h.m(t,null)):h&&(h.d(1),h=null)},d(u){p&&p.d(u),u&&k(e),u&&k(t),h&&h.d()}}}function Ln(n){let e;return{c(){e=C("div"),m(e,"class","pagefind-ui__result-thumb pagefind-ui__loading svelte-j9e30")},m(t,r){S(t,e,r)},d(t){t&&k(e)}}}function qn(n){let e,t=n[1].meta.image&&Bn(n);return{c(){e=C("div"),t&&t.c(),m(e,"class","pagefind-ui__result-thumb svelte-j9e30")},m(r,s){S(r,e,s),t&&t.m(e,null)},p(r,s){r[1].meta.image?t?t.p(r,s):(t=Bn(r),t.c(),t.m(e,null)):t&&(t.d(1),t=null)},d(r){r&&k(e),t&&t.d()}}}function Bn(n){let e,t,r;return{c(){e=C("img"),m(e,"class","pagefind-ui__result-image svelte-j9e30"),ie(e.src,t=n[1].meta?.image)||m(e,"src",t),m(e,"alt",r=n[1].meta?.image_alt||n[1].meta?.title)},m(s,l){S(s,e,l)},p(s,l){l&2&&!ie(e.src,t=s[1].meta?.image)&&m(e,"src",t),l&2&&r!==(r=s[1].meta?.image_alt||s[1].meta?.title)&&m(e,"alt",r)},d(s){s&&k(e)}}}function Vn(n){let e,t=n[2],r=[];for(let s=0;sn.toLocaleUpperCase();function xr(n,e,t){let{show_images:r=!0}=e,{process_result:s=null}=e,{result:l={data:async()=>{}}}=e,i=["title","image","image_alt","url"],a,o=[],f=async d=>{t(1,a=await d.data()),t(1,a=s?.(a)??a),t(2,o=Object.entries(a.meta).filter(([p])=>!i.includes(p)))},c=(d=30)=>". ".repeat(Math.floor(10+Math.random()*d));return n.$$set=d=>{"show_images"in d&&t(0,r=d.show_images),"process_result"in d&&t(4,s=d.process_result),"result"in d&&t(5,l=d.result)},n.$$.update=()=>{if(n.$$.dirty&32)e:f(l)},[r,a,o,c,s,l]}var Mt=class extends q{constructor(e){super(),Y(this,e,xr,Qr,G,{show_images:0,process_result:4,result:5})}},Gn=Mt;function Jn(n,e,t){let r=n.slice();return r[11]=e[t][0],r[12]=e[t][1],r}function Yn(n,e,t){let r=n.slice();return r[15]=e[t],r}function $r(n){let e,t,r,s,l,i=n[0]&&Zn(n);return{c(){i&&i.c(),e=v(),t=C("div"),r=C("p"),r.textContent=`${n[5](30)}`,s=v(),l=C("p"),l.textContent=`${n[5](40)}`,m(r,"class","pagefind-ui__result-title pagefind-ui__loading svelte-4xnkmf"),m(l,"class","pagefind-ui__result-excerpt pagefind-ui__loading svelte-4xnkmf"),m(t,"class","pagefind-ui__result-inner svelte-4xnkmf")},m(a,o){i&&i.m(a,o),S(a,e,o),S(a,t,o),R(t,r),R(t,s),R(t,l)},p(a,o){a[0]?i||(i=Zn(a),i.c(),i.m(e.parentNode,e)):i&&(i.d(1),i=null)},d(a){i&&i.d(a),a&&k(e),a&&k(t)}}}function es(n){let e,t,r,s,l=n[1].meta?.title+"",i,a,o,f,c,d=n[0]&&Xn(n),p=n[4]&&xn(n),h=n[3],u=[];for(let E=0;En.toLocaleUpperCase();function ns(n,e,t){let{show_images:r=!0}=e,{process_result:s=null}=e,{result:l={data:async()=>{}}}=e,i=["title","image","image_alt","url"],a,o=[],f=[],c=!1,d=(u,_)=>{if(u.length<=_)return u;let E=[...u].sort((b,T)=>T.locations.length-b.locations.length).slice(0,3).map(b=>b.url);return u.filter(b=>E.includes(b.url))},p=async u=>{t(1,a=await u.data()),t(1,a=s?.(a)??a),t(2,o=Object.entries(a.meta).filter(([_])=>!i.includes(_))),Array.isArray(a.sub_results)&&(t(4,c=a.sub_results?.[0]?.url===(a.meta?.url||a.url)),c?t(3,f=d(a.sub_results.slice(1),3)):t(3,f=d([...a.sub_results],3)))},h=(u=30)=>". ".repeat(Math.floor(10+Math.random()*u));return n.$$set=u=>{"show_images"in u&&t(0,r=u.show_images),"process_result"in u&&t(6,s=u.process_result),"result"in u&&t(7,l=u.result)},n.$$.update=()=>{if(n.$$.dirty&128)e:p(l)},[r,a,o,f,c,h,s,l]}var At=class extends q{constructor(e){super(),Y(this,e,ns,ts,G,{show_images:0,process_result:6,result:7})}},rr=At;function sr(n,e,t){let r=n.slice();return r[10]=e[t][0],r[11]=e[t][1],r[12]=e,r[13]=t,r}function lr(n,e,t){let r=n.slice();return r[14]=e[t][0],r[15]=e[t][1],r[16]=e,r[17]=t,r}function ir(n){let e,t,r=n[4]("filters_label",n[5],n[6])+"",s,l,i=Object.entries(n[1]),a=[];for(let o=0;on.toLocaleUpperCase(),_r=n=>n.toLowerCase();function ss(n,e,t){let{available_filters:r=null}=e,{show_empty_filters:s=!0}=e,{open_filters:l=[]}=e,{translate:i=()=>""}=e,{automatic_translations:a={}}=e,{translations:o={}}=e,{selected_filters:f={}}=e,c=!1,d=!1;function p(h,u){f[`${h}:${u}`]=this.checked,t(0,f)}return n.$$set=h=>{"available_filters"in h&&t(1,r=h.available_filters),"show_empty_filters"in h&&t(2,s=h.show_empty_filters),"open_filters"in h&&t(3,l=h.open_filters),"translate"in h&&t(4,i=h.translate),"automatic_translations"in h&&t(5,a=h.automatic_translations),"translations"in h&&t(6,o=h.translations),"selected_filters"in h&&t(0,f=h.selected_filters)},n.$$.update=()=>{if(n.$$.dirty&258){e:if(r&&!c){t(8,c=!0);let h=Object.entries(r||{});h.length===1&&Object.entries(h[0][1])?.length<=6&&t(7,d=!0)}}},[f,r,s,l,i,a,o,d,c,p]}var yt=class extends q{constructor(e){super(),Y(this,e,ss,rs,G,{available_filters:1,show_empty_filters:2,open_filters:3,translate:4,automatic_translations:5,translations:6,selected_filters:0})}},fr=yt;var vt={};A(vt,{comments:()=>is,default:()=>us,direction:()=>as,strings:()=>os,thanks_to:()=>ls});var ls="Jan Claasen ",is="",as="ltr",os={placeholder:"Soek",clear_search:"Opruim",load_more:"Laai nog resultate",search_label:"Soek hierdie webwerf",filters_label:"Filters",zero_results:"Geen resultate vir [SEARCH_TERM]",many_results:"[COUNT] resultate vir [SEARCH_TERM]",one_result:"[COUNT] resultate vir [SEARCH_TERM]",alt_search:"Geen resultate vir [SEARCH_TERM]. Toon resultate vir [DIFFERENT_TERM] in plaas daarvan",search_suggestion:"Geen resultate vir [SEARCH_TERM]. Probeer eerder een van die volgende terme:",searching:"Soek vir [SEARCH_TERM]"},us={thanks_to:ls,comments:is,direction:as,strings:os};var Ht={};A(Ht,{comments:()=>_s,default:()=>hs,direction:()=>fs,strings:()=>ds,thanks_to:()=>cs});var cs="Jermanuts",_s="",fs="rtl",ds={placeholder:"\u0628\u062D\u062B",clear_search:"\u0627\u0645\u0633\u062D",load_more:"\u062D\u0645\u0651\u0650\u0644 \u0627\u0644\u0645\u0632\u064A\u062F \u0645\u0646 \u0627\u0644\u0646\u062A\u0627\u0626\u062C",search_label:"\u0627\u0628\u062D\u062B \u0641\u064A \u0647\u0630\u0627 \u0627\u0644\u0645\u0648\u0642\u0639",filters_label:"\u062A\u0635\u0641\u064A\u0627\u062A",zero_results:"\u0644\u0627 \u062A\u0648\u062C\u062F \u0646\u062A\u0627\u0626\u062C \u0644 [SEARCH_TERM]",many_results:"[COUNT] \u0646\u062A\u0627\u0626\u062C \u0644 [SEARCH_TERM]",one_result:"[COUNT] \u0646\u062A\u064A\u062C\u0629 \u0644 [SEARCH_TERM]",alt_search:"\u0644\u0627 \u062A\u0648\u062C\u062F \u0646\u062A\u0627\u0626\u062C \u0644 [SEARCH_TERM]. \u064A\u0639\u0631\u0636 \u0627\u0644\u0646\u062A\u0627\u0626\u062C \u0644 [DIFFERENT_TERM] \u0628\u062F\u0644\u0627\u064B \u0645\u0646 \u0630\u0644\u0643",search_suggestion:"\u0644\u0627 \u062A\u0648\u062C\u062F \u0646\u062A\u0627\u0626\u062C \u0644 [SEARCH_TERM]. \u062C\u0631\u0628 \u0623\u062D\u062F \u0639\u0645\u0644\u064A\u0627\u062A \u0627\u0644\u0628\u062D\u062B \u0627\u0644\u062A\u0627\u0644\u064A\u0629:",searching:"\u064A\u0628\u062D\u062B \u0639\u0646 [SEARCH_TERM]..."},hs={thanks_to:cs,comments:_s,direction:fs,strings:ds};var wt={};A(wt,{comments:()=>ps,default:()=>Rs,direction:()=>gs,strings:()=>Es,thanks_to:()=>ms});var ms="Maruf Alom ",ps="",gs="ltr",Es={placeholder:"\u0985\u09A8\u09C1\u09B8\u09A8\u09CD\u09A7\u09BE\u09A8 \u0995\u09B0\u09C1\u09A8",clear_search:"\u09AE\u09C1\u099B\u09C7 \u09AB\u09C7\u09B2\u09C1\u09A8",load_more:"\u0986\u09B0\u09CB \u09AB\u09B2\u09BE\u09AB\u09B2 \u09A6\u09C7\u0996\u09C1\u09A8",search_label:"\u098F\u0987 \u0993\u09DF\u09C7\u09AC\u09B8\u09BE\u0987\u099F\u09C7 \u0985\u09A8\u09C1\u09B8\u09A8\u09CD\u09A7\u09BE\u09A8 \u0995\u09B0\u09C1\u09A8",filters_label:"\u09AB\u09BF\u09B2\u09CD\u099F\u09BE\u09B0",zero_results:"[SEARCH_TERM] \u098F\u09B0 \u099C\u09A8\u09CD\u09AF \u0995\u09BF\u099B\u09C1 \u0996\u09C1\u0981\u099C\u09C7 \u09AA\u09BE\u0993\u09DF\u09BE \u09AF\u09BE\u09DF\u09A8\u09BF",many_results:"[COUNT]-\u099F\u09BF \u09AB\u09B2\u09BE\u09AB\u09B2 \u09AA\u09BE\u0993\u09DF\u09BE \u0997\u09BF\u09DF\u09C7\u099B\u09C7 [SEARCH_TERM] \u098F\u09B0 \u099C\u09A8\u09CD\u09AF",one_result:"[COUNT]-\u099F\u09BF \u09AB\u09B2\u09BE\u09AB\u09B2 \u09AA\u09BE\u0993\u09DF\u09BE \u0997\u09BF\u09DF\u09C7\u099B\u09C7 [SEARCH_TERM] \u098F\u09B0 \u099C\u09A8\u09CD\u09AF",alt_search:"\u0995\u09CB\u09A8 \u0995\u09BF\u099B\u09C1 \u0996\u09C1\u0981\u099C\u09C7 \u09AA\u09BE\u0993\u09DF\u09BE \u09AF\u09BE\u09DF\u09A8\u09BF [SEARCH_TERM] \u098F\u09B0 \u099C\u09A8\u09CD\u09AF. \u09AA\u09B0\u09BF\u09AC\u09B0\u09CD\u09A4\u09C7 [DIFFERENT_TERM] \u098F\u09B0 \u099C\u09A8\u09CD\u09AF \u09A6\u09C7\u0996\u09BE\u09A8\u09CB \u09B9\u099A\u09CD\u099B\u09C7",search_suggestion:"\u0995\u09CB\u09A8 \u0995\u09BF\u099B\u09C1 \u0996\u09C1\u0981\u099C\u09C7 \u09AA\u09BE\u0993\u09DF\u09BE \u09AF\u09BE\u09DF\u09A8\u09BF [SEARCH_TERM] \u098F\u09B0 \u09AC\u09BF\u09B7\u09DF\u09C7. \u09A8\u09BF\u09A8\u09CD\u09AE\u09C7\u09B0 \u09AC\u09BF\u09B7\u09DF\u09AC\u09B8\u09CD\u09A4\u09C1 \u0996\u09C1\u0981\u099C\u09C7 \u09A6\u09C7\u0996\u09C1\u09A8:",searching:"\u0985\u09A8\u09C1\u09B8\u09A8\u09CD\u09A7\u09BE\u09A8 \u099A\u09B2\u099B\u09C7 [SEARCH_TERM]..."},Rs={thanks_to:ms,comments:ps,direction:gs,strings:Es};var Ft={};A(Ft,{comments:()=>Ts,default:()=>Ss,direction:()=>Cs,strings:()=>ks,thanks_to:()=>bs});var bs="Pablo Villaverde ",Ts="",Cs="ltr",ks={placeholder:"Cerca",clear_search:"Netejar",load_more:"Veure m\xE9s resultats",search_label:"Cerca en aquest lloc",filters_label:"Filtres",zero_results:"No es van trobar resultats per [SEARCH_TERM]",many_results:"[COUNT] resultats trobats per [SEARCH_TERM]",one_result:"[COUNT] resultat trobat per [SEARCH_TERM]",alt_search:"No es van trobar resultats per [SEARCH_TERM]. Mostrant al seu lloc resultats per [DIFFERENT_TERM]",search_suggestion:"No es van trobar resultats per [SEARCH_TERM]. Proveu una de les cerques seg\xFCents:",searching:"Cercant [SEARCH_TERM]..."},Ss={thanks_to:bs,comments:Ts,direction:Cs,strings:ks};var Nt={};A(Nt,{comments:()=>As,default:()=>Hs,direction:()=>ys,strings:()=>vs,thanks_to:()=>Ms});var Ms="Dalibor Hon ",As="",ys="ltr",vs={placeholder:"Hledat",clear_search:"Smazat",load_more:"Na\u010D\xEDst dal\u0161\xED v\xFDsledky",search_label:"Prohledat tuto str\xE1nku",filters_label:"Filtry",zero_results:"\u017D\xE1dn\xE9 v\xFDsledky pro [SEARCH_TERM]",many_results:"[COUNT] v\xFDsledk\u016F pro [SEARCH_TERM]",one_result:"[COUNT] v\xFDsledek pro [SEARCH_TERM]",alt_search:"\u017D\xE1dn\xE9 v\xFDsledky pro [SEARCH_TERM]. Zobrazuj\xED se v\xFDsledky pro [DIFFERENT_TERM]",search_suggestion:"\u017D\xE1dn\xE9 v\xFDsledky pro [SEARCH_TERM]. Souvisej\xEDc\xED v\xFDsledky hled\xE1n\xED:",searching:"Hled\xE1m [SEARCH_TERM]..."},Hs={thanks_to:Ms,comments:As,direction:ys,strings:vs};var zt={};A(zt,{comments:()=>Fs,default:()=>Os,direction:()=>Ns,strings:()=>zs,thanks_to:()=>ws});var ws="Jonas Smedegaard ",Fs="",Ns="ltr",zs={placeholder:"S\xF8g",clear_search:"Nulstil",load_more:"Indl\xE6s flere resultater",search_label:"S\xF8g p\xE5 dette website",filters_label:"Filtre",zero_results:"Ingen resultater for [SEARCH_TERM]",many_results:"[COUNT] resultater for [SEARCH_TERM]",one_result:"[COUNT] resultat for [SEARCH_TERM]",alt_search:"Ingen resultater for [SEARCH_TERM]. Viser resultater for [DIFFERENT_TERM] i stedet",search_suggestion:"Ingen resultater for [SEARCH_TERM]. Pr\xF8v et af disse s\xF8geord i stedet:",searching:"S\xF8ger efter [SEARCH_TERM]..."},Os={thanks_to:ws,comments:Fs,direction:Ns,strings:zs};var Ot={};A(Ot,{comments:()=>Us,default:()=>Ps,direction:()=>Ds,strings:()=>Is,thanks_to:()=>js});var js="Jan Claasen ",Us="",Ds="ltr",Is={placeholder:"Suche",clear_search:"L\xF6schen",load_more:"Mehr Ergebnisse laden",search_label:"Suche diese Seite",filters_label:"Filter",zero_results:"Keine Ergebnisse f\xFCr [SEARCH_TERM]",many_results:"[COUNT] Ergebnisse f\xFCr [SEARCH_TERM]",one_result:"[COUNT] Ergebnis f\xFCr [SEARCH_TERM]",alt_search:"Keine Ergebnisse f\xFCr [SEARCH_TERM]. Stattdessen werden Ergebnisse f\xFCr [DIFFERENT_TERM] angezeigt",search_suggestion:"Keine Ergebnisse f\xFCr [SEARCH_TERM]. Versuchen Sie eine der folgenden Suchen:",searching:"Suche f\xFCr [SEARCH_TERM]"},Ps={thanks_to:js,comments:Us,direction:Ds,strings:Is};var jt={};A(jt,{comments:()=>qs,default:()=>Ws,direction:()=>Bs,strings:()=>Vs,thanks_to:()=>Ls});var Ls="Liam Bigelow ",qs="",Bs="ltr",Vs={placeholder:"Search",clear_search:"Clear",load_more:"Load more results",search_label:"Search this site",filters_label:"Filters",zero_results:"No results for [SEARCH_TERM]",many_results:"[COUNT] results for [SEARCH_TERM]",one_result:"[COUNT] result for [SEARCH_TERM]",alt_search:"No results for [SEARCH_TERM]. Showing results for [DIFFERENT_TERM] instead",search_suggestion:"No results for [SEARCH_TERM]. Try one of the following searches:",searching:"Searching for [SEARCH_TERM]..."},Ws={thanks_to:Ls,comments:qs,direction:Bs,strings:Vs};var Ut={};A(Ut,{comments:()=>Gs,default:()=>Zs,direction:()=>Js,strings:()=>Ys,thanks_to:()=>Ks});var Ks="Pablo Villaverde ",Gs="",Js="ltr",Ys={placeholder:"Buscar",clear_search:"Limpiar",load_more:"Ver m\xE1s resultados",search_label:"Buscar en este sitio",filters_label:"Filtros",zero_results:"No se encontraron resultados para [SEARCH_TERM]",many_results:"[COUNT] resultados encontrados para [SEARCH_TERM]",one_result:"[COUNT] resultado encontrado para [SEARCH_TERM]",alt_search:"No se encontraron resultados para [SEARCH_TERM]. Mostrando en su lugar resultados para [DIFFERENT_TERM]",search_suggestion:"No se encontraron resultados para [SEARCH_TERM]. Prueba una de las siguientes b\xFAsquedas:",searching:"Buscando [SEARCH_TERM]..."},Zs={thanks_to:Ks,comments:Gs,direction:Js,strings:Ys};var Dt={};A(Dt,{comments:()=>Qs,default:()=>el,direction:()=>xs,strings:()=>$s,thanks_to:()=>Xs});var Xs="Mikel Larreategi ",Qs="",xs="ltr",$s={placeholder:"Bilatu",clear_search:"Garbitu",load_more:"Kargatu emaitza gehiagi",search_label:"Bilatu",filters_label:"Iragazkiak",zero_results:"Ez dago emaitzarik [SEARCH_TERM] bilaketarentzat",many_results:"[COUNT] emaitza [SEARCH_TERM] bilaketarentzat",one_result:"Emaitza bat [COUNT] [SEARCH_TERM] bilaketarentzat",alt_search:"Ez dago emaitzarik [SEARCH_TERM] bilaketarentzat. [DIFFERENT_TERM] bilaketaren emaitzak erakusten",search_suggestion:"Ez dago emaitzarik [SEARCH_TERM] bilaketarentzat. Saiatu hauetako beste bateikin:",searching:"[SEARCH_TERM] bilatzen..."},el={thanks_to:Xs,comments:Qs,direction:xs,strings:$s};var It={};A(It,{comments:()=>nl,default:()=>ll,direction:()=>rl,strings:()=>sl,thanks_to:()=>tl});var tl="Ali Khaleqi Yekta ",nl="",rl="rtl",sl={placeholder:"\u062C\u0633\u062A\u062C\u0648",clear_search:"\u067E\u0627\u06A9\u0633\u0627\u0632\u06CC",load_more:"\u0628\u0627\u0631\u06AF\u0630\u0627\u0631\u06CC \u0646\u062A\u0627\u06CC\u062C \u0628\u06CC\u0634\u062A\u0631",search_label:"\u062C\u0633\u062A\u062C\u0648 \u062F\u0631 \u0633\u0627\u06CC\u062A",filters_label:"\u0641\u06CC\u0644\u062A\u0631\u0647\u0627",zero_results:"\u0646\u062A\u06CC\u062C\u0647\u200C\u0627\u06CC \u0628\u0631\u0627\u06CC [SEARCH_TERM] \u06CC\u0627\u0641\u062A \u0646\u0634\u062F",many_results:"[COUNT] \u0646\u062A\u06CC\u062C\u0647 \u0628\u0631\u0627\u06CC [SEARCH_TERM] \u06CC\u0627\u0641\u062A \u0634\u062F",one_result:"[COUNT] \u0646\u062A\u06CC\u062C\u0647 \u0628\u0631\u0627\u06CC [SEARCH_TERM] \u06CC\u0627\u0641\u062A \u0634\u062F",alt_search:"\u0646\u062A\u06CC\u062C\u0647\u200C\u0627\u06CC \u0628\u0631\u0627\u06CC [SEARCH_TERM] \u06CC\u0627\u0641\u062A \u0646\u0634\u062F. \u062F\u0631 \u0639\u0648\u0636 \u0646\u062A\u0627\u06CC\u062C \u0628\u0631\u0627\u06CC [DIFFERENT_TERM] \u0646\u0645\u0627\u06CC\u0634 \u062F\u0627\u062F\u0647 \u0645\u06CC\u200C\u0634\u0648\u062F",search_suggestion:"\u0646\u062A\u06CC\u062C\u0647\u200C\u0627\u06CC \u0628\u0631\u0627\u06CC [SEARCH_TERM] \u06CC\u0627\u0641\u062A \u0646\u0634\u062F. \u06CC\u06A9\u06CC \u0627\u0632 \u062C\u0633\u062A\u062C\u0648\u0647\u0627\u06CC \u0632\u06CC\u0631 \u0631\u0627 \u0627\u0645\u062A\u062D\u0627\u0646 \u06A9\u0646\u06CC\u062F:",searching:"\u062F\u0631 \u062D\u0627\u0644 \u062C\u0633\u062A\u062C\u0648\u06CC [SEARCH_TERM]..."},ll={thanks_to:tl,comments:nl,direction:rl,strings:sl};var Pt={};A(Pt,{comments:()=>al,default:()=>cl,direction:()=>ol,strings:()=>ul,thanks_to:()=>il});var il="Valtteri Laitinen ",al="",ol="ltr",ul={placeholder:"Haku",clear_search:"Tyhjenn\xE4",load_more:"Lataa lis\xE4\xE4 tuloksia",search_label:"Hae t\xE4lt\xE4 sivustolta",filters_label:"Suodattimet",zero_results:"Ei tuloksia haulle [SEARCH_TERM]",many_results:"[COUNT] tulosta haulle [SEARCH_TERM]",one_result:"[COUNT] tulos haulle [SEARCH_TERM]",alt_search:"Ei tuloksia haulle [SEARCH_TERM]. N\xE4ytet\xE4\xE4n tulokset sen sijaan haulle [DIFFERENT_TERM]",search_suggestion:"Ei tuloksia haulle [SEARCH_TERM]. Kokeile jotain seuraavista:",searching:"Haetaan [SEARCH_TERM]..."},cl={thanks_to:il,comments:al,direction:ol,strings:ul};var Lt={};A(Lt,{comments:()=>fl,default:()=>ml,direction:()=>dl,strings:()=>hl,thanks_to:()=>_l});var _l="Nicolas Friedli ",fl="",dl="ltr",hl={placeholder:"Rechercher",clear_search:"Nettoyer",load_more:"Charger plus de r\xE9sultats",search_label:"Recherche sur ce site",filters_label:"Filtres",zero_results:"Pas de r\xE9sultat pour [SEARCH_TERM]",many_results:"[COUNT] r\xE9sultats pour [SEARCH_TERM]",one_result:"[COUNT] r\xE9sultat pour [SEARCH_TERM]",alt_search:"Pas de r\xE9sultat pour [SEARCH_TERM]. Montre les r\xE9sultats pour [DIFFERENT_TERM] \xE0 la place",search_suggestion:"Pas de r\xE9sultat pour [SEARCH_TERM]. Essayer une des recherches suivantes:",searching:"Recherche [SEARCH_TERM]..."},ml={thanks_to:_l,comments:fl,direction:dl,strings:hl};var qt={};A(qt,{comments:()=>gl,default:()=>bl,direction:()=>El,strings:()=>Rl,thanks_to:()=>pl});var pl="Pablo Villaverde ",gl="",El="ltr",Rl={placeholder:"Buscar",clear_search:"Limpar",load_more:"Ver m\xE1is resultados",search_label:"Buscar neste sitio",filters_label:"Filtros",zero_results:"Non se atoparon resultados para [SEARCH_TERM]",many_results:"[COUNT] resultados atopados para [SEARCH_TERM]",one_result:"[COUNT] resultado atopado para [SEARCH_TERM]",alt_search:"Non se atoparon resultados para [SEARCH_TERM]. Amosando no seu lugar resultados para [DIFFERENT_TERM]",search_suggestion:"Non se atoparon resultados para [SEARCH_TERM]. Probe unha das seguintes pesquisas:",searching:"Buscando [SEARCH_TERM]..."},bl={thanks_to:pl,comments:gl,direction:El,strings:Rl};var Bt={};A(Bt,{comments:()=>Cl,default:()=>Ml,direction:()=>kl,strings:()=>Sl,thanks_to:()=>Tl});var Tl="Nir Tamir ",Cl="",kl="rtl",Sl={placeholder:"\u05D7\u05D9\u05E4\u05D5\u05E9",clear_search:"\u05E0\u05D9\u05E7\u05D5\u05D9",load_more:"\u05E2\u05D5\u05D3 \u05EA\u05D5\u05E6\u05D0\u05D5\u05EA",search_label:"\u05D7\u05D9\u05E4\u05D5\u05E9 \u05D1\u05D0\u05EA\u05E8 \u05D6\u05D4",filters_label:"\u05DE\u05E1\u05E0\u05E0\u05D9\u05DD",zero_results:"\u05DC\u05D0 \u05E0\u05DE\u05E6\u05D0\u05D5 \u05EA\u05D5\u05E6\u05D0\u05D5\u05EA \u05E2\u05D1\u05D5\u05E8 [SEARCH_TERM]",many_results:"\u05E0\u05DE\u05E6\u05D0\u05D5 [COUNT] \u05EA\u05D5\u05E6\u05D0\u05D5\u05EA \u05E2\u05D1\u05D5\u05E8 [SEARCH_TERM]",one_result:"\u05E0\u05DE\u05E6\u05D0\u05D4 \u05EA\u05D5\u05E6\u05D0\u05D4 \u05D0\u05D7\u05EA \u05E2\u05D1\u05D5\u05E8 [SEARCH_TERM]",alt_search:"\u05DC\u05D0 \u05E0\u05DE\u05E6\u05D0\u05D5 \u05EA\u05D5\u05E6\u05D0\u05D5\u05EA \u05E2\u05D1\u05D5\u05E8 [SEARCH_TERM]. \u05DE\u05D5\u05E6\u05D2\u05D5\u05EA \u05EA\u05D5\u05E6\u05D0\u05D5\u05EA \u05E2\u05D1\u05D5\u05E8 [DIFFERENT_TERM]",search_suggestion:"\u05DC\u05D0 \u05E0\u05DE\u05E6\u05D0\u05D5 \u05EA\u05D5\u05E6\u05D0\u05D5\u05EA \u05E2\u05D1\u05D5\u05E8 [SEARCH_TERM]. \u05E0\u05E1\u05D5 \u05D0\u05D7\u05D3 \u05DE\u05D4\u05D7\u05D9\u05E4\u05D5\u05E9\u05D9\u05DD \u05D4\u05D1\u05D0\u05D9\u05DD:",searching:"\u05DE\u05D7\u05E4\u05E9 \u05D0\u05EA [SEARCH_TERM]..."},Ml={thanks_to:Tl,comments:Cl,direction:kl,strings:Sl};var Vt={};A(Vt,{comments:()=>yl,default:()=>wl,direction:()=>vl,strings:()=>Hl,thanks_to:()=>Al});var Al="Amit Yadav ",yl="",vl="ltr",Hl={placeholder:"\u0916\u094B\u091C\u0947\u0902",clear_search:"\u0938\u093E\u092B \u0915\u0930\u0947\u0902",load_more:"\u0914\u0930 \u0905\u0927\u093F\u0915 \u092A\u0930\u093F\u0923\u093E\u092E \u0932\u094B\u0921 \u0915\u0930\u0947\u0902",search_label:"\u0907\u0938 \u0938\u093E\u0907\u091F \u092E\u0947\u0902 \u0916\u094B\u091C\u0947\u0902",filters_label:"\u092B\u093C\u093F\u0932\u094D\u091F\u0930",zero_results:"\u0915\u094B\u0908 \u092A\u0930\u093F\u0923\u093E\u092E [SEARCH_TERM] \u0915\u0947 \u0932\u093F\u090F \u0928\u0939\u0940\u0902 \u092E\u093F\u0932\u093E",many_results:"[COUNT] \u092A\u0930\u093F\u0923\u093E\u092E [SEARCH_TERM] \u0915\u0947 \u0932\u093F\u090F \u092E\u093F\u0932\u0947",one_result:"[COUNT] \u092A\u0930\u093F\u0923\u093E\u092E [SEARCH_TERM] \u0915\u0947 \u0932\u093F\u090F \u092E\u093F\u0932\u093E",alt_search:"[SEARCH_TERM] \u0915\u0947 \u0932\u093F\u090F \u0915\u094B\u0908 \u092A\u0930\u093F\u0923\u093E\u092E \u0928\u0939\u0940\u0902 \u092E\u093F\u0932\u093E\u0964 \u0907\u0938\u0915\u0947 \u092C\u091C\u093E\u092F [DIFFERENT_TERM] \u0915\u0947 \u0932\u093F\u090F \u092A\u0930\u093F\u0923\u093E\u092E \u0926\u093F\u0916\u093E \u0930\u0939\u093E \u0939\u0948",search_suggestion:"[SEARCH_TERM] \u0915\u0947 \u0932\u093F\u090F \u0915\u094B\u0908 \u092A\u0930\u093F\u0923\u093E\u092E \u0928\u0939\u0940\u0902 \u092E\u093F\u0932\u093E\u0964 \u0928\u093F\u092E\u094D\u0928\u0932\u093F\u0916\u093F\u0924 \u0916\u094B\u091C\u094B\u0902 \u092E\u0947\u0902 \u0938\u0947 \u0915\u094B\u0908 \u090F\u0915 \u0906\u091C\u093C\u092E\u093E\u090F\u0902:",searching:"[SEARCH_TERM] \u0915\u0940 \u0916\u094B\u091C \u0915\u0940 \u091C\u093E \u0930\u0939\u0940 \u0939\u0948..."},wl={thanks_to:Al,comments:yl,direction:vl,strings:Hl};var Wt={};A(Wt,{comments:()=>Nl,default:()=>jl,direction:()=>zl,strings:()=>Ol,thanks_to:()=>Fl});var Fl="Diomed ",Nl="",zl="ltr",Ol={placeholder:"Tra\u017Ei",clear_search:"O\u010Disti",load_more:"U\u010Ditaj vi\u0161e rezultata",search_label:"Pretra\u017Ei ovu stranicu",filters_label:"Filteri",zero_results:"Nema rezultata za [SEARCH_TERM]",many_results:"[COUNT] rezultata za [SEARCH_TERM]",one_result:"[COUNT] rezultat za [SEARCH_TERM]",alt_search:"Nema rezultata za [SEARCH_TERM]. Prikazujem rezultate za [DIFFERENT_TERM]",search_suggestion:"Nema rezultata za [SEARCH_TERM]. Poku\u0161aj s jednom od ovih pretraga:",searching:"Pretra\u017Eujem [SEARCH_TERM]..."},jl={thanks_to:Fl,comments:Nl,direction:zl,strings:Ol};var Kt={};A(Kt,{comments:()=>Dl,default:()=>Ll,direction:()=>Il,strings:()=>Pl,thanks_to:()=>Ul});var Ul="Adam Laki ",Dl="",Il="ltr",Pl={placeholder:"Keres\xE9s",clear_search:"T\xF6rl\xE9s",load_more:"Tov\xE1bbi tal\xE1latok bet\xF6lt\xE9se",search_label:"Keres\xE9s az oldalon",filters_label:"Sz\u0171r\xE9s",zero_results:"Nincs tal\xE1lat a(z) [SEARCH_TERM] kifejez\xE9sre",many_results:"[COUNT] db tal\xE1lat a(z) [SEARCH_TERM] kifejez\xE9sre",one_result:"[COUNT] db tal\xE1lat a(z) [SEARCH_TERM] kifejez\xE9sre",alt_search:"Nincs tal\xE1lat a(z) [SEARCH_TERM] kifejez\xE9sre. Tal\xE1latok mutat\xE1sa ink\xE1bb a(z) [DIFFERENT_TERM] kifejez\xE9sre",search_suggestion:"Nincs tal\xE1lat a(z) [SEARCH_TERM] kifejez\xE9sre. Pr\xF3b\xE1ld meg a k\xF6vetkez\u0151 keres\xE9sek egyik\xE9t:",searching:"Keres\xE9s a(z) [SEARCH_TERM] kifejez\xE9sre..."},Ll={thanks_to:Ul,comments:Dl,direction:Il,strings:Pl};var Gt={};A(Gt,{comments:()=>Bl,default:()=>Kl,direction:()=>Vl,strings:()=>Wl,thanks_to:()=>ql});var ql="Nixentric",Bl="",Vl="ltr",Wl={placeholder:"Cari",clear_search:"Bersihkan",load_more:"Muat lebih banyak hasil",search_label:"Telusuri situs ini",filters_label:"Filter",zero_results:"[SEARCH_TERM] tidak ditemukan",many_results:"Ditemukan [COUNT] hasil untuk [SEARCH_TERM]",one_result:"Ditemukan [COUNT] hasil untuk [SEARCH_TERM]",alt_search:"[SEARCH_TERM] tidak ditemukan. Menampilkan hasil [DIFFERENT_TERM] sebagai gantinya",search_suggestion:"[SEARCH_TERM] tidak ditemukan. Coba salah satu pencarian berikut ini:",searching:"Mencari [SEARCH_TERM]..."},Kl={thanks_to:ql,comments:Bl,direction:Vl,strings:Wl};var Jt={};A(Jt,{comments:()=>Jl,default:()=>Xl,direction:()=>Yl,strings:()=>Zl,thanks_to:()=>Gl});var Gl="Cosette Bruhns Alonso, Andrew Janco ",Jl="",Yl="ltr",Zl={placeholder:"Cerca",clear_search:"Cancella la cronologia",load_more:"Mostra pi\xF9 risultati",search_label:"Cerca nel sito",filters_label:"Filtri di ricerca",zero_results:"Nessun risultato per [SEARCH_TERM]",many_results:"[COUNT] risultati per [SEARCH_TERM]",one_result:"[COUNT] risultato per [SEARCH_TERM]",alt_search:"Nessun risultato per [SEARCH_TERM]. Mostrando risultati per [DIFFERENT_TERM] come alternativa.",search_suggestion:"Nessun risultato per [SEARCH_TERM]. Prova una delle seguenti ricerche:",searching:"Cercando [SEARCH_TERM]..."},Xl={thanks_to:Gl,comments:Jl,direction:Yl,strings:Zl};var Yt={};A(Yt,{comments:()=>xl,default:()=>ti,direction:()=>$l,strings:()=>ei,thanks_to:()=>Ql});var Ql="Tate",xl="",$l="ltr",ei={placeholder:"\u691C\u7D22",clear_search:"\u30AF\u30EA\u30A2",load_more:"\u6B21\u3092\u8AAD\u307F\u8FBC\u3080",search_label:"\u3053\u306E\u30B5\u30A4\u30C8\u3092\u691C\u7D22",filters_label:"\u30D5\u30A3\u30EB\u30BF",zero_results:"[SEARCH_TERM]\u306E\u691C\u7D22\u306B\u4E00\u81F4\u3059\u308B\u60C5\u5831\u306F\u3042\u308A\u307E\u305B\u3093\u3067\u3057\u305F",many_results:"[SEARCH_TERM]\u306E[COUNT]\u4EF6\u306E\u691C\u7D22\u7D50\u679C",one_result:"[SEARCH_TERM]\u306E[COUNT]\u4EF6\u306E\u691C\u7D22\u7D50\u679C",alt_search:"[SEARCH_TERM]\u306E\u691C\u7D22\u306B\u4E00\u81F4\u3059\u308B\u60C5\u5831\u306F\u3042\u308A\u307E\u305B\u3093\u3067\u3057\u305F\u3002[DIFFERENT_TERM]\u306E\u691C\u7D22\u7D50\u679C\u3092\u8868\u793A\u3057\u3066\u3044\u307E\u3059",search_suggestion:"[SEARCH_TERM]\u306E\u691C\u7D22\u306B\u4E00\u81F4\u3059\u308B\u60C5\u5831\u306F\u3042\u308A\u307E\u305B\u3093\u3067\u3057\u305F\u3002\u6B21\u306E\u3044\u305A\u308C\u304B\u306E\u691C\u7D22\u3092\u8A66\u3057\u3066\u304F\u3060\u3055\u3044",searching:"[SEARCH_TERM]\u3092\u691C\u7D22\u3057\u3066\u3044\u307E\u3059"},ti={thanks_to:Ql,comments:xl,direction:$l,strings:ei};var Zt={};A(Zt,{comments:()=>ri,default:()=>ii,direction:()=>si,strings:()=>li,thanks_to:()=>ni});var ni="Seokho Son ",ri="",si="ltr",li={placeholder:"\uAC80\uC0C9\uC5B4",clear_search:"\uBE44\uC6B0\uAE30",load_more:"\uAC80\uC0C9 \uACB0\uACFC \uB354 \uBCF4\uAE30",search_label:"\uC0AC\uC774\uD2B8 \uAC80\uC0C9",filters_label:"\uD544\uD130",zero_results:"[SEARCH_TERM]\uC5D0 \uB300\uD55C \uACB0\uACFC \uC5C6\uC74C",many_results:"[SEARCH_TERM]\uC5D0 \uB300\uD55C \uACB0\uACFC [COUNT]\uAC74",one_result:"[SEARCH_TERM]\uC5D0 \uB300\uD55C \uACB0\uACFC [COUNT]\uAC74",alt_search:"[SEARCH_TERM]\uC5D0 \uB300\uD55C \uACB0\uACFC \uC5C6\uC74C. [DIFFERENT_TERM]\uC5D0 \uB300\uD55C \uACB0\uACFC",search_suggestion:"[SEARCH_TERM]\uC5D0 \uB300\uD55C \uACB0\uACFC \uC5C6\uC74C. \uCD94\uCC9C \uAC80\uC0C9\uC5B4: ",searching:"[SEARCH_TERM] \uAC80\uC0C9 \uC911..."},ii={thanks_to:ni,comments:ri,direction:si,strings:li};var Xt={};A(Xt,{comments:()=>oi,default:()=>_i,direction:()=>ui,strings:()=>ci,thanks_to:()=>ai});var ai="",oi="",ui="ltr",ci={placeholder:"Rapu",clear_search:"Whakakore",load_more:"Whakauta \u0113tahi otinga k\u0113",search_label:"Rapu",filters_label:"T\u0101tari",zero_results:"Otinga kore ki [SEARCH_TERM]",many_results:"[COUNT] otinga ki [SEARCH_TERM]",one_result:"[COUNT] otinga ki [SEARCH_TERM]",alt_search:"Otinga kore ki [SEARCH_TERM]. Otinga k\u0113 ki [DIFFERENT_TERM]",search_suggestion:"Otinga kore ki [SEARCH_TERM]. whakam\u0101tau ki ng\u0101 mea atu:",searching:"Rapu ki [SEARCH_TERM]..."},_i={thanks_to:ai,comments:oi,direction:ui,strings:ci};var Qt={};A(Qt,{comments:()=>di,default:()=>pi,direction:()=>hi,strings:()=>mi,thanks_to:()=>fi});var fi="Harry Min Khant ",di="",hi="ltr",mi={placeholder:"\u101B\u103E\u102C\u101B\u1014\u103A",clear_search:"\u101B\u103E\u102C\u1016\u103D\u1031\u1019\u103E\u102F\u1000\u102D\u102F \u101B\u103E\u1004\u103A\u1038\u101C\u1004\u103A\u1038\u1015\u102B\u104B",load_more:"\u1014\u1031\u102C\u1000\u103A\u1011\u1015\u103A\u101B\u101C\u1012\u103A\u1019\u103B\u102C\u1038\u1000\u102D\u102F \u1010\u1004\u103A\u1015\u102B\u104B",search_label:"\u1024\u1006\u102D\u102F\u1000\u103A\u1010\u103D\u1004\u103A\u101B\u103E\u102C\u1016\u103D\u1031\u1015\u102B\u104B",filters_label:"\u1005\u1005\u103A\u1011\u102F\u1010\u103A\u1019\u103E\u102F\u1019\u103B\u102C\u1038",zero_results:"[SEARCH_TERM] \u1021\u1010\u103D\u1000\u103A \u101B\u101C\u1012\u103A\u1019\u103B\u102C\u1038 \u1019\u101B\u103E\u102D\u1015\u102B",many_results:"[SEARCH_TERM] \u1021\u1010\u103D\u1000\u103A \u101B\u101C\u1012\u103A [COUNT] \u1001\u102F",one_result:"[SEARCH_TERM] \u1021\u1010\u103D\u1000\u103A \u101B\u101C\u1012\u103A [COUNT]",alt_search:"[SEARCH_TERM] \u1021\u1010\u103D\u1000\u103A \u101B\u101C\u1012\u103A\u1019\u101B\u103E\u102D\u1015\u102B\u104B \u104E\u1004\u103A\u1038\u1021\u1005\u102C\u1038 [DIFFERENT_TERM] \u1021\u1010\u103D\u1000\u103A \u101B\u101C\u1012\u103A\u1019\u103B\u102C\u1038\u1000\u102D\u102F \u1015\u103C\u101E\u101E\u100A\u103A\u104B",search_suggestion:"[SEARCH_TERM] \u1021\u1010\u103D\u1000\u103A \u101B\u101C\u1012\u103A\u1019\u101B\u103E\u102D\u1015\u102B\u104B \u1021\u1031\u102C\u1000\u103A\u1015\u102B\u101B\u103E\u102C\u1016\u103D\u1031\u1019\u103E\u102F\u1019\u103B\u102C\u1038\u1011\u1032\u1019\u103E \u1010\u1005\u103A\u1001\u102F\u1000\u102D\u102F \u1005\u1019\u103A\u1038\u1000\u103C\u100A\u1037\u103A\u1015\u102B:",searching:"[SEARCH_TERM] \u1000\u102D\u102F \u101B\u103E\u102C\u1016\u103D\u1031\u1014\u1031\u101E\u100A\u103A..."},pi={thanks_to:fi,comments:di,direction:hi,strings:mi};var xt={};A(xt,{comments:()=>Ei,default:()=>Ti,direction:()=>Ri,strings:()=>bi,thanks_to:()=>gi});var gi="Eirik Mikkelsen",Ei="",Ri="ltr",bi={placeholder:"S\xF8k",clear_search:"Fjern",load_more:"Last flere resultater",search_label:"S\xF8k p\xE5 denne siden",filters_label:"Filtre",zero_results:"Ingen resultater for [SEARCH_TERM]",many_results:"[COUNT] resultater for [SEARCH_TERM]",one_result:"[COUNT] resultat for [SEARCH_TERM]",alt_search:"Ingen resultater for [SEARCH_TERM]. Viser resultater for [DIFFERENT_TERM] i stedet",search_suggestion:"Ingen resultater for [SEARCH_TERM]. Pr\xF8v en av disse s\xF8keordene i stedet:",searching:"S\xF8ker etter [SEARCH_TERM]"},Ti={thanks_to:gi,comments:Ei,direction:Ri,strings:bi};var $t={};A($t,{comments:()=>ki,default:()=>Ai,direction:()=>Si,strings:()=>Mi,thanks_to:()=>Ci});var Ci="Paul van Brouwershaven",ki="",Si="ltr",Mi={placeholder:"Zoeken",clear_search:"Reset",load_more:"Meer resultaten laden",search_label:"Doorzoek deze site",filters_label:"Filters",zero_results:"Geen resultaten voor [SEARCH_TERM]",many_results:"[COUNT] resultaten voor [SEARCH_TERM]",one_result:"[COUNT] resultaat voor [SEARCH_TERM]",alt_search:"Geen resultaten voor [SEARCH_TERM]. In plaats daarvan worden resultaten voor [DIFFERENT_TERM] weergegeven",search_suggestion:"Geen resultaten voor [SEARCH_TERM]. Probeer een van de volgende zoekopdrachten:",searching:"Zoeken naar [SEARCH_TERM]..."},Ai={thanks_to:Ci,comments:ki,direction:Si,strings:Mi};var en={};A(en,{comments:()=>vi,default:()=>Fi,direction:()=>Hi,strings:()=>wi,thanks_to:()=>yi});var yi="Eirik Mikkelsen",vi="",Hi="ltr",wi={placeholder:"S\xF8k",clear_search:"Fjern",load_more:"Last fleire resultat",search_label:"S\xF8k p\xE5 denne sida",filters_label:"Filter",zero_results:"Ingen resultat for [SEARCH_TERM]",many_results:"[COUNT] resultat for [SEARCH_TERM]",one_result:"[COUNT] resultat for [SEARCH_TERM]",alt_search:"Ingen resultat for [SEARCH_TERM]. Viser resultat for [DIFFERENT_TERM] i staden",search_suggestion:"Ingen resultat for [SEARCH_TERM]. Pr\xF8v eitt av desse s\xF8keorda i staden:",searching:"S\xF8ker etter [SEARCH_TERM]"},Fi={thanks_to:yi,comments:vi,direction:Hi,strings:wi};var tn={};A(tn,{comments:()=>zi,default:()=>Ui,direction:()=>Oi,strings:()=>ji,thanks_to:()=>Ni});var Ni="Christopher Wingate",zi="",Oi="ltr",ji={placeholder:"S\xF8k",clear_search:"Fjern",load_more:"Last flere resultater",search_label:"S\xF8k p\xE5 denne siden",filters_label:"Filtre",zero_results:"Ingen resultater for [SEARCH_TERM]",many_results:"[COUNT] resultater for [SEARCH_TERM]",one_result:"[COUNT] resultat for [SEARCH_TERM]",alt_search:"Ingen resultater for [SEARCH_TERM]. Viser resultater for [DIFFERENT_TERM] i stedet",search_suggestion:"Ingen resultater for [SEARCH_TERM]. Pr\xF8v en av disse s\xF8keordene i stedet:",searching:"S\xF8ker etter [SEARCH_TERM]"},Ui={thanks_to:Ni,comments:zi,direction:Oi,strings:ji};var nn={};A(nn,{comments:()=>Ii,default:()=>qi,direction:()=>Pi,strings:()=>Li,thanks_to:()=>Di});var Di="",Ii="",Pi="ltr",Li={placeholder:"Szukaj",clear_search:"Wyczy\u015B\u0107",load_more:"Za\u0142aduj wi\u0119cej",search_label:"Przeszukaj t\u0119 stron\u0119",filters_label:"Filtry",zero_results:"Brak wynik\xF3w dla [SEARCH_TERM]",many_results:"[COUNT] wynik\xF3w dla [SEARCH_TERM]",one_result:"[COUNT] wynik dla [SEARCH_TERM]",alt_search:"Brak wynik\xF3w dla [SEARCH_TERM]. Wy\u015Bwietlam wyniki dla [DIFFERENT_TERM]",search_suggestion:"Brak wynik\xF3w dla [SEARCH_TERM]. Pokrewne wyniki wyszukiwania:",searching:"Szukam [SEARCH_TERM]..."},qi={thanks_to:Di,comments:Ii,direction:Pi,strings:Li};var rn={};A(rn,{comments:()=>Vi,default:()=>Gi,direction:()=>Wi,strings:()=>Ki,thanks_to:()=>Bi});var Bi="Jonatah",Vi="",Wi="ltr",Ki={placeholder:"Pesquisar",clear_search:"Limpar",load_more:"Ver mais resultados",search_label:"Pesquisar",filters_label:"Filtros",zero_results:"Nenhum resultado encontrado para [SEARCH_TERM]",many_results:"[COUNT] resultados encontrados para [SEARCH_TERM]",one_result:"[COUNT] resultado encontrado para [SEARCH_TERM]",alt_search:"Nenhum resultado encontrado para [SEARCH_TERM]. Exibindo resultados para [DIFFERENT_TERM]",search_suggestion:"Nenhum resultado encontrado para [SEARCH_TERM]. Tente uma das seguintes pesquisas:",searching:"Pesquisando por [SEARCH_TERM]..."},Gi={thanks_to:Bi,comments:Vi,direction:Wi,strings:Ki};var sn={};A(sn,{comments:()=>Yi,default:()=>Qi,direction:()=>Zi,strings:()=>Xi,thanks_to:()=>Ji});var Ji="Bogdan Mateescu ",Yi="",Zi="ltr",Xi={placeholder:"C\u0103utare",clear_search:"\u015Eterge\u0163i",load_more:"\xCEnc\u0103rca\u021Bi mai multe rezultate",search_label:"C\u0103uta\u021Bi \xEEn acest site",filters_label:"Filtre",zero_results:"Niciun rezultat pentru [SEARCH_TERM]",many_results:"[COUNT] rezultate pentru [SEARCH_TERM]",one_result:"[COUNT] rezultat pentru [SEARCH_TERM]",alt_search:"Niciun rezultat pentru [SEARCH_TERM]. Se afi\u0219eaz\u0103 \xEEn schimb rezultatele pentru [DIFFERENT_TERM]",search_suggestion:"Niciun rezultat pentru [SEARCH_TERM]. \xCEncerca\u021Bi una dintre urm\u0103toarele c\u0103ut\u0103ri:",searching:"Se caut\u0103 dup\u0103: [SEARCH_TERM]..."},Qi={thanks_to:Ji,comments:Yi,direction:Zi,strings:Xi};var ln={};A(ln,{comments:()=>$i,default:()=>na,direction:()=>ea,strings:()=>ta,thanks_to:()=>xi});var xi="Aleksandr Gordeev",$i="",ea="ltr",ta={placeholder:"\u041F\u043E\u0438\u0441\u043A",clear_search:"\u041E\u0447\u0438\u0441\u0442\u0438\u0442\u044C \u043F\u043E\u043B\u0435",load_more:"\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044C \u0435\u0449\u0435",search_label:"\u041F\u043E\u0438\u0441\u043A \u043F\u043E \u0441\u0430\u0439\u0442\u0443",filters_label:"\u0424\u0438\u043B\u044C\u0442\u0440\u044B",zero_results:"\u041D\u0438\u0447\u0435\u0433\u043E \u043D\u0435 \u043D\u0430\u0439\u0434\u0435\u043D\u043E \u043F\u043E \u0437\u0430\u043F\u0440\u043E\u0441\u0443: [SEARCH_TERM]",many_results:"[COUNT] \u0440\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442\u043E\u0432 \u043F\u043E \u0437\u0430\u043F\u0440\u043E\u0441\u0443: [SEARCH_TERM]",one_result:"[COUNT] \u0440\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442 \u043F\u043E \u0437\u0430\u043F\u0440\u043E\u0441\u0443: [SEARCH_TERM]",alt_search:"\u041D\u0438\u0447\u0435\u0433\u043E \u043D\u0435 \u043D\u0430\u0439\u0434\u0435\u043D\u043E \u043F\u043E \u0437\u0430\u043F\u0440\u043E\u0441\u0443: [SEARCH_TERM]. \u041F\u043E\u043A\u0430\u0437\u0430\u043D\u044B \u0440\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442\u044B \u043F\u043E \u0437\u0430\u043F\u0440\u043E\u0441\u0443: [DIFFERENT_TERM]",search_suggestion:"\u041D\u0438\u0447\u0435\u0433\u043E \u043D\u0435 \u043D\u0430\u0439\u0434\u0435\u043D\u043E \u043F\u043E \u0437\u0430\u043F\u0440\u043E\u0441\u0443: [SEARCH_TERM]. \u041F\u043E\u043F\u0440\u043E\u0431\u0443\u0439\u0442\u0435 \u043E\u0434\u0438\u043D \u0438\u0437 \u0441\u043B\u0435\u0434\u0443\u044E\u0449\u0438\u0445 \u0432\u0430\u0440\u0438\u0430\u043D\u0442\u043E\u0432",searching:"\u041F\u043E\u0438\u0441\u043A \u043F\u043E \u0437\u0430\u043F\u0440\u043E\u0441\u0443: [SEARCH_TERM]"},na={thanks_to:xi,comments:$i,direction:ea,strings:ta};var an={};A(an,{comments:()=>sa,default:()=>aa,direction:()=>la,strings:()=>ia,thanks_to:()=>ra});var ra="Andrija Sagicc",sa="",la="ltr",ia={placeholder:"\u041F\u0440\u0435\u0442\u0440\u0430\u0433\u0430",clear_search:"\u0411\u0440\u0438\u0441\u0430\u045A\u0435",load_more:"\u041F\u0440\u0438\u043A\u0430\u0437 \u0432\u0438\u0448\u0435 \u0440\u0435\u0437\u0443\u043B\u0442\u0430\u0442\u0430",search_label:"\u041F\u0440\u0435\u0442\u0440\u0430\u0433\u0430 \u0441\u0430\u0458\u0442\u0430",filters_label:"\u0424\u0438\u043B\u0442\u0435\u0440\u0438",zero_results:"\u041D\u0435\u043C\u0430 \u0440\u0435\u0437\u0443\u043B\u0442\u0430\u0442\u0430 \u0437\u0430 [SEARCH_TERM]",many_results:"[COUNT] \u0440\u0435\u0437\u0443\u043B\u0442\u0430\u0442\u0430 \u0437\u0430 [SEARCH_TERM]",one_result:"[COUNT] \u0440\u0435\u0437\u0443\u043B\u0442\u0430\u0442\u0430 \u0437\u0430 [SEARCH_TERM]",alt_search:"\u041D\u0435\u043C\u0430 \u0440\u0435\u0437\u0443\u043B\u0442\u0430\u0442\u0430 \u0437\u0430 [SEARCH_TERM]. \u041F\u0440\u0438\u043A\u0430\u0437 \u0434\u043E\u0434\u0430\u0442\u043D\u0438\u043A \u0440\u0435\u0437\u0443\u043B\u0442\u0430\u0442\u0430 \u0437\u0430 [DIFFERENT_TERM]",search_suggestion:"\u041D\u0435\u043C\u0430 \u0440\u0435\u0437\u0443\u043B\u0442\u0430\u0442\u0430 \u0437\u0430 [SEARCH_TERM]. \u041F\u043E\u043A\u0443\u0448\u0430\u0458\u0442\u0435 \u0441\u0430 \u043D\u0435\u043A\u043E\u043C \u043E\u0434 \u0441\u043B\u0435\u0434\u0435\u045B\u0438\u0445 \u043F\u0440\u0435\u0442\u0440\u0430\u0433\u0430:",searching:"\u041F\u0440\u0435\u0442\u0440\u0430\u0433\u0430 \u0442\u0435\u0440\u043C\u0438\u043D\u0430 [SEARCH_TERM]..."},aa={thanks_to:ra,comments:sa,direction:la,strings:ia};var on={};A(on,{comments:()=>ua,default:()=>fa,direction:()=>ca,strings:()=>_a,thanks_to:()=>oa});var oa="Montazar Al-Jaber ",ua="",ca="ltr",_a={placeholder:"S\xF6k",clear_search:"Rensa",load_more:"Visa fler tr\xE4ffar",search_label:"S\xF6k p\xE5 denna sida",filters_label:"Filter",zero_results:"[SEARCH_TERM] gav inga tr\xE4ffar",many_results:"[SEARCH_TERM] gav [COUNT] tr\xE4ffar",one_result:"[SEARCH_TERM] gav [COUNT] tr\xE4ff",alt_search:"[SEARCH_TERM] gav inga tr\xE4ffar. Visar resultat f\xF6r [DIFFERENT_TERM] ist\xE4llet",search_suggestion:"[SEARCH_TERM] gav inga tr\xE4ffar. F\xF6rs\xF6k igen med en av f\xF6ljande s\xF6kord:",searching:"S\xF6ker efter [SEARCH_TERM]..."},fa={thanks_to:oa,comments:ua,direction:ca,strings:_a};var un={};A(un,{comments:()=>ha,default:()=>ga,direction:()=>ma,strings:()=>pa,thanks_to:()=>da});var da="Anonymous",ha="",ma="ltr",pa={placeholder:"Tafuta",clear_search:"Futa",load_more:"Pakia matokeo zaidi",search_label:"Tafuta tovuti hii",filters_label:"Vichujio",zero_results:"Hakuna matokeo ya [SEARCH_TERM]",many_results:"Matokeo [COUNT] ya [SEARCH_TERM]",one_result:"Tokeo [COUNT] la [SEARCH_TERM]",alt_search:"Hakuna mayokeo ya [SEARCH_TERM]. Badala yake, inaonyesha matokeo ya [DIFFERENT_TERM]",search_suggestion:"Hakuna matokeo ya [SEARCH_TERM]. Jaribu mojawapo ya utafutaji ufuatao:",searching:"Kutafuta [SEARCH_TERM]..."},ga={thanks_to:da,comments:ha,direction:ma,strings:pa};var cn={};A(cn,{comments:()=>Ra,default:()=>Ca,direction:()=>ba,strings:()=>Ta,thanks_to:()=>Ea});var Ea="",Ra="",ba="ltr",Ta={placeholder:"\u0BA4\u0BC7\u0B9F\u0BC1\u0B95",clear_search:"\u0B85\u0BB4\u0BBF\u0B95\u0BCD\u0B95\u0BC1\u0B95",load_more:"\u0BAE\u0BC7\u0BB2\u0BC1\u0BAE\u0BCD \u0BAE\u0BC1\u0B9F\u0BBF\u0BB5\u0BC1\u0B95\u0BB3\u0BC8\u0B95\u0BCD \u0B95\u0BBE\u0B9F\u0BCD\u0B9F\u0BC1\u0B95",search_label:"\u0B87\u0BA8\u0BCD\u0BA4 \u0BA4\u0BB3\u0BA4\u0BCD\u0BA4\u0BBF\u0BB2\u0BCD \u0BA4\u0BC7\u0B9F\u0BC1\u0B95",filters_label:"\u0BB5\u0B9F\u0BBF\u0B95\u0B9F\u0BCD\u0B9F\u0BB2\u0BCD\u0B95\u0BB3\u0BCD",zero_results:"[SEARCH_TERM] \u0B95\u0BCD\u0B95\u0BBE\u0BA9 \u0BAE\u0BC1\u0B9F\u0BBF\u0BB5\u0BC1\u0B95\u0BB3\u0BCD \u0B87\u0BB2\u0BCD\u0BB2\u0BC8",many_results:"[SEARCH_TERM] \u0B95\u0BCD\u0B95\u0BBE\u0BA9 [COUNT] \u0BAE\u0BC1\u0B9F\u0BBF\u0BB5\u0BC1\u0B95\u0BB3\u0BCD",one_result:"[SEARCH_TERM] \u0B95\u0BCD\u0B95\u0BBE\u0BA9 \u0BAE\u0BC1\u0B9F\u0BBF\u0BB5\u0BC1",alt_search:"[SEARCH_TERM] \u0B87\u0BA4\u0BCD\u0BA4\u0BC7\u0B9F\u0BB2\u0BC1\u0B95\u0BCD\u0B95\u0BBE\u0BA9 \u0BAE\u0BC1\u0B9F\u0BBF\u0BB5\u0BC1\u0B95\u0BB3\u0BCD \u0B87\u0BB2\u0BCD\u0BB2\u0BC8, \u0B87\u0BA8\u0BCD\u0BA4 \u0BA4\u0BC7\u0B9F\u0BB2\u0BCD\u0B95\u0BB3\u0BC1\u0B95\u0BCD\u0B95\u0BBE\u0BA9 \u0B92\u0BA4\u0BCD\u0BA4 \u0BAE\u0BC1\u0B9F\u0BBF\u0BB5\u0BC1\u0B95\u0BB3\u0BCD [DIFFERENT_TERM]",search_suggestion:"[SEARCH_TERM] \u0B87\u0BA4\u0BCD \u0BA4\u0BC7\u0B9F\u0BB2\u0BC1\u0B95\u0BCD\u0B95\u0BBE\u0BA9 \u0BAE\u0BC1\u0B9F\u0BBF\u0BB5\u0BC1\u0B95\u0BB3\u0BCD \u0B87\u0BB2\u0BCD\u0BB2\u0BC8.\u0B87\u0BA4\u0BB1\u0BCD\u0B95\u0BC1 \u0BAA\u0BA4\u0BBF\u0BB2\u0BC0\u0B9F\u0BBE\u0BA9 \u0BA4\u0BC7\u0B9F\u0BB2\u0BCD\u0B95\u0BB3\u0BC8 \u0BA4\u0BC7\u0B9F\u0BC1\u0B95:",searching:"[SEARCH_TERM] \u0BA4\u0BC7\u0B9F\u0BAA\u0BCD\u0BAA\u0B9F\u0BC1\u0B95\u0BBF\u0BA9\u0BCD\u0BB1\u0BA4\u0BC1"},Ca={thanks_to:Ea,comments:Ra,direction:ba,strings:Ta};var _n={};A(_n,{comments:()=>Sa,default:()=>ya,direction:()=>Ma,strings:()=>Aa,thanks_to:()=>ka});var ka="Patiphon Loetsuthakun ",Sa="",Ma="ltr",Aa={placeholder:"\u0E04\u0E49\u0E19\u0E2B\u0E32",clear_search:"\u0E25\u0E49\u0E32\u0E07",load_more:"\u0E42\u0E2B\u0E25\u0E14\u0E1C\u0E25\u0E25\u0E31\u0E1E\u0E18\u0E4C\u0E40\u0E1E\u0E34\u0E48\u0E21\u0E40\u0E15\u0E34\u0E21",search_label:"\u0E04\u0E49\u0E19\u0E2B\u0E32\u0E1A\u0E19\u0E40\u0E27\u0E47\u0E1A\u0E44\u0E0B\u0E15\u0E4C",filters_label:"\u0E15\u0E31\u0E27\u0E01\u0E23\u0E2D\u0E07",zero_results:"\u0E44\u0E21\u0E48\u0E1E\u0E1A\u0E1C\u0E25\u0E25\u0E31\u0E1E\u0E18\u0E4C\u0E2A\u0E33\u0E2B\u0E23\u0E31\u0E1A [SEARCH_TERM]",many_results:"\u0E1E\u0E1A [COUNT] \u0E1C\u0E25\u0E01\u0E32\u0E23\u0E04\u0E49\u0E19\u0E2B\u0E32\u0E2A\u0E33\u0E2B\u0E23\u0E31\u0E1A [SEARCH_TERM]",one_result:"\u0E1E\u0E1A [COUNT] \u0E1C\u0E25\u0E01\u0E32\u0E23\u0E04\u0E49\u0E19\u0E2B\u0E32\u0E2A\u0E33\u0E2B\u0E23\u0E31\u0E1A [SEARCH_TERM]",alt_search:"\u0E44\u0E21\u0E48\u0E1E\u0E1A\u0E1C\u0E25\u0E25\u0E31\u0E1E\u0E18\u0E4C\u0E2A\u0E33\u0E2B\u0E23\u0E31\u0E1A [SEARCH_TERM] \u0E41\u0E2A\u0E14\u0E07\u0E1C\u0E25\u0E25\u0E31\u0E1E\u0E18\u0E4C\u0E08\u0E32\u0E01\u0E01\u0E32\u0E23\u0E04\u0E49\u0E19\u0E2B\u0E32 [DIFFERENT_TERM] \u0E41\u0E17\u0E19",search_suggestion:"\u0E44\u0E21\u0E48\u0E1E\u0E1A\u0E1C\u0E25\u0E25\u0E31\u0E1E\u0E18\u0E4C\u0E2A\u0E33\u0E2B\u0E23\u0E31\u0E1A [SEARCH_TERM] \u0E25\u0E2D\u0E07\u0E04\u0E33\u0E04\u0E49\u0E19\u0E2B\u0E32\u0E40\u0E2B\u0E25\u0E48\u0E32\u0E19\u0E35\u0E49\u0E41\u0E17\u0E19:",searching:"\u0E01\u0E33\u0E25\u0E31\u0E07\u0E04\u0E49\u0E19\u0E2B\u0E32 [SEARCH_TERM]..."},ya={thanks_to:ka,comments:Sa,direction:Ma,strings:Aa};var fn={};A(fn,{comments:()=>Ha,default:()=>Na,direction:()=>wa,strings:()=>Fa,thanks_to:()=>va});var va="Taylan \xD6zg\xFCr Bildik",Ha="",wa="ltr",Fa={placeholder:"Ara\u015Ft\u0131r",clear_search:"Temizle",load_more:"Daha fazla sonu\xE7",search_label:"Site genelinde arama",filters_label:"Filtreler",zero_results:"[SEARCH_TERM] i\xE7in sonu\xE7 yok",many_results:"[SEARCH_TERM] i\xE7in [COUNT] sonu\xE7 bulundu",one_result:"[SEARCH_TERM] i\xE7in [COUNT] sonu\xE7 bulundu",alt_search:"[SEARCH_TERM] i\xE7in sonu\xE7 yok. Bunun yerine [DIFFERENT_TERM] i\xE7in sonu\xE7lar g\xF6steriliyor",search_suggestion:"[SEARCH_TERM] i\xE7in sonu\xE7 yok. Alternatif olarak a\u015Fa\u011F\u0131daki kelimelerden birini deneyebilirsiniz:",searching:"[SEARCH_TERM] ara\u015Ft\u0131r\u0131l\u0131yor..."},Na={thanks_to:va,comments:Ha,direction:wa,strings:Fa};var dn={};A(dn,{comments:()=>Oa,default:()=>Da,direction:()=>ja,strings:()=>Ua,thanks_to:()=>za});var za="Vladyslav Lyshenko ",Oa="",ja="ltr",Ua={placeholder:"\u041F\u043E\u0448\u0443\u043A",clear_search:"\u041E\u0447\u0438\u0441\u0442\u0438\u0442\u0438 \u043F\u043E\u043B\u0435",load_more:"\u0417\u0430\u0432\u0430\u043D\u0442\u0430\u0436\u0438\u0442\u0438 \u0449\u0435",search_label:"\u041F\u043E\u0448\u0443\u043A \u043F\u043E \u0441\u0430\u0439\u0442\u0443",filters_label:"\u0424\u0456\u043B\u044C\u0442\u0440\u0438",zero_results:"\u041D\u0456\u0447\u043E\u0433\u043E \u043D\u0435 \u0437\u043D\u0430\u0439\u0434\u0435\u043D\u043E \u0437\u0430 \u0437\u0430\u043F\u0438\u0442\u043E\u043C: [SEARCH_TERM]",many_results:"[COUNT] \u0440\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442\u0456\u0432 \u043D\u0430 \u0437\u0430\u043F\u0438\u0442: [SEARCH_TERM]",one_result:"[COUNT] \u0440\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442 \u0437\u0430 \u0437\u0430\u043F\u0438\u0442\u043E\u043C: [SEARCH_TERM]",alt_search:"\u041D\u0456\u0447\u043E\u0433\u043E \u043D\u0435 \u0437\u043D\u0430\u0439\u0434\u0435\u043D\u043E \u043D\u0430 \u0437\u0430\u043F\u0438\u0442: [SEARCH_TERM]. \u041F\u043E\u043A\u0430\u0437\u0430\u043D\u043E \u0440\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442\u0438 \u043D\u0430 \u0437\u0430\u043F\u0438\u0442: [DIFFERENT_TERM]",search_suggestion:"\u041D\u0456\u0447\u043E\u0433\u043E \u043D\u0435 \u0437\u043D\u0430\u0439\u0434\u0435\u043D\u043E \u043D\u0430 \u0437\u0430\u043F\u0438\u0442: [SEARCH_TERM]. \u0421\u043F\u0440\u043E\u0431\u0443\u0439\u0442\u0435 \u043E\u0434\u0438\u043D \u0456\u0437 \u0442\u0430\u043A\u0438\u0445 \u0432\u0430\u0440\u0456\u0430\u043D\u0442\u0456\u0432",searching:"\u041F\u043E\u0448\u0443\u043A \u0437\u0430 \u0437\u0430\u043F\u0438\u0442\u043E\u043C: [SEARCH_TERM]"},Da={thanks_to:za,comments:Oa,direction:ja,strings:Ua};var hn={};A(hn,{comments:()=>Pa,default:()=>Ba,direction:()=>La,strings:()=>qa,thanks_to:()=>Ia});var Ia="Long Nhat Nguyen",Pa="",La="ltr",qa={placeholder:"T\xECm ki\u1EBFm",clear_search:"X\xF3a",load_more:"Nhi\u1EC1u k\u1EBFt qu\u1EA3 h\u01A1n",search_label:"T\xECm ki\u1EBFm trong trang n\xE0y",filters_label:"B\u1ED9 l\u1ECDc",zero_results:"Kh\xF4ng t\xECm th\u1EA5y k\u1EBFt qu\u1EA3 cho [SEARCH_TERM]",many_results:"[COUNT] k\u1EBFt qu\u1EA3 cho [SEARCH_TERM]",one_result:"[COUNT] k\u1EBFt qu\u1EA3 cho [SEARCH_TERM]",alt_search:"Kh\xF4ng t\xECm th\u1EA5y k\u1EBFt qu\u1EA3 cho [SEARCH_TERM]. Ki\u1EC3m th\u1ECB k\u1EBFt qu\u1EA3 thay th\u1EBF v\u1EDBi [DIFFERENT_TERM]",search_suggestion:"Kh\xF4ng t\xECm th\u1EA5y k\u1EBFt qu\u1EA3 cho [SEARCH_TERM]. Th\u1EED m\u1ED9t trong c\xE1c t\xECm ki\u1EBFm:",searching:"\u0110ang t\xECm ki\u1EBFm cho [SEARCH_TERM]..."},Ba={thanks_to:Ia,comments:Pa,direction:La,strings:qa};var mn={};A(mn,{comments:()=>Wa,default:()=>Ja,direction:()=>Ka,strings:()=>Ga,thanks_to:()=>Va});var Va="Amber Song",Wa="",Ka="ltr",Ga={placeholder:"\u641C\u7D22",clear_search:"\u6E05\u9664",load_more:"\u52A0\u8F7D\u66F4\u591A\u7ED3\u679C",search_label:"\u7AD9\u5185\u641C\u7D22",filters_label:"\u7B5B\u9009",zero_results:"\u672A\u627E\u5230 [SEARCH_TERM] \u7684\u76F8\u5173\u7ED3\u679C",many_results:"\u627E\u5230 [COUNT] \u4E2A [SEARCH_TERM] \u7684\u76F8\u5173\u7ED3\u679C",one_result:"\u627E\u5230 [COUNT] \u4E2A [SEARCH_TERM] \u7684\u76F8\u5173\u7ED3\u679C",alt_search:"\u672A\u627E\u5230 [SEARCH_TERM] \u7684\u76F8\u5173\u7ED3\u679C\u3002\u6539\u4E3A\u663E\u793A [DIFFERENT_TERM] \u7684\u76F8\u5173\u7ED3\u679C",search_suggestion:"\u672A\u627E\u5230 [SEARCH_TERM] \u7684\u76F8\u5173\u7ED3\u679C\u3002\u8BF7\u5C1D\u8BD5\u4EE5\u4E0B\u641C\u7D22\u3002",searching:"\u6B63\u5728\u641C\u7D22 [SEARCH_TERM]..."},Ja={thanks_to:Va,comments:Wa,direction:Ka,strings:Ga};var pn={};A(pn,{comments:()=>Za,default:()=>xa,direction:()=>Xa,strings:()=>Qa,thanks_to:()=>Ya});var Ya="Amber Song",Za="",Xa="ltr",Qa={placeholder:"\u641C\u7D22",clear_search:"\u6E05\u9664",load_more:"\u52A0\u8F09\u66F4\u591A\u7D50\u679C",search_label:"\u7AD9\u5167\u641C\u7D22",filters_label:"\u7BE9\u9078",zero_results:"\u672A\u627E\u5230 [SEARCH_TERM] \u7684\u76F8\u95DC\u7D50\u679C",many_results:"\u627E\u5230 [COUNT] \u500B [SEARCH_TERM] \u7684\u76F8\u95DC\u7D50\u679C",one_result:"\u627E\u5230 [COUNT] \u500B [SEARCH_TERM] \u7684\u76F8\u95DC\u7D50\u679C",alt_search:"\u672A\u627E\u5230 [SEARCH_TERM] \u7684\u76F8\u95DC\u7D50\u679C\u3002\u6539\u70BA\u986F\u793A [DIFFERENT_TERM] \u7684\u76F8\u95DC\u7D50\u679C",search_suggestion:"\u672A\u627E\u5230 [SEARCH_TERM] \u7684\u76F8\u95DC\u7D50\u679C\u3002\u8ACB\u5617\u8A66\u4EE5\u4E0B\u641C\u7D22\u3002",searching:"\u6B63\u5728\u641C\u7D22 [SEARCH_TERM]..."},xa={thanks_to:Ya,comments:Za,direction:Xa,strings:Qa};var gn={};A(gn,{comments:()=>eo,default:()=>ro,direction:()=>to,strings:()=>no,thanks_to:()=>$a});var $a="Amber Song",eo="",to="ltr",no={placeholder:"\u641C\u7D22",clear_search:"\u6E05\u9664",load_more:"\u52A0\u8F7D\u66F4\u591A\u7ED3\u679C",search_label:"\u7AD9\u5185\u641C\u7D22",filters_label:"\u7B5B\u9009",zero_results:"\u672A\u627E\u5230 [SEARCH_TERM] \u7684\u76F8\u5173\u7ED3\u679C",many_results:"\u627E\u5230 [COUNT] \u4E2A [SEARCH_TERM] \u7684\u76F8\u5173\u7ED3\u679C",one_result:"\u627E\u5230 [COUNT] \u4E2A [SEARCH_TERM] \u7684\u76F8\u5173\u7ED3\u679C",alt_search:"\u672A\u627E\u5230 [SEARCH_TERM] \u7684\u76F8\u5173\u7ED3\u679C\u3002\u6539\u4E3A\u663E\u793A [DIFFERENT_TERM] \u7684\u76F8\u5173\u7ED3\u679C",search_suggestion:"\u672A\u627E\u5230 [SEARCH_TERM] \u7684\u76F8\u5173\u7ED3\u679C\u3002\u8BF7\u5C1D\u8BD5\u4EE5\u4E0B\u641C\u7D22\u3002",searching:"\u6B63\u5728\u641C\u7D22 [SEARCH_TERM]..."},ro={thanks_to:$a,comments:eo,direction:to,strings:no};var so=[vt,Ht,wt,Ft,Nt,zt,Ot,jt,Ut,Dt,It,Pt,Lt,qt,Bt,Vt,Wt,Kt,Gt,Jt,Yt,Zt,Xt,Qt,xt,$t,en,tn,nn,rn,sn,ln,an,on,un,cn,_n,fn,dn,hn,mn,pn,gn],dr=so,hr=["../../translations/af.json","../../translations/ar.json","../../translations/bn.json","../../translations/ca.json","../../translations/cs.json","../../translations/da.json","../../translations/de.json","../../translations/en.json","../../translations/es.json","../../translations/eu.json","../../translations/fa.json","../../translations/fi.json","../../translations/fr.json","../../translations/gl.json","../../translations/he.json","../../translations/hi.json","../../translations/hr.json","../../translations/hu.json","../../translations/id.json","../../translations/it.json","../../translations/ja.json","../../translations/ko.json","../../translations/mi.json","../../translations/my.json","../../translations/nb.json","../../translations/nl.json","../../translations/nn.json","../../translations/no.json","../../translations/pl.json","../../translations/pt.json","../../translations/ro.json","../../translations/ru.json","../../translations/sr.json","../../translations/sv.json","../../translations/sw.json","../../translations/ta.json","../../translations/th.json","../../translations/tr.json","../../translations/uk.json","../../translations/vi.json","../../translations/zh-cn.json","../../translations/zh-tw.json","../../translations/zh.json"];function mr(n,e,t){let r=n.slice();return r[51]=e[t],r}function pr(n){let e,t,r;function s(i){n[37](i)}let l={show_empty_filters:n[5],open_filters:n[6],available_filters:n[18],translate:n[20],automatic_translations:n[19],translations:n[7]};return n[0]!==void 0&&(l.selected_filters=n[0]),e=new fr({props:l}),le.push(()=>Un(e,"selected_filters",s)),{c(){ut(e.$$.fragment)},m(i,a){me(e,i,a),r=!0},p(i,a){let o={};a[0]&32&&(o.show_empty_filters=i[5]),a[0]&64&&(o.open_filters=i[6]),a[0]&262144&&(o.available_filters=i[18]),a[0]&524288&&(o.automatic_translations=i[19]),a[0]&128&&(o.translations=i[7]),!t&&a[0]&1&&(t=!0,o.selected_filters=i[0],Nn(()=>t=!1)),e.$set(o)},i(i){r||(D(e.$$.fragment,i),r=!0)},o(i){P(e.$$.fragment,i),r=!1},d(i){ue(e,i)}}}function gr(n){let e,t,r,s,l=[ao,io],i=[];function a(o,f){return o[14]?0:1}return t=a(n,[-1,-1]),r=i[t]=l[t](n),{c(){e=C("div"),r.c(),m(e,"class","pagefind-ui__results-area svelte-e9gkc3")},m(o,f){S(o,e,f),i[t].m(e,null),s=!0},p(o,f){let c=t;t=a(o,f),t===c?i[t].p(o,f):(ae(),P(i[c],1,1,()=>{i[c]=null}),oe(),r=i[t],r?r.p(o,f):(r=i[t]=l[t](o),r.c()),D(r,1),r.m(e,null))},i(o){s||(D(r),s=!0)},o(o){P(r),s=!1},d(o){o&&k(e),i[t].d()}}}function io(n){let e,t,r,s=[],l=new Map,i,a,o;function f(_,E){return _[13].results.length===0?co:_[13].results.length===1?uo:oo}let c=f(n,[-1,-1]),d=c(n),p=n[13].results.slice(0,n[17]),h=_=>_[51].id;for(let _=0;_n[17]&&Rr(n);return{c(){e=C("p"),d.c(),t=v(),r=C("ol");for(let _=0;__[17]?u?u.p(_,E):(u=Rr(_),u.c(),u.m(a.parentNode,a)):u&&(u.d(1),u=null)},i(_){if(!o){for(let E=0;E{o[p]=null}),oe(),s=o[r],s?s.p(e,d):(s=o[r]=a[r](e),s.c()),D(s,1),s.m(l.parentNode,l))},i(c){i||(D(s),i=!0)},o(c){P(s),i=!1},d(c){c&&k(t),o[r].d(c),c&&k(l)}}}function Rr(n){let e,t=n[20]("load_more",n[19],n[7])+"",r,s,l;return{c(){e=C("button"),r=w(t),m(e,"type","button"),m(e,"class","pagefind-ui__button svelte-e9gkc3")},m(i,a){S(i,e,a),R(e,r),s||(l=J(e,"click",n[22]),s=!0)},p(i,a){a[0]&524416&&t!==(t=i[20]("load_more",i[19],i[7])+"")&&z(r,t)},d(i){i&&k(e),s=!1,l()}}}function br(n){let e,t=n[20]("searching",n[19],n[7]).replace(/\[SEARCH_TERM\]/,n[16])+"",r;return{c(){e=C("p"),r=w(t),m(e,"class","pagefind-ui__message svelte-e9gkc3")},m(s,l){S(s,e,l),R(e,r)},p(s,l){l[0]&589952&&t!==(t=s[20]("searching",s[19],s[7]).replace(/\[SEARCH_TERM\]/,s[16])+"")&&z(r,t)},d(s){s&&k(e)}}}function ho(n){let e,t,r,s,l,i,a,o=n[20]("clear_search",n[19],n[7])+"",f,c,d,p,h,u,_,E,b=n[12]&&pr(n),T=n[15]&&gr(n);return{c(){e=C("div"),t=C("form"),r=C("input"),i=v(),a=C("button"),f=w(o),c=v(),d=C("div"),b&&b.c(),p=v(),T&&T.c(),m(r,"class","pagefind-ui__search-input svelte-e9gkc3"),m(r,"type","text"),m(r,"placeholder",s=n[20]("placeholder",n[19],n[7])),m(r,"title",l=n[20]("placeholder",n[19],n[7])),m(r,"autocapitalize","none"),m(r,"enterkeyhint","search"),r.autofocus=n[8],m(a,"class","pagefind-ui__search-clear svelte-e9gkc3"),B(a,"pagefind-ui__suppressed",!n[9]),m(d,"class","pagefind-ui__drawer svelte-e9gkc3"),B(d,"pagefind-ui__hidden",!n[15]),m(t,"class","pagefind-ui__form svelte-e9gkc3"),m(t,"role","search"),m(t,"aria-label",h=n[20]("search_label",n[19],n[7])),m(t,"action","javascript:void(0);"),m(e,"class","pagefind-ui svelte-e9gkc3"),B(e,"pagefind-ui--reset",n[1])},m(M,y){S(M,e,y),R(e,t),R(t,r),Tt(r,n[9]),n[34](r),R(t,i),R(t,a),R(a,f),n[35](a),R(t,c),R(t,d),b&&b.m(d,null),R(d,p),T&&T.m(d,null),u=!0,n[8]&&r.focus(),_||(E=[J(r,"focus",n[21]),J(r,"keydown",n[32]),J(r,"input",n[33]),J(a,"click",n[36]),J(t,"submit",mo)],_=!0)},p(M,y){(!u||y[0]&524416&&s!==(s=M[20]("placeholder",M[19],M[7])))&&m(r,"placeholder",s),(!u||y[0]&524416&&l!==(l=M[20]("placeholder",M[19],M[7])))&&m(r,"title",l),(!u||y[0]&256)&&(r.autofocus=M[8]),y[0]&512&&r.value!==M[9]&&Tt(r,M[9]),(!u||y[0]&524416)&&o!==(o=M[20]("clear_search",M[19],M[7])+"")&&z(f,o),(!u||y[0]&512)&&B(a,"pagefind-ui__suppressed",!M[9]),M[12]?b?(b.p(M,y),y[0]&4096&&D(b,1)):(b=pr(M),b.c(),D(b,1),b.m(d,p)):b&&(ae(),P(b,1,1,()=>{b=null}),oe()),M[15]?T?(T.p(M,y),y[0]&32768&&D(T,1)):(T=gr(M),T.c(),D(T,1),T.m(d,null)):T&&(ae(),P(T,1,1,()=>{T=null}),oe()),(!u||y[0]&32768)&&B(d,"pagefind-ui__hidden",!M[15]),(!u||y[0]&524416&&h!==(h=M[20]("search_label",M[19],M[7])))&&m(t,"aria-label",h),(!u||y[0]&2)&&B(e,"pagefind-ui--reset",M[1])},i(M){u||(D(b),D(T),u=!0)},o(M){P(b),P(T),u=!1},d(M){M&&k(e),n[34](null),n[35](null),b&&b.d(),T&&T.d(),_=!1,K(E)}}}var mo=n=>n.preventDefault();function po(n,e,t){let r={},s=hr.map(g=>g.match(/([^\/]+)\.json$/)[1]);for(let g=0;gj[g]??N[g]??"";Ct(()=>{let g=document?.querySelector?.("html")?.getAttribute?.("lang")||"en",N=ct(g.toLocaleLowerCase());t(19,Sn=r[`${N.language}-${N.script}-${N.region}`]||r[`${N.language}-${N.region}`]||r[`${N.language}`]||r.en)}),kt(()=>{F?.destroy?.(),F=null});let Mn=async()=>{if(!ft&&(t(12,ft=!0),!F)){let g;try{g=await import(`${l}pagefind.js`)}catch(j){console.error(j),console.error([`Pagefind couldn't be loaded from ${this.options.bundlePath}pagefind.js`,"You can configure this by passing a bundlePath option to PagefindUI"].join(` +`)),document?.currentScript&&document.currentScript.tagName.toUpperCase()==="SCRIPT"?console.error(`[DEBUG: Loaded from ${document.currentScript.src??"bad script location"}]`):console.error("no known script location")}c||t(24,c=f?12:30);let N={...E||{},excerptLength:c};await g.options(N);for(let j of b){if(!j.bundlePath)throw new Error("mergeIndex requires a bundlePath parameter");let L=j.bundlePath;delete j.bundlePath,await g.mergeIndex(L,j)}F=g,Sr()}},Sr=async()=>{F&&(kn=await F.filters(),(!ce||!Object.keys(ce).length)&&t(18,ce=kn))},Mr=g=>{let N={};return Object.entries(g).filter(([,j])=>j).forEach(([j])=>{let[L,te]=j.split(/:(.*)$/);N[L]=N[L]||[],N[L].push(te)}),N},_e,Ar=async(g,N)=>{if(!g){t(15,ht=!1),_e&&clearTimeout(_e);return}let j=Mr(N),L=()=>yr(g,j);_>0&&g?(_e&&clearTimeout(_e),_e=setTimeout(L,_),await An(),F.preload(g,{filters:j})):L(),vr()},An=async()=>{for(;!F;)Mn(),await new Promise(g=>setTimeout(g,50))},yr=async(g,N)=>{t(16,Cn=g||""),typeof p=="function"&&(g=p(g)),t(14,dt=!0),t(15,ht=!0),await An();let j=++Tn,L={filters:N};X&&typeof X=="object"&&(L.sort=X);let te=await F.search(g,L);Tn===j&&(te.filters&&Object.keys(te.filters)?.length&&t(18,ce=te.filters),t(13,bn=te),t(14,dt=!1),t(17,mt=i))},vr=()=>{let g=W.offsetWidth;g!=Cr&&t(10,O.style.paddingRight=`${g+2}px`,O)},Hr=g=>{g?.preventDefault(),t(17,mt+=i)},wr=g=>{g.key==="Escape"&&(t(9,H=""),O.blur()),g.key==="Enter"&&g.preventDefault()};function Fr(){H=this.value,t(9,H),t(23,T)}function Nr(g){le[g?"unshift":"push"](()=>{O=g,t(10,O)})}function zr(g){le[g?"unshift":"push"](()=>{W=g,t(11,W)})}let Or=()=>{t(9,H=""),O.blur()};function jr(g){V=g,t(0,V)}return n.$$set=g=>{"base_path"in g&&t(25,l=g.base_path),"page_size"in g&&t(26,i=g.page_size),"reset_styles"in g&&t(1,a=g.reset_styles),"show_images"in g&&t(2,o=g.show_images),"show_sub_results"in g&&t(3,f=g.show_sub_results),"excerpt_length"in g&&t(24,c=g.excerpt_length),"process_result"in g&&t(4,d=g.process_result),"process_term"in g&&t(27,p=g.process_term),"show_empty_filters"in g&&t(5,h=g.show_empty_filters),"open_filters"in g&&t(6,u=g.open_filters),"debounce_timeout_ms"in g&&t(28,_=g.debounce_timeout_ms),"pagefind_options"in g&&t(29,E=g.pagefind_options),"merge_index"in g&&t(30,b=g.merge_index),"trigger_search_term"in g&&t(23,T=g.trigger_search_term),"translations"in g&&t(7,M=g.translations),"autofocus"in g&&t(8,y=g.autofocus),"sort"in g&&t(31,X=g.sort),"selected_filters"in g&&t(0,V=g.selected_filters)},n.$$.update=()=>{if(n.$$.dirty[0]&8388608)e:T&&(t(9,H=T),t(23,T=""));if(n.$$.dirty[0]&513)e:Ar(H,V)},[V,a,o,f,d,h,u,M,y,H,O,W,ft,bn,dt,ht,Cn,mt,ce,Sn,kr,Mn,Hr,T,c,l,i,p,_,E,b,X,wr,Fr,Nr,zr,Or,jr]}var En=class extends q{constructor(e){super(),Y(this,e,po,ho,G,{base_path:25,page_size:26,reset_styles:1,show_images:2,show_sub_results:3,excerpt_length:24,process_result:4,process_term:27,show_empty_filters:5,open_filters:6,debounce_timeout_ms:28,pagefind_options:29,merge_index:30,trigger_search_term:23,translations:7,autofocus:8,sort:31,selected_filters:0},null,[-1,-1])}},Tr=En;var Rn;try{document?.currentScript&&document.currentScript.tagName.toUpperCase()==="SCRIPT"&&(Rn=new URL(document.currentScript.src).pathname.match(/^(.*\/)(?:pagefind-)?ui.js.*$/)[1])}catch{Rn="/pagefind/"}var _t=class{constructor(e){this._pfs=null;let t=e.element??"[data-pagefind-ui]",r=e.bundlePath??Rn,s=e.pageSize??5,l=e.resetStyles??!0,i=e.showImages??!0,a=e.showSubResults??!1,o=e.excerptLength??0,f=e.processResult??null,c=e.processTerm??null,d=e.showEmptyFilters??!0,p=e.openFilters??[],h=e.debounceTimeoutMs??300,u=e.mergeIndex??[],_=e.translations??[],E=e.autofocus??!1,b=e.sort??null;delete e.element,delete e.bundlePath,delete e.pageSize,delete e.resetStyles,delete e.showImages,delete e.showSubResults,delete e.excerptLength,delete e.processResult,delete e.processTerm,delete e.showEmptyFilters,delete e.openFilters,delete e.debounceTimeoutMs,delete e.mergeIndex,delete e.translations,delete e.autofocus,delete e.sort;let T=t instanceof HTMLElement?t:document.querySelector(t);T?this._pfs=new Tr({target:T,props:{base_path:r,page_size:s,reset_styles:l,show_images:i,show_sub_results:a,excerpt_length:o,process_result:f,process_term:c,show_empty_filters:d,open_filters:p,debounce_timeout_ms:h,merge_index:u,translations:_,autofocus:E,sort:b,pagefind_options:e}}):console.error(`Pagefind UI couldn't find the selector ${t}`)}triggerSearch(e){this._pfs.$$set({trigger_search_term:e})}triggerFilters(e){let t={};for(let[r,s]of Object.entries(e))if(Array.isArray(s))for(let l of s)t[`${r}:${l}`]=!0;else t[`${r}:${s}`]=!0;this._pfs.$$set({selected_filters:t})}destroy(){this._pfs.$destroy()}};window.PagefindUI=_t;})(); diff --git a/dist/pagefind/pagefind.en_16e9ffcaaf.pf_meta b/dist/pagefind/pagefind.en_16e9ffcaaf.pf_meta new file mode 100644 index 0000000000000000000000000000000000000000..1cde0d8b74f14aa666efa7bc59e0ca27bfc57e82 GIT binary patch literal 662 zcmV;H0%`ppiwFP!00002|22|7Ym`9{#<_d%3?vc|6y5;^@dJc+|L-Dx1I1Fiu)DL9 zoE$Nn2@ydE9-@_%LM$|uU%*DR5vLXqkHdM%HPcH%=665Zrmy~*}+ZB z_^^l#z0nv1kHYrF=tG*)aWPw z^;!v2v+Jxss2DM}Z+kLQrlc|qKCq_xP!$iS&-bXwN3t5m_t=jt9op2s<3iGyYz(Y< z7E!FjL@@lwn2ici!un%IO4+Fd1D5E$4?$PAKe&%{GFc0&S2>$iB?qHx>?b8JoPqIg zHt$3Tb*jUo9;Gda*}~}SiR4^Dgtg5c1r-|>rJgbtW1=gta?F1Rtl9l^>M-a#fZMYZplf~VZs z_WE)K+2=?wezr9419b?)*IbB{uA_uAb2cwxt()3yZfc9yuCDeRC(#6?I;c0Cl`&w_ zFu1@M=5r9$-S9iNO|q)eF#5}nU8;jjuyU7YZk$&J+gJQnQy05B<4de5TPd|`6$>s{ zs0bKb;S+Kxp^nh}VU#9zN<#CGt(R1!jWFIjF%TrxJK#Pfw5V4FqZ^Orv7=mOdlOnD zlB9Z0G~eRTWQ!)VauBC|4J|TSIp1E!rZ}DK++Jk5Qa2*vd=c2syR*_Ch>F!tnpd9S wUYSl=v@(v|d=c2egOX;woD>b!u8Y7O{B`_%xggy|42OsR0rR%{throw Error('TextEncoder not available')}});const encodeString=(typeof cachedTextEncoder.encodeInto==='function'?function(arg,view){return cachedTextEncoder.encodeInto(arg,view)}:function(arg,view){const buf=cachedTextEncoder.encode(arg);view.set(buf);return{read:arg.length,written:buf.length}});function passStringToWasm0(arg,malloc,realloc){if(realloc===undefined){const buf=cachedTextEncoder.encode(arg);const ptr=malloc(buf.length,1)>>>0;getUint8Memory0().subarray(ptr,ptr+buf.length).set(buf);WASM_VECTOR_LEN=buf.length;return ptr}let len=arg.length;let ptr=malloc(len,1)>>>0;const mem=getUint8Memory0();let offset=0;for(;offset0x7F)break;mem[ptr+offset]=code}if(offset!==len){if(offset!==0){arg=arg.slice(offset)}ptr=realloc(ptr,len,len=offset+arg.length*3,1)>>>0;const view=getUint8Memory0().subarray(ptr+offset,ptr+len);const ret=encodeString(arg,view);offset+=ret.written;ptr=realloc(ptr,len,offset,1)>>>0}WASM_VECTOR_LEN=offset;return ptr}let cachedInt32Memory0=null;function getInt32Memory0(){if(cachedInt32Memory0===null||cachedInt32Memory0.byteLength===0){cachedInt32Memory0=new Int32Array(wasm.memory.buffer)}return cachedInt32Memory0}const cachedTextDecoder=(typeof TextDecoder!=='undefined'?new TextDecoder('utf-8',{ignoreBOM:true,fatal:true}):{decode:()=>{throw Error('TextDecoder not available')}});if(typeof TextDecoder!=='undefined'){cachedTextDecoder.decode()};function getStringFromWasm0(ptr,len){ptr=ptr>>>0;return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr,ptr+len))}__exports.request_indexes=function(ptr,query){let deferred2_0;let deferred2_1;try{const retptr=wasm.__wbindgen_add_to_stack_pointer(-16);const ptr0=passStringToWasm0(query,wasm.__wbindgen_malloc,wasm.__wbindgen_realloc);const len0=WASM_VECTOR_LEN;wasm.request_indexes(retptr,ptr,ptr0,len0);var r0=getInt32Memory0()[retptr/4+0];var r1=getInt32Memory0()[retptr/4+1];deferred2_0=r0;deferred2_1=r1;return getStringFromWasm0(r0,r1)}finally{wasm.__wbindgen_add_to_stack_pointer(16);wasm.__wbindgen_free(deferred2_0,deferred2_1,1)}};__exports.filters=function(ptr){let deferred1_0;let deferred1_1;try{const retptr=wasm.__wbindgen_add_to_stack_pointer(-16);wasm.filters(retptr,ptr);var r0=getInt32Memory0()[retptr/4+0];var r1=getInt32Memory0()[retptr/4+1];deferred1_0=r0;deferred1_1=r1;return getStringFromWasm0(r0,r1)}finally{wasm.__wbindgen_add_to_stack_pointer(16);wasm.__wbindgen_free(deferred1_0,deferred1_1,1)}};__exports.request_filter_indexes=function(ptr,filters){let deferred2_0;let deferred2_1;try{const retptr=wasm.__wbindgen_add_to_stack_pointer(-16);const ptr0=passStringToWasm0(filters,wasm.__wbindgen_malloc,wasm.__wbindgen_realloc);const len0=WASM_VECTOR_LEN;wasm.request_filter_indexes(retptr,ptr,ptr0,len0);var r0=getInt32Memory0()[retptr/4+0];var r1=getInt32Memory0()[retptr/4+1];deferred2_0=r0;deferred2_1=r1;return getStringFromWasm0(r0,r1)}finally{wasm.__wbindgen_add_to_stack_pointer(16);wasm.__wbindgen_free(deferred2_0,deferred2_1,1)}};__exports.enter_playground_mode=function(ptr){const ret=wasm.enter_playground_mode(ptr);return ret>>>0};__exports.request_all_filter_indexes=function(ptr){let deferred1_0;let deferred1_1;try{const retptr=wasm.__wbindgen_add_to_stack_pointer(-16);wasm.request_all_filter_indexes(retptr,ptr);var r0=getInt32Memory0()[retptr/4+0];var r1=getInt32Memory0()[retptr/4+1];deferred1_0=r0;deferred1_1=r1;return getStringFromWasm0(r0,r1)}finally{wasm.__wbindgen_add_to_stack_pointer(16);wasm.__wbindgen_free(deferred1_0,deferred1_1,1)}};function passArray8ToWasm0(arg,malloc){const ptr=malloc(arg.length*1,1)>>>0;getUint8Memory0().set(arg,ptr/1);WASM_VECTOR_LEN=arg.length;return ptr}__exports.init_pagefind=function(metadata_bytes){const ptr0=passArray8ToWasm0(metadata_bytes,wasm.__wbindgen_malloc);const len0=WASM_VECTOR_LEN;const ret=wasm.init_pagefind(ptr0,len0);return ret>>>0};__exports.search=function(ptr,query,filter,sort,exact){let deferred4_0;let deferred4_1;try{const retptr=wasm.__wbindgen_add_to_stack_pointer(-16);const ptr0=passStringToWasm0(query,wasm.__wbindgen_malloc,wasm.__wbindgen_realloc);const len0=WASM_VECTOR_LEN;const ptr1=passStringToWasm0(filter,wasm.__wbindgen_malloc,wasm.__wbindgen_realloc);const len1=WASM_VECTOR_LEN;const ptr2=passStringToWasm0(sort,wasm.__wbindgen_malloc,wasm.__wbindgen_realloc);const len2=WASM_VECTOR_LEN;wasm.search(retptr,ptr,ptr0,len0,ptr1,len1,ptr2,len2,exact);var r0=getInt32Memory0()[retptr/4+0];var r1=getInt32Memory0()[retptr/4+1];deferred4_0=r0;deferred4_1=r1;return getStringFromWasm0(r0,r1)}finally{wasm.__wbindgen_add_to_stack_pointer(16);wasm.__wbindgen_free(deferred4_0,deferred4_1,1)}};__exports.load_index_chunk=function(ptr,chunk_bytes){const ptr0=passArray8ToWasm0(chunk_bytes,wasm.__wbindgen_malloc);const len0=WASM_VECTOR_LEN;const ret=wasm.load_index_chunk(ptr,ptr0,len0);return ret>>>0};__exports.add_synthetic_filter=function(ptr,filter){const ptr0=passStringToWasm0(filter,wasm.__wbindgen_malloc,wasm.__wbindgen_realloc);const len0=WASM_VECTOR_LEN;const ret=wasm.add_synthetic_filter(ptr,ptr0,len0);return ret>>>0};__exports.set_ranking_weights=function(ptr,weights){const ptr0=passStringToWasm0(weights,wasm.__wbindgen_malloc,wasm.__wbindgen_realloc);const len0=WASM_VECTOR_LEN;const ret=wasm.set_ranking_weights(ptr,ptr0,len0);return ret>>>0};__exports.load_filter_chunk=function(ptr,chunk_bytes){const ptr0=passArray8ToWasm0(chunk_bytes,wasm.__wbindgen_malloc);const len0=WASM_VECTOR_LEN;const ret=wasm.load_filter_chunk(ptr,ptr0,len0);return ret>>>0};async function __wbg_load(module,imports){if(typeof Response==='function'&&module instanceof Response){if(typeof WebAssembly.instantiateStreaming==='function'){try{return await WebAssembly.instantiateStreaming(module,imports)}catch(e){if(module.headers.get('Content-Type')!='application/wasm'){console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n",e)}else{throw e}}}const bytes=await module.arrayBuffer();return await WebAssembly.instantiate(bytes,imports)}else{const instance=await WebAssembly.instantiate(module,imports);if(instance instanceof WebAssembly.Instance){return{instance,module}}else{return instance}}}function __wbg_get_imports(){const imports={};imports.wbg={};return imports}function __wbg_init_memory(imports,maybe_memory){}function __wbg_finalize_init(instance,module){wasm=instance.exports;__wbg_init.__wbindgen_wasm_module=module;cachedInt32Memory0=null;cachedUint8Memory0=null;return wasm}function initSync(module){if(wasm!==undefined)return wasm;const imports=__wbg_get_imports();__wbg_init_memory(imports);if(!(module instanceof WebAssembly.Module)){module=new WebAssembly.Module(module)}const instance=new WebAssembly.Instance(module,imports);return __wbg_finalize_init(instance,module)}async function __wbg_init(input){if(wasm!==undefined)return wasm;if(typeof input==='undefined'&&typeof script_src!=='undefined'){input=script_src.replace(/\.js$/,'_bg.wasm')}const imports=__wbg_get_imports();if(typeof input==='string'||(typeof Request==='function'&&input instanceof Request)||(typeof URL==='function'&&input instanceof URL)){input=fetch(input)}__wbg_init_memory(imports);const{instance,module}=await __wbg_load(await input,imports);return __wbg_finalize_init(instance,module)}wasm_bindgen=Object.assign(__wbg_init,{initSync},__exports)})();var u8=Uint8Array;var u16=Uint16Array;var u32=Uint32Array;var fleb=new u8([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0]);var fdeb=new u8([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0]);var clim=new u8([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]);var freb=function(eb,start){var b=new u16(31);for(var i2=0;i2<31;++i2){b[i2]=start+=1<>>1|(i&21845)<<1;x=(x&52428)>>>2|(x&13107)<<2;x=(x&61680)>>>4|(x&3855)<<4;rev[i]=((x&65280)>>>8|(x&255)<<8)>>>1}var x;var i;var hMap=function(cd,mb,r){var s=cd.length;var i2=0;var l=new u16(mb);for(;i2>>rvb]=sv}}}}else{co=new u16(s);for(i2=0;i2>>15-cd[i2]}}}return co};var flt=new u8(288);for(i=0;i<144;++i)flt[i]=8;var i;for(i=144;i<256;++i)flt[i]=9;var i;for(i=256;i<280;++i)flt[i]=7;var i;for(i=280;i<288;++i)flt[i]=8;var i;var fdt=new u8(32);for(i=0;i<32;++i)fdt[i]=5;var i;var flrm=hMap(flt,9,1);var fdrm=hMap(fdt,5,1);var max=function(a){var m=a[0];for(var i2=1;i2m)m=a[i2]}return m};var bits=function(d,p,m){var o=p/8|0;return(d[o]|d[o+1]<<8)>>(p&7)&m};var bits16=function(d,p){var o=p/8|0;return(d[o]|d[o+1]<<8|d[o+2]<<16)>>(p&7)};var shft=function(p){return(p+7)/8|0};var slc=function(v,s,e){if(s==null||s<0)s=0;if(e==null||e>v.length)e=v.length;var n=new(v.BYTES_PER_ELEMENT==2?u16:v.BYTES_PER_ELEMENT==4?u32:u8)(e-s);n.set(v.subarray(s,e));return n};var ec=["unexpected EOF","invalid block type","invalid length/literal","invalid distance","stream finished","no stream handler",,"no callback","invalid UTF-8 data","extra field too long","date not in range 1980-2099","filename too long","stream finishing","invalid zip data"];var err=function(ind,msg,nt){var e=new Error(msg||ec[ind]);e.code=ind;if(Error.captureStackTrace)Error.captureStackTrace(e,err);if(!nt)throw e;return e};var inflt=function(dat,buf,st){var sl=dat.length;if(!sl||st&&st.f&&!st.l)return buf||new u8(0);var noBuf=!buf||st;var noSt=!st||st.i;if(!st)st={};if(!buf)buf=new u8(sl*3);var cbuf=function(l2){var bl=buf.length;if(l2>bl){var nbuf=new u8(Math.max(bl*2,l2));nbuf.set(buf);buf=nbuf}};var final=st.f||0,pos=st.p||0,bt=st.b||0,lm=st.l,dm=st.d,lbt=st.m,dbt=st.n;var tbts=sl*8;do{if(!lm){final=bits(dat,pos,1);var type=bits(dat,pos+1,3);pos+=3;if(!type){var s=shft(pos)+4,l=dat[s-4]|dat[s-3]<<8,t=s+l;if(t>sl){if(noSt)err(0);break}if(noBuf)cbuf(bt+l);buf.set(dat.subarray(s,t),bt);st.b=bt+=l,st.p=pos=t*8,st.f=final;continue}else if(type==1)lm=flrm,dm=fdrm,lbt=9,dbt=5;else if(type==2){var hLit=bits(dat,pos,31)+257,hcLen=bits(dat,pos+10,15)+4;var tl=hLit+bits(dat,pos+5,31)+1;pos+=14;var ldt=new u8(tl);var clt=new u8(19);for(var i2=0;i2>>4;if(s<16){ldt[i2++]=s}else{var c=0,n=0;if(s==16)n=3+bits(dat,pos,3),pos+=2,c=ldt[i2-1];else if(s==17)n=3+bits(dat,pos,7),pos+=3;else if(s==18)n=11+bits(dat,pos,127),pos+=7;while(n--)ldt[i2++]=c}}var lt=ldt.subarray(0,hLit),dt=ldt.subarray(hLit);lbt=max(lt);dbt=max(dt);lm=hMap(lt,lbt,1);dm=hMap(dt,dbt,1)}else err(1);if(pos>tbts){if(noSt)err(0);break}}if(noBuf)cbuf(bt+131072);var lms=(1<>>4;pos+=c&15;if(pos>tbts){if(noSt)err(0);break}if(!c)err(2);if(sym<256)buf[bt++]=sym;else if(sym==256){lpos=pos,lm=null;break}else{var add=sym-254;if(sym>264){var i2=sym-257,b=fleb[i2];add=bits(dat,pos,(1<>>4;if(!d)err(3);pos+=d&15;var dt=fd[dsym];if(dsym>3){var b=fdeb[dsym];dt+=bits16(dat,pos)&(1<tbts){if(noSt)err(0);break}if(noBuf)cbuf(bt+131072);var end=bt+add;for(;bt>3&1)+(flg>>4&1);zs>0;zs-=!d[st++]);return st+(flg&2)};var gzl=function(d){var l=d.length;return(d[l-4]|d[l-3]<<8|d[l-2]<<16|d[l-1]<<24)>>>0};function gunzipSync(data,out){return inflt(data.subarray(gzs(data),-8),out||new u8(gzl(data)))}var td=typeof TextDecoder!="undefined"&&new TextDecoder();var tds=0;try{td.decode(et,{stream:true});tds=1}catch(e){}var gz_default=gunzipSync;var calculate_excerpt_region=(word_positions,excerpt_length)=>{if(word_positions.length===0){return 0}let words=[];for(const word of word_positions){words[word.location]=words[word.location]||0;words[word.location]+=word.balanced_score}if(words.length<=excerpt_length){return 0}let densest=words.slice(0,excerpt_length).reduce((partialSum,a)=>partialSum+a,0);let working_sum=densest;let densest_at=[0];for(let i2=0;i2densest){densest=working_sum;densest_at=[i2]}else if(working_sum===densest&&densest_at[densest_at.length-1]===i2-1){densest_at.push(i2)}}let midpoint=densest_at[Math.floor(densest_at.length/2)];return midpoint};var build_excerpt=(content,start,length,locations,not_before,not_from)=>{let is_zws_delimited=content.includes("\u200B");let fragment_words=[];if(is_zws_delimited){fragment_words=content.split("\u200B")}else{fragment_words=content.split(/[\r\n\s]+/g)}for(let word of locations){if(fragment_words[word]?.startsWith(``)){continue}fragment_words[word]=`${fragment_words[word]}`}let endcap=not_from??fragment_words.length;let startcap=not_before??0;if(endcap-startcapendcap){start=endcap-length}if(start{const anchors=fragment.anchors.filter((a)=>/h\d/i.test(a.element)&&a.text?.length&&/\S/.test(a.text)).sort((a,b)=>a.location-b.location);const results=[];let current_anchor_position=0;let current_anchor={title:fragment.meta["title"],url:fragment.url,weighted_locations:[],locations:[],excerpt:""};const add_result=(end_range)=>{if(current_anchor.locations.length){const relative_weighted_locations=current_anchor.weighted_locations.map((l)=>{return{weight:l.weight,balanced_score:l.balanced_score,location:l.location-current_anchor_position}});const excerpt_start=calculate_excerpt_region(relative_weighted_locations,desired_excerpt_length)+current_anchor_position;const excerpt_length=end_range?Math.min(end_range-excerpt_start,desired_excerpt_length):desired_excerpt_length;current_anchor.excerpt=build_excerpt(fragment.raw_content??"",excerpt_start,excerpt_length,current_anchor.locations,current_anchor_position,end_range);results.push(current_anchor)}};for(let word of fragment.weighted_locations){if(!anchors.length||word.location=anchors[0].location){next_anchor=anchors.shift()}let anchored_url=fragment.url;try{const url_is_fq=/^((https?:)?\/\/)/.test(anchored_url);if(url_is_fq){let fq_url=new URL(anchored_url);fq_url.hash=next_anchor.id;anchored_url=fq_url.toString()}else{if(!/^\//.test(anchored_url)){anchored_url=`/${anchored_url}`}let fq_url=new URL(`https://example.com${anchored_url}`);fq_url.hash=next_anchor.id;anchored_url=fq_url.toString().replace(/^https:\/\/example.com/,"")}}catch(e){console.error(`Pagefind: Couldn't process ${anchored_url} for a search result`)}current_anchor_position=next_anchor.location;current_anchor={title:next_anchor.text,url:anchored_url,anchor:next_anchor,weighted_locations:[word],locations:[word.location],excerpt:""}}}add_result(anchors[0]?.location);return results};var asyncSleep=async(ms=100)=>{return new Promise((r)=>setTimeout(r,ms))};var isBrowser=typeof window!=="undefined"&&typeof document!=="undefined";var PagefindInstance=class{constructor(opts={}){this.version=pagefind_version;this.backend=wasm_bindgen;this.decoder=new TextDecoder("utf-8");this.wasm=null;this.basePath=opts.basePath||"/pagefind/";this.primary=opts.primary||false;if(this.primary&&!opts.basePath){this.initPrimary()}if(/[^\/]$/.test(this.basePath)){this.basePath=`${this.basePath}/`}if(isBrowser&&window?.location?.origin&&this.basePath.startsWith(window.location.origin)){this.basePath=this.basePath.replace(window.location.origin,"")}this.baseUrl=opts.baseUrl||this.defaultBaseUrl();if(!/^(\/|https?:\/\/)/.test(this.baseUrl)){this.baseUrl=`/${this.baseUrl}`}this.indexWeight=opts.indexWeight??1;this.excerptLength=opts.excerptLength??30;this.mergeFilter=opts.mergeFilter??{};this.ranking=opts.ranking;this.highlightParam=opts.highlightParam??null;this.loaded_chunks={};this.loaded_filters={};this.loaded_fragments={};this.raw_ptr=null;this.searchMeta=null;this.languages=null}initPrimary(){if(isBrowser&&typeof import.meta.url!=="undefined"){let derivedBasePath=import.meta.url.match(/^(.*\/)pagefind.js.*$/)?.[1];if(derivedBasePath){this.basePath=derivedBasePath}else{console.warn(["Pagefind couldn't determine the base of the bundle from the import path. Falling back to the default.","Set a basePath option when initialising Pagefind to ignore this message."].join("\n"))}}}defaultBaseUrl(){let default_base=this.basePath.match(/^(.*\/)_?pagefind/)?.[1];return default_base||"/"}async options(options2){const opts=["basePath","baseUrl","indexWeight","excerptLength","mergeFilter","highlightParam","ranking"];for(const[k,v]of Object.entries(options2)){if(k==="mergeFilter"){let filters2=this.stringifyFilters(v);let ptr=await this.getPtr();this.raw_ptr=this.backend.add_synthetic_filter(ptr,filters2)}else if(k==="ranking"){await this.set_ranking(options2.ranking)}else if(opts.includes(k)){if(k==="basePath"&&typeof v==="string")this.basePath=v;if(k==="baseUrl"&&typeof v==="string")this.baseUrl=v;if(k==="indexWeight"&&typeof v==="number")this.indexWeight=v;if(k==="excerptLength"&&typeof v==="number")this.excerptLength=v;if(k==="mergeFilter"&&typeof v==="object")this.mergeFilter=v;if(k==="highlightParam"&&typeof v==="string")this.highlightParam=v}else{console.warn(`Unknown Pagefind option ${k}. Allowed options: [${opts.join(", ")}]`)}}}async enterPlaygroundMode(){let ptr=await this.getPtr();this.raw_ptr=this.backend.enter_playground_mode(ptr)}decompress(data,file="unknown file"){if(this.decoder.decode(data.slice(0,12))==="pagefind_dcd"){return data.slice(12)}data=gz_default(data);if(this.decoder.decode(data.slice(0,12))!=="pagefind_dcd"){console.error(`Decompressing ${file} appears to have failed: Missing signature`);return data}return data.slice(12)}async set_ranking(ranking){if(!ranking)return;let rankingWeights={term_similarity:ranking.termSimilarity??null,page_length:ranking.pageLength??null,term_saturation:ranking.termSaturation??null,term_frequency:ranking.termFrequency??null};let ptr=await this.getPtr();this.raw_ptr=this.backend.set_ranking_weights(ptr,JSON.stringify(rankingWeights))}async init(language,opts){await this.loadEntry();let index=this.findIndex(language);let lang_wasm=index.wasm?index.wasm:"unknown";this.loadedLanguage=language;let resources=[this.loadMeta(index.hash)];if(opts.load_wasm===true){resources.push(this.loadWasm(lang_wasm))}await Promise.all(resources);this.raw_ptr=this.backend.init_pagefind(new Uint8Array(this.searchMeta));if(Object.keys(this.mergeFilter)?.length){let filters2=this.stringifyFilters(this.mergeFilter);let ptr=await this.getPtr();this.raw_ptr=this.backend.add_synthetic_filter(ptr,filters2)}if(this.ranking){await this.set_ranking(this.ranking)}}async loadEntry(){try{let entry_response=await fetch(`${this.basePath}pagefind-entry.json?ts=${Date.now()}`);let entry_json=await entry_response.json();this.languages=entry_json.languages;this.loadedVersion=entry_json.version;this.includeCharacters=entry_json.include_characters??[];if(entry_json.version!==this.version){if(this.primary){console.warn(["Pagefind JS version doesn't match the version in your search index.",`Pagefind JS: ${this.version}. Pagefind index: ${entry_json.version}`,"If you upgraded Pagefind recently, you likely have a cached pagefind.js file.","If you encounter any search errors, try clearing your cache."].join("\n"))}else{console.warn(["Merging a Pagefind index from a different version than the main Pagefind instance.",`Main Pagefind JS: ${this.version}. Merged index (${this.basePath}): ${entry_json.version}`,"If you encounter any search errors, make sure that both sites are running the same version of Pagefind."].join("\n"))}}}catch(e){console.error(`Failed to load Pagefind metadata: +${e?.toString()}`);throw new Error("Failed to load Pagefind metadata")}}findIndex(language){if(this.languages){let index=this.languages[language];if(index)return index;index=this.languages[language.split("-")[0]];if(index)return index;let topLang=Object.values(this.languages).sort((a,b)=>b.page_count-a.page_count);if(topLang[0])return topLang[0]}throw new Error("Pagefind Error: No language indexes found.")}async loadMeta(index){try{let compressed_resp=await fetch(`${this.basePath}pagefind.${index}.pf_meta`);let compressed_meta=await compressed_resp.arrayBuffer();this.searchMeta=this.decompress(new Uint8Array(compressed_meta),"Pagefind metadata")}catch(e){console.error(`Failed to load the meta index: +${e?.toString()}`)}}async loadWasm(language){try{const wasm_url=`${this.basePath}wasm.${language}.pagefind`;let compressed_resp=await fetch(wasm_url);let compressed_wasm=await compressed_resp.arrayBuffer();const final_wasm=this.decompress(new Uint8Array(compressed_wasm),"Pagefind WebAssembly");if(!final_wasm){throw new Error("No WASM after decompression")}this.wasm=await this.backend(final_wasm)}catch(e){console.error(`Failed to load the Pagefind WASM: +${e?.toString()}`);throw new Error(`Failed to load the Pagefind WASM: +${e?.toString()}`)}}async _loadGenericChunk(url,method){try{let compressed_resp=await fetch(url);let compressed_chunk=await compressed_resp.arrayBuffer();let chunk=this.decompress(new Uint8Array(compressed_chunk),url);let ptr=await this.getPtr();this.raw_ptr=this.backend[method](ptr,chunk)}catch(e){console.error(`Failed to load the index chunk ${url}: +${e?.toString()}`)}}async loadChunk(hash){if(!this.loaded_chunks[hash]){const url=`${this.basePath}index/${hash}.pf_index`;this.loaded_chunks[hash]=this._loadGenericChunk(url,"load_index_chunk")}return await this.loaded_chunks[hash]}async loadFilterChunk(hash){if(!this.loaded_filters[hash]){const url=`${this.basePath}filter/${hash}.pf_filter`;this.loaded_filters[hash]=this._loadGenericChunk(url,"load_filter_chunk")}return await this.loaded_filters[hash]}async _loadFragment(hash){let compressed_resp=await fetch(`${this.basePath}fragment/${hash}.pf_fragment`);let compressed_fragment=await compressed_resp.arrayBuffer();let fragment=this.decompress(new Uint8Array(compressed_fragment),`Fragment ${hash}`);return JSON.parse(new TextDecoder().decode(fragment))}async loadFragment(hash,weighted_locations=[],search_term){if(!this.loaded_fragments[hash]){this.loaded_fragments[hash]=this._loadFragment(hash)}let fragment=await this.loaded_fragments[hash];fragment.weighted_locations=weighted_locations;fragment.locations=weighted_locations.map((l)=>l.location);if(!fragment.raw_content){fragment.raw_content=fragment.content.replace(//g,">");fragment.content=fragment.content.replace(/\u200B/g,"")}if(!fragment.raw_url){fragment.raw_url=fragment.url}fragment.url=this.processedUrl(fragment.raw_url,search_term);const excerpt_start=calculate_excerpt_region(weighted_locations,this.excerptLength);fragment.excerpt=build_excerpt(fragment.raw_content,excerpt_start,this.excerptLength,fragment.locations);fragment.sub_results=calculate_sub_results(fragment,this.excerptLength);return fragment}fullUrl(raw){if(/^(https?:)?\/\//.test(raw)){return raw}return`${this.baseUrl}/${raw}`.replace(/\/+/g,"/").replace(/^(https?:\/)/,"$1/")}processedUrl(url,search_term){const normalized=this.fullUrl(url);if(this.highlightParam===null){return normalized}let individual_terms=search_term.split(/\s+/);try{let processed=new URL(normalized);for(const term of individual_terms){processed.searchParams.append(this.highlightParam,term)}return processed.toString()}catch(e){try{let processed=new URL(`https://example.com${normalized}`);for(const term of individual_terms){processed.searchParams.append(this.highlightParam,term)}return processed.toString().replace(/^https:\/\/example\.com/,"")}catch(e2){return normalized}}}async getPtr(){while(this.raw_ptr===null){await asyncSleep(50)}if(!this.raw_ptr){console.error("Pagefind: WASM Error (No pointer)");throw new Error("Pagefind: WASM Error (No pointer)")}return this.raw_ptr}stringifyFilters(obj={}){return JSON.stringify(obj)}stringifySorts(obj={}){let sorts=Object.entries(obj);for(let[sort,direction]of sorts){if(sorts.length>1){console.warn(`Pagefind was provided multiple sort options in this search, but can only operate on one. Using the ${sort} sort.`)}if(direction!=="asc"&&direction!=="desc"){console.warn(`Pagefind was provided a sort with unknown direction ${direction}. Supported: [asc, desc]`)}return`${sort}:${direction}`}return``}async filters(){let ptr=await this.getPtr();let filters2=this.backend.request_all_filter_indexes(ptr);let filter_array=JSON.parse(filters2);if(Array.isArray(filter_array)){let filter_chunks=filter_array.filter((v)=>v).map((chunk)=>this.loadFilterChunk(chunk));await Promise.all([...filter_chunks])}ptr=await this.getPtr();let results=this.backend.filters(ptr);return JSON.parse(results)}async preload(term,options2={}){await this.search(term,{...options2,preload:true})}async search(term,options2={}){options2={verbose:false,filters:{},sort:{},...options2};const log=(str)=>{if(options2.verbose)console.log(str)};log(`Starting search on ${this.basePath}`);let start=Date.now();let ptr=await this.getPtr();let filter_only=term===null;term=term??"";let exact_search=/^\s*".+"\s*$/.test(term);if(exact_search){log(`Running an exact search`)}let trueLanguage=null;try{trueLanguage=Intl.getCanonicalLocales(this.loadedLanguage)[0]}catch(err2){}const term_chunks=[];let segments;if(trueLanguage&&typeof Intl.Segmenter!=="undefined"){const segmenter=new Intl.Segmenter(trueLanguage,{granularity:"grapheme"});segments=[...segmenter.segment(term)].map(({segment})=>segment)}else{segments=[...term]}for(const segment of segments){if(this.includeCharacters?.includes(segment)){term_chunks.push(segment)}else if(!/^\p{Pd}|\p{Pe}|\p{Pf}|\p{Pi}|\p{Po}|\p{Ps}$/u.test(segment)){term_chunks.push(segment.toLocaleLowerCase())}}term=term_chunks.join("").replace(/\s{2,}/g," ").trim();log(`Normalized search term to ${term}`);if(!term?.length&&!filter_only){return{results:[],unfilteredResultCount:0,filters:{},totalFilters:{},timings:{preload:Date.now()-start,search:Date.now()-start,total:Date.now()-start}}}let sort_list=this.stringifySorts(options2.sort);log(`Stringified sort to ${sort_list}`);const filter_list=this.stringifyFilters(options2.filters);log(`Stringified filters to ${filter_list}`);let index_resp=this.backend.request_indexes(ptr,term);let index_array=JSON.parse(index_resp);let filter_resp=this.backend.request_filter_indexes(ptr,filter_list);let filter_array=JSON.parse(filter_resp);let chunks=index_array.filter((v)=>v).map((chunk)=>this.loadChunk(chunk));let filter_chunks=filter_array.filter((v)=>v).map((chunk)=>this.loadFilterChunk(chunk));await Promise.all([...chunks,...filter_chunks]);log(`Loaded necessary chunks to run search`);if(options2.preload){log(`Preload \u2014 bailing out of search operation now.`);return null}ptr=await this.getPtr();let searchStart=Date.now();let result=this.backend.search(ptr,term,filter_list,sort_list,exact_search);log(`Got the raw search result: ${result}`);let{filtered_counts,total_counts,results,unfiltered_total,search_keywords}=JSON.parse(result);let resultsInterface=results.map((result2)=>{let weighted_locations=result2.l.map((l)=>{let loc={weight:l.w/24,balanced_score:l.s,location:l.l};if(l.v){loc.verbose={word_string:l.v.ws,length_bonus:l.v.lb}}return loc});let locations=weighted_locations.map((l)=>l.location);let res={id:result2.p,score:result2.s*this.indexWeight,words:locations,data:async()=>await this.loadFragment(result2.p,weighted_locations,term)};if(result2.params){res.params={document_length:result2.params.dl,average_page_length:result2.params.apl,total_pages:result2.params.tp}}if(result2.scores){res.scores=result2.scores.map((r)=>{return{search_term:r.w,idf:r.idf,saturating_tf:r.b_tf,raw_tf:r.r_tf,pagefind_tf:r.p_tf,score:r.s,params:{weighted_term_frequency:r.params.w_tf,pages_containing_term:r.params.pct,length_bonus:r.params.lb}}})}return res});const searchTime=Date.now()-searchStart;const realTime=Date.now()-start;log(`Found ${results.length} result${results.length == 1 ? "" : "s"} for "${term}" in ${Date.now() - searchStart}ms (${Date.now() - start}ms realtime)`);let response={results:resultsInterface,unfilteredResultCount:unfiltered_total,filters:filtered_counts,totalFilters:total_counts,timings:{preload:realTime-searchTime,search:searchTime,total:realTime}};if(search_keywords){response.search_keywords=search_keywords}return response}};var Pagefind=class{constructor(options2={}){this.backend=wasm_bindgen;this.primaryLanguage="unknown";this.searchID=0;this.primary=new PagefindInstance({...options2,primary:true});this.instances=[this.primary];this.init(options2?.language)}async options(options2){await this.primary.options(options2)}async enterPlaygroundMode(){await this.primary.enterPlaygroundMode()}async init(overrideLanguage){if(isBrowser&&document?.querySelector){const langCode=document.querySelector("html")?.getAttribute("lang")||"unknown";this.primaryLanguage=langCode.toLocaleLowerCase()}await this.primary.init(overrideLanguage?overrideLanguage:this.primaryLanguage,{load_wasm:true})}async mergeIndex(indexPath,options2={}){if(this.primary.basePath.startsWith(indexPath)){console.warn(`Skipping mergeIndex ${indexPath} that appears to be the same as the primary index (${this.primary.basePath})`);return}let newInstance=new PagefindInstance({primary:false,basePath:indexPath});this.instances.push(newInstance);while(this.primary.wasm===null){await asyncSleep(50)}await newInstance.init(options2.language||this.primaryLanguage,{load_wasm:false});delete options2["language"];await newInstance.options(options2)}mergeFilters(filters2){const merged={};for(const searchFilter of filters2){for(const[filterKey,values]of Object.entries(searchFilter)){if(!merged[filterKey]){merged[filterKey]=values;continue}else{const filter=merged[filterKey];for(const[valueKey,count]of Object.entries(values)){filter[valueKey]=(filter[valueKey]||0)+count}}}}return merged}async filters(){let filters2=await Promise.all(this.instances.map((i2)=>i2.filters()));return this.mergeFilters(filters2)}async preload(term,options2={}){await Promise.all(this.instances.map((i2)=>i2.preload(term,options2)))}async debouncedSearch(term,options2,debounceTimeoutMs){const thisSearchID=++this.searchID;this.preload(term,options2);await asyncSleep(debounceTimeoutMs);if(thisSearchID!==this.searchID){return null}const searchResult=await this.search(term,options2);if(thisSearchID!==this.searchID){return null}return searchResult}async search(term,options2={}){let search2=await Promise.all(this.instances.map((i2)=>i2.search(term,options2)));const filters2=this.mergeFilters(search2.map((s)=>s.filters));const totalFilters=this.mergeFilters(search2.map((s)=>s.totalFilters));const results=search2.map((s)=>s.results).flat().sort((a,b)=>b.score-a.score);const timings=search2.map((s)=>s.timings);const unfilteredResultCount=search2.reduce((sum,s)=>sum+s.unfilteredResultCount,0);let response={results,unfilteredResultCount,filters:filters2,totalFilters,timings};if(search2[0].search_keywords){response.search_keywords=search2[0].search_keywords}return response}};var pagefind=void 0;var initial_options=void 0;var init_pagefind=()=>{if(!pagefind){pagefind=new Pagefind(initial_options??{})}};var options=async(new_options)=>{if(pagefind){await pagefind.options(new_options)}else{initial_options=new_options}};var init=async()=>{init_pagefind()};var destroy=async()=>{pagefind=void 0;initial_options=void 0};var mergeIndex=async(indexPath,options2)=>{init_pagefind();return await pagefind.mergeIndex(indexPath,options2)};var search=async(term,options2)=>{init_pagefind();return await pagefind.search(term,options2)};var debouncedSearch=async(term,options2,debounceTimeoutMs=300)=>{init_pagefind();return await pagefind.debouncedSearch(term,options2,debounceTimeoutMs)};var preload=async(term,options2)=>{init_pagefind();return await pagefind.preload(term,options2)};var filters=async()=>{init_pagefind();return await pagefind.filters()};export{debouncedSearch,destroy,filters,init,mergeIndex,options,preload,search} \ No newline at end of file diff --git a/dist/pagefind/wasm.en.pagefind b/dist/pagefind/wasm.en.pagefind new file mode 100644 index 0000000000000000000000000000000000000000..e49ad34dd4946715466eb873c7ed0bebdaf714a7 GIT binary patch literal 55619 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 E0Dj*!bpQYW literal 0 HcmV?d00001 diff --git a/dist/pagefind/wasm.unknown.pagefind b/dist/pagefind/wasm.unknown.pagefind new file mode 100644 index 0000000000000000000000000000000000000000..e3f5520ec730243ad2fd3da8f490a3227052fca6 GIT binary patch literal 52427 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͂KOAg2-{ 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 literal 0 HcmV?d00001 diff --git a/dist/reference/example/index.html b/dist/reference/example/index.html new file mode 100644 index 0000000..8adf0de --- /dev/null +++ b/dist/reference/example/index.html @@ -0,0 +1,93 @@ + Example Reference | ISPmail Guide + Skip to content

    Example Reference

    Reference pages are ideal for outlining how things work in terse and clear terms. Less concerned with telling a story or +addressing a specific use case, they should give a comprehensive outline of what you’re documenting.

    + +

    Last updated:

    +
    +This guide is maintained by Christoph Haas since 2003. All content on workaround.org can be used under the terms of + the +Creative Commons BY-NC-SA license. + Penguin image based on AI art because I suck at drawing. +
    \ No newline at end of file diff --git a/dist/robots.txt b/dist/robots.txt new file mode 100644 index 0000000..ce950e7 --- /dev/null +++ b/dist/robots.txt @@ -0,0 +1,93 @@ +User-agent: AddSearchBot +User-agent: AI2Bot +User-agent: Ai2Bot-Dolma +User-agent: aiHitBot +User-agent: Amazonbot +User-agent: Andibot +User-agent: anthropic-ai +User-agent: Applebot +User-agent: Applebot-Extended +User-agent: Awario +User-agent: bedrockbot +User-agent: bigsur.ai +User-agent: Brightbot 1.0 +User-agent: Bytespider +User-agent: CCBot +User-agent: ChatGPT Agent +User-agent: ChatGPT-User +User-agent: Claude-SearchBot +User-agent: Claude-User +User-agent: Claude-Web +User-agent: ClaudeBot +User-agent: CloudVertexBot +User-agent: cohere-ai +User-agent: cohere-training-data-crawler +User-agent: Cotoyogi +User-agent: Crawlspace +User-agent: Datenbank Crawler +User-agent: Devin +User-agent: Diffbot +User-agent: DuckAssistBot +User-agent: Echobot Bot +User-agent: EchoboxBot +User-agent: FacebookBot +User-agent: facebookexternalhit +User-agent: Factset_spyderbot +User-agent: FirecrawlAgent +User-agent: FriendlyCrawler +User-agent: Gemini-Deep-Research +User-agent: GPTBot +User-agent: iaskspider/2.0 +User-agent: ICC-Crawler +User-agent: ImagesiftBot +User-agent: img2dataset +User-agent: ISSCyberRiskCrawler +User-agent: Kangaroo Bot +User-agent: LinerBot +User-agent: meta-externalagent +User-agent: Meta-ExternalAgent +User-agent: meta-externalfetcher +User-agent: Meta-ExternalFetcher +User-agent: meta-webindexer +User-agent: MistralAI-User +User-agent: MistralAI-User/1.0 +User-agent: MyCentralAIScraperBot +User-agent: netEstate Imprint Crawler +User-agent: NovaAct +User-agent: OAI-SearchBot +User-agent: omgili +User-agent: omgilibot +User-agent: OpenAI +User-agent: Operator +User-agent: PanguBot +User-agent: Panscient +User-agent: panscient.com +User-agent: Perplexity-User +User-agent: PerplexityBot +User-agent: PetalBot +User-agent: PhindBot +User-agent: Poseidon Research Crawler +User-agent: QualifiedBot +User-agent: QuillBot +User-agent: quillbot.com +User-agent: SBIntuitionsBot +User-agent: Scrapy +User-agent: SemrushBot-OCOB +User-agent: SemrushBot-SWA +User-agent: ShapBot +User-agent: Sidetrade indexer bot +User-agent: TerraCotta +User-agent: Thinkbot +User-agent: TikTokSpider +User-agent: Timpibot +User-agent: VelenPublicWebCrawler +User-agent: WARDBot +User-agent: Webzio-Extended +User-agent: wpbot +User-agent: YaK +User-agent: YandexAdditional +User-agent: YandexAdditionalBot +User-agent: YouBot +Disallow: / + +Sitemap: https://workaround.org/sitemap-index.xml diff --git a/dist/rsnapshot-and-usb-drives/index.html b/dist/rsnapshot-and-usb-drives/index.html new file mode 100644 index 0000000..143a4db --- /dev/null +++ b/dist/rsnapshot-and-usb-drives/index.html @@ -0,0 +1,148 @@ + Backups with rsnaphot to external USB drives | ISPmail Guide + Skip to content

    Backups with rsnaphot to external USB drives

    How long has it been since you last backed up your Linux system? Let me guess – you tried various backup systems and hate all of them? Let me show you how to use rsnapshot and an external inexpensive USB drive to back up precious data easily.

    + +

    I’m a sysadmin in my day job. How could I not care about half decent backups at home. For years I have been running Bacula which has served me half well. An old AIT drive, a couple of tapes, my trusted Adaptec 2940 card and a PostgreSQL-driven Bacula installation worked moderately well but became increasingly cumbersome and fragile. The server (a retired desktop computer) crashed randomly during backups (some ancient SCSI component started to die). Or I forgot to change one of the three needed tapes (as I lacked a changer) in time so that the backup job timeout killed the running backup. Then I had to declare the tapes as free again because cancelling a backup doesn’t make Bacula free the tapes again.Or I played with PostgreSQL and inadvertently killed the director process. So maybe one backup every two weeks really ran through. And restoring files took minutes until the database finally got me the list of files. Finally one of my tapes got stuck in the drive and the drive refused to eject it. Of course the emergency ejection screw did nothing. Enough was enough. So I thought I could use an external USB drive instead of tapes but Bacula did not actually support that. An ancient shell script (vchanger) should emulate a tape changer with USB disk drives. I was too far off from KISS. What in theory sounded like decent hard- and software failed me.

    + +

    I decided to spend 50€ (the price of one AIT tape) on a 500 GB external USB disk drive and learn about rsnapshot. And in no time I had a simple backup running where I didn’t have to worry about a huge index database and could instantly access any files backed up. What I did:

    + +

    After plugging in the disk for the first time I ran “dmesg” to find out which device the disk was occupying:

    +
    [219991.641225] scsi 12:0:0:0: Direct-Access     Seagate  Portable         0130 PQ: 0 ANSI: 4
    [219991.641765] sd 12:0:0:0: Attached scsi generic sg4 type 0
    [219991.642462] sd 12:0:0:0: [sdc] 976773168 512-byte logical blocks: (500 GB/465 GiB)
    [219991.643080] sd 12:0:0:0: [sdc] Write Protect is off
    [219991.643083] sd 12:0:0:0: [sdc] Mode Sense: 2f 08 00 00
    [219991.643085] sd 12:0:0:0: [sdc] Assuming drive cache: write through
    [219991.644964] sd 12:0:0:0: [sdc] Assuming drive cache: write through
    [219991.646599]  sdc: sdc1
    [219991.694834] sd 12:0:0:0: [sdc] Assuming drive cache: write through
    [219991.695212] sd 12:0:0:0: [sdc] Attached SCSI disk
    +

    So the disk was at /dev/sdc1. I formatted the disk using

    +
    mkfs.ext4 /dev/sdc1
    +

    and read the UUID (a unique identifier assigned to each disk while formatting) using

    +
    tune2fs -l /dev/sdc1 | grep UUID
    +

    which gave me

    +
    Filesystem UUID:          44449456-2b13-47df-bfcf-9c5eedf3b287
    + +

    You will want to have your USB mounted automatically when you plug it in and use it. On a server there is no plug-and-play like that by default. But the “autofs” software does that well. Install it:

    +
    apt-get install autofs
    +

    Edit the /etc/auto.master file and add this line:

    +
    /var/autofs/removable /etc/auto.usbdrive –timeout=2,sync,nodev,nosuid
    +

    Also create an /etc/auto.usbdrive file (that you just pointed to) and add the line into it:

    +
    usbdrive -fstype=auto    UUID=44449456-2b13-47df-bfcf-9c5eedf3b287
    +

    And finally restart the autofs process:

    +
    /etc/init.d/autofs restart
    +

    This does not yet mount the disk though. But if you change into the /var/autofs/removable/usbdrive directory then autofs will look for a disk with the given UUID and mount it there on-the-fly. Try it:

    +
    cd /var/autofs/removable/usbdrive
    +

    You may notice a short delay while autofs mounts the disk. Then you should find yourself on the mounted USB drive. Type “df .” to see the filesystem. It should look like:

    +
    Filesystem            Size  Used Avail Use% Mounted on
    /dev/sdc1             459G  198M  435G   1% /var/autofs/removable/usbdrive
    + +

    Install the rsnapshot package:

    +
    apt-get install rsnapshot
    +

    The default configuration file is located in /etc/rsnapshot.conf. Edit it. But beware that all elements have to be seperated by actual Tabs. I’m using VIM and in my default settings I used “expandtabs” which automatically turned my Tabs into spaces. You don’t want that.

    +

    In that file configure “snapshot_root” to point to your autofs directory:

    +
    snapshot_root   /var/autofs/removable/usbdrive
    +

    Unless you are happy with the default backup times you will want to change the “interval” section. Make sure that you edit the /etc/cron.d/rsnapshot, too, or else rsnapshot won’t run automatically at all. I found the intervals a bit tricky but the the “man rsnapshot” manpage helped me understand it. You can use different names for the different frequencies of backups you run. But the names like “hourly” or “daily” do not mean anything. rsnapshot doesn’t have any association of “hourly” to 60 minutes for example.

    +

    My configuration reads:

    +
    retain  daily   7
    retain  weekly  4
    +

    This is much less magical than you might imagine. It just means that if you run “rsnapshot daily” then it will create backups called daily.0 to daily.6 and rotate the numbers on every rsnapshot run. You won’t have more than 7 “daily” directories though which is what you specify in the “retain” line. And you need to make sure that you call “rsnapshot daily” through a crontab. As you can imagine I’m running 7 daily backups (up to one week) and 4 weekly backups (up to one month). So my /etc/cron.d/rsnapshot file has these lines:

    +
    30 2      * * *        root    /usr/bin/rsnapshot daily
    0  4      * * 1        root    /usr/bin/rsnapshot weekly
    +

    Are you unfamiliar with crontab entries? It’s quite easy. You specify the times that you want the certain command run. The columns stand for minute, hour, day of month, month and the day of the week. So my daily job runs at 2:30 at night every day. And the weekly job is run at 4:00 at night on every monday. See “man 5 crontab” for a reference.

    +

    Back to your /etc/rsnapshot.conf. Define which directories you want to back up and which you want to have excluded. This is what I use:

    +
    backup  /var/       myserver/
    backup  /home/      myserver/
    backup  /etc/       myserver/
    exclude /home/*/tmp/
    exclude /home/*/.local/share/Trash/
    exclude /home/*/.cache/
    exclude /var/lib/mysql/
    exclude /var/lib/postgresql/
    exclude /var/tmp/
    exclude /var/log/
    exclude /var/cache/apt/archives/
    +

    Of course you can decide to backup your entire server and just exclude evil mount points like /mnt, /dev, /sys, /media and /proc. But in a case of total emergency I’d rather reinstall Debian, install the packages and restore the files. I’m excluding the database directories for MySQL and PostgreSQL here because I cannot just copy the files but need to run a proper backup.

    +

    What I also do back up a list of installed Debian packages in case I would need to reinstall:

    +
    backup_script   /usr/bin/dpkg –get-selections > packages.txt   installed-packages/
    +

    And I backup the databases:

    +
    backup_script   /usr/bin/mysqldump –opt –databases mailserver mysql | gzip > mysqldump    mysql/
    +

    I have the MySQL root password stored in /root/.my.cnf so I don’t need to mention it here.

    + +

    To make sure your configuration is correct run

    +
    rsnapshot configtest
    +

    Fix any errors until rsnapshot is happy and shows “Syntax OK”.

    +

    You can simulate a daily backup by running:

    +
    rsnapshot -t daily
    +

    It will print out the commands that rsnapshot would run.

    + +

    If you want to access the files that rsnapshot backed up this is as simple as could be. In /var/autofs/removable/usbdrive/… you will find directories for hourly, daily and weekly backups. Since rsnapshot cleverly uses hardlinks unchanged files barely take up any space. You can just browse around in the respective subdirectories and access your files.

    +

    That way you can even buy a second external USB disk drive and put the first disk off-site in case your house burns down, get burglared or your cat pees on the first disk.

    + +

    Of course if you lost the one external disk then all your backups would be ruined. So I suggest you get a second external disk and once a month swap them. Depending on your paranoia you can lock them in your bank’s deposit box or give it to your mother-in-law. As opposed to other backup solutions you can just use the second disk without much configuration. Make sure the autofs knows about it and plug it in.

    + +

    Kudos to Jochen R. who recommended rsnapshot to me.

    \ No newline at end of file diff --git a/dist/sitemap-0.xml b/dist/sitemap-0.xml new file mode 100644 index 0000000..aab2fd4 --- /dev/null +++ b/dist/sitemap-0.xml @@ -0,0 +1 @@ +https://workaround.org/https://workaround.org/article/updating-the-bios-on-lenovo-laptops-from-linux-using-a-usb-flash-stick/https://workaround.org/bacula-cheatsheet/https://workaround.org/debian-packages-are-so-old/https://workaround.org/getting-help-on-irc/https://workaround.org/ispmail-bookworm/https://workaround.org/ispmail-bookworm/automatic-installation-with-ansible/https://workaround.org/ispmail-bookworm/big-picture/https://workaround.org/ispmail-bookworm/catchall-aliases/https://workaround.org/ispmail-bookworm/catching-spam-with-rspamd/https://workaround.org/ispmail-bookworm/creating-a-tls-encryption-key-and-certificate/https://workaround.org/ispmail-bookworm/faq-frequently-asked-questions/https://workaround.org/ispmail-bookworm/install-debian-bookworm-on-your-server/https://workaround.org/ispmail-bookworm/install-the-software-packages/https://workaround.org/ispmail-bookworm/let-postfix-send-emails-to-dovecot/https://workaround.org/ispmail-bookworm/making-postfix-get-its-information-from-the-mariadb-database/https://workaround.org/ispmail-bookworm/managing-users-aliases-and-domains/https://workaround.org/ispmail-bookworm/migrating-from-a-bullseye-to-a-bookworm-server/https://workaround.org/ispmail-bookworm/monitoring-and-backup/https://workaround.org/ispmail-bookworm/prepare-the-database/https://workaround.org/ispmail-bookworm/prevent-spoofing-using-dkim/https://workaround.org/ispmail-bookworm/quotas/https://workaround.org/ispmail-bookworm/relaying-outgoing-emails-through-postfix/https://workaround.org/ispmail-bookworm/setting-dns-records/https://workaround.org/ispmail-bookworm/setting-up-dovecot/https://workaround.org/ispmail-bookworm/success-stories/https://workaround.org/ispmail-bookworm/testing-email-delivery/https://workaround.org/ispmail-bookworm/testing-imap/https://workaround.org/ispmail-bookworm/types-of-email-domains/https://workaround.org/ispmail-bookworm/webmail-using-roundcube/https://workaround.org/ispmail-bookworm/whats-new/https://workaround.org/ispmail-trixie/https://workaround.org/ispmail-trixie/anti-spoofing-dkim-spf/https://workaround.org/ispmail-trixie/automated-installation/https://workaround.org/ispmail-trixie/catch-all/https://workaround.org/ispmail-trixie/catching-spam-with-rspamd/https://workaround.org/ispmail-trixie/database/https://workaround.org/ispmail-trixie/dns-records/https://workaround.org/ispmail-trixie/dovecot/https://workaround.org/ispmail-trixie/going-live/https://workaround.org/ispmail-trixie/imap/https://workaround.org/ispmail-trixie/install-debian/https://workaround.org/ispmail-trixie/install-the-software-packages/https://workaround.org/ispmail-trixie/lmtp/https://workaround.org/ispmail-trixie/managing-users-aliases-and-domains/https://workaround.org/ispmail-trixie/overview/https://workaround.org/ispmail-trixie/postfix/https://workaround.org/ispmail-trixie/quotas/https://workaround.org/ispmail-trixie/relaying/https://workaround.org/ispmail-trixie/tls-certificate/https://workaround.org/ispmail-trixie/upgrading/https://workaround.org/ispmail-trixie/virtual-domains/https://workaround.org/ispmail-trixie/webmail/https://workaround.org/linux/renaming-multiple-files/https://workaround.org/linuxtip/pipes/https://workaround.org/reference/example/https://workaround.org/rsnapshot-and-usb-drives/https://workaround.org/squid-acls/https://workaround.org/understanding-lvm/ \ No newline at end of file diff --git a/dist/sitemap-index.xml b/dist/sitemap-index.xml new file mode 100644 index 0000000..03187af --- /dev/null +++ b/dist/sitemap-index.xml @@ -0,0 +1 @@ +https://workaround.org/sitemap-0.xml \ No newline at end of file diff --git a/dist/squid-acls/index.html b/dist/squid-acls/index.html new file mode 100644 index 0000000..ba3c133 --- /dev/null +++ b/dist/squid-acls/index.html @@ -0,0 +1,132 @@ + How Squid ACLs work | ISPmail Guide + Skip to content

    How Squid ACLs work

    For less experienced Squid administrators the concept of ACLs can be confusing at first. But they offer a great way of controlling who is allowed to access which web pages when.

    + +

    First you need to define certain criteria like accesses from the marketing department or accesses to google.com or need to authenticate. There are certain types of ACLs for that purpose. The complete list of ACLs can be found at http://www.visolve.com/squid/squid24s1/access_controls.php

    +

    The syntax of an acl is:

    +
    acl name type definition1 definition2 definition3 ...
    +

    Examples:

    +
    acl accesses_to_google dstdomain .google.com
    acl accesses_to_search_engines dstdomain .yahoo.com .google.com .vivisimo.com
    acl accesses_from_marketing_department src 10.52.0.0/16
    acl need_to_authenticate proxy_auth
    +

    You can also use lists of definitions that are stored in files on your hard disk. Let’s assume you have a list of search engines URLs that you want to allow:

    +
    /etc/squid/search-engines-urls.txt:
    .google.com
    .yahoo.com
    .altavista.com
    .vivisimo.com
    +

    Then the ACL for that file would look like:

    +
    acl accessess_to_search_engines dstdomain "/etc/squid/search-engines-urls.txt"
    +

    The quotes are important here to tell Squid it needs to look up definitions in that file.

    + +

    Defining the ACLs alone does not actually block anything – it’s just a definition. ACLs can be used in various places of your squid.conf. The most useful feature is the http_access statement. It works similar to the way a firewall would handle rules. For each request that Squid receives it will look through all the http_access statements in order until it finds a line that matches. It then either _accept_s or _deny_s depending on your setting. The remaining rules are ignored.

    +

    The general syntax of an http_access line is:

    +
    http_access (allow|deny) acl1 acl2 acl3 ...
    +

    Example:

    +
    http_access allow accesses_from_admins
    http_access deny accesses_to_porn_urls
    http_access allow accesses_during_lunchtime
    http_access deny all
    +

    This would allow accessing from the admins (whatever that ACL looks like – probably a src ACL pointing to the subnet where the admin workstations are in). For everyone else it will deny accesses to porn URLs. Then it would allow accesses from everyone to every web site during lunch time. And finally all other accesses would be denied.

    + +

    Often you need to combine ACLs. Let’s say you want to allow access to google.com only for the back office. This combines two ACLS with an AND. This would look like this:

    +
    http_access allow accesses_to_google.com accesses_from_back_office
    +

    If you wanted to use an OR and say either accesses from the back office or accesses to google.com are allowed then the line would look like this:

    +
    http_access allow accesses_to_google.com
    http_access allow accesses_from_back_office
    +

    To summarize: AND means putting the conditions in one line. OR means using seperate lines.

    + +

    By default when you deny access the user gets the error page that is stored in the ERR_ACCESS_DENIED file. But luckily you can define your own custom error pages and display them when you deny certain accesses. A simple example:

    +
    acl google dstdomain google.com
    deny_info error-google google
    http_access deny google
    +

    Put an error page into the directory where the HTML files are stored (look for error_directory in your squid.conf) and name it error-google. If the user tries to access www.google.com the access is denied and your error page is shown.

    +

    Careful when you combine ACLs on a http_access line. Example:

    +
    acl google dstdomain google.com
    acl admin src 10.0.5.16
    deny_info google error-google
    http_access deny admin google
    +

    This will deny access only for the user from the IP address 10.0.5.16 when www.google.com is accessed. As you can see I have combined the ACLs admin and google. In such a combination the last ACL in the line is taken into account for lookups of deny_info. So it’s important that you define a deny_info for the google ACL.

    + +

    Usually when a user is authenticated at the proxy you cannot “log out” and re-authenticate. The user has to close and re-open the browser windows to be able to re-login at the proxy. A simple configuration will probably look like this:

    +
    acl my_auth proxy_auth REQUIRED
    http_access allow my_auth
    http_access deny all
    +

    Now there is a tricky change that was introduced in Squid 2.5.10. It allows to control when the user is prompted to authenticate. Now it’s possible to force the user to re-authenticate although the username and password are still correct. Example configuration:

    +
    acl my_auth proxy_auth REQUIRED
    acl google dstdomain .google.com
    http_access allow my_auth
    http_access deny google my_auth
    http_access deny all
    +

    In this case if the user requests www.google.com then the second http_access line matches and triggers re-authentication. Remember: it’s always the last ACL on a http_access line that “matches”. If the matching ACL has to do with authentication a re-authentication is triggered. If you didn’t want that you would need to switch the order of ACLs so that you get http_access deny my_auth google.

    +

    You might also run into an authentication loop if you are not careful. Assume that you use LDAP group lookups and want to deny access based on an LDAP group (e.g. only members of a certain LDAP group are allowed to reach certain web sites). In this case you may trigger re-authentication although you don’t intend to. This config is likely wrong for you:

    +
    acl ldap-auth proxy_auth REQUIRED
    acl ldapgroup-allowed external LDAP_group PROXY_ALLOWED
    +
    http_access deny !ldap-auth
    http_access deny !ldapgroup-allowed
    http_access allow all
    +

    The second http_access line would force the user to re-authenticate time and again if he/she is not member of the PROXY_ALLOWED group. This is perhaps not what you want. You rather wanted to deny access to non-members. So you need to rewrite this http_access line so that an ACL matches that has nothing to do with authentication. This is the correct example:

    +
    acl ldap-auth proxy_auth REQUIRED
    acl ldapgroup-allowed external LDAP_group PROXY_ALLOWED
    acl dummy src 0.0.0.0/0.0.0.0
    +
    http_access deny !ldap-auth
    http_access deny !ldapgroup-allowed dummy
    http_access allow all
    +

    This way the second http_access line still matches. But it’s the dummy ACL which is now last in the line. Since dummy is a static ACL (that always matches) and has nothing to do with authentication you will find that the access is just denied.

    \ No newline at end of file diff --git a/dist/understanding-lvm/index.html b/dist/understanding-lvm/index.html new file mode 100644 index 0000000..e85c249 --- /dev/null +++ b/dist/understanding-lvm/index.html @@ -0,0 +1,175 @@ + Understanding the Logical Volume Manager (LVM) | ISPmail Guide + Skip to content

    Understanding the Logical Volume Manager (LVM)

    +

    LVM is a neat feature that some system administrators still shy away from. But it’s really not that hard to learn. And these are some awesome features you get:

    +
      +
    • Create a larger (virtual) disk from smaller disk (similar to RAID-0)
    • +
    • Extend partitions without any downtime
    • +
    • Add space by adding disks without any downtime
    • +
    • Remove unused partitions and get back the space without fragmentation
    • +
    • Take snapshots of partitions. You can try out things and just roll back. Or you can create consistent database backups without keeping the database down for long.
    • +
    • Replace disks without losing data.
    • +
    +

    LVM is just a thin layer of software between the disks on your system and the partitions. On a Debian system you just “apt install lvm2” and you are ready to go.

    + +

    Three terms are commonly used:

    +
      +
    • PV (physical volume). A disk. (Or a partition.) Simple as that. An SSD. A hard drive. An SD card.
    • +
    • VG (volume group). A group of disks. Take three 2 TiB disks and you get a 6 TiB volume group. (Think of it as a RAID-0 or a JBOD – just a bunch of disks.)
    • +
    • LV (logical volume). A fraction of such a group. Just take 200 GiB of the volume group and put a file system on it.
    • +
    +

    A diagram is worth a thousand words so let’s use an illustration:

    +

    Diagram explaining components of the LVM

    + +

    On the left you see your three hard disks. Your computer has found them and made them accessible as /dev/sda, /dev/sdb and /dev/sdc. Usually you would create partitions on them (e.g. using cfdisk), put a file system on the partitions (mkfs) and mount them into your file system (mount /dev/sda1 /home).

    +

    But this time we create a volume group from it. So first we turn the disks into PVs so that LVM recognizes them:

    +
    pvcreate /dev/sda
    pvcreate /dev/sdb
    pvcreate /dev/sdc
    +

    All this does is write a little meta-data onto each disk.

    +

    You can use the “pvs” command command to list the PVs you have just created.

    +

    When you take a close look at a PV for example (“pvdisplay” command) you will notice terms like “PE size” or “Free PE” or “Allocated PE”. PE is short for physical extent. Such an extent is the smallest data size that LVM handles. By default it’s set to 4 MiB. That means you can grow or shrink a logical volume only by a factor of 4 MiB. Using “lvextend” you can specify the number of extents using “-l …” (lowercase L) instead of the size “-L …” (uppercase L). Further down on this page you will find a tip on replacing a small harddisk by a larger harddisk. That essentially moves the extents from one disk to another.

    + +

    Next we create a new volume group (VG) from these three disks:

    +
    vgcreate vg1 /dev/sda /dev/sdb /dev/sdc
    +

    Now you have VG called “vg1” consisting of the three disks. The “vgs” command shows you an overview:

    +
    VG #PV #LV #SN Attr VSize VFree
    vg1 3 0 0 wz--n- <6t <6t
    +

    So you see that there is one VG called “vg1” which consists of 3 PVs (disks). And so far no LVs are using it. We will get to that in a moment. Its size is roughly 6 TiB and all of that is free to use.

    +

    Using the “vgdisplay” command shows you even more information about it.

    + +

    The final step is to bite chunks out of the VG. Check out the diagram above. We want a partition for “/home” with a size of 100 GiB. So the command to create your LV is:

    +
    lvcreate -n lvhome -L 100G vg1
    +

    Pretty simple. The “-n” parameter sets the name of the new PV. “-L” is the size you want to use. And “vg1” is the name of the VG you want to cut a piece out of.

    +

    The “lvs” command will show you an overview of your LVs.

    +
    LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
    lvhome vg1 -wi-ao---- 100,00g
    +

    There is also an “lvdisplay” command showing more verbose information about the LV.

    + +

    Finally we have something to put a file system on. You have probably used partitions on devices like /dev/sda1 before. But now you are using LVM. And the device for your “lvhome” is “/dev/vg1/lvhome”. Right, it’s “dev” + VG + LV. You could also use “/dev/mapper/vg1-lvhome”.

    +

    Put an EXT4 file system onto it:

    +
    mkfs.ext4 /dev/vg1/lvhome
    +

    And mount that file system:

    +
    mount /dev/vg1/lvhome /home
    + +

    There are PVs (disks), VGs (groups of disk) and LVs (fractions of a VG).

    +

    To use LVM first turn disks into PVs (pvcreate), then join them to a VG (vgcreate), then take a fraction of that (lvcreate) and finally create a file system on that (/dev/vgfoo/lvbar).

    +

    Every part has a list and a display command. These are:

    +
      +
    • PV -> pvs, pvdisplay
    • +
    • VG -> vgs, vgdisplay
    • +
    • LV -> lvs, lvdisplay
    • +
    + +

    You may not be impressed yet. LVM just made your life more complicated. Of course there is a reason for it because now begins the fun part. These are some common features:

    + +

    Oh, no. Your /home partition is 99% full? With LVM this is easy to solve. If you have free space on your VG (check with “vgs”) you can just extend the disk. No need to unmount anything. No downtime. Let’s give the partition 20 GiB more space:

    +
    lvextend -L +20G -r /dev/vg1/lvhome
    +

    The “-r” parameter not only extends the LV but also the file system that lives on top. That allows you to enlarge a partition without taking it offline. This is the neatest feature that LVM delivers in my opinion.

    +

    If your volume group is also out of space then you could add another disk (physical volume) and use “pvcreate” and “vgextend” to enlarge it.

    + +

    No problem either. Let’s assume that one of your disks (physical volumes) on /dev/sda was 2 TB and you just bought a shiny new 10 TB disk (found on /dev/sdg). Now you want to move the data over to the new disk. As usual you need to turn /dev/sdg into a PV:

    +
    pvcreate /dev/sdg
    +

    And now you can just move all blocks (aka physical extents – see below) to the new disk:

    +
    pvmove /dev/sda /dev/sdg
    +

    And finally you can remove the PV from your VG:

    +
    vgreduce vg1 /dev/sda
    +

    By the way: once a disk is a PV it doesn’t matter whether your system finds it on /dev/sdb, /dev/sdc or any other device. As long as all the necessary PVs are found somewhere the VG will work. Just if your boot sector was written on /dev/sda you may need to re-install it if you change that disk.

    + +

    A snapshot is like taking a photo with your camera. You get an image of a situation at a certain point in time. Reality will continue to alter the world but your photo will always show that specific moment. You can still take a pen and draw something on the photo so it’s not read-only. (It used to be on LVM 1.x.) I commonly use this technique to get consistent database snapshots of large MySQL/MariaDB databases.

    +

    Let’s just say that you have a huge 1 TiB-sized LV called “lvmysql” that is mounted to /var/lib/mysql. Running a backup of those files takes an hour. And while you back up one file after another the SQL database is accessing the various files making arbitrary changes. Your backup would contain unusable garbage. Some files were from minute 5 while others might be from minute 30. Such a backup is unusable.

    +

    Now let’s instead use snapshots. Briefly stop the database and take a snapshot:

    +
    lvcreate -n mysnap -L 20G -s /dev/vg1/lvmysql
    +

    Note that we use “lvcreate” to take the /dev/vg1/lvmysql LV and create a new /dev/vg1/mysnap LV. Just that the latter is a snapshot.

    +

    You can start your database again. With a bit of luck this has just taken a few seconds. And now you have a perfectly consistent copy of the MySQL data directory. You can mount this snapshot anywhere in your file system:

    +
    mount /dev/vg1/mysnap /mnt/mysnap
    +

    Now you can take your time and just make a backup of /mnt/mysnap. It won’t change.

    +

    However the magic comes at a price. Have you noticed the “-L 20 G” parameter? That does not mean that the snapshot has a size of 20 GiB. After all we started with a 1 TiB LV. So why did we specify a size at all?

    +

    The answer lies in the way that snapshots work. Once you started MySQL again the data directory was changed. LVM needs to provide you with your snapshot but at the same time allow MySQL to continue doing its work. That works by a mechanism called copy-on-write. If the original LV would not change then it would be identical to the snapshot. If however the files on the LV are changed then LVM needs to keep a copy of the snapshotted state. The more changes you do the more space for those copies you will need. And that’s what is meant by “-L 20 G”. It gives your snapshot a 20 GiB storage area to track the changes.

    +

    The size depends on how much change you expect while you want to use the snapshot. If the backup takes an hour and the database typically changes 100 GiB during that period then you should give the snapshot at least that space. The “lvs” command shows you much much of that space has been used already. So you should keep the snapshot no longer than needed for a backup. Should you hit the 100% mark then your snapshot becomes unusable and all you can do it remove it. That won’t affect the original LV fortunately. So you won’t break your database.

    +

    Another use case of snapshots would be to try out things on the snapshot. And if you like what you did then merge the changes to the original LV. That can be done using “lvconvert –merge /dev/vg1/mysnap”. But I suggest you consult the man page of “lvconvert” before you do that.

    + +

    Using LV for all partitions used to be a problem in the past. Debian created an ext2 partition for /boot to make sure the system boots. This has become obsolete for quite a while. You can use LVs everywhere and Debian will happily boot the system.

    + +

    By default LVM uses RAID-0. That is the RAID level that makes you lose everything if a single disk fails. LVM support RAID levels 1 and 5 though. Besides the LVM man pages I mainly found this web page describing it.

    \ No newline at end of file