Mailman: Difference between revisions

imported>Benley
first draft (more to come)
 
Klinger (talk | contribs)
 
(17 intermediate revisions by 6 users not shown)
Line 1: Line 1:
Requires at least NixOS 20.03; the <code>services.mailman</code> module in NixOS 19.09 is insufficient.
[https://www.list.org/ Mailman] is free software for managing electronic mail discussion and e-newsletter lists. Mailman and its web interface can be configured using the corresponding NixOS module.
 
This article extends the documentation in [https://nixos.org/manual/nixos/stable/#module-services-mailman NixOS manual].
 
__TOC__
 
= Running Mailman on NixOS =


This example includes:
This example includes:
Line 7: Line 13:
* letsencrypt to acquire TLS certificates for nginx
* letsencrypt to acquire TLS certificates for nginx


== Deployment steps ==
* Edit <code>/etc/nixos/configuration.nix</code> and add this stuff:
<syntaxhighlight lang="nix">
<syntaxhighlight lang="nix">
{ config, pkgs, ... }:
{ config, pkgs, ... }:
Line 19: Line 28:
     enable = true;
     enable = true;
     relayDomains = ["hash:/var/lib/mailman/data/postfix_domains"];
     relayDomains = ["hash:/var/lib/mailman/data/postfix_domains"];
    sslCert = config.security.acme.certs.${MAILMAN_HOST}.directory + "/full.pem";
    sslKey = config.security.acme.certs.${MAILMAN_HOST}.directory + "/key.pem";
     config = {
     config = {
       transport_maps = ["hash:/var/lib/mailman/data/postfix_lmtp"];
       transport_maps = ["hash:/var/lib/mailman/data/postfix_lmtp"];
Line 30: Line 41:
     webUser = config.services.uwsgi.user;
     webUser = config.services.uwsgi.user;
     hyperkitty.enable = true;
     hyperkitty.enable = true;
    # Have mailman talk directly to hyperkitty, bypassing nginx:
    hyperkitty.baseUrl = "http://localhost:33141/hyperkitty/";
     webHosts = [MAILMAN_HOST];
     webHosts = [MAILMAN_HOST];
   };
   };
Line 42: Line 55:


   # Tweak permissions so nginx can read and serve the static assets
   # Tweak permissions so nginx can read and serve the static assets
   # (/var/lib/mailman-web defaults to mode 0600)
   # (otherwise /var/lib/mailman-web is mode 0600)
   systemd.services.uwsgi.preStart = ''
   systemd.services.mailman-settings.script = ''
     chmod o+x /var/lib/mailman-web
     chmod o+x /var/lib/mailman-web
   '';
   '';
Line 58: Line 71:
         }; [ mailman-web ]
         }; [ mailman-web ]
       );
       );
      # uwsgi protocol socket for nginx
       socket = "127.0.0.1:33140";
       socket = "127.0.0.1:33140";
      # http socket for mailman core to reach the hyperkitty API directly
      http-socket = "127.0.0.1:33141";
       wsgi-file = "${config.services.mailman.webRoot}/mailman_web/wsgi.py";
       wsgi-file = "${config.services.mailman.webRoot}/mailman_web/wsgi.py";
       chdir = "/var/lib/mailman-web";
       chdir = "/var/lib/mailman-web";
Line 72: Line 88:
   services.nginx = {
   services.nginx = {
     enable = true;
     enable = true;
    recommendedGzipSettings = true;
     recommendedProxySettings = true;
     recommendedProxySettings = true;
    recommendedTlsSettings = true;
     virtualHosts.${MAILMAN_HOST} = {
     virtualHosts.${MAILMAN_HOST} = {
       enableACME = true;
       enableACME = true;
       forceSSL = true;
       forceSSL = true;
       locations."/static/".alias = "/var/lib/mailman-web/static/";
       locations."/static/".alias = "/var/lib/mailman-web/static/";
      # If you're coming from Mailman 2, you might want these redirects:
      # locations."~ ^/(?:pipermail|private)/([a-z-]+)/".return = "303 https://${MAILMAN_HOST}/hyperkitty/list/$1.${MAILMAN_HOST}/";
      # locations."~ ^/(?:listadmin)/([a-z-]+)".return = "303 https://${MAILMAN_HOST}/postorius/lists/$1.${MAILMAN_HOST}/settings/";
      # locations."~ ^/(?:listinfo|options)/([a-z-]+)".return = "303 https://${MAILMAN_HOST}/postorius/lists/$1.${MAILMAN_HOST}/";
      # locations."/create".return = "301 https://${MAILMAN_HOST}/postorius/lists/new";
       locations."/".extraConfig = ''
       locations."/".extraConfig = ''
         uwsgi_pass 127.0.0.1:33140;
         uwsgi_pass 127.0.0.1:33140;
Line 84: Line 107:
   };
   };


   networking.firewall.allowedTCPPorts = [ 80 443 ];
   networking.firewall.allowedTCPPorts = [ 25 80 443 ];
}
}
</syntaxhighlight>
</syntaxhighlight>
* Install and start the services:
<span style="color: red">[root@mailman:~]#</span> '''nixos-rebuild switch'''
* Generate initial <code>postfix_domains.db</code> and <code>postfix_lmtp.db</code> databases for Postfix:
<span style="color: red">[root@mailman:~]#</span> '''sudo -u mailman mailman aliases'''
* Create a django superuser account.  Be careful to run this only as the <code>uwsgi</code> user in <code>/var/lib/mailman-web</code> or you will run into permission problems later.
<span style="color: red">[root@mailman:~]#</span> '''cd /var/lib/mailman-web'''
<span style="color: red">[root@mailman:/var/lib/mailman-web]#</span> '''sudo -u uwsgi mailman-web createsuperuser'''
### Using settings module from /etc/mailman3/settings.py  ####
Username (leave blank to use 'uwsgi'): '''root'''
Email address: '''postmaster@example.com'''
Password:
Password (again):
Superuser created successfully.
* Navigate to <code>https://<your_mailman_hostname>/admin</code> in a web browser and login to the Django admin interface:
*:[[File:Django_admin_login.png|400px]]
* Navigate to <code>https://<your_mailman_hostname>/admin/sites/site</code>.  Click on the '''example.com''' site, change it to your desired domain name, and hit Save.  This configures the web serving domain, ''not'' the domain used for email.
*:[[File:Django_select_site_to_change.png]]
*:[[File:Django_admin_change_site.png]]
* Navigate to <code>https://<your_mailman_hostname>/postorius/domains/new/</code>.  Fill in the form to add the domain you wish to use for mailing list email addresses.
*:[[File:Postorius_add_new_domain.png|425px]]
At this point you should have a working Mailman installation.  Create and manage lists using the web interface or the <code>mailman</code> commandline tool, and refer to the [https://docs.mailman3.org/ upstream documentation] for lots more information.
== Optional extras ==
=== Social logins ===
Mailman 3 uses [https://docs.allauth.org/en/latest/ django-allauth] to allow logins via many external auth providers, such as GitHub and Google.  To enable these we need to update our Django settings and add some per-provider specifics in the admin UI.
In this example we're just adding GitHub, but there are [https://docs.allauth.org/en/latest/socialaccount/providers/ lots of other providers] available.
* Add to your <code>configuration.nix</code> and run <code>nixos-rebuild switch</code>:
<syntaxhighlight lang="nix">
  # Extend the django settings.py directly since this can't all be
  # done via JSON settings (services.mailman.webSettings)
  environment.etc."mailman3/settings.py".text = ''
    INSTALLED_APPS.extend([
      "allauth.socialaccount.providers.github",
    ])
  '';
</syntaxhighlight>
* Register a new OAuth application on GitHub at https://github.com/settings/applications/new.  Your Authorization Callback URL will be <code>https://<your_mailman_hostname>/accounts/github/login/callback/</code>.  Save the Client ID and Client Secret that GitHub gives you at the end of this process.
* Navigate to <code>https://<your_mailman_hostname>/admin/socialaccount/socialapp/add/</code> and fill in the values you got from GitHub.  Make sure you click '''Choose all''' to enable this auth provide for your django site, then click '''Save'''.
*: [[File:Django_admin_add_social_application.png]]
Now you should be able to login to your mailman site with GitHub, and see your account's connections at <code>https://<your_mailman_hostname>/accounts/social/connections/</code>
[[Category:Mail Server]]
[[Category:Server]]
[[Category:Web Applications]]
[[Category:Django]]
[[Category:NixOS Manual]]