使用 SSL 和 X 协议的 NodeJS mysql/xdevapi '访问被拒绝'

Posted

技术标签:

【中文标题】使用 SSL 和 X 协议的 NodeJS mysql/xdevapi \'访问被拒绝\'【英文标题】:NodeJS mysql/xdevapi 'Access denied' using SSL and X Protocol使用 SSL 和 X 协议的 NodeJS mysql/xdevapi '访问被拒绝' 【发布时间】:2020-05-06 19:51:18 【问题描述】:

我正在尝试使用 X 协议和 SSL 连接到我的 mysql 服务器。 为了连接到数据库,我使用 MySQL x devapi for NodeJs(mysql/xdevapi)。 MySQL 服务器和我的 nodejs 应用程序都在同一台机器上运行。但是,每次我尝试建立连接时,都会出现以下错误:

Error: Access denied for user 'accountservice'@'localhost' (using password: YES)
at AuthenticationHandler.BaseHandler.<computed> (F:\Repositorys\Project\Application\node_modules\@mysql\xdevapi\lib\Protocol\ResponseHandlers\BaseHandler.js:113:19)
at Array.entry (F:\Repositorys\Project\Application\node_modules\@mysql\xdevapi\lib\Protocol\ResponseHandlers\BaseHandler.js:90:29)
at WorkQueue.process (F:\Repositorys\Project\Application\node_modules\@mysql\xdevapi\lib\WorkQueue.js:75:19)
at Client.handleServerMessage (F:\Repositorys\Project\Application\node_modules\@mysql\xdevapi\lib\Protocol\Client.js:201:21)
at Client.handleNetworkFragment (F:\Repositorys\Project\Application\node_modules\@mysql\xdevapi\lib\Protocol\Client.js:245:14)
at Socket.<anonymous> (F:\Repositorys\Project\Application\node_modules\@mysql\xdevapi\lib\Protocol\Client.js:89:36)
at Socket.emit (events.js:315:20)
at addChunk (_stream_readable.js:296:12)
at readableAddChunk (_stream_readable.js:272:9)
at Socket.Readable.push (_stream_readable.js:213:10) 
 info: 
  severity: 0,
  code: 1045,
  sqlState: 'HY000',
  msg: "Access denied for user 'username'@'localhost' (using password: YES)"
 

起初我以为我的密码错误或者我的证书无效但使用mysql -u username -p --ssl-ca=/etc/certs/ca.pem --ssl-cert=../res/certs/mysql/client-cert.pem --ssl-key=../res/certs/mysql/client-key.pem 登录我没有错误。

除此之外,我还授予我的用户对所有数据库和表的所有权限,以确保缺少权限不是连接失败的原因。 我能想到的唯一可能是验证服务器证书时出错,即使openssl verify -CAfile ca.pem server-cert.pem 返回server-cert.pem: OK

要连接到数据库,我使用以下用 TypeScript 编写的代码

const conf = 
    host: 'localhost',//config.getHost(),
    port: 33060,//config.getPort(),
    user: 'username',//config.getUsername(),
    password: 'password',//config.getPassword(),
    schema: 'database',//config.getDatabase(),

    auth: 'SHA256_MEMORY', //removing this results in "Invalid authentication method PLAIN"

    ssl: 
        key: config.getCertKey(),
        cert: config.getCert(),
        ca: config.getCa()
    


this.client = mysql.getClient(conf);

connect(next) 
    console.log('Connecting to database ' + this.config.getDatabase() + '(' + this.config.getHost() + ':' + this.config.getPort() + ')...');
    this.client.getSession().then(session => 
        this.session = session;
        console.log('Connection to database ' + this.config.getDatabase() + '(' + this.config.getHost() + ':' + this.config.getPort() + ') established.');
        listen(this, next);
    ).catch((err) => 
        console.log('Failed to establish connection to database ' + this.config.getDatabase() + '(' + this.config.getHost() + ':' + this.config.getPort() + ').');
        console.log(err);
    );

也许我错过了一个非常重要的步骤,但目前我不知道是什么导致了这个问题,尽管我在 *** 和其他页面上阅读了多个答案。

【问题讨论】:

【参考方案1】:

公钥身份验证不是一流的 API 问题,但没有什么可以阻止您提供密钥,在这种情况下,在配置对象中的 sslOptions 属性(不是 ssl 属性)下。调用tls.connect() 时,这些选项将简单地合并。相比之下,API 支持证书颁发机构验证,在这种情况下,您只需定义 CA 文件的路径(如 here 所述)。

以下内容应该可以解决问题:

const conf = 
  //...
  sslOptions: 
    // read contents of key.pem and cert.pem
    key: fs.readFileSync('/path/to/key.pem')
    cert: fs.readFileSync('/path/to/cert.pem'),
    // path (only) to ca.pem
    ca: '/path/to/ca.pem'
  

如果您已经在使用 8.0.20 版本,则此风格已被弃用,您应该改用:

const conf = 
  //...
  tls: 
    key: fs.readFileSync('/path/to/key.pem')
    cert: fs.readFileSync('/path/to/cert.pem'),
    ca: '/path/to/ca.pem'
  

你得到Invalid authentication method PLAIN错误的原因是因为客户端很天真并且假设由于ssl不是true,那么这意味着应该禁用TLS,这不适用于PLAIN,默认值认证机制。

无论如何,一旦您开始改用sslOptions,这种情况就会消失。

免责声明:我是 MySQL X DevAPI Connector for Node.js 的首席开发人员

【讨论】:

感谢您的回答,现在终于可以使用了。我还找到了您在上面链接的网站并尝试使用“tls”,但我可能拼错了“tls”,写了“tsl”或其他内容,不幸的是再也没有尝试过......

以上是关于使用 SSL 和 X 协议的 NodeJS mysql/xdevapi '访问被拒绝'的主要内容,如果未能解决你的问题,请参考以下文章

使用TLS协议运行NodeJS

NodeJS - 使用协议 HTTPS 建立连接 WebSocket

用nodejs快速实现websocket服务端(带SSL证书生成)

如何使用NodeJs中的对象数组选择行

NodeJS 中的 AWS RDS SSL 连接错误

基于X.509证书和SSL协议的身份认证过程实现(OpenSSL可以自己产生证书,有TCP通过SSL进行实际安全通讯的实际编程代码)good