如何利用客户端双向TLS认证保护云上应用安全
双向TLS(mTLS)通过要求服务器和客户端双方使用数字证书来验证彼此身份,从而扩展了传统TLS的安全性。常规的TLS只会验证服务器的身份(如大家的浏览器在验证网站时的场景),而mTLS确保在任何数据交换发生之前,双方都对彼此持有信任。在本文中,我们将探讨如何在云端,利用亚马逊云科技服务实现双向mTLS的客户端。
本文介绍
双向TLS(mTLS)技术在保护客户端与服务器之间敏感数据的数据传输方面正变得愈发重要。本文将介绍如何在与外部API端点进行通信的应用程序中开启mTLS的方法。
mTLS实现的具体步骤
- 客户端应用程序需要使用mTLS连接到API端点
- 服务器要求客户端在进行API连接时使用mTLS
- 客户端必须为该连接获取合适的证书
客户端侧应用介绍
- 常见部署方式: 应用程序运行在亚马逊云科技EKS/ECS/EC2上
- 需要考虑的因素: 证书管理、证书轮换以及部署。
云端开启mTLS的前提条件
- 根据服务器的证书要求创建客户端SSL证书。
在云端设置mTLS的两种方案
方案1:端到端直接在服务器中配置mTLS
1. 首先需要根据服务器端的证书生成客户端证书
2. 在Amazon Secret Manager秘钥存储服务中安全地存储证书
- 避免存储在附加到虚拟机的持久化存储硬盘中
- 使用安全的密钥管理服务Amazon Secret Manager在运行时动态检索证书
3. 配置客户端应用程序加载证书以使用mTLS
- 这需要在API调用中通过客户端代码来实现mTLS
示例基础设施创建Python CDK代码
from aws_cdk import (
aws_secretsmanager as secretsmanager,
Stack,
SecretValue,
)
from constructs import Construct
class ClientCertSecretStack(Stack):
def __init__(self, scope: Construct, id: str, **kwargs) -> None:
super().__init__(scope, id, **kwargs)
# Replace the content below with your actual client certificate
client_cert = """-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----"""
# Create a secret in AWS Secrets Manager to store the client certificate
client_cert_secret = secretsmanager.Secret(self, "ClientCertSecret",
secret_name="ClientCertificate",
description="Client certificate for mTLS authentication",
secret_string_value=SecretValue.plain_text(client_cert)
)
方法2:使用API Gateway作为mTLS的网关代理
1. 创建并设置API Gateway,使其充当外部API端点的网关代理。
2. 在API Gateway上配置mTLS相关设置。
3. 在客户端应用程序中配置使其与API Gateway进行通信。
4. 由API Gateway处理与外部服务之间的mTLS连接。
该方案优势:
对现有应用程序代码的改动最小。
能够集中管理所有后端服务的mTLS连接。
示例基础设施创建Python CDK代码
from aws_cdk import (
aws_apigateway as apigw,
aws_certificatemanager as acm,
Stack,
)
from constructs import Construct
class MtlsApiGatewayStack(Stack):
def __init__(self, scope: Construct, id: str, **kwargs) -> None:
super().__init__(scope, id, **kwargs)
# Create or import an ACM certificate for the custom domain.
# Replace "api.example.com" with your actual domain.
domain_cert = acm.Certificate(self, "DomainCert",
domain_name="api.example.com",
validation=acm.CertificateValidation.from_dns() # Uses DNS validation
)
# Create a custom domain for API Gateway with mutual TLS settings.
# The truststore_uri should point to an S3 object that stores your trust certificate.
domain = apigw.DomainName(self, "CustomDomain",
domain_name="api.example.com",
certificate=domain_cert,
endpoint_type=apigw.EndpointType.REGIONAL,
security_policy=apigw.SecurityPolicy.TLS_1_2,
mutual_tls_authentication=apigw.MutualTlsAuthentication(
truststore_uri="s3://my-bucket/truststore.pem", # Update with your S3 bucket and object
truststore_version="1" # Optional version string for the truststore
)
)
# Create an API Gateway REST API using the custom domain.
api = apigw.RestApi(self, "MtlsApi",
rest_api_name="MTLS API",
domain_name=domain
)
# Add a simple GET method on the root resource for demonstration.
api.root.add_method("GET",
apigw.MockIntegration(
integration_responses=[{
"statusCode": "200",
"responseTemplates": {"application/json": '{"message": "Hello, mTLS!"}'}
}],
passthrough_behavior=apigw.PassthroughBehavior.NEVER,
request_templates={"application/json": '{ "statusCode": 200 }'}
),
method_responses=[{
"statusCode": "200"
}]
)
结论
通过mTLS可在客户端和服务器之间实现双向身份验证,从而提升API通信的安全性。请选择最适合大家的架构解决方案与基础设施运维和安全设计的方法。总的来说,本文详细说明了在客户端实现mTLS的重要性、可能面临的部署场景,以及针对不同需求提供了两种具体方案。希望通过本文,大家能够在保护API通信安全方面有更清晰的思路与可行路径。