Welcome to Centmin Mod Community
Register Now

Nginx HotLink Protection In CentminMod

Discussion in 'Nginx, PHP-FPM & MariaDB MySQL' started by skringjer, Jan 22, 2022.

Tags:
  1. skringjer

    skringjer NoobMaster69 Premium Member

    179
    23
    18
    Apr 21, 2019
    Ratings:
    +38
    Local Time:
    12:11 PM
    Nginx 1.21.6
    MariaDB 10.3.x
    Please fill in any relevant information that applies to you:
    • CentOS Version: CentOS 7 64bit ?
    • Centmin Mod Version Installed: 123.09beta01
    • Nginx Version Installed: 1.21.4
    • PHP Version Installed: 7.4.26
    • MariaDB MySQL Version Installed: 10.3
    • When was last time updated Centmin Mod code base ? : Automatic Cront
    • Persistent Config: Do you have any persistent config file options set in /etc/centminmod/custom_config.inc ? You can check via this command:
      Code (Text):
      LETSENCRYPT_DETECT='y'
      STATICIP='y'
      PHP_PGO='y'
      NGXDYNAMIC_BROTLI='y'
      NGINX_LIBBROTLI='y'
      MARCH_TARGETNATIVE='n'
      NGXDYNAMIC_NGXPAGESPEED='y'
      NGINX_PAGESPEED='y'
      PHPFINFO='y'
      
      

    Greetings everyone, i have a question, i know about nginx Hotlink protection, but that works on image hotlink or specific files or specific directory, but does anyone know how can i protect my links?


    Like if someone other than the allowed websites comes, the link will be invalid, but if anyone comes from the specified allowed website the link will be valid.

    I already have a function like this in my app but that works on referral tags, so if someone puts rel="noreferrer" in their links this function fails.

    So i been googling around but cant find anything for this, i want my links to work only if someone visits from a website / domain that i have whitelisted
     
  2. cloud9

    cloud9 Premium Member Premium Member

    297
    84
    28
    Oct 6, 2015
    England
    Ratings:
    +143
    Local Time:
    8:11 AM
    1.21.5
    10.3.32
    I dont know how to use the whitelist you have but to allow only the websites you want I would add a location to your

    /usr/local/nginx/conf/conf.d/YOURDOMAINNAME.EXT.ssl cmm file

    in the form of

    Code:
    # Location line matches valid image extensions that will be allowed/blocked - add or remove these with the pipe separator
    location ~ .(gif|png|psd|tiff|eps|ai|raw|jpe?g)$ {
    # Valid referrers lists the websites that will be allowed to hotlink the above file types, add websites here or IP’s
    valid_referers none blocked ADDWEBSITESHERE.com *.SECONDWEBSITE.com;
    #. If the request is from a domain/IP that is not mentioned in valid_referers NGINX will include it in invalid_referer and return “403: Access Forbidden” response.
       if ($invalid_referer) {
          return 403;
       }
    }
     
  3. skringjer

    skringjer NoobMaster69 Premium Member

    179
    23
    18
    Apr 21, 2019
    Ratings:
    +38
    Local Time:
    12:11 PM
    Nginx 1.21.6
    MariaDB 10.3.x
    Thank you imma test this, and let you know :)
     
  4. noly

    noly Member

    100
    16
    18
    Jul 24, 2017
    Germany
    Ratings:
    +28
    Local Time:
    9:11 AM
    1.18.x
    10.2.x
    I‘d be interested in this too. @skringjer Looking forward to your update
     
  5. skringjer

    skringjer NoobMaster69 Premium Member

    179
    23
    18
    Apr 21, 2019
    Ratings:
    +38
    Local Time:
    12:11 PM
    Nginx 1.21.6
    MariaDB 10.3.x
    So i tested this but it does not work, it gives 404 error even after coming from the whitelisted referrer, What i want is basically that files downloaded from my servers via my web app should be protected..

    So right now, i have the following Nginx rewrite rules.

    Code:
     # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        location ~ \.php$ {
            if (!-e $request_filename) { rewrite ^/(.*) /index.php?_page_url=$1 last; }
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME   $document_root$fastcgi_script_name;
            include        fastcgi_params;
        }
    
        location / {
            if (!-e $request_filename) {
                    rewrite ^/(.*) /index.php?_page_url=$1 last;
            }
        }
    
        location /files/ {
            internal;
        }
    
        # these locations would be hidden by .htaccess normally
        location /logs/ {
            deny all;
        }
    
        location ~* "/\.(htaccess|htpasswd)$" {
            deny    all;
            return  404;
        }
    
        location /vstats/ {
            alias   /home/admin/web/domain.com/stats/;
            include /home/admin/conf/web/domain.com.auth*;
        }
    So the files arent served directly from the server but rather via my webapp, its a NextCloud like thing.
     
  6. cloud9

    cloud9 Premium Member Premium Member

    297
    84
    28
    Oct 6, 2015
    England
    Ratings:
    +143
    Local Time:
    8:11 AM
    1.21.5
    10.3.32
    You must be doing something wrong - or something else is interfering

    I just tried it - add this

    Code:
    # Location line matches valid image extensions that will be allowed/blocked - add or remove these with the pipe separator
    location ~ .(gif|png|psd|tiff|eps|ai|raw|jpe?g)$ {
    # Valid referrers lists the websites that will be allowed to hotlink the above file types, add websites here or IP’s
    valid_referers none blocked MYWEBSITEHERE.com;
    #. If the request is from a domain/IP that is not mentioned in valid_referers NGINX will include it in invalid_referer and return “403: Access Forbidden” response.
       if ($invalid_referer) {
          return 403;
       }
    }
    And nothing can hotlink - I put my website in as its an IPS forum and without my own domain name the logos and icons would not show ie internal links

    I added this to add a second site to hotlink

    Code:
    # Location line matches valid image extensions that will be allowed/blocked - add or remove these with the pipe separator
    location ~ .(gif|png|psd|tiff|eps|ai|raw|jpe?g)$ {
    # Valid referrers lists the websites that will be allowed to hotlink the above file types, add websites here or IP’s
    valid_referers none blocked MYWEBSITEHERE.com MYOTHERIPSWEBSITE.co.uk;
    #. If the request is from a domain/IP that is not mentioned in valid_referers NGINX will include it in invalid_referer and return “403: Access Forbidden” response.
       if ($invalid_referer) {
          return 403;
       }
    }
    And now my other website IPS again can hotlink the images - but couldn't without the myotherwebsite domain in the location

    No 404's nginx restarts fine and it works
     
    Last edited: Jan 23, 2022
  7. cloud9

    cloud9 Premium Member Premium Member

    297
    84
    28
    Oct 6, 2015
    England
    Ratings:
    +143
    Local Time:
    8:11 AM
    1.21.5
    10.3.32
    I just edited to make it clearer

    Code:
    # HOTLINK PROTECTION
    # Location line matches valid image extensions that will be allowed/blocked - add or remove these with the pipe separator
    # Valid referrers lists the websites that will be allowed to hotlink the above file types, add websites here or IP’s - Include your own    website    or IP as well
    # If the request is from a domain/IP that is not mentioned in valid_referers NGINX will include it in invalid_referer and return “403: Access Forbidden” response.
        location ~ .(gif|png|psd|tiff|eps|ai|raw|jpe?g)$ {
          valid_referers none blocked MYWEBSITENAME.EXT her OR MYIPADDRESS plus OTHERS you want to HOTLINK;
              if ($invalid_referer) {
              return 403;
              }
        }
     
  8. skringjer

    skringjer NoobMaster69 Premium Member

    179
    23
    18
    Apr 21, 2019
    Ratings:
    +38
    Local Time:
    12:11 PM
    Nginx 1.21.6
    MariaDB 10.3.x
    Still gives me a 404 Not found on my links, even after putting the referrers.

    May be its due to my above rewrite rules conflicting or something.

    So right now this is how my downloads works 01.23.2022-00.01.27
     
  9. cloud9

    cloud9 Premium Member Premium Member

    297
    84
    28
    Oct 6, 2015
    England
    Ratings:
    +143
    Local Time:
    8:11 AM
    1.21.5
    10.3.32
    It could be - you will have to have a play

    Also have you read the Nginx about IFs and they are not that great - try files is better (I noticed an IF in your config)

    See here
     
  10. cloud9

    cloud9 Premium Member Premium Member

    297
    84
    28
    Oct 6, 2015
    England
    Ratings:
    +143
    Local Time:
    8:11 AM
    1.21.5
    10.3.32
    Last edited: Jan 23, 2022
  11. cloud9

    cloud9 Premium Member Premium Member

    297
    84
    28
    Oct 6, 2015
    England
    Ratings:
    +143
    Local Time:
    8:11 AM
    1.21.5
    10.3.32
    Where have you got these rules ?
     
  12. cloud9

    cloud9 Premium Member Premium Member

    297
    84
    28
    Oct 6, 2015
    England
    Ratings:
    +143
    Local Time:
    8:11 AM
    1.21.5
    10.3.32
    And I apologise as your not wanting to protect images - I misread your original post
     
  13. skringjer

    skringjer NoobMaster69 Premium Member

    179
    23
    18
    Apr 21, 2019
    Ratings:
    +38
    Local Time:
    12:11 PM
    Nginx 1.21.6
    MariaDB 10.3.x
    Its okay, my main concern is protecting downloads, zip and rar.

    My app generates link for the files uploaded just like NetxtCloud but i want these links only to work from referrers.
     
  14. cloud9

    cloud9 Premium Member Premium Member

    297
    84
    28
    Oct 6, 2015
    England
    Ratings:
    +143
    Local Time:
    8:11 AM
    1.21.5
    10.3.32
    @skringjer You could try this - I havent tested it

    Code:
    # FILE PROTECTION
    # Location line matches valid extensions that will be allowed/blocked - add or remove these with the pipe separator
    # Valid referrers lists the websites that will be allowed to hotlink the above file types, add websites here or IP’s - Include your own    website    or IP as well
    # If the request is from a domain/IP that is not mentioned in valid_referers NGINX will include it in invalid_referer and return “403: Access Forbidden” response.
        location ~ .(zip|rar|tar|)$ {
          valid_referers none blocked MYWEBSITENAME.EXT her OR MYIPADDRESS plus OTHERS you want to HOTLINK;
              if ($invalid_referer) {
              return 403;
              }
        }
     
  15. eva2000

    eva2000 Administrator Staff Member

    48,417
    11,099
    113
    May 24, 2014
    Brisbane, Australia
    Ratings:
    +17,274
    Local Time:
    5:11 PM
    Nginx 1.21.x
    MariaDB 10.x
    If you use Cloudflare, you can do that pretty much using Cloudflare Firewall rules using referer as criteria.

    An example is domain.com/download.php?link= would be block requests via firewall rule if from referer is not domain.com

    cf-firewall-rules-block-by-referer-01.png

    Or if you need more than referer whitelisted can't use expression GUI builder but need to use raw expression like via edit expression link for something like
    Code (Text):
    (http.host eq "domain.com" and http.request.uri.path contains "/download.php" and http.request.uri.query contains "link=" and not (http.referer contains "domain.com" or http.referer eq "www.domain.com")


    You can also use Cloudflare Transform rules to detect such field criteria like referer, hostname, URI path and query string to redirect users to a page too https://developers.cloudflare.com/rules/transform

    For example for domain.com/download.php?link= with referrer does not contain domain.com, redirect to domain.com/no-permissions.html page removing any query strings from original request

    cf-transform-rule-redirect-by-referer-01.png
     
    Last edited: Feb 2, 2022
  16. rdan

    rdan Premium Member Premium Member

    5,201
    1,304
    113
    May 25, 2014
    Ratings:
    +1,998
    Local Time:
    3:11 PM
    Mainline
    10.2
    Nice tip, Thanks.

    I implemented the same protection but only using URI Full & Referer field, and works great.
    No direct download.
     
  17. eva2000

    eva2000 Administrator Staff Member

    48,417
    11,099
    113
    May 24, 2014
    Brisbane, Australia
    Ratings:
    +17,274
    Local Time:
    5:11 PM
    Nginx 1.21.x
    MariaDB 10.x
    Yup Cloudflare Firewall rules and Transform rules are very useful for this :D
     
  18. cloud9

    cloud9 Premium Member Premium Member

    297
    84
    28
    Oct 6, 2015
    England
    Ratings:
    +143
    Local Time:
    8:11 AM
    1.21.5
    10.3.32
    The Cloudflare tips - here and in other topics - are these paid for CF or the free version ?
     
  19. rdan

    rdan Premium Member Premium Member

    5,201
    1,304
    113
    May 25, 2014
    Ratings:
    +1,998
    Local Time:
    3:11 PM
    Mainline
    10.2
    Just Free.