401908 - Enhance DosFilter to allow dynamic configuration of attributes.

This commit is contained in:
Simone Bordet 2013-02-27 16:23:17 +01:00
parent 0e9f74ad29
commit 90bab0eb66
5 changed files with 523 additions and 367 deletions

View File

@ -84,6 +84,12 @@
<artifactId>javax.servlet</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-jmx</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>test-jetty-servlet</artifactId>

View File

@ -9,4 +9,10 @@ maxIdleTrackerMs: maximum amount of time (in milliseconds) to keep track of requ
insertHeaders: insert the DoSFilter headers into the response.
trackSessions: usage rate is tracked by session if a session exists.
remotePort: usage rate is tracked by IP+port (effectively connection) if session tracking is not used.
ipWhitelist: list of IP addresses that will not be rate limited.
enabled: whether this filter is enabled
whitelist: comma separated list of IP addresses that will not be rate limited.
clearWhitelist(): clears the list of IP addresses that will not be rate limited.
addWhitelistAddress(java.lang.String):ACTION: adds an IP address that will not be rate limited.
addWhitelistAddress(java.lang.String)[0]:address: the IP address that will not be rate limited.
removeWhitelistAddress(java.lang.String):ACTION: removes an IP address that will not be rate limited.
removeWhitelistAddress(java.lang.String)[0]:address: the IP address that will not be rate limited.

View File

@ -0,0 +1,88 @@
//
// ========================================================================
// Copyright (c) 1995-2013 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.servlets;
import java.lang.management.ManagementFactory;
import java.util.EnumSet;
import java.util.Set;
import javax.management.Attribute;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import org.eclipse.jetty.jmx.MBeanContainer;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.DispatcherType;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.nio.SelectChannelConnector;
import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.junit.Assert;
import org.junit.Test;
public class DoSFilterJMXTest
{
@Test
public void testDoSFilterJMX() throws Exception
{
Server server = new Server();
Connector connector = new SelectChannelConnector();
connector.setPort(0);
server.addConnector(connector);
ServletContextHandler context = new ServletContextHandler(server, "/", ServletContextHandler.SESSIONS);
DoSFilter filter = new DoSFilter();
FilterHolder holder = new FilterHolder(filter);
String name = "dos";
holder.setName(name);
holder.setInitParameter(DoSFilter.MANAGED_ATTR_INIT_PARAM, "true");
context.addFilter(holder, "/*", EnumSet.of(DispatcherType.REQUEST));
context.setInitParameter(ServletContextHandler.MANAGED_ATTRIBUTES, name);
MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer();
MBeanContainer mbeanContainer = new MBeanContainer(mbeanServer);
server.addBean(mbeanContainer);
server.getContainer().addEventListener(mbeanContainer);
server.start();
String domain = DoSFilter.class.getPackage().getName();
Set<ObjectName> mbeanNames = mbeanServer.queryNames(ObjectName.getInstance(domain + ":*"), null);
Assert.assertEquals(1, mbeanNames.size());
ObjectName objectName = mbeanNames.iterator().next();
boolean value = (Boolean)mbeanServer.getAttribute(objectName, "enabled");
mbeanServer.setAttribute(objectName, new Attribute("enabled", !value));
Assert.assertEquals(!value, filter.isEnabled());
String whitelist = (String)mbeanServer.getAttribute(objectName, "whitelist");
String address = "127.0.0.1";
Assert.assertFalse(whitelist.contains(address));
boolean result = (Boolean)mbeanServer.invoke(objectName, "addWhitelistAddress", new Object[]{address}, new String[]{String.class.getName()});
Assert.assertTrue(result);
whitelist = (String)mbeanServer.getAttribute(objectName, "whitelist");
Assert.assertTrue(whitelist.contains(address));
result = (Boolean)mbeanServer.invoke(objectName, "removeWhitelistAddress", new Object[]{address}, new String[]{String.class.getName()});
Assert.assertTrue(result);
whitelist = (String)mbeanServer.getAttribute(objectName, "whitelist");
Assert.assertFalse(whitelist.contains(address));
server.stop();
}
}

View File

@ -18,18 +18,21 @@
package org.eclipse.jetty.servlets;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.servlets.DoSFilter.RateTracker;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
public class DoSFilterTest extends AbstractDoSFilterTest
{
private static final Logger LOG = Log.getLogger(DoSFilterTest.class);
@ -69,6 +72,21 @@ public class DoSFilterTest extends AbstractDoSFilterTest
assertFalse("Should not exceed as we sleep 300s for each hit and thus do less than 4 hits/s",exceeded);
}
@Test
public void testWhitelist() throws Exception
{
DoSFilter filter = new DoSFilter();
List<String> whitelist = new ArrayList<String>();
whitelist.add("192.168.0.1");
whitelist.add("10.0.0.0/8");
Assert.assertTrue(filter.checkWhitelist(whitelist, "192.168.0.1"));
Assert.assertFalse(filter.checkWhitelist(whitelist, "192.168.0.2"));
Assert.assertFalse(filter.checkWhitelist(whitelist, "11.12.13.14"));
Assert.assertTrue(filter.checkWhitelist(whitelist, "10.11.12.13"));
Assert.assertTrue(filter.checkWhitelist(whitelist, "10.0.0.0"));
Assert.assertFalse(filter.checkWhitelist(whitelist, "0.0.0.0"));
}
private boolean hitRateTracker(DoSFilter doSFilter, int sleep) throws InterruptedException
{
boolean exceeded = false;