Mailman 3: Problem with binding REST server to custom address
Hi, I'm testing the new REST API of Mailman 3 at the moment and installed Mailman 3.0.0b3 on Ubuntu Server 12.04 in VirtualBox following the steps in docs/START.rst (with virtualenv). I got Mailman running without errors but I can't change the IP address the REST server binds to. I would like to bind the REST server for development to the address 0.0.0.0 to access it from outside of the VirtualBox with Port Mapping. I tried with a custom settings file 'mailman.cfg' in my Mailman working directory in which I set the property hostname to 0.0.0.0. Now when I call 'mailman info' it shows the custom defined hostname in line starting with 'REST root url' but I can't access the API from outside the virtual machine and the command 'netstat -lntpu' displays that the REST server process was bound to the address 127.0.0.1 and therefore is of course only accessible from localhost. To eliminate any configuration mistakes of my virtual machine or python I wrote a simple python script that starts a server with the wsgi library and I had no problems to bind this server to 0.0.0.0. I appreciate any ideas and tips!
Regards, Tim
On Feb 02, 2014, at 04:17 PM, Tim Marx wrote:
I got Mailman running without errors but I can't change the IP address the REST server binds to. I would like to bind the REST server for development to the address 0.0.0.0 to access it from outside of the VirtualBox with Port Mapping.
0.0.0.0 is a reserved IPv4 address:
http://en.wikipedia.org/wiki/Reserved_IP_addresses#Reserved_IPv4_addresses
so I don't think it's generally useful as an address to bind Mailman's REST API to, unless VB is doing something special I'm not aware of. (I'm not a VB expert.)
I tried with a custom settings file 'mailman.cfg' in my Mailman working directory in which I set the property hostname to 0.0.0.0. Now when I call 'mailman info' it shows the custom defined hostname in line starting with 'REST root url' but I can't access the API from outside the virtual machine and the command 'netstat -lntpu' displays that the REST server process was bound to the address 127.0.0.1 and therefore is of course only accessible from localhost.
To eliminate any configuration mistakes of my virtual machine or python I wrote a simple python script that starts a server with the wsgi library and I had no problems to bind this server to 0.0.0.0. I appreciate any ideas and tips!
Mailman doesn't do anything special here. Whatever IP address/hostname you set in mailman.cfg is passed straight through to the wsgiref server:
http://docs.python.org/2/library/wsgiref.html#module-wsgiref.simple_server
Scanning the Python 2.7 stdlib, I can't see that wsgiref does anything special to the address you give it. It passes it down through several levels, but ultimately ends up calling socket.bind() on it AFAICT.
What happens if you give it the public host name of your VB instance, e.g. myhost.mydomain?
Cheers, -Barry
Barry Warsaw writes:
the address 0.0.0.0 to access it from outside of the VirtualBox with Port Mapping.
0.0.0.0 is a reserved IPv4 address:
http://en.wikipedia.org/wiki/Reserved_IP_addresses#Reserved_IPv4_addresses
I don't think it's a very interesting idea to bind a listener to that address, since it could only hear broadcasts. *shiver* But for exactly that reason it's often used as a non-address token to express that the network server should to bind to all available interfaces.
I tried with a custom settings file 'mailman.cfg' in my Mailman working directory in which I set the property hostname to 0.0.0.0. Now when I call 'mailman info' it shows the custom defined hostname in line starting with 'REST root url' but I can't access the API from outside the virtual machine and the command 'netstat -lntpu' displays that the REST server process was bound to the address 127.0.0.1 and therefore is of course only accessible from localhost.
Given the above interpretation, it looks to me like your problem may be that the only interface found has address 127.0.0.1. I don't know much about VirtualBox, but I would look at its configuration and that of your webserver (WSGI is not a webserver, it is an interface between Python and a real webserver), despite your simple experiment (which is far from eliminating configuration errors based on the data you've provided so far, although it might do so based on information you haven't given us).
On Feb 04, 2014, at 02:49 PM, Stephen J. Turnbull wrote:
(WSGI is not a webserver, it is an interface between Python and a real webserver)
Right, but the wsgiref stdlib module does provide a WSGI-compliant HTTP server, which is what Mailman's REST runner uses currently.
-Barry
Barry Warsaw writes:
On Feb 04, 2014, at 02:49 PM, Stephen J. Turnbull wrote:
(WSGI is not a webserver, it is an interface between Python and a real webserver)
Right, but the wsgiref stdlib module does provide a WSGI-compliant HTTP server, which is what Mailman's REST runner uses currently.
Indeed, but my point is that unless the full configuration that Mailman uses and the full configuration for the OP's "simple HTTP server", not to mention the exact test case run with the "simple HTTP server" are specified, we can't be sure it's a Mailman problem.
AFAICS that point stands.
Am 03.02.2014 21:38, schrieb Barry Warsaw:
0.0.0.0 is a reserved IPv4 address:
http://en.wikipedia.org/wiki/Reserved_IP_addresses#Reserved_IPv4_addresses
so I don't think it's generally useful as an address to bind Mailman's REST API to, unless VB is doing something special I'm not aware of. (I'm not a VB expert.) I thought it might be a good idea, because the output of 'netstat -lntpu' in my virtual machine shows that all public accessible services (e.g. apache2, sshd) are bound to 0.0.0.0 and these services are accessible from the host. The services that are bound to 127.0.0.1 can only be accessed from localhost inside the virtual machine.
from wsgiref.simple_server import make_server
def hello_world(environ, start_response): start_response('200 OK', [('Content-Type', 'text/html')]) return ['''Hello world!''']
if __name__ == '__main__': srv = make_server('', 8080, hello_world) srv.serve_forever() This script responses "Hello world" to every request on Port 8080. When I pass '' or '0.0.0.0' as first argument to make_server(...) I get
host, port, make_application(), to '', port, make_application(),
I found a simple python script and modified it a little bit: the expected response "Hello world" inside and outside the virtual machine and netstat shows that the service is bound to 0.0.0.0:8080. But when I pass '127.0.0.1' I can't access it outside the virtual machine and netstat shows that the service is bound to 127.0.0.1:8080. The interesting thing is netmask shows that the Mailman rest service is always bound to 127.0.0.1 even if edit the file src/mailman/rest/wsgiapp.py directly and change line 80 from the rest service is bound to 127.0.0.1 and not accessible outside the virtual machine. This is the reason why I think it's a Mailman problem.
Thanks and Cheers, Tim
participants (3)
-
Barry Warsaw -
Stephen J. Turnbull -
Tim Marx