diff --git a/src/anyp/TrafficMode.h b/src/anyp/TrafficMode.h index 48ba4ce2659..1ce4336a9d0 100644 --- a/src/anyp/TrafficMode.h +++ b/src/anyp/TrafficMode.h @@ -21,13 +21,22 @@ namespace AnyP class TrafficMode { public: - /** marks HTTP accelerator (reverse/surrogate proxy) traffic + /** marks HTTP Proxy (forward proxy) traffic + * + * Indicating the following are required: + * - URL in absolute form (exceptions for CONNECT and OPTIONS methods) + * - NAT is prohibited + * - WWW-Auth* is restricted to cache manager + */ + bool forwardProxy = false; + + /** marks HTTP Gateway (accelerator/reverse/surrogate proxy) traffic * * Indicating the following are required: * - URL translation from relative to absolute form * - restriction to origin peer relay recommended */ - bool accelSurrogate = false; + bool gatewaySurrogate = false; /** marks ports receiving PROXY protocol traffic * @@ -73,10 +82,11 @@ class TrafficMode */ bool tunnelSslBumping = false; - /** true if the traffic is in any way intercepted - * - */ - bool isIntercepted() { return natIntercept||tproxyIntercept ;} + /// whether the traffic is in any way intercepted + bool isIntercepted() const { return natIntercept||tproxyIntercept ;} + + /// whether HTTP proxy (forward-proxy) traffic is expected + bool isForwardProxy() const { return forwardProxy || (!gatewaySurrogate && !isIntercepted()); } }; } // namespace AnyP diff --git a/src/cache_cf.cc b/src/cache_cf.cc index 4942f479bd2..ae87a4b26be 100644 --- a/src/cache_cf.cc +++ b/src/cache_cf.cc @@ -3479,47 +3479,7 @@ parse_port_option(AnyP::PortCfgPointer &s, char *token) { /* modes first */ - if (strcmp(token, "accel") == 0) { - if (s->flags.isIntercepted()) { - debugs(3, DBG_CRITICAL, "FATAL: " << cfg_directive << ": Accelerator mode requires its own port. It cannot be shared with other modes."); - self_destruct(); - return; - } - s->flags.accelSurrogate = true; - s->vhost = true; - } else if (strcmp(token, "transparent") == 0 || strcmp(token, "intercept") == 0) { - if (s->flags.accelSurrogate || s->flags.tproxyIntercept) { - debugs(3, DBG_CRITICAL, "FATAL: " << cfg_directive << ": Intercept mode requires its own interception port. It cannot be shared with other modes."); - self_destruct(); - return; - } - s->flags.natIntercept = true; - Ip::Interceptor.StartInterception(); - /* Log information regarding the port modes under interception. */ - 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) { - debugs(3,DBG_CRITICAL, "FATAL: " << cfg_directive << ": TPROXY option requires its own interception port. It cannot be shared with other modes."); - self_destruct(); - return; - } - s->flags.tproxyIntercept = true; - Ip::Interceptor.StartTransparency(); - /* 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 << " (require-proxy-header enabled)"); - } - - if (!Ip::Interceptor.ProbeForTproxy(s->s)) { - debugs(3, DBG_CRITICAL, "FATAL: " << cfg_directive << ": TPROXY support in the system does not work."); - self_destruct(); - return; - } - - } else if (strcmp(token, "require-proxy-header") == 0) { + if (strcmp(token, "require-proxy-header") == 0) { s->flags.proxySurrogate = true; if (s->flags.tproxyIntercept) { // receiving is still permitted, so we do not unset the TPROXY flag @@ -3528,61 +3488,61 @@ parse_port_option(AnyP::PortCfgPointer &s, char *token) } } else if (strncmp(token, "defaultsite=", 12) == 0) { - if (!s->flags.accelSurrogate) { - debugs(3, DBG_CRITICAL, "FATAL: " << cfg_directive << ": defaultsite option requires Acceleration mode flag."); + if (!s->flags.gatewaySurrogate) { + debugs(3, DBG_CRITICAL, "FATAL: " << cfg_directive << ": defaultsite option requires 'gateway' mode flag."); self_destruct(); return; } safe_free(s->defaultsite); s->defaultsite = xstrdup(token + 12); } else if (strcmp(token, "vhost") == 0) { - if (!s->flags.accelSurrogate) { - debugs(3, DBG_CRITICAL, "WARNING: " << cfg_directive << ": vhost option is deprecated. Use 'accel' mode flag instead."); + if (!s->flags.gatewaySurrogate) { + debugs(3, DBG_CRITICAL, "WARNING: " << cfg_directive << ": vhost option is deprecated. Use 'gateway' mode flag instead."); } - s->flags.accelSurrogate = true; + s->flags.gatewaySurrogate = true; s->vhost = true; } else if (strcmp(token, "no-vhost") == 0) { - if (!s->flags.accelSurrogate) { - debugs(3, DBG_IMPORTANT, "ERROR: " << cfg_directive << ": no-vhost option requires Acceleration mode flag."); + if (!s->flags.gatewaySurrogate) { + debugs(3, DBG_IMPORTANT, "ERROR: " << cfg_directive << ": no-vhost option requires 'gateway' mode flag."); } s->vhost = false; } else if (strcmp(token, "vport") == 0) { - if (!s->flags.accelSurrogate) { - debugs(3, DBG_CRITICAL, "FATAL: " << cfg_directive << ": vport option requires Acceleration mode flag."); + if (!s->flags.gatewaySurrogate) { + debugs(3, DBG_CRITICAL, "FATAL: " << cfg_directive << ": vport option requires 'gateway' mode flag."); self_destruct(); return; } s->vport = -1; } else if (strncmp(token, "vport=", 6) == 0) { - if (!s->flags.accelSurrogate) { - debugs(3, DBG_CRITICAL, "FATAL: " << cfg_directive << ": vport option requires Acceleration mode flag."); + if (!s->flags.gatewaySurrogate) { + debugs(3, DBG_CRITICAL, "FATAL: " << cfg_directive << ": vport option requires 'gateway' mode flag."); self_destruct(); return; } s->vport = xatos(token + 6); } else if (strncmp(token, "protocol=", 9) == 0) { - if (!s->flags.accelSurrogate) { - debugs(3, DBG_CRITICAL, "FATAL: " << cfg_directive << ": protocol option requires Acceleration mode flag."); + if (!s->flags.gatewaySurrogate) { + debugs(3, DBG_CRITICAL, "FATAL: " << cfg_directive << ": protocol option requires 'gateway' mode flag."); self_destruct(); return; } s->transport = parsePortProtocol(ToUpper(SBuf(token + 9))); } else if (strcmp(token, "allow-direct") == 0) { - if (!s->flags.accelSurrogate) { - debugs(3, DBG_CRITICAL, "FATAL: " << cfg_directive << ": allow-direct option requires Acceleration mode flag."); + if (!s->flags.gatewaySurrogate) { + debugs(3, DBG_CRITICAL, "FATAL: " << cfg_directive << ": allow-direct option requires 'gateway' mode flag."); self_destruct(); return; } s->allow_direct = true; } else if (strcmp(token, "act-as-origin") == 0) { - if (!s->flags.accelSurrogate) { - debugs(3, DBG_IMPORTANT, "ERROR: " << cfg_directive << ": act-as-origin option requires Acceleration mode flag."); + if (!s->flags.gatewaySurrogate) { + debugs(3, DBG_IMPORTANT, "ERROR: " << cfg_directive << ": act-as-origin option requires 'gateway' mode flag."); } else s->actAsOrigin = true; } else if (strcmp(token, "ignore-cc") == 0) { #if !USE_HTTP_VIOLATIONS - if (!s->flags.accelSurrogate) { - debugs(3, DBG_CRITICAL, "FATAL: " << cfg_directive << ": ignore-cc option requires Acceleration mode flag."); + if (!s->flags.gatewaySurrogate) { + debugs(3, DBG_CRITICAL, "FATAL: " << cfg_directive << ": ignore-cc option requires 'gateway' mode flag."); self_destruct(); return; } @@ -3694,6 +3654,37 @@ parse_port_option(AnyP::PortCfgPointer &s, char *token) } } +static void +parse_port_mode(AnyP::PortCfgPointer &s, char *token) +{ + if (strcmp(token, "proxy") == 0) { + s->flags.forwardProxy = true; + + } else if (strcmp(token, "gateway") == 0 || strcmp(token, "accel") == 0) { + s->flags.gatewaySurrogate = true; + s->vhost = true; + + } else if (strcmp(token, "transparent") == 0 || strcmp(token, "intercept") == 0) { + s->flags.natIntercept = true; + Ip::Interceptor.StartInterception(); + /* Log information regarding the port modes under interception. */ + 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) { + s->flags.tproxyIntercept = true; + Ip::Interceptor.StartTransparency(); + /* Log information regarding the port modes under transparency. */ + debugs(3, DBG_IMPORTANT, "Disabling Authentication on port " << s->s << " (TPROXY enabled)"); + + if (!Ip::Interceptor.ProbeForTproxy(s->s)) + throw TextException("TPROXY support in the system does not work.", Here()); + } else { + // not a mode, check as option. + parse_port_option(s, token); + } +} + void add_http_port(char *portspec) { @@ -3733,6 +3724,10 @@ parsePortCfg(AnyP::PortCfgPointer *head, const char *optionName) s->transport = parsePortProtocol(protoName); // default; protocol=... overwrites parsePortSpecification(s, token); + // port mode (or first option) + if ((token = ConfigParser::NextToken())) + parse_port_mode(s, token); + /* parse options ... */ while ((token = ConfigParser::NextToken())) { parse_port_option(s, token); @@ -3815,7 +3810,7 @@ dump_generic_port(StoreEntry * e, const char *n, const AnyP::PortCfgPointer &s) else if (s->flags.proxySurrogate) storeAppendPrintf(e, " require-proxy-header"); - else if (s->flags.accelSurrogate) { + else if (s->flags.gatewaySurrogate) { storeAppendPrintf(e, " accel"); if (s->vhost) @@ -3847,7 +3842,7 @@ dump_generic_port(StoreEntry * e, const char *n, const AnyP::PortCfgPointer &s) storeAppendPrintf(e, " name=%s", s->name); #if USE_HTTP_VIOLATIONS - if (!s->flags.accelSurrogate && s->ignore_cc) + if (!s->flags.gatewaySurrogate && s->ignore_cc) storeAppendPrintf(e, " ignore-cc"); #endif diff --git a/src/cf.data.pre b/src/cf.data.pre index 51c90a376e8..f6a79349caf 100644 --- a/src/cf.data.pre +++ b/src/cf.data.pre @@ -1347,7 +1347,7 @@ ENDIF # -s Squid will just annoy the user by "randomly" denying requests. # (the counter is reset each time the limit is reached and a # request is denied) - # NOTE: in acceleration mode or where there is mesh of child proxies, + # NOTE: in gateway mode or where there is mesh of child proxies, # clients may appear to come from multiple addresses if they are # going through proxy farms, so a limit of 1 may cause user problems. @@ -2284,17 +2284,16 @@ LOC: HttpPortList DOC_START Usage: port [mode] [options] hostname:port [mode] [options] - 1.2.3.4:port [mode] [options] + IP:port [mode] [options] The socket addresses where Squid will listen for HTTP client - requests. You may specify multiple socket addresses. - There are three forms: port alone, hostname with port, and - IP address with port. If you specify a hostname or IP + requests. There are three forms: port alone, hostname with port, + and IP address with port. If you specify a hostname or IP address, Squid binds the socket to that specific address. Most likely, you do not need to bind to a specific address, so you can use the port number alone. - If you are running Squid in accelerator mode, you + If you are running Squid in gateway mode, you probably want to listen on port 80 also, or instead. The -a command line option may be used to specify additional @@ -2305,17 +2304,25 @@ DOC_START Modes: - intercept Support for IP-Layer NAT interception delivering + proxy The default. HTTP forward-proxy traffic syntax is + expected. SSL-Bump mode may be used in addition + to inspect CONNECT tunnels. + + gateway HTTP reverse-proxy traffic syntax is expected. + + intercept Support for IP-Layer NAT interception delivering traffic to this Squid port. - NP: disables authentication on the port. - tproxy Support Linux TPROXY (or BSD divert-to) with spoofing + SECURITY NOTE: disables authentication on the port. + + tproxy Support Linux TPROXY (or BSD divert-to) with spoofing of outgoing connections using the client IP address. - NP: disables authentication on the port. - accel Accelerator / reverse proxy mode + SECURITY NOTE: disables authentication on the port. - ssl-bump For each CONNECT request allowed by ssl_bump ACLs, + ssl-bump Support inspection of TLS traffic received on this port. + + 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 Squid, and treat them as unencrypted HTTP messages, @@ -2324,19 +2331,17 @@ DOC_START The ssl_bump option is required to fully enable bumping of CONNECT requests. - Omitting the mode flag causes default forward proxy mode to be used. - - Accelerator Mode Options: + Gateway Mode Options: defaultsite=domainname What to use for the Host: header if it is not present in a request. Determines what site (not origin server) - accelerators should consider the default. + gateway should consider the default. no-vhost Disable using HTTP/1.1 Host header for virtual domain support. - protocol= Protocol to reconstruct accelerated and intercepted + protocol= Protocol to reconstruct gateway and intercepted requests with. Defaults to HTTP/1.1 for http_port and HTTPS/1.1 for https_port. When an unsupported value is configured Squid will @@ -2357,19 +2362,18 @@ DOC_START ignore-cc Ignore request Cache-Control headers. WARNING: This option violates HTTP specifications if - used in non-accelerator setups. + used in non-gateway setups. - allow-direct Allow direct forwarding in accelerator mode. Normally - accelerated requests are denied direct forwarding as if + allow-direct Allow direct forwarding in gateway mode. Normally + gateway requests are denied direct forwarding as if never_direct was used. - WARNING: this option opens accelerator mode to security - vulnerabilities usually only affecting in interception + WARNING: this option opens gateway mode to security + vulnerabilities usually only affecting interception mode. Make sure to protect forwarding with suitable http_access rules when using this. - - SSL Bump Mode Options: + SSL-Bump Mode Options: In addition to these options ssl-bump requires TLS/SSL options. generate-host-certificates[=] @@ -2567,7 +2571,7 @@ DOC_START CONFIG_START # Squid normally listens to port 3128 -http_port @DEFAULT_HTTP_PORT@ +http_port @DEFAULT_HTTP_PORT@ proxy CONFIG_END DOC_END @@ -2583,8 +2587,7 @@ DOC_START over TLS or SSL connections. Commonly referred to as HTTPS. This is most useful for situations where you are running squid in - accelerator mode and you want to do the TLS work at the accelerator - level. + gateway mode and need to do TLS termination at the gateway. You may specify multiple socket addresses on multiple lines, each with their own certificate and/or options. @@ -2593,7 +2596,7 @@ DOC_START See http_port for a list of modes and options. Not all http_port options are available for https_port. - Among the unavalable options: + Among the unavailable options: - require-proxy-header DOC_END @@ -2634,7 +2637,7 @@ DOC_START tproxy Support Linux TPROXY for spoofing outgoing connections using the client IP address. - NP: disables authentication and maybe IPv6 on the port. + SECURITY NOTE: disables authentication and maybe IPv6 on the port. By default (i.e., without an explicit mode option), Squid extracts the FTP origin address from the login@origin parameter of the FTP USER @@ -2651,7 +2654,7 @@ DOC_START HTTP requests) to reflect the current FTP server directory. Tracking is disabled by default. - protocol=FTP Protocol to reconstruct accelerated and intercepted + protocol=FTP Protocol to reconstruct gateway and intercepted requests with. Defaults to FTP. No other accepted values have been tested with. An unsupported value results in a FATAL error. Accepted values are FTP, @@ -3751,15 +3754,15 @@ DOC_START scheme, host, port, path, params Order is not important. - ==== ACCELERATOR / REVERSE-PROXY OPTIONS ==== + ==== GATEWAY OPTIONS ==== originserver Causes this parent to be contacted as an origin server. - Meant to be used in accelerator setups when the peer + Meant to be used in gateway setups when the peer is a web server. forceddomain=name Set the Host header of requests forwarded to this peer. - Useful in accelerator setups where the server (peer) + Useful in gateway setups where the server (peer) expects a certain domain name but clients may request others. ie example.com or www.example.com @@ -6170,7 +6173,7 @@ DOC_START prevent Host: header forgery by redirectors Squid rewrites any Host: header in redirected requests. - If you are running an accelerator this may not be a wanted + If you are running a CDN gateway this may not be a wanted effect of a redirector. This directive enables you disable Host: alteration in reverse-proxy traffic. @@ -7660,7 +7663,7 @@ DOC_START DOC_END COMMENT_START - HTTPD-ACCELERATOR OPTIONS + CDN GATEWAY OPTIONS ----------------------------------------------------------------------------- COMMENT_END @@ -7675,7 +7678,7 @@ DOC_START a farm of surrogates may all perform the same tasks, they may share an identification token. - When the surrogate is a reverse-proxy, this ID is also + When the surrogate is another gateway (reverse-proxy), this ID is also used as cdn-id for CDN-Loop detection (RFC 8586). DOC_END diff --git a/src/client_side.cc b/src/client_side.cc index 3c78c62e5c2..fa5fde77446 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -1292,7 +1292,7 @@ ConnStateData::parseHttpRequest(const Http1::RequestParserPointer &hp) "\n----------"); /* deny CONNECT via accelerated ports */ - if (hp->method() == Http::METHOD_CONNECT && port != nullptr && port->flags.accelSurrogate) { + if (hp->method() == Http::METHOD_CONNECT && port != nullptr && port->flags.gatewaySurrogate) { debugs(33, DBG_IMPORTANT, "WARNING: CONNECT method received on " << transferProtocol << " Accelerator port " << port->s.port()); debugs(33, DBG_IMPORTANT, "WARNING: for request: " << hp->method() << " " << hp->requestUri() << " " << hp->messageProtocol()); hp->parseStatusCode = Http::scMethodNotAllowed; @@ -1341,19 +1341,19 @@ ConnStateData::parseHttpRequest(const Http1::RequestParserPointer &hp) /* set url */ debugs(33,5, "Prepare absolute URL from " << - (transparent()?"intercept":(port->flags.accelSurrogate ? "accel":""))); + (transparent()?"intercept":(port->flags.gatewaySurrogate ? "gateway":""))); /* Rewrite the URL in transparent or accelerator mode */ /* NP: there are several cases to traverse here: - * - standard mode (forward proxy) + * - proxy mode (forward proxy) * - transparent mode (TPROXY) * - transparent mode with failures * - intercept mode (NAT) * - intercept mode with failures - * - accelerator mode (reverse proxy) + * - gateway mode (reverse proxy) * - internal relative-URL * - mixed combos of the above with internal URL * - remote interception with PROXY protocol - * - remote reverse-proxy with PROXY protocol + * - remote gateway (reverse-proxy) with PROXY protocol */ if (switchedToHttps()) { http->uri = prepareTlsSwitchingURL(hp); @@ -1367,7 +1367,7 @@ ConnStateData::parseHttpRequest(const Http1::RequestParserPointer &hp) // that may mismatch the (yet unparsed) Host header in the request. http->uri = xstrdup(internalLocalUri(nullptr, hp->requestUri())); - } else if (port->flags.accelSurrogate) { + } else if (port->flags.gatewaySurrogate) { /* accelerator mode */ http->uri = prepareAcceleratedURL(this, hp); http->flags.accel = true; @@ -3335,7 +3335,7 @@ clientListenerConnectionOpened(AnyP::PortCfgPointer &s, const Ipc::FdNoteId port (s->flags.natIntercept ? "NAT intercepted " : "") << (s->flags.tproxyIntercept ? "TPROXY intercepted " : "") << (s->flags.tunnelSslBumping ? "SSL bumped " : "") << - (s->flags.accelSurrogate ? "reverse-proxy " : "") + (s->flags.gatewaySurrogate ? "CDN gateway " : "") << FdNote(portTypeNote) << " connections at " << s->listenConn);