Selecting the port and interface where Grok listens

Author:Brandon Craig Rhodes

Hosts which use the Transmission Control Protocol (TCP) atop the Internet Protocol (IP) for communication receive connections through devices called interfaces which each specify a port numbers that they want to connect to. For example, on the machine on which I am typing, there are several interfaces (this is Linux, so I can list them with the old-fashioned command ifconfig -a or, instead, with the modern command ip a):

lo    (“loopback” interface)
eth0  (my Ethernet card)
wlan0 (wireless LAN card)

Port numbers are simple integers, and generally each new application that comes out on the Internet claims a port number on which it listens for incoming connections. Some of the most popular, just to give some examples, are:

22   SSH (Secure Shell)
25   Email server
53   Domain name service (DNS)
80   Web server (HTTP)
443  Secure web server (HTTPS)

On typical Unix systems, you can see a full list of port numbers in the file /etc/services.

Whenever you run a Grok instance, it will open a port on your machine on which it can receive, and respond to, incoming HTTP requests. Its default behavior is to listen for connections coming in on any interface as long as the connection is aimed at port 8080, which is a common port for use by unofficial web services since it looks kind of like the number 80, but is greater than 1024 and is, therefore, a port that normal users can open without needing administrator privileges on the machine.

But very often you’ll want to change this default.

First, it’s not terribly safe to have a web application you’re still developing listening to connections from the whole entire world! You will probably want to have you development Grok instances just listen on the “loopback” interface of your computer, since that way Grok will only see connections coming from other programs on your computer (like your web browser), and not connections from hackers scanning your machine to find web applications to explore and exploit.

Secondly, you might want to change the port number because you find that port 8080 is already in use by another process. Its official designation is that it’s the HTTP proxy port, and if your machine is already running a web proxy there, your Grok application might not even start.

Thirdly, if you want several Grok instances running on you machine, then only the first one can grab and use port 8080, so the others will have to be configured to use some other port.

The solution is to edit your project’s buildout.cfg and look for the [zopectl] section, which defines basic information about the little web server that Grok comes with by default. You need to add a line that looks like:

address = localhost:8012

This will make the whole [zopectl] section, at least on the version of Grok I’m using, look something like:

[zopectl]
recipe = zc.zope3recipes:instance
application = app
zope.conf = ${data:zconfig}
address = localhost:8012

The address can either be a plain port number, like 8012, or can specify both an interface’s IP address followed by a port number, like localhost:8012 or my.host.com:80.

After changing the address, you must re-run buildout for your change to have any effect! There have been many occasions on which I have adjusted this setting, and then been puzzled about why it is having no effect, because I forgot to re-run the ./bin/buildout command.

Note that, if you include the IP address and colon instead of just a bare port number, you are indirectly specifying which interface Grok will listen on by naming the IP address associated with the interface. This might confuse you at first. It means that you are not giving an actual interface name — Grok will not understand if you tell it to listen on lo or eth0 or wlan0. Instead, you have to look at the output of a command like ifconfig -a or ip a, find the IP address associated with the interface, and then name either the raw IP address or else a host name that points at that IP address.

For example, since most machines define localhost as being the IP address 127.0.0.1 (check out the file /etc/hosts on a typical Unix machine to verify that your machine defines localhost this way), the following two address lines are equivalent:

address = 127.0.0.1:8080
address = localhost:8080

Note that all of this about the buildout.cfg only applies if you are using Grok’s built-in web server. If you are instead running it under a paste-based WSGI pipeline, or inside of Apache, or under a CherryPy web server, or through some other exotic mechanism, then what you put in the [zopectl] section of your buildout.cfg will probably not matter at all. (Or your buildout.cfg might not even have that section!) Instead, you would consult the documentation for the particular web server you’re using to find out how to set its listening address.

But the central lesson of this HOWTO is the same regardless of the web server you use: letting a web application listen on all of your computer’s interfaces is dangerous if the application is not finished, polished, tested, and ready for attacks from the very clever criminals on the Internet who will test and probe every page, every form, and every script for some way to exploit a flaw. Until your application is ready to go live, you should have it listen only on localhost for connections coming directly from your machine.

If your web browser runs on a different machine than the one on which you’re developing your Grok application, but you still want the safety of having Grok listen only on the loopback interface, there are ways that you can VPN or tunnel a connection to the development machine so that your web browser’s connections look like they’re coming from “localhost”. Though port-forwarding is a big issue that I cannot cover in detail here (try a Google search), I should mention that I myself usually develop my Grok apps on a server that’s a different machine than my desktop where Firefox runs, and that the following command lets me cause port 8080 on my desktop to actually make a request to port 8080 on the server from its own loopback interface:

ssh -N -L 8080:localhost:8080 my.server.com

Note that a properly configured firewall is another way to prevent hosts out on the Internet from connecting to your development Grok instances.

Finally, even when someone is finished and ready to deploy their Grok app, an experienced web developer will often leave it listening on localhost and protect it by putting it behind another HTTP implementation as a proxy — such as Apache, Squid, Pound, or Varnish. But that is a large topic that deserves a HOWTO of its own!