Solutions: 解决方案-通用
- TAGS: 解决方案
httpDNS
背景
用户出口IP和LocalDNS供应商不一致,导致通过local dns解析的cdn域名返回的cdn节点为非就近或相同供应商的节点,进而导致用户访问资源质量下降、甚至不可用。
解决方案
采用httpdns,httpdns能直接获取客户端IP,基于客户端IP获得最精准的解析结果,让客户端更好的接入就近的业务节点。
项目收益
- 增加域名解析准确度,防止域名解析劫持。
- 降低解析延迟,提高用户体验。
- 更多可参见httpdsn优势。 注:目前因无更多数据支持,可简单通过服务上线后,此类客诉问题是否减少来评估项目收益。
httpdns的优势
- 绕过了运营商的local dns,可以防止域名劫持。
- 使用用户出口的真实IP地址做解析,使解析结果更加精准。
- 可做热点域名预热、缓存dns解析结果、解析结果懒更新等方式,有效的降低解析延迟,甚至可达到 0ms 解析延迟。
- 绕过了local dns,避免了local dns不遵循权威ttl的问题,可以使修改解析结果更快速的生效。
方案实施原则
- 不自行开发httpdns 服务,CDN域名使用CDN厂商的httpdns服务。
- 一期 API类域名暂不考虑使用httpdns。【API类域名防止DNS解析也需要使用httpdns,在二期再考虑加入。直接使用阿里云或腾讯云的httpdns服务】
- 客户端使用的 httpdns 服务地址:
- 客户端必须预置阿里云(或腾讯云)提供的httpdns服务的IP地址【即默认的httpdns api接口】【防止第一跳因dns劫持导致无法访问,从而导致后续的httpdns服务地址无法下发】。
- 必须支持httpdns服务地址由服务端下发。
服务端
- 需要开发httpdns api 下发接口。
- 接口下发粒度为【用户】级别,即自动切换用户的cdn供应商,比如从阿里切到腾讯或网宿等。
- 接口支持全部用户切换和批量用户切换cdn供应上。
- 待定或二期:支持根据区域切换cdn供应商。
- 需要做些IP储备,增加对cdn节点调度的支持,比如下发给用户的httpdns api 接口中包含请求的出口IP,让客户端请求的时候传给httpdns api 来源IP地址,进而对该用户强制调度到此IP的就近节点。
客户端
- 预置默认httpdns api接口地址【默认供应商需要确认】
- 做正常的业务请求
- 异步热点域名预热
- 异步请求【httpdns api 下发服务】API 获取新的httpdns api,并做结果缓存,如果下发了新的httpdns api,则使用新httpdns api 进行解析。
- httpdns api 接口调用鉴权,防止恶意刷量,导致不必要的成本。 注:① 异步请求的时效性需要再讨论 ② 异步请求避免对齐
具体技术细节和接口
需要客户端和服务端研发协商指定
阿里云HttpDNS
https://help.aliyun.com/product/30100.html?spm=a2c4g.11186623.6.540.6c136e96CHjOh8
注意事项
参考阿里云httpdns最佳实践
更多httpdns最佳实践:https://help.aliyun.com/document_detail/30143.html?spm=a2c4g.11186623.3.2.63be7f15odjGz0
Aliyun DTS基于VPN网关实现阿里云RDS和AWS EC2间的数据同步
DTS基于VPN网关实现阿里云RDS和AWS EC2间的数据同步
背景:DTS 阿里云polarDB与AWS RDS双向同步调研
主要操作:阿里云与AWS内网互通,DTS配置,以下是针对文档的操作记录点
阿里云VPC 10.2.0.0/16
AWS VPC 10.0.0.0/16
步骤一:在阿里云创建VPN网关实例
IPsec地址1:8.219.102.177
IPsec地址2:8.222.171.136
步骤二:在AWS平台部署VPN
1.创建客户网关。
您需要在AWS侧创建2个客户网关,将阿里云VPN网关实例的2个IP地址作为客户网关的IP地址。
2.创建虚拟私有网关。
您需要在AWS侧创建虚拟私有网关,并将虚拟私有网关绑定到需要和阿里云互通的VPC实例上。
3.创建站点到站点VPN连接。
为站点到站点VPN连接配置路由时,您除了要指定阿里云VPC网段外,还需要指定100.104.0.0/16网段,DTS服务将使用该网段下的地址同步数据。
2个站点到站点VPN连接的配置,连接不同的客户网关
预共享密钥 12345678
aliyun1隧道状态
Tunnel 1 35.166.53.23 169.254.68.60/30 关联客户网关IPsec地址1
aliyun2隧道状态
Tunnel 1 34.208.190.223 169.254.250.112/30 关联客户网关IPsec地址2
4.配置路由传播。
您需要在虚拟私有网关关联的VPC实例的路由表下开启路由传播,以确保站点到站点VPN连接下的路由可以自动传播到VPC实例的路由表中。
步骤三:在阿里云部署VPN网关
1.创建用户网关。
用户网关1 对应aws站点连接随着tunnel1的外网地址
用户网关2 对应aws站点连接随着tunnel2的外网地址
2.创建IPsec连接。
路由模式:感兴趣流模式
本端网段
VPC网段:10.2.0.0/16
DTS网段:100.104.0.0/16
对端网段aws: 10.0.0.0/16
Tunnel-2:
- 预共享密钥: 12345678
- 用户网关: 用户网关1 用户网关2
3.配置VPN网关路由
策略路由表页签,找到目标路由条目,在操作列单击发布
步骤四:测试网络连通性
略。 验证两边可互通即可
步骤五:创建DTS数据同步任务 略
同步方案概览:https://help.aliyun.com/zh/dts/user-guide/data-synchronization-scenarios
DTS:
- 阿里云PolarDB <–> AWS RDS 双向同步,支持。 注意AWS RDS不要开放外网
- 阿里云MongoDB <–> AWS DocumentDB 双向同步,不支持。
- 解决方案:
AWS CluoudFront-使用鉴权-URL
参考
- 使用签名 URL - Amazon CloudFront https://docs.aws.amazon.com/zh_cn/AmazonCloudFront/latest/DeveloperGuide/private-content-signed-urls.html
- 使用 Java 创建 URL 签名 - Amazon CloudFront https://docs.aws.amazon.com/zh_cn/AmazonCloudFront/latest/DeveloperGuide/CFPrivateDistJavaDevelopment.html
1.使用 OpenSSL 生成长度为 2048 位的 RSA 密钥对
openssl genrsa -out private_key.pem 2048
2.提取公有密钥
openssl rsa -pubout -in private_key.pem -out public_key.pem
3.将公有密钥上传到 CloudFront https://docs.aws.amazon.com/zh_cn/AmazonCloudFront/latest/DeveloperGuide/private-content-trusted-signers.html#private-content-creating-cloudfront-key-pairs
4.重新设置私有密钥的格式 java 用
openssl pkcs8 -topk8 -nocrypt -in cloudfront_private_key.pem -inform PEM -out private_key.der -outform DER
5.cloudfront 控制台域名设置限制查看器访问,绑定密钥组
6.手动测试
cat << \EOF >policy { "Statement": [ { "Resource": "https://*", "Condition": { "DateLessThan": { "AWS:EpochTime": 1721471130 } } } ] } EOF #生成Policy=策略声明的 Base64 编码版本 cat policy | tr -d "\n" | tr -d " \t\n\r" |openssl base64 -A | tr -- '+=/' '-_~' #生成Signature=策略声明经过哈希处理和签署后的版本 cat policy | tr -d "\n" | tr -d " \t\n\r" | openssl sha1 -sign private_key.pem | openssl base64 -A | tr -- '+=/' '-_~'
样例: xx.com/{{ resource }}?Policy={{ policy-base64 }}&Signature={{ signature-base64 }}&Key-Pair-Id={{ keyid }}
难点:流式传输视频点播限制,无法自动添加请求资源鉴权
解决方案:
方案1: 利用lambda改写,流量走api gateway https://aws.amazon.com/cn/blogs/networking-and-content-delivery/secure-and-cost-effective-video-streaming-using-cloudfront-signed-urls/
方案2:CDN边缘节点实现(自带lambda js脚本)
注意:模板中nodejs14.x 改为nodejs16.x。 Origin 处改成自己的s3源地址,替换自己的证书信息。如:
... Parameters: Origin: Description: Domain name of content origin Type: String Default: s3-video-storage-test.s3.us-west-2.amazonaws.com ... Runtime: nodejs16.x ... let duration = 900; //ts文件鉴权过期时间 ... let policy = JSON.stringify({ Statement: [{ //Resource: 'http*://'+ domain+path.posix.join(dir,file), 如果有备用域名,修改此处 Resource: 'http*://awsvideo.cici.online'+ path.posix.join(dir,file), Condition: { ... Runtime: nodejs16.x
测试环境-java代码对应信息
... String resourceUrl = "https://d2xxxxu.cloudfront.net"; String keyPairId = "K9xxxxxV"; ... .privateKey(new java.io.File("/path/to/private_key.der").toPath()) ...
python测试脚本
import datetime from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives import serialization from cryptography.hazmat.primitives.asymmetric import padding from botocore.signers import CloudFrontSigner def rsa_signer(message): with open('CF-priv-key.pem', 'rb') as key_file: private_key = serialization.load_pem_private_key( key_file.read(), password=None, backend=default_backend() ) return private_key.sign(message, padding.PKCS1v15(), hashes.SHA1()) key_id = 'K94AXT0F34G8V' #url = 'https://dlshqm8hlv94m.cloudfront.net/test2.m3u8' url = 'https://awsvideo.cici.com/4031f27659f871ef997b5114c1ca0102/1289b553c5e64038bef3a2e91f8acd48-009825ad620ebb8a5131ed4c04115d4c-ld.m3u8' expire_date = datetime.datetime(2054, 10, 20) cloudfront_signer = CloudFrontSigner(key_id, rsa_signer) # Create a signed url that will be valid until the specific expiry date # provided using a canned policy. signed_url = cloudfront_signer.generate_presigned_url( url, date_less_than=expire_date) print(signed_url)