Ghost 博客升级 node6.x 问题手记

原文来自静雅斋,转载请注明出处。javascript

0x00 状态

笔者博客是用 Ghost + PostgreSQL 搭建的,最近官方出了 RoadMap 作了 LTS 支持,所以作了 Ghost 的升级,同时也顺手把 node 升级到了 6.x 版本,本觉得小版本升级轻松无压力,结果重启 Ghost 的时候直接报错java

ERROR: password authentication failed for user "ghost" 

 error: password authentication failed for user "ghost"
    at Connection.parseE (/home/ghost/node_modules/.4.1.1@pg/lib/connection.js:534:11)
    at Connection.parseMessage (/home/ghost/node_modules/.4.1.1@pg/lib/connection.js:361:17)
    at TLSSocket.<anonymous> (/home/ghost/node_modules/.4.1.1@pg/lib/connection.js:105:22)
    at emitOne (events.js:96:13)
    at TLSSocket.emit (events.js:188:7)
    at readableAddChunk (_stream_readable.js:176:18)
    at TLSSocket.Readable.push (_stream_readable.js:134:10)
    at TLSWrap.onread (net.js:548:20)复制代码

0x01 回滚版本

碰到升级出错,第一反应就是回滚版本,已是习惯了,可是忘记以前的版本号了,只能尝试着回滚版本,可是发现全部版本都有这个问题,开始陷入僵局(笔者忘了 node 从 4.x 被升级到了 6.x)。因此只能暂时先将数据库从 PostgreSQL 迁移到了 MySQLnode

0x02 分析问题

从上面的错误信息来看是因为密码认证出错的问题致使的,可是实际上密码是正确的,PostgreSQL 支持 md5 和 password 两种方式认证,password 就是明文发送,笔者使用的是 ssl 加密而且使用 md5 认证,因而乎上服务器查 PostgreSQL 日志,可是并无发现认证出错的状况,照理来讲这里已经能够排除是数据库服务器的问题了,可是笔者又多作了一步,致使后面走了弯路。笔者将密码认证方式改成 password 明文发送,就 OK 了。结果就开始怀疑 pg 库和数据库的问题了。可是摸索了半天并无发现问题所在,而后 google 了也没有找到相似的状况,通常来讲,遇到问题就 google,80% 的问题都能解决,google 不到就去 github issue 上找,若是还找不到就只有两种状况,低级 bug 或者前无古人的 bug。git

0x03 线索

过了一段时间,偶然去了 npm 上面找了一下 pg 依赖包,发现这个版本已经到了 6.1.2 版本了,而 Ghost 官方依赖的版本是 4.1.1,就开始怀疑是否是 pg 版本太低的缘由了。与此同时,在 Ghost 官方博客上面也找到了一条声明,表示因为你们都用 MySQL,PostgreSQL 没人能提交意见,所以准备将 PostgreSQL 降级为“二等公民”。因此就前往 pg 库的 issue 上找了一下,还真找到了两条用户关于升级 node 后的问题。升级到最新版本的 pg 依赖就解决了问题。github

0x04 源码

因为是升级 node6.x 带来的问题,应该是 API 上作了改动,最终发现是 Buffer 上出现的问题,源代码以下数据库

//password request handling
con.on('authenticationMD5Password', checkPgPass(function(msg) {
  var inner = Client.md5(self.password + self.user);
  var outer = Client.md5(inner + msg.salt.toString('binary'));
  var md5password = "md5" + outer;
  con.password(md5password);
}));复制代码

改为以下代码就成功了npm

//password request handling
con.on('authenticationMD5Password', checkPgPass(function(msg) {
  var inner = Client.md5(self.password + self.user);
  var outer = Client.md5(Buffer.concat([new Buffer(inner), msg.salt]));
  var md5password = "md5" + outer;
  con.password(md5password);
}));复制代码

实际上也不算是 Buffer 的问题,而是 crypto 模块如今默认认为字符串为 utf8,而不是 binary,若是没有指定 encoding,就会出现这个问题。服务器

0x05 解决方案

既然上游代码都已经修复了这个 bug,直接升级版本就好了,而后提一个 PR 到官方就 ok。google

相关文章
相关标签/搜索