GrahamDumpleton / mod_wsgi

Source code for Apache/mod_wsgi.
Apache License 2.0
1.03k stars 268 forks source link

wsgi.errors writes to the wrong file in some configurations ('Listen 80') #307

Open mjw-pp opened 6 years ago

mjw-pp commented 6 years ago

If I use mod_wsgi with the following combination of settings:

Listen 80
WSGIDaemonProcess foo
<VirtualHost a.b.c.d:80>
  ...
</VirtualHost>

then messages written to wsgi.errors are sent to the global ErrorLog rather than the ErrorLog defined inside the <VirtualHost>.

I've seen this with:

Here's a simplified self-contained Apache config file that shows the problem for me:

DefaultRuntimeDir /var/run/apache2
PidFile /var/run/apache2/apache2.pid

User www-data
Group www-data

LoadModule mpm_event_module /usr/lib/apache2/modules/mod_mpm_event.so
LoadModule authz_core_module /usr/lib/apache2/modules/mod_authz_core.so
LoadModule wsgi_module /opt/mod_wsgi/mod_wsgi.so

Listen 80

ErrorLog /srv/www/mod_wsgi/logs/global_error.log

WSGIDaemonProcess wsgi-a

<VirtualHost 127.0.0.1:80>
  ServerName localhost
  ErrorLog /srv/www/mod_wsgi/logs/local_error.log
  WSGIScriptAlias / /srv/www/mod_wsgi/wsgi/test.wsgi
  <Directory /srv/www/mod_wsgi/wsgi>
    # Require all denied
    WSGIProcessGroup wsgi-a
    WSGIApplicationGroup %{GLOBAL}
  </Directory>
</VirtualHost>

where test.wsgi is:

def application(environ, start_response):
    environ['wsgi.errors'].write("test.wsgi logging to wsgi.errors\n")
    start_response('200 OK', [('Content-Type', 'text/plain')])
    return ['test.wsgi is OK\n']

The log message is written to global_error.log rather than local_error.log.

The problem goes away if I change Listen 80 to Listen 127.0.0.1:80, or if I change <VirtualHost 127.0.0.1:80> to <VirtualHost *:80> (or if I do both those things).

With this cut-down example the problem also goes away if I move the WSGIDaemonProcess inside the <VirtualHost>, but I believe I've also observed things going wrong in that configuration (the log messages seemed to end up going nowhere at all).

If I cause Apache itself to write to the error log (eg by uncommenting the # Require all denied line), it does use local_error.log.

GrahamDumpleton commented 6 years ago

I have had a few people over the years report this issue before with logging when an IP address is used with VirtualHost but I have never been able to replicate it and couldn't get the assistance I needed from the people experiencing the issue to help track it down by running custom builds with additional debugging.

From memory all those people were using an IP address with VirtualHost when there was no need to and using *:80 was the correct thing to use anyway.

So first question is whether you really need to use an IP address with VirtualHost?

In nearly all cases you don't need to. You really only need to when you have multiple network interfaces and it is important to restrict access only via certain network interfaces. People usually go and supply an IP when they only have the one network interface and so there is no point.

Using 127.0.0.1 as the IP in VirtualHost is a bit different case as it is restricting it to only the loopback interface. Even then, if you only have the one site, you can still use *:80 and then use something like:

<RequireAll>
    Require all granted

    # require localhost
    Require local
</RequireAll>

Beyond that, I am unlikely going to be able to track this down without some help since I can't replicate it.

mjw-pp commented 6 years ago

I'm using the IP address in VirtualHost because there's one site I want to be accessible only over a VPN connection.

But I'm sure I can work around the problem case in some other way: it looks like changing the Listen lines will be good enough, and if not I'll find something else.

So this is only a bug report, not a support request, and there's no urgency to do anything from my point of view.

I'm happy to help track the problem down, if you let me know what would be helpful. Building a custom mod_wsgi should be no problem.

NB using 127.0.0.1 was just a way to make the example more portable; I see the same thing with a 'real' IP address.

dirkroorda commented 2 years ago

Ah, I think I see a pattern analogous to #726: wsgi logging uses the Log directives found in the same scope as where the WSGIDaemonProcess is.

If there are other virtual hosts served by wsgi and with other log directives, the wsgi messages will not use those log directives.