Nginx – Can nginx listen on port 80, but send upstream to backend using SSL on 443

nginxreverse-proxysquidssl

For PCI compliance, my application is forced to use a secure/encrypted connection between the reverse proxy server and backend app server, whereas the connection coming into the reverse proxy is on port 80, i.e. the reverse proxy needs to act as a http-to-https converter.

A simple diagram:

IIS7<—port 443—nginx<—-port 80—-Internet

I'm evaluating using nginx over squid for this, and this is what I have in my nginx.conf so far:

worker_processes  1;
events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;
    keepalive_timeout  65;

    upstream backend {
        server mybackendserver:443;
    }

    server {
        server_name www.mysite.com
        listen       80;
        ssl on;
        ssl_certificate /etc/nginx/server.crt;
        ssl_certificate_key /etc/nginx/server.key;
        ssl_verify_client off;
        location = / {
                    proxy_pass  https://backend;
                proxy_set_header Host $http_host;
            proxy_set_header X_FORWARDED_PROTO https;
        }

    }

}

The above gives: "400 Bad Request The plain HTTP request was sent to HTTPS port" when I browse to www.mysite.com.

Where am I going wrong?
Is this even doable?
Is nginx better than squid for this purpose?

Thanks in advance,
G

Best Answer

proxy_pass is able to proxy to HTTPS, this is not a problem.

You have an error in your configuration. Remove lines

ssl on;
ssl_certificate /etc/nginx/server.crt;
ssl_certificate_key /etc/nginx/server.key;
ssl_verify_client off;

These are turning on SSL server at Nginx side, which means your Nginx expects SSL connection at port 80. Since browsers send ordinary HTTP to port 80, Nginx complains "400 Bad Request The plain HTTP request was sent to HTTPS port"