【问题标题】:Secure FTP deployment for Azure App using python (using TLS or FTPS)使用 python(使用 TLS 或 FTPS)为 Azure 应用程序安全部署 FTP
【发布时间】:2019-01-14 16:02:42
【问题描述】:

我正在尝试使用 python 作为更广泛的 python 脚本的一部分将一些文件复制到 Azure 应用程序。

我可以使用 FTP 执行此操作,但我不知道如何使用 TLS 以安全的方式执行此操作。

我正在使用从 Azure 门户下载的凭据,单击“获取发布配置文件”,然后在 python 代码中使用它们,如下所示:

import ftplib

ftpServer = ftplib.FTP_TLS(host='waws-<...>.ftp.azurewebsites.windows.net',
                        user='<MY_USER>\$<MY_USER>',
                        passwd='<VERY_LONG_PSW>')

但是在执行ftpServer.cwd('&lt;THE_PATH_TO_INSPECT&gt;') 时,我看到:ConnectionRefusedError: [Errno 111] Connection refused

当使用 ftplib.FTP(...) 而不是 ftplib.FTP_TLS(...) 时,一切都按预期工作。

查看这里的 Python 文档 https://docs.python.org/3.5/library/ftplib.html 似乎我应该确保满足某种隐式/显式条件,但我不知道该怎么做。

阅读各种网络资源,似乎我应该使用与标准 21 不同的端口,有人说 990,有人说 989,但我不知道在 python 代码中在哪里指定这个不同的端口。

  • 我的代码有什么问题?为什么我看到Connection refused
  • 如何让 python 代码通过 FTP 建立安全的 TLS 连接?

编辑 1:

似乎 FTP 的这种隐式连接与 TLS 版本 1.2 相关(根据 python 文档),我不是 100% 确定,因为我不熟悉这些标准,但是我已经尝试过但没有成功。 请记住&lt;MY_USER&gt;\$&lt;MY_USER&gt;(和密码)来自我作为“发布配置文件”从 Azure 门户下载的文件的内容,见下文:

$ 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
>>> 
>>> 

【问题讨论】:

    标签: python-3.x azure azure-functions ftplib ftps


    【解决方案1】:

    似乎在隐式 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
    

    Python 客户端库可能已过期或没有包含 DigiCert CA 的最新 CA 包。您不应该使用 FTP,而是尝试上传到 blob 存储并让 Web 应用从该存储帐户提供文件(如果文件不应该公开,则使用 SAS signature)。

    如果您尝试部署 Web 应用,请使用 git repo 或 Web Deploy,它更可靠。

    使用库存 Python 3.6 中的ftplib

    >>> 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.'
    

    【讨论】:

    • openssl 连接中的用户/密码内容在哪里?查看从 Azure 门户下载的“发布配置文件”,他们提供了带有美元符号 $ 和密码的奇怪格式的用户名,就像我在 python 代码 sn-p 中所做的那样
    • 查看我的更新答案。我相信您不会登录,因为 TLS 会话没有建立。如果你可以切换到 Python 3.6,你应该会很好。
    • 我使用的是 Python 3.6,该代码不适用于我的情况。您的代码中的 myuser 是什么?我正在使用从门户网站下载的文件中的“发布配置文件”。另外:您的功能应用程序的设置是什么?如果我点击“应用程序设置”,那么我可以看到我的 FTP 配置设置为“FTP + FTPS”
    • 在问题正文中查看我的更新。看起来myuser somhow 正在影响 FTP+TLS 会话。我不确定发生了什么,您是否使用某种特殊用户?在 Function App 页面上并单击“获取发布配置文件”时,我愿意使用 Azure 门户中提供的那个
    • 是的,您的 Python 代码 sn-p 用于与 Azure 主机的 Azure FTP 连接,使用 TLS 的 Azure 凭据在从不同网络执行时有效。所以它必须是防火墙规则(这里另一个问题的另一个故事......)。感谢您的详细回答!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多