I am using a Nginx server as a reverse proxy. It serves both HTTP and HTTPS traffic and dispatches the calls to multiple HTTP-only websites.
Recently, I wanted to be able to encrypt the traffic between Nginx and the underlying server. Nginx still decrypts the HTTPS traffic it receives from the Internet just like before, but then should use HTTPS with a different certificate to access the underlying server.
I started to change the configuration, following the official documentation. However, proxy_ssl on
can be set only within a stream
level, and not http
. This is confirmed by nginx -t
which shows for the line containing proxy_ssl on;
the following error:
"proxy_ssl" directive is not allowed here [...]
My difficulty is that I'm using Nginx to log traffic, add headers, etc., so I have to use http
. If my understanding is correct, stream
level is needed when Nginx is used to transmit HTTPS traffic directly, without the ability to decrypt it (i.e. SSL Pass-thru), which is not my case.
Can I make Nginx connect through HTTPS to the underlying server while still using http
level and all its benefits such as logging and changing headers?
Current configuration:
http {
proxy_set_header ... # Logging and custom headers.
...
upstream demo-failover {
server demo1.example.com:443 weight=1000 max_fails=0;
server demo2.example.com:443 backup;
}
server {
listen 80 proxy_protocol;
listen 443 ssl http2 proxy_protocol;
server_name demo.example.com;
# HTTPS configuration for public exchange (Internet <-> Nginx).
ssl_certificate /.../fullchain.pem;
ssl_certificate_key /.../privkey.pem;
ssl_stapling on;
ssl_stapling_verify on;
# HTTPS configuration for private exchange (Nginx <-> underlying server).
proxy_ssl on; # This is the line which is invalid.
proxy_ssl_trusted_certificate /.../ca.pem;
proxy_ssl_certificate /.../demo.pem;
proxy_ssl_certificate_key /.../demo.key;
proxy_ssl_verify on;
proxy_ssl_verify_depth 2;
proxy_ssl_session_reuse on;
if ($scheme = http) {
return 301 https://$server_name$request_uri;
}
location / {
proxy_pass http://demo-failover;
proxy_next_upstream error timeout invalid_header;
proxy_connect_timeout 2;
proxy_redirect off;
proxy_http_version 1.1;
}
}
}
Found it.
There is no need to switch to
stream
, and there is no need to useproxy_ssl on
.A different example from the official documentation shows how to use HTTPS at
http
level. The trick (and that was my mistake when I tried to removeproxy_ssl on
and found myself with Nginx trying to call the underlying server using HTTP) is theproxy_pass
value. In my case, I kept the original value:Instead, I should have changed it to
https
: