JTG
JTG

Reputation: 8836

Symfony Production Website not forcing https (using nginx)

In my app/config/security.yml file I have have:

access_control:
    - { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY, requires_channel: https }
    - { path: ^/admin, roles: ROLE_ADMIN, requires_channel: https }

In development (using the symfony built in server), if I go to localhost/login it redirects me to the https://localhost/login.

However, in my production site, going to example.com/login and I simply see the login page. The browser indicates that the connection isn't secured.

My intuition thinks it may have something to do with the nginx config file.

server {
        listen       80;
        listen       443 ssl;
        server_name  example.com;
        root /var/www/symfony/web;

        client_max_body_size 500M;

        location / {
             # try to serve file directly, fallback to app.php
             index app.php;
             try_files $uri @rewriteapp;
        }

        location @rewriteapp {
             rewrite ^(.*)$ /app.php/$1 last;
        }

        location ~ ^/app\.php(/|$) {
            fastcgi_pass unix:/var/run/php5-fpm.sock;
            fastcgi_split_path_info ^(.+\.php)(/.*)$;
            include fastcgi_params;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_param HTTPS on;
        }
        error_log /var/log/nginx/adam_error.log;
        access_log /var/log/nginx/adam_access.log;
    }

Which, I more or less copied from here

A few other things to note: If I am redirected to the login page internally by symfony (ie if I try to access an /admin restricted route or fail the login on the unsecure connection, I DO get routed to the secure https://example.com/login url, but obviously that isn't good enough, I don't want anyone entering example.com/login and not having a secure connection).

Can anyone spot what maybe going wrong?

Upvotes: 1

Views: 2898

Answers (2)

JTG
JTG

Reputation: 8836

Okay, I figured it out. In my nginx configuration:

fastcgi_param HTTPS on;

was causing the problem. It turns out that with it set to "on", it doesn't force a redirect to https if the initial port was 80 (I guess symfony considers port 80 to be https with this configuration), and with it set to "off", it causes an infinite redirect (nginx redirects url to port 80 and symfony redirects url to port 443).

So the solution was to turn it off if it was port 80 and to turn it on if it was port 443 (the ssl port).

This is what my nginx.conf looks like now:

server {
        listen       80;
        listen       443 ssl;
        server_name  example.com;
        root /path/to/symfony_directory/web;

        #if your version of nginx is < 1.11.11, uncomment these next two lines
        #as $https will not be defined.
        #if ($server_port = 443) { set $https on; }
        #if ($server_port = 80) { set $https off; }

        location / {
             # try to serve file directly, fallback to app.php                                        
             # try_files $uri /app.php$is_args$args;                                                  
             index app.php;
             try_files $uri @rewriteapp;
        }

        location @rewriteapp {
             rewrite ^(.*)$ /app.php/$1 last;
        }

        location ~ ^/app\.php(/|$) {
            fastcgi_pass unix:/var/run/php5-fpm.sock;
            fastcgi_split_path_info ^(.+\.php)(/.*)$;
            include fastcgi_params;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

            #NOTE THAT "$https" is defined by nginx to be 
            # "on" if port 443 and off for port 80 (for version > 1.1.11)
            fastcgi_param HTTPS $https; 

        }
    }

Upvotes: 5

Smashou
Smashou

Reputation: 378

For forcing HTTPS on Nginx you have to modify your nginx config file like this one:

server {
    listen 80;

    location /login {
         return 301 https://$host$request_uri;
    }
}

server {
    listen 443 ssl;

    # let the browsers know that we only accept HTTPS
    add_header Strict-Transport-Security max-age=2592000;

    #Put the rest of your config here
}

Source: Github

Upvotes: 0

Related Questions