I have an Nginx server being used as a load balancer. I have just installed an SSL certificate with Let's Encrypt and I am now looking into forcing HTTPs. The following is my config:
upstream backend {
server one.example.com;
server two.example.com;
}
server {
server_name example.com;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = example.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
server_name example.com;
return 404; # managed by Certbot
}
https requests are working correctly, but http requests are throwing a 301 Moved Permanently, the access logs show the following:
[07/Feb/2019:15:28:11 +0000] <ip> -> - | POST /api/test HTTP/1.1 | upstream_response_time - msec | request_time 0.000 msec | status: 301
[07/Feb/2019:15:28:11 +0000] <ip> -> <one.example.com IP>:80 | GET /api/test HTTP/1.1 | upstream_response_time 0.007 msec | request_time 0.007 msec | status: 405
(my log format is '[$time_local] $remote_addr -> $upstream_addr | $request | upstream_response_time $upstream_response_time msec | request_time $request_time msec | status: $status'
The return 301 seems to be modifying the request type from POST to GET (which the destination application does not allow). I have very similar setups on non load balanced web servers, all working as expected.
It's also important to note that the final config file was generated by certbot.