package main import ( "crypto/tls" "flag" "fmt" "net" "os" "time" ) // main is the entry point for the program, handling SSL certificate validity checks for a specified host and port. func main() { // Define command-line parameters var ( host string port int warningDays int criticalDays int timeout int ) flag.StringVar(&host, "H", "", "Hostname to check") flag.IntVar(&port, "p", 443, "Port to connect to (default: 443)") flag.IntVar(&warningDays, "w", 30, "Warning threshold in days (default: 30)") flag.IntVar(&criticalDays, "c", 15, "Critical threshold in days (default: 15)") flag.IntVar(&timeout, "t", 1000, "Connection timeout in milliseconds (default: 1000)") flag.Parse() if host == "" { fmt.Fprintln(os.Stderr, "Usage: -H [-p ] [-w ] [-c ] [-t ]") os.Exit(1) } // Establish a connection with timeout address := fmt.Sprintf("%s:%d", host, port) dialer := &net.Dialer{Timeout: time.Duration(timeout) * time.Millisecond} conn, err := tls.DialWithDialer(dialer, "tcp", address, &tls.Config{ServerName: host}) if err != nil { fmt.Fprintf(os.Stderr, "CRITICAL: Could not connect to %s (%v)\n", address, err) os.Exit(2) } defer conn.Close() // Fetch the certificate cert := conn.ConnectionState().PeerCertificates[0] // Validate hostname err = cert.VerifyHostname(host) if err != nil { fmt.Fprintf(os.Stderr, "CRITICAL: Hostname verification failed for %s (%v)\n", host, err) os.Exit(2) } // Check expiration timeRemaining := cert.NotAfter.Sub(time.Now()) daysRemaining := int(timeRemaining.Hours() / 24) if daysRemaining < 0 { fmt.Fprintf(os.Stderr, "CRITICAL: Certificate for %s expired %d days ago.\n", host, -daysRemaining) os.Exit(2) } else if daysRemaining < criticalDays { fmt.Printf("CRITICAL: Certificate for %s expires in %d days.\n", host, daysRemaining) os.Exit(2) } else if daysRemaining < warningDays { fmt.Printf("WARNING: Certificate for %s expires in %d days.\n", host, daysRemaining) os.Exit(1) } fmt.Printf("OK: Certificate for %s is valid, expires in %d days.\n", host, daysRemaining) os.Exit(0) }