Ubuntu生产环境.NET6 API重启失败,HTTPS证书配置异常排查
自2022年3月起,我在AWS EC2的Ubuntu 20.04服务器上通过NGINX托管.NET6 API。今日进行常规部署后,API服务无法重启,这是首次出现该问题。
执行systemctl restart后运行systemctl status的输出:
Anovite.Api.service - .NET Web API App running on Ubuntu Loaded: loaded (/etc/systemd/system/Anovite.Api.service; enabled; vendor preset: enabled) Active: activating (auto-restart) (Result: core-dump) since Sun 2023-01-08 22:18:31 UTC; 8s ago Process: 1970 ExecStart=/usr/bin/dotnet /var/www/Anovite.Api/Anovite.Api.dll (code=dumped, signal=ABRT) Main PID: 1970 (code=dumped, signal=ABRT)
运行journalctl -f得到以下输出:
Unhandled exception. System.InvalidOperationException: Unable to configure HTTPS endpoint. No server certificate was specified, and the default developer certificate could not be found or is out of date To generate a developer certificate run 'dotnet dev-certs https'. To trust the certificate (Windows and macOS only) run 'dotnet dev-certs https --trust'. For more information on configuring HTTPS see https://go.microsoft.com/fwlink/?linkid=848054. at Microsoft.AspNetCore.Server.Kestrel.KestrelConfigurationLoader.Reload() at Microsoft.AspNetCore.Server.Kestrel.KestrelConfigurationLoader.Load() at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerImpl.BindAsync(CancellationToken cancellationToken) at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerImpl.StartAsync[TContext](IHttpApplication`1 application, CancellationToken cancellationToken) at Microsoft.AspNetCore.Hosting.GenericWebHostService.StartAsync(CancellationToken cancellationToken) at Microsoft.Extensions.Hosting.Internal.Host.StartAsync(CancellationToken cancellationToken) at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token) at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token) at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.Run(IHost host) at Microsoft.AspNetCore.Builder.WebApplication.Run(String url)
起初我担心证书过期,这些证书由letsencrypt生成,但申请新证书时提示现有证书远未过期。
搜索上述错误发现大多是开发环境问题,但这是生产服务器,我们并未在本机访问API,困惑为何.NET运行时突然需要开发者证书,明明已安装有效未过期的证书。
NGINX的default.conf文件指定了主机上证书的存储路径,该配置文件数月未编辑。
当前运行的.NET版本:
dotnet --list-sdks 6.0.101 [/usr/share/dotnet/sdk] dotnet --list-runtimes Microsoft.AspNetCore.App 6.0.1 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App] Microsoft.NETCore.App 6.0.1 [/usr/share/dotnet/shared/Microsoft.NETCore.App]
最奇怪的是回滚到API旧版本也无法解决问题,问题始于新版本文件上传并重启服务后,恢复旧版本文件后服务仍无法启动,无论部署哪个版本,Postman请求API均返回503 Bad Gateway。
请问我遗漏了什么?
核心原因分析
这个错误的本质是Kestrel服务本身在尝试绑定HTTPS端口,但找不到可用的证书——和NGINX配置的Let's Encrypt证书无关,因为NGINX是反向代理,你的API应该是监听HTTP端口,由NGINX做SSL终止。现在Kestrel被配置成要启动HTTPS端点,但没有给它指定生产证书,所以它才会去寻找开发者证书。
排查&修复步骤
检查API的配置文件
打开appsettings.json或appsettings.Production.json,确认Kestrel节点或者Urls配置是否被修改,是否包含https://开头的地址。生产环境下,Kestrel应该只监听http://localhost:xxxx或者http://0.0.0.0:xxxx,让NGINX来处理HTTPS。如果发现有HTTPS相关配置,直接删除或注释,只保留HTTP监听地址。检查环境变量与服务配置
查看是否设置了ASPNETCORE_URLS环境变量,运行echo $ASPNETCORE_URLS确认是否包含HTTPS地址,若有则清空或修改为HTTP地址。同时检查/etc/systemd/system/Anovite.Api.service文件,看ExecStart行是否添加了--urls参数指定HTTPS,或是设置了相关环境变量,有则修正。验证文件权限
回滚旧版本后仍无法启动,可能是部署过程中修改了API目录或配置文件的权限。运行ls -l /var/www/Anovite.Api/检查文件所有者,确保运行dotnet的用户(通常是www-data或自定义服务用户)有读写权限,若权限错误,执行sudo chown -R www-data:www-data /var/www/Anovite.Api/修正。临时应急方案(不推荐长期使用)
如果需要快速验证问题,可临时生成开发者证书:运行dotnet dev-certs https -ep /usr/share/dotnet/https/aspnetapp.pfx -p <自定义密码>,然后在配置文件中指定该证书路径。但这只是临时方案,生产环境必须让Kestrel走HTTP,由NGINX处理SSL。
关键提醒
生产环境中,.NET Core API通过NGINX反向代理时,Kestrel不需要处理HTTPS,所有SSL终止都交给NGINX来做,这样既安全又便于统一管理证书。你的问题大概率是部署过程中误改了API的监听配置,导致Kestrel尝试启动HTTPS端点,而又没有配置对应的生产证书,才触发了寻找开发者证书的错误。
内容的提问来源于stack exchange,提问作者LNX

