NGINX Reverse Proxy redirecting instead of proxying - nginx-reverse-proxy

i have a NGINX server running as a reverse proxy. Proxy works for windows hosts however i have a owncloud server and the proxy will instead re wright the url to the internal host name or IP address. ex(I type cloud.example.com and my url bar will change to 10.1.1.19 which is unresolvable over wan
i have checked DNS records and made sure NGINX can resolve host name. also tried just forwarding http traffic to cloud server to make sure using domain name was not the issue.
server {
listen 80;
listen [::]:80;
server_name example.com;
location / {
proxy_pass http://10.1.1.16:80/;
}
}
server {
listen 80;
listen [::]:80;
server_name cloud.example.com;
location / {
proxy_pass http://10.1.1.19:80/;
}
}
server {
listen 80;
listen [::]:80;
server_name remote.example.com;
location / {
proxy_pass http://10.1.1.17:80/;
}
}
i just need NGINX to run as a proxy for "cloud.example.com" instead of rewriting URL

I found a partial answer to this -- Why is my Nginx reverse proxy doing a 301 redirect instead of proxying?.
For me, it kept nginx from changing the hostname (i.e. from good-domain.com to 10.1.5.5:8080), but there doesn't appear to be a way to stop nginx from appending the port to the client's request URL.
So, in using the answer referenced above, I was able to go from http://10.1.5.5:8080 to http://good-domain:8080. It's still not where I want to be, but it definitely gets me closer.

Related

Nginx Reverse proxy not redirecting to HTTPS

So i have a Nginx server working as a reverse proxy with this configuration
http {
server {
listen 80;
listen [::]:80;
server_name www.example.tdl;
access_log logs/reverse-access.log;
error_log logs/reverse-error.log;
location / {
proxy_pass https://127.0.0.1:443;
}
}
}
My only problem is that when i connect to example.tdl it redirects correctly, but not with HTTPS. But its redirecting to the https port of my Apache server so i dont know where is the problem.
I never used nginx before so this is probably a configuration error.
How can i make that nginx redirects to that port with https?
This may sound dumb but what you've got is that nginx is working as a proxy for you. You connect to nginx via HTTP, nginx forwards your request to apache via HTTPS, then gets the answer back and transmit it to you using HTTP.
You need to make nginx listen for HTTPS with listen 443 ssl; and supply it with a certificate (ssl_certificate <path>;) and a key (ssl_certificate_key <path>;). After that add the following piece of code to the server block:
if ($scheme != "https") {
return 301 https://$host$request_uri;
}
This will redirect everything to HTTPS.

How to listen to different port on Nginx and proxy the request?

I am a newbie to Nginx config and all, I have a process which is an express app, running on port 3000 using pm2 and I have allowed port 3000 using ufw as well, and have made a server instance on Nginx to proxy it,
server {
# SSL configuration
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name .mysite.co;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/django/mysite;
}
proxy_cache mysite;
location / {
include proxy_params;
proxy_pass http://unix:/home/django/mysite/mysite.sock;
}
gzip_comp_level 3;
gzip_types text/plain text/css image/*;
ssl_certificate /etc/letsencrypt/live/mysite.co/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/mysite.co/privkey.pem; # managed by Certbot
}
server {
if ($host = www.mysite.co) {
return 301 https://$host$request_uri;
} # managed by Certbot
if ($host = mysite.co) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80 default_server;
listen [::]:80 default_server;
server_name .mysite.co;
return 404; # managed by Certbot
}
server{
listen 3000;
listen 443 ssl http2;
server_name .mysite.co:3000;
location / {
proxy_pass https://localhost:3000;
}
}
I ran netstat -napl | grep 3000 and I could confirm that the process is running and pm2 status also says its running and no errors in log as well.
How could I make this work? Thanks for the help in advance.
You won't be able to use nginx to listen on port 3000 as well as your node process as only one service can really listen on the port at once. So you'll need to ensure nginx is listening for connections on a different port. I imagine what you're trying to do is to listen on port 80 / 443 and then send the request onto your express service which is listening on port 3000?
In this case your bottom server block is nearly correct. To get this working without TLS/SSL (just on port 80) you'll want to use something like this:
server {
listen 80;
server_name node.mysite.co
location / {
proxy_pass http://localhost:3000;
}
}
The following is a very basic example and you'll probably want to toggle some other settings. This will make "http://node.mysite.co" go proxy through to whatever service (in this case an Express server) is listening on port 3000 locally.
You do not need to make a firewall (ufw) exception for port 3000 in this case as it's a local proxy pass. You should close the port on the firewall so people can't access it directly, this way the must go through nginx.
If you want to get SSL/TLS working, you'll want another block that'll look something like the following. Again, this is very basic and doesn't have a lot of settings you probably want to research and set (such as cipher choices).
server {
listen 443 ssl;
server_name node.mysite.co
ssl_certificate certs/mysite/server.crt;
ssl_certificate_key certs/mysite/server.key;
location / {
proxy_pass http://localhost:3000;
}
}
You'll need to replace the cert and key path to point to your SSL/TLS ceritifcate and key respectively. This will enable you to access https://node.mysite.co and it'll be proxied onto the service on port 3000 as well.
Once you've done that you might then choose to go back and change the http (port 80) server to a redirect to https to force https only connections.
Also note that I've ensured the server_name is different to your existing django server_name with a subdomain (node.mysite.co). You might wish to change this value but you can't have two server blocks listening on the same port and server_name, otherwise nginx would have no idea what to do with the request. I'm sure you're doing this anyway but I wanted to make sure it was explicit and would work with your existing setup.
If you wish the site to be served only for mysite.co:3000
If for some reason you want the user to go to port 3000 on the domain mysite.co, then you will need to set the "listen" to 3000 and keep the server name as "mysite.co". This will allow someone to go to mysite.co:3000 in their browser and hit your node service. I imagine this isn't really what you want for a public facing website though, it also won't line up very nicely with your port 443 version.
Note: I don't claim to be an nginx expert, but I've used it for all my node projects for the past few years and I find this setup to be pretty clear. There might be some nicer syntax you can use.

When enable SSL on Nginx page redirects to default page

I have a nginx server which is running multiple vhost, I have configured one more vhost and tried to make it https, but when I tried to access it redirects to default page. I have configured SSL certs with letsencrypt.
my config file is
server {
listen 443 ssl;
root /var/www/html;
server_name abc.xyz.com;
include includes/letsencrypt;
location / {
proxy_pass http://abc;
include includes/proxy-config;
}
}
I have also tried with below config
server {
listen 80;
server_name abc.xyz.com;
return 301 https://abc.xyz.com$request_uri;
}
server {
listen 443 ssl;
server_name abc.xyz.com;
ssl on;
include includes/letsencrypt;
access_log /var/log/nginx/log/abc.access.log;
error_log /var/log/nginx/log/abc.error.log;
location /.well-known/acme-challenge {
root /var/www/letsencrypt;
}
location / {
proxy_pass http://abc;
}
}
After this page is redirecting to my firewall.
Port 443 is also opened up.
Any Ideas what is wrong here?
I have nail down this by adding NAT rule in firewall.
Basically nothing wrong in above configuration.
I had only opened port on firewall.
As opening port is just between Internet and firewall
NAT redirects traffic from public-ip:443 -> local-ip:443
I too had this problem, but for me the solution was eventually found in a problem with the configuration file for php-fpm. There was a problem creating/accessing the error log for php-fpm, which I had turned on myself in the config file for php-fpm earlier thinking it was a good thing to do. Turning it back off again, restarting php-fpm and nginx got everything working as expected.
Just in case you're googling around like I was and kept finding this question at the top ;-)

'ERR_TOO_MANY_REDIRECTS' error nginx docker

I am using nginx docker for deploying my app in aws server. I have to access my api using nginx proxy url which looks like https://domain.com/api/. This is a https request so i have to set proxy redirection to another port where api service running and the service is running under another docker container in same server instance. so my nginx conf file looks like below,
server {
listen 80;
server_name domain.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
server_name domain.com;
# add Strict-Transport-Security to prevent man in the middle attacks
add_header Strict-Transport-Security "max-age=31536000";
location /api/ {
proxy_pass http://my-public-ip-address:3000;
}
}
So my problem is that while I am trying to access the api endpoint using above url its showing ERR_TOO_MANY_REDIRECTS. So any one know about this issue? And also i went through all the article with same issue mentioned but no luck.

Nginx non HTTPS websites redirect to other HTTPS websites

I'm using nginx for hosting multiple websites on a ubuntu server. Basically my setup is as follows.
My first domain example1.com (SSL enabled) can be accessed from http://example1.com as well as from https://example1.com. This working fine.
But my 2nd domain example2.com, I don't have SSL enabled - but when I type https://example2.com the url redirects to the first domain https://example1.com - Which is wrong
Now currently I have added this server block if someone type in the URL with https:// it will redirect back to http:// on the same domain. But this is not the right way to handle this issue. Does anyone has some better ideas?
server {
listen 443 ssl;
server_name example2.com www.example2.com;
rewrite ^ http://$server_name$request_uri? permanent;
}
The problem here is that you’re only using a single IP address (server-side) and rely on the TLS Server Name Indication extension (client-side). Nginx will always use your default HTTPS server if nothing else is available to handle the request.
Your solution looks quite right to me, although it will produce an error on the client-side if you have no valid certificate. The only other possibility would be to create a default invalid HTTPS server that simply drops the connection attempt. But I guess that’s not what you want.
server {
listen 443 ssl;
server_name example2.com *.example2.com;
return 301 http://$server_name$request_uri;
}
Always use return if you redirect at such a point.
A default invalid catch all configuration could look like the following:
server {
listen 443 ssl;
server_name _;
ssl_certificate blank.crt;
ssl_certificate_key blank.key;
return 403;
}
As I said, it will simply drop any connection attempt that doesn't contain a valid HTTP Host in the submitted headers or if the submitted HTTP Host in the header is not valid.
Having the following will listen on 443 (SSL), and because you don't have a SSL certificate for this domain, nginx will use the first or default SSL certificate, which will throw invalid domain error. Simply remove it, so that it doesn't listen on 443 (SSL).
server {
listen 443 ssl;
server_name example2.com www.example2.com;
rewrite ^ http://$server_name$request_uri? permanent;
}