I am running an HTTP service and want to put nginx in front for SSL termination. This can be done in two ways; either as a stream proxy

stream {
    server {
        listen               443 ssl;
        ssl_certificate      /certs/fullchain.pem;
        ssl_certificate_key  /certs/privkey.pem;
        proxy_pass           ip-for-backend-service:80;

or as an http proxy

http {
    server {
        listen 443 ssl;
        ssl_certificate      /certs/fullchain.pem;
        ssl_certificate_key  /certs/privkey.pem;

        location / {
            proxy_pass       http://ip-for-backend-service:80;
            proxy_set_header ...;

From a quick glance it seems like that the configuration of the stream proxy is much simpler since you don't have to add a bunch of extra headers (proxy_set_header etc) and other configuration.

I am trying to understand the pros and cons between these two methods, and in particular I have the following questions:

  1. Will either method leak more information about the backend service? For example, will the ip-for-backend-service be visible?

  2. Will either method result in better protection from attacks? I guess if the backend service has flaws it will be visible/exploitable through both options?

  3. Which option is more efficient? I think that the stream option might be faster since it just routes the traffic and there is no http-server in the middle?


1 Answer 1


With both methods the upstream IP address will remain hidden.

As for the rest:

  • stream is certainly faster, since less code is executed. However both are well-written C code and when you compare it with network delays, the difference might not be noticeable.
  • With stream the upstream logs will only contain one client IP address (the address of the proxy server). This can be changed with the proxy_bind directive, but requires additional networking setup. On the other hand adding an X-Forwarded-For header in the http setup is straightforward:

    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  • With stream the upstream server needs to be manually configured to consider the incoming connection secure: e.g. Tomcat requires the addition of scheme="https" and secure="true" on the <Connector> element. Using the http proxy and a X-Forwarded-Proto header the upstream server can decide whether HTTP or HTTPS was used on a per-connection basis.

The question of the security of the setup is quite opinion-based:

  • Using the http proxy, you can limit the URI paths that will be proxied, hence you will not expose to the public the administrative part of your website,
  • On the other hand, by adding additional computational strain on your system (against the alternative of accessing the upstream server directly), you are more exposed to DDoS attacks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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