Opened 11 years ago
Closed 9 years ago
#538 closed defect (wontfix)
Server origin header not passed through the proxy
Reported by: | pornel.net | Owned by: | |
---|---|---|---|
Priority: | trivial | Milestone: | |
Component: | nginx-core | Version: | 1.5.x |
Keywords: | Cc: | ||
uname -a: | Darwin .local 13.1.0 Darwin Kernel Version 13.1.0 | ||
nginx -V: |
nginx version: nginx/1.5.12
built by clang 5.1 (clang-503.0.38) (based on LLVM 3.4svn) TLS SNI support enabled configure arguments: --prefix=/usr/local/Cellar/nginx/1.5.12 --with-http_ssl_module --with-pcre --with-ipv6 --sbin-path=/usr/local/Cellar/nginx/1.5.12/bin/nginx --with-cc-opt='-I/usr/local/Cellar/pcre/8.34/include -I/usr/local/Cellar/openssl/1.0.1f/include' --with-ld-opt='-L/usr/local/Cellar/pcre/8.34/lib -L/usr/local/Cellar/openssl/1.0.1f/lib' --conf-path=/usr/local/etc/nginx/nginx.conf --pid-path=/usr/local/var/run/nginx.pid --lock-path=/usr/local/var/run/nginx.lock --http-client-body-temp-path=/usr/local/var/run/nginx/client_body_temp --http-proxy-temp-path=/usr/local/var/run/nginx/proxy_temp --http-fastcgi-temp-path=/usr/local/var/run/nginx/fastcgi_temp --http-uwsgi-temp-path=/usr/local/var/run/nginx/uwsgi_temp --http-scgi-temp-path=/usr/local/var/run/nginx/scgi_temp --http-log-path=/usr/local/var/log/nginx/access.log --error-log-path=/usr/local/var/log/nginx/error.log --with-http_gzip_static_module |
Description
The Server header is intended to indicate origin server. If the response is being forwarded through a proxy, the proxy application MUST NOT modify the Server response-header.
IMHO the correct behavior should be to pass the header by default and perhaps add nginx to the Via header.
To reproduce:
server { listen 8001; server_name localhost; location / { proxy_pass http://localhost:8002; } }
printf 'HTTP/1.0 200 OK\r\nServer: origin\r\n\r\n' | nc -l 8002 & printf 'GET / HTTP/1.0\r\n\r\n' | nc localhost 8001
Actual output:
HTTP/1.1 200 OK Server: nginx/1.5.12 Date: Thu, 10 Apr 2014 12:57:54 GMT Connection: close
Expected:
HTTP/1.1 200 OK Server: origin Via: 1.0 nginx/1.5.12 Date: Thu, 10 Apr 2014 12:57:54 GMT Connection: close
Change History (6)
comment:1 by , 11 years ago
comment:2 by , 11 years ago
Nginx isn't a proxy (in terms of classical forward proxy). It's a reverse proxy as it originally stated by Apache's mod_proxy terminology:
A reverse proxy, by contrast, appears to the client just like an ordinary web server. No special configuration on the client is necessary. The client makes ordinary requests for content in the name-space of the reverse proxy. The reverse proxy then decides where to send those requests, and returns the content as if it was itself the origin.
So it acts like an origin.
comment:3 by , 11 years ago
Resolution: | → wontfix |
---|---|
Status: | new → closed |
As already explained by Valentin, nginx is origin server if you want to follow RFC 2616 terminology.
comment:4 by , 9 years ago
Resolution: | wontfix |
---|---|
Status: | closed → reopened |
Following RFC 2616 terminology a "reverse proxy" is a gateway.
RFC 2616 does give conditions for a gateway in 14.45 Via:
The Via general-header field MUST be used by gateways and proxies to indicate the intermediate protocols and recipients between the user agent and the server on requests, and between the origin server and the client on responses.
The apache mod_proxy link where "reverse proxy" is defined for acting "as if origin" for networking, rather than having to configure the client, and goes on to say:
A typical usage of a reverse proxy is to provide Internet users access to a server that is behind a firewall. Reverse proxies can also be used to balance load among several back-end servers, or to provide caching for a slower back-end server. In addition, reverse proxies can be used simply to bring several servers into the same URL space.
The reverse-proxy acts as the origin for networking purposes meaning no client configuration is required.
Following the "reverse proxy is origin" rather than "as if" argument though; it would mean all load balancers should overwrite the server header and all caches should overwrite the server header; which doesn't happen.
Examples of other reverse-proxies:
- Varnish cache
- Adds: Via:1.1 varnish
- Example: https://www.varnish-cache.org/ or https://en.wikipedia.org/ or all of github.io
- Apache Traffic Server
- Adds: via: http/1.1 usproxy1.fp.bf1.yahoo.com (ApacheTrafficServer)
- Example: https://www.yahoo.com/
- Application Request Routing
- Doesn't add anything; though sets a ARRAffinity cookie
- Example: http://azure.microsoft.com/en-us/
- Squid cache
- Doesn't add anything
- Example: http://www.squid-cache.org/
- AWS Cloudfront
- Adds: Via:1.1 d84fed7fd1b1bbf46db79b86f6968b79.cloudfront.net (CloudFront)
- Example: https://a0.awsstatic.com/main/css/1.0.170/style.css (on http://aws.amazon.com/ )
- Google HTTP/HTTPS Load Balancing
- Adds: Via: 1.1 google
- Example: ? docs here: https://cloud.google.com/compute/docs/load-balancing/http/
Also mod_proxy which is acting "as if origin" doesn't overwrite the server header when used as a reverse proxy and they explicitly state this: http://httpd.apache.org/docs/2.4/mod/mod_proxy.html#ProxyPassReverse
This directive lets Apache httpd adjust the URL in the Location, Content-Location and URI headers on HTTP redirect responses. This is essential when Apache httpd is used as a reverse proxy (or gateway) to avoid by-passing the reverse proxy because of HTTP redirects on the backend servers which stay behind the reverse proxy.
Only the HTTP response headers specifically mentioned above will be rewritten. Apache httpd will not rewrite other response headers, nor will it by default rewrite URL references inside HTML pages.
So nginx should not be overwriting the server header, but adding/appending to a Via header.
comment:5 by , 9 years ago
RFC 7230 updates the language in 2.3. Intermediaries to explicitly equate "gateway" and "reverse-proxy" http://tools.ietf.org/html/rfc7230#section-2.3
A "gateway" (a.k.a. "reverse proxy") is an intermediary that acts as an origin server for the outbound connection but translates received requests and forwards them inbound to another server or servers. Gateways are often used to encapsulate legacy or untrusted information services, to improve server performance through "accelerator" caching, and to enable partitioning or load balancing of HTTP services across multiple machines.
And relaxes outbound Via to MAY from MUST in 5.7.1. Via http://tools.ietf.org/html/rfc7230#section-5.7.1
An HTTP-to-HTTP gateway MUST send an appropriate Via header field in each inbound request message and MAY send a Via header field in forwarded response messages.
It allows for overriding fields as an option but not by default: 5.7.2. Transformations http://tools.ietf.org/html/rfc7230#section-5.7.1
An HTTP-to-HTTP proxy is called a "transforming proxy" if it is designed or configured to modify messages in a semantically meaningful way (i.e., modifications, beyond those required by normal HTTP processing, that change the message in a way that would be significant to the original sender or potentially significant to downstream recipients). For example, a transforming proxy might be acting as a shared annotation server (modifying responses to include references to a local annotation database), a malware filter, a format transcoder, or a privacy filter. Such transformations are presumed to be desired by whichever client (or client organization) selected the proxy.
...
A proxy SHOULD NOT modify header fields that provide information about the endpoints of the communication chain, the resource state, or the selected representation (other than the payload) unless the field's definition specifically allows such modification or the modification is deemed necessary for privacy or security.
comment:6 by , 9 years ago
Resolution: | → wontfix |
---|---|
Status: | reopened → closed |
There are no plans to change current behaviour. If you want nginx to behave differently, you are free to configure it to do so.
BTW: I'm aware that this can be achieved with proxy_pass_header/proxy_set_header directives. I'm just suggesting change of the defaults to align with the RFC out of the box.