nginx proxy_pass to https / image-server not working - nginx

I'm trying to proxy an image server imagekit.io so that all requests have same domain name.
Have tried multiple configurations in HTTPS nginx server (with self-signed certificate) and even in HTTP server.
Let's say the URL is https://ik.imagekit.io/hj8sm3kk7/brochures/92/1579/suzuki-gsx-r150-615123.pdf
With the below configuration, I'm trying to hit http://localhost.com:8800/brochures/92/1579/suzuki-gsx-r150-615123.pdf
server {
listen 8800;
server_name localhost.com;
location /brochures {
proxy_ignore_headers Set-Cookie;
proxy_set_header Host ik.imagekit.io;
# proxy_set_header X-Real-IP $remote_addr;
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Pragma no-cache;
proxy_set_header Accept $http_accept;
proxy_set_header User-Agent $http_user_agent;
proxy_set_header Accept-Encoding $http_accept_encoding;
proxy_set_header Accept-Language $http_accept_language;
proxy_set_header sec-fetch-mode navigate;
proxy_set_header sec-fetch-site cross-site;
proxy_set_header sec-fetch-user ?1;
proxy_set_header :authority ik.imagekit.io;
proxy_set_header :method GET;
proxy_set_header :path $path;
proxy_set_header :scheme https;
proxy_set_header Upgrade-Insecure-Requests 1;
proxy_pass https://ik.imagekit.io/hj8sm3kk7/brochures;
}
}
This however works:
http://localhost.com:8800/financial-advisor/mfs-investment-management-review opens the same page as https://smartasset.com/financial-advisor/mfs-investment-management-review
location /financial-advisor {
proxy_ignore_headers Set-Cookie;
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_pass https://smartasset.com;
}

The real issue turned out to be an SSL problem with ik.imagekit.io, using http:// instead of https:// in the proxy_pass value helps.
Original (and wrong) answer I've given:
The first example requires a manipulation of the URL path. Consider a similar approach:
location ~ ^/(brochures/.*) {
# all the previous config you used should be added here
proxy_pass https://ik.imagekit.io/hj8sm3kk7/$1;
}
This will proxy the request to the proper URL path, which changes from the original request. $1 is the part of the request URL path that matches the first brackets (...).

Related

nginx always adding trailing slash after domain

I've spent forever searching and I can't see that I'm doing anything wrong.
Basically I have two domains and want to route to a backend service depending on which one is visited.
clientkey.local
clientkey.strapi.local
When I visit each of these domains, it's rewriting the urls as:
clientkey.local/
clientkey.strapi.local/
There is no point to adding the extra slashes if I'm just visiting the base domain. I can add the trailing slash if I want and still end up on the home page, but it shouldn't redirect me there automatically. Below is my nginx config.
Any ideas? I'm using docker-compose if that matters. I feel like I'm missing something obvious.
worker_processes 4;
events { worker_connections 1024; }
http {
upstream strapi_servers {
server strapi:1337;
}
upstream gallery_servers {
server gallery;
}
server {
listen 80;
server_name clientkey.strapi.local;
location / {
proxy_pass http://strapi_servers;
proxy_http_version 1.1;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $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 Host $http_host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_pass_request_headers on;
}
}
server {
listen 80;
server_name clientkey.local;
location / {
proxy_pass http://gallery_servers;
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;
}
}
}
Quick testing reveals that slash is not hidden for non-public TLD websites (Chromium/Chrome).
In other words, if the TLD isn't real, then slash is not being ommited.
example.local - slash shown
example.anyting-non-real - slash shown
example.com - slash hidden

Nginx reverse proxy to two services

I'm running nodeJS script..
on localhost:9001
it is running behind nginx reverse proxy
it accept request in the form of /v{{ version }}/{{ lang }}/...
So for example:
domain.com/api/v1/en/news
domain.com/api/v2/fr/news
domain.com/api/v3/en/news
Until now I had this is nginx
location /api/ {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_pass http://localhost:9001/;
}
and everything work.
My goal now is to run additional (identical) script on localhost:9002 which will accept v4 requests. And v3, v2 and v1 will be still 'processed' by localhost:9001
So I want that request domain.com/api/v4/en/news is routed to localhost:9002
I put this above current rule like this
location ~* /api/v4/(.*)$ {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_pass http://localhost:9002/v4/$1;
}
location /api/ {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_pass http://localhost:9001/;
}
Request /v3/.. is routed to localhost:9001 (as expected) but /v4/.. returns 502.
Any pointers?
location /api/v4/ {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_pass http://localhost:9002/v4/;
}
location /api/ {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_pass http://localhost:9001/;
}

Nginx content_by_lua_block deletes request body?

I wanted to make some changes on existing nginx configuration. My previous configuration was like this:
location /serviceprovider {
proxy_pass http://localhost:8080;
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_redirect off;
}
Then I added content_by_lua_block as below:
location /serviceprovider {
proxy_pass http://localhost:8080;
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_redirect off;
content_by_lua_block{
ngx.req.read_body()
body = ngx.req.get_body_data()
file = io.open("/etc/nginx/test", "w")
file:write(body)
file:close()
}
}
My /serviceprovider actually accepts JSON request in POST. When I send request after adding lua block I get error message "Invalid JSON: Empty string", but It writes request body to file successfully.
I think this lua block deletes request body after writing it to file. I only want that location block worked as usual but in addition to write request body to a file.

How to proxy pass to a certain url depends on the request url by nginx?

I have two hello servers in server1(1.1.1.1) and server2(1.1.1.2). Now I want to use Nginx(example.com) to proxy pass request to the certain server like this:
Request Url:http://example.com/hello1
proxy pass:http://1.1.1.1/hello
Reqeust Url:http://example.com/hello2
proxy pass:http://1.1.1.2/hello
Just add the location block to example.com config. This should work.
location ^~ /hello1 {
proxy_set_header Proxy "";
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header HOST $http_host;
proxy_pass http://1.1.1.1/hello;
proxy_redirect off;
}
location ^~ /hello2 {
proxy_set_header Proxy "";
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header HOST $http_host;
proxy_pass http://1.1.1.2/hello;
proxy_redirect off;
}

Rewrite a subdomain to a backend proxy whith nginx

if have a subdomain on my nginx webserver configuration: sub.mydomain.com
and i have a backend server which listen on port 5000: http://127.0.0.1:5000
is it possible to pass all subdomain calls to the backend?
Like: https://sub.mydomain.com/list to http://127.0.0.1:5000/sub/list
This should work with all methods: POST, PUT, GET, DELETE
UPDATE:
when i call my server: https://mysubdomain.mydomain.com
with the following configuration:
upstream http_backend {
server 127.0.0.1:5000;
}
server_name ~^(?<subdomain>[^.]+)\.mydomain\.com;
This does not work (error: 404):
location / {
proxy_pass http://http_backend/$subdomain/;
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-Proto https;
}
This works fine:
location / {
proxy_pass http://http_backend/mysubdomain/;
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-Proto https;
}
When i log the $subdomain variable in the access_log, it seems to be correct.
nginx version: nginx/1.9.15
To pass all subdomains you need to set it in server name by putting dot before domain.
server_name .mydomain.com;
Yes, you can use variables in proxy_pass. And you can extract part of domain using regexp server name.
server {
server_name ~^(?<sub>[^.]+)\.example\.com;
# now subdomain of example.com placed to $sub
# please, note, this rule do not work for http://example.com
location / {
proxy_pass http://127.0.0.1:5000/$sub/;
# Path part of proxy_par URI will replace path
# part of location directive (so / -> /$sub/, /xxxx/ -> /$sub/xxxx/)
}
}
Thats all :)
It seems nginx does not add the $uri to the proxy_pass if i use the $subdomain variable.
The following solution works:
location / {
proxy_pass http://http_backend/$subdomain/$uri;
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-Proto https;
}

Resources