根据 IP 地理位置,提供不同的源作为 DNS CNAME 值

Serve different origin as DNS CNAME value, depending on the IP Geolocation

提问人:ROKIKOKI 提问时间:6/15/2021 更新时间:6/15/2021 访问量:304

问:

我有部署为 Lambda Edge 的 Next.js 应用程序和以 S3 静态文件作为源的 Cloudfront。AWS Cloudfront URL 是 CNAME 的值 example-domain.com。

现在,我对应用程序进行了大量更改,并且想要部署这些更改。 我不希望这些更改覆盖当前部署,而是想创建新环境,并且该环境应该在少数国家/地区可用。

因此,在本例中,我将有 2 个不同的 Cloudfront URL:

  • oldfeatures.cloudfront.net
  • newfeatures.cloudfront.net

应根据地理位置提供不同的源 URL。

我不确定这是否是正确的方法,但我愿意接受建议。

我正在管理Cloudflare中的域设置,其余的都是AWS环境。

如何在不更改应用程序代码的情况下实现此目的。

Amazon-CloudFront Cloudflare IP 地理位置

评论

0赞 Ked Mardemootoo 6/15/2021
您是否为您的域启用了 cloudflare 代理?
0赞 StefanN 6/15/2021
您是否正在进行某种金丝雀发布或 A/B 测试?或者你实际上每个县(组)都有单独的版本?
0赞 ROKIKOKI 6/16/2021
我想要单独的版本。旧版本将保留到世界其他地区,新版本应该可用于国家/地区列表
0赞 StefanN 6/16/2021
然后,您可能应该在代码中正确地执行此操作,因为维护单独的版本很快就会变得非常混乱......

答:

1赞 Ked Mardemootoo 6/15/2021 #1

最简单(且具有成本效益)的选择是创建一个 Cloudflare (CF) Worker 并将其附加到您的子域。最好将其附加到两个子域,以确保它们在“不允许”的情况下无法手动访问 URL。第二种选择是使用 CF 负载均衡器功能附带的 CF 流量转向。此选项的成本很小,可能不太适合您的用例 - 它基于地区而不是国家/地区进行重定向 - 我相信您需要支付更多的钱并获得一个企业帐户以进行基于国家/地区的转向。newfeatures.cloudfront.net

也就是说,以下使用 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)
    }
}

评论

0赞 ROKIKOKI 6/16/2021
所有DNS记录都应该保持不变吗?例如: 类型:CNAME 名称:example-domain.com 内容:oldfeatures.cloudfront.net
0赞 Ked Mardemootoo 6/16/2021
我不确定我是否正确理解了您的问题 - 新旧功能域会是什么样子?