Yet another 502 error with nginx - nginx

I'm trying to put a server#home in place with some basic services. All services run into a dedicated VM. Each VM is hosted on vSphere 5.5. So far I have :
Debian wheezy with nginx used as a reverse proxy : 192.168.1.12
Debian wheezy with nodeJS used as a webapp server : 192.168.1.43
192.168.1.43:3000 => http web server that makes a redirection on 192.168.1.43:3001
192.168.1.43:3001 => https web server that makes provides the service
Debian wheezy with madsonic installed : 192.168.1.35
As said in documentation I put --https-port=443 in the config to enable https access
I use nginx to be able to have things like this :
myapp.mydomaine.com => go to nodejs # 192.168.1.43
music.mydomain.com => go to madsonic # 192.168.1.35
I followed a tutorial and edited the "default" file in /etc/nginx/sites-enabled. Here is how it looks like :
server {
listen 80;
server_name myapp.domaine.com;
location / {
proxy_pass http://192.168.1.43:3000;
}
}
server {
listen 443;
server_name myapp.domain.com;
ssl on;
ssl_certificate [...];
ssl_certificate_key [...];
location / {
proxy_pass https://192.168.1.43:3001;
}
}
server {
listen 80;
server_name music.domain.com;
location / {
proxy_pass http://192.168.1.35:4040;
}
}
server {
listen 443;
server_name music.domain.com;
ssl on;
ssl_certificate [...];
ssl_certificate_key [...];
location / {
proxy_pass https://192.168.1.35;
}
}
The first redirection on myapp works. The redirection on music works when I had only http on the madsonic server. When I activate https on madsonic server I get a 502 Bad gateway error (but the URL in Firefox is https://music.domain.com).
I also tryed some other methods like mentionned here :
How to redirect on the same port from http to https with nginx reverse proxy
Did not work either.
I also saw in /var/logs/nginx/error.log that the 502 error is due to a SSL_do_handshake error (SSl23_GET_SERVER_HELLO:tlsv1). No idea if it is related to the 502 error or not.
I'm a bit confused because other https services work fine. Someone has a suggestion ? Thanks very much.

Here is the answer of the user "desasteralex" that was posted for the same question on serverfault.com. It worked so I share his answer here (and big thx him btw :D).
First of all, Nginx is your SSL terminator here. That means that you don't need to run your app in both - HTTP and HTTPS mode. HTTP would be enough.
So, for your app the config could look like that:
server { listen 192.168.1.12:80; server_name myapp.domain.com; location / { rewrite ^ https://$server_name$request_uri? permanent; } }
The directive above will redirect all HTTP requests to HTTPS.
server { listen 192.168.1.12:443; server_name myapp.domain.com; ssl on; ssl_certificate [...]; ssl_certificate_key [...]; location / { proxy_pass https://192.168.1.43:3000; } }
I've chosen the port 3000 in the proxy_pass here to point to the HTTP version of your app. You would need to turn off the redrection of your app to port 3001.
Regarding your music.domain.com redirection - for HTTP you use the port 4040 in the proxy_pass parameter, in HTTPS you don't. I assume that the madsonic server only listens on port 4040, so a config could look like this:
server { listen 192.168.1.12:80; server_name music.domain.com; location / { rewrite ^ https://$server_name$request_uri? permanent; } }
server { listen 192.168.1.12:443; server_name music.domain.com; ssl on; ssl_certificate [...]; ssl_certificate_key [...]; location / { proxy_pass https://192.168.1.35:4040; } }
Hope this helps.

Related

How can a request resolve to a different domain while keeping URI information?

I have 2 domains domain.xyz and domainxyz.com
I have the boilerplate for a dynamic routing service set up on domain.xyz which serves domain.xyz/example-uri.
I would like to make domainxyz.com/example-uri resolve to domain.xyz/example-uri
On the server I am using Nginx to direct requests on port 80 to the React app
instead of using a dns redirect to resolve the .com to the .xyz (which is what I was initially doing), direct both domains to the nginx server. Then configure the nginx server like this:
source/explanation: https://www.nginx.com/blog/creating-nginx-rewrite-rules/
server {
listen 80;
server_name www.domainxyz.com domainxyz.com;
location / {
return 301 $scheme://domain.xyz$request_uri;
proxy_pass http://localhost:3000;
}
}
server {
listen 80;
server_name www.domain.xyz domain.xyz;
location / {
proxy_pass http://localhost:3000;
}
}

Nginx reverse proxy to an https address behind corporate proxy

I am trying to setup an Nginx reverse proxy to an AWS API Gateway address like https://12345.execute-api.eu-central-1.amazonaws.com/v2 behind a corporate proxy.
I tried the following setup to www.example.com and it works. But as soon as I add https to it like https://www.example.com it fails. I add https since my API Gateway address is not accessible without it.
Current working config:
server {
listen 80;
listen [::]:80;
listen 443;
underscores_in_headers on;
location / {
proxy_pass_request_headers on;
proxy_set_header Host www.example.com;
proxy_pass http://myCorporateProxy.org:8080;
}
}
What I want to achieve and error I get:
Redirect all incoming traffic to localhost to be redirected to API Gateway address which looks similar to https://123456.execute-api.region.amazonaws.com/v2/
When trying following config, I get a 302 temporarily Moved error.
In configuration it would look like this:
server {
listen 80;
listen [::]:80;
listen 443;
underscores_in_headers on;
location / {
proxy_pass_request_headers on;
proxy_set_header Host https://www.example.com;
proxy_pass http://myCorporateProxy.org:8080;
}
}
You should try something like this. To redirect from http to https is a little different.
server {
listen 80;
server_name myCorporateProxy.org www.myCorporateProxy.org;
return 301 https://myCorporateProxy.org$request_uri;
}

How to create reverse proxy for multiple websites in nginx

I have many different technologies serving APIs and sites on my local machine. I want to be able to see them via human-readable names, rather than ports.
For example, I have:
localhost:8000 => laravel api for user panel
localhost:8001 => laravel api for admin panel
localhost:3000 => react client for user panel
localhost:3001 => nextjs client for site
localhost:3002 => react client for admin panel
And this list goes on.
Remembering all these ports is not possible of course. Thus I thought to setup a reverse proxy for them:
api.user.example.local
api.admin.example.local
example.local
user.example.local
admin.example.local
I know I have to add these host headers to /etc/hosts file. I also read about how to configure nginx as a reverse proxy for one domain.
I don't know how to do it for many sites. And only as a reverse proxy, not as a server.
Please note: I'm not considering myself as really super nginx expert, just starting to learn nginx, but I think I can help you with this task.
Here is my approach:
First, make sure your default nginx config (usually /etc/nginx/nginx.conf) has line include /etc/nginx/conf.d/*.conf; in its http block, so you may specify internal servers in separate config files for ease of use.
Create additional config file /etc/nginx/conf.d/local_domains.conf and add following server blocks in it:
server {
listen 80;
server_name api.user.example.local;
location / {
set $target http://localhost:8000;
proxy_pass $target;
}
}
server {
listen 80;
server_name api.admin.example.local;
location / {
set $target http://localhost:8001;
proxy_pass $target;
}
}
server {
listen 80;
server_name example.local;
location / {
set $target http://localhost:3000;
proxy_pass $target;
}
}
server {
listen 80;
server_name user.example.local;
location / {
set $target http://localhost:3001;
proxy_pass $target;
}
}
server {
listen 80;
server_name admin.example.local;
location / {
set $target http://localhost:3002;
proxy_pass $target;
}
}
On the client machine, add these records to the hosts file
192.168.1.1 api.user.example.local
192.168.1.1 api.admin.example.local
192.168.1.1 example.local
192.168.1.1 user.example.local
192.168.1.1 admin.example.local
Where 192.168.1.1 is the address of your nginx server.
That's it, it should work if your internal servers are using HTTP protocol.
But if you need to use HTTPS for internal servers and for the main nginx server, modify each server block as follows:
server {
listen 443 ssl http2;
server_name api.user.example.local;
ssl_certificate /usr/local/share/ca-certificates/example.local.crt;
ssl_certificate_key /usr/local/share/ca-certificates/example.local.key;
add_header Strict-Transport-Security "max-age=31536000" always;
location / {
set $target https://api.user.example.local:8000;
proxy_pass $target;
}
}
and so on
ssl_certificate and ssl_certificate_key should point to correct certificate and key files for the domain.
If you would like nginx main server to listen port 80 and redirect all traffic to https, add additional server blocks for each server:
server {
server_name api.user.example.local;
listen 80;
# Force redirection to https on nginx side
location / {
return 301 https://$host$request_uri;
}
}
and so on
More information on NGINX Reverse Proxy
NGINX Reverse Proxy
Module ngx_http_proxy_module

Nginx - Stop forcing HTTPS on subdomain

I have a site which is ran with nginx, and with the structure where we have a load balancer, and currently only one web server behind it (currently no real traffic so one web server only).
Anyways, in load balancer nginx config, we forced HTTPS on each request:
server {
listen 80;
server_name www.xyz.com xyz.com
return 301 https://www.xyz.com$request_uri;
}
This works fine, but now I want to say "on this subdomain - dev.xyz.com, allow HTTP too and don't do the forcing".
At first, the server_name param was "any", and thought that might be the problem, so I specifically typed the names as in the above samples, and when I type http://www.dev.xyz.com, I get redirected back to the https://www.xyz.com.
Below server block, we have SSL definitions too:
server {
listen 443;
ssl on;
ssl_certificate /etc/nginx/ssl/xyz.com.pem;
ssl_certificate_key /etc/nginx/ssl/xyzPrivateKeyNginx.key;
keepalive_timeout 70;
server_name www.xyz.com;
root /usr/local/nginx/html;
client_max_body_size 25M;
client_body_timeout 120s;
# Add trailing slash if missing
rewrite ^([^\.]*[^/])$ $1/ permanent;
}
Thanks! :)
it turned out the solution was simple, I only inserted a simple redirect:
server {
listen 80;
server_name www.dev.xyz.com
location / {
proxy_pass http://xxyyzz;
}
}
Where xxyyzz is:
upstream xxyyzz{
ip_hash;
server 10.100.1.100:80;
}
Thanks anyways!

Redirect all http to https in nginx, except one file

I am currently running my site on http, and want to move it over to https such that nginx handles the redirection automagically. This is fairly trivial to do, I guess.
However, there is one file that (for several reasons) is hot-linked from other sites, some of which are over http and some over https. I want to ensure that the file is available over both http and https, so as to ensure that browsers don't complain with the "mixed content" dialog. The path of the file looks something like this:
http(s)://mydomain.com/scripts/[some_sha1_hash]/file.js
So, the nginx rule should say: "If the request is already over https, everything is sweet, and just reverse-proxy it. Otherwise, redirect all requests from http to https, except if this one file is requested, in which case don't do any such http->https redirect."
Can anyone either tell me where to look to learn about such a config, or help me with the config itself? Thanks in advance. (I'm sorry, but I'm not skilled enough yet at nginx configuration.)
This is what I did, which works:
server {
listen 80;
server_name example.com;
charset utf-8;
access_log /var/www/path/logs/nginx_access.log;
error_log /var/www/path/logs/nginx_error.log;
location /path/to/script.js {
# serve the file here
}
location / {
return 301 https://example.com$request_uri;
}
}
This one handles only http requests and serves the said file - otherwise redirects to https. Define your ssl server block, which will serve all https requests.
server {
listen 443;
server_name example.com;
ssl on;
# rest of the config
}
This way your script file will be available on http as well as https.
Try this:
server {
listen 80; ssl off;
listen 443 ssl;
server_name example.com;
# <ssl settings>
# ... other settings
location = /scripts/[some_sha1_hash]/file.js {
# Empty block catches the match but does nothing with it
}
location / {
if ($scheme = "http") {
rewrite ^ https://$http_host$request_uri? permanent;
}
# ... other settings
}
}
server {
listen 80;
server_name my.domain.com;
rewrite ^ https://$server_name$request_uri? permanent;
}
server {
listen 443;
server_name my.domain.com;
ssl on;
[....]
}
The above should mostly do the trick if im not wrong

Resources