diff --git a/CHANGELOG.md b/CHANGELOG.md
index 82b01407e..9fe0509fa 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,6 +10,7 @@
* [HELM] Improved method for setting extra env variables on HTTP and MQTT pods.
* [HELM] Add database connection to Keycloak provider.
* Added setting for sessionCookiePath.
+* Added support for [Tomcat Remote IP Filter](https://tomcat.apache.org/tomcat-9.0-doc/config/filter.html#Remote_IP_Filter).
**Internal changes & Bugfixes**
* Improved generated queries when fetching entities over a one-to-many relation.
diff --git a/FROST-Server.HTTP.Common/src/main/java/de/fraunhofer/iosb/ilt/frostserver/http/common/AbstractContextListener.java b/FROST-Server.HTTP.Common/src/main/java/de/fraunhofer/iosb/ilt/frostserver/http/common/AbstractContextListener.java
index 2bf349b19..ad310d92f 100644
--- a/FROST-Server.HTTP.Common/src/main/java/de/fraunhofer/iosb/ilt/frostserver/http/common/AbstractContextListener.java
+++ b/FROST-Server.HTTP.Common/src/main/java/de/fraunhofer/iosb/ilt/frostserver/http/common/AbstractContextListener.java
@@ -93,6 +93,8 @@ public void contextInitialized(ServletContextEvent sce) {
initCoreSettings(context);
context.setAttribute(TAG_CORE_SETTINGS, coreSettings);
+ IpFilterHelper.setupRemoteIpFilter(context, coreSettings);
+
setUpCorsFilter(context, coreSettings);
PersistenceManagerFactory.init(coreSettings);
diff --git a/FROST-Server.HTTP.Common/src/main/java/de/fraunhofer/iosb/ilt/frostserver/http/common/IpFilterHelper.java b/FROST-Server.HTTP.Common/src/main/java/de/fraunhofer/iosb/ilt/frostserver/http/common/IpFilterHelper.java
new file mode 100644
index 000000000..3b123ce63
--- /dev/null
+++ b/FROST-Server.HTTP.Common/src/main/java/de/fraunhofer/iosb/ilt/frostserver/http/common/IpFilterHelper.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2024 Fraunhofer Institut IOSB, Fraunhoferstr. 1, D 76131
+ * Karlsruhe, Germany.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ */
+package de.fraunhofer.iosb.ilt.frostserver.http.common;
+
+import de.fraunhofer.iosb.ilt.frostserver.settings.ConfigProvider;
+import de.fraunhofer.iosb.ilt.frostserver.settings.CoreSettings;
+import de.fraunhofer.iosb.ilt.frostserver.settings.Settings;
+import de.fraunhofer.iosb.ilt.frostserver.settings.annotation.DefaultValueBoolean;
+import de.fraunhofer.iosb.ilt.frostserver.util.StringHelper;
+import java.util.EnumSet;
+import javax.servlet.DispatcherType;
+import javax.servlet.FilterRegistration;
+import javax.servlet.ServletContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Helper class for setting up the tomcat Remote-IP-Filter.
+ *
+ * @see
+ * https://tomcat.apache.org/tomcat-9.0-doc/config/filter.html#Remote_IP_Filter
+ */
+public class IpFilterHelper extends ConfigProvider {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(IpFilterHelper.class.getName());
+
+ public static final String PREFIX_REMOTE_IP_FILTER = "remoteIpFilter.";
+ public static final String NAME_REMOTE_IP_FILTER = "RemoteIpFilter";
+ public static final String NAME_CLASS_REMOTE_IP_FILTER = "org.apache.catalina.filters.RemoteIpFilter";
+
+ @DefaultValueBoolean(false)
+ public static final String TAG_ENABLE = "enable";
+
+ public IpFilterHelper(Settings settings) {
+ super(settings);
+ }
+
+ public static void setupRemoteIpFilter(ServletContext servletContext, CoreSettings coreSettings) {
+ Settings httpSettings = coreSettings.getHttpSettings();
+ new IpFilterHelper(httpSettings.getSubSettings(PREFIX_REMOTE_IP_FILTER))
+ .setupFilter(servletContext);
+
+ }
+
+ private void setupFilter(ServletContext servletContext) {
+ if (!getBoolean(TAG_ENABLE)) {
+ return;
+ }
+ try {
+ FilterRegistration.Dynamic ripFilter = servletContext.addFilter(NAME_REMOTE_IP_FILTER, NAME_CLASS_REMOTE_IP_FILTER);
+ ripFilter.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD), true, "/*");
+ setInitParameter(ripFilter, "enableLookups");
+ setInitParameter(ripFilter, "remoteIpHeader");
+ setInitParameter(ripFilter, "internalProxies");
+ setInitParameter(ripFilter, "proxiesHeader");
+ setInitParameter(ripFilter, "requestAttributesEnabled");
+ setInitParameter(ripFilter, "trustedProxies");
+ setInitParameter(ripFilter, "protocolHeader");
+ setInitParameter(ripFilter, "hostHeader");
+ setInitParameter(ripFilter, "hostHeader");
+ setInitParameter(ripFilter, "protocolHeaderHttpsValue");
+ setInitParameter(ripFilter, "httpServerPort");
+ setInitParameter(ripFilter, "httpsServerPort");
+ setInitParameter(ripFilter, "changeLocalName");
+ setInitParameter(ripFilter, "changeLocalPort");
+ } catch (Exception exc) {
+ LOGGER.error("Failed to initialise RemoteIpFilter.", exc);
+ }
+ }
+
+ private void setInitParameter(FilterRegistration.Dynamic filter, String pramName) {
+ String value = getSettings().get(pramName, "");
+ if (!StringHelper.isNullOrEmpty(value)) {
+ filter.setInitParameter(pramName, value);
+ }
+ }
+
+ @Override
+ public IpFilterHelper getThis() {
+ return this;
+ }
+
+}