35

I have a Nginx server, and disabled hidden files in the nginx_vhost.conf

## Disable .htaccess and other hidden files
    location ~ /\. {
        deny all;
        access_log off;
        log_not_found off;
    }

But LetsEncrypt needs access to the .well-known directory.

How do I allow the .well-known directory and deny the other hidden files?

2
  • 1
    Note: nginx does not use or have .htaccess files. It has configuraiton files but they aren't called .htaccess, nor do they work the same.
    – Rob
    Aug 26, 2018 at 12:11
  • 1
    @Rob it's not that nginx uses .htaccess files... it's in case you are moving from apache to nginx and you don't want nginx to serve the content of .htaccess files... and you don't want to move or delete the .htaccess files yet either
    – aequalsb
    Jan 19, 2023 at 16:24

5 Answers 5

42

The other solutions did not helped me.

My solution is to include a negative regex for .well-known. Your code block should look like this then:

## Disable .htaccess and other hidden files
location ~ /\.(?!well-known).* {
    deny all;
    access_log off;
    log_not_found off;
}

It will block every dot file except the ones starting with .well-known

P.S.: I would also add return 404; to the block.

4
  • 1
    Is location ~* /\.(?!well-known\/) { as seen at github.com/h5bp/server-configs-nginx/blob/master/h5bp/location/… identical to this location ~ /\.(?!well-known).* { ?
    – Pro Backup
    Mar 17, 2018 at 21:21
  • 3
    no it's not the same exactly. /\.(?!well-known\/) is not as expressive as my regex (because I block all dot files except well-known by definition). Maybe the best would be a combination like location ~ /\.(?!well-known\/).* which unblocks only the well-known directory instead also a theoretical .well-known-blabla. But I think there is no real danger in not blocking a theoretic .well-known-blabla file. Apr 4, 2018 at 8:59
  • why disable htaccess since anyway Nginx doesn't handle it ?
    – DiaJos
    Sep 18, 2018 at 13:10
  • 3
    Yes you're right @webwoman but sometimes there are mixed environments. Any dot file should not be served in my opinion (security or unwanted exposing of history like with .git) unless really needed. Mar 8, 2019 at 21:57
29

Nginx applies locations with regular expressions in the order of their appearance in the configuration file.

Therefore, adding an entry like this just before your current location it will help you.

location ~ /\.well-known { 
    allow all;
}
1
  • Thank you, this is exactly what I needed! Placed this before a rule denying access to all dotfiles. Only thing I changed was escaping the dot, e.g. location ~ /\.well-known {. Either way, this should be the accepted answer. Nov 30, 2018 at 13:13
9

I've provided a full step by step tutorial on how to use Let's Encrypt with NGINX on my website.

The key parts are:

  • The official client is only ok, and is really poor on Amazon Linux. I recommend a different client, ACME.
  • Use this location for the webroot method, with my recommend client. Note that the requests are served over http, not https.

You don't need listeners in your https block at all, it's all done on https. This is only to prove you control the domain, it's not serving anything private or secret.

# Answer let's encrypt requests, but forward everything else to https
server {
  listen       80;
  server_name  example.com www.example.com
  access_log  /var/log/nginx/access.log main;

  # Let's Encrypt certificates with Acmetool
  location /.well-known/acme-challenge/ {
    alias /var/www/.well-known/acme-challenge/;
  }

  location / {
    return       301 https://www.example.com$request_uri;
  }
}

Full step by step guide linked above.

3

Add this (before or after):

location ^~ /.well-known/ {
        log_not_found off;
     }

You can add this also at bottom, because the matching ^~ modifier takes precedence over regular expressions. See the the docs.

0

If you have lots of config files and they already contain a deny on .htaccess like

location ~ /\.ht { deny all; }

then instead of ignoring all dot files, you can simply add a second ignore for .git with

sed -i '/location ~ \/\\.ht { deny all; }/a \  location ~ \/\\.git { deny all; }' /etc/nginx/*

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .