
Re: Easiest way to install a new mailman3 deployment?
by Andrew Hodgson
Hi,
I completed this on a Debian Buster server instance during last year and have got some notes on the process. I decided to go down the venv route rather than use Docker, but I already had it up and running using the Docker instance on another machine. I found getting it up and running on Docker helped me understand how everything hung together, but ultimately I wanted to run it under a venv so I could understand it a bit more and also I wasn't using Docker in the rest of the environment on that server. I also got caught out earlier on with the Docker containers changing the search engine from Woosh to Xapian which is why I wanted more control over what was going on. Here is a copy of those notes for interest.
I used package managers to provide PostgreSQL support as that was what the Docker install gave me to start with. I may have chosen another DB engine but as I was already using Postgres I stuck with that. I also installed Xapian using the package manager as well as Exim, Nginx, Sassc and Python using the package managers. I didn't install Memcached.
I mainly followed the instructions at: https://wiki.list.org/DOC/Mailman%203%20installation%20experience
My directory structure uses /opt/mailman as the base, the instructions on this web page use /opt/mailman/mm and I didn't have this extra subdirectory. I ensured this directory was owned by list:list.
I installed my venv under /opt/mailman/venv choosing to copy over the existing distribution installed Python packages and installed the following packages via Pip after activating it:
Upgrade packages that are already installed which need an upgrade to work with Mailman3:
pip3 install -U pip zope.interface
Get the rest installed:
pip3 install mailman mailmanclient django-mailman3 mailman-hyperkitty hyperkitty postorius psycopg2-binary xapian-haystack
This also installs Gunicorn which I use as the backend wsgi server.
The reason I chose to use existing system packages as part of the venv is because I wanted to use the Xapian installation I had installed via system packages as I ran into issues installing it via Pip. In future I think I will try and install the PostgreSQL driver this way as well.
Once deactivating the venv I recommend getting the directory structure and files copied to the right places from the links on the wiki, noting that in my cases I had to edit the files to change the relevant paths to suit my new layout, and also where necessary (Systemd units) change the user/group. . You should then run all the Mailman specific commands using these scripts in /opt/mailman/bin. I learnt the hard way that you will run into problems if you try and run Mailman from the venv directory as it will look for files in the wrong place and create data files in the wrong directory. As I went down this road my configuration files mailman.cfg and mailman-hyperkitty.cfg are actually located in /opt/mailman/etc but that isn't a requirement if you follow the wiki and use the scripts provided.
I obtained manage.py, settings.py, urls.py and wsgi.py from the Gitlab Mailman-suite project instead of the wiki site to ensure I got the latest versions and put these files in /opt/mailman. Regarding /opt/mailman/bin/mailman-post/update, I removed the references to Memcached as I didn't use it. I also didn't symlink /opt/mailman/logs to /opt/mailman/var/logs as advised by the wiki but will do this on a reinstall.
I generated a new Mailman PostgreSQL user and restored my existing database to the new server (which also upgraded the DB to a newer Postgresql version as the Docker-Compose from the Mailman Docker project uses an older Postgresql container).
I copied the Mailman runtime files from the Mailman core container data volume to /opt/mailman/var.
I generated a Hyperkitty API secret key and also a Django secret key.
Taking the mailman.cfg file from the wiki as a base, I updated the following parts:
[database]
class: mailman.database.postgresql.PostgreSQLDatabase
url: postgres://mailman:[password]@localhost/mailmandb
[mailman]
site_owner: mailman-owner(a)lists.domain.com
[mta]
incoming: mailman.mta.exim4.LMTP
configuration: python:mailman.config.exim4
[archiver.hyperkitty]
class: mailman_hyperkitty.Archiver
enable: yes
configuration: /opt/mailman/etc/mailman-hyperkitty.cfg
In /opt/mailman/etc/mailman-hyperkitty.cfg add the following:
[general]
base_url: http://localhost:8000/hyperkitty/
api_key: [generated-hyperkitty-api-key]
Using systemctl see if you can start Mailman and observe logs etc.
In terms of the Django stuff you need to create /opt/mailman/settings-local.py which will be read in by the system and will overwrite the default settings in /opt/mailman/settings.py obtained from the Mailman-suite project. This directly configures the Django framework which the Mailman web components Postorius and Hyperkitty run under.
Here is a outline copy of my file:
import os
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
SECRET_KEY = '[generated-django-secret-key]'
MAILMAN_ARCHIVER_KEY = '[generated-hyperkitty-api-key]'
DEFAULT_FROM_EMAIL = 'mailman-owner(a)lists.domain.com'
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
DEBUG = False
USE_X_FORWARDED_HOST = True
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
ALLOWED_HOSTS = [
'localhost',
'lists.domain.com'
]
INSTALLED_APPS = (
# Copy the installed apps from the settings.py and remove the social provider logins you don't want to support.
)
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'mailmandb',
'USER': 'mailman',
'PASSWORD': '[password]',
'HOST': 'localhost'
}
}
HAYSTACK_CONNECTIONS = {
'default': {
'PATH': os.path.join(BASE_DIR, "fulltext_index"),
'ENGINE': 'xapian_backend.XapianEngine'
},
}
LOGGING = {
# Copy the complete LOGGING section from settings.py and change the path as follows, if there is a way of just adding the relevant path override to this file let me know. I am doing this only because I didn't create a symlink for /opt/mailman/logs.
'version': 1,
'disable_existing_loggers': False,
'filters': {
[...]
}
},
'handlers': {
'mail_admins': {
[...]
},
'file':{
'level': 'INFO',
'class': 'logging.handlers.WatchedFileHandler',
'filename': os.path.join(BASE_DIR, 'var/logs', 'mailmansuite.log'),
'formatter': 'verbose',
},
'console': {
[...]
},
},
'loggers': {
'django.request': {
[...]
},
'django': {
[...]
},
'hyperkitty': {
[...]
},
'postorius': {
[...]
},
},
'formatters': {
'verbose': {
[...]
},
'simple': {
[...]
},
},
}
Try running /opt/mailman/bin/mailman-post-update and choose to rebuild indexes, see if the static files get saved to /opt/mailman/static and the search indexes get saved to /opt/mailman/fulltext_index. In my case I had plenty of indexing to do, not sure if these files are created on a green-field installation with nothing archived. This command will also populate the Postgresql database schema.
See if the Systemd units for mailman-web and mailman-cluster come up. Observe logs. If everything ok the Gunicorn should be listening on localhost:8000.
For Nginx integration I followed the wiki, only change I had to make was to send the host header to the backend server, here is a partial config file:
server {
server_name lists.domain.com;
root /var/www/lists;
access_log /var/log/nginx/lists-access.log;
error_log /var/log/nginx/lists-error.log warn;
listen [::]:443 ssl; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/lists.domain.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/lists.domain.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
location = /favicon.ico {
log_not_found off;
}
location = /robots.txt {
log_not_found off;
}
location / {
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_pass http://localhost:8000/;
}
location /static {
alias /opt/mailman/static;
}
}
server {
if ($host = lists.domain.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
listen [::]:80;
server_name lists.domain.com;
return 404; # managed by Certbot
}
For Exim integration I followed to the letter the information here: https://mailman.readthedocs.io/en/latest/src/mailman/docs/mta.html#exim
Here is a Logrotate script which is not in the Mailman wiki:
/opt/mailman/var/logs/*.log {
missingok
sharedscripts
su list list
postrotate
/opt/mailman/bin/mailman reopen &>/dev/null || true
if [ -r /opt/mailman/var/gunicorn.pid ]; then
PID=`cat /opt/mailman/var/gunicorn.pid`
kill -s USR1 $PID
fi
endscript
}
I have been running this setup since March 2020, I run around 10 lists on this server with around 10 mails per list per day. I actually had more issues when moving from Mailman2 to Mailman3 using the Docker containers and actually this process made me understand a lot more how everything hangs together and where to troubleshoot issues.
Hope this helps someone out there.
Andrew.
-----Original Message-----
From: Matthew Alberti <matthew(a)alberti.us>
Sent: 01 January 2021 02:48
To: ieso(a)johnwillson.com
Cc: 'Mailman users' <mailman-users(a)mailman3.org>
Subject: [MM3-users] Re: Easiest way to install a new mailman3 deployment?
I had a very similar experience. I don't mean to knock the dev team; Mailman3 is an awesome tool that really meets a need. It is really much much more than a 'tool.' A very comprehensive software suite.
For me, I ended up using the docker option on Ubuntu 20.04. My advice is to give up on the idea of using OS package managers. They just aren't current enough (certainly for Ubuntu LTS), or updated frequently enough, for the current development of Mailman3. Nothing but problems for me on Ubuntu, and Debian is about the same.
Pypi, or installation in a virtualized environment, was equally challenging. I strongly recommend the docker installation method. It is not quite turnkey, but the documentation is close enough where it might 'just work' in your environment. I used MariaDB, and that introduced some challenges. If you are using postgre, postfix, and nginx, you are pretty close to a very easy installation.
This list is very supportive, with very frequent responses from the core dev team. And there are guys like me who really struggled to get to a production instance. Please let us all know what isn't working in the docker approach, and we will try to help I'm sure.
- Matt Alberti
Get BlueMail for Android
On Dec 31, 2020, 8:15 PM, at 8:15 PM, ieso(a)johnwillson.com wrote:
>So I've been trying for the last two weeks to get a new mailman3 server
>running on a virtualized server (any server), and I'm turning to this
>list after having failed many times and running out of holiday time.
>
>I started trying a non-docker installation on Ubuntu 18.04
>(https://docs.google.com/document/d/1xIcSsoNFp2nHi7r4eQys00s9a0k2sHhu1V
>5PlantPTs/edit#) , which got me the closest. Except I had a problem
>with inbound email only being triggered when it came from certain
>accounts. But that clearly wasn't good enough for production, so after
>many attempts to figure out where it was failing, I decided to turn to
>docker as a solution that should be cleaner.
>
>A few attempts at doing a docker installation on digitalocean.com
>failed, which I realized might be due to it not routing private IP
>addresses, so I moved to AWS after checking that their VPC policy would
>fit mailman's docker requirements. I found a great but slightly
>outdated guide on how to do this
>(https://xiaoxing.us/2018/01/01/deploy-mailman-3-on-aws-using-docker/)
>By this point I knew enough to correct a number of places where the
>environment had changed since the procedure was written, but postorius
>still failed at the curl test.
>
>The challenge for me has been the difficulty to know how to
>troubleshoot the different different systems and network infrastructure
>that are used to keep mailman3 humming. I've tried about 7 different
>installation walkthroughs (there are no recent ones on Youtube by the
>way, in case anyone wants to seize that opportunity!), and the good
>guides provide ways to check each stage to try to help you a bit on
>that front.
>
>Nonetheless, I feel stuck and thought I'd ask the simple question...
>for a completely basic, barebones new installation, what's the easiest
>way to get a mailman3 installation up-and running? (e.g. Which server
>provider? Which operating system and version? Docker or otherwise?)
>
>Any pointers highly appreciated. Google Groups is clearly on its way
>out, as it no longer allows for people to easily join groups by sending
>an email or clicking a link, so that should be a big opportunity for
>mailman3 to step up and help give those mailing list migrants a new
>home... which is what we're looking for. We're just not quite as smart
>as you guys. ;-) _______________________________________________
>Mailman-users mailing list -- mailman-users(a)mailman3.org To unsubscribe
>send an email to mailman-users-leave(a)mailman3.org
>https://lists.mailman3.org/mailman3/lists/mailman-users.mailman3.org/
_______________________________________________
Mailman-users mailing list -- mailman-users(a)mailman3.org To unsubscribe send an email to mailman-users-leave(a)mailman3.org https://lists.mailman3.org/mailman3/lists/mailman-users.mailman3.org/
4 years, 9 months

Re: Confirmation emails to Users has wrong domain name (example.com!)
by Odhiambo Washington
On Thu, Sep 30, 2021 at 4:09 PM Abhilash Raj <maxking(a)asynchronous.in>
wrote:
>
>
> On Thu, Sep 30, 2021, at 2:20 AM, Odhiambo Washington wrote:
> > On Thu, Sep 30, 2021 at 1:59 AM Abhilash Raj <maxking(a)asynchronous.in>
> > wrote:
> >
> >>
> >>
> >> > On Sep 29, 2021, at 2:34 PM, Odhiambo Washington <odhiambo(a)gmail.com>
> >> wrote:
> >> >
> >> > On Wed, Sep 29, 2021 at 8:31 PM Mark Sapiro <mark(a)msapiro.net> wrote:
> >> >
> >> >> On 9/29/21 9:50 AM, Odhiambo Washington wrote:
> >> >>> 1. Confirmation emails to Users has wrong domain name (example.com
> !)
> >> >>> <https://docs.mailman3.org/en/latest/faq.html#id1>
> >> >>> <
> >> >>
> >>
> https://docs.mailman3.org/en/latest/faq.html#confirmation-emails-to-users-h…
> >> >>>
> >> >>>
> >> >>> This happens when your reverse (SSL) proxy isn’t setting up the
> correct
> >> >>> headers when proxying requests. Fix this by setting the right
> >> >>> proxy_set_header directives:
> >> >> ...
> >> >>> How is this supposed to be mitigated in Apache when using WSGI?
> >> >>>
> >> >>> My config:
> >> >>>
> >> >>> WSGIDaemonProcess hyperkitty threads=25
> python-path=/usr/local/mailman
> >> >>> user=mailman group=mailman
> >> >>> WSGIPythonHome "/usr/local"
> >> >>> WSGIProcessGroup hyperkitty
> >> >>
> >> >>
> >> >> You are using mod_wsgi and not proxying at all, so this is not
> relevant
> >> >> in your case.
> >> >>
> >> >> Are you actually seeing this issue? If so, it might be related to
> >> >>
> >> >>
> >>
> https://docs.mailman3.org/en/latest/faq.html#the-domain-name-displayed-in-h…
> >> >>
> >> >
> >> > My issue is related to this, but the documentation referred to is not
> for
> >> > the faint-hearted!
> >> > I can't make head or tails of it.
> >>
> >> Click on “Domain” in Postorius from the top bar, which should take you
> to
> >> the Domains page.
> >>
> >> For your domain (in the “Mail Host” column), see the corresponding “Web
> >> Host” column, it should look something like:
> >>
> >> lists.mailman3.org (lists.mailman3.org)
> >> (Edit)
> >> SITE_ID = 1
> >>
> >
> > Mine looks different, slightly. But there is no example.com at all.
> >
> > [image: Abhilash.png]
> >
> >
> >
> >>
> >> on a new-ish version of Postorius.
> >>
> >
> > I have the newest versions of everything, having installed only
> yesterday.
> >
> >
> >>
> >> If it doesn’t show the right values and instead shows “example.com” for
> >> you, click on the “Edit” link, which will take
> >> you to a page that will allow you to edit both the values.
> >>
> >
> > It shows the right values, but with "SITE_ID = 2". In my
> settings_local.py
> > I have SITE_ID = 1.
> > I suppose the example.com is the one tied to SITE_ID = 1 and that is
> what I
> > have in my settings_local.py.
>
> That is most likely what is happening.
>
> > Should I edit my settings_local.py?
>
> Yes, please update it to have SITE_ID = 2 to correspond to the site you
> want and restart.
I did this, but there is still a problem: The hyperkitty URL still shows
example.com.
Maybe I need to re-import the database to clear this?
--
Best regards,
Odhiambo WASHINGTON,
Nairobi,KE
+254 7 3200 0004/+254 7 2274 3223
"Oh, the cruft.", egrep -v '^$|^.*#' :-)
4 years

Re: How to configure mailman3-web
by Mark Sapiro
On 6/14/22 10:19, robert.winkler(a)bioprocess.org wrote:
> Hi, I just installed mailman3-web on my Ubuntu 20.04 LTS web server.
By Mailman3-web, I assume you mean the Debian/Ubuntu package. If so,
your primary support resources are Ubuntu and Debian.
> Port 8001 is open, the service is running:
>
> root@localhost:/etc/mailman3# systemctl status mailman3-web.service
> ● mailman3-web.service - Mailman3-web uWSGI service
> Loaded: loaded (/lib/systemd/system/mailman3-web.service; enabled; vendor preset: enabled)
> Active: active (running) since Tue 2022-06-14 17:05:06 UTC; 47s ago
> Docs: file:///usr/share/doc/mailman3-web/README.rst
> Main PID: 30135 (uwsgi)
> Status: "uWSGI is ready"
> Tasks: 10 (limit: 2306)
> Memory: 147.7M
> CGroup: /system.slice/mailman3-web.service
> ├─30135 /usr/bin/uwsgi --plugin python3 --ini /etc/mailman3/uwsgi.ini
> ├─30152 /usr/bin/uwsgi --plugin python3 --ini /etc/mailman3/uwsgi.ini
> ├─30153 /bin/sh -c python3 manage.py qcluster
> ├─30155 python3 manage.py qcluster
> ├─30158 python3 manage.py qcluster
> ├─30159 python3 manage.py qcluster
> ├─30160 python3 manage.py qcluster
> ├─30161 python3 manage.py qcluster
> └─30162 python3 manage.py qcluster
>
> Jun 14 17:05:05 localhost systemd[1]: Starting Mailman3-web uWSGI service...
> Jun 14 17:05:05 localhost uwsgi[30135]: [uWSGI] getting INI configuration from /etc/mailman3/uwsgi.ini
> Jun 14 17:05:06 localhost systemd[1]: Started Mailman3-web uWSGI service.
>
> in /etc/mailman3/mailman-web.py I changed localhost for my domain:port:
>
> MAILMAN_REST_API_URL = 'http://meteomex.com:8001'
> POSTORIUS_TEMPLATE_BASE_URL = 'http://meteomex.com:8001/mailman3/
>
> and restarted the service.
>
> on the server side, it looks fine, the mailman3 DB in postgresql exists.
>
> However, I cannot access the web interface, trying, e.g.
> http://meteomex.com:8001/mailman3/
> 'http://meteomex.com/mailman3
> 'http://meteomex.com:8001
>
> anything I am missing? E.g. concerning the Apache config?
You should not be accessing port 8001 directly. Mailman core's REST API
listens on port 8001 and Postorius is the one that accesses that API.
uWSGI normally listens on port 8000 and Apache proxies to uWSGI on that
port. What happens when you go to http://meteomex.com/mailman3?
In order to say more, we would probably need to see your uWSGI
configuration and the relevant parts of your Apache configuration
--
Mark Sapiro <mark(a)msapiro.net> The highway is for gamblers,
San Francisco Bay Area, California better use your sense - B. Dylan
3 years, 4 months

Re: Trouble Installing Mailman3
by Mark Sapiro
On 6/12/25 12:44, Henry Hartley via Mailman-users wrote:
>
> Here's what I mean when I say I'm doing this "in venv"
>
> I've become the mailman user: sudo su - mailman
> The .bashrc for that user includes: source /opt/mailman/venv/bin/activate
> The prompt has (venv) at the left end of it: (venv) mailman@wz-prd-tpmd-1:~$
So your venv is active. That is good.
> All pip commands have been run in this state. I did first install setuptools with apt install python3-setuptools and that installed version 68.1.2-2ubuntu1.2.
Which installed it in some /usr/<maybe local
here>/lib/pythonxx/dist-packages or maybe site-packages directory which
is probably not goint to be consulted by the python in your venv.
> Note that I'm still not sure the firewall is completely out of the picture, since I do have to include the --trusted-host and --proxy options. Some things install, though, so I think that's OK.
>
> When I do this at the (venv) prompt, asking to install both setuptools and mailman-web:
>
> pip install --proxy http://webproxyta.westat.com:3128 --trusted-host pypi.org setuptools mailman-web
>
> The first line of the output is:
>
> Requirement already satisfied: setuptools in ./venv/lib/python3.12/site-packages (80.9.0)
So setuptools 80.9.0 is installed in your venv which is good.
> And that's followed by downloading (or using a cached version) of 11 items before I get the subprocess error.
>
> (venv) mailman@wz-prd-tpmd-1:~$ /opt/mailman/venv/bin/pip install --proxy http://webproxyta.westat.com:3128 --trusted-host pypi.org setuptools mailman-web
> Requirement already satisfied: setuptools in ./venv/lib/python3.12/site-packages (80.9.0)
> Collecting mailman-web
> Downloading mailman_web-0.0.9-py3-none-any.whl.metadata (3.2 kB)
> Collecting django<4.3,>=4.0 (from mailman-web)
> Downloading django-4.2.23-py3-none-any.whl.metadata (4.2 kB)
> Collecting hyperkitty (from mailman-web)
> Downloading hyperkitty-1.3.12-py3-none-any.whl.metadata (3.6 kB)
> Collecting postorius (from mailman-web)
> Downloading postorius-1.3.13-py3-none-any.whl.metadata (2.9 kB)
> Collecting whoosh (from mailman-web)
> Downloading Whoosh-2.7.4-py2.py3-none-any.whl.metadata (3.1 kB)
> Collecting asgiref<4,>=3.6.0 (from django<4.3,>=4.0->mailman-web)
> Downloading asgiref-3.8.1-py3-none-any.whl.metadata (9.3 kB)
> Collecting sqlparse>=0.3.1 (from django<4.3,>=4.0->mailman-web)
> Downloading sqlparse-0.5.3-py3-none-any.whl.metadata (3.9 kB)
> Collecting django-compressor>=1.3 (from hyperkitty->mailman-web)
> Downloading django_compressor-4.5.1-py2.py3-none-any.whl.metadata (5.0 kB)
> Collecting django-extensions>=1.3.7 (from hyperkitty->mailman-web)
> Downloading django_extensions-4.1-py3-none-any.whl.metadata (6.1 kB)
> Collecting django-gravatar2>=1.0.6 (from hyperkitty->mailman-web)
> Downloading django_gravatar2-1.4.5-py2.py3-none-any.whl.metadata (4.3 kB)
> Collecting django-haystack>=2.8.0 (from hyperkitty->mailman-web) > Downloading django_haystack-3.3.0.tar.gz (467 kB)
> ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 467.3/467.3 kB 22.3 MB/s eta 0:00:00
The above is collecting mailman-web and its dependencies.
> Installing build dependencies ... error
> error: subprocess-exited-with-error
>
> × pip subprocess to install build dependencies did not run successfully.
> │ exit code: 1
> ╰─> [2 lines of output]
> ERROR: Could not find a version that satisfies the requirement setuptools>=61.2 (from versions: none)
> ERROR: No matching distribution found for setuptools>=61.2
> [end of output]
>
> note: This error originates from a subprocess, and is likely not a problem with pip.
> error: subprocess-exited-with-error
>
> × pip subprocess to install build dependencies did not run successfully.
> │ exit code: 1
> ╰─> See above for output.
>
> note: This error originates from a subprocess, and is likely not a problem with pip.
And this is all from a pip subprocess which is trying to build install
build dependencies. I.e., this error is not necessarily related to
django-haystack or any other specific package, but is saying it can't
find a setuptools package to satisfy the build requirements.
This in turn may be that the subprocess doesn't see your --proxy option.
I think the issue may be that normally pip installs build requirements
in an isolated temporary directory so as not to create potential
conflicts with installed packages. See
<https://pip.pypa.io/en/stable/reference/build-system/pyproject-toml/#build-…>.
Specifying --no-build-isolation on the pip command will disable this.
See
<https://pip.pypa.io/en/stable/cli/pip_install/#cmdoption-no-build-isolation>.
If you specify --no-build-isolation on the pip command, it should use
setuptools and wheel from your venv.
--
Mark Sapiro <mark(a)msapiro.net> The highway is for gamblers,
San Francisco Bay Area, California better use your sense - B. Dylan
4 months, 1 week

Re: Hacking attempts?
by Lists
Hi Tim,
Yes, we use fail2ban already. I just wanted to check that this is actually being caused solely by the would be hackers and the “error” isn’t indicative of something we’ve configured wrong within MM3?
Also, this error doesn’t appear in the MM or Apache logs, it just gets emailed, so I am going to have to figure out how to turn on the appropriate logging in order to get fail2ban to monitor it. Any pointers in this regard would be gratefully received.
Thanks,
Chris
> On 14 Jul 2022, at 13:09, Tim Cutts <tim(a)thecutts.org> wrote:
>
> You could use an application like fail2ban to watch your mailman/web logs and automatically firewall off attacking IP addresses which cause a lot of these errors in a defined window of time. This application is independent from mailman, and you can use it to protect against all kinds of brute force attacks. Ssh, web, mail - anything that creates a log file recording errors from remote IP addresses.
>
> Just be careful when configuring it for remote servers so you don’t saw off the branch you’re sitting on…. I run a mail server for my family, and on one occasion a family member repeatedly got her password wrong which caused fail2ban to lock all of us out because it blocked our home NAT address, and I had to use my mobile phone to unblock us. :-)
>
> Tim
>
>> On 14 Jul 2022, at 08:29, Lists via Mailman-users <mailman-users(a)mailman3.org <mailto:mailman-users@mailman3.org>> wrote:
>>
>> Hi,
>>
>> We are seeing thousands of these emails every day, looks like someone is trying to hack our Mailman3 but would appreciate someone with more knowledge of MM3 to confirm.
>>
>> Is this a problem with our setup? i.e. the “Internal Server Error” bit, or are the hackers just sending bad data that is causing the error? also how do we stop/block this?
>>
>> TIA and here is a typical email:
>>
>>
>> Subject: [Django] ERROR (EXTERNAL IP): Internal Server Error: /mailman3/accounts/fedora/login/
>>
>> Internal Server Error: /mailman3/accounts/fedora/login/
>>
>> TypeError at /accounts/fedora/login/
>> _openid_consumer() missing 2 required positional arguments: 'provider' and 'endpoint'
>>
>> Request Method: GET
>> Request URL: https://mailman.ardc.net/mailman3/accounts/fedora/login/?process=login&next… <https://mailman.ardc.net/mailman3/accounts/fedora/login/?process=login&next…><https://mailman.ardc.net/mailman3/accounts/fedora/login/?process=login&next… <https://mailman.ardc.net/mailman3/accounts/fedora/login/?process=login&next…>>
>> Django Version: 2.2.26
>> Python Executable: /usr/bin/uwsgi-core
>> Python Version: 3.9.2
>> Python Path: ['.', '', '/usr/lib/python39.zip', '/usr/lib/python3.9', '/usr/lib/python3.9/lib-dynload', '/usr/local/lib/python3.9/dist-packages', '/usr/lib/python3/dist-packages', '/usr/lib/python3.9/dist-packages']
>> Server time: Thu, 14 Jul 2022 02:34:04 -0400
>> Installed Applications:
>> ('hyperkitty',
>> 'postorius',
>> 'django_mailman3',
>> 'django.contrib.admin',
>> 'django.contrib.auth',
>> 'django.contrib.contenttypes',
>> 'django.contrib.sessions',
>> 'django.contrib.sites',
>> 'django.contrib.messages',
>> 'django.contrib.staticfiles',
>> 'rest_framework',
>> 'django_gravatar',
>> 'compressor',
>> 'haystack',
>> 'django_extensions',
>> 'django_q',
>> 'allauth',
>> 'allauth.account',
>> 'allauth.socialaccount',
>> 'django_mailman3.lib.auth.fedora')
>> Installed Middleware:
>> ('django.contrib.sessions.middleware.SessionMiddleware',
>> 'django.middleware.common.CommonMiddleware',
>> 'django.middleware.csrf.CsrfViewMiddleware',
>> 'django.middleware.locale.LocaleMiddleware',
>> 'django.contrib.auth.middleware.AuthenticationMiddleware',
>> 'django.contrib.messages.middleware.MessageMiddleware',
>> 'django.middleware.clickjacking.XFrameOptionsMiddleware',
>> 'django.middleware.security.SecurityMiddleware',
>> 'django_mailman3.middleware.TimezoneMiddleware',
>> 'postorius.middleware.PostoriusMiddleware')
>>
>>
>> Traceback:
>>
>> File "/usr/lib/python3/dist-packages/django/core/handlers/exception.py" in inner
>> 34. response = get_response(request)
>>
>> File "/usr/lib/python3/dist-packages/django/core/handlers/base.py" in _get_response
>> 115. response = self.process_exception_by_middleware(e, request)
>>
>> File "/usr/lib/python3/dist-packages/django/core/handlers/base.py" in _get_response
>> 113. response = wrapped_callback(request, *callback_args, **callback_kwargs)
>>
>> File "/usr/lib/python3/dist-packages/django/views/generic/base.py" in view
>> 71. return self.dispatch(request, *args, **kwargs)
>>
>> File "/usr/lib/python3/dist-packages/django/views/generic/base.py" in dispatch
>> 97. return handler(request, *args, **kwargs)
>>
>> File "/usr/lib/python3/dist-packages/django_mailman3/lib/auth/fedora/views.py" in get
>> 56. return self.post(request, *args, **kwargs)
>>
>> File "/usr/lib/python3/dist-packages/django_mailman3/lib/auth/fedora/views.py" in post
>> 67. client = _openid_consumer(request)
>>
>> Exception Type: TypeError at /accounts/fedora/login/
>> Exception Value: _openid_consumer() missing 2 required positional arguments: 'provider' and 'endpoint'
>> Request information:
>> USER: AnonymousUser
>>
>> GET:
>> process = 'login'
>> next = '/mailman3/hyperkitty/list/44net(a)mailman.ampr.org <mailto:mailman3/hyperkitty/list/44net@mailman.ampr.org><mailto:mailman3/hyperkitty/list/44net@mailman.ampr.org <mailto:mailman3/hyperkitty/list/44net@mailman.ampr.org>>/message/O5Z2YZBJZXFPH2ACAORN6BST7B2S3M3P/'
>>
>> POST: No POST data
>>
>> FILES: No FILES data
>>
>> COOKIES: No cookie data
>>
>> META:
>> CONTEXT_DOCUMENT_ROOT = '/var/www/html'
>> CONTEXT_PREFIX = ''
>> DOCUMENT_ROOT = '/var/www/html'
>> GATEWAY_INTERFACE = 'CGI/1.1'
>> HTTPS = 'on'
>> HTTP_ACCEPT = 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'
>> HTTP_ACCEPT_ENCODING = 'gzip,deflate'
>> HTTP_CONNECTION = 'Keep-Alive'
>> HTTP_HOST = 'mailman.ardc.net <http://mailman.ardc.net/> <http://mailman.ardc.net/ <http://mailman.ardc.net/>>'
>> HTTP_USER_AGENT = 'Mozilla/5.0 (compatible; BLEXBot/1.0; +http://webmeup-crawler.com/ <http://webmeup-crawler.com/> <http://webmeup-crawler.com/ <http://webmeup-crawler.com/>>)'
>> PATH = '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
>> PATH_INFO = '/accounts/fedora/login/'
>> QUERY_STRING = 'process=login&next=/mailman3/hyperkitty/list/44net(a)mailman.ampr.org <mailto:process=login&next=/mailman3/hyperkitty/list/44net@mailman.ampr.org><mailto:process=login&next=/mailman3/hyperkitty/list/44net@mailman.ampr.org <mailto:process=login&next=/mailman3/hyperkitty/list/44net@mailman.ampr.org>>/message/O5Z2YZBJZXFPH2ACAORN6BST7B2S3M3P/'
>> REMOTE_ADDR = '157.90.177.212'
>> REMOTE_PORT = '63384'
>> REQUEST_METHOD = 'GET'
>> REQUEST_SCHEME = 'https'
>> REQUEST_URI = '/mailman3/accounts/fedora/login/?process=login&next=/mailman3/hyperkitty/list/44net(a)mailman.ampr.org <mailto:mailman3/accounts/fedora/login/?process=login&next=/mailman3/hyperkitty/list/44net@mailman.ampr.org><mailto:mailman3/accounts/fedora/login/?process=login&next=/mailman3/hyperkitty/list/44net@mailman.ampr.org <mailto:mailman3/accounts/fedora/login/?process=login&next=/mailman3/hyperkitty/list/44net@mailman.ampr.org>>/message/O5Z2YZBJZXFPH2ACAORN6BST7B2S3M3P/'
>> SCRIPT_FILENAME = 'proxy:uwsgi://localhost//accounts/fedora/login/' <uwsgi://localhost//accounts/fedora/login/'><uwsgi://localhost//accounts/fedora/login/' <uwsgi://localhost//accounts/fedora/login/'>>
>> SCRIPT_NAME = '/mailman3'
>> SERVER_ADDR = '44.1.1.29'
>> SERVER_ADMIN = 'postmaster(a)ardc.net <mailto:postmaster@ardc.net> <mailto:postmaster@ardc.net <mailto:postmaster@ardc.net>>'
>> SERVER_NAME = 'mailman.ardc.net <http://mailman.ardc.net/> <http://mailman.ardc.net/ <http://mailman.ardc.net/>>'
>> SERVER_PORT = '443'
>> SERVER_PROTOCOL = 'HTTP/1.1'
>> SERVER_SIGNATURE = '<address>Apache/2.4.53 (Debian) Server at mailman.ardc.net <http://mailman.ardc.net/><http://mailman.ardc.net/ <http://mailman.ardc.net/>> Port 443</address>\n'
>> SERVER_SOFTWARE = 'Apache/2.4.53 (Debian)'
>> SSL_TLS_SNI = 'mailman.ardc.net <http://mailman.ardc.net/> <http://mailman.ardc.net/ <http://mailman.ardc.net/>>'
>> uwsgi.core = 1
>> uwsgi.node = b'mailman'
>> uwsgi.version = b'2.0.19.1-debian'
>> wsgi.errors = <_io.TextIOWrapper name=2 mode='w' encoding='UTF-8'>
>> wsgi.file_wrapper = ''
>> wsgi.input = <uwsgi._Input object at 0x7f8e0b4a0410>
>> wsgi.multiprocess = False
>> wsgi.multithread = True
>> wsgi.run_once = False
>> wsgi.url_scheme = 'https'
>> wsgi.version = '(1, 0)'
>>
>> Settings:
>> Using settings module settings
>> ABSOLUTE_URL_OVERRIDES = {}
>> ACCOUNT_AUTHENTICATION_METHOD = 'username_email'
>> ACCOUNT_DEFAULT_HTTP_PROTOCOL = 'https'
>> ACCOUNT_EMAIL_REQUIRED = True
>> ACCOUNT_EMAIL_VERIFICATION = 'mandatory'
>> ACCOUNT_UNIQUE_EMAIL = True
>> ADMINS = "(('Mailman Suite Admin', 'postmaster(a)ardc.net <mailto:postmaster@ardc.net><mailto:postmaster@ardc.net <mailto:postmaster@ardc.net>>'),)"
>> ALLOWED_HOSTS = ['*']
>> APPEND_SLASH = True
>> AUTHENTICATION_BACKENDS = "('django.contrib.auth.backends.ModelBackend', 'allauth.account.auth_backends.AuthenticationBackend')"
>> AUTH_PASSWORD_VALIDATORS = '********************'
>> AUTH_USER_MODEL = 'auth.User'
>> BASE_DIR = '/usr/share/mailman3-web'
>> CACHES = {'default': {'BACKEND': 'django.core.cache.backends.locmem.LocMemCache'}}
>> CACHE_MIDDLEWARE_ALIAS = 'default'
>> CACHE_MIDDLEWARE_KEY_PREFIX = '********************'
>> CACHE_MIDDLEWARE_SECONDS = 600
>> COMPRESSORS = {'css': 'compressor.css.CssCompressor', 'js': 'compressor.js.JsCompressor'}
>> COMPRESS_CACHEABLE_PRECOMPILERS = '()'
>> COMPRESS_CACHE_BACKEND = 'default'
>> COMPRESS_CACHE_KEY_FUNCTION = '********************'
>> COMPRESS_CLEAN_CSS_ARGUMENTS = ''
>> COMPRESS_CLEAN_CSS_BINARY = 'cleancss'
>> COMPRESS_CLOSURE_COMPILER_ARGUMENTS = ''
>> COMPRESS_CLOSURE_COMPILER_BINARY = 'java -jar compiler.jar'
>> COMPRESS_CSS_HASHING_METHOD = 'mtime'
>> COMPRESS_DATA_URI_MAX_SIZE = 1024
>> COMPRESS_DEBUG_TOGGLE = None
>> COMPRESS_ENABLED = True
>> COMPRESS_FILTERS = {'css': ['compressor.filters.css_default.CssAbsoluteFilter'], 'js': ['compressor.filters.jsmin.JSMinFilter']}
>> COMPRESS_JINJA2_GET_ENVIRONMENT = <function CompressorConf.JINJA2_GET_ENVIRONMENT at 0x7f8e17d7a670>
>> COMPRESS_MINT_DELAY = 30
>> COMPRESS_MTIME_DELAY = 10
>> COMPRESS_OFFLINE = True
>> COMPRESS_OFFLINE_CONTEXT = {'STATIC_URL': '/mailman3/static/'}
>> COMPRESS_OFFLINE_MANIFEST = 'manifest.json'
>> COMPRESS_OFFLINE_TIMEOUT = 31536000
>> COMPRESS_OUTPUT_DIR = 'CACHE'
>> COMPRESS_PARSER = 'compressor.parser.AutoSelectParser'
>> COMPRESS_PRECOMPILERS = '()'
>> COMPRESS_REBUILD_TIMEOUT = 2592000
>> COMPRESS_ROOT = '/var/lib/mailman3/web/static'
>> COMPRESS_STORAGE = 'compressor.storage.CompressorFileStorage'
>> COMPRESS_TEMPLATE_FILTER_CONTEXT = {'STATIC_URL': '/mailman3/static/'}
>> COMPRESS_URL = '/mailman3/static/'
>> COMPRESS_URL_PLACEHOLDER = '/__compressor_url_placeholder__/'
>> COMPRESS_VERBOSE = False
>> COMPRESS_YUGLIFY_BINARY = 'yuglify'
>> COMPRESS_YUGLIFY_CSS_ARGUMENTS = '--terminal'
>> COMPRESS_YUGLIFY_JS_ARGUMENTS = '--terminal'
>> COMPRESS_YUI_BINARY = 'java -jar yuicompressor.jar'
>> COMPRESS_YUI_CSS_ARGUMENTS = ''
>> COMPRESS_YUI_JS_ARGUMENTS = ''
>> CSRF_COOKIE_AGE = 31449600
>> CSRF_COOKIE_DOMAIN = None
>> CSRF_COOKIE_HTTPONLY = False
>> CSRF_COOKIE_NAME = 'csrftoken'
>> CSRF_COOKIE_PATH = '/'
>> CSRF_COOKIE_SAMESITE = 'Lax'
>> CSRF_COOKIE_SECURE = False
>> CSRF_FAILURE_VIEW = 'django.views.csrf.csrf_failure'
>> CSRF_HEADER_NAME = 'HTTP_X_CSRFTOKEN'
>> CSRF_TRUSTED_ORIGINS = []
>> CSRF_USE_SESSIONS = False
>> DATABASES = {'default': {'ENGINE': 'django.db.backends.mysql', 'NAME': 'mailman', 'USER': 'mailman', 'PASSWORD': '********************', 'HOST': ‘X.X.X.X', 'PORT': '', 'OPTIONS': {'init_command': "SET sql_mode='STRICT_TRANS_TABLES'", 'charset': 'utf8mb4'}, 'ATOMIC_REQUESTS': False, 'AUTOCOMMIT': True, 'CONN_MAX_AGE': 0, 'TIME_ZONE': None, 'TEST': {'CHARSET': None, 'COLLATION': None, 'NAME': None, 'MIRROR': None}}}
>> DATABASE_ROUTERS = []
>> DATA_UPLOAD_MAX_MEMORY_SIZE = 2621440
>> DATA_UPLOAD_MAX_NUMBER_FIELDS = 1000
>> DATETIME_FORMAT = 'N j, Y, P'
>> DATETIME_INPUT_FORMATS = ['%Y-%m-%d %H:%M:%S', '%Y-%m-%d %H:%M:%S.%f', '%Y-%m-%d %H:%M', '%Y-%m-%d', '%m/%d/%Y %H:%M:%S', '%m/%d/%Y %H:%M:%S.%f', '%m/%d/%Y %H:%M', '%m/%d/%Y', '%m/%d/%y %H:%M:%S', '%m/%d/%y %H:%M:%S.%f', '%m/%d/%y %H:%M', '%m/%d/%y']
>> DATE_FORMAT = 'N j, Y'
>> DATE_INPUT_FORMATS = ['%Y-%m-%d', '%m/%d/%Y', '%m/%d/%y', '%b %d %Y', '%b %d, %Y', '%d %b %Y', '%d %b, %Y', '%B %d %Y', '%B %d, %Y', '%d %B %Y', '%d %B, %Y']
>> DEBUG = False
>> DEBUG_PROPAGATE_EXCEPTIONS = False
>> DECIMAL_SEPARATOR = '.'
>> DEFAULT_CHARSET = 'utf-8'
>> DEFAULT_CONTENT_TYPE = 'text/html'
>> DEFAULT_EXCEPTION_REPORTER_FILTER = 'django.views.debug.SafeExceptionReporterFilter'
>> DEFAULT_FILE_STORAGE = 'django.core.files.storage.FileSystemStorage'
>> DEFAULT_FROM_EMAIL = 'postorius(a)mailman.ardc.net <mailto:postorius@mailman.ardc.net><mailto:postorius@mailman.ardc.net <mailto:postorius@mailman.ardc.net>>'
>> DEFAULT_INDEX_TABLESPACE = ''
>> DEFAULT_TABLESPACE = ''
>> DISALLOWED_USER_AGENTS = []
>> EMAILNAME = 'mailman.ardc.net <http://mailman.ardc.net/> <http://mailman.ardc.net/ <http://mailman.ardc.net/>>'
>> EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
>> EMAIL_HOST = 'localhost'
>> EMAIL_HOST_PASSWORD = '********************'
>> EMAIL_HOST_USER = ''
>> EMAIL_PORT = 25
>> EMAIL_SSL_CERTFILE = None
>> EMAIL_SSL_KEYFILE = '********************'
>> EMAIL_SUBJECT_PREFIX = '[Django] '
>> EMAIL_TIMEOUT = None
>> EMAIL_USE_LOCALTIME = False
>> EMAIL_USE_SSL = False
>> EMAIL_USE_TLS = False
>> FILE_CHARSET = 'utf-8'
>> FILE_UPLOAD_DIRECTORY_PERMISSIONS = None
>> FILE_UPLOAD_HANDLERS = ['django.core.files.uploadhandler.MemoryFileUploadHandler', 'django.core.files.uploadhandler.TemporaryFileUploadHandler']
>> FILE_UPLOAD_MAX_MEMORY_SIZE = 2621440
>> FILE_UPLOAD_PERMISSIONS = None
>> FILE_UPLOAD_TEMP_DIR = None
>> FILTER_VHOST = False
>> FIRST_DAY_OF_WEEK = 0
>> FIXTURE_DIRS = []
>> FORCE_SCRIPT_NAME = None
>> FORMAT_MODULE_PATH = None
>> FORM_RENDERER = 'django.forms.renderers.DjangoTemplates'
>> HAYSTACK_CONNECTIONS = {'default': {'ENGINE': 'haystack.backends.whoosh_backend.WhooshEngine', 'PATH': '/var/lib/mailman3/web/fulltext_index'}}
>> HOSTNAME = 'localhost.local'
>> IGNORABLE_404_URLS = []
>> INSTALLED_APPS = "('hyperkitty', 'postorius', 'django_mailman3', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.messages', 'django.contrib.staticfiles', 'rest_framework', 'django_gravatar', 'compressor', 'haystack', 'django_extensions', 'django_q', 'allauth', 'allauth.account', 'allauth.socialaccount', 'django_mailman3.lib.auth.fedora')"
>> INTERNAL_IPS = []
>> LANGUAGES = [('af', 'Afrikaans'), ('ar', 'Arabic'), ('ast', 'Asturian'), ('az', 'Azerbaijani'), ('bg', 'Bulgarian'), ('be', 'Belarusian'), ('bn', 'Bengali'), ('br', 'Breton'), ('bs', 'Bosnian'), ('ca', 'Catalan'), ('cs', 'Czech'), ('cy', 'Welsh'), ('da', 'Danish'), ('de', 'German'), ('dsb', 'Lower Sorbian'), ('el', 'Greek'), ('en', 'English'), ('en-au', 'Australian English'), ('en-gb', 'British English'), ('eo', 'Esperanto'), ('es', 'Spanish'), ('es-ar', 'Argentinian Spanish'), ('es-co', 'Colombian Spanish'), ('es-mx', 'Mexican Spanish'), ('es-ni', 'Nicaraguan Spanish'), ('es-ve', 'Venezuelan Spanish'), ('et', 'Estonian'), ('eu', 'Basque'), ('fa', 'Persian'), ('fi', 'Finnish'), ('fr', 'French'), ('fy', 'Frisian'), ('ga', 'Irish'), ('gd', 'Scottish Gaelic'), ('gl', 'Galician'), ('he', 'Hebrew'), ('hi', 'Hindi'), ('hr', 'Croatian'), ('hsb', 'Upper Sorbian'), ('hu', 'Hungarian'), ('hy', 'Armenian'), ('ia', 'Interlingua'), ('id', 'Indonesian'), ('io', 'Ido'), ('is', 'Icelandic'), ('it', 'Italian'), ('ja', 'Japanese'), ('ka', 'Georgian'), ('kab', 'Kabyle'), ('kk', 'Kazakh'), ('km', 'Khmer'), ('kn', 'Kannada'), ('ko', 'Korean'), ('lb', 'Luxembourgish'), ('lt', 'Lithuanian'), ('lv', 'Latvian'), ('mk', 'Macedonian'), ('ml', 'Malayalam'), ('mn', 'Mongolian'), ('mr', 'Marathi'), ('my', 'Burmese'), ('nb', 'Norwegian Bokmål'), ('ne', 'Nepali'), ('nl', 'Dutch'), ('nn', 'Norwegian Nynorsk'), ('os', 'Ossetic'), ('pa', 'Punjabi'), ('pl', 'Polish'), ('pt', 'Portuguese'), ('pt-br', 'Brazilian Portuguese'), ('ro', 'Romanian'), ('ru', 'Russian'), ('sk', 'Slovak'), ('sl', 'Slovenian'), ('sq', 'Albanian'), ('sr', 'Serbian'), ('sr-latn', 'Serbian Latin'), ('sv', 'Swedish'), ('sw', 'Swahili'), ('ta', 'Tamil'), ('te', 'Telugu'), ('th', 'Thai'), ('tr', 'Turkish'), ('tt', 'Tatar'), ('udm', 'Udmurt'), ('uk', 'Ukrainian'), ('ur', 'Urdu'), ('vi', 'Vietnamese'), ('zh-hans', 'Simplified Chinese'), ('zh-hant', 'Traditional Chinese')]
>> LANGUAGES_BIDI = ['he', 'ar', 'fa', 'ur']
>> LANGUAGE_CODE = 'en-us'
>> LANGUAGE_COOKIE_AGE = None
>> LANGUAGE_COOKIE_DOMAIN = None
>> LANGUAGE_COOKIE_NAME = 'django_language'
>> LANGUAGE_COOKIE_PATH = '/'
>> LOCALE_PATHS = []
>> LOGGING = {'version': 1, 'disable_existing_loggers': False, 'filters': {'require_debug_false': {'()': 'django.utils.log.RequireDebugFalse'}}, 'handlers': {'mail_admins': {'level': 'ERROR', 'filters': ['require_debug_false'], 'class': 'django.utils.log.AdminEmailHandler'}, 'file': {'level': 'INFO', 'class': 'logging.handlers.RotatingFileHandler', 'filename': '/var/log/mailman3/web/mailman-web.log', 'formatter': 'verbose'}, 'console': {'class': 'logging.StreamHandler', 'formatter': 'simple'}}, 'loggers': {'django.request': {'handlers': ['mail_admins', 'file'], 'level': 'INFO', 'propagate': True}, 'django': {'handlers': ['file'], 'level': 'INFO', 'propagate': True}, 'hyperkitty': {'handlers': ['file'], 'level': 'INFO', 'propagate': True}, 'postorius': {'handlers': ['file'], 'level': 'INFO', 'propagate': True}}, 'formatters': {'verbose': {'format': '%(levelname)s %(asctime)s %(process)d %(name)s %(message)s'}, 'simple': {'format': '%(levelname)s %(message)s'}}}
>> LOGGING_CONFIG = 'logging.config.dictConfig'
>> LOGIN_REDIRECT_URL = 'list_index'
>> LOGIN_URL = 'account_login'
>> LOGOUT_REDIRECT_URL = None
>> LOGOUT_URL = 'account_logout'
>> MAILMAN_ARCHIVER_FROM = "('127.0.0.1', '::1', '10.4.16.129', '44.1.1.29')"
>> MAILMAN_ARCHIVER_KEY = '********************'
>> MAILMAN_REST_API_PASS = '********************'
>> MAILMAN_REST_API_URL = '********************'
>> MAILMAN_REST_API_USER = '********************'
>> MANAGERS = []
>> MEDIA_ROOT = ''
>> MEDIA_URL = ''
>> MESSAGE_STORAGE = 'django.contrib.messages.storage.fallback.FallbackStorage'
>> MESSAGE_TAGS = {40: 'danger'}
>> MIDDLEWARE = "('django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.middleware.locale.LocaleMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'django.middleware.security.SecurityMiddleware', 'django_mailman3.middleware.TimezoneMiddleware', 'postorius.middleware.PostoriusMiddleware')"
>> MIGRATION_MODULES = {}
>> MONTH_DAY_FORMAT = 'F j'
>> NUMBER_GROUPING = 0
>> PASSWORD_HASHERS = '********************'
>> PASSWORD_RESET_TIMEOUT_DAYS = '********************'
>> POSTORIUS_TEMPLATE_BASE_URL = 'http://localhost/mailman3/ <http://localhost/mailman3/><http://localhost/mailman3/ <http://localhost/mailman3/>>'
>> PREPEND_WWW = False
>> Q_CLUSTER = {'timeout': 300, 'save_limit': 100, 'orm': 'default', 'poll': 5}
>> ROOT_URLCONF = 'urls'
>> SECRET_KEY = '********************'
>> SECURE_BROWSER_XSS_FILTER = False
>> SECURE_CONTENT_TYPE_NOSNIFF = False
>> SECURE_HSTS_INCLUDE_SUBDOMAINS = False
>> SECURE_HSTS_PRELOAD = False
>> SECURE_HSTS_SECONDS = 0
>> SECURE_PROXY_SSL_HEADER = None
>> SECURE_REDIRECT_EXEMPT = []
>> SECURE_SSL_HOST = None
>> SECURE_SSL_REDIRECT = False
>> SERVER_EMAIL = 'root(a)mailman.ardc.net <mailto:root@mailman.ardc.net> <mailto:root@mailman.ardc.net <mailto:root@mailman.ardc.net>>'
>> SESSION_CACHE_ALIAS = 'default'
>> SESSION_COOKIE_AGE = 1209600
>> SESSION_COOKIE_DOMAIN = None
>> SESSION_COOKIE_HTTPONLY = True
>> SESSION_COOKIE_NAME = 'sessionid'
>> SESSION_COOKIE_PATH = '/'
>> SESSION_COOKIE_SAMESITE = 'Lax'
>> SESSION_COOKIE_SECURE = False
>> SESSION_ENGINE = 'django.contrib.sessions.backends.db'
>> SESSION_EXPIRE_AT_BROWSER_CLOSE = False
>> SESSION_FILE_PATH = None
>> SESSION_SAVE_EVERY_REQUEST = False
>> SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer'
>> SETTINGS_MODULE = 'settings'
>> SHORT_DATETIME_FORMAT = 'm/d/Y P'
>> SHORT_DATE_FORMAT = 'm/d/Y'
>> SIGNING_BACKEND = 'django.core.signing.TimestampSigner'
>> SILENCED_SYSTEM_CHECKS = []
>> SITE_ID = 1
>> SOCIALACCOUNT_PROVIDERS = {}
>> STATICFILES_DIRS = '()'
>> STATICFILES_FINDERS = "('django.contrib.staticfiles.finders.FileSystemFinder', 'django.contrib.staticfiles.finders.AppDirectoriesFinder', 'compressor.finders.CompressorFinder')"
>> STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.StaticFilesStorage'
>> STATIC_ROOT = '/var/lib/mailman3/web/static'
>> STATIC_URL = '/mailman3/static/'
>> TEMPLATES = [{'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [], 'APP_DIRS': True, 'OPTIONS': {'context_processors': ['django.template.context_processors.debug', 'django.template.context_processors.i18n', 'django.template.context_processors.media', 'django.template.context_processors.static', 'django.template.context_processors.tz', 'django.template.context_processors.csrf', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', 'django_mailman3.context_processors.common', 'hyperkitty.context_processors.common', 'postorius.context_processors.postorius']}}]
>> TEST_NON_SERIALIZED_APPS = []
>> TEST_RUNNER = 'django.test.runner.DiscoverRunner'
>> THOUSAND_SEPARATOR = ','
>> TIME_FORMAT = 'P'
>> TIME_INPUT_FORMATS = ['%H:%M:%S', '%H:%M:%S.%f', '%H:%M']
>> TIME_ZONE = 'UTC'
>> USE_I18N = True
>> USE_L10N = True
>> USE_THOUSAND_SEPARATOR = False
>> USE_TZ = True
>> USE_X_FORWARDED_HOST = True
>> USE_X_FORWARDED_PORT = False
>> WSGI_APPLICATION = 'wsgi.application'
>> X_FRAME_OPTIONS = 'SAMEORIGIN'
>> YEAR_MONTH_FORMAT = 'F Y’
>>
>>
>>
>>
>> _______________________________________________
>> Mailman-users mailing list -- mailman-users(a)mailman3.org <mailto:mailman-users@mailman3.org>
>> To unsubscribe send an email to mailman-users-leave(a)mailman3.org <mailto:mailman-users-leave@mailman3.org>
>> https://lists.mailman3.org/mailman3/lists/mailman-users.mailman3.org/ <https://lists.mailman3.org/mailman3/lists/mailman-users.mailman3.org/>
>
> _______________________________________________
> Mailman-users mailing list -- mailman-users(a)mailman3.org <mailto:mailman-users@mailman3.org>
> To unsubscribe send an email to mailman-users-leave(a)mailman3.org <mailto:mailman-users-leave@mailman3.org>
> https://lists.mailman3.org/mailman3/lists/mailman-users.mailman3.org/ <https://lists.mailman3.org/mailman3/lists/mailman-users.mailman3.org/>
3 years, 3 months

Django errors after deleting a thread
by peter@chubb.wattle.id.au
After deleting a thread via the web interface (because it's spam), I
get lots of messages from hyperkitty
E.g.
Internal Server Error: /hyperkitty/list/list@domain/top-threads
DoesNotExist at /hyperkitty/list/list@domain/top-threads
Thread matching query does not exist.
Request Method: GET
Request URL: https://example.com/hyperkitty/list/list@domain/top-threads
Django Version: 2.2.17
Python Executable: /usr/bin/uwsgi-core
Python Version: 3.8.6
Python Path: ['.', '', '/usr/lib/python38.zip', '/usr/lib/python3.8', '/usr/lib/python3.8/lib-dynload', '/usr/local/lib/python3.8/dist-packages', '/usr/lib/python3/dist-packages']
Server time: Wed, 25 Nov 2020 07:12:00 +1100
Installed Applications:
('hyperkitty',
'postorius',
'django_mailman3',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'django_gravatar',
'compressor',
'haystack',
'django_extensions',
'django_q',
'allauth',
'allauth.account',
'allauth.socialaccount')
Installed Middleware:
('django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.middleware.locale.LocaleMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.security.SecurityMiddleware',
'django_mailman3.middleware.TimezoneMiddleware',
'postorius.middleware.PostoriusMiddleware')
Traceback:
File "/usr/lib/python3/dist-packages/django/core/handlers/exception.py" in inner
34. response = get_response(request)
File "/usr/lib/python3/dist-packages/django/core/handlers/base.py" in _get_response
115. response = self.process_exception_by_middleware(e, request)
File "/usr/lib/python3/dist-packages/django/core/handlers/base.py" in _get_response
113. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/lib/python3/dist-packages/hyperkitty/lib/view_helpers.py" in inner
135. return func(request, *args, **kwargs)
File "/usr/lib/python3/dist-packages/hyperkitty/views/mlist.py" in overview_top_threads
220. 'threads': mlist.top_threads,
File "/usr/lib/python3/dist-packages/hyperkitty/models/mailinglist.py" in top_threads
168. return self.cached_values["top_threads"]()
File "/usr/lib/python3/dist-packages/hyperkitty/models/common.py" in __call__
59. return self.get_or_set(*args, **kwargs)
File "/usr/lib/python3/dist-packages/hyperkitty/models/mailinglist.py" in get_or_set
376. return [Thread.objects.get(pk=pk) for pk in thread_ids]
File "/usr/lib/python3/dist-packages/hyperkitty/models/mailinglist.py" in <listcomp>
376. return [Thread.objects.get(pk=pk) for pk in thread_ids]
File "/usr/lib/python3/dist-packages/django/db/models/manager.py" in manager_method
82. return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/usr/lib/python3/dist-packages/django/db/models/query.py" in get
406. raise self.model.DoesNotExist(
Exception Type: DoesNotExist at /hyperkitty/list/devel(a)sel4.systems/top-threads
Exception Value: Thread matching query does not exist.
Request information:
USER: AnonymousUser
GET: No GET data
POST: No POST data
FILES: No FILES data
COOKIES: No cookie data
4 years, 10 months

Re: FILTER_VHOST = True doesn't work fine with alias_domain
by Élodie BOSSIER
Thank you for your response Mark,
With Mailman 2.1, the lists were split on their webpage respectively.
How could I do same with Mailman 3.3.3 (Tom Sawyer) please ?
My domain table SQL have this result :
id, mail_host, description, alias_domain
1, ml.franceserv.fr, NULL, local.ml.franceserv.fr
2, ml.viticreation.fr, NULL, local.ml.viticreation.fr
mailinglist table SQL :
id, list_name, mail_host, list_id, ...
1, bar, ml.franceserv.fr, bar.ml.franceserv.fr, ...
2, viticreation, ml.viticreation.fr, viticreation.ml.viticreation.fr, ...
Can I do something ? A patch somewhere ? Shall I wait issues are solved
and how long approximatively please ?
Which don't reassure me is I can see old discussions about FILTER_VHOST
there are 2 years.
I can retrieve my own old question there are 2 years when I tried to
migrate from Mailman 2 to Mailman 3 :
https://lists.mailman3.org/archives/list/mailman-users@mailman3.org/thread/…
and in 2020 you told me it was working for you at this date. It's don't
reassure me to retrieve a problem I got there are 2 years.
I could set in production my Mailman 3 but the problem is my customers
won't understand why they can see the lists of others domains name ...
and not sure about the security ...
Thank you again.
Le 18/02/2022 à 00:33, Mark Sapiro a écrit :
> There are issues with FILTER_VHOST due to the fact that mailing lists
> do not have a web host attribute. This means when you go to HyperKitty
> or Postorius when FILTER_VHOST is True, we look up the domain record
> for the web host you are visiting and show you all the lists whose
> mail host matches the mail host for the web host domain. This has
> nothing to do with alias domains.
>
> What that means is if all your domains records have a unique mail
> host, FILTER_VHOST will work as you expect, but if multiple domains
> have the same mail host FILTER_VHOST will show you the lists for the
> current web host plus all those with a matching mail host.
>
> I.e. if in your case, the ml.franceserv.fr domain and the
> ml.viticreation.fr domain have the same mail host, FILTER_VHOST won't
> separate them. If they have different mail hosts FILTER_VHOST will
> separate them.
>
3 years, 8 months

Easiest way to install a new mailman3 deployment?
by ieso@johnwillson.com
So I've been trying for the last two weeks to get a new mailman3 server running on a virtualized server (any server), and I'm turning to this list after having failed many times and running out of holiday time.
I started trying a non-docker installation on Ubuntu 18.04 (https://docs.google.com/document/d/1xIcSsoNFp2nHi7r4eQys00s9a0k2sHhu1V5Plan…) , which got me the closest. Except I had a problem with inbound email only being triggered when it came from certain accounts. But that clearly wasn't good enough for production, so after many attempts to figure out where it was failing, I decided to turn to docker as a solution that should be cleaner.
A few attempts at doing a docker installation on digitalocean.com failed, which I realized might be due to it not routing private IP addresses, so I moved to AWS after checking that their VPC policy would fit mailman's docker requirements. I found a great but slightly outdated guide on how to do this (https://xiaoxing.us/2018/01/01/deploy-mailman-3-on-aws-using-docker/) By this point I knew enough to correct a number of places where the environment had changed since the procedure was written, but postorius still failed at the curl test.
The challenge for me has been the difficulty to know how to troubleshoot the different different systems and network infrastructure that are used to keep mailman3 humming. I've tried about 7 different installation walkthroughs (there are no recent ones on Youtube by the way, in case anyone wants to seize that opportunity!), and the good guides provide ways to check each stage to try to help you a bit on that front.
Nonetheless, I feel stuck and thought I'd ask the simple question... for a completely basic, barebones new installation, what's the easiest way to get a mailman3 installation up-and running? (e.g. Which server provider? Which operating system and version? Docker or otherwise?)
Any pointers highly appreciated. Google Groups is clearly on its way out, as it no longer allows for people to easily join groups by sending an email or clicking a link, so that should be a big opportunity for mailman3 to step up and help give those mailing list migrants a new home... which is what we're looking for. We're just not quite as smart as you guys. ;-)
4 years, 9 months

Re: Could not locate column in row for column 'user.id'
by Mark Sapiro
On 7/26/20 10:56 AM, Shashikanth Komandoor wrote:
> Hi Team,
>
> I am currently running Mailman 3 with version 3.3.1 and in built postfix
> version 2.10.1-6 on RHEL 7.5 in production environment from the past 2
> months almost.
>
> From the past few days, I found my server is responding to the users
> very slowly and throwing the Server Error page (of course getting the
> required page after multiple refreshes) for almost every click on the
> postorius pages (not yet observed on hyperkitty front end which in fact is
> not so important for me as of now).
>
> During that time, I observed in the mailman.log an error message saying
> "Could not locate column in row for column 'user.id'". The complete
> traceback log is attached with the mail. The error message is generated for
> almost all the lists and all the clicks.
I don't understand what's going on. I suspect some kind of database
corruption, but I don't know what.
The traceback indicates Mailman is getting the Members of a list and in
this process is trying to get the display_name for a member. The
member's subscriber attribute doesn't have a display_name so it is
trying to get is from the member's user attribute so it is trying to get
the user record for the member's email address via
IUserManager.get_user(). This in turn gets the Address record for the
email address and returns it's user attribute.
This leads to the
sqlalchemy.exc.NoSuchColumnError: "Could not locate column in row for
column 'user.id'"
error which I don't understand. There is no table with a 'user.id'
column. user.id refers to the id column in the user table which comes
from the user_id column in the address table which should be a reference
to the id column in the user table, not a reference to ay 'user.id' column.
What is your backend database and what is the structure of the address
table in that database. Have you done any kind of direct database query
that might have affected this?
--
Mark Sapiro <mark(a)msapiro.net> The highway is for gamblers,
San Francisco Bay Area, California better use your sense - B. Dylan
5 years, 2 months

Re: Hyperkitty 403 Forbidden Error
by Phil Thompson
On 07/08/2019 17:04, Abhilash Raj wrote:
> On Wed, Aug 7, 2019, at 8:41 AM, Phil Thompson wrote:
>> On 06/08/2019 09:48, Phil Thompson wrote:
>> > On 06/08/2019 03:38, Abhilash Raj wrote:
>> >> On Mon, Aug 5, 2019, at 10:06 AM, Phil Thompson wrote:
>> >>> I'm in the process of setting up mailman3. The only problem I seem to
>> >>> be
>> >>> having is getting Hyperkitty to archive messages. Rather than the
>> >>> authorisation problems people have previously asked about on the
>> >>> list, I
>> >>> am getting a 403 error...
>> >>>
>> >>> Aug 05 15:38:40 2019 (10229) HyperKitty failure on
>> >>> http://localhost/mailman3/hyperkitty/api/mailman/urls:
>> >>> <html><title>Forbidden</title><body>
>> >>> <h1>Access is forbidden</h1></body></html> (403)
>> >>> Aug 05 15:38:58 2019 (10222) HyperKitty failure on
>> >>> http://localhost/mailman3/hyperkitty/api/mailman/archive:
>> >>> <html><title>Forbidden</title><body>
>> >>> <h1>Access is forbidden</h1></body></html> (403)
>> >>>
>> >>> Any suggestions would be appreciated.
>> >>
>> >> How did you install Hyperkitty?
>> >
>> > On Ubuntu...
>> >
>> > apt-get install mailman3-full
>> >
>> >> You probably need to the set the API key correctly in both Core and
>> >> Hyperkitty.
>> >>
>> >> Have you looked at documentation here[1]?
>> >>
>> >> [1]:
>> >> https://hyperkitty.readthedocs.io/en/latest/install.html#connecting-to-mail…
>> >>
>> >> Note that the MAILMAN_ARCHIVER_KEY = "value" (this value should be in
>> >> quotes, single or double, doesn't matter) in your settings.py for Web
>> >> (Django) should be same as the `api_key : value` (without quotes here
>> >> in hyperkitty.cfg config file).
>> >
>> > That's all correct. I'm familiar with the authorisation issues that
>> > other people have had.
>> >
>> > The only thing I'm doing differently (as far as I am aware) is that
>> > I'm using a URL prefixed with /mailman3 which is stripped off in my
>> > nginx configuration...
>> >
>> > # mailman3.
>> > location /mailman3/ {
>> > uwsgi_pass unix:/run/mailman3/web/uwsgi.sock;
>> > include uwsgi_params;
>> > uwsgi_param SERVER_ADDR $server_addr;
>> > uwsgi_modifier1 30;
>> > uwsgi_param SCRIPT_NAME /mailman3;
>> > }
>> >
>> > location /mailman3/static {
>> > alias /var/lib/mailman3/web/static;
>> > }
>> >
>> > location /mailman3/static/favicon.ico {
>> > alias /var/lib/mailman3/web/static/postorius/img/favicon.ico;
>> > }
>> >
>> > ...but I don't see this affecting the mailman to Hyperkitty
>> > communication. Posting to lists and the Postorius and Hyperkitty
>> > frontends seem to work fine.
>>
>> I have now fixed the 403 error (by setting MAILMAN_ARCHIVER_FROM to my
>> public IP address). However I now get a 400 Bad Request error.
>>
>> I have traced this to the archive() function in
>> hyperkitty/views/mailman.py which is expect a POST but is actually
>> getting a GET, specifically...
>>
>> GET '/mailman3/hyperkitty/api/mailman/archive?key=...'
>>
>> ...which seems to be a fairly fundamental problem.
>>
>> Again, any suggestions would be welcome.
>
> It should be sending POST request to archive emails[1]. How did you
> grab the above request? Was it from logs?
Yes, I added DEBUG=True in mailman-web.py and captured the HTML from
mailman.log.
> Do you have anything else in the logs? There should be something in
> the Mailman Core or web logs should have something.
There's nothing useful in the core log.
There are 3 preceding entries in the web log...
GET /mailman3/hyperkitty/api/mailman/urls?mlist=...&key=...
GET /mailman3/hyperkitty/api/mailman/urls?mlist=...&msgid=...&key=...
GET /mailman3/hyperkitty/api/mailman/urls?mlist=...&msgid=...&key=...
There is one item in the spool directory.
These were all (apparently) successful. It seems odd that the last two
entries were identical.
Phil
6 years, 2 months