Nginx preserve $request_uri - nginx

I'm not sure if the behavior I want is actually possible natively with nginx but here goes.
I have a server running on port 81 with the following nginx config:
CONFIGURATION OF SERVER1 NGINX
server {
listen 81;
server_name SERVER_DNS_NAME;
location /server1 {
proxy_pass http://127.0.0.1:8084/;
proxy_set_header Host $host;
}
location / {
proxy_pass http://127.0.0.1:8084;
proxy_set_header Host $host:$server_port;
}
}
I have another server running on port 82 with similar configuration. Now what'd i'd like to do is be able to visit them both from port 80 with just different uris.
For example: URL/server1 would take me to the first server, and URL/server2 would take me to the second.
CONFIGURATION OF NGINX LISTENING ON PORT 80
server {
listen SERVER_IP:80;
location /server1{
proxy_set_header Host $host;
http://SERVER_IP:81;
}
location /server2 {
proxy_pass http://SERVER_IP:82;
proxy_set_header Host $host;
}
This works fine when I go to URL/server1. I am successfully routed to the main page on server1. However as soon as I click any of the links present on the page on server1 I get a 404. This is because the site tries to go to URL/some_subdir_of_server1 (for which there is no mapping) rather than doing URL/server1/some_subdir_of_server1. Is this behavior doable? If so how?
Thanks!

Be careful with trailing slashes: in your example, you have
proxy_pass http://SERVER_IP:81/; which will set the proxy URL to root /

Related

nginx reverse proxy sends all traffic to first defined server

I have multiple servers running on the same host. I am trying to configure nginx to route traffic based on the server_name, but all traffic is sent to the first defined server.
I have two urls:
example.domain.net
domain.net
which I have configured nginx to proxy with configuration:
server {
listen 3978;
listen [::]:3978;
server_name example.domain.net:3978 example.domain.net:3978;
location / {
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass https://127.0.0.1:8443;
}
}
server {
listen 3978;
listen [::]:3978;
server_name domain.net:3978 www.domain.net:3978;
location / {
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass https://127.0.0.1:8020;
}
}
But all traffic to both example.domain.net:3978 and domain.net:3978 is being sent to whichever server is defined first in the file (in this case example.domain.net)
I've seen other examples where this worked like This post. Is this possible with one having a subdomain and another not?
I am using nginx version 1.18.0 with the default nginx.conf on Ubuntu 18.04
server_name should not have ports. Try removing :3978 from the server_name.
Because you have the ports, the hostname does not match any of the server_name. So, the entire traffic is sent to the first server which is considered as a default for no matches.

NGINX Proxy pass to external site that has internal redirect

i'm trying to configure an nginx proxy that hide an internal site via the proxy pass but without success.
the config i used is
location /internal1/ {
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 15;
proxy_read_timeout 180;
proxy_pass http://internal1/;
}
upstream internal1 {
server a.b.c.d:80;
}
the problem is that when i try to reach the a.b.c.d site it redirect to a login page that sould be http://a.b.c.d/login and after i login it redirect at another page http://a.b.c.d/device/config . with the proxy it redirect to http://mysite/login and http://mysite/device/config
that make the proxy do not work and show me resource not found and i couldn not see any of the pages.
If i change the proxy_pass value to http://a.b.c.d/login/ it show the login page at http://mysite/internal1 and after i login it show no resource found because it try to reach http://mysite/device/config.
someone have some suggestion on how to configure it in the proper way?
thanks for all the answer
EDIT:
sorry for the late answer but i got very busy in the meanwhile, anyway that solution work for 1 device but now all my device connected go only that device "internal" page and i cannot differentiate between more cause nginx do not support the same location in multiple config ( all device have ip/page1 )
location /page1/
{
proxy_pass mysite/internal1/page1;
proxy_redirect off;
proxy_set_header Host $host;
}
EDIT2:
unlucky it's not possible to expose all device to internet directly. the solution i found is:
create a custom DNS subdomain and then create a different nginx server block for every device with his own location and future redirect/proxy ecc...
If you want to expose the web UI of all your devices that live in the internal network to be accessible through Internet - then you will have to create a subdomain (and a corresponding virtual host config) for each device.
Suppose that the domain that points to your nginX is mydevices.net and that you have 2 devices - on 192.168.2.10 and 192.168.2.20
Then your nginX config will look like this:
server {
listen 80;
server_name dev1.mydevices.net;
location / {
proxy_pass internal1;
proxy_redirect default;
}
}
upstream internal1 {
server 192.168.2.10;
}
server {
listen 80;
server_name dev2.mydevices.net;
location / {
proxy_pass internal2;
proxy_redirect default;
}
}
upstream internal2 {
server 192.168.2.20;
}

How can I configure access from external ip to internal ip on GCP through nginx reverse proxy?

Can't connect to application through External IP.
I started gerrit code review application on GCP's vm instance(CentOS 7).
It works on http://localhost:8080 and I can't connect to it through external IP. Also I tried to create NGINX reverse proxy, but probably my configuration is wrong. By the way after installing NGINX, the starter page were shown on external ip.
# nginx configuration /etc/nginx/conf.d/default.conf
server {
listen 80;
server_name localhost;
auth_basic "Welcomme to Gerrit Code Review Site!";
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
}
}
gerrit.config
[httpd]
listenUrl = proxy-http://127.0.0.1:8080/
You use localhost as a server_name. I think that may cause conflict, because you connect to your server externally. You don't need server_name, cause you are going connect to your server by ip. And I recommend you enable logs in your nginx config. It will help you with bug fixing.
I recommend you try this config:
server {
listen 80;
access_log /var/log/nginx/gerrit_access.log;
error_log /var/log/nginx/gerrit_error.log;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
}
}
add a line in /etc/hosts
127.0.0.1 internal.domain
Update proxy config
proxy_pass http://internal.domain:8080;
It works with me

Nginx Reverse proxy config

I'm having issues with getting a simple config to work with nginx. I have a server that host docker containers so nginx is in a container. So lets call the url foo.com. I would like for the url foo.com/service1 to actually just go to foo.com on another port, so it would actually be pulling foo.com:4321 and foo.com/service2 to be pulling foo.com:5432 and so on. Here is the config I have been having issues with.
http {
server {
listen 0.0.0.0:80;
location /service1/ {
proxy_pass http://192.168.0.2:4321/;
}
location /service2/ {
proxy_pass http://192.168.0.2:5432/;
}
}
}
So the services and nginx live at 192.168.0.2. What is the prefered way to be able to do this? Thank you in advance!
As A side note, this is running in a docker container. Thanks!
I think you should check whether your foo.com is pointing to the right ip address or not first by removing the reverse proxy config. E.g.
http {
server {
listen 80;
server_name foo.com;
location / {
}
}
}
Then, if your ip address already has a service running on port 80 you should specify the server_name for each service like in my example. Nginx can only distinguish which service to respond to which domain by server_name.
*My guess is that you forgot the server_name option.
http {
server {
listen 80;
server_name foo.com;
location /service1/ {
proxy_pass http://192.168.0.2:4321/;
}
location /service2/ {
proxy_pass http://192.168.0.2:5432/;
}
}
}
I have a guess your problem is not related to Nginx per se, but instead it is related to Docker networking. You provided insufficient information to make a detailed conclusion, but here it is a couple of suggestions:
run a simple Docker container at the same host where nginx container is running and try curl from inside that container (I've seen your answer that you are able to call curl from the server running Nginx, but it's not really the same)
for example, if the server running nginx container is OSX or Windows, it may use an intermediate Linux virtual machine with its own network stack, IP addreses, routing, etc.
This is my conf sending to inner glassfish. Check out the use of proxy_redirect off & proxy_set_header X-NginX-Proxy true;
#Glassfish
location /MyService/ {
index index.html;
add_header Access-Control-Allow-Origin $http_origin;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-NginX-Proxy true;
proxy_ssl_session_reuse off;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://127.0.0.1:18000/MyService/;
}

Nginx: How to forward requests to a port using proxy_pass

I'm just getting started with Nginx and am trying to set up a server block to forward all requests on the subdomain api.mydomain.com to port 8080.
Here's what I've got:
UPDATED:
server {
server_name api.mydomain.com;
location / {
proxy_pass http://127.0.0.1:8080/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-for $remote_addr;
}
}
server {
server_name www.mydomain.com;
return 301 $scheme://mydomain.com$request_uri;
}
server {
server_name mydomain.com;
root /var/www/mydomain.com;
index index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
}
The server block exists in /etc/nginx/sites-available and I have created a symlink in /etc/nginx/sites-enabled.
What I expect:
I'm running deployd on port 8080. When I go to api.mydomain.com/users I expect to get a JSON response from the deployd API, but I get no response instead.
Also, my 301 redirect for www.mydomain.com is not working. That block was code I copied from Nginx Pitfalls.
What I've tried:
Confirmed that mydomain.com:8080/users and $ curl
http://127.0.0.1:8080/users return the expected response.
Restarted the nginx service after making changes to the server block.
Tried removing the proxy_set_header lines.
Any idea what I'm missing here?
You shouldn't need to explicitly capture the URL for your use case. The following should work for your location block:
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
}
As it turns out, my problem was not with Nginx configuration but rather with my DNS settings. I had to create an A NAME record for each of my sub-domains (www and api). Rookie mistake.
A colleague of mine actually helped me troubleshoot the issue. We discovered the problem when using telnet from my local machine to connect to the server via IP address and saw that Nginx was, in fact, doing what I intended.

Resources