You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用SSH隧道连接MySQL主机失败问题求助

错误信息

Connection.Open() Error: MySqlConnector.MySqlException: 'Unable to connect to any of the specified MySQL hosts.'

问题描述

尝试多种代码方案仍触发上述错误,需通过跳板机连接EC2上的生产MySQL数据库。将连接字符串改为localhost时仅能连接本地数据库,端口转发操作未解决问题。

问题排查与修复方案

你的代码存在核心逻辑错误:构建了正确的隧道连接字符串connStr,但实际使用的却是配置文件中的mySQLConnectionString,直接导致端口隧道未被利用,自然无法连接生产库。同时还有几个细节需要调整:

  • 区分跳板机与数据库地址:当前代码把同一个_host同时用作SSH跳板机地址和数据库地址,若跳板机和EC2数据库不是同一台服务器,必须分开配置。
  • 端口转发目标地址:如果MySQL部署在EC2本地(相对于跳板机),目标地址应写127.0.0.1而非MyDbHost,跳板机访问本地数据库用localhost即可。
  • 延长连接超时时间:当前3秒超时过短,网络波动时极易失败,建议调整为15秒以上。

修正后的完整代码

static bool isFirstTimeSSH()
{
    Console.WriteLine("Verificando se é a primeira vez");

    // 跳板机配置
    string jumpboxHost = "你的跳板机IP或域名";
    int jumpboxPort = 22;
    string jumpboxUser = "MyUserSSH";
    string privateKeyPath = @"MyKeyPath";
    string privateKeyPassPhrase = "";

    // 生产MySQL配置(相对于跳板机的访问地址)
    string dbHost = "127.0.0.1"; // 若MySQL在EC2本地,跳板机访问用127.0.0.1;其他情况填实际地址
    int dbPort = 3306;
    string dbName = "database";
    string dbUser = "MyDbUser";
    string dbPass = "MyDbPass";

    var privateKeyStream = new PrivateKeyFile(privateKeyPath, privateKeyPassPhrase);
    var ci = new PrivateKeyConnectionInfo(jumpboxHost, jumpboxPort, jumpboxUser, privateKeyStream);         

    using (var client = new SshClient(ci))
    {
        client.Connect();
        if (client.IsConnected)
        {
            // 建立端口转发:本地随机端口 转发到 跳板机可访问的数据库地址
            var portForwarded = new ForwardedPortLocal("127.0.0.1", 0, dbHost, dbPort);
            client.AddForwardedPort(portForwarded);
            portForwarded.Start();                
            Console.WriteLine($"隧道已建立,本地绑定端口:{portForwarded.BoundPort}");

            // 使用隧道连接字符串
            string connStr = string.Format(
                "Server={0};Port={1};Database={2};Uid={3};Pwd={4};SslMode=none;default command timeout=30;Connection Timeout=15;MinimumPoolSize=20;maximumpoolsize=500",
                portForwarded.BoundHost, portForwarded.BoundPort, dbName, dbUser, dbPass);

            var connection = new MySqlConnection(connStr);
            var command = connection.CreateCommand();
            int numberOfTransactions = 0;

            try
            {
                connection.Open();
                command.CommandText = "SELECT count(*) FROM transactions;";
                using (MySqlDataReader reader = command.ExecuteReader())
                {
                    if (reader.Read())
                    {
                        numberOfTransactions = Convert.ToInt32(reader[0]);
                    }
                }
                return numberOfTransactions < 20;
            }
            finally
            {
                if (connection.State == ConnectionState.Open)
                    connection.Close();
                portForwarded.Stop();
                client.Disconnect();
            }                    
        }
        else
        {
            Console.WriteLine("无法连接到跳板机...");
            return false;
        }
    }
}

额外排查步骤

  • 验证跳板机连通性:在跳板机上执行mysql -h 数据库地址 -u 用户名 -p,确认能正常连接生产库。
  • 检查本地防火墙:确保本地未阻止隧道绑定的端口。
  • 确认私钥权限:Linux跳板机上的私钥文件权限需设置为600,避免权限过高导致SSH连接失败。

内容的提问来源于stack exchange,提问作者Gabriel Barros

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 05:12:08