]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Allow proxy-surrogate to be used with any traffic mode
authorAmos Jeffries <squid3@treenet.co.nz>
Fri, 25 Jul 2014 08:27:38 +0000 (01:27 -0700)
committerAmos Jeffries <squid3@treenet.co.nz>
Fri, 25 Jul 2014 08:27:38 +0000 (01:27 -0700)
The accel/intercept/tproxy mode flag when used with proxy-surrogate
indicates what type of traffic the remote client used to receive this
traffic.

* disable use on https_port

* disable TPROXY spoofing when the PROXY header provides client IP

src/anyp/TrafficMode.h
src/cache_cf.cc
src/cf.data.pre
src/client_side.cc

index 4e5bea7b299eb0c0de8b54861e1605183af75d7c..eb03cf9bac704cedc42817a3e6a166bcabcd3b95 100644 (file)
@@ -30,8 +30,8 @@ public:
      * Indicating the following are required:
      *  - PROXY protocol magic header
      *  - src/dst IP retrieved from magic PROXY header
-     *  - reverse-proxy traffic prohibited
-     *  - intercepted traffic prohibited
+     *  - indirect client IP trust verification is mandatory
+     *  - TLS is not supported
      */
     bool proxySurrogate;
 
index f65c34e93022b84699e6a4b1dcf6e5864a84ed7c..e7ccd2f155bfe1a4aded4c002e9cb266e8223b0d 100644 (file)
@@ -3566,14 +3566,14 @@ parse_port_option(AnyP::PortCfg * s, char *token)
     /* modes first */
 
     if (strcmp(token, "accel") == 0) {
-        if (s->flags.isIntercepted() || s->flags.proxySurrogate) {
+        if (s->flags.isIntercepted()) {
             debugs(3, DBG_CRITICAL, "FATAL: http(s)_port: Accelerator mode requires its own port. It cannot be shared with other modes.");
             self_destruct();
         }
         s->flags.accelSurrogate = true;
         s->vhost = true;
     } else if (strcmp(token, "transparent") == 0 || strcmp(token, "intercept") == 0) {
-        if (s->flags.accelSurrogate || s->flags.tproxyIntercept || s->flags.proxySurrogate) {
+        if (s->flags.accelSurrogate || s->flags.tproxyIntercept) {
             debugs(3, DBG_CRITICAL, "FATAL: http(s)_port: Intercept mode requires its own interception port. It cannot be shared with other modes.");
             self_destruct();
         }
@@ -3583,7 +3583,7 @@ parse_port_option(AnyP::PortCfg * s, char *token)
         debugs(3, DBG_IMPORTANT, "Starting Authentication on port " << s->s);
         debugs(3, DBG_IMPORTANT, "Disabling Authentication on port " << s->s << " (interception enabled)");
     } else if (strcmp(token, "tproxy") == 0) {
-        if (s->flags.natIntercept || s->flags.accelSurrogate || s->flags.proxySurrogate) {
+        if (s->flags.natIntercept || s->flags.accelSurrogate) {
             debugs(3,DBG_CRITICAL, "FATAL: http(s)_port: TPROXY option requires its own interception port. It cannot be shared with other modes.");
             self_destruct();
         }
@@ -3592,17 +3592,18 @@ parse_port_option(AnyP::PortCfg * s, char *token)
         /* Log information regarding the port modes under transparency. */
         debugs(3, DBG_IMPORTANT, "Disabling Authentication on port " << s->s << " (TPROXY enabled)");
 
+        if (s->flags.proxySurrogate) {
+            debugs(3, DBG_IMPORTANT, "Disabling TPROXY Spoofing on port " << s->s << " (proxy-surrogate enabled)");
+        }
+
         if (!Ip::Interceptor.ProbeForTproxy(s->s)) {
             debugs(3, DBG_CRITICAL, "FATAL: http(s)_port: TPROXY support in the system does not work.");
             self_destruct();
         }
 
     } else if (strcmp(token, "proxy-surrogate") == 0) {
-        if (s->flags.natIntercept || s->flags.accelSurrogate  || s->flags.tproxyIntercept) {
-            debugs(3,DBG_CRITICAL, "FATAL: http(s)_port: proxy-surrogate option requires its own port. It cannot be shared with other modes.");
-            self_destruct();
-        }
         s->flags.proxySurrogate = true;
+        debugs(3, DBG_IMPORTANT, "Disabling TPROXY Spoofing on port " << s->s << " (proxy-surrogate enabled)");
 
     } else if (strncmp(token, "defaultsite=", 12) == 0) {
         if (!s->flags.accelSurrogate) {
@@ -3802,8 +3803,8 @@ parsePortCfg(AnyP::PortCfg ** head, const char *optionName)
         parse_port_option(s, token);
     }
 
-#if USE_OPENSSL
     if (s->transport.protocol == AnyP::PROTO_HTTPS) {
+#if USE_OPENSSL
         /* ssl-bump on https_port configuration requires either tproxy or intercept, and vice versa */
         const bool hijacked = s->flags.isIntercepted();
         if (s->flags.tunnelSslBumping && !hijacked) {
@@ -3814,8 +3815,12 @@ parsePortCfg(AnyP::PortCfg ** head, const char *optionName)
             debugs(3, DBG_CRITICAL, "FATAL: tproxy/intercept on https_port requires ssl-bump which is missing.");
             self_destruct();
         }
-    }
 #endif
+        if (s->transport.protocol == AnyP::PROTO_HTTPS) {
+            debugs(3,DBG_CRITICAL, "FATAL: https_port: proxy-surrogate option cannot be used on HTTPS ports.");
+            self_destruct();
+        }
+    }
 
     if (Ip::EnableIpv6&IPV6_SPECIAL_SPLITSTACK && s->s.isAnyAddr()) {
         // clone the port options from *s to *(s->next)
index 462e4c18615647508b23b2c410d60b1d62b9053f..27136249f1c6163477a703c3ecd7c75ef04d6e20 100644 (file)
@@ -1543,11 +1543,6 @@ DOC_START
 
           accel        Accelerator / reverse proxy mode
 
-          proxy-surrogate
-                       Support for PROXY protocol version 1 or 2 connections.
-                       The proxy_forwarded_access is required to whitelist
-                       downstream proxies which can be trusted.
-
           ssl-bump     For each CONNECT request allowed by ssl_bump ACLs,
                        establish secure connection with the client and with
                        the server, decrypt HTTPS messages as they pass through
@@ -1734,6 +1729,11 @@ DOC_START
                        probing the connection, interval how often to probe, and
                        timeout the time before giving up.
 
+          proxy-surrogate
+                       Require PROXY protocol version 1 or 2 connections.
+                       The proxy_forwarded_access is required to whitelist
+                       downstream proxies which can be trusted.
+
        If you run Squid on a dual-homed machine with an internal
        and an external interface we recommend you to specify the
        internal address:port in http_port. This way Squid will only be
index ba587b692ab53826fdc401b2675c7ac524ecdea5..3dfc41da211f392d9388fd6ec93e0e5583d36e76 100644 (file)
@@ -2342,6 +2342,8 @@ parseHttpRequest(ConnStateData *csd, HttpParser *hp, HttpRequestMethod * method_
      *  - accelerator mode (reverse proxy)
      *  - internal URL
      *  - mixed combos of the above with internal URL
+     *  - remote interception with PROXY protocol
+     *  - remote reverse-proxy with PROXY protocol
      */
     if (csd->transparent()) {
         /* intercept or transparent mode, properly working with no failures */
@@ -3045,6 +3047,7 @@ ConnStateData::parseProxy10()
         debugs(33, 5, "PROXY/1.0 protocol on connection " << clientConnection);
         clientConnection->local = originalDest;
         clientConnection->remote = originalClient;
+        clientConnection->flags ^= COMM_TRANSPARENT; // prevent TPROXY spoofing of this new IP.
         debugs(33, 5, "PROXY/1.0 upgrade: " << clientConnection);
 
         // repeat fetch ensuring the new client FQDN can be logged
@@ -3122,12 +3125,14 @@ ConnStateData::parseProxy20()
         clientConnection->local.port(ntohs(ipu->ipv4_addr.dst_port));
         clientConnection->remote = ipu->ipv4_addr.src_addr;
         clientConnection->remote.port(ntohs(ipu->ipv4_addr.src_port));
+        clientConnection->flags ^= COMM_TRANSPARENT; // prevent TPROXY spoofing of this new IP.
         break;
     case 0x2: // IPv6
         clientConnection->local = ipu->ipv6_addr.dst_addr;
         clientConnection->local.port(ntohs(ipu->ipv6_addr.dst_port));
         clientConnection->remote = ipu->ipv6_addr.src_addr;
         clientConnection->remote.port(ntohs(ipu->ipv6_addr.src_port));
+        clientConnection->flags ^= COMM_TRANSPARENT; // prevent TPROXY spoofing of this new IP.
         break;
     default: // do nothing
         break;