You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@knox.apache.org by sm...@apache.org on 2022/09/30 09:39:33 UTC

[knox] branch master updated: KNOX-2806 - Implement a new DoS security provider (#634)

This is an automated email from the ASF dual-hosted git repository.

smolnar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/knox.git


The following commit(s) were added to refs/heads/master by this push:
     new c47a425a6 KNOX-2806 - Implement a new DoS security provider (#634)
c47a425a6 is described below

commit c47a425a6a70669134716ce552a7cca4abb12dbe
Author: MrtnBalazs <77...@users.noreply.github.com>
AuthorDate: Fri Sep 30 11:39:27 2022 +0200

    KNOX-2806 - Implement a new DoS security provider (#634)
---
 .../JerseyServiceDeploymentContributorBase.java    |  1 +
 gateway-provider-security-dos/pom.xml              | 43 +++++++++++++++
 .../impl/DosFilterDeploymentContributor.java       | 64 ++++++++++++++++++++++
 ...ox.gateway.deploy.ProviderDeploymentContributor | 19 +++++++
 gateway-release/pom.xml                            |  4 ++
 .../gateway/config/impl/GatewayConfigImpl.java     |  8 ++-
 .../knox/gateway/deploy/DeploymentFactory.java     | 11 ++--
 .../impl/ApplicationDeploymentContributor.java     |  1 +
 .../ServiceDefinitionDeploymentContributor.java    |  1 +
 .../org/apache/knox/gateway/GatewayTestConfig.java |  5 ++
 .../apache/knox/gateway/config/GatewayConfig.java  |  5 ++
 .../deploy/ProviderDeploymentContributorBase.java  | 17 ++++++
 .../deploy/ServiceDeploymentContributorBase.java   |  6 ++
 pom.xml                                            | 11 ++++
 14 files changed, 190 insertions(+), 6 deletions(-)

diff --git a/gateway-provider-jersey/src/main/java/org/apache/knox/gateway/jersey/JerseyServiceDeploymentContributorBase.java b/gateway-provider-jersey/src/main/java/org/apache/knox/gateway/jersey/JerseyServiceDeploymentContributorBase.java
index 4ad2c6f88..edea237cd 100644
--- a/gateway-provider-jersey/src/main/java/org/apache/knox/gateway/jersey/JerseyServiceDeploymentContributorBase.java
+++ b/gateway-provider-jersey/src/main/java/org/apache/knox/gateway/jersey/JerseyServiceDeploymentContributorBase.java
@@ -44,6 +44,7 @@ public abstract class JerseyServiceDeploymentContributorBase extends ServiceDepl
       ResourceDescriptor resource = context.getGatewayDescriptor().addResource();
       resource.role( service.getRole() );
       resource.pattern( pattern );
+      addDoSFilter(context, service, resource);
       addWebAppSecFilters( context, service, resource );
       addXForwardedFilter( context, service, resource );
       addAuthenticationFilter( context, service, resource );
diff --git a/gateway-provider-security-dos/pom.xml b/gateway-provider-security-dos/pom.xml
new file mode 100644
index 000000000..1347354e5
--- /dev/null
+++ b/gateway-provider-security-dos/pom.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <artifactId>gateway</artifactId>
+        <groupId>org.apache.knox</groupId>
+        <version>2.0.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>gateway-provider-security-dos</artifactId>
+    <name>gateway-provider-security-dos</name>
+    <description>An extension of the gateway introducing Denial of Service filter.</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.knox</groupId>
+            <artifactId>gateway-spi</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-servlets</artifactId>
+        </dependency>
+    </dependencies>
+
+</project>
\ No newline at end of file
diff --git a/gateway-provider-security-dos/src/main/java/org/apache/knox/gateway/deploy/impl/DosFilterDeploymentContributor.java b/gateway-provider-security-dos/src/main/java/org/apache/knox/gateway/deploy/impl/DosFilterDeploymentContributor.java
new file mode 100644
index 000000000..3cea6edae
--- /dev/null
+++ b/gateway-provider-security-dos/src/main/java/org/apache/knox/gateway/deploy/impl/DosFilterDeploymentContributor.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.knox.gateway.deploy.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.knox.gateway.deploy.DeploymentContext;
+import org.apache.knox.gateway.deploy.ProviderDeploymentContributorBase;
+import org.apache.knox.gateway.descriptor.FilterParamDescriptor;
+import org.apache.knox.gateway.descriptor.ResourceDescriptor;
+import org.apache.knox.gateway.topology.Provider;
+import org.apache.knox.gateway.topology.Service;
+
+public class DosFilterDeploymentContributor extends ProviderDeploymentContributorBase {
+  private static final String JETTY_DOS_FILTER_CLASSNAME = "org.eclipse.jetty.servlets.DoSFilter";
+
+  private static final String ROLE = "dos";
+  private static final String NAME = "JettyDoS";
+
+  @Override
+  public String getRole() {
+    return ROLE;
+  }
+
+  @Override
+  public String getName() {
+    return NAME;
+  }
+
+  @Override
+  public void initializeContribution(DeploymentContext context) {
+    super.initializeContribution(context);
+  }
+
+  @Override
+  public void contributeProvider(DeploymentContext context, Provider provider) {
+    super.contributeProvider(context, provider);
+  }
+
+  @Override
+  public void contributeFilter(DeploymentContext context, Provider provider, Service service, ResourceDescriptor resource, List<FilterParamDescriptor> params) {
+    if (params == null) {
+      params = new ArrayList<>();
+    }
+    copyAllProviderParams(provider, resource, params, false);
+    resource.addFilter().name(getName()).role(getRole()).impl(JETTY_DOS_FILTER_CLASSNAME).params(params);
+  }
+}
diff --git a/gateway-provider-security-dos/src/main/resources/META-INF/services/org.apache.knox.gateway.deploy.ProviderDeploymentContributor b/gateway-provider-security-dos/src/main/resources/META-INF/services/org.apache.knox.gateway.deploy.ProviderDeploymentContributor
new file mode 100644
index 000000000..2af424621
--- /dev/null
+++ b/gateway-provider-security-dos/src/main/resources/META-INF/services/org.apache.knox.gateway.deploy.ProviderDeploymentContributor
@@ -0,0 +1,19 @@
+##########################################################################
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##########################################################################
+
+org.apache.knox.gateway.deploy.impl.DosFilterDeploymentContributor
\ No newline at end of file
diff --git a/gateway-release/pom.xml b/gateway-release/pom.xml
index 6529bc640..5de943006 100644
--- a/gateway-release/pom.xml
+++ b/gateway-release/pom.xml
@@ -470,5 +470,9 @@
             <groupId>org.apache.knox</groupId>
             <artifactId>knox-token-management-ui</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.apache.knox</groupId>
+            <artifactId>gateway-provider-security-dos</artifactId>
+        </dependency>
     </dependencies>
 </project>
diff --git a/gateway-server/src/main/java/org/apache/knox/gateway/config/impl/GatewayConfigImpl.java b/gateway-server/src/main/java/org/apache/knox/gateway/config/impl/GatewayConfigImpl.java
index b231fb527..eb3409a93 100644
--- a/gateway-server/src/main/java/org/apache/knox/gateway/config/impl/GatewayConfigImpl.java
+++ b/gateway-server/src/main/java/org/apache/knox/gateway/config/impl/GatewayConfigImpl.java
@@ -305,6 +305,8 @@ public class GatewayConfigImpl extends Configuration implements GatewayConfig {
   private static final String GATEWAY_SESSION_VERIFICATION_EXPIRED_TOKENS_CLEANING_PERIOD = GATEWAY_SESSION_VERIFICATION_PREFIX + ".expired.tokens.cleaning.period";
   private static final long GATEWAY_SESSION_VERIFICATION_EXPIRED_TOKENS_CLEANING_PERIOD_DEFAULT = TimeUnit.MINUTES.toSeconds(30);
 
+  private static final String GATEWAY_SERVLET_ASYNC_SUPPORTED = GATEWAY_CONFIG_FILE_PREFIX + ".servlet.async.supported";
+  private static final boolean GATEWAY_SERVLET_ASYNC_SUPPORTED_DEFAULT = false;
 
   public GatewayConfigImpl() {
     init();
@@ -1385,9 +1387,13 @@ public class GatewayConfigImpl extends Configuration implements GatewayConfig {
     return nonPrivilegedUsers == null ? Collections.emptySet() : new HashSet<>(nonPrivilegedUsers);
   }
 
-
   @Override
   public long getConcurrentSessionVerifierExpiredTokensCleaningPeriod() {
     return getLong(GATEWAY_SESSION_VERIFICATION_EXPIRED_TOKENS_CLEANING_PERIOD, GATEWAY_SESSION_VERIFICATION_EXPIRED_TOKENS_CLEANING_PERIOD_DEFAULT);
   }
+
+  @Override
+  public boolean isAsyncSupported() {
+    return getBoolean(GATEWAY_SERVLET_ASYNC_SUPPORTED, GATEWAY_SERVLET_ASYNC_SUPPORTED_DEFAULT);
+  }
 }
diff --git a/gateway-server/src/main/java/org/apache/knox/gateway/deploy/DeploymentFactory.java b/gateway-server/src/main/java/org/apache/knox/gateway/deploy/DeploymentFactory.java
index 170c76b2c..323458eff 100644
--- a/gateway-server/src/main/java/org/apache/knox/gateway/deploy/DeploymentFactory.java
+++ b/gateway-server/src/main/java/org/apache/knox/gateway/deploy/DeploymentFactory.java
@@ -193,7 +193,7 @@ public abstract class DeploymentFactory {
       Map<String,List<ProviderDeploymentContributor>> providers,
       Map<String,List<ServiceDeploymentContributor>> services ) {
     DeploymentContext context = createDeploymentContext( config, "/", topology, providers );
-    initialize( context, providers, services, null );
+    initialize(context, providers, services, null, config);
     contribute( context, providers, services, null );
     finish( context, providers, services, null );
     return context.getWebArchive();
@@ -206,7 +206,7 @@ public abstract class DeploymentFactory {
       Map.Entry<String,ServiceDeploymentContributor> application ) {
     String appPath = "/" + Urls.trimLeadingAndTrailingSlash( application.getKey() );
     DeploymentContext context = createDeploymentContext( config, appPath, topology, providers );
-    initialize( context, providers, null, application );
+    initialize(context, providers, null, application, config);
     contribute( context, providers, null, application );
     finish( context, providers, null, application );
     return context.getWebArchive();
@@ -364,16 +364,17 @@ public abstract class DeploymentFactory {
       DeploymentContext context,
       Map<String,List<ProviderDeploymentContributor>> providers,
       Map<String,List<ServiceDeploymentContributor>> services,
-      Map.Entry<String,ServiceDeploymentContributor> applications ) {
+      Map.Entry<String,ServiceDeploymentContributor> applications,
+      GatewayConfig gatewayConfig) {
     WebAppDescriptor wad = context.getWebAppDescriptor();
     String topoName = context.getTopology().getName();
     if( applications == null ) {
       String servletName = topoName + SERVLET_NAME_SUFFIX;
-      wad.createServlet().servletName( servletName ).servletClass( GatewayServlet.class.getName() );
+      wad.createServlet().asyncSupported(gatewayConfig.isAsyncSupported()).servletName(servletName).servletClass(GatewayServlet.class.getName());
       wad.createServletMapping().servletName( servletName ).urlPattern( "/*" );
     } else {
       String filterName = topoName + FILTER_NAME_SUFFIX;
-      wad.createFilter().filterName( filterName ).filterClass( GatewayServlet.class.getName() );
+      wad.createFilter().asyncSupported(gatewayConfig.isAsyncSupported()).filterName(filterName).filterClass(GatewayServlet.class.getName());
       wad.createFilterMapping().filterName( filterName ).urlPattern( "/*" );
     }
     if (gatewayServices != null) {
diff --git a/gateway-server/src/main/java/org/apache/knox/gateway/deploy/impl/ApplicationDeploymentContributor.java b/gateway-server/src/main/java/org/apache/knox/gateway/deploy/impl/ApplicationDeploymentContributor.java
index eac88d824..931eb6b09 100644
--- a/gateway-server/src/main/java/org/apache/knox/gateway/deploy/impl/ApplicationDeploymentContributor.java
+++ b/gateway-server/src/main/java/org/apache/knox/gateway/deploy/impl/ApplicationDeploymentContributor.java
@@ -229,6 +229,7 @@ public class ApplicationDeploymentContributor extends ServiceDeploymentContribut
   }
 
   private void addDefaultPolicies( DeploymentContext context, Service service, Map<String, String> filterParams, List<FilterParamDescriptor> params, ResourceDescriptor resource) throws URISyntaxException {
+    addDoSFilter(context, service, resource);
     addWebAppSecFilters(context, service, resource);
     addAuthenticationFilter(context, service, resource);
     addRewriteFilter(context, service, filterParams, params, resource);
diff --git a/gateway-server/src/main/java/org/apache/knox/gateway/deploy/impl/ServiceDefinitionDeploymentContributor.java b/gateway-server/src/main/java/org/apache/knox/gateway/deploy/impl/ServiceDefinitionDeploymentContributor.java
index 1a9a7eb36..09f63ab42 100644
--- a/gateway-server/src/main/java/org/apache/knox/gateway/deploy/impl/ServiceDefinitionDeploymentContributor.java
+++ b/gateway-server/src/main/java/org/apache/knox/gateway/deploy/impl/ServiceDefinitionDeploymentContributor.java
@@ -213,6 +213,7 @@ public class ServiceDefinitionDeploymentContributor extends ServiceDeploymentCon
   }
 
   private void addDefaultPolicies(DeploymentContext context, Service service, Map<String, String> filterParams, List<FilterParamDescriptor> params, ResourceDescriptor resource) throws URISyntaxException {
+    addDoSFilter(context, service, resource);
     addWebAppSecFilters(context, service, resource);
     addAuthenticationFilter(context, service, resource);
     addRewriteFilter(context, service, filterParams, params, resource);
diff --git a/gateway-spi-common/src/main/java/org/apache/knox/gateway/GatewayTestConfig.java b/gateway-spi-common/src/main/java/org/apache/knox/gateway/GatewayTestConfig.java
index a3bbc4079..388b21188 100644
--- a/gateway-spi-common/src/main/java/org/apache/knox/gateway/GatewayTestConfig.java
+++ b/gateway-spi-common/src/main/java/org/apache/knox/gateway/GatewayTestConfig.java
@@ -978,4 +978,9 @@ public class GatewayTestConfig extends Configuration implements GatewayConfig {
   public long getConcurrentSessionVerifierExpiredTokensCleaningPeriod() {
     return 0;
   }
+
+  @Override
+  public boolean isAsyncSupported() {
+    return false;
+  }
 }
diff --git a/gateway-spi/src/main/java/org/apache/knox/gateway/config/GatewayConfig.java b/gateway-spi/src/main/java/org/apache/knox/gateway/config/GatewayConfig.java
index 49b056850..773d04055 100644
--- a/gateway-spi/src/main/java/org/apache/knox/gateway/config/GatewayConfig.java
+++ b/gateway-spi/src/main/java/org/apache/knox/gateway/config/GatewayConfig.java
@@ -825,4 +825,9 @@ public interface GatewayConfig {
   Set<String> getSessionVerificationUnlimitedUsers();
 
   long getConcurrentSessionVerifierExpiredTokensCleaningPeriod();
+
+  /**
+   * @return true if the async supported flag is enabled in jetty gateway servlet; false otherwise (defaults to false)
+   */
+  boolean isAsyncSupported();
 }
diff --git a/gateway-spi/src/main/java/org/apache/knox/gateway/deploy/ProviderDeploymentContributorBase.java b/gateway-spi/src/main/java/org/apache/knox/gateway/deploy/ProviderDeploymentContributorBase.java
index f796dc63c..c988ea012 100644
--- a/gateway-spi/src/main/java/org/apache/knox/gateway/deploy/ProviderDeploymentContributorBase.java
+++ b/gateway-spi/src/main/java/org/apache/knox/gateway/deploy/ProviderDeploymentContributorBase.java
@@ -17,6 +17,12 @@
  */
 package org.apache.knox.gateway.deploy;
 
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import org.apache.knox.gateway.descriptor.FilterParamDescriptor;
+import org.apache.knox.gateway.descriptor.ResourceDescriptor;
 import org.apache.knox.gateway.topology.Provider;
 
 public abstract class ProviderDeploymentContributorBase extends DeploymentContributorBase implements ProviderDeploymentContributor {
@@ -36,4 +42,15 @@ public abstract class ProviderDeploymentContributorBase extends DeploymentContri
     // Noop.
   }
 
+  protected void copyAllProviderParams(Provider provider, ResourceDescriptor resource, List<FilterParamDescriptor> params) {
+    copyAllProviderParams(provider, resource, params, true);
+  }
+
+  protected void copyAllProviderParams(Provider provider, ResourceDescriptor resource, List<FilterParamDescriptor> params, boolean useLowerCaseKeys) {
+    for (Map.Entry<String, String> entry : provider.getParams().entrySet()) {
+      String key = useLowerCaseKeys ? entry.getKey().toLowerCase(Locale.ROOT) : entry.getKey();
+      params.add(resource.createFilterParam().name(key).value(entry.getValue()));
+    }
+  }
+
 }
diff --git a/gateway-spi/src/main/java/org/apache/knox/gateway/deploy/ServiceDeploymentContributorBase.java b/gateway-spi/src/main/java/org/apache/knox/gateway/deploy/ServiceDeploymentContributorBase.java
index e80311296..bfec05bdd 100644
--- a/gateway-spi/src/main/java/org/apache/knox/gateway/deploy/ServiceDeploymentContributorBase.java
+++ b/gateway-spi/src/main/java/org/apache/knox/gateway/deploy/ServiceDeploymentContributorBase.java
@@ -128,4 +128,10 @@ public abstract class ServiceDeploymentContributorBase extends DeploymentContrib
     context.contributeFilter( service, resource, role, name, params );
   }
 
+  protected void addDoSFilter(DeploymentContext context, Service service, ResourceDescriptor resource) {
+    if (topologyContainsProviderType(context, "dos")) {
+      context.contributeFilter(service, resource, "dos", null, null);
+    }
+  }
+
 }
diff --git a/pom.xml b/pom.xml
index fe6e4f85a..4c7893d95 100644
--- a/pom.xml
+++ b/pom.xml
@@ -94,6 +94,7 @@
         <module>gateway-provider-security-authz-acls</module>
         <module>gateway-provider-security-authz-composite</module>
         <module>gateway-provider-security-authc-anon</module>
+        <module>gateway-provider-security-dos</module>
         <module>gateway-provider-identity-assertion-common</module>
         <module>gateway-provider-identity-assertion-concat</module>
         <module>gateway-provider-identity-assertion-hadoop-groups</module>
@@ -1299,6 +1300,11 @@
                 <type>pom</type>
                 <scope>import</scope>
             </dependency>
+            <dependency>
+                <groupId>org.eclipse.jetty</groupId>
+                <artifactId>jetty-servlets</artifactId>
+                <version>${jetty.version}</version>
+            </dependency>
             <!-- Need these additional due to classifier tests -->
             <dependency>
                 <groupId>org.eclipse.jetty</groupId>
@@ -2528,6 +2534,11 @@
                 <version>${system-stubs-junit4.version}</version>
                 <scope>test</scope>
             </dependency>
+            <dependency>
+                <groupId>org.apache.knox</groupId>
+                <artifactId>gateway-provider-security-dos</artifactId>
+                <version>${project.version}</version>
+            </dependency>
         </dependencies>
     </dependencyManagement>