I am using nginx as a reverse proxy listening at port 80 (http). I am using proxy_pass to forward requests to backend http and https servers. Everything works fine for my http server but when I try to reach the https server through nginx reverse proxy the ip of the https server is shown in the client's web browser. I want the uri of the nginx server to be shown instead of the https backend server's ip (once again, this works fine with the http server but not for the https server). See this post on the forum

Here is my configuration file :

server {
    listen 80;
    server_name domain1.com;
    access_log off;

    root /var/www;

if ($request_method !~ ^(GET|HEAD|POST)$ ) {
return 444;

location / {
    proxy_pass http://ipOfHttpServer:port/;

server {
    listen 80;
    server_name domain2.com;
    access_log off;

    root /var/www;

if ($request_method !~ ^(GET|HEAD|POST)$ ) {
return 444;

location / {
    proxy_pass http://ipOfHttpsServer:port/;
    proxy_set_header X_FORWARDED_PROTO https;
    #proxy_set_header Host $http_host;

When I try the "proxy_set_header Host $http_host" directive and "proxy_set_header Host $host" the web page can't be reached (page not found). But when I comment it, the ip of the https server is shown in the browser (which is bad).

Does anyone have an idea ?

My other configs files are :

proxy_redirect          off;
proxy_set_header        Host            $host;
proxy_set_header        X-Real-IP       $remote_addr;
proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
#proxy_hide_header       X-Powered-By;
proxy_intercept_errors on;
proxy_buffering on;

proxy_cache_key "$scheme://$host$request_uri";
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=cache:10m inactive=7d max_size=700m;

user www-data;
worker_processes  2;
error_log  /var/log/nginx/error.log;
pid        /var/run/nginx.pid;
events {
    worker_connections  1024;
http {
 include                        /etc/nginx/mime.types;
 default_type                   application/octet-stream;
 access_log                     /var/log/nginx/access.log;
 server_names_hash_bucket_size  64;
 sendfile                       off;
 tcp_nopush                     on;
 #keepalive_timeout             0;
 keepalive_timeout              65;
 tcp_nodelay                    on;
 gzip                           on;
 gzip_comp_level                5;
 gzip_http_version              1.0;
 gzip_min_length                0;
 gzip_types                     text/plain text/html text/css image/x-icon application/x-javascript;
 gzip_vary                      on;
 include                        /etc/nginx/conf.d/*.conf;
 include                        /etc/nginx/sites-enabled/*;

Thanks for your help !

I followed your advice and your example, and moves my cache directives to outside server blocks and proxy directives inside location blocs. I still have the exact same issue: when proxy_set_header Host $host; is written the https web site is unreacheable through nginx.

When I comment it, I can reach the https server through nginx but the lan ip adress of the https server is displayed in the adress bar, in spite of the proxy_pass directive and the proxy_redirect off. But it still works for the http server (the nginx's ip is displayed instead of the http server ip).

One more precision: I don't reach the https web page as soon as I go to http://addressOfMyNginx/. There is a warning page before because the certificate is not authentified. On this page I still have http://addressOfMyNginx/ in the address bar. But when I follow the "continue to the web site anyway" link, I am redirected to the https website and then the ip adress of the https server is displayed.

After reading debug logs, I have found :

2012/07/30 17:24:13 [debug] 4412#0: *75 http proxy header:
"GET / HTTP/1.0^M
Host: nameOfMMyNginxServer^M
X-Real-IP: xxx.xxx.xxx.xxx^M
X-Forwarded-For: xxx.xxx.xxx.xxx^M
Connection: close^M
Accept: text/html, application/xhtml+xml, */*^M
Accept-Language: fr-FR^M
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)^M
Accept-Encoding: gzip, deflate^M
Cookie: a_cookie_which_has_nothing_to_do_with_my_nginx_and_mybackend_server^M

Where xxx.xxx.xxx.xxx is the public address of a server which has nothing to do with nginx or my backend server (and has nothing to do with the cookie mentionned before either).

I reloaded/restarted and cleared my browser's cache and nginx's cache lot of time since I tested the server which could have concerned this cookie. But xxx.xxx.xxx.xxx has really really nothing to do with this all.

I can not comment last post because I posted with an anonymous account and I cleared my browser's cache. So SF did not reconize me as Vulpo anymore... (then I created an account).


proxy_redirect off should do the trick. I think you should also change your proxy_pass to use SSL if you want to use SSL for your backend. Although a Unix socket would be much better to tighten security and still keep a fast connection.

My recommended nginx.conf:

# /etc/nginx/nginx.conf

user www-data;
worker_processes 2; # Do you really have two CPU cores?
events {
  multi_accept        on;
  worker_connections  768;
  use                 epoll;
http {
  charset                         utf-8;
  client_body_timeout             65;
  client_header_timeout           65;
  client_max_body_size            10m;
  default_type                    application/octet-stream;
  index                           index.html index.php /index.php;
  keepalive_timeout               20;
  reset_timedout_connection       on;
  send_timeout                    65;
  sendfile                        on;
  server_names_hash_bucket_size   64;
  tcp_nodelay                     off;
  tcp_nopush                      on;
  gzip              on;
  gzip_buffers      32 4k;
  gzip_comp_level   2;
  gzip_disable      "msie6";
  gzip_http_version 1.1;
  gzip_min_length   1100;
  gzip_proxied      any;
  gzip_static       on;
    #text/html is always compressed by HttpGzipModule
  gzip_vary         on;
  include                        mime.types;
  include                        conf.d/*.conf;
  include                        sites-enabled/*;

My recommended virtual host configuration:

# /etc/nginx/sites-available/default.conf

proxy_cache_key "$scheme://$host$request_uri";
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=cache:10m inactive=7d max_size=700m;

server {
  listen 80;
  server_name example.com;
  access_log off;
  root /var/www;

  # Consider using a map for this! If is bad!
  if ($request_method !~ ^(GET|HEAD|POST)$ ) {
    return 444;

  location / {
    proxy_redirect off;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwared-For $proxy_add_x_forwarded_for;
    proxy_intercept_errors on;
    proxy_buffering on;

Have a look at my nginx configuration at GitHub for more advanced stuff (not finished yet, have to write more comments first): https://github.com/Fleshgrinder/nginx

  • Thanks for your answer. However, "proxy_redirect off" was already set in my /etc/nginx/conf.d/proxy.conf. I tried to add it one more time in my server-block just in case, but it did not resolve the problem. I think it's becase I can't add the "proxy_set_header Host $host" directive, which is the one which replaces the ip address by the servername. Any other idea ? – Vulpo Aug 24 '12 at 8:17
  • Oh, now I see it. Move all your proxy directives inside the location block and the proxy cache zone directly before the server (inside the http) block. That should solve your issues. – Fleshgrinder Aug 24 '12 at 16:35
  • I edited my answer, please have a look at it. – Fleshgrinder Aug 24 '12 at 16:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.