我的网站是一个expressjs应用程序,它被打包成一个docker镜像,并在ALB后面的AWS Fargate中运行。域上有大量cookie(~7KB)的用户遇到400 HTTP错误。但是,如果用户清除其Cookie,则问题会清除,至少几天后才会重新安装已删除的Cookie。我是这个域名的一个子域名,我没有政治影响力来减少cookie数量,或者如何安装cookie;我在一家大公司工作。
我已经消除了ALB导致错误的原因。 CloudWatch指标,HTTPCode_ELB_4XX_Count为0,而HTTPCode_Target_4XX_Count在我测试此错误时激增。
我的诊断设置如下:在我的预生产AWS账户中,我已将DEBUG
环境变量设置为容器上的*
。我还将目标组的健康检查减少到每5分钟运行一次(以减少聊天),并将任务计数减少到1(将日志集中到一个cwlog流中)。 Expressjs应记录它路由的任何传入请求,与Expressjs's debugging page类似,但是,日志中绝对没有输出任何内容。就好像请求没有达到expressjs。我想也许我搞砸了设置,但是在隐身模式下测试会打印很多调试语句。
使用邮递员,我已经从Chrome CDT复制了Cookie标题;我继续使用响应中包含的Connection: close
头获得相同的400结果。我正在使用express-sessions
模块,如果我删除了会话cookie(connect.sid
),请求就可以了。如果我删除除connect.sid
之外的所有cookie(保留旧值),则请求有效。如果我发送所有cookie,但将connect.sid
更新为Set-Cookie
返回的值,则该请求有效。
如果我使用docker-compose
在本地尝试相同的测试,我无法重现400错误响应问题。 docker-compose和fargate中的docker图像相同。两者都通过connect-pg-simple
模块使用postgres作为会话存储。因此,可能存在AWS网络堆栈或AWS Fargate运行时环境中的某些内容。
package.json中的相关依赖项:
"connect-pg-simple": "^5.0.0",
"express": "^4.16.4",
"express-session": "^1.11.1",
"helmet": "^3.15.0",
"method-override": "^3.0.0",
"morgan": "^1.9.1",
"pg": "^7.6.1",
以下是我的代码的一些摘录。我已经包含了其他安装库,以防它们发生冲突,但是省略了护照。
const express = require('express');
const compression = require('compression');
const helmet = require('helmet');
const methodOverride = require('method-override');
const pg = require('pg');
const session = require('express-session');
const pgSession = require('connect-pg-simple')(session);
const sessionStore = new pgSession({
pool: new pg.Pool()
});
const app = express();
app.use(methodOverride());
app.use(compression());
app.use(helmet({
// helmet settings omitted
}));
app.enable('trust proxy'); // Process X-Forwarded-* headers
app.use(session({
cookie: {
httpOnly: true,
secure: true
},
name: 'connect.sid',
resave: false,
saveUninitialized: true,
secret: 'some secret here',
store: sessionStore
}));
// rest of the code
我很乐意收到任何提示,指示,建议和澄清问题。花了几个小时后,我可以用一个全新的视角。
通过我使用快速会话模块记录的bug report上的对话,我找到了答案。在November 2018中,最大http标头长度从80KB减少到8KB以解决CVE问题。这影响了所有受支持的nodejs版本(v6,v8,v10)。对于那些面临类似问题的人,请升级到最新的nodejs微版本,它引入了--max-http-header-size flag。对于nodejs v10,这是在v10.15中引入的。