Nginx does redirect, not proxy - ssl

I want to set up Nginx as a reverse proxy for a https service, because we have a special usecase where we need to "un-https" a connection:
http://nginx_server:8080/myserver ==> https://mysecureservice
But what happens is that the actual https service isn't proxied. Nginx does redirect me to the actual service, so the URL in the browser changes. I want to interact with Nginx as it was the actual service, just without https.
This is what I have:
server {
listen 0.0.0.0:8080 default_server;
location /myserver {
proxy_pass https://myserver/;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
}
}

You have to use the proxy_redirect to handle the redirection.
Sets the text that should be changed in the “Location” and “Refresh” header fields of a
proxied server response. Suppose a proxied server returned the header field
“Location:https://myserver/uri/”. The directive
will rewrite this string to “Location: http://nginx_server:8080/uri/”.
Example:
proxy_redirect https://myserver/ http://nginx_server:8080/;
Source: http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_redirect

You can setup nginx like this if you do not want the server to do redirects:
server
{
listen 80;
server_name YOUR.OWN.DOMAIN.URL;
location / {
proxy_pass http://THE.SITE.URL.YOU.WANT.TO.DELEGAGE/;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}

For me, this config was sufficient:
events {
}
http {
server {
location / {
resolver 8.8.8.8;
proxy_pass https://www.example.com$request_uri;
}
}
}
(Note that the resolver directive has nothing to do with the problem in the OP, I just needed it to be able to proxy an external domain such as example.com)
The problem for me was just that I was missing the www. in www.example.com. In the Firefox developer's console, I could see the GET request to localhost coming back with a 301, and so I thought that NGINX was issuing 301s instead of just mirroring example.com. Not so: in fact the problem was that example.com was returning 301s to redirect to www.example.com, NGINX was dutifully mirroring those 301s, and then Firefox "changed the URL" (followed the redirect) straight from localhost to www.example.com.

I was having a similar issue. In my case, I was able to resolve the issue by added a trailing slash to the proxy_pass URL:
before
server {
location / {
proxy_pass http://example.com/path/to/some/folder;
}
}
after
server {
location / {
# added trailing slash
proxy_pass http://example.com/path/to/some/folder/;
}
}

Related

Nginx not redirecting on named route

I'm trying to setup a reverse proxy to a sentry relay using Nginx. Config file as follows:
events {
worker_connections 768;
}
http {
server {
listen 0.0.0.0:80;
location /sentry-relay {
proxy_pass http://127.0.0.1:3001;
proxy_redirect off;
proxy_set_header Host $host;
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;
}
}
}
Browsing directly to the relay server on port 3001 works fine:
However using the location path set in Nginx fails:
I've also put the redirect onto the default path: location / and it works fine. Why won't this custom path redirect properly?
I worked it out.
Nginx will append the location prefix to the proxy server request unless this prefix is replaced.
Thus to fix I changed:
proxy_pass http://127.0.0.1:3001;
to
proxy_pass http://127.0.0.1:3001/;
The extra slash is used to replace the sentry-relay path.

troubleshooting application behind nginx reverse proxy, as POST/PUT requests are replied with Error 400 (Bad Request)

I'm trying to host my Angular/ASP.net core 3.1 application on linux for the first time.
Nginx stands on the port 80 and serves the static files and acts as a reverse proxy for the api part which will be passed to the .NET/kestrel server.
The problem is that I systematically get a 400 status code error (Bad Request) on any web API request containing a body, like POST & PUT, but GET is ok.
I added some logs through a middleware, just to see if I can get the requests. Basically, something like:
app.Use(async (context, next) => {
context.Request.EnableBuffering();
string reqBody;
using (var reader = new StreamReader(context.Request.Body))
{
reqBody = await reader.ReadToEndAsync();
context.Request.Body.Seek(0, SeekOrigin.Begin);
ms_oLogger.Debug($"Incoming request: METHOD={context.Request.Method} PATH={context.Request.Path} BODY=\"{reqBody}\"");
}
await next();
});
This just loggs stuff for GET requests, but nothing appears for the problematic PUT/POST requests... Can I conclude that this is only a nginx problem?
I also enabled the logs on nginx for the given "/api" location, but I can not tell what happens... How can I know which tier has generated the 400 status code?
EDIT1: I started a blank new project just with a poor Web API project containing one GET and one POST method just to check if there was something wrong with my application, but I still get the problem.
So I set up a new ubuntu server (this time, ubuntu server instead of desktop version) and now it works!!!
I compared configuration etc... but could not figure out what was wrong!....
But my initial question is still valid: how can I troubleshoot where the problem comes from?
EDIT2: This is my default.conf:
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
server_name _;
location / {
try_files $uri $uri/ =404;
}
location /fusion {
root /opt/fichet/WebUI/NgApp;
}
location /fusion/api {
proxy_pass http://localhost:5000/api;
error_log /var/log/nginx/fusion_error_logs.log debug;
access_log /var/log/nginx/fusion_access.log;
proxy_http_version 1.1;
proxy_cache_bypass $http_upgrade;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
}
}
It seems that no firewall is enabled ("sudo ufw status verbose" tells us that it is "inactive")
Remove these lines from your nginx config.
proxy_cache_bypass $http_upgrade;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
These headers are used for WebSocket connections, and shouldn't be present for non-websocket requests. My guess is your upstream server doesn't mind them for GET requests but does for POST/PUT, for some reason.
If you are not using websockets, you can leave them removed.
If you are using websockets, you need nginx to add or not these headers based on whether the requests is websockets or not. Something like this should work:
http {
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
...
location /fusion/api {
proxy_pass ...
...
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}
See here for more info.

Setting up Jenkins DNS

I've been trying to set up Jenkins on my VPS.
I did everything and got it to work on the ip:8080.
What I am really wanting to do is get it working on ci.domain.com, but I have been having trouble.
I use Pterodactyl on the same machine, which runs on Nginx.
When I point the domain to the ip I get redirected to Pterodactyl which is on hub.domain.com.
I tried setting up Jenkins with apache and leaving Pterodactyl on Nginx but didn't work.
Is there a way to make make it work?
Cheers.
I had the same issue, seems like the nginx congif on the website doesn't work well.
Try this one:
upstream jenkins {
server 127.0.0.1:8080 fail_timeout=0;
}
server {
listen 80;
server_name ci.domain.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name ci.domain.com;
#if you want sll
#ssl_certificate put_path_here;
#ssl_certificate_key put_path_here;
location / {
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect http:// https://;
proxy_pass http://jenkins;
# Required for new HTTP-based CLI
proxy_http_version 1.1;
proxy_request_buffering off;
proxy_buffering off; # Required for HTTP-based CLI to work over SSL
# workaround for https://issues.jenkins-ci.org/browse/JENKINS-45651
add_header 'X-SSH-Endpoint' 'jenkins.domain.tld:50022' always;
}
}

Customize URL location for loadbalancing nginx

I am new to nginx.
I am having WCF Rest Service listening in the following url,
127.0.0.1:portHere/Service1.svc/RemainingRestURLTemplate.
Here is the config I am having.
http {
upstream servers_customserver {
server 127.0.0.1:62133;
server 127.0.0.1:62134;
server 127.0.0.1:62135;
}
server {
listen 8090;
server_name localhost;
location /two/ {
proxy_set_header Host $host;
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;
proxy_pass http://servers_customserver;
}
}
}
Upon entering localhost:8090/two/, I thought the upstream will work,but the browser reports problem, as in the image.
But the browser works fine when I have removed the "/two/" from my location, as below.
So, how to make my upstream to work, only when the user typed the url ends with "/two/".
Could some one share some input on it.
Thx in advance.
Finally after some hrs, found that trailing slash did the work.
proxy_pass http://servers_customserver/ works instead of proxy_pass http://servers_customserver Correct me if am wrong.
Thx.

hst.actionUrl virtual configuration Hippo CMS

Following the instruction here, my website can display the contents fine.
However, handling the form submission is current a problem.
I have virtual host set up in my environment. Rendering of contents is fine but form submission ends up in a blank page.
My form is at http://mysite.local/contact
My virtual host is http://mysite.local matches to http://localhost:8080/site
My form follows the developer trail:
<#hst.actionURL var="actionUrl"/>
<form id="" class="form" action="${actionUrl}" method="post">
When I click submit, I was redirected to a blank page: http://localhost:8080/contact?r14_r1_r1:u_u_i_d=5641b2fe-10ad-41b2-8f30-06d8a59ff451
Using my custom component, I printed out the serverName and it's "localhost"!
How do I configure it's in the Console so that my server is "mysite.local" instead of "localhost"?
#Override
public void doBeforeRender(final HstRequest request,
final HstResponse response)
throws HstComponentException {
super.doBeforeRender(request, response);
l.info(request.getServerName());
}
Updates:
I've added the node as per Joeren's suggestion.
However it's still not working.
I event removed the "localhost" node that was orginally under hst:hosts >> dev-localhost but it broke the Site site.
I've noticed that "hst:hosts" have hst:defaulthostname set to "localhost".
I haven't dared to make the change because it would be irreversible I thought.
Updates:
My virtual host configuration (nginx) is as follows:
server {
# listen 80;
server_name mysite.local;
location /site/ {
proxy_pass http://localhost:8080/site/;
# include /etc/nginx/proxy_params;
}
location /cms/ {
proxy_pass http://localhost:8080/cms/;
# include /etc/nginx/proxy_params;
}
location / {
proxy_pass http://localhost:8080/site/;
# include /etc/nginx/proxy_params;
}
}
To redirect to the fully qualified domain name you will need to setup the virtual host in the HST configuration tree in the CMS JCR console.
If the mysite.local is a domain on your local machine you can place it in the dev-localhost host group. By creating the following nodes:
hst:hst
+ hst:hosts
+ dev-localhost
+ local
+ mysite
+ hst:root
See the hosts configuration documentation for more background information.
If you have a web server in front like apache make sure you leave the proxypreserve host on, so that the HST can detect the host. See the Apache webserver configuration documentation for more information.
Passing the host name solve the problem! Thanks to Jeroen's comment.
There is no need to update the hst:hosts configurations in the console though.
I've updated my nginx config to as follows:
server {
# listen 80;
server_name mysite.local;
location /site/ {
proxy_pass http://localhost:8080/site/;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
}
location /cms/ {
proxy_pass http://localhost:8080/cms/;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
}
location / {
proxy_pass http://localhost:8080/site/;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
}
}