通过SSH隧道连接远程MySQL部署Streamlit时遇认证错误求助
解决SSH隧道连接MySQL时的"No password or public key available!"错误
针对你遇到的这个错误,以下是几个排查和解决方向:
修正SSH私钥的传递方式
你代码中直接传入ssh_pkey=("path_to_private_sshkey"),在Streamlit云部署环境中,本地路径肯定无效。建议用Streamlit Secrets管理私钥内容,而非依赖文件路径:import streamlit as st from sshtunnel import SSHTunnelForwarder, read_private_key import MySQLdb as db import pandas as pd def query(q): # 从Secrets读取私钥 pkey = read_private_key(st.secrets["ssh"]["private_key"]) with SSHTunnelForwarder( ssh_address_or_host=(st.secrets["ssh"]["host"], 22), ssh_username=st.secrets["ssh"]["username"], ssh_pkey=pkey, remote_bind_address=(st.secrets["mysql"]["remote_host"], st.secrets["mysql"]["remote_port"]) ) as server: conn = db.connect( host="localhost", port=server.local_bind_port, user=st.secrets["mysql"]["user"], passwd=st.secrets["mysql"]["password"], db=st.secrets["mysql"]["database"] ) return pd.read_sql_query(q, conn)对应的
.streamlit/secrets.toml配置:[ssh] host = "你的SSH服务器IP" username = "SSH用户名" private_key = """-----BEGIN RSA PRIVATE KEY----- 你的私钥完整内容,包含首尾行 -----END RSA PRIVATE KEY-----""" [mysql] remote_host = "MySQL服务器内网IP" remote_port = 3306 user = "MySQL用户名" password = "MySQL密码" database = "目标数据库名"修复代码中的参数错误
ssh_address_or_host必须是包含IP和端口的元组,比如("x.x.x.x", 22),仅传IP会导致连接逻辑异常;remote_bind_address的端口需要是整数,不要传字符串类型;- 如果坚持用文件路径,确保路径是部署环境中的绝对路径,且私钥文件权限设置为
600(SSH强制要求私钥不能被其他用户读取),可在部署脚本中添加chmod 600 /app/你的仓库名/私钥文件.pem。
验证私钥格式与有效性
- 确保私钥是PEM格式,若你用的是OpenSSH格式(新生成的密钥默认是这种),需要转换:
ssh-keygen -p -m PEM -f 你的私钥文件; - 本地先测试SSH连接:
ssh -i 私钥文件 用户名@服务器IP -L 3307:MySQL内网IP:3306,如果本地能成功建立隧道并连接MySQL,说明密钥和服务器配置无问题,问题仅出在部署环境的配置上。
- 确保私钥是PEM格式,若你用的是OpenSSH格式(新生成的密钥默认是这种),需要转换:
排查部署环境的密钥访问权限
Streamlit云环境中,若你上传了私钥文件,要确认文件被正确放置在代码目录下,且代码中引用的路径正确。避免用相对路径,尽量用绝对路径定位文件。
内容的提问来源于stack exchange,提问作者Cace
相关产品推荐
相关产品推荐

