AWS上使用ACM证书建立MongoDB TLS/SSL连接遇健康检查失败
解决方案:AWS上MongoDB TLS/SSL连接配置与NLB健康检查修复
一、修复NLB目标组健康检查失败问题
NLB的TCP健康检查失败通常和网络连通性、端口映射或安全组配置有关,按以下步骤排查修复:
验证端口映射与容器监听
确认EC2上的MongoDB容器已正确将27017端口映射到宿主机的所有网卡:docker ps | grep mongo # 输出需包含 0.0.0.0:27017->27017/tcp 格式的映射如果容器仅监听
127.0.0.1:27017,修改Docker运行命令,添加--bind_ip_all参数(MongoDB 4.0+)确保监听宿主机所有网卡:docker run -d -p 0.0.0.0:27017:27017 mongo --bind_ip_all调整EC2安全组规则
EC2实例的安全组需允许NLB所在VPC的CIDR范围(或NLB的安全组)发起的入站TCP 27017连接,用于健康检查和流量转发。Terraform配置示例:resource "aws_security_group" "ec2_mongo" { name = "mongo-ec2-sg" description = "Allow NLB traffic and health checks" vpc_id = aws_vpc.main.id ingress { from_port = 27017 to_port = 27017 protocol = "tcp" security_groups = [aws_security_group.nlb_sg.id] # 引用NLB的安全组 } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } }修正NLB目标组健康检查配置
NLB仅支持TCP层健康检查,若需验证MongoDB服务可用性,可在EC2上部署简单的健康检查代理:- 编写Python代理脚本(监听8080端口,执行MongoDB ping命令),加入user-data.sh:
#!/usr/bin/env python3 import socket from pymongo import MongoClient def health_check(): try: client = MongoClient('mongodb://localhost:27017') client.admin.command('ping') return b"OK\n" except: return b"FAILED\n" server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.bind(('0.0.0.0', 8080)) server_socket.listen(5) while True: client_socket, addr = server_socket.accept() response = health_check() client_socket.sendall(response) client_socket.close() - 在user-data中安装依赖:
pip3 install pymongo - 修改NLB目标组的健康检查端口为8080,同时在EC2安全组开放该端口给NLB。
- 编写Python代理脚本(监听8080端口,执行MongoDB ping命令),加入user-data.sh:
二、实现MongoDB的TLS/SSL连接
由于ACM证书无法下载到EC2实例,最优方案是在NLB层做TLS终止,客户端通过TLS连接NLB,NLB解密后以明文转发到EC2上的MongoDB容器:
配置NLB TLS监听器
在Terraform中创建NLB的TLS监听器,绑定ACM证书,转发到目标组的27017端口:resource "aws_lb_listener" "nlb_tls" { load_balancer_arn = aws_lb.mongo_nlb.arn port = "27017" protocol = "TLS" certificate_arn = aws_acm_certificate.mongo_cert.arn # 引用ACM证书ARN default_action { type = "forward" target_group_arn = aws_lb_target_group.mongo_tg.arn } }客户端连接配置
客户端连接时,指定NLB的Route53解析域名,启用TLS验证:mongo "mongodb://<NLB-DOMAIN>:27017/?tls=true&tlsAllowInvalidHostnames=false"若需双向TLS验证,将客户端证书上传到ACM,在NLB监听器中启用客户端证书验证即可,MongoDB无需额外配置。
可选:端到端加密方案
若必须实现MongoDB直接处理TLS,需自行生成证书并存储在AWS Secrets Manager中,通过user-data.sh拉取配置:# 从Secrets Manager拉取证书 aws secretsmanager get-secret-value --secret-id mongo-tls-cert --query SecretString --output text > /tmp/mongo-cert.json # 解析证书和私钥到文件 jq -r '.cert' /tmp/mongo-cert.json > /etc/mongo/tls.crt jq -r '.key' /tmp/mongo-cert.json > /etc/mongo/tls.key # 启动MongoDB容器并指定TLS参数 docker run -d -p 27017:27017 \ -v /etc/mongo:/etc/mongo \ mongo --tlsMode requireTLS --tlsCertificateKeyFile /etc/mongo/tls.crt --tlsCAFile /etc/mongo/ca.crt
内容的提问来源于stack exchange,提问作者Tom McLean
相关产品推荐
相关产品推荐

