Python通过SSH连接本地MySQL失败求助:SSHTunnelForwarder无法连接
解决SSHTunnelForwarder连接MySQL失败的问题
先看日志里的关键错误信息,这是问题的核心:
2020-10-09 17:19:41,160| TRA | Thread-3/0349@sshtunnel | #1 <-- ('127.0.0.1', 58390) to ('127.0.0.1', 3306) was rejected by the SSH server
2020-10-09 17:19:41,160| ERR | Thread-3/0384@sshtunnel | Could not establish connection from ('127.0.0.1', 38583) to remote side of the tunnel
这说明SSH隧道的端口转发请求被远程服务器拒绝了,进而导致pymysql连接时出现丢包报错。下面是针对性的解决方法:
1. 检查远程MySQL的绑定地址
远程MySQL可能只绑定了服务器的公网IP或特定网卡,而非127.0.0.1,导致隧道过来的本地连接无法访问:
- 登录远程服务器,找到MySQL配置文件(通常是
/etc/my.cnf或/etc/mysql/my.cnf) - 找到
bind-address参数,改成0.0.0.0(允许所有网卡连接)或者保留127.0.0.1(确保隧道请求属于本地连接) - 重启MySQL服务:
sudo systemctl restart mysql
2. 验证MySQL用户的连接权限
确保你的db_user拥有从远程服务器本地(localhost)连接的权限:
- 登录远程MySQL终端:
mysql -u root -p - 执行权限查询:
SELECT user, host FROM mysql.user WHERE user='db_user'; - 如果没有
'db_user'@'localhost'这条记录,添加权限:GRANT ALL ON db_name.* TO 'db_user'@'localhost' IDENTIFIED BY 'db_pass'; - 刷新权限:
FLUSH PRIVILEGES;
3. 修正代码中的错误并调整连接配置
原代码里有个明显的错误:pymysql不能直接用connection.execute执行查询,必须先创建cursor对象。同时调整隧道和连接参数,避免超时或地址绑定问题:
with SSHTunnelForwarder( (ssh_host, ssh_port), ssh_username=ssh_user, ssh_password=ssh_pass, remote_bind_address=('127.0.0.1', 3306), local_bind_address=('127.0.0.1', 0), # 让系统自动分配可用端口 logger=create_logger(loglevel=1) ) as tunnel: with pymysql.connect( host='127.0.0.1', user=db_user, passwd=db_pass, db=db_name, port=tunnel.local_bind_port, connect_timeout=10, # 添加超时时间,避免无限等待 charset='utf8mb4' ) as connection: print("!!!!!!!!!CONNECTED!!!!!!!!!!!") with connection.cursor() as cursor: cursor.execute("select * from BD.b_catalog limit 1") output = cursor.fetchone() # 获取查询结果 print(output)
4. 检查SSH服务器的端口转发设置
确保远程SSH服务器允许TCP转发:
- 登录远程服务器,编辑
/etc/ssh/sshd_config - 找到
AllowTcpForwarding参数,设置为yes(默认可能开启,但最好确认) - 重启SSH服务:
sudo systemctl restart sshd
按照这些步骤排查,应该能解决你的连接问题。
内容的提问来源于stack exchange,提问作者Andrew Gl
相关产品推荐
相关产品推荐

