Saya ingin menulis ulang semua permintaan http di server web saya menjadi permintaan https, saya mulai dengan yang berikut:
server { dengarkan 80; lokasi / { menulis ulang ^ (. *) https: //mysite.com$1 permanen; } ...
Satu Masalahnya adalah bahwa ini menghapus informasi subdomain (mis., Node1.mysite.com/folder), bagaimana saya bisa menulis ulang di atas untuk mengubah rute semuanya menjadi https dan mempertahankan sub-domain?
Jawaban:
Cara yang benar dalam versi nginx baru
Ternyata jawaban pertama saya untuk pertanyaan ini benar pada waktu tertentu, tetapi itu berubah menjadi jebakan lain - untuk tetap up to date silakan periksa Perpajakan penulisan ulang perangkap
Saya telah dikoreksi oleh banyak pengguna SE, jadi kredit diberikan kepada mereka, tetapi yang lebih penting, ini adalah kode yang benar:
sumber
$host
alih-alih$server_name
jika Anda menggunakan subdomain.CATATAN: Cara terbaik untuk melakukan ini disediakan oleh https://serverfault.com/a/401632/3641 - tetapi diulangi di sini:
Dalam kasus yang paling sederhana, host Anda akan diperbaiki untuk menjadi layanan yang ingin Anda kirimi mereka - ini akan melakukan pengalihan ke browser dan URL browser akan diperbarui sesuai dengan itu.
Di bawah ini adalah jawaban sebelumnya, yang tidak efisien karena regex, 301 sederhana sangat bagus seperti yang ditunjukkan oleh @kmindi
Saya telah menggunakan nginx 0.8.39 ke atas, dan menggunakan yang berikut:
Mengirim redirect permanen ke klien.
sumber
Saya pikir cara terbaik dan satu-satunya harus menggunakan HTTP 301 Moved redirect secara permanen seperti ini:
The HTTP 301 Moved Permanently redirect juga yang paling efisien karena tidak ada regex untuk dievaluasi, menurut yang telah disebutkan pitfails .
Baru HTTP 308 Moved Permanently mempertahankan metode Permintaan dan didukung oleh browser utama . Misalnya, menggunakan
308
mencegah browser mengubah metode permintaan dariPOST
menjadiGET
untuk permintaan pengalihan.Jika Anda ingin mempertahankan nama host dan subdomain, inilah caranya.
Ini masih berfungsi jika Anda tidak memiliki DNS , karena saya juga menggunakannya secara lokal. Saya meminta misalnya dengan
http://192.168.0.100/index.php
dan akan diarahkan ke tepathttps://192.168.0.100/index.php
.Saya menggunakan
listen [::]:80
pada host saya karena saya telahbindv6only
menetapkan untukfalse
, sehingga juga mengikat socket ipv4. ubah kelisten 80
jika Anda tidak ingin IPv6 atau ingin mengikat di tempat lain.Solusi dari Saif Bechan menggunakan
server_name
yang dalam kasus saya adalah localhost tetapi itu tidak dapat dijangkau melalui jaringan.Solusi dari Michael Neale bagus, tetapi menurut pitfail, ada solusi yang lebih baik dengan redirect 301;)
sumber
Dalam blok server Anda juga dapat melakukan hal berikut:
sumber
Di atas tidak berfungsi dengan subdomain baru yang dibuat setiap saat. misalnya AAA.example.com BBB.example.com untuk sekitar 30 subdomain.
Akhirnya ada konfigurasi yang bekerja dengan yang berikut:
sumber
301 https://*/
atau membatalkan permintaan sebelum waktunya di jawaban lain di sini.server_name _;
dengan$host
adalah jawaban yang berhasil. +1_
dengan domain yang sebenarnya, misalnya.domain.com
saya punya dua server, dan nginx secara tidak sengaja mengarahkan salah satu server saya ke server default.Saya mengirim komentar pada jawaban yang benar sejak dulu, dengan koreksi yang sangat penting, tetapi saya merasa perlu untuk menyoroti koreksi ini dalam jawabannya sendiri. Tidak satu pun dari jawaban sebelumnya yang aman digunakan jika pada suatu saat Anda memiliki HTTP yang tidak aman diatur dan mengharapkan konten pengguna, memiliki formulir, host API, atau telah mengkonfigurasi situs web, alat, aplikasi, atau utilitas untuk berbicara ke situs Anda.
Masalah terjadi ketika
POST
permintaan dibuat ke server Anda. Jika respons server dengan30x
pengalihan polos , konten POST akan hilang. Apa yang terjadi adalah bahwa browser / klien akan meningkatkan permintaan untuk SSL tapi downgrade yangPOST
keGET
permintaan. ThePOST
parameter akan hilang dan permintaan yang salah akan dibuat ke server Anda.Solusinya sederhana. Anda perlu menggunakan
HTTP 1.1 307
arahan ulang. Ini dirinci dalam RFC 7231 S6.4.7:Solusinya, diadaptasi dari solusi yang diterima, adalah untuk digunakan
307
dalam kode pengalihan Anda:sumber
Saya berhasil melakukannya seperti ini:
https://stackoverflow.com/a/36777526/6076984
sumber
Saya menjalankan ngnix di belakang AWS ELB. ELB sedang berbicara dengan ngnix melalui http. Karena ELB tidak memiliki cara untuk mengirim arahan ulang ke klien, saya memeriksa header X-Forwarded-Proto dan mengarahkan ulang:
sumber
Jika Anda
return 301 https://$host$request_uri;
sebagai respons default pada port 80, maka server Anda cepat atau lambat akan masuk dalam daftar proxy terbuka [1] dan mulai disalahgunakan untuk mengirim lalu lintas ke tempat lain di Internet. Jika log Anda diisi dengan pesan seperti ini, maka Anda tahu itu terjadi pada Anda:Masalahnya adalah bahwa
$host
akan mengulang kembali apa pun yang dikirim browser diHost
header atau bahkan nama host dari baris pembuka HTTP, seperti ini:Karena masalah itu, beberapa jawaban lain di sini merekomendasikan menggunakan
$server_name
bukan$host
.$server_name
selalu mengevaluasi apa yang Anda masukkan dalamserver_name
deklarasi. Tetapi jika Anda memiliki beberapa subdomain di sana atau menggunakan wildcard, itu tidak akan berhasil, karena$server_name
hanya menggunakan entri pertama setelahserver_name
deklarasi, dan yang lebih penting hanya akan menggemakan kembali wildcard (tidak memperluasnya).Jadi bagaimana cara mendukung banyak domain sambil menjaga keamanan? Pada sistem saya sendiri, saya telah menangani dilema ini dengan terlebih dahulu mendaftar
default_server
blok yang tidak digunakan$host
, dan kemudian daftar blok wildcard yang:(Anda juga bisa mencantumkan lebih dari satu domain di blok kedua.)
Dengan kombinasi itu, domain yang tidak cocok akan dialihkan ke tempat yang di-hardcode (selalu
example.com
), dan domain yang cocok dengan domain Anda akan menuju ke tempat yang tepat. Server Anda tidak akan berguna sebagai proxy terbuka, sehingga Anda tidak akan menarik masalah.Jika Anda merasa sulit, saya kira Anda juga bisa membuat
default_server
blok tidak cocok dengan domain Anda yang sah dan menyajikan sesuatu yang menyinggung. . . .[1] Secara teknis "proxy" adalah kata yang salah, karena server Anda tidak keluar dan memenuhi permintaan untuk klien, hanya mengirim redirect, tetapi saya tidak yakin apa kata yang tepat. Saya juga tidak yakin apa tujuannya, tetapi mengisi log Anda dengan noise dan menghabiskan CPU dan bandwidth Anda, jadi sebaiknya Anda menghentikannya.
sumber
Sepertinya tidak ada yang benar-benar mendapatkannya 100% benar. Untuk meminta permintaan port 80 pergi ke 443 ekuivalennya untuk seluruh server web, Anda perlu menggunakan directive listen , bukan directive server_name untuk menentukan nama catch-all . Lihat juga https://nginx.org/en/docs/http/request_processing.html
Dan pastikan Anda memeriksa apa yang sudah ada di /etc/nginx/conf.d/ karena lebih sering saya tidak memiliki masalah di mana default.conf mengembalikan beberapa vhost yang ada. Pesanan saya untuk mengatasi masalah nginx selalu dimulai dengan memindahkan file default, mengembalikannya mengomentari baris demi baris untuk melihat kesalahannya.
sumber
sumber