NGINX filter requests to lan IP - django

I have received several requests via NGINX that appear to be to my LAN IP 192.168.0.1 as follows:
nginx.vhost.access.log:
192.227.134.73 - - [29/Jul/2021:10:33:47 +0000] "POST /GponForm/diag_Form?style/ HTTP/1.1" 400 154 "-" "curl/7.3.2"
and from Django:
Invalid HTTP_HOST header: '192.168.0.1:443'. You may need to add '192.168.0.1' to ALLOWED_HOSTS.
My NGINX configurations as follows:
upstream django_server {
server 127.0.0.1:8000;
}
# Catch all requests with an invalid HOST header
server {
server_name "";
listen 80;
return 301 https://backoffice.example.com$request_uri;
}
server {
listen 80;
# Redirect www to https
server_name www.backoffice.example.com;
modsecurity on;
modsecurity_rules_file /some_directory/nginx/modsec/modsec_includes.conf;
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains;" always;
add_header X-Frame-Options "deny" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
#add_header Content-Security-Policy "script-src 'self' https://example.com https://backoffice.example.com https://fonts.gstatic.com https://code.jquery.com";
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
return 301 https://backoffice.example.com$request_uri;
}
server {
listen 443 ssl http2;
server_name www.backoffice.example.com backoffice.example.com;
modsecurity on;
modsecurity_rules_file /some_directory/nginx/modsec/modsec_includes.conf;
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains;" always;
add_header X-Frame-Options "deny" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
#add_header Content-Security-Policy "script-src 'self' https://example.com https://backoffice.example.com https://fonts.gstatic.com https://code.jquery.com";
add_header Referrer-Policy "strict-origin-when-cross-origin";
ssl_certificate /etc/ssl/nginx-ssl/backofficebundle.crt;
ssl_certificate_key /etc/ssl/nginx-ssl/backoffice.key;
access_log /some_directory/nginx/nginx.vhost.access.log;
error_log /some_directory/nginx/nginx.vhost.error.log;
location / {
proxy_pass http://localhost:8000;
proxy_pass_header Server;
proxy_redirect off;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_set_header REMOTE_ADDR $remote_addr;
}
location /media/ {
alias /some_directory/backoffice/media/;
}
location /static/ {
alias /some_directory/backoffice/static/;
}
}
My questions:
Is there any way of configuring NGINX to block requests to all LAN IP's?
Can this be done better by ModSecurity?

Is there any way of configuring NGINX to block requests to all LAN IP's?
There is, just make nginx listen only on the public IP (e.g. listen backoffice.example.com:443 ssl http2;). Although I have no idea why you'd want this…
Because if it's an internal IP it cannot be accessed externally (by definition – otherwise you wouldn't call it internal). If that would be the case you'd have more like a problem with your network/firewall.
Regarding the nginx access log, I cannot spot any problem. 192.227.134.73 is not a private IP.
Regarding the Django log, curl -H "Host: 192.168.0.1:443" https://backoffice.example.com would have caused such a request. The "Host" header is just a header after all that can contain anything.

Related

nginx not loading my project from other server

I have three servers 10.77.12.54,10.77.12.55,10.77.12.56 my application on 54, Postgres on 55, and Nginx on 56 servers I created gunicorn.shock file and gunicorn.server file and I added app IP to Nginx config file and also create sites-available, sites-enabled but Nginx not fetching my application is there anything I have to do?
server {
listen 80;
server_name 10.77.12.54;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options nosniff always;
add_header X-XSS-Protection "1; mode=block" always;
proxy_cookie_path / "/; Secure";
access_log /var/log/nginx/access_rkvy.log main buffer=32k;
location / {
access_log /var/log/nginx/app54log.log main;
proxy_pass http://loadblncer;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
proxy_buffering off;
proxy_buffer_size 128k;
proxy_buffers 100 128k;
proxy_set_header X-Forwarded-For $http_x_forwarded_for;
}

Insecure Login Blocked

I am working on a site (which the name is https://tutumluannev2test.derinpos.com/). I've been trying to add facebook login. At localhost no problem but at staging, I always get this error message:
Insecure Login Blocked: You can’t get an access token or log in to this app from an insecure page. Try reloading the page as https://
it's a ASP.NET Core 2.1 project.
served by nginx from ubuntu 16.04
Valid OAuth Redirect URIs: https://tutumluannev2test.derinpos.com/signin-facebook
https://www.facebook.com/v2.12/dialog/oauth?client_id=201510504064809&scope=public_profile%2Cemail&response_type=code&redirect_uri=http%3A%2F%2Ftutumluannev2test.derinpos.com%2Fsignin-facebook&state=...
nginx.conf:
server {
listen 80
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name tutumluannev2test.derinpos.com;
location / {
proxy_set_header X-Forwarded-SSL on;
proxy_set_header X-Forwarded-Protocol $scheme;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $host;
proxy_pass http://localhost:5003;
proxy_http_version 1.1;
}
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
ssl_certificate /etc/letsencrypt/live/tutumluannev2test.derinpos.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/tutumluannev2test.derinpos.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
}
Can anybody help me?
Thanks in advance

How do i configure the django rest framework pagination url

when I get an object in django rest framework the urls always come absolute with localhost, but in production im going through a proxy on nginx, is there a way to set this url in the settings
Example
count: 11
next: "http://localhost:8000/api/accounts/?ordering=-date_registered&page=2"
previous: null
I need it to be
count: 11
next: "http:/example.com/api/accounts/?ordering=-date_registered&page=2"
previous: null
---------- edit --------------------------
please see my complete nginx config
server {
listen 80;
server_name 123.123.123.123;
root /home/admin/www/site-web/dist;
index index.html;
charset utf-8;
location /static/ {
alias /home/admin/www/site/static/;
}
location /media/ {
alias /home/admin/www/site/media/;
}
location /nginx_status/ {
# Turn on nginx stats
stub_status on;
# I do not need logs for stats
access_log off;
# Security: Only allow access from 192.168.1.100 IP #
# allow 192.168.1.100;
# Send rest of the world to /dev/null #
# deny all;
}
location / {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
try_files $uri $uri/ /index.html;
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
#
# Om nom nom cookies
#
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
#
# Custom headers and headers various browsers *should* be OK with but aren't
#
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
#
# Tell client that this pre-flight info is valid for 20 days
#
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' 0;
return 204;
}
if ($request_method = 'POST') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
}
if ($request_method = 'GET') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
}
}
location /docs/ {
proxy_pass http://127.0.0.1:8000/docs/;
break;
}
location /api/ {
underscores_in_headers on;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://127.0.0.1:8000/api/;
break;
}
location /admin/ {
proxy_pass http://127.0.0.1:8000/admin/;
break;
}
}
==== super edit====
Sorry guys, i had 'underscores_in_headers on;' i removed it and all is working
================
It sounds like your Host header is not being set properly, which would be an issue in your nginx configuration. The issue is that your Host header that is being sent includes the port number, so Django is including the port number when building out urls. This will cause future issues with CSRF, because CSRF checks do strict port checking when you are not debugging.
This is known to cause issues with SSL for similar reasons.
You can fix this by setting the Host header within Nginx to not include the proxied port.
proxy_set_header Host $http_host;
Note that I used the $http_host variable instead of $host or $host:$server_port. This will ensure that Django will still respect CSRF requests on non-standard ports, while still giving you the correct absolute urls.
Set USE_X_FORWARDED_HOST in your settings to True and make sure you pass it along using your web server(proxy) as well.
When django does build_absolute_uri() it calls get_host() - see below in django.http.request:
def get_host(self):
"""Returns the HTTP host using the environment or request headers."""
# We try three options, in order of decreasing preference.
if settings.USE_X_FORWARDED_HOST and (
'HTTP_X_FORWARDED_HOST' in self.META):
host = self.META['HTTP_X_FORWARDED_HOST']
...
See Real life usage of the X-Forwarded-Host header?

Access-Control-Allow-Origin is not allowed by Access-Control-Allow-Headers

I have two separate server,one is nginx with node,and another one is django with django-rest-framework for build ding REST API,nginx is responsible for the REST API request,node takes care of client request, also i use polymer for the frontend .Below are a brief description:
machine one:
nginx:192.168.239.149:8888 (API listening address) forward to 192.168.239.147:8080
node:192.168.239.149:80 (client listening address)
machine two:
unicorn:192.168.239.147:8080(listening address)
The process is when a request comes in,node server(192.168.239.149:80) responses to return html,in html an AJAX request ask for API server(nginx:192.168.239.149:8888 forward to unicorn:192.168.239.147:8080),and then unicorn(192.168.239.147:8080) returns the result.
but there is a CORS problem,I read a lot article,and many people met the same questions,I tried many methods,but no help.still error.
what i get is :
that is:
XMLHttpRequest cannot load http://192.168.239.149:8888/article/. Request header field Access-Control-Allow-Origin is not allowed by Access-Control-Allow-Headers.
What i do is :
core-ajax
<core-ajax auto headers='{"Access-Control-Allow-Origin":"*","X-Requested-With": "XMLHttpRequest"}' url="http://192.168.239.149:8888/article/" handleAs="json" response="{{response}}"></core-ajax>
nginx:
http {
include mime.types;
default_type application/octet-stream;
access_log /tmp/nginx.access.log;
sendfile on;
upstream realservers{
#server 192.168.239.140:8080;
#server 192.168.239.138:8000;
server 192.168.239.147:8080;
}
server {
listen 8888 default;
server_name example.com;
client_max_body_size 4G;
keepalive_timeout 5;
location / {
add_header Access-Control-Allow-Origin *;
try_files $uri $uri/index.html $uri.html #proxy_to_app;
}
location #proxy_to_app{
add_header Access-Control-Allow-Origin *;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
#proxy_set_header X-Real-IP $remote_addr;
proxy_redirect off;
proxy_pass http://realservers;
}
}
}
node:
app.listen(80, function() {
console.log('server.js running');
});
unicorn:
return Response(serializer.data,headers={'Access-Control-Allow-Origin':'*',
'Access-Control-Allow-Methods':'GET',
'Access-Control-Allow-Headers':'Access-Control-Allow-Origin, x-requested-with, content-type',
})
Because,I have not much experience on CORS,and I want to understand it thoroughly,can anyone point out what i was doing wrong here,I will thank you very much!
Wow,so excited,I sovled this all by my self,what i do wrong here is that the request header i sent is not included in the nginx config add_header 'Access-Control-Allow-Headers'
complete nginx config:
http {
include mime.types;
default_type application/octet-stream;
access_log /tmp/nginx.access.log;
sendfile on;
upstream realservers{
#server 192.168.239.140:8080;
#server 192.168.239.138:8000;
server 192.168.239.147:8080;
}
server {
listen 8888 default;
server_name example.com;
client_max_body_size 4G;
keepalive_timeout 5;
location / {
add_header Access-Control-Allow-Origin *;
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'Access-Control-Allow-Orgin,XMLHttpRequest,Accept,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Mx-ReqToken,X-Requested-With';
try_files $uri $uri/index.html $uri.html #proxy_to_app;
}
location #proxy_to_app{
add_header Access-Control-Allow-Origin *;
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'Access-Control-Allow-Orgin,XMLHttpRequest,Accept,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Mx-ReqToken,X-Requested-With';
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
#proxy_set_header X-Real-IP $remote_addr;
proxy_redirect off;
proxy_pass http://realservers;
}
}
}
because my request is :
core-ajax auto headers='{"Access-Control-Allow-Origin":"*","X-Requested-With": "XMLHttpRequest"}' url="http://192.168.239.149:8888/article/" handleAs="json" response="{{response}}"></core-ajax>
i didnt include the Access-Control-Allow-Origin and XMLHttpRequest header into the nginx config Access-Control-Allow-Headers,so that is the problem.
I hope its useful to whom has the same problem!
You do not have to include CORS header into request manualy. The browser takes care of it, you just need to allow it on the api server

Nginx fails to load CSS in a particular location

D
I want to use cache for the CSS file on my site, I've this configuration:
server {
root /webapps/sitoweb;
listen 443;
ssl on;
ssl_certificate /etc/nginx/ssl/bundle.crt;
ssl_certificate_key /etc/nginx/ssl/privateKey.key;
ssl_ciphers HIGH:!aNULL:!MD5:!DSS:!RC4;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
server_name mysite.com;
access_log of;
location /django/ {
proxy_pass http://127.0.0.1:8001;
proxy_set_header X-Forwarded-Host $server_name;
proxy_set_header X-Real-IP $remote_addr;
add_header P3P 'CP="ALL DSP COR PSAa PSDa OUR NOR ONL UNI COM NAV"';
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Headers' 'Content-Type,Accept';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE';
}
}
Now the situation is (Without using Cache):
File in www.mysite.com/homeCSS.css Found
File in www.mysite.com/django/djangoCSS.css Found
I've modify Nging adding this:
location ~* \.(css|js|gif|jpe?g|png)$ {
expires 168h;
add_header Pragma public;
add_header Cache-Control "public, must-revalidate, proxy-revalidate";
}
Now the situation is (Using Cache):
File in www.mysite.com/homeCSS.css Found
File in www.mysite.com/django/djangoCSS.css NOT Found
Why the CSS in a declared location (location "django" in this case) is NOT foud?
That location is not found, because the regular expression is preferred over standard matches. That means you turned the .css into a local request instead of a proxy request and so it will look for that CSS file in the configured root.
The solution is to repeat that block below the Django location and instead use proxy_set_header and equivalents for the expiration. But it's probably better to have the backend send the correct headers instead.