diff --git a/utils/ssl/ssl.go b/utils/ssl/ssl.go index 7147e16..004f432 100644 --- a/utils/ssl/ssl.go +++ b/utils/ssl/ssl.go @@ -1,6 +1,7 @@ package ssl import ( + "SamWaf/common/zlog" "SamWaf/model" "SamWaf/utils" "crypto" @@ -93,18 +94,23 @@ func RegistrationSSL(order model.SslOrder, savePath string, caServerAddress stri // because we aren't running as root and can't bind a listener to port 80 and 443 // (used later when we attempt to pass challenges). Keep in mind that you still // need to proxy challenge traffic to port 5002 and 5001. - if order.ApplyMethod == "http01" { + switch order.ApplyMethod { + case "http01": provider, err := webroot.NewHTTPProvider(savePath) if err != nil { return order, err } err = client.Challenge.SetHTTP01Provider(provider) - } else if order.ApplyMethod == "dns01" { + case "dns01": dnsProvider, err := GetDnsProvider(order.ApplyDns) if err != nil { + zlog.Error(fmt.Sprintf("Failed to initialize DNS provider `%s`: %v", order.ApplyDns, err)) return order, err } err = setDNS01ProviderWithRetry(client, dnsProvider, order.SkipDNSVerify) + if err != nil { + zlog.Error(fmt.Sprintf("Failed to set DNS-01 provider: %v", err)) + } } if err != nil { @@ -134,6 +140,11 @@ func RegistrationSSL(order model.SslOrder, savePath string, caServerAddress stri certificates := &certificate.Resource{} if !isIpSSL { + // 诊断域名权威 NS + if order.ApplyMethod == "dns01" { + DiagnoseDomainNS(order.ApplyDomain) + } + request := certificate.ObtainRequest{ Domains: strings.Split(order.ApplyDomain, ","), Bundle: true, @@ -187,7 +198,6 @@ func RegistrationSSL(order model.SslOrder, savePath string, caServerAddress stri } // Each certificate comes back with the cert bytes, the bytes of the client's // private key, and a certificate URL. SAVE THESE TO DISK. - fmt.Printf("%#v\n", certificates) order.ResultPrivateKey = certificates.PrivateKey order.ResultCertificate = certificates.Certificate @@ -270,9 +280,13 @@ func ReNewSSL(order model.SslOrder, savePath string, caServerAddress string, app } else if order.ApplyMethod == "dns01" { dnsProvider, err := GetDnsProvider(order.ApplyDns) if err != nil { + zlog.Error(fmt.Sprintf("Failed to initialize DNS provider `%s`: %v", order.ApplyDns, err)) return order, err } err = setDNS01ProviderWithRetry(client, dnsProvider, order.SkipDNSVerify) + if err != nil { + zlog.Error(fmt.Sprintf("Failed to set DNS-01 provider: %v", err)) + } } if err != nil { @@ -303,6 +317,11 @@ func ReNewSSL(order model.SslOrder, savePath string, caServerAddress string, app certificates := &certificate.Resource{} if !isIpSSL { + // 诊断域名权威 NS + if order.ApplyMethod == "dns01" { + DiagnoseDomainNS(order.ApplyDomain) + } + // 域名证书:使用续期方式 certRes := certificate.Resource{ Domain: order.ResultDomain, @@ -365,7 +384,6 @@ func ReNewSSL(order model.SslOrder, savePath string, caServerAddress string, app // Each certificate comes back with the cert bytes, the bytes of the client's // private key, and a certificate URL. SAVE THESE TO DISK. - fmt.Printf("%#v\n", certificates) order.ResultPrivateKey = certificates.PrivateKey order.ResultCertificate = certificates.Certificate @@ -431,13 +449,10 @@ func GetDnsProvider(dnsName string) (challenge.Provider, error) { case "huaweicloud": return huaweicloud.NewDNSProvider() case "tencentcloud": - return tencentcloud.NewDNSProvider() case "cloudflare": - return cloudflare.NewDNSProvider() case "baiducloud": - return baiducloud.NewDNSProvider() default: return nil, fmt.Errorf("unrecognized DNS provider: %s", dnsName) @@ -445,13 +460,16 @@ func GetDnsProvider(dnsName string) (challenge.Provider, error) { } func setDNS01ProviderWithRetry(client *lego.Client, dnsProvider challenge.Provider, skipDNSVerify int64) error { - // 默认重试3次,每次间隔15秒 - dnsPrecheckRetry := 3 - dnsPrecheckRetryInterval := 15 * time.Second + // 默认重试10次,每次间隔30秒 + dnsPrecheckRetry := 10 + dnsPrecheckRetryInterval := 30 * time.Second + + // DNS 传播等待时间:300秒(3分钟) + propagationTimeout := 180 * time.Second if skipDNSVerify == 1 { // 跳过本地DNS传播校验:固定等待后直接通知CA进行验证 - return client.Challenge.SetDNS01Provider(dnsProvider, dns01.PropagationWait(60*time.Second, true)) + return client.Challenge.SetDNS01Provider(dnsProvider, dns01.PropagationWait(propagationTimeout, true)) } // 默认执行本地DNS传播校验,并增加重试机制 @@ -476,3 +494,31 @@ func setDNS01ProviderWithRetry(client *lego.Client, dnsProvider challenge.Provid }), ) } + +// DiagnoseDomainNS 诊断域名的权威 NS 服务器 +func DiagnoseDomainNS(domain string) error { + zlog.Info(fmt.Sprintf("Checking authoritative nameservers for domain: %s", domain)) + + // 查询域名的权威 NS 记录 + nameServers, err := net.LookupNS(domain) + if err != nil { + zlog.Warn(fmt.Sprintf("Failed to lookup NS records for %s: %v", domain, err)) + return err + } + + // 检查是否是预期的 DNS 提供商 + nsStr := strings.ToLower(fmt.Sprintf("%v", nameServers)) + if strings.Contains(nsStr, "dnspod") || strings.Contains(nsStr, "tencent") { + zlog.Info(fmt.Sprintf("Domain %s is managed by Tencent Cloud DNSPod", domain)) + } else if strings.Contains(nsStr, "alidns") || strings.Contains(nsStr, "alibaba") { + zlog.Warn(fmt.Sprintf("Domain %s appears to be managed by Alibaba Cloud (not Tencent Cloud)", domain)) + } else if strings.Contains(nsStr, "huawei") { + zlog.Warn(fmt.Sprintf("Domain %s appears to be managed by Huawei Cloud (not Tencent Cloud)", domain)) + } else if strings.Contains(nsStr, "cloudflare") { + zlog.Warn(fmt.Sprintf("Domain %s appears to be managed by Cloudflare (not Tencent Cloud)", domain)) + } else { + zlog.Warn(fmt.Sprintf("Domain %s's authoritative NS is not recognized. Make sure NS records point to your DNS provider", domain)) + } + + return nil +} diff --git a/wafenginecore/sslorder.go b/wafenginecore/sslorder.go index 951f812..73d033f 100644 --- a/wafenginecore/sslorder.go +++ b/wafenginecore/sslorder.go @@ -31,6 +31,7 @@ func (waf *WafEngine) ApplySSLOrder(chanType int, bean model.SslOrder) { //加载环境变量 privateGroupName := bean.PrivateGroupName privateGroupBelongCloud := bean.ApplyDns + zlog.Debug(fmt.Sprintf("Loading DNS provider env info - Group: `%s`, Cloud: `%s` for domain: %s", privateGroupName, privateGroupBelongCloud, bean.ApplyDomain)) //查询环境变量信息 wafssl.LoadDnsProviderEnvInfo(privateGroupName, privateGroupBelongCloud) } diff --git a/wafssl/wafssl.go b/wafssl/wafssl.go index 78e8f1b..1adad86 100644 --- a/wafssl/wafssl.go +++ b/wafssl/wafssl.go @@ -11,19 +11,46 @@ import ( // LoadDnsProviderEnvInfo 初始化dns所需要的参数信息 func LoadDnsProviderEnvInfo(groupName string, belongCloud string) { - privateInfos, _, err := waf_service.WafPrivateInfoServiceApp.GetListByGroupAndBelongCloudPureApi(groupName, belongCloud) - if err == nil { - for _, info := range privateInfos { - err := os.Setenv(info.PrivateKey, info.PrivateValue) - if err != nil { - return - } else { - zlog.Info(fmt.Sprintf("Cloud `%s` Group `%s` ENV `%s` LOADED", belongCloud, groupName, info.PrivateKey)) - } - } + // 清除旧的 DNS provider 相关环境变量,防止污染 + dnsEnvKeys := []string{ + // Tencent Cloud + "TENCENTCLOUD_SECRET_ID", "TENCENTCLOUD_SECRET_KEY", "TENCENTCLOUD_REGION", + // Alibaba Cloud + "ALICLOUD_ACCESS_KEY", "ALICLOUD_SECRET_KEY", "ALICLOUD_REGION_ID", + // Huawei Cloud + "HUAWEICLOUD_DOMAIN_NAME", "HUAWEICLOUD_ACCESS_KEY_ID", "HUAWEICLOUD_ACCESS_KEY_SECRET", "HUAWEICLOUD_REGION", + // Cloudflare + "CLOUDFLARE_API_TOKEN", "CLOUDFLARE_API_KEY", "CLOUDFLARE_ACCOUNT_ID", + // Baidu Cloud + "BAIDUCLOUD_ACCESS_KEY", "BAIDUCLOUD_SECRET_ACCESS_KEY", "BAIDUCLOUD_REGION", } + for _, key := range dnsEnvKeys { + os.Unsetenv(key) + } + + privateInfos, _, err := waf_service.WafPrivateInfoServiceApp.GetListByGroupAndBelongCloudPureApi(groupName, belongCloud) + if err != nil { + zlog.Error(fmt.Sprintf("Failed to load DNS provider env info for cloud `%s` group `%s`: %v", belongCloud, groupName, err)) + return + } + if len(privateInfos) == 0 { + zlog.Warn(fmt.Sprintf("No DNS credentials found in DB for cloud `%s` group `%s` - DNS provider will have no auth", belongCloud, groupName)) + return + } + + for _, info := range privateInfos { + err := os.Setenv(info.PrivateKey, info.PrivateValue) + if err != nil { + zlog.Error(fmt.Sprintf("Failed to set env var `%s`: %v", info.PrivateKey, err)) + return + } + zlog.Info(fmt.Sprintf("Cloud `%s` Group `%s` ENV `%s` LOADED", belongCloud, groupName, info.PrivateKey)) + } + + zlog.Info(fmt.Sprintf("Successfully loaded %d credentials for cloud `%s` group `%s`", len(privateInfos), belongCloud, groupName)) + if global.GWAF_RELEASE == "false" { - fmt.Println("当前环境变量:") + zlog.Debug("Current DNS-related environment variables:") for _, env := range os.Environ() { parts := strings.SplitN(env, "=", 2) key := parts[0] @@ -31,7 +58,7 @@ func LoadDnsProviderEnvInfo(groupName string, belongCloud string) { if len(parts) > 1 { value = parts[1] } - fmt.Printf("%s = %s\n", key, value) + zlog.Debug(fmt.Sprintf("%s = %s", key, value)) } } }