首页 > 解决方案 > Azure Functions (Python) 无法使用 [SSL: WRONG_VERSION_NUMBER] 连接到 Azure MySQL 实例

问题描述

我正在使用 Python 创建一个简单的 Azure 函数。它只是简单地从 Azure MySQL 实例中读取并将某些内容写回同一实例。但是,我无法成功连接到数据库。

import logging
from datetime import datetime

import azure.functions as func
import mysql.connector
from mysql.connector import errorcode

def connect_to_db():
    logging.info(os.getcwd()) 
    try:
        db_conn = mysql.connector.connect(
            user="...", 
            password='...', 
            host="....mysql.database.azure.com", 
            port=3306, 
            database='...'
        )
        return db_conn
    except mysql.connector.Error as err:
        if err.errno == errorcode.ER_ACCESS_DENIED_ERROR:
            logging.error("Something is wrong with your user name or password")
        elif err.errno == errorcode.ER_BAD_DB_ERROR:
            logging.error("Database does not exist")
        else:
            logging.error(err)

    return None


def main(req: func.HttpRequest) -> func.HttpResponse:
    logging.info('Python HTTP trigger function processed a request.')

    db_conn = connect_to_db()
    if db_conn:
        logging.info('DB Connection is established {}'.format(db_conn))
    else:
        return func.HttpResponse(
             "Azure Functions cannot connect to MySQL database.",
             status_code=500
        )

    ....

当我使用时,代码在我的本地机器上运行良好func host start,我也使用了相同的 Azure MySQL 实例。

但是,在我部署了 Azure 函数后,它不起作用并给我以下错误:

2055: Lost connection to MySQL server at '....mysql.database.azure.com:3306', 
system error: 1 [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:852)

我还尝试在 Azure 门户中禁用“SSL 强制”,并启用Allow access to Azure services,这没有帮助。

任何帮助和意见将不胜感激!谢谢!

标签: pythonsslazure-functionsazure-mysql-database

解决方案


我最终自己解决了这个问题。

以下是步骤:

  1. 从 Azure 文档存储库下载 SSL 证书。你可以在这里得到它:https ://docs.microsoft.com/en-us/azure/mysql/howto-configure-ssl

  2. 将证书文件与 Azure Function 项目一起放置。对我来说,我把它放在项目的根文件夹中,因为我可能在这个项目中有多个需要这个证书的功能

  3. 然后,在python代码中获取认证文件如下

    import pathlib
    
    def get_ssl_cert():
        current_path = pathlib.Path(__file__).parent.parent
        return str(current_path / 'BaltimoreCyberTrustRoot.crt.pem')
    
  4. 所以,当我连接到 MySQL 时,我可以使用 SSL 证书

    # Connect to MySQL
    cnx = mysql.connector.connect(
        user="ctao@azure-mysql-test", 
        password='*******', 
        host="azure-mysql-test.mysql.database.azure.com", 
        port=3306, 
        database='ciscoepcstats',
        ssl_ca=get_ssl_cert()
    )
    

PS 出于安全考虑,我不能选择禁用 SSL 验证。但幸运的是我找到了解决方案。


推荐阅读