Mengapa 443 default_server mendengarkan; aturan nginx menimpa aturan yang sudah dikonfigurasi (aturan http bekerja dengan cara normal)?


9

Saya memiliki subdomain nginx dan berbeda:

a.mydomain.com
b.mydomain.com
c.mydomain.com

Nginx memiliki 4 aturan:

1) aturan penulisan ulang:

server {
  listen 80
  server_name gl.udesk.org;

  root /nowhere;
  rewrite ^ https://a.mydomain.com$request_uri permanent;
}

2) aturan https:

server {

  listen 443;
  server_name a.mydomain.com;

  root /home/a/a/public;

  ssl on;
  ssl_certificate conf.d/ssl/a.crt;
  ssl_certificate_key conf.d/ssl/a.key;
  ssl_protocols ...
  ssl_ciphers ...
  ssl_prefer_server_ciphers on;

  location ...
}

3) aturan default http:

server {
  listen 80 default_server;
  return 444;
}

4) https aturan default:

server {
  listen 443 default_server;
  return 444;
}

Jadi jika saya mulai nginx dan:

  • jika saya masuk ke browser ke http://a.mydomain.com, itu dialihkan ke https://a.mydomain.com dan kemudian mengembalikan Galat 107 (bersih :: ERR_SSL_PROTOCOL_ERROR): Kesalahan protokol SSL.
  • jika saya masuk ke peramban ke https://b.mydomain.com, saya berharap akan mengembalikan Galat 444 kembali. Tetapi sebaliknya ia mengembalikan Kesalahan 107 yang sama (net :: ERR_SSL_PROTOCOL_ERROR): Kesalahan protokol SSL.
  • dan untuk semua yang terdaftar oleh penyedia DNS CNAMEs (yaitu a, b, c)
  • semua versi http (mis. aturan 3 -) berfungsi seperti yang diharapkan:

Jadi mengapa aturan https di nginx sangat rumit untuk dikonfigurasikan dan bagaimana cara mengkonfigurasinya dengan benar untuk mendapatkan perilaku yang sama dengan versi http?

Memperbarui:

Membuat sertifikat baru dan menambahkan:

ssl on;
ssl_certificate conf.d/ssl/default.crt;
ssl_certificate_key conf.d/ssl/default.key;

berfungsi sekarang, tetapi saya akan memiliki solusi tanpa memerlukan sertifikat SSL. Setel ulang semua koneksi untuk semua subdomain https (port 443) kecuali https://a.mydomain.com tanpa memberikan sertifikat.


2
Kamu tidak bisa SSL memerlukan sertifikat sebelum server web tahu domain apa yang Anda inginkan . Itu harus memiliki sertifikat untuk dikirim, atau tidak dapat membuat koneksi untuk berbicara dengan klien.
Darth Android

2
@DarthAndroid: Keajaiban ini disebut SNI - en.wikipedia.org/wiki/Server_Name_Indication .
Shi

@Shi Aku sadar SNI - Yang memungkinkan webserver untuk memilih yang sertifikat untuk mengirim, tetapi masih harus memilih sebuah sertifikat. nginxtidak cukup pintar untuk menyadari bahwa itu tidak memerlukan sertifikat untuk apa yang ingin dilakukan pengguna.
Darth Android

Jawaban:


3

Jangan campur Port 443 dengan ssl! Nginx sepenuhnya port agnostik. Anda dapat menawarkan https melalui Port 80 juga. Versi nginx modern memungkinkan

listen 1234 ssl;

dan Anda tidak perlu ssl on;saluran itu.

Tetapi jika Anda ingin melayani https, Anda perlu menentukan sertifikat. Server Anda memasukkan https saat ia menulis ulang permintaan http menjadi permintaan https.

Anda mendapatkan PROTOCOL ERROR, karena SSL Handshake dilakukan sebelum hal lain. Jadi return 444tidak tercapai. Dan setiap Handshake SSL akan memerlukan sertifikat dan kunci pribadi, untuk memberi makan algoritma enkripsi dengan pasangan kunci sertifikat / pribadi.


3

The returndirektif merupakan bagian dari modul rewrite. Jika Anda memeriksa dokumentasi , Anda mungkin melihat bahwa itu berfungsi dengan permintaan. Dalam HTTPS, permintaan hanya dapat dilakukan setelah jabat tangan selesai.

Ada permintaan fitur: https://trac.nginx.org/nginx/ticket/195 dan solusi penyelesaiannya disediakan.

server {
    listen 443 ssl;
    server_name bbb.example.com;
    ssl_ciphers aNULL;
    ssl_certificate /path/to/dummy.crt;
    ssl_certificate_key /path/to/dummy.key;
    return 444;
}

Catatan ini akan mematahkan klien HTTPS non-SNI-mampu (seperti nginx sendiri proxy_pass, kecuali jika Anda mengatur proxy_ssl_server_name on;) mencapai lain server_names(jadi pada dasarnya melanggar sah server_names yang Anda lakukan ingin membiarkan melalui). Lihat trac.nginx.org/nginx/ticket/195#comment:11 untuk detailnya.
nh2
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.