I want to restrict access by IP for specific php file in Nginx reverse_proxy.
so in my virtual host path /etc/nginx/sites-available/sub.mydmn.com I have the following configs:
server {
server_name wwww.sub.mydmn.com sub.mydmn.com;
root /home/mydmn/;
access_log off;
# Static contents
location ~* ^.+.(png|mp4|jpeg)$ {
expires max;
}
# Limit IP access
location = /mine.php {
allow <MyIP_Here>;
deny all;
return 404;
}
# Dynamic content, forward to Apache
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:8080;
}
}
# Deny server with IP access!
server {
listen 80 default_server;
server_name _;
location / {
return 403;
}
}
But when I start the server, Nginx blocks all IPs for mine.php.
What is the problem?
Nginx chooses a single location block to process a request (see this document). Your location = /mine.php block, not only returns a 403 status if the IP address is denied, but also returns a 404 status if the IP address is allowed. You need the request to be handled by the service on port 8080 if the IP address is allowed.
One solution is to duplicate the statements from the location / block.
For example:
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
location = /mine.php {
allow ...;
deny all;
proxy_pass http://127.0.0.1:8080;
}
location / {
proxy_pass http://127.0.0.1:8080;
}
Note that proxy_set_header statements can be moved into the outer block so that they are inherited by both blocks. See this document for details.
Related
We have a working NGINX redirecting our external users to our IIS server. The problem is that the IP seen by the IIS is the NGINX machine, not the IP from external users. Our logs are full of "10.0.0.2" IPs which is incorrect.
A similar configuration file is shown. We already included "proxy_set_header" lines.
Is this config file correct? What should be done at IIS server? Should we just include some topics at web.config file? If this is the case, what should we add?
server {
listen 10.0.0.2:443 ssl;
server_name web.mydomain.com;
ssl_certificate /home/admin/conf/web/ssl.web.mydomain.com.pem;
ssl_certificate_key /home/admin/conf/web/ssl.web.mydomain.com.key;
error_log /var/log/apache2/domains/web.mydomain.com.error.log error;
location / {
proxy_set_header x-real-IP Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Host $remote_addr;
proxy_pass https://10.0.0.11;
location ~* ^.+\.(jpeg|jpg|png|gif|bmp|ico|svg|tif|tiff|css|js|htm|html|ttf|otf)$ {
root /home/admin/web/web.mydomain.com/public_html;
access_log /var/log/apache2/domains/web.mydomain.com.log combined;
access_log /var/log/apache2/domains/web.mydomain.com.bytes bytes;
expires max;
try_files $uri #fallback;
}
}
location /error/ {
alias /home/admin/web/web.mydomain.com/document_errors/;
}
location #fallback {
proxy_pass https://10.0.0.11;
}
location ~ /\.ht {return 404;}
location ~ /\.svn/ {return 404;}
location ~ /\.git/ {return 404;}
location ~ /\.hg/ {return 404;}
location ~ /\.bzr/ {return 404;}
include /home/admin/conf/web/snginx.web.mydomain.com.conf*;
}
You can use IIS enhanced logging to write custom headers like X-Forwarded-For to log files,
https://learn.microsoft.com/en-us/iis/configuration/system.applicationhost/sites/site/logfile/customfields/add
There is no way to change the source IP field, because indeed that's IP address recorded in the TCP/HTTP packets.
At first I though this would be something related to IIS/NGINX, but after #lex-li and #bruce-zhang repplies I researched more about it.
I actually did not know but inside our application (running at IIS) there are listeners to those headers, and those listeners were not properly implemented.
So it was just a misalignment between our application and NGINX.
Thanks both #lex-li and #bruce-zhang
i have the following nginx configuration
GIVES WRONG RESULTS
upstream webapp {
server webapp:8000;
}
upstream db {
server phppgadmin:80;
}
server {
listen 80;
server_name db.*;
location / {
proxy_pass http://db;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
}
}
server {
listen 80;
location / {
proxy_pass http://webapp;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
}
location /static {
autoindex on;
alias /staticfiles/;
}
location /media {
autoindex on;
alias /mediafiles/;
}
}
My ip address of the pc is xx.xx.xx.xx
what I observed is that
db.xx.xx.xx.xx - shows the db upstream
and also xx.xx.xx.xx - shows the db upstream
GIVES CORRECT RESULTS
where as when i change the order it shows properly
upstream webapp {
server webapp:8000;
}
upstream db {
server phppgadmin:80;
}
server {
listen 80;
location / {
proxy_pass http://webapp;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
}
location /static {
autoindex on;
alias /staticfiles/;
}
location /media {
autoindex on;
alias /mediafiles/;
}
}
server {
listen 80;
server_name db.*;
location / {
proxy_pass http://db;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
}
}
Now
db.xx.xx.xx.xx - shows the db upstream
and xx.xx.xx.xx - shows the webapp upstream
QUESTION
I am not able to understand in the first case how come xx.xx.xx.xx is matched by server_name db.*; Or why the second one shows the intended behaviour
note
Ofcourse in my /etc/hosts i have setup
xx.xx.xx.xx app.xx.xx.xx.xx
xx.xx.xx.xx db.xx.xx.xx.xx
Nginx selects server block by port (with IP, if given) and Host header. If there is no match, it uses a block where default_server is set. In your case there is no match by Host and neither there is a default_server so I think it just picked first. Either add server_name to the block with the webapp upstream or make it a default one:
listen 80 default_server;
I have two websites, ineedbabypics.com and ineedtoclose.com
I have updated both domain names A record to point to my public IP address.
The problem is I followed various online settings for proxy and can't get the simple redirect to work. When I type in both domain names in my browser, it both goes to ineedbabypics.com.
I want ineedbabypics.com to go to 192.168.1.96 and ineedtoclose.com to go to 192.168.1.83. Here are my server block settings:
#nginx.conf
server {
listen 80;
listen [::]:80;
server_name _;
root /usr/share/nginx/html;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location / {
}
#ineedbabypics.conf
server {
server_name http://ineedbabypics.com www.ineedbabypics.com;
set $upstream 192.168.1.96;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://$upstream;
}
}
#ineedtoclose.conf
server {
server_name http://ineedtoclose.com www.ineedtoclose.com;
set $upstream 192.168.1.83;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://$upstream;
}
}
Is it possible to pass requests for a specific path to a different upstream server?
Here is my nginx site configuration:
upstream example.org {
server 127.0.0.1:8070;
keepalive 8;
}
server {
listen 0.0.0.0:80;
server_name example.org www.example.org;
access_log /var/log/nginx/example.org.log;
location / {
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-NginX-Proxy true;
proxy_pass http://example.org;
proxy_redirect off;
}
}
Currently, requests to this site are redirected to a Node.js instance running on port 8070.
I would like requests to this site that have a path starting with /services to be redirected to another Node.js instance running on port 8080.
Is this possible? And of course -- how so?
Yes, just add another location block:
upstream example.org {
server 127.0.0.1:8070;
keepalive 8;
}
upstream other.example.org {
server 127.0.0.1:8080;
keepalive 8;
}
server {
listen 0.0.0.0:80;
server_name example.org www.example.org;
access_log /var/log/nginx/example.org.log;
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-NginX-Proxy true;
proxy_redirect off;
location / {
proxy_pass http://example.org;
}
location /services {
proxy_pass http://other.example.org;
}
}
Note: I extracted all shared proxy directives into the server block so that they are not repeated in each location block. If they would differ between different locations, you would have to move them again into the location blocks...
I would like to be able to pass subdomain.domain.com to .domain.com apache server, with subdomain info too.
I would like to make a nginx cache for domain, acting like wildcard, but passing subdomain to the destination (there is apache witch wildcard too). Up to now, I pass the info via proxy_set_header Host $host; but I would like to have request with subdomain at the apache server.
upstream domain.com {
server 172.1.1.1:80 weight=50 fail_timeout=30s;
}
server {
server_name *.domain.com;
location / {
proxy_pass http://domain.com;
#proxy_pass $request;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
}
location ~* ^.+. (jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js|swf)$ {
proxy_pass http://topmanagergame.com;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_cache my-cache;
proxy_cache_valid 200 302 30m;
proxy_cache_valid 404 1m;
}
access_log /var/log/nginx/domain.com.log main;
error_log off;
}
Do you think I can use proxy_pass with upstream ?
Nginx (*wildcard_domain.com) --(cache)--> Apache (*wildcard_domain.com)
Nginx (anything.domain.com) --(cache)--> Apache (anything.domain.com)
upstream somestring {
server domain2.com:80 weight=50 fail_timeout=30s;
}
server {
listen 80;
server_name *.domain.com;
server_name ~^(?<subdomain>.+)\.domain\.com$;
location / {
proxy_pass http://somestring;
proxy_set_header Host $subdomain.domain2.com;
}
}
So I was trying to find the answer to this problem and kept finding this post. But I think dmytrivv answer is out of date. In our scenario, we have both wildcard domains (e.g. *.mydomain.com) and custom domains (e.g. fullycustomdomain.com). But you can solve both by using proxy_set_header Host $host; and having default at the end of your listen.
upstream qaweb {
# Servers in the web farm
server ip-notreal-name.ec2.internal:80;
}
server {
listen 443 ssl default;
ssl_certificate certs/mydomain.com.crt;
ssl_certificate_key certs/mydomain.com.key;
# Support for wildcard domains
server_name admin.mydomain.com *.mydomain.com "";
location / {
# Turn off access logging so we don't fill the hardrive
access_log off;
proxy_pass http://qaweb;
proxy_set_header Host $host;
# So that the correct IP shows up in the log once libapache2-mod-rpaf is installed
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
Note, we are also using it as a TLS termination proxy.
You can also find more examples on how to use proxy_pass here https://www.liaohuqiu.net/posts/nginx-proxy-pass/