11

Trong appserver phát triển AppEngine Tôi nhận được một lỗi như thế này:AppEngine nạp url validate_certificate = False/Không không được tôn trọng

SSLCertificateError: Invalid and/or missing SSL certificate for URL ... 

khi tôi đang làm cho một lấy như thế này đến một máy chủ https với một ký tự giấy chứng nhận (hầu như luôn luôn localhost cổng chuyển tiếp qua ssh đến một vm):

result = urlfetch.fetch(url=url, method=method, payload=payload, 
         deadline=DEADLINE, validate_certificate=None) 

một sẽ không mong đợi thất bại SSL cho chứng chỉ không hợp lệ nơi validate_certificateFalse, mặc dù điều này là khá có thể là một tác dụng phụ của chính sách 2.7.9 trong Python để luôn xác nhận các chứng chỉ ssl.

Lưu ý rằng vượt qua False (thay vì None) cho validate_certificate cũng không hoạt động.

Sự cố này xảy ra trên Python 2.7.9-10 qua Homebrew/XCode trên OS X 10.10.2-4 với AppEngine 1.9.18 đến 1.19.26.

Có vấn đề (ví dụ: 12096) về điều này trên Google App Engine, nhưng tôi đang tìm cách giải quyết.

Dưới đây là những gì tôi đã cố gắng để làm việc xung quanh này:

  1. Thêm giấy chứng nhận để keychain đăng nhập của Mac (công trình trong trình duyệt, không phải từ Python)

  2. Thêm giấy chứng nhận để app-engine-python/lib/cacerts/cacerts.txt và/hoặc ./lib/cacerts/urlfetch_cacerts.txt (mặc dù điều này có thể yêu cầu xác minh chuyển trên để thiết bị hoạt động, vì dường như trường hợp này chỉ được sử dụng) với ví dụ

    $ echo >> /usr/local/share/app-engine-python/lib/cacerts/urlfetch_cacerts.txt

    $ openssl x509 -subject -in server.crt >>/usr/local /share/app-engine-python/lib/cacerts/urlfetch_cacerts.txt

  3. HTTPS ssl Disable kiểm tra với PEP-0476 workaround tức

    ssl._create_default_https_context = ssl._create_unverified_context

    tại hoặc sau import ssl (khoảng dòng 1149) của google/appengine/dist27/python_std_lib/httplib.py

Điều này đặc biệt có vấn đề trên Mac kể từ khi hạ như của XCode 7/OS X El Capital không còn là một lựa chọn thực tế.

Cách giải quyết thích hợp hơn sẽ không liên quan đến việc khỉ vá mã AppEngine phù hợp mỗi khi máy chủ ứng dụng phát triển được cập nhật.


EDIT

Lưu ý rằng giấy chứng nhận OpenSSL Mac BUILTIN được lưu trữ trong /System/Library/OpenSSL, được bảo vệ với SIP/rootlessness, mà thẳng thắn là một nỗi đau để muck với và một tính năng đáng giá để giữ nếu chúng ta có thể.

Tôi đã xác minh rằng chứng chỉ xác thực bằng cách sử dụng openssl s_client -connect localhost:7500 -CAfile server.pem.

Nó đã được thêm vào Keychain và /usr/local/etc/openssl/certs với định dạng hash.# trong đó băm xuất phát từ openssl x509 -subject_hash -in server.pem (hoặc seb homebrew, cụ thể là /usr/local/Cellar/openssl/1.0.2d_1/bin/openssl). Trong trường hợp đó, /usr/local/Cellar/openssl/1.0.2d_1/bin/openssl s_client -connect localhost:7500 xác minh chứng chỉ (nhưng vẫn không có python).

Tôi đã thử sử dụng phiên bản homebrew của python và openssl, nhưng không có kết quả. Chạy như sau trong Python có vẻ luôn thất bại;

./pve/bin/python -c "import requests; requests.get('https://localhost:7500')" 

này cũng không nơi SSL_CERT_FILE được thiết lập để chứng chỉ của máy chủ (ví dụ: cho thêm một biện pháp có thể mong đợi nó để làm việc kể từ khi lệnh openssl về cơ bản các công trình như thế này), và cũng không nơi SSL_CERT_PATH được thiết lập để /usr/local/etc/openssl/certs.

Note, pve là một env ảo nơi help(ssl) cho thấy một FILE của /usr/local/Cellar/python/2.7.10_2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ssl.py

Tiếp tục xác minh rằng homebrew Python của _ssl.so liên kết đến các homebrew của OpenSSL Tôi chạy:

xcrun otool -L /usr/local/Cellar /python/2.7.10_2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-dynload/_ssl.so

trả về

./Cellar/python/2.7.10_2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-dynload/_ssl.so:

/usr/local/opt/openssl /lib/libssl.1.0.0.dylib (phiên bản tương thích 1.0.0, phiên bản hiện tại 1.0.0)

/usr/local/opt/openssl/lib/libcrypto.1.0.0.dylib (phiên bản tương thích 1.0. 0, phiên bản hiện tại 1.0.0)

/usr/lib/libSystem.B.dylib (tương thích phiên bản 1.0.0, phiên bản hiện tại 1225.1.1)

.210

Nếu một chạy brew info openssl nó nhận xét dưới CAVEATS:

Một tập tin CA đã được bootstrapped sử dụng giấy chứng nhận từ hệ thống keychain. Để thêm các chứng chỉ bổ sung, đặt .pem nào tập tin trong /usr/local/etc/openssl/certs

nhưng rõ ràng đối với một số lý do python không sử dụng thuật toán openssl homebrew của cho việc tìm kiếm chứng chỉ.

Vì vậy, tôi vẫn không biết tại sao thư viện chuẩn của Python không xác thực chứng chỉ nằm trong thư mục OpenSSL được chỉ định trong tài liệu cũng như Keychain (ở cả hai định dạng .pem.p12, với "luôn tin cậy" cho Secure Sockets Layer (SSL)).

Trả lời

8

Đây là lỗi dev_appserver do thay đổi hành vi httplib.HTTPSConnection (kiểm tra chứng chỉ được bật theo mặc định) trong một số bản phát hành Python gần đây (tôi tin 2.7.9).

Như lỗi này là trong nội bộ dev_appserver mã (tập tin google_appengine/google/appengine/api/urlfetch_stub.py của appengine SDK) được điều hành một cách độc lập của ứng dụng thử nghiệm, không có cách nào để làm cho một sửa chữa mà sẽ tồn tại một bản cập nhật SDK.

Cách khắc phục vĩnh viễn duy nhất tôi có thể nghĩ là bật validate_certificate và thêm chứng chỉ CA vào tệp urlfetch_cacerts.txt. Để sửa chữa tạm thời, bạn có thể vá urlfetch_stub.py với giải pháp thay thế # 3.

+0

Cảm ơn @Alex. Nếu không thể thêm chứng chỉ vào hệ thống của Mac, Httplib của Python sẽ sử dụng? –

+0

Brian, tôi không phải là rất quen thuộc với cách python ssl lib hoạt động trên Mac, tôi sẽ kiểm tra [ssl doc page] (https://docs.python.org/2/library/ssl.html#ssl-contexts) và xem chuỗi đường dẫn mặc định là gì: 'ssl.get_default_verify_paths()'. Có thể có một cách để sử dụng [biến env để đặt đường dẫn đến tệp chứng chỉ của bạn] (https://www.python.org/dev/peps/pep-0476/#trust-database). – Alex

+0

[Đây là tài liệu liên quan] (http://gagravarr.org/writing/openssl-certs/others.shtml) về cách thêm cert tự ký cho openssl. – Alex

1

Tôi đã gặp sự cố tương tự trên Windows. Tôi đã sử dụng một phiên bản cũ của Python (2.7). Khi tôi nâng cấp lên Python 2.7.11, vấn đề đã biến mất.

Các vấn đề liên quan