根据 IP 地理位置,将不同的来源作为 DNS CNAME 值
Posted
技术标签:
【中文标题】根据 IP 地理位置,将不同的来源作为 DNS CNAME 值【英文标题】:Serve different origin as DNS CNAME value, depending on the IP Geolocation 【发布时间】:2021-06-15 11:33:50 【问题描述】:我有 Next.js 应用程序,它部署为 Lambda Edge 和 Cloudfront,它以 S3 静态文件作为源。 AWS Cloudfront URL 是 example-domain.com CNAME 的值。
现在我对应用程序进行了很多更改,我想部署这些更改。 我不希望这些更改覆盖当前部署,而是我想创建新环境,并且该环境应该在少数国家/地区可用。
所以在这种情况下,我将有 2 个不同的 Cloudfront URL:
oldfeatures.cloudfront.net newfeatures.cloudfront.net应根据地理位置提供不同的来源网址。
我不确定这是不是正确的方法,但我愿意接受建议。
我在 Cloudflare 中管理域设置,其余的都是 AWS 环境。
如何在不更改应用程序代码的情况下实现这一点。
【问题讨论】:
您是否为您的域启用了 cloudflare 代理? 你在做某种金丝雀发布或 A/B 测试吗?或者您实际上每个县(组)都有单独的版本? 我想要单独的版本。旧版本将留在世界其他地方,新版本应可用于国家列表 您应该在代码中正确执行此操作,因为维护单独的版本很快就会变得非常混乱...... 【参考方案1】:最简单(且具有成本效益)的选项是创建一个 Cloudflare (CF) Worker 并将其附加到您的子域。可能最好将其附加到两个子域,以确保它们在“不允许”时无法手动访问newfeatures.cloudfront.net
URL。第二种选择是使用 CF 负载均衡器功能附带的CF Traffic Steering。此选项的成本很低,并且可能并不真正适合您的用例 - 它根据地区而不是国家/地区进行重定向 - 我相信您需要花更多的钱并获得一个企业帐户来进行基于国家/地区的转向。
也就是说,以下使用 CF Worker javascript 的选项将要求您打开 CF 代理(橙色云)。
这里有 3 个选项可以满足您的要求 - 根据我对您问题的理解推荐选项 1。
addEventListener('fetch', event =>
event.respondWith(handleRequest(event.request))
)
async function handleRequest(request)
return setRedirect(request) //Change to appropriate function
// Option 1
// Return same newfeatures URL for specific countries based on a country list
// Useful if single URL applies for many countries - I guess that's your case
async function setRedirect(request)
const country = request.cf.country
var cSet = new Set(["US",
"ES",
"FR",
"CA",
"CZ"]);
if (cSet.has(country))
return Response.redirect('https://newfeatures.cloudfront.net', 302);
// Else return oldfeatures URL for all other countries
else
return await fetch(request)
// Option 2
const countryMap =
US: "https://newfeatures1.cloudfront.net", //URL1
CA: "https://newfeatures2.cloudfront.net", //URL2
FR: "https://newfeatures3.cloudfront.net" //URL3
// Return different newfeatures URL for specific countries based on a map
// Useful if more than two URLs
async function mapRedirect(request)
const country = request.cf.country
if (country != null && country in countryMap)
const url = countryMap[country]
return Response.redirect(url, 302)
// Else return old features for all other countries
else
return await fetch(request)
// Option 3
// Return single newfeatures URL for a single country.
// Much simpler one if you only have one specific country to redirect.
async function singleRedirect(request)
const country = request.cf.country
if (country == 'US')
return Response.redirect('https://newfeatures.cloudfront.net', 302)
// Else return oldfeatures URL for all other countries
else
return await fetch(request)
【讨论】:
所有 DNS 记录都应该保持不变吗?例如:类型:CNAME 名称:example-domain.com 内容:oldfeatures.cloudfront.net 我不确定我是否正确理解了您的问题 - 新旧功能域的情况如何?以上是关于根据 IP 地理位置,将不同的来源作为 DNS CNAME 值的主要内容,如果未能解决你的问题,请参考以下文章
Linux服务器作为网关的DNS分离解析服务(CentOS 7版本)