Nginx. Bagaimana cara saya menolak permintaan ke server virtual ssl tidak terdaftar?

13

Saya memiliki sertifikat SSL wildcard dan beberapa subdomain pada ip yang sama. Sekarang saya ingin nginx saya hanya menangani nama server yang disebutkan dan memutuskan koneksi untuk yang lain sehingga sepertinya nginxtidak berjalan untuk nama server yang tidak terdaftar (tidak merespons, menolak, mati, bukan byte tunggal sebagai tanggapan). Saya melakukan hal berikut

ssl_certificate         tls/domain.crt;
ssl_certificate_key     tls/domain.key;

server {
  listen 1.2.3.4:443 ssl;
  server_name validname.domain.com;
  //
}

server {
  listen 1.2.3.4:443 ssl;
  server_name _;
  // deny all;
  // return 444;
  // return 404;
  //location {
  //  deny all;
  //}
}

Saya sudah mencoba hampir semua yang ada di blok server terakhir, tetapi tidak berhasil. Saya mendapatkan respons yang valid dari server virtual yang dikenal atau kode kesalahan. Tolong bantu.

andbi
sumber

Jawaban:

7

Tidak berfungsi seperti itu: jabat tangan SSL terjadi sebelum HTTP, jadi nama pada sertifikat akan dievaluasi di browser sebelum Anda dapat mengarahkan ulang atau melakukan hal lain di dalam konfigurasi nginx.

cjc
sumber
ini buruk, tetapi harus mengakui) Terima kasih.
andbi
3
Ini tidak benar: Anda dapat melakukan hal lain di level bawah, seperti menjatuhkan koneksi tanpa respons apa pun, seperti yang dijelaskan dalam jawaban lain.
collimarco
13

Jawaban oleh cjc sudah dengan benar menunjukkan masalah dengan mencoba mencocokkan nama host ketika SSL diaktifkan. Namun, dimungkinkan untuk melakukannya, seperti ini:

server {
    ...

    if ($host !~* ^validname\.domain\.com$ ) {
        return 444;
    }
    ...
}

Catatan: ya memang benar bahwa pada umumnya ifjahat , tetapi aman untuk digunakan ifdalam kasus ini. (Baca halaman tertaut jika Anda perlu meyakinkan diri sendiri.)

Berlawanan dengan apa yang telah disarankan, hanya menambahkan blok berikut tidak akan berfungsi:

server {
    listen 80;
    listen 443 ssl;
    return 444;
}

karena sertifikat SSL yang cocok validname.domain.comtidak akan cocok dengan beberapa nama domain acak. Saya sudah mencobanya, dan nginx bertindak seperti blok tidak ada sama sekali.

Ini juga tidak akan berfungsi:

server {
    listen       443;
    server_name    _;
    return 444; 
}

karena itu akan membuat setiap koneksi HTTPS tunggal pada port 443 gagal, bahkan yang harus melalui. Saya sudah mencoba yang ini juga. wgetmelaporkan kesalahan jabat tangan SSL.

Louis
sumber
5

Sebagian besar jawaban di sini adalah tentang mengapa itu tidak berhasil, bukan bagaimana membuatnya bekerja.

Begini caranya - Anda perlu menjadikan catch-all server sebagai 'default_server' dan perlu memberikan path ke cert / key sehingga dapat mendekripsi permintaan ssl yang masuk dan cocok dengan header Host:

server {
    listen 80 default_server;
    listen 443 ssl default_server;
    server_name _;
    ssl_certificate <path to cert>;
    ssl_certificate_key <path to key>;
    return 404;
}

Perhatikan ssl_certificate / ssl_certificate_key di sana. Jika tidak ditentukan, nginx masih mencoba menggunakan default_server tersebut dan gagal karena tidak dapat menerima koneksi ssl dengan kunci / sertifikat. Seseorang dapat menggunakan sertifikat / kunci apa pun misalnya ditandatangani sendiri. ...

Untuk menghasilkan sertifikat yang ditandatangani sendiri:

openssl req -x509 -newkey rsa:4096 -nodes -out cert.pem -keyout key.pem -days 365 

Lihat juga /server//a/841643/87439

andreycpp
sumber
1
Sudahkah Anda mencoba ini? Bagaimana Anda membuat sertifikat SSL yang cocok dengan nama server "_"?
Tim
Ya, solusi ini bekerja untuk saya. Saya memiliki masalah yang sama persis dan menemukan dari dokumentasi bahwa nginx memerlukan sertifikat / kunci karena tidak melihat TLS SNI. Anda dapat menggunakan sertifikat / kunci apa saja, misalnya ditandatangani sendiri.
andreycpp
1

Saya menerapkan solusi di atas hari ini, dan itu berhasil dengan baik. Semua URL yang tidak ditentukan dihapus, sekarang. Menempatkan kode server ini sebelum entri server virtual yang sebenarnya adalah kunci - semua URL yang salah terbentuk sekarang masuk ke server 'default' ini.

... 
server {
     listen       443;
     server_name    _;
     return 444; }

server {
     listen       443;
     server_name  [URL]
David Sexton
sumber
0

Anda harus dapat menangani ini dengan membuat server yang menangani item yang tidak terdaftar sebagai blok server pertama dalam konfigurasi Anda.

http {
    ...

    server {
        listen 80;
        listen 443 ssl;
        return 444;
    }

    server {
        server_name validname.domain.com;
        ...
    }
}

Semua domain yang tidak diidentifikasi secara spesifik akan ditangani oleh blok server ini.

Dayo
sumber
1
Tidak berfungsi
AmirHossein