skyfielders / python-skyfield

Elegant astronomy for Python
MIT License
1.39k stars 209 forks source link

Can't download de421.bsp due to new OpenSSL restriction (Update: Fixed by JPL) #740

Closed jak574 closed 2 years ago

jak574 commented 2 years ago

I'm reporting this, despite the fact it's not strictly caused by Skyfield itself, but I've encoutered it a few times recently. I'm getting an error when trying to download ds421.bsp, the error looks like this:

OSError: cannot download https://ssd.jpl.nasa.gov/ftp/eph/planets/bsp/de421.bsp because 
<urlopen error [SSL: UNSAFE_LEGACY_RENEGOTIATION_DISABLED] unsafe legacy renegotiation 
disabled (_ssl.c:1129)>

This appears to be caused by an update to OpenSSL which now blocks websites that have not had the security issue CVE-2009-3555 fix yet. Apparently JPL's website is such a website. The OpenSSL checkin that's causing the crash can be found here:

https://github.com/openssl/openssl/commit/72d2670bd21becfa6a64bb03fa55ad82d6d0c0f3

I found a detailed discussion of the issue, and a work around here:

https://bugs.launchpad.net/ubuntu/+source/openssl/+bug/1963834

Although I applied the fix (at a system level), and it worked, clearly the fix is that JPL needs to update their website, however as this is causing Skyfield to essentially break, I wondered if a work around, perhaps fetching this (and probably other affected files) from another location might be a good fix.

Of course, the best way to fix it would be to get JPL to fix their webserver, but I don't know how realistic that is, knowing how NASA IT works.

jak574 commented 2 years ago

I've looked into this some more and there is a work around. Here is a modified snippet from iokit.py:

if create_default_context is not None:
    ssl_context = create_default_context(cafile=certifi.where())
    ssl_context.options |= 4
    connection = urlopen(url, context=ssl_context)

The ssl_context.options |= 4 enables OP_LEGACY_SERVER_CONNECT. Full credit, I found this solution on here:

SSL error unsafe legacy renegotiation disabled

I tested the above change, and it fixed the issue on my computer at least.

jak574 commented 2 years ago

I contacted JPL folks about this, and they passed on the issue to their IT. Didn't sound very convinced a fix would be quick, but it might happen.

davidmikolas commented 2 years ago

@jak574 Can you try it again now? I think there's been some action already.

jak574 commented 2 years ago

@jak574 Can you try it again now? I think there's been some action already.

Yep, it works now. openssl now reports "Secure Renegotiation IS supported". I guess this problem is fixed (by JPL).

kaya4me2 commented 2 years ago

Yes, confirmed the JPL interface problem seems now fixed and code snippets described

https://astroquery.readthedocs.io/en/latest/jplhorizons/jplhorizons.html

such as

from astroquery.jplhorizons import Horizons

obj = Horizons(id='Ceres', location='568', ... epochs={'start':'2010-01-01', 'stop':'2010-03-01', ... 'step':'10d'}) eph = obj.ephemerides() print(eph)

now work correctly and returns data without SSLEerror port=443 UNSAFE_LEGACY_RENEGOTIATION_DISABLED timeout

Thanks to JPL folks for timely fixing this

brandon-rhodes commented 2 years ago

@jak574 — Wow! They fixed it!

Thanks very much for opening an issue for this with a workaround. I was traveling to attend this year's PyCon, and it's so encouraging that even in my absence Skyfield users are flagging new failure modes, investigating solutions (involving SSL flags, no less!), and are even letting the JPL know about problems with their servers.

I'm going to close this issue based on my understanding that the issue is now resolved, but please comment further or re-open if it looks like there are still loose ends. Thanks!