Wednesday, April 14, 2010

Public/Private Exposure of your GeoServer

When you setup your GeoServer, you may wish to expose only a portion of it to the public. Namely, in the case of serving “tiles” for an overlay in a google map, you need to permit the public to reach the GeoWebCache, but not permit them to reach the other functionality of GeoServer.

One way to do this is by fronting your Tomcat server with an Apache server and use mod_jk to “mount” only the URLs needed to support tile serving.

The URL used by google maps to grab tiles has the format of:

var url = "http://private:8080/geoserver/gwc/service/gmaps?layers=layer_name&" +
  "zoom=" + zoom + "&x=" + coord.x + "&y=" + coord.y + "&format=image/png";

 

All the GeoServer functionality exists under  /geoserver/*, so we would like to limit exposure only to /geoserver/gwc/service/gmaps/*.

(A litmus test is loading /geoserver/gwc/demo and seeing if it exists or not. We don’t want this page to load for the public.)

 

So how to hookup mod_jk between Apache and Tomcat? I will first assume you have a working Apache installation. I am using version 2.x. I will also presume you have a working Tomcat installation with GeoServer installed and functioning.

First, Apache must have the mod_jk.so module loaded. (You may have to build mod_jk, which is beyond the scope of this post.) In the httpd.conf file, check for the following line, and add it if it doesn’t exist. There should be a whole list of LoadModule entries together in the httpd.conf.

LoadModule jk_module libexec/apache22/mod_jk.so

 

At the end of the httpd.conf, add the following:

<IfModule jk_module>
# Where to find workers.properties
# Update this path to match your conf directory location (put
# workers.properties next to httpd.conf)
JkWorkersFile /your/website/path/etc/apache22/workers.properties
# Where to put jk shared memory
# Update this path to match your local state directory or logs directory
JkShmFile     /your/website/path/log/mod_jk.shm
# Where to put jk logs
# Update this path to match your logs directory location (put mod_jk.log
# next to access_log)
JkLogFile     /your/website/path/log/mod_jk.log
# Set the jk log level [debug/error/info]
JkLogLevel    info
# Select the timestamp log format
JkLogStampFormat "[%a %b %d %H:%M:%S %Y] "
</IfModule>
## my mod_jk mounts, same for SSL section too
Include etc/apache22/mod_jk_mounts.conf

 

This sets up apache to use mod_jk and its log files. It also refers to two more important files that you must create. Those two files are mod_jk_mounts.conf and workers.properties.

The mod_jk_mounts.conf file is used to tell Apache what URL patterns to watch for, and if it has a match, it will delegate the work to render the page to a tomcat worker. The file looks like this:

<IfModule jk_module>
# this maps to /geoserver tile server at localhost tomcat
JkMount  /geoserver/gwc/service/gmaps* worker1
</IfModule>

 

Above you see that the URL is the precise URL we need to serve our tiles, i.e. /geoserver/gwc/service/gmaps/*.  So traffic at this URL will get directed to Tomcat’s worker1, which is defined in the next file, workers.properties, which looks like:

# Define workers using ajp13
worker.list=worker1
# Set properties for worker1 (ajp13)
worker.worker1.type=ajp13
worker.worker1.host=localhost
worker.worker1.port=8009

 

Apache and Tomcat speak a custom protocol on a custom port. This is the meaning of ajp13 and port 8009. It is also presumed that Tomcat is listening on a localhost address. If not, supply your local (and presumably private!) address above.

Now you should be able to serve tiles from the GeoWebCache via the front-end apache, but not be able to see the other GeoServer functionality.  So now you can use a public URL like this:

var url = "http://publicserver/geoserver/gwc/service/gmaps?layers=layer_name&" +
  "zoom=" + zoom + "&x=" + coord.x + "&y=" + coord.y + "&format=image/png";

 

 

Postscript:

It would be nice to also have a super clean URL that obscures the URL that indicates you are using GeoServer. Bu you cannot use the Apache “Alias” configuration to remap the URL because it expects the target path to be a physical path and not a virtual one. I would like to hear if anyone out there has a way to Alias mounted JK paths.