FastCGI application behind NGINX is unable to detect that HTTPS secure connection is used

17,455

Solution 1

Make sure nginx is sending fastcgi_param HTTPS on for connections on 443.

Solution 2

Thanks to Yuji for the answer. I've updated my server block to conditionally inject HTTPS on or HTTPS off, depending on $server_port:

{

server {
    listen       80;
    listen       443 default ssl;

    if ($server_port = 443) { set $https on; }
    if ($server_port = 80) { set $https off; }

    ssl_certificate   /home/webapp/ssl.crt
    ssl_certificate_key /home/webapp/ssl.key

    server_name  myapp.com;
    access_log /home/webapp/access.log
    error_log  /home/webapp/error.log

    root   /home/mywebapp;

    location / {
           # host and port to fastcgi server                      
       fastcgi_pass 127.0.0.1:8801;
       fastcgi_param PATH_INFO $fastcgi_script_name;
       fastcgi_param REQUEST_METHOD $request_method;
       fastcgi_param QUERY_STRING $query_string;
       fastcgi_param SERVER_NAME $server_name;
       fastcgi_param SERVER_PORT $server_port;
       fastcgi_param SERVER_PROTOCOL $server_protocol;
       fastcgi_param CONTENT_TYPE $content_type;
       fastcgi_param CONTENT_LENGTH $content_length;
       fastcgi_pass_header Authorization;
       fastcgi_intercept_errors off;

       fastcgi_param HTTPS $https;
    }
}

}

Share:
17,455
Aneil Mallavarapu
Author by

Aneil Mallavarapu

Updated on June 07, 2022

Comments

  • Aneil Mallavarapu
    Aneil Mallavarapu almost 2 years

    I'm running FastCGI behind Nginx, and need to detect when the url is accessed via HTTPS. However, my Django web application always reports that the connection is HTTP (request.is_secure() == False). However, SSL is setup correctly, and I've verified my https:// urls are secure with an SSL checker.

    How can I get Django to correctly detect when the request is from an HTTPS url?

    My Nginx settings are:

    http {
        include       mime.types;
        default_type  application/octet-stream;
    
        sendfile        on;
        keepalive_timeout  65;
    
        gzip  on;
    
        server {
            listen       80;
            listen       443 default ssl;
            ssl_certificate   /home/webapp/ssl.crt
            ssl_certificate_key /home/webapp/ssl.key
    
            server_name  myapp.com;
            access_log /home/webapp/access.log
            error_log  /home/webapp/error.log
    
            root   /home/mywebapp;
    
            location / {
                   # host and port to fastcgi server                      
               fastcgi_pass 127.0.0.1:8801;
               fastcgi_param PATH_INFO $fastcgi_script_name;
               fastcgi_param REQUEST_METHOD $request_method;
               fastcgi_param QUERY_STRING $query_string;
               fastcgi_param SERVER_NAME $server_name;
               fastcgi_param SERVER_PORT $server_port;
               fastcgi_param SERVER_PROTOCOL $server_protocol;
               fastcgi_param CONTENT_TYPE $content_type;
               fastcgi_param CONTENT_LENGTH $content_length;
               fastcgi_pass_header Authorization;
               fastcgi_intercept_errors off;
            }
        }
    }
    

    I start the Django FastCGI process with:

    python /home/webapp/manage.py runfcgi method=threaded host=127.0.0.1 port=8801 pidfile=/home/webapp/fastcgi.pid 
    
  • Aneil Mallavarapu
    Aneil Mallavarapu over 13 years
    Ah, thanks, that does the trick. Is there a way to set this parameter just for port 443? That is, without having to duplicate the entire configuration block?
  • samy-delux
    samy-delux over 11 years
    The $https is now defined by nginx since 1.1.11 by default.
  • Sean Anderson
    Sean Anderson over 10 years
    As demonstrated below...you should set the variable to "off" for port 80 as well.
  • Ben
    Ben almost 10 years
    very good answer. the way to go on my nginx/1.0.15 installation
  • Adrián Jaramillo
    Adrián Jaramillo over 2 years
    You made me realize that fastcgi_param HTTPS is the line on the php location that dictates whether HTTPS is used or not. I was having problems with my Nextcloud + Nginx configuration because I was getting redirected to HTTPS, and I eliminated that line and worked (alongside deleted some other lines).