Is there any way to suppress the huge emails

I get these gigantic emails every time script kiddies hit my site. When they hit

 "GET /admin/index.html HTTP/1.1" 302 511 "-" "Mozilla/5.0 (compatible; GenomeCrawlerd/1.0; +https://www.nokia.com/genomecrawler)"

It handles it nicely and I guess they get a 302. But when they hit

"GET /admin/login/?next=/admin/index.html HTTP/1.1" 500 1125 "https://96.126.110.20/admin/index.html" "Mozilla/5.0 (compatible; GenomeCrawlerd/1.0; +https://www.nokia.com/genomecrawler)"

It causes an unhandled exception and I end up with an email with a full stack dump and all the settings. In this case, it’s a crawler so I’m going to try a robots.txt to exclude it, but yesterday I got about 10 messages from two different IPs. I know python devs don’t see exceptions as the evils that those of us who grew up on other languages might, but couldn’t we just handle this and return a 403 (or my favorite 418)?

If you’re getting a 500 as a result of this, you’ve likely got something misconfigured.

This request should (in the common case) return the login page.

I suggest you take a closer look at the stack dump you’re getting and figure out what the root cause is.

(Side note: The emails are handled by the logging module using the AdminEmailHandler. You can customize the processing of that handler as desired using the normal logging facilities.)

If I just do a curl, I get a 302 back. I don’t know what the script kiddies are doing different, but the stack trace looks like

Traceback (most recent call last):
File "/opt/mailman/venv/lib/python3.13/site-packages/django/contrib/sites/models.py", line 39, in _get_site_by_request
SITE_CACHE[host] = self.get(domain__iexact=host)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/mailman/venv/lib/python3.13/site-packages/django/db/models/manager.py", line 87, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/mailman/venv/lib/python3.13/site-packages/django/db/models/query.py", line 639, in get
raise self.model.DoesNotExist(
^

During handling of the above exception (Site matching query does not exist.), another exception occurred:
File "/opt/mailman/venv/lib/python3.13/site-packages/django/core/handlers/exception.py", line 55, in inner
response = get_response(request)
^^^^^^^^^^^^^^^^^^^^^
File "/opt/mailman/venv/lib/python3.13/site-packages/django/core/handlers/base.py", line 198, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/mailman/venv/lib/python3.13/site-packages/django/utils/decorators.py", line 48, in _wrapper
return bound_method(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/mailman/venv/lib/python3.13/site-packages/django/views/decorators/cache.py", line 80, in _view_wrapper
response = view_func(request, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/mailman/venv/lib/python3.13/site-packages/django/contrib/admin/sites.py", line 450, in login
return LoginView.as_view(**defaults)(request)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/mailman/venv/lib/python3.13/site-packages/django/views/generic/base.py", line 106, in view
return self.dispatch(request, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/mailman/venv/lib/python3.13/site-packages/django/utils/decorators.py", line 48, in _wrapper
return bound_method(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/mailman/venv/lib/python3.13/site-packages/django/views/decorators/debug.py", line 143, in sensitive_post_parameters_wrapper
return view(request, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/mailman/venv/lib/python3.13/site-packages/django/utils/decorators.py", line 192, in _view_wrapper
result = _process_exception(request, e)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/mailman/venv/lib/python3.13/site-packages/django/utils/decorators.py", line 190, in _view_wrapper
response = view_func(request, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/mailman/venv/lib/python3.13/site-packages/django/views/decorators/cache.py", line 80, in _view_wrapper
response = view_func(request, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/mailman/venv/lib/python3.13/site-packages/django/contrib/auth/views.py", line 89, in dispatch
return super().dispatch(request, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/mailman/venv/lib/python3.13/site-packages/django/views/generic/base.py", line 145, in dispatch
return handler(request, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/mailman/venv/lib/python3.13/site-packages/django/views/generic/edit.py", line 142, in get
return self.render_to_response(self.get_context_data())
^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/mailman/venv/lib/python3.13/site-packages/django/contrib/auth/views.py", line 113, in get_context_data
current_site = get_current_site(self.request)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/mailman/venv/lib/python3.13/site-packages/django/contrib/sites/shortcuts.py", line 16, in get_current_site
return Site.objects.get_current(request)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/mailman/venv/lib/python3.13/site-packages/django/contrib/sites/models.py", line 61, in get_current
return self._get_site_by_request(request)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/mailman/venv/lib/python3.13/site-packages/django/contrib/sites/models.py", line 45, in _get_site_by_request
SITE_CACHE[domain] = self.get(domain__iexact=domain)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/mailman/venv/lib/python3.13/site-packages/django/db/models/manager.py", line 87, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/mailman/venv/lib/python3.13/site-packages/django/db/models/query.py", line 639, in get
raise self.model.DoesNotExist(
^

BTW: Didn’t we work together at CareFirst?

Dusting off my atrophying python skills, it appears that the offending requests are somehow setting HTTP_X_FORWARDED_HOST and HTTP_HOST to my IP instead of my domain name, and my IP isn’t in the django_site table. Oh, did I mention the django site is behind an apache site that uses ProxyPass to forward it?

I still haven’t figured out how they did that to the HTTP_X_FORWARDED_HOST. But would it be safe just to insert the IP into django_site?

A long time ago in a galaxy far, far away. (Yes. I thought I recognized your name, but it’s tough to recognize you from your avatar picture.)

Apache is setting that in mod_proxy from the originating HOST header, depending upon the ProxyPreserveHost directive. (See mod_proxy - Apache HTTP Server Version 2.4)

I haven’t used the sites framework very often, and I generally don’t have it enabled. So with that caveat, you could do worse than to give it a try.

Or, you could probably add a RequestHeader directive in that section to replace the IP address with the desired domain name.

Or, you could filter out (or handle in a different paragraph) requests coming in using the IP address instead of a domain name. (I do that in nginx for my https sites.)