nginx: not matching the correct way - nginx

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;

Related

Nginx Fails to connect when Upstream resolves to IPv6

I have configurations in nginx that perform proxy_pass to google-analytics.com. But as you know google-analytics same times resolves to ipv4 and at times to ipv6 when it does resolve to ipv6 nginx fails with this error.
connect() to [2a00:xxx:xxx:809::xxx]:443 failed (101: Network is unreachable) while connecting to upstream. ( I just obfuscated the real ip of the upstream)
upstream server temporarily disabled while connecting to upstream
Why does nginx faile with upstream in proxy_pass resolves to ipv6?
server {
server_name upstream.nmmapper.com;
location /.well-known/acme-challenge/ {
allow all;
root /var/www/letsencrypt;
try_files $uri =404;
break;
}
}
location = /analytics.js {
proxy_set_header Accept-Encoding "";
proxy_pass https://www.google-analytics.com/analytics.js;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}
Try adding ipv6 listen [::]:80 directive:
server {
listen 80;
listen [::]:80;
server_name upstream.nmmapper.com;
...
}
For ssl:
listen 443 ssl;
listen [::]:443 ssl;
To always connect over IPv4 you need to add a resolver with ipv6=off.
However, Nginx is doing DNS resolution at startup by default.
Include (an empty) variable in the hostname to force Nginx to do resolution at runtime with the specified resolver directive.
location / {
resolver 1.1.1.1 ipv6=off valid=30s;
set $empty "";
proxy_pass https://example.com$empty;
}
Source: https://serverfault.com/a/1006465/242991.
In your case this should work:
location = /analytics.js {
resolver 1.1.1.1 ipv6=off valid=30s;
set $empty "";
proxy_set_header Accept-Encoding "";
proxy_pass https://www.google-analytics.com/analytics.js$empty;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}

How to restrict ip access in nginx

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.

how to config nginx reverse proxy

I want to access to http://serverIP:9000/projects through my domain name. I tried to write the config file like this
server {
listen 80;
server_name xxx.xxx.com;
location / {
proxy_pass http://myserverip:9000/projects;
}
}
and this
server {
listen 80;
server_name xxx.xxx.com;
client_max_body_size 90m;
client_body_timeout 20m;
location / {
proxy_pass http://myserverip:9000/projects;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
but it still cannot access to http://myserverip:9000/projects. How should I write the config file to make it right. Thanks!
You can use:
proxy_redirect http://xxx.xxx.com http://myserverip:9000/projects;
proxy_redirect off;
server_name_in_redirect off;
but make sure CSS's path is right for this.
Or :
proxy_pass http://myserverip:9000/;
then you can access : http://xxx.xxx.com/projects

nginx proxy requests for a specific path

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...

Nginx wildcard proxy, pass subdomain to the server (upstream proxy)

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/

Resources