crossbario / autobahn-python

WebSocket and WAMP in Python for Twisted and asyncio
https://crossbar.io/autobahn
MIT License
2.47k stars 768 forks source link

Better error reporting for failed TLS server cert verification #866

Open richardartoul opened 7 years ago

richardartoul commented 7 years ago

Hey ya'll,

This code works fine when I connect to localhost with ws://, but it fails when I try to use it with wss:// and a production server with a valid certificate. Specifically, my TLS certificate seems to get rejected (CA unknown) despite being valid. I've posted wireshark logs and a minimum reproduction below.

Here is the minimum reproduction:

from autobahn.twisted.wamp import Session
from autobahn.twisted.wamp import ApplicationRunner

from twisted.internet import reactor

def onClose(wasClean, code=None, reason=None):
    print(reason)

def create_disconnect_monkeypatch():
    """https://github.com/crossbario/autobahn-python/issues/559"""
    def connect_success(proto):
        orig_on_close = proto.onClose

        def fake_on_close(*args, **kwargs):
            if proto._session is None:
                onClose(*args, **kwargs)
            else:
                orig_on_close(*args, **kwargs)

        proto.onClose = fake_on_close
    return connect_success

class Test(Session):

  def onJoin(self, *args, **kwargs):
    print("Joined!")

application_runner = ApplicationRunner(
  url="wss://hyperdash.io/api/v1/sdk",
  realm="hyperdash.sdk",
)

application_runner_deferred = application_runner.run(
  Test,
  start_reactor=False,
  auto_reconnect=False,
)

application_runner_deferred.addCallback(
    create_disconnect_monkeypatch(),
)

reactor.run()

This generates logs like this:

(env)richie$ python repo.py 
connection was closed uncleanly (peer dropped the TCP connection without previous WebSocket closing handshake)

Executing pip freeze shows these dependencies:

asn1crypto==0.22.0
attrs==17.2.0
autobahn==17.6.2
Automat==0.6.0
cffi==1.10.0
constantly==15.1.0
cryptography==1.9
enum34==1.1.6
hyperlink==17.2.1
idna==2.5
incremental==17.5.0
ipaddress==1.0.18
pyasn1==0.2.3
pyasn1-modules==0.0.9
pycparser==2.17
pyOpenSSL==17.1.0
service-identity==17.0.0
six==1.10.0
Twisted==17.5.0
txaio==2.8.0
zope.interface==4.4.2
python --version
Python 2.7.10
openssl version
OpenSSL 1.0.2l  25 May 2017
which openssl
/Users/richie/anaconda3/bin/openssl

In a python REPL:

>>> import ssl
>>> ssl.OPENSSL_VERSION
'OpenSSL 0.9.8zh 14 Jan 2016'

I thought maybe it was related to an old version of openssl, but when I run the code using Conda which has a newer version:

conda REPL:

>>> import ssl
>>> ssl.OPENSSL_VERSION
'OpenSSL 1.0.2l  25 May 2017'

I still get the same error.

Any thoughts? The wireshark logs seem to indicate that thats a TLS issue (specifically, the CA unknown error), however, I'm pretty sure our certificate is fine:

openssl s_client -showcerts -connect hyperdash.io:443
CONNECTED(00000003)
depth=4 C = US, O = "Starfield Technologies, Inc.", OU = Starfield Class 2 Certification Authority
verify return:1
depth=3 C = US, ST = Arizona, L = Scottsdale, O = "Starfield Technologies, Inc.", CN = Starfield Services Root Certificate Authority - G2
verify return:1
depth=2 C = US, O = Amazon, CN = Amazon Root CA 1
verify return:1
depth=1 C = US, O = Amazon, OU = Server CA 1B, CN = Amazon
verify return:1
depth=0 CN = hyperdash.io
verify return:1
---
Certificate chain
 0 s:/CN=hyperdash.io
   i:/C=US/O=Amazon/OU=Server CA 1B/CN=Amazon
-----BEGIN CERTIFICATE-----
MIIEXDCCA0SgAwIBAgIQDvBr0vUpu8dU1eUBRrZR8DANBgkqhkiG9w0BAQsFADBG
MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRUwEwYDVQQLEwxTZXJ2ZXIg
Q0EgMUIxDzANBgNVBAMTBkFtYXpvbjAeFw0xNzA2MTEwMDAwMDBaFw0xODA3MTEx
MjAwMDBaMBcxFTATBgNVBAMTDGh5cGVyZGFzaC5pbzCCASIwDQYJKoZIhvcNAQEB
BQADggEPADCCAQoCggEBAMhG4HC0G38/+saEd9YjKxwxBwypUw7FF+MiJoYsPC4z
AhwdMRMmG+JYM8DM1oHz5zD6+AyrnvgZu+zr89lAD/ZpYW8oFUpKQm19mZ0JPRkz
P4qeUawpPJeGlrVbSTXOV7cO5VydGH4eVBvOiUacwpmezKMXvyZN3kdhrsDqX+NY
MUQHmtaONtadBJ/ucTU82TJtA7MkfStNlEY29ZCNFfslSRdGIQFJSnllhWmrcvGE
PM4ilRe3Tr8RuMZ74i9WghUL7FeFYV4k/nLLfhhzHMucMz5JtvSG/13G3ILAlLIY
yHJQ7cMVSakJuVAiEvFkY7xqauVB35xdM3B60LrK3kkCAwEAAaOCAXMwggFvMB8G
A1UdIwQYMBaAFFmkZgZSoHuVkjyjlAcnlnRb+T3QMB0GA1UdDgQWBBRS/0F75pzx
U42JooLskwpeS1BrHTAnBgNVHREEIDAeggxoeXBlcmRhc2guaW+CDiouaHlwZXJk
YXNoLmlvMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYB
BQUHAwIwOwYDVR0fBDQwMjAwoC6gLIYqaHR0cDovL2NybC5zY2ExYi5hbWF6b250
cnVzdC5jb20vc2NhMWIuY3JsMBMGA1UdIAQMMAowCAYGZ4EMAQIBMHUGCCsGAQUF
BwEBBGkwZzAtBggrBgEFBQcwAYYhaHR0cDovL29jc3Auc2NhMWIuYW1hem9udHJ1
c3QuY29tMDYGCCsGAQUFBzAChipodHRwOi8vY3J0LnNjYTFiLmFtYXpvbnRydXN0
LmNvbS9zY2ExYi5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAQEA
fwJ+IZX3RZEr0Li6zAJrJn2NS5DsNP0WvArljtnKhx4zDMwIZ8MCde1mponuSrZk
JQ3L0CqYBRCVPSHzbQZeMYnrpVHC0gwLwpJUKKe85wQCZLkFARL5nxEjnwqMokJG
r2tssSJ1CMmgiTI19KWmZsuGIORt9oHAJpzXZins7TpcMfpKYxmrS+VfbUZCMXhF
0eLmEiLyTCxQtavlyGyI/0A0y/AVb2higpax4082cRnQpY0fQgMo9zdi0mfsMIx8
fZv+hkjZpJz1w5w5HtKJtIYVt60W/UxP6VHB1vahoL+WCDkbB6x4Y7ns+nJoboGI
v1l/QyWbxuoZ2qPy1fF/5w==
-----END CERTIFICATE-----
 1 s:/C=US/O=Amazon/OU=Server CA 1B/CN=Amazon
   i:/C=US/O=Amazon/CN=Amazon Root CA 1
-----BEGIN CERTIFICATE-----
MIIESTCCAzGgAwIBAgITBn+UV4WH6Kx33rJTMlu8mYtWDTANBgkqhkiG9w0BAQsF
ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6
b24gUm9vdCBDQSAxMB4XDTE1MTAyMjAwMDAwMFoXDTI1MTAxOTAwMDAwMFowRjEL
MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEVMBMGA1UECxMMU2VydmVyIENB
IDFCMQ8wDQYDVQQDEwZBbWF6b24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
AoIBAQDCThZn3c68asg3Wuw6MLAd5tES6BIoSMzoKcG5blPVo+sDORrMd4f2AbnZ
cMzPa43j4wNxhplty6aUKk4T1qe9BOwKFjwK6zmxxLVYo7bHViXsPlJ6qOMpFge5
blDP+18x+B26A0piiQOuPkfyDyeR4xQghfj66Yo19V+emU3nazfvpFA+ROz6WoVm
B5x+F2pV8xeKNR7u6azDdU5YVX1TawprmxRC1+WsAYmz6qP+z8ArDITC2FMVy2fw
0IjKOtEXc/VfmtTFch5+AfGYMGMqqvJ6LcXiAhqG5TI+Dr0RtM88k+8XUBCeQ8IG
KuANaL7TiItKZYxK1MMuTJtV9IblAgMBAAGjggE7MIIBNzASBgNVHRMBAf8ECDAG
AQH/AgEAMA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUWaRmBlKge5WSPKOUByeW
dFv5PdAwHwYDVR0jBBgwFoAUhBjMhTTsvAyUlC4IWZzHshBOCggwewYIKwYBBQUH
AQEEbzBtMC8GCCsGAQUFBzABhiNodHRwOi8vb2NzcC5yb290Y2ExLmFtYXpvbnRy
dXN0LmNvbTA6BggrBgEFBQcwAoYuaHR0cDovL2NydC5yb290Y2ExLmFtYXpvbnRy
dXN0LmNvbS9yb290Y2ExLmNlcjA/BgNVHR8EODA2MDSgMqAwhi5odHRwOi8vY3Js
LnJvb3RjYTEuYW1hem9udHJ1c3QuY29tL3Jvb3RjYTEuY3JsMBMGA1UdIAQMMAow
CAYGZ4EMAQIBMA0GCSqGSIb3DQEBCwUAA4IBAQCFkr41u3nPo4FCHOTjY3NTOVI1
59Gt/a6ZiqyJEi+752+a1U5y6iAwYfmXss2lJwJFqMp2PphKg5625kXg8kP2CN5t
6G7bMQcT8C8xDZNtYTd7WPD8UZiRKAJPBXa30/AbwuZe0GaFEQ8ugcYQgSn+IGBI
8/LwhBNTZTUVEWuCUUBVV18YtbAiPq3yXqMB48Oz+ctBWuZSkbvkNodPLamkB2g1
upRyzQ7qDn1X8nn8N8V7YJ6y68AtkHcNSRAnpTitxBKjtKPISLMVCx7i4hncxHZS
yLyKQXhw2W2Xs0qLeC1etA+jTGDK4UfLeC0SF7FSi8o5LL21L8IzApar2pR/
-----END CERTIFICATE-----
 2 s:/C=US/O=Amazon/CN=Amazon Root CA 1
   i:/C=US/ST=Arizona/L=Scottsdale/O=Starfield Technologies, Inc./CN=Starfield Services Root Certificate Authority - G2
-----BEGIN CERTIFICATE-----
MIIEkjCCA3qgAwIBAgITBn+USionzfP6wq4rAfkI7rnExjANBgkqhkiG9w0BAQsF
ADCBmDELMAkGA1UEBhMCVVMxEDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNj
b3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4x
OzA5BgNVBAMTMlN0YXJmaWVsZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1
dGhvcml0eSAtIEcyMB4XDTE1MDUyNTEyMDAwMFoXDTM3MTIzMTAxMDAwMFowOTEL
MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv
b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj
ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM
9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw
IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6
VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L
93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm
jgSubJrIqg0CAwEAAaOCATEwggEtMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/
BAQDAgGGMB0GA1UdDgQWBBSEGMyFNOy8DJSULghZnMeyEE4KCDAfBgNVHSMEGDAW
gBScXwDfqgHXMCs4iKK4bUqc8hGRgzB4BggrBgEFBQcBAQRsMGowLgYIKwYBBQUH
MAGGImh0dHA6Ly9vY3NwLnJvb3RnMi5hbWF6b250cnVzdC5jb20wOAYIKwYBBQUH
MAKGLGh0dHA6Ly9jcnQucm9vdGcyLmFtYXpvbnRydXN0LmNvbS9yb290ZzIuY2Vy
MD0GA1UdHwQ2MDQwMqAwoC6GLGh0dHA6Ly9jcmwucm9vdGcyLmFtYXpvbnRydXN0
LmNvbS9yb290ZzIuY3JsMBEGA1UdIAQKMAgwBgYEVR0gADANBgkqhkiG9w0BAQsF
AAOCAQEAYjdCXLwQtT6LLOkMm2xF4gcAevnFWAu5CIw+7bMlPLVvUOTNNWqnkzSW
MiGpSESrnO09tKpzbeR/FoCJbM8oAxiDR3mjEH4wW6w7sGDgd9QIpuEdfF7Au/ma
eyKdpwAJfqxGF4PcnCZXmTA5YpaP7dreqsXMGz7KQ2hsVxa81Q4gLv7/wmpdLqBK
bRRYh5TmOTFffHPLkIhqhBGWJ6bt2YFGpn6jcgAKUj6DiAdjd4lpFw85hdKrCEVN
0FE6/V1dN2RMfjCyVSRCnTawXZwXgWHxyvkQAiSr6w10kY17RSlQOYiypok1JR4U
akcjMS9cmvqtmg5iUaQqqcT5NJ0hGA==
-----END CERTIFICATE-----
 3 s:/C=US/ST=Arizona/L=Scottsdale/O=Starfield Technologies, Inc./CN=Starfield Services Root Certificate Authority - G2
   i:/C=US/O=Starfield Technologies, Inc./OU=Starfield Class 2 Certification Authority
-----BEGIN CERTIFICATE-----
MIIEdTCCA12gAwIBAgIJAKcOSkw0grd/MA0GCSqGSIb3DQEBCwUAMGgxCzAJBgNV
BAYTAlVTMSUwIwYDVQQKExxTdGFyZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTIw
MAYDVQQLEylTdGFyZmllbGQgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0
eTAeFw0wOTA5MDIwMDAwMDBaFw0zNDA2MjgxNzM5MTZaMIGYMQswCQYDVQQGEwJV
UzEQMA4GA1UECBMHQXJpem9uYTETMBEGA1UEBxMKU2NvdHRzZGFsZTElMCMGA1UE
ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjE7MDkGA1UEAxMyU3RhcmZp
ZWxkIFNlcnZpY2VzIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gRzIwggEi
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDVDDrEKvlO4vW+GZdfjohTsR8/
y8+fIBNtKTrID30892t2OGPZNmCom15cAICyL1l/9of5JUOG52kbUpqQ4XHj2C0N
Tm/2yEnZtvMaVq4rtnQU68/7JuMauh2WLmo7WJSJR1b/JaCTcFOD2oR0FMNnngRo
Ot+OQFodSk7PQ5E751bWAHDLUu57fa4657wx+UX2wmDPE1kCK4DMNEffud6QZW0C
zyyRpqbn3oUYSXxmTqM6bam17jQuug0DuDPfR+uxa40l2ZvOgdFFRjKWcIfeAg5J
Q4W2bHO7ZOphQazJ1FTfhy/HIrImzJ9ZVGif/L4qL8RVHHVAYBeFAlU5i38FAgMB
AAGjgfAwge0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0O
BBYEFJxfAN+qAdcwKziIorhtSpzyEZGDMB8GA1UdIwQYMBaAFL9ft9HO3R+G9FtV
rNzXEMIOqYjnME8GCCsGAQUFBwEBBEMwQTAcBggrBgEFBQcwAYYQaHR0cDovL28u
c3MyLnVzLzAhBggrBgEFBQcwAoYVaHR0cDovL3guc3MyLnVzL3guY2VyMCYGA1Ud
HwQfMB0wG6AZoBeGFWh0dHA6Ly9zLnNzMi51cy9yLmNybDARBgNVHSAECjAIMAYG
BFUdIAAwDQYJKoZIhvcNAQELBQADggEBACMd44pXyn3pF3lM8R5V/cxTbj5HD9/G
VfKyBDbtgB9TxF00KGu+x1X8Z+rLP3+QsjPNG1gQggL4+C/1E2DUBc7xgQjB3ad1
l08YuW3e95ORCLp+QCztweq7dp4zBncdDQh/U90bZKuCJ/Fp1U1ervShw3WnWEQt
8jxwmKy6abaVd38PMV4s/KCHOkdp8Hlf9BRUpJVeEXgSYCfOn8J3/yNTd126/+pZ
59vPr5KW7ySaNRB6nJHGDn2Z9j8Z3/VyVOEVqQdZe4O/Ui5GjLIAZHYcSNPYeehu
VsyuLAOQ1xk4meTKCRlb/weWsKh/NEnfVqn3sF/tM+2MR7cwA130A4w=
-----END CERTIFICATE-----
---
Server certificate
subject=/CN=hyperdash.io
issuer=/C=US/O=Amazon/OU=Server CA 1B/CN=Amazon
---
No client certificate CA names sent
Peer signing digest: SHA512
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 5219 bytes and written 433 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES128-GCM-SHA256
    Session-ID: 928185310E190E60D629529C83C1E476ECD1EEB8EDA96B25ACA82D2F7599C104
    Session-ID-ctx: 
    Master-Key: BA5456ED1379C7D991D8955499C614F78FE36D75D4156D55112837D9EC030F776488C3ED6F722A65A6C1CE0D165B411D
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    TLS session ticket lifetime hint: 43200 (seconds)
    TLS session ticket:
    0000 - bd cb 52 c0 db 80 ea a1-15 4b a0 fd b1 a8 91 4e   ..R......K.....N
    0010 - a3 98 e1 2f 36 b1 6e a6-d9 26 99 00 26 ed 79 1a   .../6.n..&..&.y.
    0020 - 9e 43 4c 77 b2 6e 7b 66-57 eb a6 22 da 13 2a 8c   .CLw.n{fW.."..*.
    0030 - b1 ee 62 0e e5 9c f9 e7-60 f5 2c f3 ac 36 71 4f   ..b.....`.,..6qO
    0040 - d7 1e 3c cf 56 40 5b e7-6f fe da c7 bb 49 96 4c   ..<.V@[.o....I.L
    0050 - 3d 54 ba f4 60 86 9b 50-7c c1 b6 90 fc 26 b5 49   =T..`..P|....&.I
    0060 - 18 98 fa 5e 72 1d 29 c1-22 1b 5d 36 92 0d 46 86   ...^r.).".]6..F.
    0070 - d9 dd a4 63 26 d8 29 6e-7f 8b 85 cf 40 3b 07 ea   ...c&.)n....@;..
    0080 - 8c da d0 49 93 3b c7 4a-2a 10 c3 96 53 d2 24 fe   ...I.;.J*...S.$.
    0090 - 32 ab 7f bf 26 1d e2 7d-8c 0b 6d cb c8 05 3b 42   2...&..}..m...;B
    00a0 - c1 cd 4b e7 c0 d9 8a e4-07 de e4 78 5c 7c c2 e3   ..K........x\|..

    Start Time: 1499200369
    Timeout   : 300 (sec)
    Verify return code: 0 (ok)
---

autobahn_wamp_packets.pcapng.zip

meejah commented 7 years ago

Some of those packages are slightly out of date. I don't know how Python gets root certificates on Mac, but perhaps "pip install certifi" helps? If it does, then Python probably isn't finding the system root certificates properly.

richardartoul commented 7 years ago

Unfortunately the same problem persists after pip install certifi

meejah commented 7 years ago

There's a 17.2.0 for pyOpenSSL; does "pip install --upgrade autobahn" help? Does curl or a "normal" browser verify that site's certificate correctly? (FWIW, my browser on Linux does)

richardartoul commented 7 years ago

This problem doesn't occur with regular HTTPS requests (I.E this works fine):

import requests
requests.get('https://hyperdash.io/api/v1/sdk/wamp').content

Let me try upgrade

richardartoul commented 7 years ago

pip seems to think I'm up to date.

richie$ pip install --upgrade autobahn --no-cache-dir
Requirement already up-to-date: autobahn in ./env/lib/python2.7/site-packages
Requirement already up-to-date: six>=1.10.0 in ./env/lib/python2.7/site-packages (from autobahn)
Requirement already up-to-date: txaio>=2.7.0 in ./env/lib/python2.7/site-packages (from autobahn)
richie$ pip install --upgrade pyopssl --no-cache-dir
Requirement already up-to-date: pyopenssl in ./env/lib/python2.7/site-packages
Requirement already up-to-date: six>=1.5.2 in ./env/lib/python2.7/site-packages (from pyopenssl)
Requirement already up-to-date: cryptography>=1.9 in ./env/lib/python2.7/site-packages (from pyopenssl)
Requirement already up-to-date: ipaddress in ./env/lib/python2.7/site-packages (from cryptography>=1.9->pyopenssl)
Requirement already up-to-date: asn1crypto>=0.21.0 in ./env/lib/python2.7/site-packages (from cryptography>=1.9->pyopenssl)
Requirement already up-to-date: enum34 in ./env/lib/python2.7/site-packages (from cryptography>=1.9->pyopenssl)
Requirement already up-to-date: idna>=2.1 in ./env/lib/python2.7/site-packages (from cryptography>=1.9->pyopenssl)
Requirement already up-to-date: cffi>=1.7 in ./env/lib/python2.7/site-packages (from cryptography>=1.9->pyopenssl)
Requirement already up-to-date: pycparser in ./env/lib/python2.7/site-packages (from cffi>=1.7->cryptography>=1.9->pyopenssl)
(env) richie$ python repo.py 
connection was closed uncleanly (peer dropped the TCP connection without previous WebSocket closing handshake)
richardartoul commented 7 years ago

@meejah A little more digging seems to narrow this problem down to Twisted. I'm able to reproduce the issues as follows:

from __future__ import print_function

from twisted.internet import reactor
from twisted.web.client import Agent
from twisted.web.http_headers import Headers

agent = Agent(reactor)

d = agent.request(
    'GET',
    'https://google.com',)

def cbResponse(ignored):
    print('Response received')
d.addCallback(cbResponse)

def cbShutdown(ignored):
    reactor.stop()
d.addBoth(cbShutdown)

reactor.run()

In that snippet, "Response received" is never printed and the program just terminates. Wireshark logs show similar behavior with an Unknown CA error being thrown at the TLS level.

Replace the URL above with 'http://google.com' works fine though...

meejah commented 7 years ago

Hmm, okay. Thanks for the digging! That's ... weird.

The above snippet works for me on Debian with Twisted==17.5.0, pyOpenSSL==17.1.0, certifi==2017.4.17 so I'm going to guess this is Mac-only.

richardartoul commented 7 years ago

@meejah

What do you think of this? https://github.com/twisted/treq/issues/94#issuecomment-116226820

I'm not home to verify the suggested fix, but seems like this could be the issue.

meejah commented 7 years ago

What OS are you on?

richardartoul commented 7 years ago

OSX Sierra

meejah commented 7 years ago

Did you install Python with homebrew, or something else? (It seems like your Python or openSSL can't find any certificate roots at all). See the "note" about OS X here: https://twisted.readthedocs.io/en/twisted-17.5.0/core/howto/ssl.html

richardartoul commented 7 years ago

@meejah I figured out a solution, but its gross:

SSL_CERT_FILE="$(python -m certifi)" python test_script.py

Solves the problem

but since I need a programatic solution...

import os
from certifi import where
os.environ['SSL_CERT_FILE'] = where()

Also fixes it. At this point I'm probably just gonna ship it with this hack unless you have a better idea.

Also I'm happy to discuss how we can make this a better experience for other developers. I know its an issue with Twisted so its somewhat out of your hands, but maybe we can make Autobahn throw a more helpful error message or just do the environment hack I placed above?

meejah commented 7 years ago

See also: https://twistedmatrix.com/trac/ticket/9209

Looks like it might help to try "pip install certitude" instead, and/or install at least OpenSSL via homebrew. Did you install Python itself via homebrew or some other method? (In my past Mac experience, I found it much better to use the homebrew version of Python).

meejah commented 7 years ago

I'm leaving this open so that hopefully we can provide a better error (and/or some hints) for users.

@richardartoul can you confirm how you installed both Python and OpenSSL? (Basically: via homebrew or some other way?)

meejah commented 7 years ago

Also, it would be awesome if you can test an asyncio variant to see if you experience the same problem!

richardartoul commented 7 years ago

@meejah I'm actually not sure how I setup Python/OpenSSL on this machine. I've been writing software on it for 2 years so its possible I've reinstalled them multiple times and messed up the configuration. Anecdotally, two of my friends also have macbooks and it worked on one of their machines and not on the other.

If there are some commands you want me to run I'm happy to do it, but I probably won't dig into that too much further because I'm writing a library that needs to run on all machines and I won't be able to tell people to reinstall python or OpenSSL so I'll have to live with this certifi hack for now.

meejah commented 7 years ago

I'm just trying to learn what's special about how a "not working" machine is set up so hopefully we can steer new-installers in the right direction.

richardartoul commented 7 years ago

Sure, is there an easy way for me to check how I setup Python/OpenSSL?

meejah commented 7 years ago

Does which python or locate libssl turn up any hints?

oberstet commented 7 years ago

@richardartoul you could also try our Docker images for Autobahn. That way, you should be shielded from issues like this ..

meejah commented 7 years ago

For the record (as per the Twisted bug 9209 linked above), our install instructions for non-Docker (etc) users should tell people to use "homebrew" to install Python on Mac OS if they want TLS root certificates to "probably work".

richardartoul commented 7 years ago

Inside of virtual environment

(env)Richards-MacBook-Pro:test richie$ which python
/Users/richie/Documents/projects/test/env/bin/python
(env)Richards-MacBook-Pro:test richie$ which openssl
/Users/richie/anaconda3/bin/openssl

Outside of virtual environment

Richards-MacBook-Pro:test richie$ which python
/Users/richie/anaconda3/bin/python
Richards-MacBook-Pro:test richie$ which openssl
/Users/richie/anaconda3/bin/openssl

So looks like it doesn't work with anaconda, and also doesn't seem to work with the python installation in virtual environment either. I actually don't know how virtualenv works under the hood, is that symlink to system python or its own installation?

richardartoul commented 7 years ago

It doesn't seem like just telling people to use Docker is really a good enough solution though, in our case for example, we're developing a library for other people to run on their own machines.

Could we catch this error with a errback call where the Autobahn code calls into twisted?

richardartoul commented 7 years ago

@meejah I got this error when I ran locate libssl

WARNING: The locate database (/var/db/locate.database) does not exist.
To create the database, run the following command:

  sudo launchctl load -w /System/Library/LaunchDaemons/com.apple.locate.plist

Please be aware that the database can take some time to generate; once
the database has been created, this message will no longer appear.

Running the suggest command didn't fix it

oberstet commented 7 years ago

we're developing a library for other people to run on their own machines

What kind of machines (developer boxes or embedded devices)?

Curious: what library?

Could we catch this error with a errback call where the Autobahn code calls into twisted?

Yep, that would be definitely good. I changed the issue title to reflect that.

richardartoul commented 7 years ago

This is it: https://github.com/hyperdashio/hyperdash-sdk-py

The website's not up yet, but the idea is that it automatically monitors your machine learning jobs.

We originally stared with websockets and then realized that we had no way to signal back to the SDK that we failed to process a message so we're trying WAMP now for the RPC features

EDIT: Developer boxes

oberstet commented 7 years ago

Interesting! Thanks for sharing. Yeah, the combination of RPC+PubSub should bring you more flexibility at higher level of abstraction compared to raw WebSocket.

Also, should you use Crossbar.io as a WAMP router, you get more goodies for free, like the HTTP/REST bridge. I once needed to access data exposed in a registered WAMP procedure from Jupyter. Easy using the HTTP/REST bridge: I could call and fetch the data directly from a code snipped in my Jupyter workbook. Publishing is easy too. Registering/subscribing isn't obvious though.

Developer boxes: actually, personally I am pretty bullish on using Docker (also) for development. Eg I don't have a Java SDK on my notebook, all the toolchain is in a Docker toolchain container. Only thing I do on the host (notebook) is edit source code. So I can work on AutobahnJava without loosing more hair. It effectively shields me from all the details getting a complete environment and toolchain set up correctly. And I am doing this despite being on Ubuntu, which I guess has less issues (for a developer) compared to OSX/Windows. Like this TLS cert stuff. On the other hand, Docker experience on non-Linux is still lagging behind too. This toolchain Docker image approach saves me countless hours ..

richardartoul commented 7 years ago

Yeah I'll definetly look into the crossbar.io WAMP router at some point. Currently we're just using the Turnpike Golang library, but I'd like to dig into the official router some more and see what we could use it for.

Agreed I think Docker is great and we use it for development/production of our server, however, our target demographic for the library is data scientists who are already happy with their setup, but just want to be able to remotely monitor their jobs. Very smart people, but we're trying to give them a python package to import and forget about, not ask them to install docker.

I've also never heard of anyone running a deep learning job in a docker container, but I'm not an expert haha

oberstet commented 7 years ago

Ok, if your audience is more data scientists, they probably expect something easy working on Anaconda.

FWIW, even Anaconda seems to be pushing Docker: https://www.continuum.io/blog/developer-blog/anaconda-and-docker-better-together-reproducible-data-science

Eg this gets me started in like 1 minute

docker run -i -t -p 8888:8888 continuumio/anaconda3 \
   /bin/bash -c "/opt/conda/bin/conda install jupyter -y \
   --quiet && mkdir /opt/notebooks && /opt/conda/bin/jupyter notebook \
   --notebook-dir=/opt/notebooks --ip='*' --port=8888 --no-browser --allow-root"

I had to add --allow-root compared to above blog post.

meejah commented 7 years ago

Packaging Python applications for "end users' systems" still doesn't have as good a story as I would like :/

Docker is pretty good. "snapcraft"/snaps from Canonical and "flatpak" both sound very promising, though. There's also a tool called AppImage but it doesn't provide sandboxing like the first two. I haven't spent a lot of time looking into either of these very extensively, but they do at least aim to provide easy installation of "apps" on Linux systems.

oberstet commented 7 years ago

I think snaps are really promising. Also because it takes OS updates into account (an Ubuntu Core system completely consists of snap .. including kernel and OS userland).

snaps also run on most Linux distros these days

https://snapcraft.io/docs/core/install

However, the isolation only works with Ubuntu AppArmor enabled kernels currently (as far as I understand, not all Ubuntu AppArmor kernel mods are upstreamed yet).

Crossbar.io is currently available as a snap for x86-64 and armhf - aarch64 doesn't work yet in snapcraft.

meejah commented 7 years ago

Yeah, the sandboxing of flatpak uses SElinux (via 'bubblewrap') and works on more linux distros than just Ubuntu. However, I don't have a good way to compare them beyond that ;)

probonopd commented 7 years ago

Providing an AppImage would have, among others, these advantages:

Here is an overview of projects that are already distributing upstream-provided, official AppImages.

richardartoul commented 7 years ago

I understand the benefits of alternative packaging methods, but unfortunately I'm writing a pip installable library, not a stand-alone executable