【Azure APIM】APIM的自建网关如何解决自签名证书的受信任问题呢?(方案三)

简介: 本文详解在Azure AKS中为APIM自建网关Pod信任自签名证书的实践方案:通过创建CA证书Secret、挂载至容器,并设置SSL_CERT_FILE环境变量,使网关成功验证后端HTTPS服务。附完整YAML配置与排错日志分析。(239字)

问题描述

在先前的四篇博文

1:【Azure APIM】APIM的自建网关如何解决自签名证书的受信任问题呢?(方案二)

2:【Azure APIM】APIM的自建网关如何解决自签名证书的受信任问题呢?(方案一)

3:【Azure APIM】如何解决后端API服务配置自签名证书时APIM请求报错500:Error occured while calling backend service

4:【Azure 环境】在Windows环境中使用OpenSSL生成自签名证书链步骤分享

我们分别介绍了使用OpenSSL生成自签名证书,然后解决APIM服务对自签名证书的信任问题。不论是APIM托管的网关,还是自建的网关都可以通过安装证书后使得请求受信任,通过配置API跳过证书验证环节。

本文这从“自建网关本身AKS POD” 方面入手,通过配置 SSL_CERT_FILE 环境变量,来安装自签名证书 (根证书和中间证书)到POD中。

经过AI大模型解答,在 AKS (Azure Kubernetes Service) 中访问使用自签名证书的 API,关键在于让客户端信任该证书,主要的思路是:

  1. 创建包含 CA 证书的 Secret
  2. 将自签名的 CA 证书文件 (例如 ca.crt) 导入到 AKS 集群
  3. 在应用部署的 YAML 文件中,将该 Secret 挂载到容器内,并设置 SSL_CERT_FILE 环境变量指向该证书

操作步骤

第一步:准备好中间证书和根证书合并一起的 .crt 内容

导出方法:通过浏览器导出中间证书+根证书的 crt 文件,其内容是 Base64 编码

 

第二步:创建Kubernetes Secret

将自签名的 CA 证书文件 (例如 my-inetr-ca.crt) 导入到 AKS 集群中:

命令:

kubectl create secret generic self-signed-ca --from-file="<the full path of my-inetr-ca.crt>"

结果:

 

第三步:在APIM的自建网关Pod中挂载证书

在应用部署的 YAML 文件中,将该 Secret 挂载到容器内,并设置 SSL_CERT_FILE 环境变量指向该证书

...
        volumeMounts:
        - name: ca-volume
          mountPath: /etc/ssl/certs/my-ca.crt
          subPath: my-inetr-ca.crt
        env:
        - name: SSL_CERT_FILE
          value: /etc/ssl/certs/my-ca.crt
  ... 
      volumes:
      - name: ca-volume
        secret:
          secretName: self-signed-ca
...

把从APIM获取的部署yaml内容,只修改如图中的三个位置,即可。

第四步:部署以上配置,后访问AKS Service External URL进行测试验证

# 部署

kubectl apply -f "<apim self-hosted gateway yaml file>"

#获取对外暴露的IP地址

kubectl get services

 

##测试访问自建网关中的API

curl https://<external ip>/api -k

测试结果,成功通过证书验证及获取正确的结果:

 

如果没有配置SSL_CERT_FILE 及挂载证书,就会遇见500 Internal server error。如果进一步通过 kubectl logs <pod name> 查看GatewayLogs日志,就会发现详细错误:The remote certificate was rejected by the provided RemoteCertificateValidationCallback.


详细错误

[Info] 2026-01-23T07:26:27.251 [DnsResolutionScheduled], message: xselfca02.myxxxxx.com, source: RoundRobinNameResolver

[Info] 2026-01-23T07:26:27.252 [OutgoingTlsProtocolsSet], message: Tls, Tls11, Tls12, source: TcpChannelFactory

[Info] 2026-01-23T07:26:27.598 [CertificateInfoVerificationScheduled], message: thumbprint: 62BF1CFA2116828E3F0B3C7D8FB4C380CD2CE358, subjectName: CN=*.myxxxxx.com, O=My Self Server Org, S=Chongqing, C=CN (CRL URLs: ; AIA URLs: )

[Warn] 2026-01-23T07:26:27.601 [FailedToProcessRequest], ActivityId: d5d383dc-c395-4111-8558-2193f9bbb8ff, correlationId: d5d383dc-c395-4111-8558-2193f9bbb8ff, apiId: 69303f7730caebcf2a534309, operationId: get-home-page, tags: 20, httpMethod: GET, source: request-forwarder, serviceName: apim-gateway, exception: System.Security.Authentication.AuthenticationException: The remote certificate was rejected by the provided RemoteCertificateValidationCallback.

at System.Net.Security.SslStream.SendAuthResetSignal(ReadOnlySpan`1 alert, ExceptionDispatchInfo exception)

at System.Net.Security.SslStream.CompleteHandshake(SslAuthenticationOptions sslAuthenticationOptions)

at System.Net.Security.SslStream.ForceAuthenticationAsync[TIOAdapter](Boolean receiveFirst, Byte[] reAuthenticationData, CancellationToken cancellationToken)

at Gateway.Http.Client.DotNetty.TcpChannelFactory.CreateChannelAsync(IPEndPoint endpoint, RequestedApplicationProtocol requestedApplicationProtocol, TlsInfo tlsMetadata, HttpProxy httpProxyMetadata, Int32 destinationPort, CancellationToken cancellationToken) in C:\__w\1\s\Proxy\Gateway.Http.Client.DotNetty\TcpChannelFactory.cs:line 116

at Gateway.Http.Client.DotNetty.EndpointPool.CreateAsyncInternal(IPipelineContext pipelineContext, ChannelPoolKey channelPoolKey, RequestedApplicationProtocol requestedApplicationProtocol, CancellationToken cancellationToken, GateInfo gateInfo) in C:\__w\1\s\Proxy\Gateway.Http.Client.DotNetty\EndpointPool.cs:line 307

at Gateway.Http.Client.DotNetty.EndpointPool.CreateAsync(IPipelineContext pipelineContext, ChannelPoolKey channelPoolKey, RequestedApplicationProtocol requestedApplicationProtocol, CancellationToken cancellationToken) in C:\__w\1\s\Proxy\Gateway.Http.Client.DotNetty\EndpointPool.cs:line 128

at Gateway.Http.Client.DotNetty.SingleThreadedBackendChannelPool.AcquireAsync(IPipelineContext context, CancellationToken cancellationToken) in C:\__w\1\s\Proxy\Gateway.Http.Client.DotNetty\SingleThreadedBackendChannelPool.cs:line 189

at Gateway.Http.Client.DotNetty.RoundRobinBackendChannelPool.Acquire0(Object state) in C:\__w\1\s\Proxy\Gateway.Http.Client.DotNetty\RoundRobinBackendChannelPool.cs:line 73

at Gateway.Http.Client.DotNetty.DotNettyHttpBackend.AcquireChannelAsync(IPipelineContext ctx, CancellationToken cancellationToken) in C:\__w\1\s\Proxy\Gateway.Http.Client.DotNetty\DotNettyHttpBackend.cs:line 791

at Gateway.Http.Client.DotNetty.DotNettyHttpBackend.ProcessAsync(IPipelineContext context, CancellationToken cancellation) in C:\__w\1\s\Proxy\Gateway.Http.Client.DotNetty\DotNettyHttpBackend.cs:line 172

at Microsoft.WindowsAzure.ApiManagement.Proxy.Gateway.Policies.PipelineWalker.ExecuteAsync(IPipelineContext context, IEnumerable`1 steps, CancellationToken cancellation) in C:\__w\1\s\Proxy\Gateway.Pipeline\PipelineWalker.cs:line 66

at Microsoft.WindowsAzure.ApiManagement.Proxy.Gateway.ChildPipeline.ExecuteAsync(IPipelineContext context, CancellationToken cancellationToken) in C:\__w\1\s\Proxy\Gateway.Pipeline\ChildPipeline.cs:line 35

at Gateway.Pipeline.Extensions.ValueTaskExtensions.Await[T](ValueTask`1 input) in C:\__w\1\s\Proxy\Gateway.Pipeline\Extensions\ValueTaskExtensions.cs:line 28

at Microsoft.WindowsAzure.ApiManagement.Proxy.Gateway.Policies.IO.CallServiceHandler.ProcessAsync(IPipelineContext context, CancellationToken cancellation) in C:\__w\1\s\Proxy\Gateway.Policies.General\IO\CallServiceHandler.cs:line 94

at Gateway.Http.Client.DotNetty.SingleThreadedBackendChannelPool.AcquireAsync(IPipelineContext context, CancellationToken cancellationToken) in C:\__w\1\s\Proxy\Gateway.Http.Client.DotNetty\SingleThreadedBackendChannelPool.cs:line 189

at Gateway.Http.Client.DotNetty.RoundRobinBackendChannelPool.Acquire0(Object state) in C:\__w\1\s\Proxy\Gateway.Http.Client.DotNetty\RoundRobinBackendChannelPool.cs:line 73

at Gateway.Http.Client.DotNetty.DotNettyHttpBackend.AcquireChannelAsync(IPipelineContext ctx, CancellationToken cancellationToken) in C:\__w\1\s\Proxy\Gateway.Http.Client.DotNetty\DotNettyHttpBackend.cs:line 791

at Gateway.Http.Client.DotNetty.DotNettyHttpBackend.ProcessAsync(IPipelineContext context, CancellationToken cancellation) in C:\__w\1\s\Proxy\Gateway.Http.Client.DotNetty\DotNettyHttpBackend.cs:line 172

at Microsoft.WindowsAzure.ApiManagement.Proxy.Gateway.Policies.PipelineWalker.ExecuteAsync(IPipelineContext context, IEnumerable`1 steps, CancellationToken cancellation) in C:\__w\1\s\Proxy\Gateway.Pipeline\PipelineWalker.cs:line 66

at Microsoft.WindowsAzure.ApiManagement.Proxy.Gateway.ChildPipeline.ExecuteAsync(IPipelineContext context, CancellationToken cancellationToken) in C:\__w\1\s\Proxy\Gateway.Pipeline\ChildPipeline.cs:line 35

at Gateway.Pipeline.Extensions.ValueTaskExtensions.Await[T](ValueTask`1 input) in C:\__w\1\s\Proxy\Gateway.Pipeline\Extensions\ValueTaskExtensions.cs:line 28

at Microsoft.WindowsAzure.ApiManagement.Proxy.Gateway.Policies.IO.CallServiceHandler.ProcessAsync(IPipelineContext context, CancellationToken cancellation) in C:\__w\1\s\Proxy\Gateway.Policies.General\IO\CallServiceHandler.cs:line 94

at Microsoft.WindowsAzure.ApiManagement.Proxy.Gateway.Policies.PipelineWalker.ExecuteAsync(IPipelineContext context, IEnumerable`1 steps, CancellationToken cancellation) in C:\__w\1\s\Proxy\Gateway.Pipeline\PipelineWalker.cs:line 66

at Microsoft.WindowsAzure.ApiManagement.Proxy.Gateway.ChildPipeline.ExecuteAsync(IPipelineContext context, CancellationToken cancellationToken) in C:\__w\1\s\Proxy\Gateway.Pipeline\ChildPipeline.cs:line 35

at Gateway.Pipeline.Extensions.ValueTaskExtensions.Await[T](ValueTask`1 input) in C:\__w\1\s\Proxy\Gateway.Pipeline\Extensions\ValueTaskExtensions.cs:line 28

at Microsoft.WindowsAzure.ApiManagement.Proxy.Gateway.Policies.PipelineWalker.ExecuteAsync(IPipelineContext context, IEnumerable`1 steps, CancellationToken cancellation) in C:\__w\1\s\Proxy\Gateway.Pipeline\PipelineWalker.cs:line 66

at Microsoft.WindowsAzure.ApiManagement.Proxy.Gateway.PipelineExecutor.ExecuteAsync(IPipelineContext context, CancellationToken cancellationToken) in C:\__w\1\s\Proxy\Gateway.Pipeline\PipelineExecutor.cs:line 215, transportError: 0, httpError: 0

[Info] 2026-01-23T07:26:26.678 [GatewayLogs], correlationId: x-x-x-x, isRequestSuccess: false, totalTime: 922, category: "GatewayLogs", callerIpAddress: "x.x.x.x", timeGenerated: 2026-01-23T07:26:26.678, region: "aks", correlationId: "x-x-x-x-x", method: "GET", url: "https://x.x.x.x/xselfca", responseCode: 500, responseSize: 259, cache: "none", backendTime: 920, apiId: "XXXXXXXXXXXXXXXXXXX", operationId: "get-home-page", clientProtocol: "HTTP/1.1", apiRevision: "1", clientTlsVersion: "1.3", backendMethod: "GET", backendUrl: "https://xxx.xxx.com/", lastError: {"elapsed":921,"source":"request-forwarder","path":"forward-request\\forward-request","reason":"BackendConnectionFailure","message":"The remote certificate was rejected by the provided RemoteCertificateValidationCallback.","section":"backend"}, errors: [{"elapsed":921,"source":"request-forwarder","path":"forward-request\\forward-request","reason":"BackendConnectionFailure","message":"The remote certificate was rejected by the provided RemoteCertificateValidationCallback.","section":"backend"}]

[Info] 2026-01-23T07:27:22.895 [InitialDnsNeighborDiscoverySucceeded], message: Successfully resolved IP addresses for DNS name xnewcstest-instance-discovery: 10.244.1.11, source: Neighborhood

 

参考资料

Use custom certificate authorities (CAs) in Azure Kubernetes Service (AKS) : https://learn.microsoft.com/en-us/azure/aks/custom-certificate-authority

 



当在复杂的环境中面临问题,格物之道需:浊而静之徐清,安以动之徐生。 云中,恰是如此!

相关文章
|
2月前
|
人工智能 弹性计算 Cloud Native
【云故事探索】NO.19:阿里云 × 闪剪智能:AI 原生重塑视频创作
深圳闪剪智能,12年打磨短视频工具、5年深耕AI,国内数字人先行者,服务全球3亿用户。携手阿里云,以ACK弹性计算、全球加速与FinOps体系,破解高并发与成本难题,打造AI原生视频创作引擎。
|
3月前
|
人工智能 运维 监控
进阶指南:BrowserUse + AgentRun Sandbox 最佳实践
本文将深入讲解 BrowserUse 框架集成、提供类 Manus Agent 的代码示例、Sandbox 高级生命周期管理、性能优化与生产部署策略。涵盖连接池设计、安全控制、可观测性建设及成本优化方案,助力构建高效、稳定、可扩展的 AI 浏览器自动化系统。
750 48
|
2月前
|
人工智能 安全 应用服务中间件
Docker OpenClaw 生产环境部署指南(单机架构版)
OpenClaw是2026年爆火的开源AI执行引擎,由PSPDFKit创始人Peter Steinberger主导开发。它不是聊天机器人,而是本地运行、可自托管的“数字员工”,支持自然语言指令驱动全流程任务执行,兼容主流大模型与通讯平台,MIT协议开源。
2404 3
|
1月前
|
人工智能 安全 索引
【Azure AI Search】AI Search的索引器(Indexer)中使用解码函数base64Decode报错
Azure AI Search索引器使用base64Decode时失败,因默认启用URL安全解码(useHttpServerUtilityUrlTokenDecode=true),而源数据为标准Base64编码。解决方案:在mappingFunction中显式设置`&quot;useHttpServerUtilityUrlTokenDecode&quot;: false`,即可正确解码。
170 6
|
1月前
|
自然语言处理 安全 JavaScript
OpenClaw有什么Skill?OpenClaw部署流程+免费大模型API(百炼+Ollama+Qwen2.5)及 find-skills 功能详解
而find-skills技能的出现,彻底解决了这一痛点。作为OpenClaw生态中最受欢迎的技能发现工具,它累计部署量达87.6k,收获398个GitHub星标,支持通过自然语言或关键词快速搜索、安装、更新技能,让技能管理像“逛应用商店”一样简单。本文基于官方文档与实测经验,先拆解find-skills的核心功能与安全注意事项,再完整呈现2026年OpenClaw零基础阿里云部署流程、阿里云百炼API与免费大模型API(Ollama+Qwen2.5)双配置方案,详解find-skills实战场景与避坑要点,所有代码命令可直接复制执行,无营销词汇,助力新手高效解锁OpenClaw的全场景能力。
2426 7
|
2月前
|
开发者
【Azure App Service】记录App Service Kudu站点的File Manger中无法查看文件列表的原因
本文描述Azure App Service Kudu控制台中文件目录UI显示为空(实际有文件),但PowerShell的`ls`命令可正常列出的问题。通过浏览器开发者工具定位到Unicode字符编码错误(\uDC6D),根源是文件名含非法代理对字符。解决方案:检查并重命名本地文件。
110 6
|
2月前
|
安全 Go Python
【Azure Function】在Azure上的 Python Function 资源被扫描出包含安全漏洞
Azure Python Function因`cryptography&lt;41.0.5`(当前3.1.1)存在CVE-2023-5363高危漏洞。本地开发可直接修改requirements.txt;Portal创建的函数则需通过Kudu站点(scm.chinacloudsites.cn)进入/wwwroot,编辑requirements.txt升级版本并重启应用。
179 11
|
2月前
|
人工智能 安全 JavaScript
Claude Code 中的 Commands、Skills 与 Agents:不是进阶路径,而是协作维度
本文澄清Claude Code中Commands、Skills、Agents并非线性进阶关系,而是面向不同协作粒度的互补机制:Commands用于即时原子操作,Skills封装可复用专业能力,Agents承担目标导向的自主任务。三者构成“协作三角”,应依任务复杂度灵活选用或组合,核心是扩展而非替代人类能力。(239字)
2185 10
|
2月前
|
开发工具 C++ Python
【Azure Function App】部署完 Azure Function 发现 Function 在门户消失了
VS Code部署Python Function App至Azure成功,但门户无函数显示。经查,因`WEBSITE_RUN_FROM_PACKAGE=1`导致依赖未按requirements.txt安装,缺失`azure.monitor`包。解决:设该变量为0,补全依赖,重新部署即可。
146 2
|
3月前
|
JSON 人工智能 自然语言处理
基于Qwen-3B-Raw的本地化SD Prompt生成器研究
本项目用NLP技术把人类的模糊美学意图,蒸馏成可重复、可微调、可部署的图像生成指令引擎。
319 13