1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Force SSL for admin pages only on nginx

Discussion in 'Server Configuration and Hosting' started by Per Hansson, Sep 10, 2015.

  1. Per Hansson

    Per Hansson Member

    Hi, I'm trying to force SSL or HTTPS access only for the admin interface in Xenforo.
    I want the rest of the forum to be in regular http for advertising purposes.
    Maybe next year the ad-pool will be the same for http as well so the whole site can be https, but not yet...

    Currently this is what I have on a local testserver, it's working fine but I'd like input on if there is anything I have missed; and if anything can be done in a better or even just nicer way config wise...

    The config is quite simple, the first "server" block handles https requests coming from any other domain and rewrites it to our domain; then follows the https server config.
    Here I only allow specific locations which should be SSL enabled to continue, all others go back to the regular http server that follows further down.
    In our case I'm allowing the Xenforo admin page and deferred page, plus the folders where it includes content from.
    Also the small favicon is allowed, as that would otherwise also cause a mixed content warning...

    The http server is divided up in two servers, just like the https one, so we can rewrite the url of traffic coming from any domain to our own.
    What follows is an expires directive for static content, and then the Xenforo config.

    As long as the admin.php file is not requested all traffic will be served via http.
    But as soon as someone requests admin.php we will be redirected back to the https server.
    I tested this on all buttons I could find in the admin interface and never got a mixed content warning. ;)
    But your input is of course most welcome! :)

    Code:
        server {
            ## Redirect to Domain if $host does not match https://www.domain.com
            ## This will raise a SSL warning because the SSL cert obviously does not match the requested domain (somedomain, direct ip etc)
            listen       443 ssl spdy default_server;
            server_name  _;
            ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
            ssl_certificate /somepath...crt;
            ssl_certificate_key /somepath...key;
            return 301 http://www.domain.com$request_uri;
        }
        server {
            ## SSL server listening on https port 443
            listen       443 ssl spdy;
            server_name  www.domain.com;
            limit_conn addr 20;
            ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
            ssl_certificate /somepath...crt;
            ssl_certificate_key /somepath...key;
    
            ## Redirect back to http for all general requests
            location / {
              return 301 http://www.domain.com$request_uri;
            }
    
            ## Xenforo admin pages
            location = /community/admin.php {
              fastcgi_pass _php;
            }
            location = /community/deferred.php {
              fastcgi_pass _php;
            }
            location ~ ^/community/(js|styles|data) {
              #This location allows Xenforo content to be delivered via https
              #without raising mixed content warnings in browsers
              try_files $uri =404;
            }
            location = /favicon.ico {
              log_not_found off;
              access_log off;
            }
        }
    
        server {
            ## Redirect to Domain if $host does not match http://www.domain.com
            listen       80 default_server;
            server_name  _;
            return 301 http://www.domain.com$request_uri;
        }
        server {
            ## Domain server listening on http port 80
            listen       80;
            server_name  www.domain.com;
            limit_conn addr 20;
    
            ## Tell browsers to cache these files for 90 days and serve them directly
            ## Note that thus these filetypes can NOT be rewritten again below!
            location ~* \.(jpg|jpeg|gif|css|png|ico|js)$ {
              expires 90d;
            }
    
    
            # Xenforo
            location /community/ {
               try_files  $uri $uri/ /community/index.php?$uri&$args;
            }
            location ~ /community/(internal_data|library|install/data|install/templates) {
               internal;
            }
            # SSL redirect for Xenforo admin pages
            location = /community/admin.php {
               return 301 https://$server_name$request_uri;
            }
    
    
            # Pass all .php files onto a php-fpm/php-fcgi server.
            location ~ \.php$ {
               # Zero-day exploit defense.
               # http://forum.nginx.org/read.php?2,88845,page=3
               # Won't work properly (404 error) if the file is not stored on this server, which is entirely possible with php-fpm/php-fcgi.
               # Comment the 'try_files' line out if you set up php-fpm/php-fcgi on another machine.  And then cross your fingers that you won't get hacked.
               try_files $uri =404;
               fastcgi_split_path_info ^(.+\.php)(/.+)$;
               fastcgi_pass _php;
            }
    
    
            # deny access to .htaccess files, if Apache's document root
            # concurs with nginx's one
            #
            location ~ /\.ht {
                deny  all;
            }
            location ~ /\.git {
                deny all;
            }
    
     
    Last edited: Sep 11, 2015
    Marcus likes this.
  2. pegasus

    pegasus Well-Known Member

    If the application (XenForo) is not aware of this change with any of its settings, make sure you don't redirect POST requests or you might lose data from forms that use absolute URLs.
     

Share This Page