You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无法通过.NET Core代理服务转发GitHub Webhook至Jenkins

问题描述

环境配置

  • 内网部署Jenkins与Traefik;DMZ区域IIS上部署自行开发的.NET Core代理服务(可公开访问),用于接收GitHub Webhook并转发至内网Jenkins。

错误信息

System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception.
 ---> System.Security.Authentication.AuthenticationException: Authentication failed because the remote party sent a TLS alert: 'InternalError'.
 ---> System.ComponentModel.Win32Exception (0x80090326): The message received was unexpected or badly formatted.
   --- End of inner exception stack trace ---
   // 更多堆栈信息...

代理服务核心代码

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

namespace GithubProxy.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class GitController : ControllerBase
    {
        private readonly HttpClient _httpClient;
        private readonly ILogger<GitController> _logger;

        public GitController(IHttpClientFactory httpClientFactory, ILogger<GitController> logger)
        {
            _logger = logger;
            _httpClient = httpClientFactory.CreateClient();
        }

        [HttpPost("notifyCommit")]
        public async Task<IActionResult> GitHubWebhook([FromBody] dynamic payload)
        {
            return ToActionResult(await ForwardPayloadToJenkins(payload, HttpContext.Request.Headers));
        }

        private async Task<HttpResponseMessage> ForwardPayloadToJenkins(dynamic payload, IHeaderDictionary headers)
        {
            string jsonPayload = payload.ToString();
            string jenkinsUrl = "https://jenkins.xxx.xx/github-webhook/";

            foreach (var header in headers)
            {
                _httpClient.DefaultRequestHeaders.TryAddWithoutValidation(header.Key, header.Value.ToString());
            }

            HttpContent content = new StringContent(jsonPayload, Encoding.UTF8, "application/json");
            return await _httpClient.PostAsync(jenkinsUrl, content);
        }

        public IActionResult ToActionResult(HttpResponseMessage response)
        {
            if (response.IsSuccessStatusCode)
            {
                return new OkResult();
            }
            else
            {
                string errorMessage = response.Content.ReadAsStringAsync().Result;
                return new ObjectResult(errorMessage)
                {
                    StatusCode = (int)response.StatusCode
                };
            }
        }
    }
}

预期结果

代理服务可成功将GitHub Webhook请求转发至内网Jenkins


解决方案

1. 修复TLS版本与证书验证问题

内网Traefik/Jenkins可能仅支持TLS 1.2+,而.NET Core HttpClient默认配置可能不匹配。修改HttpClient的TLS配置:

// 在ConfigureServices或构造函数中替换HttpClient初始化逻辑
var handler = new HttpClientHandler
{
    SslProtocols = SslProtocols.Tls12 | SslProtocols.Tls13,
    // 生产环境请勿直接跳过验证,需将内网CA根证书导入DMZ服务器信任列表
    ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true
};
_httpClient = new HttpClient(handler);

2. 过滤无效请求头

原代码转发所有请求头,部分头(如Host、Content-Length)会干扰目标服务器的TLS握手与请求解析,仅保留GitHub Webhook必需的头:

// 替换原头循环逻辑
var allowedHeaders = new HashSet<string> 
{ 
    "X-GitHub-Event", 
    "X-Hub-Signature", 
    "X-Hub-Signature-256", 
    "User-Agent" 
};
foreach (var header in headers)
{
    if (allowedHeaders.Contains(header.Key) && !_httpClient.DefaultRequestHeaders.Contains(header.Key))
    {
        _httpClient.DefaultRequestHeaders.TryAddWithoutValidation(header.Key, header.Value.ToString());
    }
}

3. 修正Payload序列化方式

dynamic.ToString()可能导致JSON格式错误,改用专业序列化库保证格式一致性:

// 先安装Newtonsoft.Json包:Install-Package Newtonsoft.Json
string jsonPayload = JsonConvert.SerializeObject(payload);

4. 验证网络与DNS连通性

  • 确认DMZ服务器能正确解析jenkins.xxx.xx到内网IP
  • 在DMZ服务器执行测试命令验证TLS握手:
Invoke-WebRequest -Uri "https://jenkins.xxx.xx/github-webhook/" -Method Post -ContentType "application/json" -Body "{}"

若测试同样报错,说明问题出在网络或Traefik的TLS配置,而非代码。

5. 检查Traefik TLS配置

  • 确认Traefik使用的证书有效且未过期
  • 禁用TLS 1.0/1.1等旧版本协议
  • 确保加密套件配置符合.NET Core客户端支持范围

内容的提问来源于stack exchange,提问作者Gift Ntokozo Mavuso

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 05:25:48