Bagaimana cara kerja pergantian sertifikat HTTPS (seperti pada suche.org)?

20

Bagi mereka yang tidak tahu apa itu Suche.org, itu adalah situs web yang memiliki peringkat A + sempurna pada SSL Labs di setiap kategori: (hasil Suche.org SSL Labs ). Saya mengetahui situs web ini ketika saya membuka tiket lain tentang sertifikat ECC yang tidak berfungsi di Chrome , dan salah satu responden menggunakan situs tersebut sebagai contoh.

Yang membingungkan saya adalah bahwa meskipun Protocol Supportbagian dari laporan mengatakan bahwa situs web hanya menggunakan TLSv1.2 ...

TLS 1.2 Yes
TLS 1.1 No
TLS 1.0 No
SSL 3   No
SSL 2   No

Itu jelas tidak terjadi karena di bawah Handshake Simulationbagian ini, ini menampilkan bahwa beberapa klien lama yang disimulasikan menggunakan TLSv1.0 untuk menghubungkan ...

Android 4.0.4   EC 384 (SHA256)     TLS 1.0 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA   ECDH secp521r1  FS
Android 4.1.1   EC 384 (SHA256)     TLS 1.0 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA   ECDH secp521r1  FS
Android 4.2.2   EC 384 (SHA256)     TLS 1.0 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA   ECDH secp521r1  FS
Android 4.3     EC 384 (SHA256)     TLS 1.0 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA   ECDH secp521r1  FS
Android 4.4.2   EC 384 (SHA256)     TLS 1.2 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384   ECDH secp521r1  FS

Ini agak frustasi karena jika saya menonaktifkan TLSv1.0 di situs web pengujian saya seperti ...

# Apache example
SSLProtocol all -SSLv3 -SSLv2 -TLSv1

Menjalankan pemindaian Labs SSL di situs web pengujian saya menghasilkan yang berikut untuk beberapa klien lama:

Android 4.0.4   Server closed connection
Android 4.1.1   Server closed connection
Android 4.2.2   Server closed connection
Android 4.3     Server closed connection
Android 4.4.2   EC 384 (SHA256)     TLS 1.2 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256   ECDH secp256r1  FS

Bagaimana mungkin untuk secara bersamaan mengizinkan hanya koneksi TLSv1.2, namun mendukung klien yang lebih tua juga?

Scott Crooks
sumber
Haruskah kita membuat judul lebih umum, seperti "HTTPS cert switching logic"?
gf_
1
@ gf_ Ide bagus. Selesai
Scott Crooks

Jawaban:

17

Saya cukup yakin bahwa mereka sedang memeriksa kemampuan klien dan bertindak sesuai, seperti dijelaskan di utas yang terkait dengan jawaban @ Jeff .

Untuk mendapatkan gambaran bagaimana ini bisa terlihat secara detail, lihat ini . Ini menunjukkan implementasi yang dibuat dengan HAProxyuntuk melayani klien yang berbeda, sertifikat yang berbeda, tergantung pada kemampuan mereka. Saya sudah melakukan copy / paste lengkap, untuk mencegah pembusukan tautan, dan karena saya pikir pertanyaan ini mungkin menarik di masa depan:

Sertifikat SHA-1 sedang dalam perjalanan keluar, dan Anda harus meningkatkan ke sertifikat SHA-256 sesegera mungkin ... kecuali jika Anda memiliki klien yang sangat lama dan harus mempertahankan kompatibilitas SHA-1 untuk sementara waktu.

Jika Anda berada dalam situasi ini, Anda perlu memaksa klien Anda untuk memutakhirkan (sulit) atau menerapkan beberapa bentuk logika pemilihan sertifikat: kami menyebutnya "peralihan sertifikat".

Metode pemilihan yang paling deterministik adalah untuk melayani sertifikat SHA-256 untuk klien yang menghadirkan TLS1.2 HELLO HELLO yang secara eksplisit mengumumkan dukungan mereka untuk SHA256-RSA (0x0401) dalam ekstensi signature_algorithms.

ekstensi algoritma tanda tangan

Browser web modern akan mengirim ekstensi ini. Namun, saya tidak mengetahui adanya penyeimbang beban sumber terbuka yang saat ini dapat memeriksa konten ekstensi signature_algorithms. Itu mungkin datang di masa depan, tetapi untuk saat ini cara termudah untuk mencapai pengalihan sertifikat adalah dengan menggunakan HAProxy SNI ACL: jika klien menyajikan ekstensi SNI, arahkan ke backend yang menghadirkan sertifikat SHA-256. Jika tidak menampilkan ekstensi, anggaplah klien lama yang menggunakan SSLv3 atau versi TLS yang rusak, dan berikan sertifikat SHA-1.

Ini dapat dicapai dalam HAProxy dengan merantai frontend dan backend:

Pergantian sertifikat HAProxy

global
        ssl-default-bind-ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128
-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-R
SA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK

frontend https-in
        bind 0.0.0.0:443
        mode tcp
        tcp-request inspect-delay 5s
        tcp-request content accept if { req_ssl_hello_type 1 }
        use_backend jve_https if { req.ssl_sni -i jve.linuxwall.info }

        # fallback to backward compatible sha1
        default_backend jve_https_sha1

backend jve_https
        mode tcp
        server jve_https 127.0.0.1:1665
frontend jve_https
        bind 127.0.0.1:1665 ssl no-sslv3 no-tlsv10 crt /etc/haproxy/certs/jve_sha256.pem tfo
        mode http
        option forwardfor
        use_backend jve

backend jve_https_sha1
        mode tcp
        server jve_https 127.0.0.1:1667
frontend jve_https_sha1
        bind 127.0.0.1:1667 ssl crt /etc/haproxy/certs/jve_sha1.pem tfo ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA
        mode http
        option forwardfor
        use_backend jve

backend jve
        rspadd Strict-Transport-Security:\ max-age=15768000
        server jve 172.16.0.6:80 maxconn 128

Konfigurasi di atas menerima lalu lintas masuk di frontend yang disebut "https-in". Frontend itu dalam mode TCP dan memeriksa CLIENT HELLO yang berasal dari klien untuk nilai ekstensi SNI. Jika nilai itu ada dan cocok dengan situs target kami, itu mengirimkan koneksi ke backend bernama "jve_https", yang dialihkan ke frontend juga bernama "jve_https" di mana sertifikat SHA256 dikonfigurasi dan disajikan kepada klien.

Jika klien gagal memberikan CLIENT HELLO dengan SNI, atau menyajikan SNI yang tidak cocok dengan situs target kami, itu dialihkan ke backend "https_jve_sha1", kemudian ke frontend yang sesuai di mana sertifikat SHA1 disajikan. Frontend itu juga mendukung ciphersuite yang lebih lama untuk mengakomodasi klien yang lebih tua.

Kedua frontend akhirnya mengarahkan ke backend tunggal bernama "jve" yang mengirimkan lalu lintas ke server web tujuan.

Ini adalah konfigurasi yang sangat sederhana, dan pada akhirnya dapat ditingkatkan dengan menggunakan ACL yang lebih baik (HAproxy secara teratur menambahkan berita), tetapi untuk konfigurasi pensaklaran cert dasar, ini akan menyelesaikan pekerjaan!

gf_
sumber
9

Pertanyaan serupa ditanyakan di https://community.qualys.com/thread/16387

Saya pikir jawaban ini adalah solusinya:

suche.org adalah implementasi yang cerdas. Sejauh yang saya mengerti, itu menanyakan kemampuan klien dan kemudian hanya menawarkan yang terbaik yang tersedia, untuk menghilangkan keraguan.

Jeff
sumber
2
"itu menanyakan kemampuan klien" bukan deskripsi yang berguna. Hampir tidak ada informasi yang cukup bagi orang lain untuk melakukan implementasi mereka sendiri.
womble