You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by wr...@apache.org on 2009/04/09 17:54:33 UTC

svn commit: r763708 - in /httpd/sandbox/mod_remoteip: README mod_remoteip.c

Author: wrowe
Date: Thu Apr  9 15:54:33 2009
New Revision: 763708

URL: http://svn.apache.org/viewvc?rev=763708&view=rev
Log:
Address a few of Colm's concerns; 

  The ->internal designations were not initialized properly; fixed.

  If no explicit servers are defined, apply absolute (intranet) 
  trust to the contents of the designated RemoteIPHeader
  (e.g. a load balancer originated header).

  Collect all of the applicable IP host addresses for each hostname
  (e.g. A and AAAA) and disallow hostname/subnet syntax.

Modified:
    httpd/sandbox/mod_remoteip/README
    httpd/sandbox/mod_remoteip/mod_remoteip.c

Modified: httpd/sandbox/mod_remoteip/README
URL: http://svn.apache.org/viewvc/httpd/sandbox/mod_remoteip/README?rev=763708&r1=763707&r2=763708&view=diff
==============================================================================
--- httpd/sandbox/mod_remoteip/README (original)
+++ httpd/sandbox/mod_remoteip/README Thu Apr  9 15:54:33 2009
@@ -66,7 +66,7 @@
 trusted internal proxies, specify one or more IP's (or IP prefixes such as
 the pattern "10.", or IP with /subnet bits) using any combination of;
 
-  RemoteIPInternalProxy [IP|IP/subnet|hostname]...
+  RemoteIPInternalProxy [hostname|IP|IP/subnet]...
   RemoteIPInternalProxyList filename
 
 where the filename contains entries, one or more per line, of IP, IP/subnet
@@ -78,18 +78,21 @@
 
  * http://meta.wikimedia.org/wiki/XFF_project
 
-  RemoteIPTrustedProxy [IP|IP/subnet|hostname]...
+  RemoteIPTrustedProxy [hostname|IP|IP/subnet]...
   RemoteIPTrustedProxyList filename
 
 The Proxy/ProxyList directives should accept hostnames, although these then
-must be translated to IP when added to the table.
+must be translated to IP when added to the table which can be an agonizingly
+slow process for a long proxy list.  An inverted flavor of logresolve would
+be very useful here.  
 
 There is a second tier of issues.  We will only recognize private IP
 addresses when presented by a specific internal proxy or chain of internal 
 proxies.  On balance, most private addresses from external trusted proxies
 are not useful.  RFC 1918 defines these as 10./8, 172.16./12 and 192.168./16, 
-and even 127./8 may be of interest for purposes of testing or remoting one 
-particular box.  Other non-extranet patterns are similarly disallowed.
+and even 169.254./16 or 127./8 may be of interest for purposes of testing or 
+remoting one particular box.  Similarly all IPv6 addresses outside of the 
+public 2000::/3 block are handled as private addresses.
 
 If a given proxy is trusted, but not one of our private proxies, and indicates
 that its immediate X-Forwarded-For pointer is within a private subnet, that

Modified: httpd/sandbox/mod_remoteip/mod_remoteip.c
URL: http://svn.apache.org/viewvc/httpd/sandbox/mod_remoteip/mod_remoteip.c?rev=763708&r1=763707&r2=763708&view=diff
==============================================================================
--- httpd/sandbox/mod_remoteip/mod_remoteip.c (original)
+++ httpd/sandbox/mod_remoteip/mod_remoteip.c Thu Apr  9 15:54:33 2009
@@ -141,20 +141,36 @@
     if (!config->proxymatch_ip)
         config->proxymatch_ip = apr_array_make(cmd->pool, 1, sizeof(*match));
     match = (remoteip_proxymatch_t *) apr_array_push(config->proxymatch_ip);
+    match->internal = (int)internal;
 
-    if (!looks_like_ip(ip)) {
+    if (looks_like_ip(ip)) {
+        /* Note s may be null, that's fine (explicit host) */
+        rv = apr_ipsubnet_create(&match->ip, ip, s, cmd->pool);
+    }
+    else
+    {
         apr_sockaddr_t *temp_sa;
+
+        if (s) {
+            return apr_pstrcat(cmd->pool, "RemoteIP: Error parsing IP ", arg, 
+                               " the subnet /", s, " is invalid for ", 
+                               cmd->cmd->name, NULL);
+        }
+
         rv = apr_sockaddr_info_get(&temp_sa,  ip, APR_UNSPEC, 0,
                                    APR_IPV4_ADDR_OK, cmd->temp_pool);
-        if (rv == APR_SUCCESS) 
+        while (rv == APR_SUCCESS)
+        {
             apr_sockaddr_ip_get(&ip, temp_sa);
+            rv = apr_ipsubnet_create(&match->ip, ip, NULL, cmd->pool);
+            if (!(temp_sa = temp_sa->next))
+                break;
+            match = (remoteip_proxymatch_t *) 
+                    apr_array_push(config->proxymatch_ip);
+            match->internal = (int)internal;
+        }
     }
 
-    if (s)
-        rv = apr_ipsubnet_create(&match->ip, ip, s, cmd->pool);
-    else
-        rv = apr_ipsubnet_create(&match->ip, ip, NULL, cmd->pool);
-
     if (rv != APR_SUCCESS) {
         char msgbuf[128];
         apr_strerror(rv, msgbuf, sizeof(msgbuf));
@@ -325,26 +341,27 @@
         }
 
         addrbyte = (unsigned char *) &temp_sa->sa.sin.sin_addr;
+
+        /* For intranet (Internal proxies) ignore all restrictions below */
         if (!internal
               && ((temp_sa->family == APR_INET
-                         /* denying 127. loopback, 10., 172.240..., 192.168. 
-                          * private subnets, and Class D and E special subnets
-                          */
-                      && (addrbyte[0] == 127
-                       || addrbyte[0] == 10
-                       || (addrbyte[0] == 172 && (addrbyte[1] & 0xf0) == 0xf0)
-                       || (addrbyte[0] == 192 && addrbyte[1] == 168)
+                   /* For internet (non-Internal proxies) deny all
+                    * RFC3330 designated local/private subnets:
+                    * 10.0.0.0/8   169.254.0.0/16  192.168.0.0/16 
+                    * 127.0.0.0/8  172.16.0.0/12
+                    */
+                      && (addrbyte[0] == 10
+                       || addrbyte[0] == 127
                        || (addrbyte[0] == 169 && addrbyte[1] == 254)
-                       || (addrbyte[0] & 0xe0) == 0xe0))
+                       || (addrbyte[0] == 172 && (addrbyte[1] & 0xf0) == 16)
+                       || (addrbyte[0] == 192 && addrbyte[1] == 168)))
 #if APR_HAVE_IPV6
                || (temp_sa->family == APR_INET6
-                         /* we translated IPv4-over-IPv6-mapped addresses 
-                          * as IPv4 above, all that is left to deny are 
-                          * multicast, special subnets, etc etc, where the
-                          * high nibble of the address is 0 or f
-                          */
-                      && ((temp_sa->sa.sin6.sin6_addr.s6_addr[0] & 0xf0) == 0x00
-                       || (temp_sa->sa.sin6.sin6_addr.s6_addr[0] & 0xf0) == 0xf0))
+                   /* For internet (non-Internal proxies) we translated 
+                    * IPv4-over-IPv6-mapped addresses as IPv4, above.
+                    * Accept only Global Unicast 2000::/3 defined by RFC4291
+                    */
+                      && ((temp_sa->sa.sin6.sin6_addr.s6_addr[0] & 0xe0) != 0x20))
 #endif
         )) {
             ap_log_rerror(APLOG_MARK, APLOG_DEBUG,  rv, r,