Azure Front Door 配置路由指南
Azure Front Door 的 Standard/Premium 里,一条能对外服务的路由,背后是几个资源按顺序拼起来的:自定义域名、源组与源、路由,必要时再加 WAF(Web Application Firewall,Web 应用防火墙)。顺序错了,或者某个字段理解偏了,就会出现「域名配好了却打不开」「健康探针一直 Unhealthy」之类的问题。
本文按实际配置顺序把整条链路走一遍,希望能让刚接触 Front Door 的人照着做就能跑通。文中说的 Front Door 均指 Standard/Premium(classic 版本正在退役)。
Azure 上的几个入口服务
Azure 上有几个容易混淆的流量入口服务,定位差别很大:
| 服务 | 工作层次 | 范围 | 典型用途 |
|---|---|---|---|
| Azure Front Door | L7(HTTP/HTTPS) | 全局(location 就是 Global,接入点遍布各地) | 全球入口:加速、缓存、TLS 卸载、WAF |
| Application Gateway | L7(HTTP/HTTPS) | 区域(部署在某个区域 / VNet 里) | 区域内的 L7 负载均衡,可带 WAF |
| Azure Load Balancer | L4(TCP/UDP) | 区域 | 四层负载均衡 |
| Azure Traffic Manager | DNS | 全局 | 基于 DNS 的流量调度 |
关键区别在范围:Front Door 是全局服务(它的 location 就叫 Global),用户就近接入边缘节点;Application Gateway 是区域服务,部署在具体的 VNet 里。所以两者定位不同,也常常配合使用——Front Door 放最外层做全球入口,Application Gateway 放在区域内的入口。(顺带一提,Azure CDN from Microsoft (classic) 正在退役,其缓存能力已并入 Front Door。)
先认识几个资源
| 资源 | 作用 |
|---|---|
| Profile | Front Door 本体,也是日志、安全策略的作用域 |
| Endpoint | 每个 endpoint 都有一个默认域名 xxx.z01.azurefd.net |
| Custom domain | 对外的自定义域名(含通配符) |
| Origin group / Origin | 源组和源,即后端服务 |
| Route | 把自定义域名和源组连起来 |
| Rule set / Rule | 规则集与规则:匹配条件 + 动作,挂在路由上(URL 重写、改请求/响应头、缓存覆盖等) |
| Security policy | 把自定义域名和 WAF policy 连起来 |
依赖关系上,通常是:先把域名建好并验证,再建源组和源,然后建路由把两者连起来,最后按需挂规则集、接 WAF。
第 1 步:创建自定义域名
Front Door 支持三种自定义域名:
| 类型 | 示例 | 典型用途 |
|---|---|---|
| 子域名 | www.contoso.com | 最常见 |
| 顶级域名(apex) | contoso.com | 裸域名 |
| 通配符 | *.contoso.com | 多租户 / SaaS,一个通配符覆盖所有一级子域名 |
通配符最省事:配好一条路由,customer1.contoso.com、customer2.contoso.com 这类一级子域名就都被覆盖了。新增租户时,只要在 DNS 里加一条 CNAME 指过来即可——完全不用碰 Front Door,也不用逐个签发证书。换句话说,以后新增域名只动 DNS,不动 Front Door。
关于域名,有一点要特别提醒:一个自定义域名同一时间只能关联一个 endpoint。不同 profile 可以用同一个域名的不同子域名,但不能用同一个完整域名。
这一点比较坑,值得展开说:它意味着把一个已经上线的域名从 profile A 挪到 profile B,只能先把它从 A 删掉、再加到 B,这中间必然有中断,因为 Front Door 不支持在 B 里先把同一个域名配好。官方给的两条「无中断」路子是——临时把流量切到源站或另一个 CDN 做中转,或者走 tier 升级(classic → Standard/Premium、Standard → Premium)。再叠加下面要说的配置传播时间,这个窗口会比预想的更长,迁移前记得留够维护窗口。同样的坑在从 Azure CDN 迁过来时也会遇到,可参考 《迁移 Azure CDN (Classic) 到 Azure Front Door》。
第 2 步:用 _dnsauth 的 TXT 记录验证所有权
域名所有权验证是必须做的。默认用 _dnsauth 的 TXT 记录完成,这也是选择 Azure 托管证书时的固定方式;如果自带证书(BYOC)且证书的 CN/SAN 与域名匹配,所有权会自动通过,就不需要再加 TXT(不匹配时仍然要加)。
添加域名时,Front Door 会给出一个验证令牌(validation token),需要在 DNS 里建一条 TXT 记录来证明域名归属。
TXT 记录名的规律是 _dnsauth. 加上去掉开头 *. 的域名,最终以门户给出的记录名为准:
| 自定义域名 | TXT 记录名(FQDN) |
|---|---|
www.contoso.com | _dnsauth.www.contoso.com |
contoso.com(apex) | _dnsauth.contoso.com |
*.contoso.com | _dnsauth.contoso.com |
记录值就是门户上显示的 token。验证状态会经历 Submitting → Pending → Approved,通常几分钟内完成。如果一直不通过,检查记录名和值是否完全一致、TTL 是否过大;验证用的 TXT 记录有一定时效,失败时可以重新生成一个。
验证通过后,就可以给域名启用 HTTPS 了,两种方式:
- Azure 托管证书:免费,Front Door 负责签发和部署,推荐。选择它时,所有权继续用上面的 TXT 记录验证。
- 自带证书(BYOC):证书放在 Key Vault,记得给 Front Door 的托管标识授予 Key Vault 的读取权限。
托管证书会自动轮换,但轮换时是否需要重新验证域名所有权,取决于 Azure 当前的最新策略,不同域名类型可能不同:
| 域名类型 | 是否支持托管证书 |
|---|---|
| 子域名 | 支持 |
| apex(顶级域名) | 支持 |
| 通配符 | 支持 |
无论哪种域名,轮换时都有可能进入 Pending revalidation,此时需要重新生成并更新 _dnsauth 的 TXT 记录。保险的做法是关注域名的验证状态,看到 Pending revalidation 就及时处理,别等到证书到期。
最后,还要把域名的 CNAME 指向 Front Door 的 endpoint 域名,流量才会过来。apex 域名不支持 CNAME,需要用 Azure DNS 的 alias 记录,或提供商的 CNAME flattening。
第 3 步:创建源组和源
先分清 SNI、Host 和 X-Forwarded-Host
这是最容易踩坑的地方。Front Door 到源之间,有三个不同的概念:
| 名称 | 出现在哪 | 由谁决定 |
|---|---|---|
| SNI | TLS 握手 | 源的 Host name |
| Host 头 | HTTP 请求 | 源的 Origin host header;留空则透传客户端请求的原始 Host |
| X-Forwarded-Host | HTTP 请求 | Front Door 自动添加,值 = 客户端请求的原始 Host(会覆盖已有值) |
要点:
- Front Door 与源建立 TLS 连接时,SNI 用的是源的 Host name,而不是客户端请求的域名。
- 转发给源的 Host 头由 Origin host header 决定;把它留空,Front Door 就会把客户端请求的原始 Host 透传下去,这就是所谓的 Host 名保留。
- 无论 Host 头是什么,源都能从 X-Forwarded-Host 拿到客户端最初请求的域名。
由此有个常见结论:如果源要求 Host 头与证书一致(比如 App Service、Blob Storage),就把 Origin host header 设成源主机名;如果源依赖原始域名做路由,就把它留空。
还有一个开关:证书主体名称校验(Certificate subject name validation),默认开启。开启时,源返回的证书的 CN/SAN 必须匹配源的 Host name,否则连接会被拒绝。启用 Private Link 时这个校验是必须的。
当 SNI 与 Host 不同时
有时候需要让 SNI 与 Host 是两回事:用 A 域名(源主机名)和源的证书建立 TLS,再用 B 域名(面向用户的域名)做路由。这时源必须同时接受两者——用 SNI 选证书,用 Host(或 X-Forwarded-Host)匹配路由。
这在 SaaS 场景里很常见:租户带着自己的域名(B)接进来,证书由 Front Door 统一管理,源站则用内部域名(A)和内部证书接住 Front Door 的 TLS,再靠 Host 头把请求分给对应的租户。
Kubernetes 的 Gateway API 是个典型例子。默认它要求 TLS 的 SNI 与 HTTP 的 Host 一致,或至少有交集,否则返回 404。解决办法是在 Gateway 上不设置 hostname、只配置 TLS 证书,把域名匹配交给 HTTPRoute 的 hostnames。这样一来,即使 Front Door 用源的 Host name 作为 SNI 建连、而 Host 头是另一个域名,也能正常路由。具体可参考 《在 K8s Gateway API 中为多个 Hostname 使用单个证书》 和 《将 Ingress NGINX 迁移到 Azure Kubernetes Service 上的 Gateway API》。
配好后,可以在本地直接验证源是否接受 SNI 与 Host 不一致:
# 用一个 SNI 建 TLS,检查证书是否匹配源的 Host nameopenssl s_client -connect <origin-host>:443 -servername <origin-host-name>
# TLS 用源的 Host name,但 HTTP Host 用另一个域名curl -sv --resolve <origin-host-name>:443:<origin-ip> -H "Host: <public-domain>" https://<origin-host-name>/注意,这种「容忍 SNI 与 Host 不一致」是 Front Door 对源的要求;换成 Front Door 自己做入口,情况就反过来了。Front Door 有域名前置(domain fronting)防护:请求的 SNI 与 Host 不匹配时会被拒绝,返回 421 Misdirected Request,日志里 Error Info 记为 SSLMismatchedSNI;只有两个域名同属一个订阅、且都配置在路由里时才放行。
这也解释了一个实际限制:Front Door 不能套 Front Door。官方 FAQ 明确说,把一个 Front Door profile/endpoint 放在另一个后面会共用同一批边缘 POP,导致路由冲突和性能问题,所以不要把多个 Front Door 串起来。
源在私有网络里:用 Private Link
如果源在内网 VNet 里,Front Door「看不到」它,可以让源通过 Private Link Service 暴露出来,Front Door 侧作为一个 private endpoint 接入。几个要点:
- 启用 Private Link 后,Host name 用于 SNI,要与服务端证书匹配;Origin host header 只用于 HTTP 请求头。
- 必须开启证书主体名称校验。
- 需要在源侧 Private Link Service 里 approve 这个 private endpoint connection(也可以配置自动 approve)。
- 同一个源组里不能混用公有源和私有源。
源组的其他设置
- 健康探针(协议、路径、间隔):HTTPS 探针同样用源的 Host name 建连,所以源的证书必须匹配它,否则探针会报 Unhealthy。
- 负载均衡:按延迟或按样本。
- 优先级(Priority)与权重(Weight):用于主备或多活。
- 会话保持(Session affinity):见下。
会话保持(Session affinity)
同一个域名、应用在多个源上做分布式部署时,Front Door 默认会把同一客户端的不同请求分发到不同源。对无状态应用没问题,但对有状态应用(本机 session、内存缓存、要求固定实例的鉴权令牌等)就会出问题。开启源组级的 Session affinity 后,Front Door 会给客户端下发会话 cookie(ASLBSA 和 ASLBSACORS),后续请求据此回到同一个源。
几个容易踩的点:
- 它在源组级别开启(Standard/Premium),作用于与该源组关联的域名。
- 它是尽力而为,不是硬绑定。Front Door 先按延迟筛出候选源(最佳 RTT + 延迟灵敏度窗口),再从候选里优先选 cookie 指向的那个。如果固定的源不健康,或掉出延迟窗口,请求仍会被切走。延迟灵敏度越大越稳,但不是硬绑定。
- 只有在不可缓存的响应上才会建立会话 cookie:响应要带
Cache-Control: no-store(注意no-cache不算),或是带未过期Authorization头、或 302 响应,并且源必须健康。源回可缓存内容时 cookie 不会下发,粘性也就无从谈起。 - 它是会话 cookie,浏览器关闭即失效;通配符域名下,同一浏览器会话可在子域名之间共享。
- 它替代不了共享状态。真正需要跨实例共享的 session 或缓存,还是应该放到共享存储里,不要依赖粘性。
源响应超时(Origin response timeout)
Front Door 等待源返回的时间是有上限的。这个值在 profile 的 Overview 页设置(不在源组里),作用于该 profile 的所有 endpoint,可填范围是 16–240 秒,最长 4 分钟。接口偶尔会慢(比如报表生成、长轮询)时,记得先把这个值调大,否则会收到 5xx。
注意 4 分钟就是天花板。真有需要更长时间才返回的请求,Front Door 满足不了,得换个入口放在源前面,可能就要改用 Application Gateway。
第 4 步:创建路由
路由把自定义域名和源组连起来,主要配:
- 域名:选择一个或多个自定义域名。
- 路径模式:通常用
/*。注意各条路由之间的路径模式要一致,否则可能出现域名命中了、路径却没命中,客户端直接失败。 - 转发协议:到源用 HTTP 还是 HTTPS。
- 缓存、压缩、规则集(Rule set)等。
域名匹配遵循最具体优先:同时存在通配符 *.contoso.com 和具体子域名 image.contoso.com 时,请求 image.contoso.com 会走具体子域名的那条路由。
缓存与压缩
在路由上可以开启缓存,对静态资源(图片、CSS、JS)收益最大;反过来,动态或需要鉴权的接口不要缓存,以免串数据——建议把静态和动态拆成不同路由。
- 查询字符串缓存行为决定带
?a=1的请求算不算同一个缓存对象,有四种:Ignore Query String、Use Query String、Ignore specified query strings、Include specified query strings。 - 压缩(动态压缩)也在这里开,可以指定要压缩的 content type。
- 缓存时长优先看源返回的
Cache-Control;源没给时,Front Door 默认随机缓存 1–3 天。private、no-cache、no-store的响应不会被缓存。 - 需要按条件覆盖缓存行为或时长时,可以在规则集里做;规则集的缓存配置会覆盖路由的。
规则集(Rule set):挂在路由上的小逻辑
规则集由「匹配条件 + 动作」组成,建好后要关联到路由才会生效;一个规则集可以关联多条路由。常用动作有:URL 重定向、URL 重写、修改请求头、修改响应头,以及缓存相关的覆盖。
一个典型用法是加安全响应头:新建规则集,动作用「修改响应头(Response header)」、操作选 Append,头名写 Content-Security-Policy、值填策略,再挂到对应的路由上——这样匹配该路由的响应都会带上 CSP。HSTS、X-Frame-Options、CORS 的 Access-Control-Allow-Origin 同理。
注意:Front Door 有一批保留头不能由规则修改,X-Forwarded-Host 等就在其中。
路由数量不是无限的:composite route limit
Front Door 对路由的约束不是「一个 endpoint 最多几条」这么简单,而是按 profile 算一个综合值(composite route metric),上限 5000(完整规则和示例见 Routing limits in Azure Front Door)。算法是:
- 单条路由:
HTTP 域名数 × HTTP 路径数加上HTTPS 域名数 × HTTPS 路径数; - 如果这条路由通过规则集做了路由覆盖(route override),还要再加
域名数 × 覆盖次数(HTTP、HTTPS 分别算); - 把所有路由的这些值加起来,就是该 profile 的综合值。
几点提醒:
- 它是按 profile 汇总的;origin group、origin、endpoint 的数量不影响这个值。
- 域名和路径是相乘的关系,域名一多就很容易撞上限——SaaS 场景尤其要注意。
- 同时开 HTTP 和 HTTPS,等于把路径算了两遍;接入只留 HTTPS,同样配置的占用能减半。
- 另外还有一条硬性数量限制:每个 profile 最多 100(Standard)/ 200(Premium)条路由。
真撞上限时,官方建议:把路由拆到多个 profile、多用通配符域名、接入只开 HTTPS。
顺带一提,源的名字建好后无法就地修改;真要改名又不能中断服务,可参考 《Azure Front Door 技巧:修改 Origin Name》。
第 5 步:把域名关联到 WAF
WAF 不是直接挂在 Front Door 上,而是通过 security policy 把域名和 WAF policy 关联起来。
- 作用域与优先级:route 级 > domain 级 > profile 级,命中时用最具体的一层。可以先用 profile 级做基线,再对特定域名或路由叠加。
- WAF policy 有 Classic/Standard/Premium 之分,要与 Front Door profile 的 tier 对应。自定义规则两层都能用;托管规则集(默认规则集 DRS、Bot 保护)和 Private Link 只有 Premium 有。
- 费用要留意:Front Door 的底价 Standard 约 $35/月、Premium 约 $330/月(以官方定价为准,因区域而异);WAF 和 Private Link 已包含在 Premium 里,Standard 的自定义 WAF 规则也不额外收费。只需要自定义规则就选 Standard,要用托管规则集再上 Premium。
- 通配符域名可以直接挂 WAF,用一条 policy 覆盖所有子域名。Standard/Premium 下,子域名默认继承通配符域名的 WAF policy;如果某个子域名要用不同的 policy,就显式关联它(具体优先)。
- 如果不想让某个子域名跑 WAF,可以给它关联一个没有规则的空 policy。
第 6 步:验证配置并切换 DNS
正式切域名前,最好先验证整条链路是否通。此时域名还没指向 Front Door,有两种办法。
可以修改本地 hosts 文件,把域名临时指向 Front Door endpoint 的 IP;更推荐用 curl 的 --connect-to,让 SNI 和 Host 都保持为目标域名,但把连接打到 Front Door 的 endpoint:
# 连接到 endpoint,但 SNI 与 Host 都保持为 www.contoso.comcurl -sv --connect-to www.contoso.com:443:contoso.z01.azurefd.net:443 https://www.contoso.com/health也可以用 --resolve 指定 endpoint 的 IP:
curl -sv --resolve www.contoso.com:443:<endpoint-ip> https://www.contoso.com/health-v 会打印 TLS 握手里真正的 SNI、证书的 CN/SAN 以及响应头,方便确认证书是否已为这个域名签发、命中了哪条路由。更完整的说明见 《测试已启用 HTTPS 但尚未配置域名的站点》。
其他全局设置与运维
诊断日志
访问日志、健康探针日志、WAF 日志默认都不开,需要在 Front Door profile 的 Diagnostic settings 里显式开启,发送到 Log Analytics、存储账户或 Event Hub:
FrontDoorAccessLog:所有经过 Front Door 的请求。FrontDoorHealthProbeLog:健康探针的结果。FrontDoorWebApplicationFirewallLog:被 WAF 规则命中的请求。
排障时的查询示例:
// 访问日志AzureDiagnostics| where ResourceProvider == "MICROSOFT.CDN" and Category == "FrontDoorAccessLog"
// 被 WAF 拦截的请求AzureDiagnostics| where ResourceProvider == "MICROSOFT.CDN" and Category == "FrontDoorWebApplicationFirewallLog"| where action_s == "Block"除了日志,Front Door 还提供指标(包括 WAF 请求计数),可以在 Metrics 里直接看。
清除缓存(Purge cache)
改了内容但 TTL 还没到,可以手动清除(purge):在 profile 的 Overview 页点 Purge cache,选 endpoint 和域名,然后要么清除全部,要么填具体路径。路径支持单个文件(如 /pictures/strasbourg.png),也支持通配符(如文件夹 /scripts/*、整个 endpoint /*)。
几个注意点:
- 一次 purge 最多 100 个 URL(域名 + 路径);更多要分批,且必须等上一批完成再提交,否则会被拒。
- purge 大小写不敏感、且忽略查询字符串:清一个 URL 会连带清掉它所有
?query变体。 - 通配符域名不能直接 purge,要指定具体子域名。
- purge 是全局操作,在所有 POP 生效最长约 10 分钟。
比起频繁 purge,更好的做法是给静态资源加版本号(每次更新换新 URL),Front Door 下次请求自然就取到新的了。
耐心等待变更生效
Front Door 的配置变更是一次全局操作,改完不会马上生效。按官方 FAQ,单次创建/更新/删除/WAF 操作最长可能要等约 15 分钟,缓存清除约 10 分钟;连续改好几处时,后面的会排队,总时间可能拉到约 30 分钟。自定义 TLS 证书更慢,最长约一小时。
这事也有来历:2025 年 10 月 Front Door 那次多区域故障出在配置传播上,官方随后给传播流水线加了额外的安全阶段和 bake time,传播时间一度被拉长到 45 分钟,之后才逐步压回 15 分钟。
所以,改完配置或切完 DNS,泡杯茶回来再看结果也不迟——别一刷新就怀疑自己配错了。配个东西等半小时,心态要稳。
小结
按顺序走下来其实不复杂:先建域名并用 _dnsauth 的 TXT 记录验证,启用托管证书;再建源组和源,想清楚 SNI、Host 与 X-Forwarded-Host 各自由谁决定;然后用路由把域名和源组连起来;按需用 security policy 接上 WAF;最后别急着切 DNS,先用 curl --connect-to 验证通过再正式切换。日志和 WAF 日志记得打开,排障时会省很多事。
参考资料
- Domains in Azure Front Door
- Add a custom domain to Azure Front Door
- Wildcard domains in Azure Front Door
- Apex domains in Azure Front Door
- Origins and origin groups in Azure Front Door
- How to configure origins in Azure Front Door
- Protocol support for HTTP headers in Azure Front Door
- Enable Private Link for an internal load balancer as an origin
- How requests are matched to a routing rule
- Routing limits in Azure Front Door
- Caching with Azure Front Door
- Cache purge in Azure Front Door
- What is a rule set in Azure Front Door
- Add security headers with a rules engine
- Traffic routing methods in Azure Front Door
- Azure Web Application Firewall on Azure Front Door
- WAF policy settings for Azure Front Door
- Configure Azure Front Door logs
- Azure Front Door frequently asked questions (FAQ)
- Monitoring data reference for Azure Front Door