Go代码简单检测域名证书过期时间

package main

import (
	"crypto/tls"
	"fmt"
	"net"
	"sync"
	"time"
)

type CertInfo struct {
	Domain     string
	ExpiryTime time.Time
	DaysLeft   int
	Error      error
}

func CheckDomain(domain string, wg *sync.WaitGroup, resultChan chan<- CertInfo) {
	defer wg.Done()

	info := CertInfo{Domain: domain}

	conn, err := tls.DialWithDialer(
		&net.Dialer{Timeout: 10 * time.Second},
		"tcp",
		domain+":443",
		&tls.Config{InsecureSkipVerify: true},
	)
	if err != nil {
		info.Error = err
		resultChan <- info
		return
	}
	defer conn.Close()

	state := conn.ConnectionState()
	if len(state.PeerCertificates) == 0 {
		info.Error = fmt.Errorf("no certificates found")
		resultChan <- info
		return
	}
	cert := state.PeerCertificates[0]
	info.ExpiryTime = cert.NotAfter
	info.DaysLeft = int(time.Until(cert.NotAfter).Hours() / 24)

	resultChan <- info
}

func CheckDomainsConcurrently(domains []string) []CertInfo {
	var wg sync.WaitGroup
	resultChan := make(chan CertInfo, len(domains))
	results := make([]CertInfo, 0, len(domains))

	for _, domain := range domains {
		wg.Add(1)
		go CheckDomain(domain, &wg, resultChan)
	}

	wg.Wait()
	close(resultChan)

	for info := range resultChan {
		results = append(results, info)
	}

	return results
}

func main() {
	domains := []string{
		"www.cnblogs.com",
		"www.baidu.com",
		"expired.badssl.com",
		"google.com",
	}

	results := CheckDomainsConcurrently(domains)
	for _, info := range results {
		if info.Error != nil {
			fmt.Printf("%-25s  ERROR: %v\n", info.Domain, info.Error)
		} else {
			fmt.Printf("%-25s  Expires: %s  Days left: %d\n", info.Domain, info.ExpiryTime.Format("2006-01-02 15:04:05"), info.DaysLeft)
		}
	}
}

类似这种

www.baidu.com              Expires: 2025-08-09 01:41:01  Days left: 21
www.cnblogs.com            Expires: 2026-02-16 23:59:59  Days left: 213
expired.badssl.com         Expires: 2015-04-12 23:59:59  Days left: -3749
google.com                 ERROR: dial tcp 46.82.174.69:443: i/o timeout
posted @ 2025-07-18 16:48  朝阳1  阅读(9)  评论(0)    收藏  举报