Requests: Dukungan TLS SNI

Dibuat pada 1 Agu 2012  ·  46Komentar  ·  Sumber: psf/requests

Sepertinya saya mengalami masalah saat menggunakan permintaan dengan server yang memerlukan dukungan TLS SNI. Kapan permintaan memiliki fitur ini? Apakah ini sesuatu yang direncanakan?

Terima kasih,
--Ram

Komentar yang paling membantu

Ini ditentukan dalam request/packages/urllib3/contrib/pyopenssl.py :

  • pyOpenSSL (diuji dengan 0,13)
  • ndg-httpsclient (diuji dengan 0.3.2)
  • pyasn1 (diuji dengan 0.1.6)

(Atau python3.2 atau lebih tinggi, yang selalu berfungsi)

Semua 46 komentar

Tidak mungkin dalam Python 2.x di atas modul ssl stdlib.

Twisted memilikinya, kan? Mungkin waktunya bergantung pada pyopenssl atau modul ssl lainnya?

Ada permintaan tarik untuk urllib3 menambahkan dukungan SNI untuk Py32+, tetapi masih membutuhkan cakupan pengujian. https://github.com/shazow/urllib3/pull/89

shzow: Terima kasih atas penunjuknya. Sayangnya saya menggunakan Twisted/Flask, yang berarti saya terjebak di 2.7. Memutar tampaknya dapat melakukan sesuatu seperti ini, tetapi saya belum melihat contoh, dan itu perlu pyopenssl + decoding bengkok untuk melakukan ini. Saya bukan ahli dalam melakukan ini. Pada titik ini, hanya berpikir untuk membungkus beberapa utilitas baris perintah seperti wget... :(

PyOpenSSL harus dapat melakukannya pada 2.x. Jadi ada harapan.

Saya bisa membuatnya bekerja dengan pyopenssl. Tapi saya masih kesulitan menyelesaikannya dengan benar. http://pbin.be/show/719/ -- jenis karya. Tapi kemudian kita harus membangun API di atasnya agar berguna. Saya masih tidak tahu bagaimana cara menyampaikan konteks yang benar ke Agen.

Lukas: apakah ini diselesaikan?

Tidak. Kami diblokir di shazow/urllib3#89.

Digabungkan. Melanjutkan. :)

Perhatikan bahwa itu hanya didukung di Py32+ untuk saat ini. Seharusnya cukup untuk memulai.

Peringatan adil lainnya: Beberapa tes pada Py32 gagal pada master urllib3 sekarang. Beberapa bantuan untuk menyelesaikan ini akan sangat dihargai (dan mungkin memengaruhi fungsi ini): https://github.com/shazow/urllib3/issues/128

bekerja untuk saya di archlinux x64 di py26, py27, py32, py33

Ah saya seharusnya memenuhi syarat bahwa ini ada di OSX. OSX bajingan.

t-8ch: Apakah tes sni melewati py26/27/32 dan 33 untuk Anda?

Tes SNI bahkan tidak dijalankan pada py2, tetapi pada py32 dan py33 berfungsi.
Tidak ada cara untuk melakukan SNI dengan modul ssl dari perpustakaan standar sebelum py32.

@shazow : Agaknya Anda tidak tertarik membuat urllib3 bergantung pada PyOpenSSL?

Saya akan senang memiliki perpustakaan terpisah yang menambahkan SSL melalui dukungan PyOpenSSL ke urllib3.

Sepertinya @t-8ch membuatnya keluar dari taman dengan pekerjaan di urllib3. Saya akan membiarkan dia memberi tahu kami kapan ini bisa ditutup.

urllib3 memiliki dukungan opsional untuk SNI dengan python2, meskipun dengan beberapa dependensi opsional. (Lihat urllib3#156 ).

Saya percaya ini harus bekerja menggunakan:

from requests.packages.urllib3.contrib import pyopenssl
pyopenssl.inject_into_urllib3

Setelah menambahkan ini ke packages di setup.py

requests.packages.urllib3.contrib

Perhatikan bahwa paket contrib tidak diimpor secara default.

Pada dasarnya ada dua alternatif untuk mengaktifkan SNI dalam permintaan:

  • Buat fungsi untuk mengaktifkan SNI secara manual yang pada dasarnya menjalankan kode di atas. (kelemahannya adalah pengguna harus secara eksplisit mengaktifkan dukungan SNI).
  • Cobalah untuk mengimpor prasyarat. Jika ada, aktifkan SNI, kalau tidak jangan.

Saya tidak masalah menerapkan salah satu dari kedua alternatif, meskipun saya lebih suka mengetahui mana yang lebih disukai untuk permintaan. Saya pribadi memilih alternatif kedua.

BTW: bisakah kami membuka kembali masalah ini, sekarang kami mendapat dukungan dari urllib3?

Saya sebenarnya lebih suka yang pertama karena orang-orang yang membutuhkannya adalah orang-orang yang tahu bahwa mereka akan membutuhkannya dan mereka cukup sedikit sehingga tidak akan menimbulkan terlalu banyak keluhan. Namun, jika kita ingin konsisten dengan API yang ada, yang terakhir akan menjadi cara untuk mengimplementasikannya. Saat ini, urllib3 (dan permintaan) akan menyediakan API untuk mengirim permintaan HTTPS tanpa modul ssl, tetapi akan gagal jika modul ssl tidak tersedia. Dengan kata lain, API ada di sana dan Anda dapat menggunakannya tetapi itu tidak akan berfungsi dan itu ditunjukkan dengan pengecualian.

Untuk membuka kembali ini, terserah @kennethreitz. Masalahnya tentu saja (dengan semua ini) adalah bahwa kami saat ini sedang dalam pembekuan fitur (#1165, #1168) jadi saya tidak yakin apakah pekerjaan itu layak dilakukan karena mungkin tidak diterima.

Biar lebih jelas: yang saya maksud dengan alternatif kedua adalah "Coba gunakan SNI jika deps opsional tersedia, tetapi tetap gunakan SSL karena kami selalu memilikinya tidak.". Ini seharusnya tidak merusak apa pun yang ada hingga sekarang.

Adapun membuka kembali (atau tidak) masalah, IMHO, masalah ini tidak boleh dianggap enteng. permintaan dapat menjadi tidak berguna tanpa dukungan SNI untuk banyak skenario. Secara khusus, beberapa domain pada satu host IPv4 tanpa SNI menjadi tidak mungkin. Dan alamat IPv4 tambahan tidak mungkin bagi banyak pengguna (karena biayanya).

Bagaimanapun, ini adalah setengah fitur, setengah bug, meskipun saya akan menunggu balasan @kennethreitz tentang membuka kembali masalah ini.

Hugo: Saya baru saja melakukan permintaan pip install -U, dan ketika saya tidak dapat mengimpor contrib.
Bagaimana cara memperbaikinya? (Importerror : Tidak ada modul bernama contrib).

Pada Jum, 3 Mei 2013 pukul 13:12, Hugo Osvaldo Barrera <
[email protected]> menulis:

urllib3 memiliki dukungan opsional untuk SNI dengan python2, meskipun dengan beberapa
dependensi opsional. (Lihat urllib3#156https://github.com/shazow/urllib3/pull/156
).

Saya percaya ini harus bekerja menggunakan:

dari request.packages.urllib3.contrib impor pyopenssl
pyopenssl.inject_into_urllib3

Perhatikan bahwa paket contrib tidak diimpor secara default.

Pada dasarnya ada dua alternatif untuk mengaktifkan SNI dalam permintaan:

  • Buat fungsi untuk mengaktifkan SNI secara manual yang pada dasarnya menjalankan hal di atas
    kode. (kelemahannya adalah pengguna harus secara eksplisit mengaktifkan SNI
    mendukung).
  • Cobalah untuk mengimpor prasyarat. Jika ada, aktifkan SNI, kalau tidak
    jangan.

Saya tidak masalah menerapkan salah satu dari kedua alternatif, meskipun saya lebih suka
untuk mengetahui mana yang lebih disukai untuk permintaan. Saya pribadi memilih
alternatif kedua.


Balas email ini secara langsung atau lihat di Gi tHubhttps://github.com/kennethreitz/requests/issues/749#issuecomment -17406518
.

setup.py permintaan tidak menyertakan paket itu (sumbernya ada di sana, tetapi dikecualikan saat menginstal/mengemas), jadi itu tidak diinstal, itu sebabnya saya menyebutkan:

Setelah menambahkan ini ke packages in setup.py
request.packages.urllib3.contrib

Anda pada dasarnya harus menginstal dari sumber.
Lihat permintaan tarik saya jika Anda tertarik, membuat ini berfungsi hanya beberapa baris. :)

"Coba gunakan SNI jika deps opsional tersedia, tetapi tetap gunakan SSL karena kami selalu memilikinya."

SSL tidak selalu ada. Itu poin saya. Saat ini kami mencoba dan menggunakannya tetapi gagal keras dan cepat jika kami tidak memilikinya dan pengguna mencoba membuat permintaan https. Cara Anda menggambarkannya, saya mendapat kesan bahwa SNI akan mengharuskan pengguna untuk memberikan beberapa gagasan tambahan ke urllib3 dan Anda hanya berfokus pada pengaturan untuk itu. Jika semua yang diperlukan adalah #1347 maka saya 100% di belakang ini.

Akan sangat bagus jika ini adalah default (Dukungan SNI) dan permintaan
hanya berfungsi tanpa kode atau pengaturan tambahan dari sumber. Untuk urllib3 nya 2
baris kode. Mengapa tidak menambahkannya saja ke permintaan. Apakah saya sedang bermimpi? :)

Pada Jumat, 3 Mei 2013 pukul 22:43, Ian Cordasco [email protected] menulis :

"Coba gunakan SNI jika deps opsional tersedia, tetapi tetap gunakan SSL sebagai
kita selalu memilikinya, mereka tidak."

SSL tidak selalu ada. Itu poin saya. Saat ini kami mencoba dan
menggunakannya tetapi gagal keras dan cepat jika kita tidak memilikinya dan pengguna mencoba membuatnya
permintaan https. Cara Anda menggambarkannya, saya berada di bawah
kesan SNI akan mengharuskan pengguna untuk memberikan beberapa gagasan tambahan ke urllib3
dan Anda hanya berfokus pada pengaturan untuk itu. Jika semua itu perlu
adalah #1347 https://github.com/kennethreitz/requests/issues/1347 lalu saya
100% di belakang ini.


Balas email ini secara langsung atau lihat di Gi tHubhttps://github.com/kennethreitz/requests/issues/749#issuecomment -17426626
.

@pythonmobile berputar di atas. Jika tidak berhenti berputar, Anda sedang bermimpi.

inception

Meninggalkan komentar demi orang lain yang mungkin mengalami masalah yang sama dengan saya:
Jika Anda mengalami masalah saat membuat permintaan aman menggunakan pustaka requests , khususnya saat mencoba membuka aplikasi yang dihosting di Google App Engine, mungkin inilah alasannya. Kesalahan yang saya lihat adalah "EOF terjadi pelanggaran protokol". Untuk mendiagnosis ini, coba tekan host yang sama menggunakan s_client (ganti example.com dengan host yang dimaksud):

openssl s_client -connect example.com:443
openssl s_client -connect example.com:443 -servername example.com

Jika perintah pertama gagal dengan "kegagalan jabat tangan" dan yang kedua berhasil, maka Anda mencoba menekan server yang menggunakan SNI. Utas saat ini memiliki beberapa info bagus tentang cara membuat requests bekerja dalam situasi ini. Apa yang saya lakukan adalah mencoba menjalankan from requests.packages.urllib3.contrib import pyopenssl di ipython, dan saya terus menginstal pip kesalahan impor. YMMV.

@mshang Versi 1.2.3 seharusnya sudah melakukan ini untuk Anda; apakah Anda yakin menjalankan versi itu?

@hobarrera Ya, saya menjalankan 1.2.3. requests.packages.urllib3.contrib ada di sana, tetapi pernyataan impor itu masih menimbulkan banyak kesalahan impor. Saya harus menginstal ndg-httpsclient dan saya lupa apa lagi.

Benar. Permintaan hanya mencoba mengimpor modul yang diperlukan, dan jika tidak dapat menyerah dan melanjutkan hidupnya. Namun, mungkin ada baiknya untuk mendokumentasikan apa yang Anda perlukan untuk menggunakan SNI dengan Permintaan.

Ini ditentukan dalam request/packages/urllib3/contrib/pyopenssl.py :

  • pyOpenSSL (diuji dengan 0,13)
  • ndg-httpsclient (diuji dengan 0.3.2)
  • pyasn1 (diuji dengan 0.1.6)

(Atau python3.2 atau lebih tinggi, yang selalu berfungsi)

Sepertinya permintaan dan urllib3 rusak untuk SNI saat ini. Satu
masalahnya adalah jika seseorang menambahkan batas waktu = 5.0, kode berperilaku berbeda dari
tanpa batas waktu. Masalah kedua adalah dengan domain yang tidak ada.
Pengujian perlu menambahkan lebih banyak domain SNI dibandingkan hanya bergantung pada
simpul/httpbin/. Keduanya sama sekali tidak mencerminkan penggunaan SNI.

Pada Senin, 10 Jun 2013 pukul 04.57, Thomas Weißschuh
[email protected] menulis :

Ini ditentukan dalam permintaan/paket/urllib3/contrib/pyopenssl. pyhttps://github.com/kennethreitz/requests/blob/master/requests/packages/urllib3/contrib/pyopenssl.py
:

  • pyOpenSSL (diuji dengan 0,13)
  • ndg-httpsclient (diuji dengan 0.3.2)
  • pyasn1 (diuji dengan 0.1.6)

(Atau python3.2 atau lebih tinggi, yang selalu berfungsi)


Balas email ini secara langsung atau lihat di Gi tHubhttps://github.com/kennethreitz/requests/issues/749#issuecomment -19187417
.

@pythonmobile Jika itu masalahnya, dan Anda memiliki kasus uji yang dapat direproduksi dengan baik, silakan buka masalah yang menyorotinya di urllib3. Permintaan tidak memiliki kode khusus SNI (sejauh yang saya tahu), jadi perbaikan di sana akan memperbaiki kami juga.

Kecuali urllib3 sudah diperbaiki, yang sepertinya banyak terjadi akhir-akhir ini. Shazow _et. al._ cukup mengagumkan. @t-8ch, apakah kalian sudah melihat/memperbaiki ini?

Saya pikir jika kita menulis tes dalam permintaan, mereka lebih mudah untuk menulis dan menguji, meskipun, itu hanya berarti bahwa itu akan menguji sebagian besar kode urllib3. Dengan begitu, akan lebih mudah untuk memeriksa setiap impor urllib3 dalam permintaan, apakah sni rusak atau tidak dan membunyikan alarm. Saya akan segera menulis tes permintaan.

Maaf @pythonmobile , saya tidak setuju. =)

SNI secara eksplisit adalah fungsi urllib3. Jika SNI rusak di urllib3 Anda benar-benar harus menyediakan proyek itu dengan perbaikan, pengujian, atau setidaknya laporan bug. Ketika proyek itu diperbaiki, Permintaan akan secara ajaib diperbaiki juga (ketika kami memperbarui urllib3 berikutnya, yang cukup sering kami lakukan). =)

Meskipun lebih banyak tes untuk permintaan tentu tidak ada salahnya, seperti yang dikatakan @Lukasa , Anda harus menulis tes untuk urllib3 jika Anda ingin melihat ini benar-benar diperbaiki. :)

Kami sudah memiliki banyak tes dalam nada yang sama, ping saya jika Anda memerlukan bantuan.

Tampaknya perilaku batas waktu pyOpenSSL berbeda dari yang
modul ssl standar:

from OpenSSL import SSL
import socket
import ssl

sock = socket.create_connection(('httpbin.org', 443), timeout=4.0)
ssl_sock = ssl.wrap_socket(sock)
ssl_sock.send('GET /ip HTTP/1.1\r\nHost: httpbin.org\r\n\r\n')
print(ssl_sock.recv(10000))

ctx = SSL.Context(SSL.TLSv1_METHOD)
sock = socket.create_connection(('httpbin.org', 443), timeout=4.0)
ctn = SSL.Connection(ctx, sock)
ctn.set_connect_state()

ctn.send('GET /ip HTTP/1.1\r\nHost: httpbin.org\r\n\r\n')
print(sock.read(10000))

Ini melempar WantReadError , hal yang sama juga dikeluarkan dari urllib3
saat menentukan batas waktu.

Dokumentasi memiliki
ini untuk mengatakan tentang kesalahan:

The operation did not complete; the same I/O method should be called again
later, with the same arguments. Any I/O method can lead to this since new
handshakes can occur at any time.

The wanted read is for dirty data sent over the network, not the clean data
inside the tunnel. For a socket based SSL connection, read means data coming at
us over the network. Until that read succeeds, the attempted
OpenSSL.SSL.Connection.recv, OpenSSL.SSL.Connection.send, or
OpenSSL.SSL.Connection.do_handshake is prevented or incomplete. You probably
want to select() on the socket before trying again. 

Saya tidak tahu bagaimana di mana batas waktu harus ditangani. Apakah soketnya ajaib?
ingat batas waktu pemanggilan select() atau apakah ini tugasnya
urlib3?
Melacak batas waktu dengan tangan tidak terdengar lucu.

@pythonmobile Apa yang Anda maksud dengan domain yang tidak ada. Aku tidak bisa mengikutimu.

@pythonmobile Bisakah Anda mencoba perubahan dari shazow/urllib3#233 dan lihat apakah kode berfungsi dengan pyopenssl dan batas waktu?

@t-8ch @pythonmobile : Bisakah kalian melihat utas ini juga: https://github.com/kennethreitz/requests/issues/1522#issuecomment -22443282

Akan menyenangkan untuk mendapatkan permintaan ini dalam pengujian unit di dalam urllib3 atau permintaan.

Masalah dengan mendapatkan ini sebagai unit test adalah bahwa mereka hanya muncul dalam konfigurasi yang sangat spesifik. Misalnya, saya tidak pernah dapat mereproduksi bagian kedua dari masalah ini atau #1522 di salah satu sistem saya, apakah itu Windows, OS X atau Ubuntu. Itu sebabnya saya meminta @pythonmobile untuk unit test yang dapat direproduksi. Jika kami dapat menemukannya, kami dapat mengembangkannya, jika tidak, kami terjebak berharap @t-8ch terus menjadi jenius dan secara ajaib memperbaiki semua masalah kami hingga urllib3 .

NB: @t-8ch, saya rasa saya tidak cukup berterima kasih atas pekerjaan Anda, baik di sini maupun di urllib3 . Anda luar biasa. =D :kue: :nanas: :pisang: :kue: :bir:

@lukasa Terima kasih :smile: Saya kira saya bisa menambahkan diri saya ke AUTHORS.txt beberapa waktu di masa depan.

@t-8ch Lakukan. :+1:

Perubahan pada shazow/urllib3#233 (sekarang ditarik ke urllib3 master) memperbaiki masalah bagi saya ( SSLError('bad handshake', WantReadError()) ) yang terjadi untuk beberapa url, beberapa kali, dalam beberapa konfigurasi :rage4:. Bisakah kita memasukkan ini ke dalam permintaan master?

@rcoup Kami akan memasukkan versi terbaru ke dalam Permintaan saat kami merilis 2.0. =)

Saya menjalankan Python 2.7.6 dan tidak dapat menginstal pyOpenSSL. Saya telah mencoba bekerja di sekitar posting htis -> https://stackoverflow.com/questions/18578439/using-requests-with-tls-doesnt-give-sni-support/18578484#18579484

Saya juga tidak bisa memutakhirkan dengan Python. Ada solusi lain?

Saya meminta kami mempertimbangkan kembali penggunaan tanpa syarat (jika ada) dari "inject_into_urllib3()".

Ditambahkan 7 tahun yang lalu, tujuannya adalah untuk "menambahkan dukungan SNI untuk Python 2"

"urllib3.contrib.pyopenssl.inject_into_urllib3()" dijelaskan ke "Monkey-patch urllib3 dengan dukungan SSL yang didukung PyOpenSSL.":
(https://github.com/urllib3/urllib3/blob/master/src/urllib3/contrib/pyopenssl.py)

Pembenaran:
1: Keamanan/stabilitas: Penambalan monyet untuk menukar penggunaan perpustakaan standar untuk perpustakaan pihak ke-3 bisa dibilang lebih bedah, terutama untuk ssl. Jika tambalan untuk dukungan di Python2, maka setidaknya periksa versi utama. Atau bahkan lebih baik, periksa apakah dukungan SNI sudah ada ssl.HAS_SNI .

2: Tidak Perlu: Mulai 10 Desember 2014, keseluruhan modul ssl Python 3.4 telah di-backport untuk Python 2.7.9. Lihat PEP 466 untuk pembenaran. https://www.python.org/downloads/release/python-279/. Ini memungkinkan dukungan SNI di pustaka standar untuk > v2.7.9

3: Tidak fleksibel: Seperti yang diterapkan, tidak ada cara untuk menonaktifkan perilaku ini. Satu-satunya pilihan untuk mencegah requests penggunaan konteks pyopenssl adalah menghapus instalan pyopenssl untuk seluruh lingkungan python saya.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat