When working with Nginx, many developers struggle with properly mapping URL paths to different filesystem locations while maintaining security. The common pain point involves hiding actual directory structures from public access while providing clean, alternative URLs.
The fundamental misunderstanding often stems from how Nginx processes paths:
# Incorrect approach (common mistake)
location /mail2admin {
alias /vimbadmin/public; # This won't work as expected
}
The key difference between root
and alias
:
root
appends the location path to the root pathalias
replaces the location path with the alias path
Here's the proper way to implement your security requirement:
server {
listen 80;
server_name myserver.com;
root /var/www;
# Block direct access to /vimbadmin
location /vimbadmin {
return 403;
}
# Proper alias configuration
location /mail2admin {
alias /var/www/vimbadmin/public;
try_files $uri $uri/ /index.php?$args;
# PHP handling within the aliased location
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_pass unix:/var/run/php5-fpm.sock;
}
}
}
When implementing path aliasing:
- Always use absolute paths in alias directives
- Restrict access to original paths (like the 403 return above)
- Ensure proper permissions on both original and aliased directories
After making changes:
sudo nginx -t # Test configuration
sudo systemctl reload nginx # Apply changes
Verify both the positive and negative cases:
http://myserver.com/mail2admin
should workhttp://myserver.com/vimbadmin
should return 403
For more complex scenarios, you can use regex locations:
location ~ ^/hiddenpath/(.*)$ {
alias /var/www/secret/$1;
}
When setting up web applications, we often need to serve content from non-standard locations while maintaining clean and secure URLs. A common scenario involves wanting to expose content from /var/www/vimbadmin/public
through a different URL path like /mail2admin
for security reasons.
The key to solving this lies in understanding how Nginx processes requests:
# root vs alias example:
location /images/ {
root /data/; # Nginx will look for /data/images/file.jpg
}
location /img/ {
alias /data/images/; # Nginx will look for /data/images/file.jpg
}
Here's the proper way to implement the requested functionality:
server {
listen 80;
server_name myserver.com;
root /var/www;
index index.php;
access_log /var/log/nginx/vimbadmin.access.log;
error_log /var/log/nginx/vimbadmin.error.log;
location /mail2admin {
alias /var/www/vimbadmin/public;
try_files $uri $uri/ /index.php?$args;
# PHP processing for this location
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_pass unix:/var/run/php5-fpm.sock;
}
}
# Block direct access to vimbadmin path
location /vimbadmin {
return 403;
}
}
- The
alias
directive must specify the full absolute path - For PHP processing,
SCRIPT_FILENAME
should use$request_filename
with aliases - Always include trailing slashes in directory paths for consistency
Consider adding these additional security measures:
# Deny access to hidden files
location ~ /\. {
deny all;
}
# Restrict access to sensitive directories
location ~* ^/(config|logs|temp)/ {
deny all;
}
After making changes, always test your configuration:
sudo nginx -t
sudo systemctl reload nginx
If you encounter 403 errors:
- Verify directory permissions (
chmod 755
on directories) - Check ownership (
chown www-data:www-data
for PHP files) - Ensure SELinux contexts are correct if applicable