saya bertanya-tanya apakah nginx dapat menangani permintaan http dan https di port yang sama . [*]
Inilah yang saya coba lakukan. Saya menjalankan server web (lighttpd) yang menangani permintaan http, dan program C yang melayani bagian tertentu dari pohon dokumen melalui https. Kedua proses ini berjalan di server yang sama.
Pada level firewall, saya hanya dapat memiliki satu port forwarding traffic ke server ini . Jadi yang ingin saya lakukan adalah mengatur nginx di server ini sehingga ia mendengarkan permintaan pada satu port dan kemudian:
A) mengarahkan ulang semua permintaan http://myhost.com/ * sehingga mereka pergi ke localhost: 8080 (di mana lighttpd mendengarkan)
B) jika pengguna meminta URL yang dimulai dengan, misalnya, https: // myhost.com/app, itu mengirimkan permintaan itu ke localhost: 8008 (program C). Perhatikan bahwa dalam hal ini, lalu lintas antara browser jarak jauh dan nginx harus dienkripsi.
Apakah Anda pikir ini mungkin? Jika ya, bagaimana itu bisa dilakukan?
Saya tahu cara melakukan ini menggunakan dua port yang berbeda. Tantangan yang saya hadapi adalah melakukan ini hanya dengan satu port (sayangnya, saya tidak memiliki kendali atas konfigurasi firewall pada lingkungan khusus ini, jadi itu adalah batasan yang tidak bisa saya hindari). Menggunakan teknik seperti membalikkan port fowarding melalui ssh untuk mem-bypass firewall tidak akan berhasil, karena ini harus bekerja untuk pengguna jarak jauh yang memiliki tidak lebih dari browser web dan tautan internet.
Jika ini di luar kemampuan nginx, apakah Anda tahu ada produk lain yang dapat memenuhi persyaratan ini? (Sejauh ini saya tidak berhasil dalam pengaturan ini dengan lighttpd dan pound). Saya juga lebih suka menghindari Apache (walaupun saya bersedia menggunakannya jika itu satu-satunya pilihan).
Terima kasih sebelumnya, Alex
[*] Untuk lebih jelasnya, saya berbicara tentang menangani koneksi HTTP terenkripsi dan tidak terenkripsi melalui port yang sama. Tidak masalah jika enkripsi dilakukan melalui SSL atau TLS.
Jawaban:
Menurut artikel wikipedia tentang kode status, Nginx memiliki kode kesalahan khusus ketika lalu lintas http dikirim ke port https (kode kesalahan 497)
Dan menurut nginx docs pada error_page , Anda dapat mendefinisikan URI yang akan ditampilkan untuk kesalahan tertentu.
Dengan demikian kita dapat membuat uri bahwa klien akan dikirim ketika kode kesalahan 497 dinaikkan.
nginx.conf
Namun jika klien membuat permintaan melalui metode lain selain GET, permintaan itu akan berubah menjadi GET. Dengan demikian untuk mempertahankan metode permintaan yang datang melalui klien; kami menggunakan pengalihan kesalahan pemrosesan seperti yang ditunjukkan dalam dokumen nginx pada error_page
Dan itulah sebabnya kami menggunakan
301 =307
pengalihan.Dengan menggunakan file nginx.conf yang ditampilkan di sini, kami dapat meminta http dan https mendengarkan pada port yang sama
sumber
Bagi mereka yang mungkin mencari:
Tambahkan
ssl on;
danerror_page 497 $request_uri;
ke definisi server Anda.sumber
ssl on;
danerror_page 497 =200 $request_uri;
ke definisi server Anda. Ini akan mengubah kode status menjadi 200.Jika Anda ingin benar-benar pintar, Anda dapat menggunakan proxy koneksi untuk mengendus beberapa byte pertama dari aliran data yang masuk, dan menyerahkan koneksi berdasarkan pada konten byte 0: jika 0x16 (SSL / TLS ' handshake 'byte), meneruskan koneksi ke sisi SSL, jika ini merupakan karakter alfabet, lakukan HTTP normal. Komentar saya tentang penomoran port berlaku .
sumber
Ya, itu mungkin, tetapi perlu menambal kode sumber nginx (HoverHell memiliki solusi tanpa menambal). Nginx memperlakukan ini sebagai kesalahan konfigurasi daripada konfigurasi yang valid.
Variabel $ ssl_session_id dapat digunakan untuk membedakan antara koneksi biasa dan ssl.
Patch terhadap nginx-0.7.65:
Konfigurasi server:
sumber
Saya tidak berpikir ada sesuatu yang dapat menangani dua protokol berbeda pada satu port ...
Saya ingin tahu mengapa Anda hanya dapat meneruskan satu port, tetapi selain itu ... itu tidak ideal tetapi jika saya berada di posisi Anda, saya akan melayani semuanya melalui https.
sumber
Anda tidak dapat mendukung HTTP dan HTTPS melalui port yang sama, karena kedua ujung koneksi mengharapkan untuk berbicara bahasa tertentu, dan mereka tidak cukup pintar untuk bekerja jika ujung yang lain berbicara sesuatu yang lain.
Seperti komentar Anda untuk jawaban Wil menyarankan, Anda dapat menggunakan upgrade TLS (saya percaya rilis nginx yang lebih baru mendukungnya, meskipun saya belum mencoba), tetapi itu tidak menjalankan HTTP dan HTTPS, itu hanya menjalankan HTTP dengan upgrade TLS. Masalahnya masih dukungan browser - sebagian besar browser (masih) tidak mendukungnya. Jika Anda memiliki sekelompok klien yang terbatas, maka ini adalah kemungkinan.
sumber
Saya tidak yakin bagaimana itu berhasil, tetapi CUPSD merespons baik http maupun https pada port 631. Jika nginx tidak dapat melakukannya sekarang, mungkin mereka dapat belajar dari bagaimana tim CUPS menariknya, tetapi CUPS berada di bawah GPL, jadi nginx mungkin harus melihat mengubah lisensinya jika mereka ingin menerapkan kemampuan seperti itu dan tidak dapat menemukan kode untuk melakukannya di tempat lain.
sumber
Secara teori, Anda dapat memiliki halaman web yang dapat diakses melalui HTTP, yang dapat membuka WebSocket di https: 443 ke mana saja yang diinginkan. Jabat tangan awal WebSocket adalah HTTP. Jadi, ya, dimungkinkan untuk membuat halaman yang terlihat tidak aman benar-benar mampu komunikasi yang aman. Anda bisa melakukan ini dengan Perpustakaan Netty .
sumber
Ini akhirnya mungkin dilakukan dengan benar sejak 1.15.2. Lihat informasinya di sini .
Di nginx.conf Anda, tambahkan blok seperti ini (di luar blok http):
Kemudian Anda dapat membuat blok server normal, tetapi mendengarkan pada port yang berbeda ini:
Dengan cara ini, blok stream dapat membaca dan mendeteksi apakah itu TLS atau tidak (pada port 8080 dalam contoh ini), dan kemudian proksi meneruskannya ke port server yang benar secara lokal.
sumber