Nginx Proxy ile Yönlendirme, URL'yi Yeniden Yazma ve Koruma


71

Nginx’de bir URL’yi aşağıdaki gibi yönlendirmeye çalışıyoruz:

http://example.com/some/path -> http://192.168.1.24

Kullanıcının, orijinal URL’yi hala tarayıcılarında gördüğü Kullanıcı yönlendirildiğinde, bağlantıyı tıkladıklarını söyleyin, bunun yönlendirmeye yönlendiren /section/index.htmlbir istek yapmasını isteriz

http://example.com/some/path/section/index.html -> http://192.168.1.24/section/index.html

ve yine orijinal URL’yi koru.

Denemelerimiz proxy'ler ve yeniden yazma kuralları kullanan çeşitli çözümler içeriyordu ve aşağıda bizi bir çözüme en yakın hale getiren yapılandırma gösteriliyor (bunun web sunucusu için web sunucusu yapılandırması olduğuna dikkat edin example.com). Ancak, bununla ilgili hala iki sorun var:

  • Web sunucusundan alınan istek URL’si http://192.168.1.24içerdiğinden /some/pathve bu nedenle gerekli sayfayı sunamadığından, yeniden yazma işlemini doğru şekilde yapmaz .
  • Bir sayfa sunulduktan sonra bir linke /some/pathgeldiğinizde, URL’de eksik

    server {
        listen          80;
        server_name     www.example.com;
    
        location /some/path/ {
            proxy_pass http://192.168.1.24;
            proxy_redirect http://www.example.com/some/path http://192.168.1.24;
            proxy_set_header Host $host;
        }
    
        location / {
            index index.html;
            root  /var/www/example.com/htdocs;
        }
    }
    

Yalnızca web sunucusu yapılandırmasını değiştirmeyi içeren bir çözüm arıyoruz example.com. Yapılandırma'yı 192.168.1.24(Nginx) de değiştirebiliyoruz , ancak bunu denemek ve önlemek istiyoruz, çünkü bu kurulumu, erişiminin sağlandığı yüzlerce farklı sunucu için tekrarlamamız gerekecek example.com.

Yanıtlar:


59

İlk olarak, rootkonum bloğunun içinde yönergeyi kullanmamalısınız , bu kötü bir uygulamadır. Bu durumda önemli değil.

İkinci bir konum bloğu eklemeyi deneyin:

location ~ /some/path/(?<section>.+)/index.html {
    proxy_pass http://192.168.1.24/$section/index.html;
    proxy_set_header Host $host;
}

Bu, / some / path / sonrasındaki ve index.html'den önceki kısmı $ section değişkenine yakalar, bu daha sonra proxy_pass hedefini ayarlamak için kullanılır. İhtiyacınız olursa, regex'i daha spesifik hale getirebilirsiniz.


1
Geç cevap için özür dilerim - bu aradığımız şeyi başarmaya çok yakın. Tek eksiklik, hedef sayfa sunulduktan sonra, tarayıcıdaki linklerin URL'lerinin '/ some / path /' içermediği, yani bir kullanıcı tıkladığında çalışmadığı anlamına gelir. Bunun üstesinden nasıl gelinebilirsek, bu cevabı güncelleyeceğim ve kabul edeceğim, neredeyse orada.
robjohncox

8
Tarayıcının gördüğü bağlantılar, 192.168.1.24 sunucusunda çalışan yazılım tarafından oluşturulur. İstediğinizi elde etmek için bu yazılımı değiştirmelisiniz.
Tero Kilkanen

Konum bloğu içindeki kök hakkındaki uyarınızı izlediğimden emin değilim. nginx dokümantasyonunu okumak, bir şeyler yapmanın doğru yoludur. yalnızca kötü uygulamaları, tüm konumların dışında varsayılan bir kök kullanmamaları konusunda uyarırlar. nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/…
guy mograbi

Eh, rootbir locationbloğun içinde kullanmama kuralına uymak daha kolaydır , o zaman varsayılan konumlar için beklenmeyen bir davranış elde edemezsiniz. Yalnızca roother konum için varsayılanı değiştirmeniz gerekirse, onu kullanabilirsiniz.
Tero Kilkanen

1
$ Host ismini almakla neyi kastediyorsunuz ? Tam olarak gönderilen HTTP üstbilgisi nedir ve tam olarak ne gönderilmesini istiyorsunuz?
Tero Kilkanen

65

URI bölümünü proxy_passyönergede kullanmalısınız . Ayrıca, proxy_redirectdirektifin argümanlarını düzenlediniz, ve muhtemelen buna hiç ihtiyacınız yok. Nginx'in bu direktif için makul bir varsayılanı vardır.

Bu durumda, locationbloğunuz gerçekten basit olabilir:

location /some/path/ {
    proxy_pass http://192.168.1.24/;
    # note this slash  -----------^
    proxy_set_header Host $host;
}

1
Geç cevap için özür dilerim - Bunu denedim ve ne yazık ki kullanım durumumuz için işe yaramadı. Sorun, istek hedef sunucuda yapıldığında /some/path/, URL’nin bir kısmının geçerli bir URL olmayan istekte korunmasıdır (bunu kaldırmak için URL’yi de yeniden yazmamız gerekir).
robjohncox

@robjohncox tam olarak ne denediniz?
Alexey Ten

9
eğik çizgi benim için hile yaptı. Şimdi etkialanim.com/some/path/* doğru olarak 192.168.1.24/*
proxy'lerine

7
Bu yanıttaki "# bu eğikliği not et" yorumunu değiştirebilir miyim? Bu yorum için üç alkış!
06-12

Bunun hepiniz için nasıl çalıştığından emin değilim. Ben bunu başarmaya çalışıyorum. Ancak, bir kullanıcı yerel hizmette örneğin 192.168.1.24/login'e yönlendiren bir bağlantıyı tıklattığında, o
alanım.com.tr/some/path/login

4

/some/path/Ön uç ve /arka uç arasında% 100 kesintisiz eşleme yapmak için aşağıdaki yapılandırmayı kullanabilirsiniz .

404 Not FoundDoğru HTTP Refererbaşlığının tarayıcı tarafından gönderilmesi şartıyla, hatalar oluşturan kesin yollara da dikkatle bakacak tek cevabın bu olduğuna dikkat edin. (yalnızca pahalı değil, aynı zamanda varsayılan olarak derlenmemiş ek modüller olmadan da desteklenmez).

location /some/path/ {
    proxy_pass http://192.168.1.24/; # note the trailing slash!
}
location / {
    error_page 404 = @404;
    return 404; # this would normally be `try_files` first
}
location @404 {
    add_header Vary Referer; # sadly, no effect on 404
    if ($http_referer ~ ://[^/]*(/some/path|/the/other)/) {
        return 302 $1$uri;
    }
    return 404 "Not Found\n";
}

Sen bulabilirsiniz komple kanıtı kavramını ve minimal-canlı-ürün içinde https://github.com/cnst/StackOverflow.cnst.nginx.conf depo.

İşte tüm kenar kasalarının işe yaradığını belirten bir deneme çalışması:

curl -v -H 'Referer: http://example.su/some/path/page.html' localhost:6586/and/more.gif | & fgrep -e HTTP/ -e Referer -e Location
> GET /and/more.gif HTTP/1.1
> Referer: http://example.su/some/path/page.html
< HTTP/1.1 302 Moved Temporarily
< Location: http://localhost:6586/some/path/and/more.gif
< Vary: Referer

curl -v localhost:6586/and/more.gif | & fgrep -e HTTP/ -e Referer -e Location
> GET /and/more.gif HTTP/1.1
< HTTP/1.1 404 Not Found

curl -v localhost:6586/some/path/and/more.gif | & fgrep -e HTTP/ -e Referer -e Location -e uri
> GET /some/path/and/more.gif HTTP/1.1
< HTTP/1.1 200 OK
request_uri:    /and/more.gif

PS Eğer haritalanacak çok farklı yolunuz varsa, o zaman $http_refererbir ifiçindeki regex karşılaştırması yapmak yerine, bunun yerine location @404global-tabanlı mapyönergeyi kullanmak isteyebilirsiniz .

Ayrıca sondaki hem de eğik olduğuna dikkat proxy_passyanı sıra, locationbu bulunur, ilgili Yanıt başına kadar oldukça önemlidir .

Referanslar:


2

Bu eğik çizgi nginx proxy'li jenkinlere eklendiğinde, “Ters proxy kurulumunuz bozuldu gibi görünüyor” hatasıyla karşılaşıyorsunuz.

proxy_pass          http://localhost:8080/;

Remove this -----------------------------^

Okumalı

proxy_pass          http://localhost:8080;

OP'nin sorusunun bununla ilgili olduğunu ya da belirtilen sorunların hiçbiri ile ilgili olduğunu sanmıyorum.
Cory Robinson
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.