Nginx block access to url
I am using concrete5 and I need to disable /login url on my website. Nginx is my server.
I tried so far to allow access only to specified ips:
location /login {
allow 5.69.34.213;
allow 5.80.29.130;
deny all;
}
But it did not work. It blocks all ips and the specified too. What am I doing wrong?
Update My conf file is:
server {
listen 80;
server_name my_website.com;
return 301 https://my_website.com$request_uri;
}
#HTTPS server
server {
listen 443 ssl;
server_name my_website.com;
root /var/www-staging/my_website/public_html;
gzip on;
gzip_proxied any;
gzip_types text/plain text/html text/css application/json application/javascript application/x-javascript text/javascript text;
ssl on;
ssl_certificate /etc/letsencrypt/live/my_website.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/my_website.com/privkey.pem;
ssl_session_timeout 5m;
add_header Strict-Transport-Security "max-age=31536000";
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA";
ssl_prefer_server_ciphers on;
# mkdir /etc/nginx/ssl
# openssl dhparam -out /etc/nginx/ssl/dhparam.pem 2048
ssl_dhparam /etc/nginx/ssl/dhparam.pem;
location /templates {
alias /var/www-staging/my_website/templates/dist;
}
location / {
try_files $uri /index.php$request_uri;
}
location ~ \.php($|/) {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param QUERY_STRING $query_string;
fastcgi_intercept_errors on;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
include fastcgi_params;
}
location /login {
allow 5.80.29.130;
deny all;
}
error_log /var/log/nginx/my_website_error.log;
access_log /var/log/nginx/my_website_access.log;
}
Solution 1:
nginx documentation explains your case: http://nginx.org/en/docs/http/request_processing.html#simple_php_site_configuration
nginx first searches for the most specific prefix location given by literal strings regardless of the listed order. In the configuration above the only prefix location is “/” and since it matches any request it will be used as a last resort. Then nginx checks locations given by regular expression in the order listed in the configuration file. The first matching expression stops the search and nginx will use this location. If no regular expression matches a request, then nginx uses the most specific prefix location found earlier.
so following this statement /login
only matches if there is no regex that matches. If you access /login/login.php
for example, your location ~ \.php($|/)
wins the election on who gets to handle this request.
SOLUTION 1
To fix your problem set this location ABOVE the php location
location ~* /login {
allow 5.80.29.130;
deny all;
}
SOLUTION 2
use
location ^~ /login {
allow 5.80.29.130;
deny all;
}
http://nginx.org/en/docs/http/ngx_http_core_module.html#location explains that ^~
disables regex matching if this prefix string location matches.