VPN aktif, dasbor internal terbuka di peramban, tetapi skrip Python tetap melempar galat proxy. Tidak ada yang salah dengan terowongan pada gambaran itu: penerjemah membaca alamat proxy dari lingkungannya sendiri dan mengirim permintaan ke sana. Runbook ini membaca lingkungan yang benar-benar dilihat proses, menerapkan pengecualian tersempit, dan baru kemudian mempertimbangkan kebijakan sesi eksplisit. Setiap langkah berakhir dengan perintah yang keluarannya menentukan apakah Anda melanjutkan.

Baca lingkungan yang benar-benar dilihat proses

Setelan proxy desktop, ekspor shell, dan baris Environment= unit systemd adalah tiga sumber berbeda, dan Requests hanya membaca yang terakhir ia warisi. Jalankan diagnostik di bawah pada shell, kontainer, atau unit yang sama yang menjalankan skrip gagal, bukan di terminal interaktif Anda. Variabel yang diekspor di shell login tidak terlihat oleh proses kontainer, dan celah itu menjelaskan banyak laporan proxy yang muncul entah dari mana. Kedua perintah mencetak data yang sama pada tingkat detail berbeda.

env | grep -i -E 'proxy|requests_ca_bundle|curl_ca_bundle'
python3 -c "import os;[print(k,'=',v) for k,v in sorted(os.environ.items()) if 'proxy' in k.lower()]"

Kedua ejaan setiap variabel dibaca, dan entri duplikat diterapkan dalam urutan penerimaannya oleh proses, sehingga HTTP_PROXY yang basi dapat menimpa nilai yang baru saja Anda ekspor. Variabel bundel CA juga penting di sini, karena mengubah ke apa verify diselesaikan tanpa muncul di mana pun dalam kode. Jika keluarannya kosong, lingkungan bukan masalah Anda dan Anda bisa berhenti membaca bagian ini. Jika ia mencantumkan proxy yang tidak Anda kenali, temukan berkas atau unit yang menyetelnya sebelum mengubah apa pun.

Tanyakan kepada Requests apa yang akan dilakukannya dengan URL tertentu. Panggilan ini menunjukkan nilai proxy, verify, dan cert yang digabungkan untuk permintaan itu tanpa mengirim paket.

python3 -c "import requests;s=requests.Session();print(s.merge_environment_settings('https://api.corp.example/status',{},None,None,None))"

Entri proxies yang tidak kosong untuk host privat adalah jawaban Anda, dan nilai verify yang tercetak memberi tahu bundel CA mana yang akan dipercaya permintaan. Jika keduanya tampak benar, kegagalannya lebih jauh di tumpukan dan Anda sebaiknya melompat ke bagian verifikasi. Jangan menebak dari kode: penggabungan terjadi per permintaan, itulah sebabnya satu sesi dapat berperilaku berbeda untuk dua host.

Kecualikan host privat sebelum Anda menonaktifkan apa pun

Ketika proxy benar-benar diperlukan untuk tujuan lain, perbaikan sempitnya adalah pengecualian untuk host ini. Tambahkan ke daftar yang ada alih-alih menggantinya, karena menghapus NO_PROXY merusak setiap tujuan internal lain yang mengandalkannya. Perintah di bawah menambahkan entri lalu menanyakan apakah bypass berlaku.

export NO_PROXY="${NO_PROXY:+$NO_PROXY,}api.corp.example,.corp.example"
python3 -c "import requests;print(requests.utils.should_bypass_proxies('https://api.corp.example/status',None))"

Pencocokan berdasarkan sufiks host, sehingga .corp.example mencakup seluruh domain sementara api.corp.example mencakup satu nama. Tanda bintang telanjang menonaktifkan proxy untuk setiap host dan hampir tidak pernah menjadi keinginan pekerjaan produksi. Apakah entri CIDR dihormati bergantung pada versi Requests dan urllib3 di image, jadi uji entri persisnya alih-alih menganggapnya berfungsi. Periksa hasil should_bypass_proxies untuk URL sebenarnya, bukan untuk nama host yang Anda ketik dari ingatan.

Jaga kedua lapisan tetap terpisah di kepala Anda. Melewati proxy HTTP tidak melewati VPN, karena keputusan proxy terjadi di pustaka dan keputusan terowongan terjadi di tabel perutean kernel.

Nonaktifkan trust_env hanya sebagai kebijakan sesi yang disengaja

Jika seluruh pekerjaan harus mengabaikan konfigurasi sekitar, bangun sesi secara eksplisit dan catat keputusan di kode. Itu kebijakan, bukan akal-akalan, dan tempatnya di diff yang dapat dilihat peninjau. Contoh di bawah mempertahankan timeout, jalur CA eksplisit, dan pemeriksaan status.

import requests

with requests.Session() as session:
    session.trust_env = False
    response = session.get(
        "https://api.corp.example/status",
        timeout=(5, 20),
        verify="/etc/ssl/certs/corp-ca.pem",
    )
    response.raise_for_status()

Mematikan trust_env mengubah tiga perilaku sekaligus, dan hanya satu yang berkaitan dengan proxy. Requests berhenti membaca kredensial .netrc, dan variabel REQUESTS_CA_BUNDLE serta CURL_CA_BUNDLE berhenti memengaruhi verify, yang kemudian kembali ke penyimpanan sertifikat bawaan. Jika organisasi Anda mengakhiri TLS dengan CA-nya sendiri, fallback itu memunculkan galat verifikasi yang tampak tidak terkait dengan perubahan yang baru Anda buat. Melewatkan verify secara eksplisit adalah yang menjaga kedua efek tetap terpisah.

Yang tidak boleh Anda lakukan adalah menyetel verify=False untuk membungkam galat yang muncul. Itu menukar salah konfigurasi proxy dengan koneksi tanpa verifikasi, dan menyembunyikan masalah sertifikat yang seharusnya diungkap pengecualian itu.

Verifikasi lapisan yang gagal dan pertahankan rollback

Tiga kegagalan tampak sama di log dan tidak punya kesamaan: proxy yang tidak dapat mencapai tujuan melempar ProxyError atau mengembalikan 502, masalah kepercayaan melempar SSLError, dan penolakan aplikasi mengembalikan 401 atau 403. Reproduksi permintaan di luar Requests untuk melihat mana yang Anda hadapi. Perintah di bawah menghapus proxy, menguji rantai sertifikat, lalu mengulang panggilan melalui pustaka.

curl -sv --noproxy '*' https://api.corp.example/status -o /dev/null
openssl s_client -connect api.corp.example:443 -servername api.corp.example </dev/null
python3 -c "import requests;r=requests.get('https://api.corp.example/status',timeout=10);print(r.status_code)"

Jika panggilan curl berhasil dan panggilan Python gagal, lingkungannya masih tetap pembedanya. Jika keduanya gagal pada tahap TLS, proxy tidak pernah menjadi masalah dan rantai sertifikatlah masalahnya. Jika keduanya mengembalikan 401, permintaan telah mencapai aplikasi dan pekerjaan yang tersisa adalah autentikasi. Mencatat mana dari ketiganya yang Anda amati menghemat satu jam bagi orang berikutnya.

Rollback adalah satu baris ke kedua arah: hapus pengecualian, atau balikkan trust_env. Simpan nilai NO_PROXY sebelumnya sebelum menambahkan, dan utamakan skrip pembungkus atau entri Environment= tingkat unit daripada ekspor yang hanya hidup di riwayat terminal Anda. Kedua perubahan terlihat di lingkungan proses, sehingga restart biasanya mengembalikan Anda ke perilaku lama.

Akhiri dengan memastikan empat hal: setelan gabungan untuk URL privat tidak menunjukkan proxy, sertifikat tervalidasi terhadap CA yang dimaksud, permintaan mengembalikan status yang Anda harapkan, dan perubahan di-commit di tempat yang dapat direproduksi. Skrip hijau dengan lingkungan yang tidak dijelaskan adalah perbaikan yang akan rusak lagi di mesin berikutnya. Perintah dalam runbook ini adalah yang perlu ditempel di tiket.

Artikel terkait