Published on Jun 24 2014 in Java Tomcat

Usually you use .htaccess to allow or block specific IPs from accessing your website. This changes with Java hosting. When some or all requests are proxied to Tomcat the .htaccess will not work for them as it is not consulted for such requests at all.

If this is the case you need to block the IPs on Tomcat level. An example IP filter that can be used in web.xml of your web application or global one follows:

<filter>
  <filter-name>Remote IP Filter</filter-name>
  <filter-class>org.apache.catalina.filters.RemoteAddrFilter</filter-class>
  <init-param>
   <param-name>deny</param-name>
   <param-value>172\.20\.\d+\.\d+</param-value>
  </init-param>```
    
  <init-param>
    <param-name>denyStatus</param-name>
    <param-value>404</param-value>
  </init-param>
</filter>
   
<filter-mapping>
  <filter-name>Remote IP Filter</filter-name>
 <url-pattern>/*</url-pattern>
</filter-mapping>

As you can see regular expressions can be used in allow and deny parameter values. This will allow you to block all IP ranges. If you skip the denyStatus parameter its default value of 403 will be used. You can define multiple filters and apply them to specific URLs/servlets. Restart Tomcat after defining the filter.

Read http://tomcat.apache.org/tomcat-7.0-doc/config/filter.html on different kinds of filters you can use.

You are free to build your own filters in Java by writing a class that implements javax.servlet.Filter. Here goes a simple IP filter example HOWTO.

package net.jvmhost.test;```

import java.io.IOException;
import java.util.StringTokenizer;
import javax.servlet.*;
import javax.servlet.http.*;
    
public class IPFilter implements Filter {
  private FilterConfig config;
  // the regex must define whole string to match - for example a substring without .* will not match
  // note the double backslashes that need to be present in Java code but not in web.xml
  private String IP_REGEX = "172\\.20\\.\\d+\\.\\d+.*";
  // private String IP_REGEX = "172\\.20\\..*";
  public void init(FilterConfig filterConfig) throws ServletException {```
this.config = filterConfig;
    // optionally you can get regex from init parameter overwriting the class' private variable
    IP_REGEX = config.getInitParameter("IP_REGEX");
  }
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
String ip = request.getRemoteAddr();
    HttpServletResponse httpResp = null;
    if (response instanceof HttpServletResponse) httpResp = (HttpServletResponse) response;
    if (ip.matches(IP_REGEX)) {
      httpResp.sendError(HttpServletResponse.SC_FORBIDDEN,"Your own message 403 Forbidden");
    } else {
      chain.doFilter(request, response);
    }
  }
  public void destroy() {}
}
javac -cp ~/appservers/apache-tomcat-7.0.28/lib/servlet-api.jar IPFilter.java
<filter>
  <filter-name>Custom Remote Address Filter</filter-name>
  <filter-class>net.jvmhost.test.IPFilter</filter-class>
  <init-param>
    <param-name>IP_REGEX</param-name>
    <param-value>172\.20\.\d+\.\d+</param-value>
  </init-param>
</filter>
<filter-mapping>
  <filter-name>Custom Remote Address Filter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

All paths, IPs and regular expressions are example ones and need to be customized for your environment and needs.