Reputation: 4891
I am trying to copy some files to an Azure App using python as part of a wider python script.
I can do this using FTP, but I can not figure out how to do it in a secure way using TLS.
I am using the credentials I downloaded from the Azure Portal clicking on "Get Publish Profile", then using them inside the python code like this:
import ftplib
ftpServer = ftplib.FTP_TLS(host='waws-<...>.ftp.azurewebsites.windows.net',
user='<MY_USER>\$<MY_USER>',
passwd='<VERY_LONG_PSW>')
however when executing ftpServer.cwd('<THE_PATH_TO_INSPECT>')
then I see: ConnectionRefusedError: [Errno 111] Connection refused
When using ftplib.FTP(...)
instead of ftplib.FTP_TLS(...)
everything works as expected.
Looking at the Python docs here https://docs.python.org/3.5/library/ftplib.html it seems I should make sure there is some sort of implicit/explicit condition met, but I can not figure out what to do.
Reading on various web resources it seems I should use a different port than the standard 21, someone is saying 990, some other is saying 989, but I can not figure out where to specify this different port in the python code.
Connection refused
?EDIT 1:
It seems this implicit connection for FTP is related to TLS version 1.2 (as per python docs), I am not 100% sure as I am not familiar with these standards, however I've tried anyway but without success.
Bare in mind that <MY_USER>\$<MY_USER>
(and password) comes from the content of the file I download from the Azure Portal as a "Publish Profile", see below:
$ python
Python 3.6.6 |Anaconda, Inc.| (default, Jun 28 2018, 17:14:51)
[GCC 7.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>
>>>
>>>
>>>
>>> import ftplib
>>>
>>>
>>> ftpServer = ftplib.FTP_TLS(host='waws-<...>.ftp.azurewebsites.windows.net',
... user='<MY_USER>\$<MY_USER>',
... passwd='<VERY_LONG_PSW>')
>>>
>>>
>>>
>>> ftpServer.dir()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/<MY_USER>/Conda/lib/python3.6/ftplib.py", line 575, in dir
self.retrlines(cmd, func)
File "/home/<MY_USER>/Conda/lib/python3.6/ftplib.py", line 468, in retrlines
with self.transfercmd(cmd) as conn, \
File "/home/<MY_USER>/Conda/lib/python3.6/ftplib.py", line 399, in transfercmd
return self.ntransfercmd(cmd, rest)[0]
File "/home/<MY_USER>/Conda/lib/python3.6/ftplib.py", line 798, in ntransfercmd
conn, size = FTP.ntransfercmd(self, cmd, rest)
File "/home/<MY_USER>/Conda/lib/python3.6/ftplib.py", line 361, in ntransfercmd
source_address=self.source_address)
File "/home/<MY_USER>/Conda/lib/python3.6/socket.py", line 724, in create_connection
raise err
File "/home/<MY_USER>/Conda/lib/python3.6/socket.py", line 713, in create_connection
sock.connect(sa)
ConnectionRefusedError: [Errno 111] Connection refused
>>>
>>>
Upvotes: 0
Views: 1431
Reputation: 26324
Seems to work just fine on implicit FTPS (990/TCP):
$ openssl s_client -connect waws-prod-am2-119.ftp.azurewebsites.windows.net:990
CONNECTED(00000003)
[...]
---
Certificate chain
0 s:/C=US/ST=Washington/L=Redmond/O=Microsoft Corporation/
CN=waws-prod-am2-119.publish.azurewebsites.windows.net
i:/C=US/O=DigiCert Inc/CN=DigiCert SHA2 Secure Server CA
1 s:/C=US/O=DigiCert Inc/CN=DigiCert SHA2 Secure Server CA
i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Global Root CA
---
[...]
SSL handshake has read 3574 bytes and written 390 bytes
Verification: OK
---
New, TLSv1.2, Cipher is ECDHE-RSA-AES256-SHA384
Server public key is 2048 bit
[...]
SSL-Session:
Protocol : TLSv1.2
Cipher : ECDHE-RSA-AES256-SHA384
[...]
Verify return code: 0 (ok)
Extended master secret: yes
---
220 Microsoft FTP Service
The Python client library may be out of date or does not have a recent CA bundle containing the DigiCert CAs. You shouldn't be FTP-ing, try to upload to blob storage instead and have the Web App serve the files from that storage account (with a SAS signature if the files shouldn't be public).
If you're trying to deploy the Web App, use a git repo or Web Deploy, it's much more reliable.
Using ftplib
in stock Python 3.6:
>>> ftpServer = FTP_TLS(host='waws-prod-am2-119.ftp.azurewebsites.windows.net',
... user='myuser\$myuser',
... passwd='rM....dsFsfp')
>>> ftpServer.dir()
03-21-17 09:27AM <DIR> .ssh
02-22-18 08:19AM <DIR> ciphers
02-22-18 10:28AM <DIR> data
01-12-18 12:58AM <DIR> LogFiles
02-22-18 08:16AM <DIR> site
>>> ftpServer.cwd('data')
'250 CWD command successful.'
Upvotes: 1