JavaScript Lambda发送AWS SNS通知失败求助
S3病毒扫描Lambda函数SNS通知不触发问题排查
针对你遇到的「对象标记为dirty时SNS通知无法触发」的问题,从代码逻辑和AWS配置层面梳理几个核心排查方向:
1. 检查Lambda执行角色的SNS发布权限
Lambda的执行角色必须拥有sns:Publish权限,且目标SNS Topic的ARN需明确出现在权限策略的资源列表中:
- 登录IAM控制台,找到该Lambda对应的执行角色
- 确认附加的权限策略包含以下内容(替换为你的Topic ARN):
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "sns:Publish", "Resource": "arn:aws:sns:eu-west-1:96xxxxxxxxxx:test-cost-lambda" } ] }
2. 修正Clamscan错误状态码的判断逻辑
execSync执行clamscan抛出的错误中,退出码实际存储在err.code属性而非err.status,且clamscan的退出码有明确含义:
- 0:无病毒
- 1:发现病毒(对应dirty场景)
- 2:扫描过程出错(如文件读取失败、病毒库损坏)
先修改catch块的日志,打印完整错误信息确认实际退出码:
catch(err) { console.log('完整错误详情:', JSON.stringify(err, null, 2)); console.log('clamscan退出码:', err.code); console.log('clamscan stderr输出:', err.stderr?.toString()); // 调整判断条件为err.code === 1 if (err.code === 1) { // 原有标记dirty和发送SNS的逻辑... } }
3. 确认SNS Topic ARN的正确性
检查代码中SNS_TOPIC_ARN的准确性:
- 区域是否与Lambda所在区域匹配(跨区域发布需额外配置权限)
- 账号ID、主题名称是否存在拼写错误
- 可直接从SNS控制台复制正确的ARN替换代码中的值
4. 捕获SNS发布操作的错误
当前代码中sns.publish()的错误未被单独捕获,发布失败时不会有日志提示。建议给SNS操作添加独立的异常捕获:
// 发送SNS通知 try { await sns.publish({ TopicArn: SNS_TOPIC_ARN, Message: `Object ${record.s3.object.key} in bucket ${record.s3.bucket.name} has been tagged as dirty.` }).promise(); console.log('SNS通知发送成功'); } catch(snsErr) { console.log('SNS通知发送失败:', snsErr); }
5. 处理含特殊字符的临时文件路径
如果S3对象的Key包含斜杠(如docs/report.pdf),/tmp/${record.s3.object.key}会尝试创建子目录,但writeFileSync不会自动生成目录,可能导致clamscan扫描失败触发非1的错误码。可修改临时文件名规避:
// 将Key中的斜杠替换为下划线,避免创建子目录 const tempFileName = record.s3.object.key.replace(/\//g, '_'); writeFileSync(`/tmp/${tempFileName}`, s3Object.Body); // 扫描时使用新的临时文件名 execSync(`./bin/clamscan --database=./var/lib/clamav /tmp/${tempFileName}`); // 删除临时文件时也使用新文件名 unlinkSync(`/tmp/${tempFileName}`);
内容的提问来源于stack exchange,提问作者Sudip Pramanick
相关产品推荐
相关产品推荐

