Nginx reverse proxy to subpage (non-root url) - nginx

I want http://example.com to map to a subpage from somewhere else:
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://somewhere.com/foo;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
}
}
The problem is that this page will load stuff like
<script src="/assets/script.js">
which will then be attempted to get loaded from http://example.com/assets/script.js - but this will actually go to http://somewhere.com/foo/assets/script.js instead of http://somewhere.com/assets/script.js
So how can I convince nginx to just map the root domain - http://example.com to http://somewhere.com/foo and everything else to http://somewhere.com/*?
I tried many things but couldn't get it to work...

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

proxy_set_header Hodst $host necessary for admin panel urls but messes up other wordpress urls

When I put
proxy_set_header Host $host;
under location /wordpress/ in my nginx.conf-file, I get working Wordpress urls apart from the admin panel where /wordpress/ is removed from the urls, making all links in the admin panel non-functional.
If I remove proxy_set_header Host $host;, I get non-working Wordpress urls but a working admin-panel.
I run a Wordpress install with a NextJs front-end with docker-compose and an nginx reverse proxy in front of it. I need both working Wordpress urls and the admin panel because I need access to the RSS feed (the /feed-url which doesn't work when I do the proxy_set_header-thing).
My location-block in nginx-conf:
location /wordpress/ {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://IP-TO-WORDPRESS:8000/;
# proxy_set_header Host $host;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-Proto $scheme;
}
Tried
adding and removing proxy_set_header Host $host,
adding a special location block for wp-admin (/wordpress/wp-admin - didn't work)
changing the url of proxy_pass
changing siteurl and home in wp_options in the wordpress mysql database
Entire Nginx.conf:
events {
worker_connections 1024;
# worker_processes and worker_connections allows you to
calculate maxclients value:
# max_clients = worker_processes * worker_connections
}
http{
server {
listen 80;
listen [::]:80 default_server ipv6only=on;
return 301 https://$host$request_uri;
}
# HTTPS ?~#~T proxy all requests to the Node app
server {
# Enable HTTP/2
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name SERVER-NAME.no;
# Use the Let?~#~Ys Encrypt certificates
ssl_certificate /etc/letsencrypt/live/SERVER-
NAME.no/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/SERVER-
NAME.no/privkey.pem;
# Include the SSL configuration from cipherli.st
include snippets/ssl-params.conf;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For
$proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://localhost:82/;
proxy_ssl_session_reuse off;
proxy_set_header Host $http_host;
proxy_cache_bypass $http_upgrade;
proxy_redirect off;
}
location = /wordpress {
return https://SERVER-NAME.no/NEXT-JS-BLOG-PAGE;
}
location /wordpress/ {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For
$proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://IP.TO-WORDPRESS:8000/;
# proxy_set_header Host $host;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
}
Expected:
I would expect urls to work both in the wordpress admin panel and for the wordpress posts and rss feed. This is not the case.
Please help as I'm quite lost on this one.
Found the problem was in the Wordpress app and not with the Nginx configuration. Turns out Wordpress has something called wp_admin_canonical_url() that sets the url in addition to siteurl and home.
See https://wordpress.stackexchange.com/questions/269798/wrong-wp-admin-url.

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;
}

nginx: redirect to two different servers based on domain

Let's say I have a domain: mike.com.
I'd like to have mike.com and www.mike.com hit my nginx server and get served a page sitting at 123.1.1.1.
I'd like to have api.mike.com get served by a server sitting at 123.2.2.2.
Perhaps my google-fu is failing me in epic fashion, but how would I go about arranging such a setup?
Create 2 server blocks and proxy_pass to the appropriate backend server.
Try with this example:
server {
listen 80;
server_name mike.com www.mike.com;
location / {
proxy_pass http://123.1.1.1:8080;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
server {
listen 80;
server_name api.mike.com;
location / {
proxy_pass http://123.2.2.2:8080;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}

nginx redirect all http to https with exceptions

I would like to redirect all http traffic to https with a handful of exceptions. Anything with /exception/ in the url I would like to keep on http.
Have tried the following suggested by Redirect all http to https in nginx, except one file
but it's not working. The /exception/ urls will be passed from nginx to apache for some php processing in a laravel framework but that shouldn't matter.
Any suggestions for improvement much appreciated!
server {
listen 127.0.0.1:80;
location / {
proxy_pass http://127.0.0.1:7080;
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-Accel-Internal /internal-nginx-static-location;
access_log off;
}
location /exception/ {
# empty block do nothing
# I've also tried adding "break;" here
}
return 301 https://localhost$request_uri;
}
Nginx finds the longest matching location and processes it first, but your return at the end of the server block was being processed regardless. This will redirect everything but /exception/ which is passed upstream.
server {
listen 127.0.0.1:80;
access_log off;
location / {
return 301 https://localhost$request_uri;
}
location /exception/ {
proxy_pass http://127.0.0.1:7080;
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-Accel-Internal /internal-nginx-static-location;
}
}

Resources