diff --git a/Hua.DDNS/Jobs/SslDownloadJob.cs b/Hua.DDNS/Jobs/SslDownloadJob.cs index e079051..cb0b4c2 100644 --- a/Hua.DDNS/Jobs/SslDownloadJob.cs +++ b/Hua.DDNS/Jobs/SslDownloadJob.cs @@ -4,6 +4,7 @@ using Hua.DDNS.SslProviders.Ali; using Hua.DDNS.SslProviders.Tencent; using Quartz; using Microsoft.Extensions.Options; +using System.Security.Cryptography.X509Certificates; namespace Hua.DDNS.Jobs { @@ -70,16 +71,32 @@ namespace Hua.DDNS.Jobs var certificate = matchingCertificates.OrderByDescending(c => c.CertEndTime).First(); + var localCertExpiry = GetLocalCertificateExpiry(item); var daysUntilExpiry = (certificate.CertEndTime - DateTime.Now).Days; - if (daysUntilExpiry <= _sslDownloadOption.ExpireDays) + if (localCertExpiry == null) { - _logger.LogInformation($"证书 {certificate.CertificateId} ({certificate.Domain}) 将在 {daysUntilExpiry} 天后过期,开始下载"); + _logger.LogInformation($"本地证书文件不存在,开始下载: {item.Domain}"); downloadTasks.Add(DownloadFileAsync(sslProvider, item, certificate.CertificateId, certificate.Domain)); } else { - _logger.LogInformation($"证书 {certificate.CertificateId} ({certificate.Domain}) 还有 {daysUntilExpiry} 天过期,跳过下载"); + var localDaysUntilExpiry = (localCertExpiry.Value - DateTime.Now).Days; + + if (localDaysUntilExpiry <= _sslDownloadOption.ExpireDays) + { + _logger.LogInformation($"本地证书 {item.Domain} 将在 {localDaysUntilExpiry} 天后过期,开始更新"); + downloadTasks.Add(DownloadFileAsync(sslProvider, item, certificate.CertificateId, certificate.Domain)); + } + else if (certificate.CertEndTime > localCertExpiry.Value) + { + _logger.LogInformation($"云端证书 {item.Domain} 过期时间更晚,开始更新 (本地: {localCertExpiry:yyyy-MM-dd}, 云端: {certificate.CertEndTime:yyyy-MM-dd})"); + downloadTasks.Add(DownloadFileAsync(sslProvider, item, certificate.CertificateId, certificate.Domain)); + } + else + { + _logger.LogInformation($"本地证书 {item.Domain} 还有 {localDaysUntilExpiry} 天过期,跳过下载"); + } } } @@ -93,6 +110,33 @@ namespace Hua.DDNS.Jobs } } + private DateTime? GetLocalCertificateExpiry(SslDownloadItem item) + { + try + { + var domainPath = Path.Combine(_sslDownloadOption.SavePath, item.Domain); + var certFileName = Path.GetFileNameWithoutExtension(item.FileName); + var certPath = Path.Combine(domainPath, $"{certFileName}_bundle.crt"); + + if (!File.Exists(certPath)) + { + _logger.LogInformation($"本地证书文件不存在: {certPath}"); + return null; + } + + var certBytes = File.ReadAllBytes(certPath); + var certificate = new X509Certificate2(certBytes); + + _logger.LogInformation($"本地证书 {item.Domain} 过期时间: {certificate.NotAfter}"); + return certificate.NotAfter; + } + catch (Exception ex) + { + _logger.LogError(ex, $"读取本地证书过期时间失败: {item.FileName}"); + return null; + } + } + private async Task DownloadFileAsync(ISslDownloadProvider provider, SslDownloadItem item, string certificateId, string domain) { try