我正在尝试使用指向亚马逊提供的 DNS 记录的 Route 53 DNS CNAME 记录连接到 MSK 集群。
AWS MSK DNS:
b-1.msksandbox.nrfnuy.c42.kafka.us-east-1.amazonaws.com
我需要使用的 DNS:b-1.msk.sandbox.internal.company.com
我得到的错误:
Error while executing topic command : SSL handshake failed
ERROR org.apache.kafka.common.errors.SslAuthenticationException: SSL handshake failed
Caused by: javax.net.ssl.SSLHandshakeException: No subject alternative DNS name matching b-1.msk.sandbox.internal.company.com found.
Caused by: java.security.cert.CertificateException: No subject alternative DNS name matching b-1.msk.sandbox.internal.company.com found.
当我查看服务器证书时它说
Server certificate
subject=CN = *.msksandbox.nrfnuy.c42.kafka.us-east-1.amazonaws.com
issuer=C = US, O = Amazon, OU = Server CA 1B, CN = Amazon
我想知道是否可以让 Route 53 和 MSK 一起工作(我使用的是 IAM 身份验证)
你可以用 NLB 实现这个。 然后您将在 NLB 上附加证书。您的证书将在 NLB 上终止。 NLB 和 MSK 之间的连接将使用 MSK 证书。
暂不支持自定义域名
为了使用 R53 和证书实现自定义域名,您需要在 NLB 处终止证书,然后目标组将创建一个连接到代理的……IP 地址,因为在target group 您可以指定的只是IP,而不是经纪人的域名。 NLB 和代理之间的 SSL 连接将失败,因为代理的 IP 地址未添加到部署在代理端的证书中,因此 NLB 不会信任该连接。
唯一可行的方法是在 NLB 和 MSK 之间使用 PLAINTEXT 连接(端口 9092)。但这是不安全且不推荐的方法。
我搜索并搜索了一种能够使用虚名 DNS 名称而不是 AWS 为 MSK 代理生成的 DNS 名称来引导 Kafka 客户端的方法。
在拼凑来自不同来源的信息后,我和我的团队终于找到了解决方案。这是我们的解决方案。
对于每个 MSK 经纪商:
MSK 经纪人的 IP 地址是通过他们的 DNS A 记录查找的
这是地形配置。希望对你有帮助:
locals {
msk_scram_addrs = split(",", aws_msk_cluster.myclust.bootstrap_brokers_sasl_scram)
msk_scram_hosts = toset([for x in local.msk_scram_addrs : split(":", x)[0]])
// b-1, b-2, b-3, ...
broker_short_names = toset([
for a in data.dns_a_record_set.myclust_scram_brokers :
split(".", a.host)[0]
])
}
data "dns_a_record_set" "myclust_scram_brokers" {
for_each = local.msk_scram_hosts
host = each.value
depends_on = [
aws_msk_cluster.myclust
]
}
resource "aws_lb" "msk_broker" {
for_each = local.broker_short_names
name = each.value
tags = [...]
internal = false
subnets = local.aws_vpc_public_subnets
load_balancer_type = "network"
idle_timeout = 3600
timeouts {
create = "20m"
}
}
resource "aws_lb_target_group" "msk_broker_scram_public" {
for_each = local.broker_short_names
name = each.value
tags = [...]
# https://aws.amazon.com/blogs/aws/new-tls-termination-for-network-load-balancers/
protocol = "TLS"
vpc_id = local.aws_vpc_id
target_type = "ip" // Targets Kafka broker by IP address.
port = 9196
lifecycle {
create_before_destroy = true
}
depends_on = [
aws_lb.msk_broker
]
}
resource "aws_lb_target_group_attachment" "msk_broker_scram_public" {
for_each = {
for a in data.dns_a_record_set.myclust_scram_brokers : split(".", a.host)[0] => a.addrs[0]
}
target_group_arn = aws_lb_target_group.msk_broker_scram_public[each.key].arn
target_id = each.value // This is the Kafka broker IP address.
}
resource "aws_lb_listener" "msk_bootstrap_public" {
for_each = local.broker_short_names
# https://aws.amazon.com/blogs/aws/new-tls-termination-for-network-load-balancers/
protocol = "TLS"
port = 9196
certificate_arn = module.msk_lb_cert[each.value].acm_cert.arn
load_balancer_arn = aws_lb.msk_broker[each.value].arn
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.msk_broker_scram_public[each.value].arn
}
lifecycle {
create_before_destroy = true
}
}
module "msk_lb_cert" {
source = "../certificates"
for_each = local.broker_short_names
org_public_zone_id = local.org_zone_id
io_public_zone_id = data.aws_route53_zone.io_public.zone_id
org_domain_name = "${each.value}.${local.params.msk_org_domain}"
vanity_domain_names = [
"${each.value}.${local.params.msk_vanity_domain}"
]
resource_health_check = false
resource_domain_name = aws_lb.msk_broker[each.value].dns_name
resource_zone_id = aws_lb.msk_broker[each.value].zone_id
providers = {
aws.org_zone = aws.org
aws.io_zone = aws.io
}
}