You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2020/11/26 19:04:44 UTC

[tomcat] branch 7.0.x updated: Fix BZ 56181 - return correct remoteHost with RemoteIP[Valve|Filter]

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

markt pushed a commit to branch 7.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/7.0.x by this push:
     new 2e832af  Fix BZ 56181 - return correct remoteHost with RemoteIP[Valve|Filter]
2e832af is described below

commit 2e832afd3ba43f7f09d6a58e0d583e140c94b617
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Thu Nov 26 18:57:25 2020 +0000

    Fix BZ 56181 - return correct remoteHost with RemoteIP[Valve|Filter]
    
    https://bz.apache.org/bugzilla/show_bug.cgi?id=56181
---
 .../catalina/filters/LocalStrings.properties       |  1 +
 .../apache/catalina/filters/RemoteIpFilter.java    | 42 +++++++++++++++++++++-
 .../apache/catalina/valves/LocalStrings.properties |  2 +-
 .../catalina/valves/LocalStrings_es.properties     |  1 -
 java/org/apache/catalina/valves/RemoteIpValve.java | 19 +++++++++-
 webapps/docs/changelog.xml                         | 10 ++++++
 webapps/docs/config/filter.xml                     |  6 ++++
 7 files changed, 77 insertions(+), 4 deletions(-)

diff --git a/java/org/apache/catalina/filters/LocalStrings.properties b/java/org/apache/catalina/filters/LocalStrings.properties
index 2e9f564..5877b76 100644
--- a/java/org/apache/catalina/filters/LocalStrings.properties
+++ b/java/org/apache/catalina/filters/LocalStrings.properties
@@ -58,6 +58,7 @@ remoteCidrFilter.noRemoteIp=Client does not have an IP address. Request denied.
 remoteIpFilter.invalidHostHeader=Invalid value [{0}] found for Host in HTTP header [{1}]
 remoteIpFilter.invalidHostWithPort=Host value [{0}] in HTTP header [{1}] included a port number which will be ignored
 remoteIpFilter.invalidNumber=Illegal number for parameter [{0}]: [{1}]
+remoteIpFilter.invalidRemoteAddress=Unable to determine the remote host because the reported remote address [{0}] is not valid
 
 requestFilter.deny=Denied request for [{0}] based on property [{1}]
 
diff --git a/java/org/apache/catalina/filters/RemoteIpFilter.java b/java/org/apache/catalina/filters/RemoteIpFilter.java
index 188176d..ed04087 100644
--- a/java/org/apache/catalina/filters/RemoteIpFilter.java
+++ b/java/org/apache/catalina/filters/RemoteIpFilter.java
@@ -17,6 +17,8 @@
 package org.apache.catalina.filters;
 
 import java.io.IOException;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
 import java.util.Collections;
 import java.util.Enumeration;
 import java.util.HashMap;
@@ -160,6 +162,13 @@ import org.apache.tomcat.util.res.StringManager;
  * <td>integer</td>
  * <td>443</td>
  * </tr>
+ * <tr>
+ * <td>enableLookups</td>
+ * <td>Should a DNS lookup be performed to provide a host name when calling {@link ServletRequest#getRemoteHost()}</td>
+ * <td>N/A</td>
+ * <td>boolean</td>
+ * <td>false</td>
+ * </tr>
  * </table>
  * <p>
  * <strong>Regular expression vs. IP address blocks:</strong> <code>mod_remoteip</code> allows to use address blocks (e.g.
@@ -676,6 +685,8 @@ public class RemoteIpFilter implements Filter {
 
     protected static final String TRUSTED_PROXIES_PARAMETER = "trustedProxies";
 
+    protected static final String ENABLE_LOOKUPS_PARAMETER = "enableLookups";
+
     /**
      * Convert a given comma delimited list of regular expressions into an array of String
      *
@@ -765,6 +776,8 @@ public class RemoteIpFilter implements Filter {
      */
     private Pattern trustedProxies = null;
 
+    private boolean enableLookups;
+
     @Override
     public void destroy() {
         // NOOP
@@ -820,7 +833,22 @@ public class RemoteIpFilter implements Filter {
             if (remoteIp != null) {
 
                 xRequest.setRemoteAddr(remoteIp);
-                xRequest.setRemoteHost(remoteIp);
+                if (getEnableLookups()) {
+                    // This isn't a lazy lookup but that would be a little more
+                    // invasive - mainly in XForwardedRequest - and if
+                    // enableLookups is true is seems reasonable that the
+                    // hostname will be required so look it up here.
+                    try {
+                        InetAddress inetAddress = InetAddress.getByName(remoteIp);
+                        // We know we need a DNS look up so use getCanonicalHostName()
+                        xRequest.setRemoteHost(inetAddress.getCanonicalHostName());
+                    } catch (UnknownHostException e) {
+                        log.debug(sm.getString("remoteIpFilter.invalidRemoteAddress", remoteIp), e);
+                        xRequest.setRemoteHost(remoteIp);
+                    }
+                } else {
+                    xRequest.setRemoteHost(remoteIp);
+                }
 
                 if (proxiesHeaderValue.size() == 0) {
                     xRequest.removeHeader(proxiesHeader);
@@ -1010,6 +1038,10 @@ public class RemoteIpFilter implements Filter {
         return trustedProxies;
     }
 
+    public boolean getEnableLookups() {
+        return enableLookups;
+    }
+
     @Override
     public void init(FilterConfig filterConfig) throws ServletException {
         if (filterConfig.getInitParameter(INTERNAL_PROXIES_PARAMETER) != null) {
@@ -1067,6 +1099,10 @@ public class RemoteIpFilter implements Filter {
                 throw new NumberFormatException(sm.getString("remoteIpFilter.invalidNumber", HTTPS_SERVER_PORT_PARAMETER, e.getLocalizedMessage()));
             }
         }
+
+        if (filterConfig.getInitParameter(ENABLE_LOOKUPS_PARAMETER) != null) {
+            setEnableLookups(Boolean.parseBoolean(filterConfig.getInitParameter(ENABLE_LOOKUPS_PARAMETER)));
+        }
     }
 
     /**
@@ -1278,4 +1314,8 @@ public class RemoteIpFilter implements Filter {
             this.trustedProxies = Pattern.compile(trustedProxies);
         }
     }
+
+    public void setEnableLookups(boolean enableLookups) {
+        this.enableLookups = enableLookups;
+    }
 }
diff --git a/java/org/apache/catalina/valves/LocalStrings.properties b/java/org/apache/catalina/valves/LocalStrings.properties
index a5d260e..6ad98b0 100644
--- a/java/org/apache/catalina/valves/LocalStrings.properties
+++ b/java/org/apache/catalina/valves/LocalStrings.properties
@@ -128,7 +128,7 @@ remoteCidrValve.noRemoteIp=Client does not have an IP address. Request denied.
 remoteIpValve.invalidHostHeader=Invalid value [{0}] found for Host in HTTP header [{1}]
 remoteIpValve.invalidHostWithPort=Host value [{0}] in HTTP header [{1}] included a port number which will be ignored
 remoteIpValve.invalidPortHeader=Invalid value [{0}] found for port in HTTP header [{1}]
-remoteIpValve.syntax=Invalid regular expressions [{0}] provided.
+remoteIpValve.invalidRemoteAddress=Unable to determine the remote host because the reported remote address [{0}] is not valid
 
 requestFilterValve.configInvalid=One or more invalid configuration settings were provided for the Remote[Addr|Host]Valve which prevented the Valve and its parent containers from starting
 requestFilterValve.deny=Denied request for [{0}] based on property [{1}]
diff --git a/java/org/apache/catalina/valves/LocalStrings_es.properties b/java/org/apache/catalina/valves/LocalStrings_es.properties
index b3d55f0..824a616 100644
--- a/java/org/apache/catalina/valves/LocalStrings_es.properties
+++ b/java/org/apache/catalina/valves/LocalStrings_es.properties
@@ -79,7 +79,6 @@ jdbcAccessLogValve.close=Excepción cerrando conexión a base de datos
 jdbcAccessLogValve.exception=Excepción realizando entrada de acceso a inserción
 
 remoteIpValve.invalidPortHeader=Valor inválido [{0}] hallado para el puerto en cabecera HTTP [{1}]
-remoteIpValve.syntax=Se han suministrado expresiones regulares [{0}] no válidas.
 
 requestFilterValve.configInvalid=Uno o más parámetros de configuración inválidos fueron proveídos para  Remote[Addr|Host]Valve lo cual impide que el Valve y sus contenedores padres puedan iniciar
 requestFilterValve.next=No hay ''siguiente'' válvula configurada
diff --git a/java/org/apache/catalina/valves/RemoteIpValve.java b/java/org/apache/catalina/valves/RemoteIpValve.java
index b7c722a..823a1ee 100644
--- a/java/org/apache/catalina/valves/RemoteIpValve.java
+++ b/java/org/apache/catalina/valves/RemoteIpValve.java
@@ -17,6 +17,8 @@
 package org.apache.catalina.valves;
 
 import java.io.IOException;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
 import java.util.Enumeration;
 import java.util.Iterator;
 import java.util.LinkedList;
@@ -666,7 +668,22 @@ public class RemoteIpValve extends ValveBase {
             if (remoteIp != null) {
 
                 request.setRemoteAddr(remoteIp);
-                request.setRemoteHost(remoteIp);
+                if (request.getConnector().getEnableLookups()) {
+                    // This isn't a lazy lookup but that would be a little more
+                    // invasive - mainly in Request.getRemoteHost() - and if
+                    // enableLookups is true it seems reasonable that the
+                    // hotsname will be required so look it up here.
+                    try {
+                        InetAddress inetAddress = InetAddress.getByName(remoteIp);
+                        // We know we need a DNS look up so use getCanonicalHostName()
+                        request.setRemoteHost(inetAddress.getCanonicalHostName());
+                    } catch (UnknownHostException e) {
+                        log.debug(sm.getString("remoteIpValve.invalidRemoteAddress", remoteIp), e);
+                        request.setRemoteHost(remoteIp);
+                    }
+                } else {
+                    request.setRemoteHost(remoteIp);
+                }
 
                 if (proxiesHeaderValue.size() == 0) {
                     request.getCoyoteRequest().getMimeHeaders().removeHeader(proxiesHeader);
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 58a5f98..0dd2bd3 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -119,6 +119,16 @@
   issues do not "pop up" wrt. others).
 -->
 <section name="Tomcat 7.0.108 (violetagg)" rtext="in development">
+  <subsection name="Catalina">
+    <changelog>
+      <fix>
+        <bug>56181</bug>: Update the RemoteIpValve and RemoteIpFilter so that
+        calls to <code>ServletRequest.getRemoteHost()</code> are consistent with
+        the return value of <code>ServletRequest.getRemoteAddr()</code> rather
+        than always returning a value for the proxy. (markt)
+      </fix>
+    </changelog>
+  </subsection>
   <subsection name="Web applications">
     <changelog>
       <fix>
diff --git a/webapps/docs/config/filter.xml b/webapps/docs/config/filter.xml
index fbf6648..4e8c159 100644
--- a/webapps/docs/config/filter.xml
+++ b/webapps/docs/config/filter.xml
@@ -1551,6 +1551,12 @@ FINE: Request "/docs/config/manager.html" with response status "200"
 
     <attributes>
 
+      <attribute name="enableLookups" required="false">
+        <p>Should a DNS lookup be performed to provide a host name when calling
+        <code>ServletRequest#getRemoteHost()</code>. If not specified, the
+        default of <code>false</code> is used.</p>
+      </attribute>
+
       <attribute name="remoteIpHeader" required="false">
         <p>Name of the HTTP Header read by this valve that holds the list of
         traversed IP addresses starting from the requesting client. If not


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org