nginx deny not working with return - nginx

I am trying to deny all access on a certain server block.
server {
listen 8080;
server_name myserver;
root /srv/nkosl;
deny all;
location /mydistro {
return 302 https://www.ubuntu.com/;
}
location /files {
autoindex on;
}
}
This denies access on files location (and successfully returns 403 forbidden message).
However I can still access myserver:8080/mydistro and it redirects me to ubuntu page.
How can I deny the /mydistro location as well?

this answer describes why allow/deny does not work with return/rewrite.
one way to work around it is indeed using ifs, however ifs can be tricky in nginx in certain cases and allow/deny can also take a network mask...

Try to completely remove the /mydistro location. Or, at least, comment the line return 302 https://www.ubuntu.com/;.
To redirect selectively, try this:
location /mydistro {
if ($remote_addr != 127.0.0.1) {
rewrite ^ https://www.ubuntu.com;
}
}

Related

Capture variable nginx if statement

I am working on a site i have since long time and i would kike to redirect old useless pages to a category page listing relevant articles.
I have seen n my google search console the following url :
https://www.example.com/Greece/sport%20?page=55
I would like to get :
https://www.example.com/greece.html?page=55
I am using nginx with a custom script that imposes in the server setting to indicate for which domain the redirection has to be done.
I am trying to figure out the way to do it and the following code is not giving me the right redirection.
I would appreciate if anybody could give me a hint.
location ^~ /(.*)/ {
if ($host ~* ^(www\.)?(mysite\.com)$) {
return 301 $scheme://$host/$1.html;
}
return 404;
}
Thanks
Try this config:
server {
...
server_name mysite.com www.mysite.com;
location ~* ^(/[^/]+)/ {
return 301 $scheme://$host$1.html$is_args$args;
}
....
}
The regular expression in location block you can modify as you need.

How to drop path in rewrite and proxy pass the args in nginx

Example request - http://localhost/iframe?ip=192.168.0.237
I want to proxy pass the request to the value of IP and remove the path and args after localhost/ .
Ideally the proxy_pass should point to 192.168.0.237 and the URL should be http://localhost/.
localhost /iframe {
rewrite ^/(iframe/.*)$ http://localhost/ permanent;
proxy_pass $arg_ip;
}
I'm not sure whether rewrite is the proper way to address this problem.
I would use the argument ip and a rewrite to remove the iframe location
server {
listen 8085;
location /iframe {
rewrite ^/iframe(.*)$ /$1 break;
proxy_pass http://$arg_ip;
}
}
server {
listen 8080;
location / { return 200 "$host$uri"; }
}
Security Notice
I just have a feeling you should whilelist the upstream servers accepted as arguments. If not this will be a wildcard proxy to every single http-server reachable in the network. This is a easy to use SSRF attack vector. So please add some extra layer of security.
SSRF Explained:
Let's say we use this configuration without any further security. Given the folowing NGINX config:
server {
listen 8085;
location /iframe {
rewrite ^/iframe(.*)$ /$1 break;
proxy_pass http://$arg_ip;
}
}
# Server for iframe service
server {
listen 8080;
root /usr/share/nginx/;
location / { return 200 "$host$uri\n"; }
}
# Private Server Section here!
server {
listen 8086;
allow 127.0.0.1;
deny all;
.....
location / {
index welcome.html;
}
}
Trying to reach the secret server directly
curl -v EXTERNALIP:8086
will fail with HTTP 403.
The NGINX will just allow connections form localhost/127.0.0.1 as defined in the allow/deny directives.
But lets try the iframe with the ip argument.
$# curl localhost:8085/iframe?ip=127.0.0.1:8086
Welcome to our very secure server! Internals only!
It prints the content of the secret server. Whitlisting a proxy-pass like this is never a good idea regardless its working or not.

Extension realurl - display of SQL query parts in URL

First of all, I have to deal with a project-related upgrade of a TYPO3 version and am also relatively new to the Nginx web server.
I have upgraded a TYPO3 installation from version 7.6-LTS to 8.7-LTS and transferred the site from an IIS (Windows) server to an Ubuntu 18.04 system with Nginx.
I have now discovered the following: the first click on an internal link on the website in the menu e.g. domain.com/prices works correctly. The URL domain.com/prices is called and also shown in the URL. Now when the page has been reloaded, the same menu item link now looks like this...
domain.com/index.php?id=8&L=1%20or%20%281%2C2%29%3D%28select%2Afrom%28select%20name_const%28CHAR%28111%2C108%2C111%2C108%2C111%2C115%2C104%2C101%2C114%29%2C1%29%2Cname_const%28CHAR%28111%2C108%2C111%2C108%2C111%2C108%2C111%2C115%2C104%2C101%2C114%29%2C1%29%29a%29%20- -%20and%201%3D1
...instead of the usual domain.com/prices. The oontent of the page is still correctly, so the correct page is being loaded.
The Typo3 installation uses the extension real url, which is exactly for this feature. It translates domain.com/index.php?id=8&L=1... into a speaking url like domain.com/prices. So why is it working on the first load, but then no longer?
I also thought, it could be an issue with the configuration of Nginx, but now I think it is a different topic here, because if it is a webserver issue, it won't work the first time, will it?
What can cause this behaviour?
Update
I actually saw, that the English version of the website is working well. So here, the links are displayed correctly: domain.com/prices, domain.com/modules and not even not first page load.
Maybe it is helpful. This is the Nginx config, I currently use:
server {
listen 80;
server_name domain.com;
root /var/www/domain.com/public;
index index.php index.html index.htm index.nginx-debian.html;
listen 443 ssl;
ssl_certificate /var/www/domain.com/ssl/domain.com-2020.crt;
ssl_certificate_key /var/www/domain.com/ssl/domain.com-2020.rsa;
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
# Special root site case. prevent "try_files $uri/" + "index" from skipping the cache
# by accessing /index.php directly
location =/ {
recursive_error_pages on;
error_page 405 = #sfc;
return 405;
}
location #t3frontend {
# Using try_files for ease of configuration demonstration here,
# you can also fastcgi_pass directly to php here
try_files $uri /index.php$is_args$args;
}
location #sfc {
# Perform an internal redirect to TYPO3 if any of the required
# conditions for StaticFileCache don't match
error_page 405 = #t3frontend;
# Query String needs to be empty
if ($args != '') {
return 405;
}
# We can't serve static files for logged-in BE/FE users
if ($cookie_staticfilecache = 'fe_typo_user_logged_in') {
return 405;
}
if ($cookie_be_typo_user != '') {
return 405;
}
# Ensure we redirect to TYPO3 for non GET/HEAD requests
if ($request_method !~ ^(GET|HEAD)$ ) {
return 405;
}
charset utf-8;
try_files /typo3temp/tx_staticfilecache/${scheme}/${host}/${server_port}${uri}/index.html
/typo3temp/tx_staticfilecache/${scheme}/${host}/${server_port}${uri}
=405;
}
location /typo3temp/tx_staticfilecache {
deny all;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
}
location ~ /\.ht {
deny all;
}
# Prevent clients from accessing hidden files (starting with a dot)
# This is particularly important if you store .htpasswd files in the site hierarchy
# Access to `/.well-known/` is allowed.
# https://www.mnot.net/blog/2010/04/07/well-known
# https://tools.ietf.org/html/rfc5785
location ~* /\.(?!well-known\/) {
deny all;
}
# Prevent clients from accessing to backup/config/source files
location ~* (?:\.(?:bak|conf|dist|fla|in[ci]|log|psd|sh|sql|sw[op])|~)$ {
deny all;
}
# TYPO3 - Block access to composer files
location ~* composer\.(?:json|lock) {
deny all;
}
# TYPO3 - Block access to flexform files
location ~* flexform[^.]*\.xml {
deny all;
}
# TYPO3 - Block access to language files
location ~* locallang[^.]*\.(?:xml|xlf)$ {
deny all;
}
# TYPO3 - Block access to static typoscript files
location ~* ext_conf_template\.txt|ext_typoscript_constants\.(?:txt|typoscript)|ext_typoscript_setup\.(?:txt|typoscript) {
deny all;
}
# TYPO3 - Block access to miscellaneous protected files
location ~* /.*\.(?:bak|co?nf|cfg|ya?ml|ts|typoscript|dist|fla|in[ci]|log|sh|sql)$ {
deny all;
}
# TYPO3 - Block access to recycler and temporary directories
location ~ _(?:recycler|temp)_/ {
deny all;
}
# TYPO3 - Block access to configuration files stored in fileadmin
location ~ fileadmin/(?:templates)/.*\.(?:txt|ts|typoscript)$ {
deny all;
}
# TYPO3 - Block access to libaries, source and temporary compiled data
location ~ ^(?:vendor|typo3_src|typo3temp/var) {
deny all;
}
# TYPO3 - Block access to protected extension directories
location ~ (?:typo3conf/ext|typo3/sysext|typo3/ext)/[^/]+/(?:Configuration|Resources/Private|Tests?|Documentation|docs?)/ {
deny all;
}
}
server {
if ($host = domain.com) {
return 301 https://$host$request_uri;
}
listen 80;
server_name domain.com;
return 404;
}
And this is the config of realurl:
The template analysis does not show any error. This is the template analysis for realurl:
Update 2
I'm a step further in this issue. I've read the bug report https://github.com/dmitryd/typo3-realurl/issues/333 which is similar to my issue. I tried to switch the config.linkVars value from L to L(0,1). That helped in the URL issue. But now it switches always back to German language.
With the setting L in config.linkVars, it added the language in the url, if it was not German:
domain.com/en/prices
With the new value L(0,1) it removes the language in the URL
domain.com/prices
So it always shows the German version of the page. I even tried to set the value to L(0,2), because of German, English and French language is integrated (1=English, 2=French), but it does not help in this case. It switches always back to German because of the missing language code in the URL.
Ok. Now I found the solution.
As I wrote in the comments it was the config setting:
config.linkVars
which was set initially to
config.linkVars = L
After I found this bug report
https://github.com/dmitryd/typo3-realurl/issues/333
I saw that I need to limit the L-value for security reasons.
In our case 0 for german, 1 for english, 2 for french:
config.linkVars = L(0-2)
Then all worked fine.

nginx if specific subdomain endpoint

I'd like to put robots.txt for the subdomain dev. to point to a specific robots.txt static file.
What routing rule do I need?
This is what i'm thinking:
if ($host = "dev.example.com") {
location ^~ /robots.txt {
allow all;
root /static/disallow/robots.txt;
}
}
Based on Nginx subdomain configuration I believe I may need to just make separate server blocks and use include's. If not a simple routing rule, is the includes method how this is typically done?
If you are wanting a specific robots.txt for each subdomain, you can do so with separate server blocks like this, which you allude (and link) to in your question:
server {
server_name subdomainA.domain.com;
include /common/config/path;
location = /robots.txt {
root /subdomainA/path;
}
}
server {
server_name subdomainB.domain.com;
include /common/config/path;
location = /robots.txt {
root /subdomainB/path;
}
}
Regarding your other approach, have you read If is Evil?

Block folder in nginx and ALL contents inside, throw 404 EXCEPT for localhost. Browser is requesting script download

Here is my code:
# I had to do this one because going .com/restricted was throwing 403, not 404.
location /restricted {
return 404;
}
#This seemed to work except I don't want localhost to have 404, I want it to access correctly
location ~ /restricted/(.+)\.php$ {
deny all;
return 404;
allow 127.0.0.1;
}
So, basically:
Get 404 everytime NON-localhost tries to access restricted OR its contents (e.g. /restricted/should_be_restricted_script.php)
Whenever I try to access the folder, the browser asks me if I want to download the script... When I saved and opened it, it was should_be_restricted_script.php indeed, and I can't figure out why...
Can someone help me? tyvm
try this
location ~ /restricted/(.+)\.php$ {
deny all;
return 404;
allow 127.0.0.1;
}
location ~ ^/restricted {
return 404;
}
I think that your problem is related about how nginx chooses the "best" location, he gives priority to non regexp location.
Look at this article
I think you should replace deny and allow rows, because the first match will apply:
location ~ /restricted/(.+)\.php$ {
allow 127.0.0.1;
deny all;
}

Resources