nginx rewrite rule not working - nginx

I want to redirect all traffic to HTTPS, except two locations for domain validation.
Here is my config:
server {
server_name xxxx.de www.xxxx.de;
# SSLMate domain validation
location /.well-known/pki-validation/ {
proxy_pass https://xxxx.http-approval.sslmate.com$request_uri;
proxy_set_header X-Forwarded-Host $http_host;
resolver 8.8.8.8;
}
location /.well-known/acme-challenge/ {
proxy_pass https://xxxx.http-approval.sslmate.com$request_uri;
proxy_set_header X-Forwarded-Host $http_host;
resolver 8.8.8.8;
}
# Redirect everything else to HTTPS
location / {
rewrite ^ https://xxxx.de/index.htm permanent;
}
}
Unfortunately everything is picked up by the rule for the "/" location. What am I doing wrong?

Related

Regex in nginx inside map

I cannot fix routing in nginx for different parts in URI . So if the request has URI starting with de it should pass the traffic to app_b. That does not happen and I'm getting error: invalid URL prefix in "http://"
Here's the config.
map $request_uri $resources_location {
"/" "app_a:1234/";
"^.*de.*$" "app_b:2345/";
}
server {
listen 80;
listen [::]:80;
server_name example.com;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header HOST $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://$resources_location;
proxy_redirect off;
}
location ~ ^/(assets|public|favicon.ico) {
proxy_pass http://$resources_location;
}
}
How that can be solved (also with a help of map)?

Permanent redirect while reverse proxying with nginx

I have setup an nginx reverse proxy server which proxy blog.xxx.com to xxx.com/blog. Here is my config file.
server {
listen 80;
root /var/www/html;
server_name xxx.com www.xxx.com;
location /.well-known/acme-challenge {
root /tmp/letsencrypt/www;
}
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443;
server_name xxx.com;
root /var/www/html;
include /etc/nginx/snippet/ssl.conf;
location /blog/ {
proxy_pass https://blog.xxx.com;
proxy_set_header Host blog.xxx.com;
rewrite /blog/(.*) /$1 break;
proxy_redirect off;
expires -1;
add_header Cache-Control no-store;
proxy_read_timeout 90;
proxy_connect_timeout 90;
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-NginX-Proxy true;
proxy_set_header Connection "";
}
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://xxx:8090;
}
}
It works just fine. But I need to have a permanent redirect on blog.xxx.com to xxx.com/blog as well. Once I set the redirect rule, a too many redirects situation happens.
Is there any way to have both reverse proxy and 301 redirect at the same time?
Do I understand correctly that the two sites mentioned are hosted in different places? If so, I would do a 303 redirect to your second page on the first page. If you don't have Nginx on the first page, you can probably do this in your blog software (or directly in HTML, PHP, etc.) To prevent endless redirection, you can rewrite them while sending them to the client:
https://serverfault.com/a/986034/304842

Problem with nginx location and proxy_pass

I have a rule in my nginx.conf that does not work and I have no idea why. According to the documentation it should work. Part of the config looks like this.
The first rule on port 8100 works and redirects the call http://example.com/api/domains to https://localhost:8181/oan/resources/domains
# Working
server {
listen 8100 default_server;
server_name example.com;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
root /var/www/html/example;
location /api {
proxy_pass https://localhost:8181/oan/resources; break;
}
# For ReactJS to handle routes
location / {
if (!-e $request_filename) {
rewrite ^(.*)$ / break;
}
}
}
# Not working
server {
listen 8200;
server_name api.example.com;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
location / {
proxy_pass https://localhost:8181/oan/resources; break;
}
}
The last call to port 8200: http://api.example.com:8200/domains SHOULD redirect to: https://localhost:8181/oan/resources/domains but does NOT do that.
What is wrong with this config and how can I get the last rule on port 8200 do the correct stuff, always redirect to https://localhost:8181/oan/resources/$uri
When you use proxy_pass with an optional URI within a prefix location block, Nginx will transform the requested URI by performing a straight text substitution.
In your case, the prefix location value is / and the optional URI value is /oan/resources. So a requested URI of /foo will be transformed into /oan/resourcesfoo.
For correct operation, both values should end with / or neither end with /.
For example:
location / {
proxy_pass https://localhost:8181/oan/resources/;
}
See this document for details.

How to rewrite the URL using nginx

I have a URL as
https://test.rockon.me/Profiles/XYZ-ABC-PQRS/default.aspx
now using nginx i have to write rules for creating a subdomain which can make the URL as https://XYZ-ABC-PQRS/test.rockon.me/Profiles/default.aspx here XYZ-ABC-PQRS is the username of some user.
server
{
access_log /var/log/nginx/subcalls.log;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
add_header Access-Control-Allow-Origin *;
listen 80;
server_name ~^(?<subdomain>.+)\nithinveer\.com$;
location /
{
proxy_pass http://192.168.6.190/Profiles/$subdomain$request_uri/;
}
Yours not working, probably because you expect $request_uri = /default.aspx which is not, it is actually, everything after subdomain i.e., /Profiles/user/default.aspx
Try this,
server {
server_name test.rockon.me;
rewrite ^/Profiles/(.*)/default.aspx http://$1/test.rockon.me/Profiles/default.aspx permanent;
}
The other option using proxy_pass can be,
server{
server_name test.rockon.me;
location / {
rewrite /Profiles/(.*)/(.*) /Profiles/$1/$2 break;
proxy_pass http://192.168.6.190;
}
}
Hope it helps. :)

How to configure Nginx to try two upstreams before 404ing?

Given an Nginx configuration roughly like this:
upstream A {
server aa:8080;
}
upstream B {
server bb:8080;
}
server {
listen 80;
location #backendA {
proxy_pass http://A/;
}
location #backendB {
proxy_pass http://B/;
}
location / {
# This doesn't work. :)
try_files #backendA #backendB =404;
}
}
Basically, I would like Nginx to try upstream A, and if A returns a 404, then try upstream B instead, and failing that, return a 404 to the client. try_files does this for filesystem locations, then can fall back to a named location, but it doesn't work for multiple named locations. Is there something that will work?
Background: I have a Django web application (upstream A) and an Apache/Wordpress instance (upstream B) that I would like to coexist in the same URL namespace for simpler Wordpress URLs: mysite.com/hello-world/ instead of mysite.com/blog/hello-world/.
I could duplicate my Django URLs in the Nginx locations and use wordpress as a catch-all:
location /something-django-handles/ {
proxy_pass http://A/;
}
location /something-else-django-handles/ {
proxy_pass http://A/;
}
location / {
proxy_pass http://B/;
}
But this violates the DRY principle, so I'd like to avoid it if possible. :) Is there a solution?
After further googling, I came upon this solution:
location / {
# Send 404s to B
error_page 404 = #backendB;
proxy_intercept_errors on;
log_not_found off;
# Try the proxy like normal
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://A;
}
location #backendB {
# If A didn't work, let's try B.
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://B;
# Any 404s here are handled normally.
}

Resources