Many Nginx administrators implement security measures to block access to hidden files (files starting with a dot) by adding this to their server configuration:
location ~ /\\. {
deny all;
access_log off;
log_not_found off;
}
This effectively blocks access to files like .htaccess
, .git
, and other sensitive hidden files. However, this creates problems when you need to allow specific hidden directories like .well-known
which are required for services like Let's Encrypt certificate verification.
Here's how to modify your Nginx configuration to block all hidden files except the .well-known
directory:
# Block all hidden files except .well-known
location ~ /\\.(?!well-known).* {
deny all;
access_log off;
log_not_found off;
}
For more precise control, you can use exact matching for the .well-known directory while maintaining the general hidden files block:
location /\.well-known/ {
allow all;
}
location ~ /\\. {
deny all;
access_log off;
log_not_found off;
}
Here's a complete server block example showing the proper implementation:
server {
listen 80;
server_name example.com;
root /var/www/html;
# Allow access to .well-known for Let's Encrypt
location ^~ /.well-known/ {
allow all;
}
# Block all other hidden files
location ~ /\\. {
deny all;
access_log off;
log_not_found off;
}
# Your other configurations...
}
After making changes, always test your configuration:
sudo nginx -t
sudo systemctl reload nginx
Then verify access to both protected and allowed paths:
curl -I http://example.com/.well-known/acme-challenge/test
curl -I http://example.com/.htaccess
When implementing these rules:
- The
^~
modifier ensures this location takes precedence over regex matches - Consider adding specific permissions to the
.well-known
directory at filesystem level too - Regularly monitor access logs for any suspicious attempts to access hidden files
Many Nginx administrators block access to hidden files (starting with a dot) for security reasons. A common approach is:
location ~ /\\. {
deny all;
access_log off;
log_not_found off;
}
This works well until you need to use services like Let's Encrypt that require access to the .well-known
directory for ACME challenges.
We need to modify our configuration to make an exception for .well-known
while maintaining security for other hidden files. Here's how:
# Block all hidden files except .well-known
location ~* /\\.(?!well-known).* {
deny all;
access_log off;
log_not_found off;
}
# Explicitly allow .well-known
location ~* ^/\\.well-known {
allow all;
try_files $uri $uri/ =404;
}
For those who prefer a single location block, this regex-based solution works too:
location ~ /\\.(?!well-known) {
deny all;
access_log off;
log_not_found off;
}
After making changes, always test:
nginx -t
systemctl reload nginx
Then verify both scenarios:
- Access to
/.well-known/acme-challenge/test
should return 404 (not 403) - Access to
/.htaccess
should return 403
The regex approach has minimal performance impact. However, if you have very high traffic, consider this optimized version:
location = /.well-known {
allow all;
try_files $uri $uri/ =404;
}
location ~ /\\. {
deny all;
access_log off;
log_not_found off;
}