Squid proxy : blocking download of some file extensions

It is a common request in squid to have it block downloading certain files based on their extension in the url path. A quick look at google’s results on the subject apparently gives us the solution to get this done easily by squid.

The common solution is to create an ACL file listing regular expressions of the extensions you want to block and then apply this to your http_access rules.

blockExtensions.acl

\.exe$

squid.conf

acl blockExtensions urlpath_regex -i "/etc/squid/blockExtensions.acl"

[...]

http_access allow localnet !blockExtensions

Unfortunately this is not enough to prevent users from downloading .exe files.Β The mistake here is that we assume that the URL will strictly finish by the extension we want to block, consider the two examples below :

http://download.com/badass.exe     // will be DENIED as expected

http://download.com/badass.exe?    // WON'T be denied as it does not match the regex !

Squid uses the extended regex processor which is the same as egrep. So we need to change our blockExtensions.acl file to handle the possible ?whateverΒ string which may be trailing our url_path. Here’s the solution to handle all the cases :

blockExtensions.acl

\.exe(\?.*)?$
\.msi(\?.*)?$
\.msu(\?.*)?$
\.torrent(\?.*)?$

You will still be hated for limiting people’s need to download and install shit on their Windows but you implemented it the right way and no script kiddie can brag about bypassing you πŸ˜‰

29 thoughts on “Squid proxy : blocking download of some file extensions”

  1. I hate you!
    OK, so you block ?, but what about # ?
    Do Squid consider it part of the url?

    1. Good question indeed, usually it should not but I guess squid would consider it in the regex matching. So I might indeed be missing the # !

      Since you’re not hating me that much, would be kind enough to try and report back to me so I can fix my post thanks to your insight ? πŸ™‚

  2. OK now I hate you twice as much:
    – because the anchor seems to be not included in the urlpath for squid. And it makes sense because it’s the same content being accessed/cached, and the anchor is supposed to be processed on the client side. So your regex matches well.
    – and because for some reason I could download all file types before you applied this patch (even without ?) and now I can’t.

    So thank you Mr SysAdmin!

  3. Does this work for squid version 3.1.19? I tried it on this version and it didn’t work. Please assist.

    1. Well it should. As 3.1.19 is only a minor release of squid we can expect that they didn’t break anything. What exactly doesn’t work mate ?

      1. I followed the steps above to block torrents both in url and also tried to block the torrent application by configuring the acl port denied. But all did not work on squid3

        acl smile_lan src 10.32.0.0/23
        acl limited_users src 10.32.0.0/23
        acl blockExtensions urlpath_regex -i “/etc/squid3/blockExtensions.acl”

        acl SSL_ports port 443
        acl Safe_ports port 80 # http
        acl Safe_ports port 21 # ftp
        acl Safe_ports port 443 # https
        acl Safe_ports port 70 # gopher
        acl Safe_ports port 210 # wais
        #acl Safe_ports port 1025-65535 # unregistered ports
        acl Safe_ports port 280 # http-mgmt
        acl Safe_ports port 488 # gss-http
        acl Safe_ports port 591 # filemaker
        acl Safe_ports port 777 # multiling http
        acl Denied_ports port 1025-65535
        acl CONNECT method CONNECT
        acl download method CONNECT
        acl download method GET

        http_access allow manager localhost
        http_access deny manager

        # Deny requests to certain unsafe ports
        http_access deny !Safe_ports
        http_access deny Denied_ports

        # Deny CONNECT to other than secure SSL ports
        http_access deny CONNECT !SSL_ports
        http_access deny CONNECT Denied_ports

        http_access allow localhost
        http_access allow smile_lan
        http_access allow !blockExtensions

        1. Hello Bayo,

          The http_access rules are processed consecutively until one matches.
          In your case, if the host you’re trying to limit is part of the smile_lan, it will be allowed to access any URL because the rule is written before the !blockExtensions one.

          I think that to resolve this you can either use :
          http_access allow localhost
          http_access allow !blockExtensions smile_lan

          or

          http_access allow localhost
          http_access deny blockExtensions
          http_access allow smile_lan

          Hope this helps.

  4. this method will not apply for https links with blocked attachments.. For example when zip attachment is blocked you can still download through yahoo emails and or dropbox .. Any way to block all those as well that are going through https?

    1. That would require SSL inspection which, AFAIR, you could do on the websites where you actually have the private SSL key but not the others.

  5. Hello:
    I am unable to block any type of downloading in squid .I am using Linux Mint 17 (ubuntu 14.04). squid server is 3.3.8. I searched on google alot and also tried the above but I am faild to do so. here is my simple conf. file. Looking for quick reasponse.
    Thanks in advance.

    acl localnet src 10.0.0.0/8 # RFC1918 possible internal network
    acl SSL_ports port 443
    acl Safe_ports port 80 # http
    acl Safe_ports port 21 # ftp
    acl Safe_ports port 443 # https
    acl Safe_ports port 70 # gopher
    acl Safe_ports port 210 # wais
    acl Safe_ports port 1025-65535 # unregistered ports
    acl Safe_ports port 280 # http-mgmt
    acl Safe_ports port 488 # gss-http
    acl Safe_ports port 591 # filemaker
    acl Safe_ports port 777 # multiling http
    acl CONNECT method CONNECT
    acl blockfiles urlpath_regex β€œ/etc/squid3/blocks.files.acl”
    acl yt dstdomain .facebook.com

    http_access deny !Safe_ports
    http_access deny CONNECT !SSL_ports
    http_reply_access deny yt
    http_access deny CONNECT yt

    http_access deny blockfiles

    http_access allow localnet
    http_access allow localhost
    http_port 3128

    1. As mentioned in the article, I don’t think you should use http_access deny blockfiles but only use http_access allow localnet !blockfiles instead

  6. Thanks for quick reply, I tried the following :
    http_access allow localnet !blockfiles
    http_access deny all

    but the result is the same :(. Any Idea ????

  7. Hi

    I have successfully blocked most of the extensions using this reg pattern.. it cannot be blocked some extensions for some urls like this..

    http://urlblacklist.com/cgi-bin/commercialdownload.pl?type=information&file=bigblacklist
    (above url is One of the squid guard blacklist db urls)
    But cant understand what mechanism will allow this tar.gz?
    Apparently it does not pass any extension details through the url itself.. Any idea how to block these things as well ?

    1. Hi Ara,

      Maybe it’s normal, but the URL you provide does not work. Anyway, regular expressions only work on URIs and do NOT provide any type of content inspection so Squid at this stage will not know you’re actually downloading a tar.gz.

      On this case, the best course would maybe to block the whole domain or use a regular expression to match the whole /commercialdownload.pl URL path and block it altogether.

      Hope this helps

  8. Hi
    Just wondering.. Is there a way to apply this extension block only for a single site?
    For example i want to block .zip only for xyz.com. and let other sites as allowed.. Kindly shade a light how to proceed? I have just tried my self .. but failed πŸ™ dont know how to apply conditions.. Thanking you in advanced..

    1. Hi,

      Yes it should be doable mate:
      – create a new file containing the domains you want to match, for example noDownloadDomains.acl and inside put your domain like this .xyz.com
      – create the matching ACL in your squid.conf : acl noDownloadDomains dstdomain "/etc/squid/noDownloadDomains.acl"
      – then apply the restriction by combining the two together : http_access deny noDownloadDomains blockExtensions

      This should work I guess πŸ™‚

  9. How to block websites based on keywords?

    For example porn, nude, like that.

    Also i need to know how to block the torrent websites. So that i can impliment in my company without any issues.

    1. Well you could use the same kind of ACL and use it on the whole URL (remove the $ at the end) but I strongly suggest using blacklists in your case which all provide categorized lists of URLS. Then you’ll be able to filter out ‘adult’, ‘torrent’ URLS even if they don’t contain ‘porn’ or ‘torrent’ in them πŸ˜‰

      To sum up : what you’re looking for is SquidGuard !

    1. Hello Brian, thanks for your insight.

      As for your question, the easiest way would maybe be:

      \.crypt([a-zA-Z]*)?(\?.*)?$

      1. thanks for your quick and good response. its Works!
        An additional question:
        I have the following locked extension:
        \ .zip$
        in a acl with the rule
        acl ext url_regex -i “/home/user/acl/ext.txt”
        http_access deny ext
        this rule block:
        http://www.hirensbootcd.org/files/Hirens.BootCD.15.2.zip
        But not block this:
        http://www.hirensbootcd.org/files/Hirens.BootCD.15.2.zip?
        How I can block anything after an extension? (like this? … \.zip([a-zA-Z]*)?(\?.*)?$ or how)
        Thanks a lot

        1. Yes. This \.zip([a-zA-Z]*)?(\?.*)?$ block both (.zip and zip?)
          however I need to block ransomware extensions with letters and numbers. Example:
          .73i87A
          .8lock8
          .AES256
          How can i complete regex to block letter (a-zA-Z) and numbers (0-9)
          Thanks

          1. Just add the numeric range in the regexp like this πŸ™‚

            \.crypt([a-zA-Z0-9]*)?(\?.*)?$

    1. Hello, indeed this does not apply to HTTPS links because this would require SSL inspection. See ara’s comment above and my reply about it.

      1. thanks for the reply man … really appreciate ur help … im new in this things so i understand that u need de SSL certificates of the sites in order to block https downloads … that i dont know how to do it … the other thing its to block the specific https site … or to block all https sites … because if i block only the https site users always can find another … so … that 2 other options … not so good in my opinion .. there is another possible way … im using besides the regular acl urlpath_regex with file extensions in it and also this
        reply_body_max_size 1 MB

        what do u think … my case exactly it’s to block downloads until it’s 15:00 hour

        thanks in advance

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.