Alihkan semua permintaan http di belakang Amazon ELB ke https tanpa menggunakan if

27

Saat ini saya memiliki ELB yang melayani http://www.example.org dan https://www.example.org .

Saya ingin mengaturnya sehingga permintaan apa pun yang mengarah ke http://www.example.org dialihkan ke https://www.example.org .

ELB mengirimkan permintaan https sebagai permintaan http, jadi menggunakan:

server {
      listen         80;
       server_name    www.example.org;
       rewrite        ^ https://$server_name$request_uri? permanent;
}

tidak akan berfungsi karena permintaan yang dibuat ke https://www.example.org masih akan dilakukan ke port 80 di nginx.

Saya tahu mungkin untuk menulis ulang sebagai

server {
      listen         80;
      server_name    www.example.org;
      if ($http_x_forwarded_proto != "https") {
          rewrite ^(.*)$ https://$server_name$1 permanent;
      }
}

Tetapi semua yang saya baca mengatakan bahwa ifharus dihindari di semua biaya dalam konfigurasi nginx, dan ini akan untuk setiap permintaan tunggal. Juga, itu berarti saya harus mengatur konfigurasi terpisah khusus untuk pemeriksaan kesehatan ( seperti dijelaskan di sini : "... ketika Anda berada di belakang ELB, di mana ELB bertindak sebagai titik akhir HTTPS dan hanya mengirim lalu lintas HTTP ke server Anda, Anda mematahkan kemampuan untuk merespons dengan respons HTTP 200 OK untuk pemeriksaan kesehatan yang dibutuhkan ELB ").

Saya mempertimbangkan untuk memasukkan login ke dalam kode aplikasi web daripada konfigurasi nginx (dan untuk keperluan pertanyaan ini mari kita asumsikan itu adalah aplikasi berbasis Django), tetapi saya tidak yakin apakah itu akan lebih mahal daripada yang if di konfigurasi.

Jordan Reiter
sumber
Hai, bisakah Anda memberi tahu saya di mana Anda meletakkan kode ini?
YuAn Shaolin Maculelê Lai
@ YuAnShaolinMaculelêLai Sure. Ini adalah file konfigurasi untuk nginx, jadi saya hanya memasukkan kode dalam file di /etc/nginx/conf.d/. Saya biasanya memberi nama file domainname.conf di mana "domainname" adalah domain situs web yang dimaksud. Anda dapat memberi nama file apa pun yang Anda inginkan asalkan berakhir dengan .conf.
Jordan Reiter
Terima kasih banyak. Saya mencoba membuat file baru yang diikuti oleh .conf. Tetapi itu tidak berhasil untuk saya. Lalu saya memasukkan kode ke file yang dihasilkan dari AWS di /etc/nginx/conf.d/. Ini berfungsi sekarang.
YuAn Shaolin Maculelê Lai

Jawaban:

9

Jika itu berfungsi dengan benar seperti itu, jangan takut. http://wiki.nginx.org/IfIsEvil

Penting untuk dicatat bahwa perilaku if tidak tidak konsisten, mengingat dua permintaan yang identik tidak akan gagal secara acak pada satu dan bekerja pada yang lain, dengan pengujian dan pemahaman yang tepat jika dapat digunakan . Saran untuk menggunakan arahan lain di mana tersedia masih sangat berlaku.

ceejayoz
sumber
Halaman ini juga mengatakan bahwa "jika memiliki masalah ketika digunakan dalam konteks lokasi". Sepertinya saya bisa melakukan apa yang perlu dilakukan di luar location {}, server {}sebagai gantinya. (Tapi tolong beri tahu saya jika ini salah!)
Excalibur
15
  1. Atur pemetaan AWS ELB Anda ELB: 80 menjadi contoh: 80 dan ELB: 443 sebagai contoh: 1443.
  2. Ikat nginx untuk mendengarkan pada port 80 dan 1443.
  3. Permintaan penerusan tiba di port 80 ke port 443.
  4. Pemeriksaan kesehatan harus HTTP: 1443. Ia menolak HTTP: 80 karena 301 redirect.

pengaturan aws elb

Pengaturan NGINX

    server {
       listen         80;
       server_name    www.example.org;
       rewrite        ^ https://$server_name$request_uri? permanent;
    }

    server {
       listen         1443;
       server_name    www.example.org;
   } 
nu everest
sumber
bagaimana dengan pengaturan pemeriksaan kesehatan? bisa tolong jelaskan tentang itu juga.
samkhan13
ini tidak bekerja dengan cek helth diatur ke http: 80, pemeriksaan kesehatan gagal.
samkhan13
2
Pemeriksaan kesehatan seharusnya HTTP:1443. Ia menolak HTTP:80karena 301 redirect.
cbron
ini sebagian besar bekerja untuk saya tetapi baris penulisan ulang tidak berfungsi dengan domain wildcard saya. Posting lain ini memperbaiki bagian itu: serverfault.com/questions/447258/…
Ron
9

Solusi ini menggunakan logika kondisional, tetapi seperti jawaban yang diterima menyarankan, saya juga berpikir ini ok. Ref: /programming/4833238/nginx-conf-redirect-multiple-conditions

Juga, ini tidak memerlukan pembukaan port tambahan dalam pengaturan keamanan aws untuk gambar. Anda dapat menghentikan ssl di AWS LB, dan merutekan lalu lintas https ke http port 80 atas contoh Anda.

Dalam contoh ini, pemeriksaan kesehatan LB mengenai kesehatan di port 80 yang merutekan ke server aplikasi, jadi pemeriksaan kesehatan memvalidasi nginx dan aplikasi Anda bernafas.

server {
  listen 80 default deferred;

  set $redirect_to_https 0;
  if ($http_x_forwarded_proto != 'https') {
    set $redirect_to_https 1;
  }
  if ($request_uri = '/health') {
    set $redirect_to_https 0;
  }
  if ($redirect_to_https = 1) {
    rewrite ^ https://www.example.com$request_uri? permanent;
  }
  ...
}
Jonny Mac
sumber
1
pasti ada cara yang lebih elegan untuk melakukan ini
Edward
0

Anda sekarang dapat membuat Listener baru di AWS Load Balancer Settings yang mengarahkan ulang HTTP Port 80 ke HTTPS Port 443. Jadi Anda tidak perlu menyentuh konfigurasi nginx / apache lagi.

Kenny Greulich
sumber
sayangnya, itu belum didukung di Cloudformation
Aryeh Leib Taurog