DosFilter can be disabled. (#561)
* DosFilter can be disabled. Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * Moved filters our of security core. Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * Move caffeine dependency. Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com>
This commit is contained in:
@@ -35,7 +35,6 @@ import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
||||
import org.eclipse.hawkbit.security.ControllerTenantAwareAuthenticationDetailsSource;
|
||||
import org.eclipse.hawkbit.security.DdiSecurityProperties;
|
||||
import org.eclipse.hawkbit.security.DosFilter;
|
||||
import org.eclipse.hawkbit.security.ExcludePathAwareShallowETagFilter;
|
||||
import org.eclipse.hawkbit.security.HawkbitSecurityProperties;
|
||||
import org.eclipse.hawkbit.security.HttpControllerPreAuthenticateAnonymousDownloadFilter;
|
||||
import org.eclipse.hawkbit.security.HttpControllerPreAuthenticateSecurityTokenFilter;
|
||||
@@ -51,6 +50,7 @@ import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.autoconfigure.security.SecurityProperties;
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
|
||||
@@ -172,6 +172,7 @@ public class SecurityManagedConfiguration {
|
||||
* of service protection filter in the filter chain
|
||||
*/
|
||||
@Bean
|
||||
@ConditionalOnProperty(prefix = "hawkbit.server.security.dos.filter", name = "enabled", matchIfMissing = true)
|
||||
public FilterRegistrationBean dosDDiFilter(final HawkbitSecurityProperties securityProperties) {
|
||||
|
||||
final FilterRegistrationBean filterRegBean = dosFilter(Arrays.asList(DDI_ANT_MATCHER),
|
||||
@@ -262,6 +263,7 @@ public class SecurityManagedConfiguration {
|
||||
* service protection filter in the filter chain
|
||||
*/
|
||||
@Bean
|
||||
@ConditionalOnProperty(prefix = "hawkbit.server.security.dos.filter", name = "enabled", matchIfMissing = true)
|
||||
public FilterRegistrationBean dosSystemFilter(final HawkbitSecurityProperties securityProperties) {
|
||||
|
||||
final FilterRegistrationBean filterRegBean = dosFilter(Collections.emptyList(),
|
||||
@@ -355,6 +357,7 @@ public class SecurityManagedConfiguration {
|
||||
* of service protection filter in the filter chain
|
||||
*/
|
||||
@Bean
|
||||
@ConditionalOnProperty(prefix = "hawkbit.server.security.dos.filter", name = "enabled", matchIfMissing = true)
|
||||
public FilterRegistrationBean dosMgmtFilter(final HawkbitSecurityProperties securityProperties) {
|
||||
|
||||
final FilterRegistrationBean filterRegBean = dosFilter(null, securityProperties.getDos().getFilter(),
|
||||
@@ -406,29 +409,6 @@ public class SecurityManagedConfiguration {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter registration bean for spring etag filter.
|
||||
*
|
||||
* @return the spring filter registration bean for registering an etag
|
||||
* filter in the filter chain
|
||||
*/
|
||||
@Bean
|
||||
@Order(380)
|
||||
public FilterRegistrationBean eTagFilter() {
|
||||
|
||||
final FilterRegistrationBean filterRegBean = new FilterRegistrationBean();
|
||||
// Exclude the URLs for downloading artifacts, so no eTag is generated
|
||||
// in the ShallowEtagHeaderFilter, just using the SH1 hash of the
|
||||
// artifact itself as 'ETag', because otherwise the file will be copied
|
||||
// in memory!
|
||||
filterRegBean.setFilter(new ExcludePathAwareShallowETagFilter("/UI/**",
|
||||
"/rest/v1/softwaremodules/{smId}/artifacts/{artId}/download",
|
||||
"/{tenant}/controller/v1/{controllerId}/softwaremodules/{softwareModuleId}/artifacts/**",
|
||||
"/api/v1/downloadserver/**"));
|
||||
|
||||
return filterRegBean;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link WebSecurityConfigurer} for external (management) access.
|
||||
*/
|
||||
@@ -457,6 +437,7 @@ public class SecurityManagedConfiguration {
|
||||
* of service protection filter in the filter chain
|
||||
*/
|
||||
@Bean
|
||||
@ConditionalOnProperty(prefix = "hawkbit.server.security.dos.ui-filter", name = "enabled", matchIfMissing = true)
|
||||
public FilterRegistrationBean dosMgmtUiFilter(final HawkbitSecurityProperties securityProperties) {
|
||||
|
||||
final FilterRegistrationBean filterRegBean = dosFilter(null, securityProperties.getDos().getUiFilter(),
|
||||
|
||||
@@ -19,9 +19,9 @@ import java.util.List;
|
||||
import org.eclipse.hawkbit.repository.model.Action;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
import org.eclipse.hawkbit.rest.filter.ExcludePathAwareShallowETagFilter;
|
||||
import org.eclipse.hawkbit.rest.util.JsonBuilder;
|
||||
import org.eclipse.hawkbit.security.DosFilter;
|
||||
import org.eclipse.hawkbit.security.ExcludePathAwareShallowETagFilter;
|
||||
import org.junit.Test;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
|
||||
@@ -39,6 +39,10 @@
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>javax.servlet-api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.ben-manes.caffeine</groupId>
|
||||
<artifactId>caffeine</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Test -->
|
||||
|
||||
@@ -11,10 +11,12 @@ package org.eclipse.hawkbit.rest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.eclipse.hawkbit.rest.exception.ResponseExceptionHandler;
|
||||
import org.eclipse.hawkbit.rest.filter.ExcludePathAwareShallowETagFilter;
|
||||
import org.eclipse.hawkbit.rest.util.FilterHttpResponse;
|
||||
import org.eclipse.hawkbit.rest.util.HttpResponseFactoryBean;
|
||||
import org.eclipse.hawkbit.rest.util.RequestResponseContextHolder;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
@@ -64,4 +66,26 @@ public class RestConfiguration {
|
||||
ResponseExceptionHandler responseExceptionHandler() {
|
||||
return new ResponseExceptionHandler();
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter registration bean for spring etag filter.
|
||||
*
|
||||
* @return the spring filter registration bean for registering an etag
|
||||
* filter in the filter chain
|
||||
*/
|
||||
@Bean
|
||||
FilterRegistrationBean eTagFilter() {
|
||||
|
||||
final FilterRegistrationBean filterRegBean = new FilterRegistrationBean();
|
||||
// Exclude the URLs for downloading artifacts, so no eTag is generated
|
||||
// in the ShallowEtagHeaderFilter, just using the SH1 hash of the
|
||||
// artifact itself as 'ETag', because otherwise the file will be copied
|
||||
// in memory!
|
||||
filterRegBean.setFilter(new ExcludePathAwareShallowETagFilter("/UI/**",
|
||||
"/rest/v1/softwaremodules/{smId}/artifacts/{artId}/download",
|
||||
"/{tenant}/controller/v1/{controllerId}/softwaremodules/{softwareModuleId}/artifacts/**",
|
||||
"/api/v1/downloadserver/**"));
|
||||
|
||||
return filterRegBean;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*/
|
||||
package org.eclipse.hawkbit.security;
|
||||
package org.eclipse.hawkbit.rest.filter;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@@ -10,8 +10,8 @@ package org.eclipse.hawkbit.rest;
|
||||
|
||||
import org.eclipse.hawkbit.repository.jpa.RepositoryApplicationConfiguration;
|
||||
import org.eclipse.hawkbit.repository.test.util.AbstractIntegrationTest;
|
||||
import org.eclipse.hawkbit.rest.filter.ExcludePathAwareShallowETagFilter;
|
||||
import org.eclipse.hawkbit.rest.util.FilterHttpResponse;
|
||||
import org.eclipse.hawkbit.security.ExcludePathAwareShallowETagFilter;
|
||||
import org.junit.Before;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.SpringApplicationConfiguration;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*/
|
||||
package org.eclipse.hawkbit.security;
|
||||
package org.eclipse.hawkbit.rest.filter;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.mockingDetails;
|
||||
@@ -21,6 +21,7 @@ import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.eclipse.hawkbit.rest.filter.ExcludePathAwareShallowETagFilter;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
@@ -31,14 +31,6 @@
|
||||
<artifactId>javax.servlet-api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.ben-manes.caffeine</groupId>
|
||||
<artifactId>caffeine</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
|
||||
@@ -159,10 +159,15 @@ public class HawkbitSecurityProperties {
|
||||
|
||||
/**
|
||||
* Configuration for hawkBits DOS prevention filter. This is usually an
|
||||
* infrastructure topic but might be useful in some cases.
|
||||
* infrastructure topic (e.g. Web Application Firewall (WAF)) but might
|
||||
* be useful in some cases, e.g. to prevent unintended misuse.
|
||||
*
|
||||
*/
|
||||
public static class Filter {
|
||||
/**
|
||||
* True if filter is enabled.
|
||||
*/
|
||||
private boolean enabled = true;
|
||||
|
||||
/**
|
||||
* White list of peer IP addresses for DOS filter (regular
|
||||
@@ -172,16 +177,24 @@ public class HawkbitSecurityProperties {
|
||||
|
||||
/**
|
||||
* # Maximum number of allowed REST read/GET requests per second per
|
||||
* client.
|
||||
* client IP.
|
||||
*/
|
||||
int maxRead = 200;
|
||||
|
||||
/**
|
||||
* Maximum number of allowed REST write/(PUT/POST/etc.) requests per
|
||||
* second per client.
|
||||
* second per client IP.
|
||||
*/
|
||||
int maxWrite = 50;
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(final boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public String getWhitelist() {
|
||||
return whitelist;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user