This is my environment:
- Rails
- Axios
- Next.js
- AWS EC2
- Nginx
- Vercel
I have two domains in production environment.
One is let's say fuga.com
which is made with rails and containing some front pages.
Another one is hoge.com
which is made with next.js.
hoge.com
usually fetch data from fuga.com
using http request.
But if I access to let's say fuga.com/users_data
using browser I would see all users data.
Because api is global?
Anyway It's really bad in terms of security.
So I came up with blocking all domains aside from hoge.com
.
I configured in nginx:
server {
listen 80;
server_name fuga.com hoge.com;
root /var/www/xxx/current/public;
location / {
proxy_pass http://xxx;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
}
# ↓here↓
location /admin {
valid_referers none blocked server_names hoge\.com;
if ($invalid_referer) { return 403; }
}
}
I want to block all domains /admin/~
aside from hoge.com
.
So I used valid_referers none blocked
.
From my search, it's white list which can only access.
But I got this parameter from access log in nginx:
172.31.xx.xxx - - [10/May/2022:13:31:58 0000] "POST /admin/auth/sign_in/ HTTP/1.1" 404 188 "https://hoge.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/xxx.0.xxxx.54 Safari/xxx.36" "106.xx.xx.xxx" "-"
status code is 404
.
So I tried allow
instead of valid_referers
like:
...
location /admin {
allow 172.xx.xx.xxx;
deny all;
}
But nginx returns:
172.xx.x.xxx - - [10/May/2022:13:34:12 0000] "POST /admin/auth/sign_in/ HTTP/1.1" 403 187 "https://hoge.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/xxx.x.xxxx.54 Safari/xxx.xx" "xxx.xx.xx.xxx" "-"
I can't understand what's going on...
I'm sure It's completely problem of nginx setting.
Because if I remove allow
and valid_referers
it would work fine.
How can I fix the problem..?
CodePudding user response:
Every request ends up in a particular location and uses that location content handler. You can't do something like
location / {
... some settings ruleset
}
location /admin {
... additional settings ruleset
}
and expect that /admin/...
request would use a combined settings ruleset. Your first locations uses an http_proxy_module
content handler declared with the proxy_pass
directive (other content handlers directive examples are fastcgi_pass
, uwsgi_pass
, etc.). Since there is no any content handler declared in your second location, nginx will use a local content handler for the requests handled with that location (in other words, will try to serve a request with some local file), and since such a local file does not exists, gives you an HTTP 404 Not Found
response. You can either duplicate your main location content with your second location (not the best way) or use some other solution like map
block:
map $uri $deny {
~^/admin $invalid_referer;
# default value will be an empty string, so we can omit "default '';" here
}
server {
...
location / {
if ($deny) { return 403; }
... rest of the configuration
}
}