Soru Nginx ile tek bir bağlantı noktasını kullanarak http ve https isteklerini işleme


nginx'in http ve https isteklerini ele alıp alamayacağını merak ediyordum aynı limanda. [*]

Yapmaya çalıştığım şey bu. Http isteklerini işleyen bir web sunucusu (lighttpd) ve https aracılığıyla belge ağacının belirli bir bölümüne hizmet eden bir C programı çalıştırıyorum. Bu iki işlem aynı sunucuda çalışır.

Güvenlik duvarı düzeyinde Bu sunucuya sadece bir tane yönlendirme trafiği trafiği olabilir. Yani yapmak istediğim, bu sunucuda nginx'i kurmak ve böylece tek bir bağlantı noktasındaki istekleri dinlemektir:

A) tüm yönlendirir http://myhost.com/* istekleri localhost'a gider: 8080 (lighttpd dinliyor)

B) Bir kullanıcı, örneğin https: // myhost.com/app ile başlayan bir URL isterse, bu isteği localhost: 8008 (C programı) olarak gönderir. Bu durumda, uzak tarayıcı ile nginx arasındaki trafiğin şifrelenmesi gerektiğini unutmayın.

Bunun mümkün olabileceğini düşünüyor musunuz? Öyleyse, nasıl yapılabilir?

Bunu iki farklı port kullanarak nasıl yapacağımı biliyorum. Karşılaştığım zorluk sadece tek bir portla bunu yapıyor (maalesef bu özel ortamdaki güvenlik duvarı konfigürasyonu üzerinde kontrole sahip değilim, bu yüzden kaçınamayacağım bir kısıtlama). Güvenlik duvarı baypas etmek için ssh üzerinden ters port fowarding gibi tekniklerin kullanılması işe yaramaz, çünkü bu, uzak kullanıcılar için bir web tarayıcısından ve bir internet bağlantısından başka bir şey içermemelidir.

Bu, nginx özelliklerinin ötesindeyse, bu gereksinimleri karşılayabilecek başka bir ürünü biliyor musunuz? (şimdiye kadar bunu lighttpd ve pound ile kurmakta başarısız oldum). Ayrıca Apache'den kaçınmayı tercih ederim (ancak mümkün olan tek seçenekse kullanmaya razıyım).

Şimdiden teşekkürler, Alex

[*] Sadece açık olmak gerekirse, şifreli işlemden bahsediyorum ve Aynı bağlantı noktasından şifrelenmemiş HTTP bağlantıları. Şifrelemenin SSL veya TLS yoluyla yapılması önemli değildir.


13
2017-07-30 02:58


Menşei


HTTPS istekleri varsayılan olarak 443 numaralı bağlantı noktasına gider, bu nedenle bu çalışmayı (hatta biraz korsanlıkla mümkün olabileceğini düşünüyorum) bile kullanabilmeniz gerekir. yourhost.com ve yourhost.com:80 bağlantılar olarak (veya yourhost.com:443 ve yourhost.com). - Zanchey
Tamam, Sunucu Arızasında yeniyim ve kendi sorumu silip atamayacağımı bilmiyorum. Sorun yeterince açık bir şekilde formüle edilmediğinden, bunun yerine yeni bir soru açacağım. Her neyse, bu konuyla ilgili yararlı önerilerde bulunan herkese çok teşekkürler. - alemartini


Cevaplar:


Arayanlar için:

Eklemek ssl on; ve error_page 497 $request_uri; sunucu tanımınıza.


13
2018-04-07 15:09



HoverHells için küçük iyileştirme cevap: Ekle ssl on; ve error_page 497 =200 $request_uri; sunucu tanımınıza. Bu durum kodunu 200 olarak değiştirecektir. - Mawi12345
Bu servis arızası Cevap Bu çözümün neden işe yarayacağını açıklar. - SiliconMind


Durum kodları hakkındaki wikipedia makalesine göre, Nginx'in http trafiği https bağlantı noktasına gönderildiğinde özel hata kodu vardır (hata kodu 497)

Ve göre error_page üzerinde nginx dokümanlarBelirli bir hata için gösterilecek bir URI tanımlayabilirsiniz.
Böylece, hata kodu 497 yükseltildiğinde istemcilerin gönderileceği bir uri oluşturabiliriz.

nginx.conf

#lets assume your IP address is 89.89.89.89 and also that you want nginx to listen on port 7000 and your app is running on port 3000

server {
    listen 7000 ssl;

    ssl_certificate /path/to/ssl_certificate.cer;
    ssl_certificate_key /path/to/ssl_certificate_key.key;
    ssl_client_certificate /path/to/ssl_client_certificate.cer;

    error_page 497 301 =307 https://89.89.89.89:7000$request_uri;

    location / {
        proxy_pass http://89.89.89.89:3000/;

        proxy_pass_header Server;
        proxy_set_header Host $http_host;
        proxy_redirect off;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Protocol $scheme;
    }
}

Ancak, bir müşteri bir GET dışında başka bir yöntemle istekte bulunursa, bu istek bir GET'e dönüştürülür. Böylece müşterinin istediği istek yöntemini korumak için; gösterildiği gibi hata işleme yönlendirmelerini kullanıyoruz error_page üzerinde nginx dokümanlar

Ve bu yüzden neden kullanıyoruz 301 =307 yönlendirir.

Burada gösterilen nginx.conf dosyasını kullanarak, aynı bağlantı noktasında http ve https dinleyebiliyoruz.


12
2018-02-04 13:59





Gerçekten akıllı olmak istiyorsanız, gelen veri akışının ilk çift baytını koklamak ve bağlantıyı bayt 0 içeriğine göre kapatmak için bir bağlantı proxy'si kullanabilirsiniz: eğer 0x16 ise (SSL / TLS) el sıkışma 'bayt', bağlantıyı SSL tarafına iletin, eğer alfabetik bir karakterse, normal HTTP yapın. Port numaralandırma hakkındaki yorumum geçerlidir.


4
2017-07-30 05:58





Evet, bu mümkündür, ancak nginx kaynak kodunu yamaya ihtiyaç duyar (HoverHell'in yama olmadan çözümü vardır). Nginx bunu yanlış yapılandırma olarak değil, daha sonra geçerli yapılandırma olarak değerlendirir.

Değişken $ ssl_session_id, düz ve ssl bağlantısı arasında farklılık göstermek için kullanılabilir.

Nginx-0.7.65'e karşı yama:

--- src/http/ngx_http_request.c-orig    2011-05-03 15:47:09.000000000 +0200
+++ src/http/ngx_http_request.c 2011-05-03 15:44:01.000000000 +0200
@@ -1545,12 +1545,14 @@

    c = r->connection;

+    /* disable plain http over https port warning
     if (r->plain_http) {
         ngx_log_error(NGX_LOG_INFO, c->log, 0,
                       "client sent plain HTTP request to HTTPS port");
         ngx_http_finalize_request(r, NGX_HTTP_TO_HTTPS);
         return;
     }
+    */

#if (NGX_HTTP_SSL)

Sunucu yapılandırması:

server {
    listen 80;
    index index.html;

    location / {
        root html;
        if ($ssl_session_id) {
            root html_ssl;
        }
    }

    ssl on;
    ssl_certificate cert.crt;
    ssl_certificate_key cert.key;
}

2
2018-05-03 14:31





Tek bir portta iki farklı protokolü halledebilecek bir şey olduğunu düşünmüyorum ...

Neden sadece bir limanı yönlendirebileceğinizi merak ediyorum ama bir kenara ... bu ideal değil, ama ben senin ayakkabının içinde olsaydım, https üzerinden herşeyi yaparım.


1
2017-07-30 03:25



Merhaba Wil ve cevabınız için teşekkürler! Bunu, https üzerinden her şeye hizmet etmenin bir seçenek olabileceğini düşünüyorum, ancak bunu anlattığım şekilde ayarlayabilmek istiyorum. Belki bu, ön web sunucusu (ters proxy gibi davranan) normal bir http oturumu kurabilir ve daha sonra portları değiştirmeden https'e yükseltebilirse yapılabilir. Bu davranışın RFC2817'de (HTTP / 1.1 ile TLS'ye yükseltme) açıklandığını düşünüyorum, ancak nginx veya diğer web sunucularının bu standartla nasıl başa çıkılacağını bildiğinden emin değilim. - alemartini
Bütün bir RFC'yi okumak için zamanım yok (ve bunu anlamak için yeterince akıllı olduğumdan emin değilim!) Fakat güvenli oturumun kurulmasından veya tam olarak farklı oturumlardan önce standart müzakereden mi bahsediyorsunuz? Sanırım biraz daha anlıyorum - sunucu iki bağlantı noktasında hizmet veriyor ve bu istekleri ifade eden bir proxy - sesler harika ama hiç görmedim. Belki de bir çözüm, tek bir bağlantı noktasında tek bir güvenli site oluşturarak ve diğer web sitesini basitçe devralan / içe aktaran bir sanal dizine sahip olmakla olabilir. Tüm meseleleri aşmaz, ancak sadece işe yarayabilir: S - William Hilsum


Aynı bağlantı noktası üzerinden hem HTTP hem de HTTPS'yi destekleyemezsiniz, çünkü bağlantının her iki ucu da belirli bir dili konuşmayı bekler ve diğer uç başka bir şey konuşuyorsa yeterince çalışacak kadar zeki değildirler.

Wil'in cevabını önerdin, could TLS yükseltmesini kullan (daha yeni nginx sürümlerinin bunu desteklememesine rağmen, desteklemesine rağmen), ancak bu HTTP ve HTTPS'yi çalıştırmıyor, bu sadece TLS yükseltmesiyle HTTP kullanıyor. Sorun hala tarayıcı desteği - çoğu tarayıcı (hala) desteklemiyor. Sınırlı sayıda müşteriniz varsa, bu bir olasılıktır.


1
2017-07-30 04:24



Şifrelenmiş ve şifrelenmemiş HTTP trafiği, tek bir port üzerinden ele alınabilir. Nginx veya ters proxy gibi davranan diğer ürünler (lighttpd gibi) kullanarak bu mümkün değilse, bilmek istiyorum. Muhtemelen bu tür bir kurulum Apache tarafından ele alınabilir, fakat asıl soruda Apache'yi kullanmayı tercih etmemi tercih ettim (Linux'ta başka bir seçenek yoksa bunu yapsam da) Bunu başarmak için platform. - alemartini
Benim cevabımda dediğim gibi, "Ben denemedim rağmen, daha yeni nginx sürüm desteği [TLS yükseltme] inanıyorum". El kitabını okumak için bana ihtiyacın olursa, o zaman şansın yok demektir. - womble♦
Benim için bir kılavuzu okumak için birine ihtiyacım olduğu izlenimini verdiysem özür dilerim. Görünüşe göre, problem (ve onun hakkındaki sorular) tam olarak (benim hatam) yeterince açıklanmamıştı, ne istediğime ya da ihtiyaç duyduğumun farklı yorumlara yol açıyordu. Bu yüzden bu konuyla ilgili yeni bir soru açmaya karar verdim ve problemle ya da bu konuyla ilgili özel sorularla ilgili olası karışıklıklardan kaçınmaya çalıştım. Her neyse, zaman ayırdığınız için ve içgörünüzü paylaştığınız için teşekkürler. - alemartini


Bunu nasıl gerçekleştirdiğinden emin değilim, fakat CUPSD, hem http hem de http://support.google.com/support/ adresinde http://support.microsoft.com/downloads/default.html adresinde yanıt veriyor. Eğer nginx bunu şimdi yapamıyorsa, belki de CUPS ekibinin bunu nasıl çekeceğini öğrenebilirler, ancak CUPS GPL, bu nedenle, böyle bir yeteneği uygulamak istiyorsa ve başka bir yerde bunu yapmak için kodu bulamazsa, nginx lisansını değiştirmeye bakmak zorunda kalabilir.


0
2017-11-20 18:20





Teorik olarak, HTTP üzerinden erişilebilen bir web sayfanız olabilir. WebSocket https: 443 üzerinde istediği her yere. WebSocket ilk el sıkışma HTTP'dir. Yani, evet, aslında güvenli iletişim yeteneğine sahip güvensiz görünümlü bir sayfa yapmak mümkündür. Bunu ile yapabilirsin Netty Kütüphanesi.


0
2018-01-05 23:58