I am trying to fetch some files via ftplib in my Python application Error I am constantly encountering:
[SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure (_ssl.c:1007)
My code to connect via FTP:
host = 'ftp.appareldownload.com'
ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
ssl_context.set_ciphers("AES256-GCM-SHA384")
ssl_context.set_alpn_protocols(["http/1.1"])
ftp = FTP_TLS()
ftp.ssl_context = ssl_context
ftp.connect(host)
ftp.login(user=user, passwd=passwd)
download_file(ftp, filename)
ftp.quit()
Tried adding all these ciphers and TLS protocol that I fetched from openssl s_client -connect ftp.appareldownload.com:21 -starttls ftp
o/p
CONNECTED(00000003)
depth=2 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root G2
verify return:1
depth=1 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = Thawte TLS RSA CA G1
verify return:1
depth=0 CN = ftp.appareldownload.com
verify return:1
---
Certificate chain
0 s:CN = ftp.appareldownload.com
i:C = US, O = DigiCert Inc, OU = www.digicert.com, CN = Thawte TLS RSA CA G1
a:PKEY: rsaEncryption, 2048 (bit); sigalg: RSA-SHA256
v:NotBefore: Mar 6 00:00:00 2023 GMT; NotAfter: Apr 5 23:59:59 2024 GMT
1 s:C = US, O = DigiCert Inc, OU = www.digicert.com, CN = Thawte TLS RSA CA G1
i:C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root G2
a:PKEY: rsaEncryption, 2048 (bit); sigalg: RSA-SHA256
v:NotBefore: Nov 2 12:24:25 2017 GMT; NotAfter: Nov 2 12:24:25 2027 GMT
2 s:C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root G2
i:C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root G2
a:PKEY: rsaEncryption, 2048 (bit); sigalg: RSA-SHA256
v:NotBefore: Aug 1 12:00:00 2013 GMT; NotAfter: Jan 15 12:00:00 2038 GMT
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIGHzCCBQegAwIBAgIQDF0nwoY6uFRmGjvTETk8oTANBgkqhkiG9w0BAQsFADBe
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMR0wGwYDVQQDExRUaGF3dGUgVExTIFJTQSBDQSBHMTAe
Fw0yMzAzMDYwMDAwMDBaFw0yNDA0MDUyMzU5NTlaMCIxIDAeBgNVBAMTF2Z0cC5h
cHBhcmVsZG93bmxvYWQuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
AQEA3ZRNQ6Eo3DPV68FAvRA18aJ0BjjMm5xERgErDqkNF67ScMG+SUy9LzYnZK0D
QS3m65soJ483HZXnBJTRuUi5PGTAOMvKU/wl2w/4JJQFPS7mQzkvh2wDb4k9h3J3
xPKQkhdqrdfDmP4qTYF5Gcewu28u5+YFG7olcvYtl73HG8kfCOj5MpQxeXDZ1gsi
Qt9P85fimO5pl31TCsEDItz7DdjpmbyEXZUmXypydQaY71BhI8i6fQ2C2MfsKIhA
stYJH1Gfge8nyx7/5+7T1t7tCs6oa5MoBVtEayPposRWdbHdJ6H3w6vOoU2rw2FO
6jVzO3MwRidGIR+9GYNHZOlhdQIDAQABo4IDEzCCAw8wHwYDVR0jBBgwFoAUpYz+
MszrDyzUGcYIuAAkiF3DxbcwHQYDVR0OBBYEFNkt68PBPoUQGzrsoXLzGFOkTGPP
MCIGA1UdEQQbMBmCF2Z0cC5hcHBhcmVsZG93bmxvYWQuY29tMA4GA1UdDwEB/wQE
AwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwOwYDVR0fBDQwMjAw
oC6gLIYqaHR0cDovL2NkcC50aGF3dGUuY29tL1RoYXd0ZVRMU1JTQUNBRzEuY3Js
MD4GA1UdIAQ3MDUwMwYGZ4EMAQIBMCkwJwYIKwYBBQUHAgEWG2h0dHA6Ly93d3cu
ZGlnaWNlcnQuY29tL0NQUzBwBggrBgEFBQcBAQRkMGIwJAYIKwYBBQUHMAGGGGh0
dHA6Ly9zdGF0dXMudGhhd3RlLmNvbTA6BggrBgEFBQcwAoYuaHR0cDovL2NhY2Vy
dHMudGhhd3RlLmNvbS9UaGF3dGVUTFNSU0FDQUcxLmNydDAJBgNVHRMEAjAAMIIB
fgYKKwYBBAHWeQIEAgSCAW4EggFqAWgAdgDuzdBk1dsazsVct520zROiModGfLzs
3sNRSFlGcR+1mwAAAYa4a/nUAAAEAwBHMEUCIFvJziHidLE6XYnfWfTYNB5n50wP
nQ8IXhX/+A1SWwIjAiEAwa2ab90sUntGHcFNQ8KfGKwPSRhJ79UNaYgZNjevOY4A
dwBIsONr2qZHNA/lagL6nTDrHFIBy1bdLIHZu7+rOdiEcwAAAYa4a/oIAAAEAwBI
MEYCIQDVJGon5z7/5Lf/+eE8NXjwrUxSOGx2s2SAsNJBJiFNEAIhAPKGzbMhJhET
J3kNPGJZy1GVzPoGeBfYSaYidVzK79qhAHUAO1N3dT4tuYBOizBbBv5AO2fYT8P0
x70ADS1yb+H61BcAAAGGuGv6DwAABAMARjBEAiBkxeMdebR8kPAT4O4N7mFTgqSZ
rN1pekPUs4m+M3YldAIgP0sAhVqQevfUnziARzUNw6xph5AQifIwkJcCRdJbyS0w
DQYJKoZIhvcNAQELBQADggEBAEnPkIBWpX1kaiu5YzZy0GoH6RLFPqfq8R+J73VH
a66phougREr+pM9dYh3UA675fqFcxNFCV74ogvW3AOCLXbB9MRkm2YE6jQVyTG9M
tjV98oRzifwyJcVb2MbqLWDefQUdoNkV0SGTtPZTUQktHjCzp/a4O1+++BQYpVmH
sDvSQpSFS7XYNIBzpbFMwrK5syiR9Wg96yeI2Lq9+flvY58GDgShat14MPt7M/Ri
LZiLEobPOYe7PejKWhqi4q6lqBsqRc1DdejtE0Yf9eZNJUbYBSmPN0S+hVZvEkNa
d7eA3BVsnMjVd2SXfzhwnQEdEqschy9APeZONZAbVRhebmI=
-----END CERTIFICATE-----
subject=CN = ftp.appareldownload.com
issuer=C = US, O = DigiCert Inc, OU = www.digicert.com, CN = Thawte TLS RSA CA G1
---
No client certificate CA names sent
---
SSL handshake has read 4099 bytes and written 657 bytes
Verification: OK
---
New, TLSv1.2, Cipher is AES256-GCM-SHA384
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1.2
Cipher : AES256-GCM-SHA384
Session-ID: 99F8A067156144FCE55741788AAC15E42759D4836B47FB7B90221920524995A7
Session-ID-ctx:
Master-Key: 0280D714F6F15ED7781AE92E94EE7BF355C435E4FE59A6A478CDD627D743C6CAC79482F65BA2D03CB96AFE8EB5DE47FF
PSK identity: None
PSK identity hint: None
SRP username: None
TLS session ticket lifetime hint: 300 (seconds)
TLS session ticket:
0000 - 24 6d b4 25 6f a5 b2 56-7b 9c 07 9d 14 71 88 5d $m.%o..V{....q.]
0010 - 98 db 8f 45 a8 fe 53 98-f4 2a 54 8b ae 49 d8 be ...E..S..*T..I..
0020 - cb f0 93 ed 6e c5 dc cb-b6 c9 69 90 cd 96 e0 f4 ....n.....i.....
0030 - 74 75 54 b4 67 79 ce 9f-8f 0d 11 dc 71 7d 1e 7a tuT.gy......q}.z
0040 - ac 8d 8d 0c 4e 20 1b 8a-81 4c 1e 9a 90 ba 9c 09 ....N ...L......
0050 - e4 30 bf 27 41 4e d7 81-d3 d1 6c 6f 90 cf c0 9d .0.'AN....lo....
0060 - cd 70 80 53 24 9d e5 a6-fb 2c 48 cd a7 07 59 a4 .p.S$....,H...Y.
0070 - ee ae 20 53 90 16 db fe-c2 74 86 48 25 d0 59 49 .. S.....t.H%.YI
0080 - 25 5b 6b c9 4d db 01 1a-b8 c1 f3 c3 64 0a 48 af %[k.M.......d.H.
0090 - eb 0f f3 10 31 bb b0 fc-b1 ea 4d 78 08 a2 cd 94 ....1.....Mx....
00a0 - 51 3f f3 86 bd a7 0b 1b-7c b8 1f 8f fb 73 c0 7a Q?......|....s.z
00b0 - 9f 59 74 65 ed cc 70 c0-c0 2d bc a1 f9 b8 18 4e .Yte..p..-.....N
Start Time: 1702873717
Timeout : 7200 (sec)
Verify return code: 0 (ok)
Extended master secret: no
---
220 ftp7.broderbros.com X2 WS_FTP Server 7.7(76106001)
closed
I am running it an docker container python:3.10.13-bookworm and OpenSSL version is OpenSSL 3.0.11 19 Sep 2023.
I tried adding the SSL contexts expecting passing of handshake. Still the issue remains.
stacktrace of the error
Attaching to my_python_app-1
my_python_app-1 | /app/main.py:29: DeprecationWarning: ssl.PROTOCOL_TLSv1_2 is deprecated
my_python_app-1 | ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
my_python_app-1 | *get* '220 ftp7.broderbros.com X2 WS_FTP Server 7.7(41376683)\n'
my_python_app-1 | *resp* '220 ftp7.broderbros.com X2 WS_FTP Server 7.7(41376683)'
my_python_app-1 | *cmd* 'AUTH TLS'
my_python_app-1 | *put* 'AUTH TLS\r\n'
my_python_app-1 | *get* '234 SSL enabled and waiting for negotiation\n'
my_python_app-1 | *resp* '234 SSL enabled and waiting for negotiation'
my_python_app-1 | Traceback (most recent call last):
my_python_app-1 | File "/app/main.py", line 45, in <module>
my_python_app-1 | testone().download_alpha('AllDBDiscoALP_4.txt')
my_python_app-1 | File "/app/main.py", line 37, in download_alpha
my_python_app-1 | ftp.login(user=user, passwd=passwd)
my_python_app-1 | File "/usr/local/lib/python3.10/ftplib.py", line 745, in login
my_python_app-1 | self.auth()
my_python_app-1 | File "/usr/local/lib/python3.10/ftplib.py", line 756, in auth
my_python_app-1 | self.sock = self.context.wrap_socket(self.sock, server_hostname=self.host)
my_python_app-1 | File "/usr/local/lib/python3.10/ssl.py", line 513, in wrap_socket
my_python_app-1 | return self.sslsocket_class._create(
my_python_app-1 | File "/usr/local/lib/python3.10/ssl.py", line 1104, in _create
my_python_app-1 | self.do_handshake()
my_python_app-1 | File "/usr/local/lib/python3.10/ssl.py", line 1375, in do_handshake```
my_python_app-1 | self._sslobj.do_handshake()
my_python_app-1 | ssl.SSLError: [SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure (_ssl.c:1007)
ftp = FTP_TLS()
ftp.ssl_context = ssl_context
The setting of ftp.ssl_context
has no effect. And it is not documented that it should have any effect. Instead the context should be given as argument to FTP_TLS
as documented:
ftp = FTP_TLS(context = ssl_context)
Since the original setting had no effect the more secure defaults of the newer Python and OpenSSL versions were used which have disabled RSA key exchange by default. Unfortunately the server seems to require RSA key exchange, so the connection with the default settings failed.