Httpd Forward Proxy



Skip to end of metadataGo to start of metadata

Why do I see requests for foreign sites appearing in my log files?

Normally the client connects with http (plain tcp) to the proxy and sends the CONNECT method (and host header) to host:443. Then the proxy will make a transparent connection to the endpoint and then the client sends the SSL handshake through. In this scenario the data is ssl protected 'end to end'. As httpd receives a request from a client, the request itself is proxied to one of these backend servers, which then handles the request, generates the content and then sends this content back to httpd, which then generates the actual HTTP response back to the client. ProxyRequests is a security measure, setting it to off will prevent your machine being used as a forward proxy server. ProxyPass will map a remote server location to a local path. In this case, every request done to the root directory will be redirected to localhost at port 8080. LoadModule proxymodule modules/modproxy.so. LoadModule proxyfcgimodule modules/modproxyfcgi.so. Now, there are different ways to actually forward requests for.php files to this module, ranging from everything (using ProxyPass) to very specific or rewritten files or patterns (using modrewrite with the P flag). Systemctl enable httpd. Systemctl start httpd. Systemctl enable htcacheclean. Systemctl start htcacheclean. Iptables -A INPUT -p tcp -dport 3128 -j ACCEPT. Ip6tables -A INPUT -p tcp -dport 3128 -j ACCEPT. Service iptables save. Service ip6tables save. This will start Apache.

An access_log entry showing this situation could look like this:

For this log line, the 200 code (second to last field in this example) indicates that the request was successful – but see below for an explanation of what “success” means in this situation.

This is usually the result of malicious clients trying to exploit open proxy servers to access a website without revealing their true location. They could be doing this to manipulate pay-per-click ad systems, to add comment or link-spam to someone else's site, or just to do something nasty without being detected.

It is important to prevent your server from being used as an open proxy to abuse other sites.

How can I prevent these requests from accessing the foreign server through my server?

First, if you don't need to run a proxy server, disable mod_proxy by commenting out its LoadModule line or setting ProxyRequests off in httpd.conf. Remember that disabling ProxyRequests does not prevent you from using a reverse proxy with the ProxyPass directive.

If you do need to have Apache act as a proxy server, be sure to secure your server by restricting access with a <Proxy> section in httpd.conf.

My server is properly configured not to proxy, so why is Apache returning a 200 (Success) status code?

That status code indicates that Apache successfully sent a response to the client, but not necessarily that the response was retrieved from the foreign website.

RFC2616 section 5.1.2 mandates that Apache must accept requests with absolute URLs in the request-URI, even for non-proxy requests. This means that even when proxying is turned off, Apache will accept requests that look like proxy requests. But instead of retrieving the content from the foreign site, Apache will serve the content at the corresponding location on your website. Since the hostname probably doesn't match a name for your site, Apache will look for the content on your default host.

In the above example, since www.yahoo.com is obviously not a valid virtual host on your system, Apache will serve the homepage content from your default (virtual) host. The size of the response (1456 in the above example) can be compared to the size of the corresponding page on your default site to confirm that the response was served locally and no proxying was involved.

But how can I be really sure that I am not allowing the abuse of other sites

You can try yourself to use your server as a proxy to access other sites and make sure that you get either a failure, or local content from your site. Among the ways to do this:

Httpd Forward Proxy
  1. Configure your browser to use your web server as its default proxy server and then try to request foreign sites. You should get only your own website content back in reply.
    2. Manually construct requests using telnet:
Httpd Forward Proxy

Then press enter twice. If your server is properly configured, you should receive content from your own site and not Yahoo.

What about these strange CONNECT requests?

A variant of this problem is an access_log entry that looks like

Httpd

The CONNECT method is usually used to tunnel SSL requests through proxies. But in this case, the port 25 on the target shows us that someone is attempting to use our HTTP proxy to send mail (probably spam) to a foreign site.

Everything mentioned above applies equally to this case. But normally, as long as the proxy is disabled, Apache would respond to such requests with status code 405 (Method not allowed). The fact that a success status code is returned indicates that a third-party module is processing the CONNECT requests. The most likely culprit is php, which in its default configuration will accept all methods and treat them identically.

Forward

This isn't inherently a problem since php will handle the request locally and will not proxy to the foreign host. But it is still a good idea to configure php to accept only specific methods (using the php configuration setting http.allowed_methods) or have your php script reject requests for non-standard methods.

I don't like the idea of my server responding to requests for random hostnames, even if it serves local content. How can I deny these requests?

You can configure Apache to deny access to any host that isn't specifically configured by setting up a default virtual host:

See also the CanonicalHostNames recipe.

Proxy

Can't I just drop these requests entirely?

Apache is an HTTP server and responds to HTTP requests with HTTP responses. It does not simply drop requests on the floor, since this would make it difficult to debug problems with client-server interactions.

Httpd Forward Proxy

If you really want to send no response at all, the third-party module mod_security is able to drop requests. But the savings in resource usage will be minuscule.

Unfortunately, even if your server is properly configured, you may see this type of exploit attempt recur. Since the offending client is usually itself a compromised computer (or a botnet), there is little that can be done to stop them beyond assuring that your site does not act as an open proxy.

Environment Variables

In addition to the configuration directives that control the behaviour of mod_proxy, there are a number of environment variables that control the HTTP protocol provider. Environment variables below that don't specify specific values are enabled when set to any value.

Windows Server 2012 Forward Proxy

proxy-sendextracrlf
Causes proxy to send an extra CR-LF newline on the end of a request. This is a workaround for a bug in some browsers.
force-proxy-request-1.0
Forces the proxy to send requests to the backend as HTTP/1.0 and disables HTTP/1.1 features.
proxy-nokeepalive
Forces the proxy to close the backend connection after each request.
proxy-chain-auth
If the proxy requires authentication, it will read and consume the proxy authentication credentials sent by the client. With proxy-chain-auth it will also forward the credentials to the next proxy in the chain. This may be necessary if you have a chain of proxies that share authentication information. Security Warning: Do not set this unless you know you need it, as it forwards sensitive information!
proxy-sendcl
HTTP/1.0 required all HTTP requests that include a body (e.g. POST requests) to include a Content-Length header. This environment variable forces the Apache proxy to send this header to the backend server, regardless of what the Client sent to the proxy. It ensures compatibility when proxying for an HTTP/1.0 or unknown backend. However, it may require the entire request to be buffered by the proxy, so it becomes very inefficient for large requests.
proxy-sendchunks or proxy-sendchunked
This is the opposite of proxy-sendcl. It allows request bodies to be sent to the backend using chunked transfer encoding. This allows the request to be efficiently streamed, but requires that the backend server supports HTTP/1.1.
proxy-interim-response
This variable takes values RFC (the default) or Suppress. Earlier httpd versions would suppress HTTP interim (1xx) responses sent from the backend. This is technically a violation of the HTTP protocol. In practice, if a backend sends an interim response, it may itself be extending the protocol in a manner we know nothing about, or just broken. So this is now configurable: set proxy-interim-response RFC to be fully protocol compliant, or proxy-interim-response Suppress to suppress interim responses.
proxy-initial-not-pooled
If this variable is set, no pooled connection will be reused if the client request is the initial request on the frontend connection. This avoids the 'proxy: error reading status line from remote server' error message caused by the race condition that the backend server closed the pooled connection after the connection check by the proxy and before data sent by the proxy reached the backend. It has to be kept in mind that setting this variable downgrades performance, especially with HTTP/1.0 clients.