Skip to content

Instantly share code, notes, and snippets.

@gwillem
Last active July 29, 2023 10:13
Show Gist options
  • Save gwillem/cd5ae6845fa33aa0d481 to your computer and use it in GitHub Desktop.
Save gwillem/cd5ae6845fa33aa0d481 to your computer and use it in GitHub Desktop.

Revisions

  1. gwillem revised this gist Apr 12, 2016. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions magento-nginx.conf
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,8 @@
    # This is an annotated subset of the Nginx configuration from our Magento production platform @ www.hypernode.com
    # See https://www.byte.nl/blog/magento-cacheleak-issue

    # !!!! If you are a Hypernode customer, do not use this config as it will result in duplicate statements. !!!!!

    user app;
    worker_processes 4;
    pid /var/run/nginx.pid;
  2. gwillem revised this gist Oct 7, 2015. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion magento-nginx.conf
    Original file line number Diff line number Diff line change
    @@ -38,7 +38,7 @@ http {

    gzip_min_length 1000;
    gzip_proxied any;
    gzip_types text/plain application/xml text/css text/js application/x-javascript;
    gzip_types text/plain text/html application/json application/xml text/css text/js application/x-javascript;

    # Determine whether a request comes from a human, a search crawler or another bot.
    map $http_user_agent $is_non_search_bot {
  3. gwillem revised this gist Oct 7, 2015. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions magento-nginx.conf
    Original file line number Diff line number Diff line change
    @@ -1,5 +1,5 @@
    # This is an annotated subset of the configuration from our Magento production platform @ www.hypernode.com
    # We share this config to eliminate Magento cacheleak risks - see http://www.byte.nl/blog.
    # This is an annotated subset of the Nginx configuration from our Magento production platform @ www.hypernode.com
    # See https://www.byte.nl/blog/magento-cacheleak-issue

    user app;
    worker_processes 4;
  4. gwillem created this gist Oct 2, 2015.
    242 changes: 242 additions & 0 deletions magento-nginx.conf
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,242 @@
    # This is an annotated subset of the configuration from our Magento production platform @ www.hypernode.com
    # We share this config to eliminate Magento cacheleak risks - see http://www.byte.nl/blog.

    user app;
    worker_processes 4;
    pid /var/run/nginx.pid;

    events {
    worker_connections 768;
    }

    http {
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;
    server_tokens off;
    server_names_hash_bucket_size 64;

    # allows big media uploads
    client_max_body_size 120m;

    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    # GeoIP support is included in the Ubuntu 12.04 Nginx.
    # This enables logging, and the following:
    # if ($geoip_country_code ~ (CN|ZW) ) {
    # return 403;
    # }
    geoip_country /usr/share/GeoIP/GeoIP.dat;
    gzip on;
    gzip_disable "msie6";

    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    gzip_min_length 1000;
    gzip_proxied any;
    gzip_types text/plain application/xml text/css text/js application/x-javascript;

    # Determine whether a request comes from a human, a search crawler or another bot.
    map $http_user_agent $is_non_search_bot {
    default '';
    ~*(google|bing|pingdom|monitis.com|Zend_Http_Client) '';
    ~*(http|crawler|spider|bot|search|ForusP|Wget/|Python-urllib|PHPCrawl|bGenius) 'bot';
    }

    # Rate limit bots (that are not search spiders) to one PHP request per second.
    # An empty '$limit_bots' would disable rate limiting for this requests
    limit_req_zone $is_non_search_bot zone=bots:1m rate=1r/s;
    limit_req_log_level error;

    index index.html index.php;

    server {
    listen 80 default_server;
    root /var/www;

    # Android dupe request bug, https://www.byte.nl/blog/android-bug-can-kill-site-duplicate-requests
    set $request_url "$scheme://$http_host$request_uri";
    if ($request_url = $http_referer) {
    set $request_is_referer 1;
    }
    if ($http_user_agent ~ 'Android ([23]|4\.[0123])') {
    set $android_buggy_ua 1;
    }
    set $android_dupe_bug "${request_method}${android_buggy_ua}${request_is_referer}";
    if ($android_dupe_bug = 'GET11') {
    # http://en.wikipedia.org/wiki/List_of_HTTP_status_codes
    return 429;
    }

    # Denied locations require a "^~" to prevent regexes (such as the PHP handler below) from matching
    # http://nginx.org/en/docs/http/ngx_http_core_module.html#location
    location ^~ /app/ { return 403; }
    location ^~ /includes/ { return 403; }
    location ^~ /media/downloadable/ { return 403; }
    location ^~ /pkginfo/ { return 403; }
    location ^~ /report/config.xml { return 403; }
    location ^~ /var/ { return 403; }
    location ^~ /lib/ { return 403; }
    location ^~ /dev/ { return 403; }
    location ^~ /RELEASE_NOTES.txt { return 403; }
    location ^~ /downloader/pearlib { return 403; }
    location ^~ /downloader/template { return 403; }
    location ^~ /downloader/Maged { return 403; }
    location ~* ^/errors/.+\.xml { return 403; }

    # CVE-2015-3428 / AW_Blog vulnerability
    # Note the .+ at the start: We want to allow url's like
    # order=create_date, which would otherwise match.
    if ($arg_order ~* .+(select|create|insert|update|drop|delete|concat|alter|load)) {
    return 403;
    }

    # Don't skip .thumbs, this is a default directory where Magento places thumbnails
    # Nginx cannot "not" match something, instead the target is matched with an empty block
    # http://stackoverflow.com/a/16304073
    location ~ /\.thumbs {
    }

    # Skip .git, .htpasswd etc
    location ~ /\. {
    return 404;
    }

    set $fastcgi_root $document_root;

    location / {
    try_files $uri $uri/ @handler;
    expires 30d;
    }

    # SUPEE 6285
    # Only allow the new url case sensitive lowercase, deny case insensitive
    location ^~ /rss/order/new {
    echo_exec @handler;
    }
    location ^~ /rss/catalog/notifystock {
    echo_exec @handler;
    }
    location ^~ /rss/catalog/review {
    echo_exec @handler;
    }
    location ~* /rss/order/new {
    return 403;
    }
    location ~* /rss/catalog/notifystock {
    return 403;
    }
    location ~* /rss/catalog/review {
    return 403;
    }

    ## Order IS important! this is required BEFORE the PHP regex
    ## Allow PHP scripts in skin and JS, but render static 404 pages when skin or js file is missing
    ## Magento has RewriteCond %{REQUEST_URI} !^/(media|skin|js)/ in default htaccess
    location ~ ^/(skin|js)/ {
    location ~ \.php$ {
    echo_exec @phpfpm;
    }
    try_files $uri $uri/ =404;
    expires 30d;
    }
    # Disallow PHP scripts in /media/
    # Also render static 404 pages for missing media
    location ~ ^/media/ {
    location ~ \.php$ {
    return 403;
    }
    try_files $uri $uri/ =404;
    expires 30d;
    }

    location @handler {
    rewrite / /index.php;
    }

    location @fastcgi_backend {

    # Bot rate limit, https://gist.github.com/supairish/2951524
    # Burst=0 (default) --WdG
    limit_req zone=bots;

    # server_name is read-only, so we need a temp var
    set $my_server_name $server_name;
    if ($my_server_name = "") {
    set $my_server_name $http_host;
    }

    try_files $uri =404;
    expires off;
    root $fastcgi_root;
    fastcgi_read_timeout 900s;
    fastcgi_index index.php;
    fastcgi_pass $fastcgi_pass;

    include /etc/nginx/fastcgi_params;

    fastcgi_param HTTP_AUTHORIZATION $http_authorization;
    fastcgi_param SERVER_NAME $my_server_name;

    fastcgi_param NGINX_REQUEST_TIME $date_gmt;

    # If these variables are unset, set them to an empty value here
    # so they are al least defined when fastcgi_param directives are called
    if ($storecode = "") {
    set $storecode "";
    }

    if ($storetype = "") {
    set $storetype "";
    }

    # These are set in http.magerunmaps
    fastcgi_param MAGE_RUN_CODE $storecode if_not_empty;
    fastcgi_param MAGE_RUN_TYPE $storetype if_not_empty;

    }

    location @phpfpm {
    set $log_handler phpfpm;
    set $fastcgi_pass 127.0.0.1:9000;
    echo_exec @fastcgi_backend;
    }

    location @hhvm {
    set $log_handler hhvm;
    set $fastcgi_pass 127.0.0.1:9001;
    echo_exec @fastcgi_backend;
    }

    # Protection against unsecured magmi installs. User-editable
    # so user may set it up as they want. Must be included here
    # to catch and redirect PHP files, if this was loaded in later
    # (after the default php-fpm handler for .php files) then we
    # would not be able to redirect the magmi .php files (which are
    # the ones we really MUST redirect).
    location ~* /magmi($|/) {
    return https://support.hypernode.com/knowledgebase/securing-access-to-magmi/;
    }

    location ~ .php/ {
    rewrite ^(.*.php)/ $1 last;
    }

    # always execute our own handler for php-fpm, to prevent serving raw php code and to have
    # a default when user removes configuration from ~/nginx/
    location ~ \.php$ {
    echo_exec @phpfpm;
    }


    rewrite ^/minify/([0-9]+)(/.*.(js|css))$ /lib/minify/m.php?f=$2&d=$1 last;
    rewrite ^/skin/m/([0-9]+)(/.*.(js|css))$ /lib/minify/m.php?f=$2&d=$1 last;
    location /lib/minify/ { allow all; }

    }

    }