Ubuntu 20上.NET Kestrel无响应及Nginx 403问题求助
.NET应用在Ubuntu上的端口连接与Nginx反向代理问题
问题背景
我在Ubuntu系统上运行.NET应用,使用以下配置和代码:
appsettings.json配置
{ "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } }, "AllowedHosts": "*", "ConnectionStrings": { "DefaultConnection": "Server=1.2.3.5:1234;Database=somedomain.com;Uid=default;Pwd=password;" }, "Kestrel": { "Endpoints": { "Https": { "Url": "https://localhost:7000", "Certificate": { "Path": "/etc/letsencrypt/live/somedomain.com/cert.pem", "KeyPath": "/etc/letsencrypt/live/somedomain.com/privkey.pem" } } } } }
Program.cs代码
using Microsoft.AspNetCore.HttpOverrides; var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllers(); builder.Services.AddRazorPages(); var app = builder.Build(); app.UseForwardedHeaders(new ForwardedHeadersOptions { ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto }); // Configure the HTTP request pipeline. if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Error"); //app.UseHttpsRedirection(); } app.UseStaticFiles(); app.UseRouting(); app.UseAuthorization(); app.MapControllers(); app.MapRazorPages(); app.Run();
初始问题:应用启动正常,lsof -i:7000显示端口处于监听状态,但外部主机用telnet无法连接,本地连接正常。Nginx运行时,通过浏览器访问443端口返回403 Forbidden,初始Nginx配置如下:
limit_req_zone $binary_remote_addr zone=one:10m rate=5r/s; server_tokens off; upstream somedomain.com { server 127.0.0.1:7000; } server { root /var/www/somedomain.com; server_name somedomain.com; listen [::]:443 ssl ipv6only=on; # managed by Certbot listen 443 ssl; # managed by Certbot ssl_certificate /etc/letsencrypt/live/somedomain.com/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/somedomain.com/privkey.pem; # managed by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot add_header X-Frame-Options DENY; add_header X-Content-Type-Options nosniff; #Redirects all traffic location / { proxy_pass https://somedomain.com; limit_req zone=one burst=10 nodelay; try_files $uri $uri/ =404; } } server { if ($host = somedomain.com) { return 301 https://$host$request_uri; } # managed by Certbot listen 80 default_server; listen [::]:80 default_server; server_name somedomain.com; return 404; # managed by Certbot }
更新2:修改了Nginx的location配置,但问题依旧:
location / { proxy_pass https://127.0.0.1:7000/; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; }
问题分析与解决方案
1. 外部无法连接7000端口的原因
Kestrel配置的监听地址是https://localhost:7000,这意味着服务仅绑定本地回环地址(127.0.0.1),外部请求无法穿透到这个地址。需要修改监听地址为0.0.0.0:7000,让服务监听服务器所有网卡:
修改appsettings.json中的Kestrel配置:
"Kestrel": { "Endpoints": { "Https": { "Url": "https://0.0.0.0:7000", "Certificate": { "Path": "/etc/letsencrypt/live/somedomain.com/cert.pem", "KeyPath": "/etc/letsencrypt/live/somedomain.com/privkey.pem" } } } }
同时确保Ubuntu防火墙开放7000端口:
sudo ufw allow 7000/tcp sudo ufw reload
2. Nginx返回403 Forbidden的原因
核心问题:初始配置冲突与不必要的本地目录绑定
- 初始
location /块同时存在proxy_pass和try_files,Nginx会优先尝试查找本地文件,找不到就直接返回404,不会执行反向代理。 - 配置中的
root /var/www/somedomain.com;会让Nginx尝试访问本地目录,如果该目录不存在、权限不足或没有默认索引文件,就会返回403。
修正步骤:
- 移除Nginx server块中的
root /var/www/somedomain.com;配置(如果.NET应用不需要Nginx托管静态资源)。 - 确保Kestrel服务本地可访问:执行
curl https://127.0.0.1:7000,确认能正常返回响应。 - 查看Nginx错误日志(
/var/log/nginx/error.log),排查具体的403触发原因(比如证书验证、权限问题)。
修正后的Nginx server块示例:
server { server_name somedomain.com; listen [::]:443 ssl ipv6only=on; # managed by Certbot listen 443 ssl; # managed by Certbot ssl_certificate /etc/letsencrypt/live/somedomain.com/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/somedomain.com/privkey.pem; # managed by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot add_header X-Frame-Options DENY; add_header X-Content-Type-Options nosniff; location / { proxy_pass https://127.0.0.1:7000/; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; limit_req zone=one burst=10 nodelay; } }
3. 生效配置的最终步骤
修改完配置后,重启.NET应用和Nginx:
# 假设用systemd托管.NET应用,替换为你的服务名 sudo systemctl restart your-dotnet-app.service # 重启Nginx sudo systemctl restart nginx
另外,检查Kestrel证书文件的权限,确保运行.NET应用的用户(比如www-data)有权限读取证书:
sudo chown -R www-data:www-data /etc/letsencrypt/live/somedomain.com/ sudo chmod -R 755 /etc/letsencrypt/live/somedomain.com/
内容的提问来源于stack exchange,提问作者Andy
相关产品推荐
相关产品推荐

