Secure Mediawiki Nginx Configuration

From Bonus Bits
Jump to: navigation, search

Description

This article gives a secure Nginx with PHP-FPM 7.0 configuration example for a Mediawiki server.


HTTPS Terminates on Load Balancer

In this example a load balancer terminates SSL/TLS traffic and sends on the backend Clear HTTP to the server. In order for the server to understand the traffic was secured and the load balancer is dealing with the encryption we look for a X Forward Protocol Header as an identification. So in the LocalSettings.php we have https://www.example.com and all the published URLs will include HTTPS. I believe that this will work fine even if only using HTTP due to the condition, but I have not tested it.

127.0.0.1:9000 is what PHP-FPM is default listening on. This is set in the /etc/php-fpm-7.0.d/www.conf file.

The location ^~ /resources/ { internal; } will break the default logo and any image files you try to serve from the folder. Either comment this out or move you logo/s to the images folder and adjust your LocalSettings.php

10.0.0.1 is the IP address LAN Network Adapter on the Firewall/Load Balancer/WAF/HTTPS Termination Device.

vim /etc/nginx/conf.d/mediawiki.conf
server {
    listen 80 backlog=1024;
    set_real_ip_from 10.0.0.1;
    real_ip_header X-Forwarded-For;
    real_ip_recursive on;
    server_name example.com www.example.com;
    root /var/www/html/mediawiki;
    index index.php;
    client_max_body_size 24000M;
    #access_log /var/log/nginx/mediawiki_access.log;
    #error_log /var/log/nginx/mediawiki_error.log;
    #error_log /var/log/nginx/debug.log debug;

    location / {
        #   Recognize if HTTPS Terminate Prior to Nginx Getting Hands on it
        if ($http_x_forwarded_proto != 'https') {
            rewrite ^ https://$host$request_uri? permanent;
        }
        try_files $uri $uri/ @handler;
        error_page 404 = @mediawiki;
    }

    # location @mediawiki {
    #     rewrite ^/wiki([^?]*)(?:\?(.*))? /index.php?title=$1&$2 last;
    # }

    location @handler {
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_param SCRIPT_FILENAME /var/www/html/mediawiki/index.php;
        include /etc/nginx/fastcgi_params;
        fastcgi_param SCRIPT_NAME /index.php;
    }

    location ~ .php$ {
        try_files $uri @handler;
        fastcgi_pass    127.0.0.1:9000;
        fastcgi_index   index.php;
        fastcgi_param SCRIPT_FILENAME /var/www/html/mediawiki$fastcgi_script_name;
        include fastcgi_params;
    }

    #    Exclude all access from the cache directory
    location ^~ /cache/ { deny all; }

    #    Prevent access to any files starting with a dot, like .htaccess
    #    or text editor temp files
    location ~ /\. { access_log off; log_not_found off; deny all; }

    #    Prevent access to any files starting with a dot, like .htaccess
    #    or text editor temp files
    location ~ /\. { access_log off; log_not_found off; deny all; }

    #    Prevent access to any files starting with a $ (usually temp files)
    location ~ ~$ { access_log off; log_not_found off; deny all; }

    #    Do not log access to robots.txt, to keep the logs cleaner
    location = /robots.txt { access_log off; log_not_found off; }

    #    Do not log access to the favicon, to keep the logs cleaner
    location = /favicon.ico { access_log off; log_not_found off; }

    #    Keep images and CSS around in browser cache for as long as possible,
    #    to cut down on server load
    location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
        try_files $uri /index.php;
        expires max;
        log_not_found off;
    }

    # Exception for AutoSitemap sitemap.xml template
    location = /extensions/AutoSitemap/sitemap.xsl { allow all; }

    #    Mark all of these directories as "internal", which means that they cannot
    #    be explicitly accessed by clients. However, the web server can still use
    #    and serve the files inside of them. This keeps people from poking around
    #    in the wiki's internals.
    location ^~ /bin/ { internal; }
    location ^~ /docs/ { internal; }
    location ^~ /extensions/ { internal; }
    location ^~ /includes/ { internal; }
    location ^~ /maintenance/ { internal; }
    #location ^~ /mw-config/ { internal; } #Uncomment after installation
    location ^~ /resources/lib/ { internal; }
    location ^~ /resources/src/ { internal; }
    location ^~ /resources/Resources.php { internal; }
    location ^~ /resources/ResourcesOOUI.php { internal; }
    location ^~ /serialized/ { internal; }
    location ^~ /tests/ { internal; }
    location ^~ /skins/ { internal; }
    location ^~ /vendor/ { internal; }

    #    Force potentially-malicious files in the /images directory to be served
    #    with a text/plain mime type, to prevent them from being executed by
    #    the PHP handler
    location ~* ^/images/.*.(html|htm|shtml|php)$ { types { } default_type text/plain; }

    #    Redirect all requests for unknown URLs out of images and back to the
    #    root index.php file
    location ^~ /images/ { try_files $uri /index.php; }

    #    Deny direct access to uploads directory
    location ~* /(?:uploads|nfsuploads|files)/.*\.php$ { deny all; }
}


Related Articles


Sources