Tomcat: Revisiting IP Access Restriction

This is another in my series of short posts on configuring Tomcat as I get a Tomcat/ACF10 development environment configured. For a bit of background, see the first post in the series.

We took a quick look earlier at restricting access to my Tomcat server based on the IP address from which the request originated. In that first take, we used Tomcat’s Remote Address Valve component to restrict access to just requests from the local system. In that post, I indicated we would probably look at this subject again in the future. Here’s my second look… and I know we have at least one more coming.

One of the first items I plan on digging into with ACF10 is how it deals with IPv6. As I started poking around the edges of this, I discovered two things that merited further investigation:

  1. Requests to my local server with an IPv6-based URI (e.g., http://[::1]:8501/sample.cfm) were being blocked despite the inclusion of the IPv6 versions of the local server address (i.e., ::1 and 0:0:0:0:0:0:0:1) in our earlier Valve-based set of allowed addresses, and
  2. I was not seeing my custom 403 error page that I expected, based on my earlier work to configure one

To figure out what’s going on with the second of those two items, let’s look at where the addressed-based restrictions were implemented vs. where the custom error pages were configured:

  • My Valve-based address restrictions were implemented within the Host element in ./cfusion/runtime/conf/server.xml
  • My custom error pages were configured in the web-app element within ./WEB-INF/web.xml

It’s not too big a leap to see that the two items are configured at two different levels within the overall configuration of Tomcat and the ColdFusion Web application. This is one of those places I’ve bumped into the “there is more than one way to get there” aspect of Tomcat. Tomcat also provides a Remote Address Filter which provides the same functionality as the valve we used in our first run at this. As a filter, it is configured for the Web application (i.e., at the same level as our custom error pages) so it made sense this might address problem #2 from above.

Add the following filter specification to ./WEB-INF/web.xml as the first filter:

<filter>
   <filter-name>Remote Address Filter</filter-name>
   <filter-class>org.apache.catalina.filters.RemoteAddrFilter</filter-class>
   <init-param>
      <param-name>allow</param-name>
      <param-value>127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1</param-value>
   </init-param>
</filter>
...

Add the following filter-mapping specification to the same file as the first such mapping:

<filter-mapping>
   <filter-name>Remote Address Filter</filter-name>
   <url-pattern>/*</url-pattern>
</filter-mapping>
...

Remove the corresponding Valve specification from ./cfusion/runtime/conf/server.xml. Bounce the server and verify that the custom error pages are still being served appropriately.

In my next post, we’ll figure out what’s going on with IPv6-based URI’s and why we’re still being blocked (although now we at least get our custom error page). And as noted above, we’ll revisit this whole subject of address-based access restrictions at least one more time in the future.

Tomcat: Custom Error Pages

This is the latest in my series of short posts related to configuring Tomcat, as I work on getting a Tomcat/ACF10 development environment stood up next to my existing Apache/JRun/ACF9 application stack. See the first post in the series for a bit of background.

There are several reasons you may want to set up custom error pages to be served by Tomcat when different kinds of errors or exceptions are encountered. These reasons might include:

  • Security: the default error pages served by Tomcat can include information about the server and its configuration that could be considered a vulnerability (e.g.., file paths, configuration or version information)
  • Application-specific error handling: you may want to provide site- or application-specific information about the error to assist the user (or the developer!)

Part of the servlet specification allows for the definition of error pages to be served up based on either an exception or an error code in the following format:

<web-app>
   ...
   <error-page>
      <exception-type>java.lang.NullPointerException</error-code>
      <location>/nullpointer.jsp</location>
   </error-page>

   <error-page>
      <error-code>404</error-code>
      <location>/404.html</location>
   </error-page>
   ...
</web-app>

The specific files served up can be static HTML or dynamic pages of any type supported by the server. The paths are relative to the root of the web application.

Because the default error pages served up by Tomcat include version information, I typically define a basic set of error pages for HTTP 403 and 404 status codes, place those pages in a ./errors/ folder off the Web root and then reference them in ./WEB-INF/web.xml for my application.

Tomcat: Default Web Document List

This is the sixth in my series of short posts covering the different aspects of setting up a development environment based on Tomcat and Adobe’s ColdFusion 10 application server stack. For background on this, see the initial post in the series.

The list of default documents the server will provide is specified in ./cfusion/runtime/conf/web.xml and then replaced (if specified) in the ./WEB-INF/web.xml file within each defined context. As all of the ColdFusion configuration is handled at the context level, it makes sense to make this particular change also at the context level. Find the welcome-file-list element toward the end of file ./cfusion/wwwroot/WEB-INF/web.xml and add the needed entries:

<welcome-file-list ...>
   <welcome-file>index.shtm</welcome-file>
   <welcome-file>index.cfm</welcome-file>
   <welcome-file>index.html</welcome-file>
   <welcome-file>index.htm</welcome-file>
   ...
</welcome-file-list>

Note that order does matter here: the first file found from the list will be served up when the request does not specify the file name. As shown above, we’ll look for index.shtm (which necessitates enabling SSI to function), then index.cfm, then static HTML pages index.html and index.htm. This sequence is specific to how our applications are configured; adjust accordingly per your own configuration needs.

Make the needed changes and restart the server.

Tomcat: Enabling SSI

This is the fifth in my series detailing my efforts to stand up a Tomcat/ACF10 development environment next to my existing Apache/JRun/ACF9 stack. For background, see the first post in the series.

Enabling Tomcat’s ability to process server-side includes (SSI) requires changes to two configuration files. File ./cfusion/runtime/conf/web.xml contains definitions for both a filter and a servlet for processing SSI’s, as well as a pair of corresponding servlet-mapping and filter-mapping definitions for filenames matching the *.shtml pattern. Uncomment either the filter or the servlet element (but not both), and the corresponding -mapping element. Modify the -mapping element based on the naming conventions you use and/or add additional -mapping elements, as needed.

If you decide to go the filter route on this, you should also note that the default web.xml file’s definition of the filter determines whether to run files through the SSI processing based on the MIME-type of the file. You will almost certainly have to also uncomment, and possibly supplement, the entry/entries in the MIME-type mappings in the same file.

The second file that requires a tweak, per the Tomcat SSI How-To, is ./cfusion/runtime/conf/server.xml. As noted in the docs, only contexts configured as “privileged” can use the SSI capabilities. Add the privileged="true" attribute to Context element for the ColdFusion context:

<Context
   path="/"
   docBase="/Applications/ColdFusion10/cfusion/wwwroot"
   ...
   privileged="true"
>
...
</Context>

Throw together a quick test SSI file, bounce your server, and verify that it works.

I clearly have some additional homework to do on this one, as I dont yet understand the benefits and drawbacks of the filter-vs-servlet choice above. More to come on that.

Tomcat: Restricting Access by IP

This is the fourth in my series detailing my efforts to stand up a Tomcat/ACF10 development environment next to my existing Apache/JRun/ACF9 stack. For background, see the first post in the series.

A couple items have struck me in wading around in the Tomcat docs and configuration files: the flexibility and power of Tomcat, along with the fact that there are often multiple ways to do quite a few things when it comes to configuring Tomcat. Restricting access to applications and content available via Tomcat is no exception: there are at least three ways to accomplish this. For now, primarily in the interest of getting our dev environment up and running as quickly as we can, we’ll take the simplest approach. As with access logging, we’ll configure a valve within ./cfusion/runtime/conf/server.xml. This valve will restrict access to only requests coming from the localhost:

<Host name="localhost" ... >
   ...
   <Valve
      className="org.apache.catalina.valves.RemoteAddrValve"
      allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1"
   />
   ...
</Host>

See the docs for details on this valve, but it is very straightforward: just a regex identifying the IP addresses to be allowed. Requests from any addresses not listed in the allow attribute will be blocked.

Clearly, you’d not place such a restriction on a production box, but in a dev environment I typically do not want to allow access to other boxes under normal circumstances. You’ll note that this is an all-or-nothing approach; in reality, it is more likely that we will want to at least open access to specific folders for specific addresses occasionally. This approach won’t provide that flexibility but we will return to this topic for another approach later in this series.

Make the change shown above, bounce your server, and verify that access from other systems on your network are no longer able to access pages/apps on your dev box.