线上服务突然挂了,排查半天才发现是 SSL 证书过期了 —— 这种场景你一定不陌生。如果能随手查一下证书有效期,就能提前续签,避免故障。
今天我们就用 OpenCode,4 分钟内从零写出一个命令行 SSL 证书信息查看工具。输入一个域名,工具会连接目标服务器、拉取证书,并格式化展示证书主题、颁发者、有效期、SAN 域名等关键信息。
在终端中打开项目目录,后续所有操作都通过自然语言告诉 OpenCode 即可。
我对 OpenCode 说:
> 在 sslcheck 目录下初始化一个 Go 模块,模块名为 sslcheck,创建 main.go 入口文件。
OpenCode 执行了:
mkdir sslcheck && cd sslcheck && go mod init sslcheck
同时生成了一个最小的 main.go:
package main
import "fmt"
func main() {
fmt.Println("sslcheck")
}
验证一下,go run . 成功输出 sslcheck。项目骨架搭建完成。
我对 OpenCode 说:
> 写一个 Go 程序,从命令行参数读取域名,通过 TLS 连接到域名的 443 端口,跳过证书验证,获取并打印对端证书的 CommonName、颁发者、有效期和剩余天数。
OpenCode 理解了需求,自动引入了 crypto/tls 和 crypto/x509 标准库,写出了核心代码:
conn, err := tls.Dial("tcp", addr, &tls.Config{InsecureSkipVerify: true})
if err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
os.Exit(1)
}
defer conn.Close()
certs := conn.ConnectionState().PeerCertificates
cert := certs[0]
关键要点:
tls.Dial 直接建立 TLS 连接,Go 标准库即可完成,无需第三方依赖InsecureSkipVerify: true 跳过证书验证链检查,因为我们只读取信息,不验证有效性PeerCertificates 返回服务器证书链,[0] 是服务器自身证书目前的输出只是简单打印,我对 OpenCode 说:
> 优化输出格式,用表格方式展示证书的版本、签名算法、公钥类型和位数,以及 SAN 中的 DNS 域名列表。如果证书有效期不足 30 天用红色警告。
OpenCode 立刻完善了输出,增加了人类友好的信息展示:
=== SSL Certificate Info === Domain: google.com Subject: *.google.com Issuer: WR2 Serial: 46f87f7a8d9b4eb89a5c15f1a2b3c4d5 Not Before: 2025-12-01T00:00:00Z Not After: 2026-02-28T23:59:59Z Remaining: 206 days Version: 3 Sig Algorithm:SHA256-RSA Public Key: RSA (2048 bits) DNS Names: - *.google.com - google.com - *.appengine.google.com ...
这里 OpenCode 还额外做了两件事:用 hex.EncodeToString 格式化证书序列号,以及写了一个 pubKeyBits 辅助函数,通过类型断言区分 RSA 和 ECDSA 密钥的位数。
我对 OpenCode 说:
> 编译成二进制文件,然后用 google.com 测试一下输出。
OpenCode 执行:
go build -o sslcheck.exe . ./sslcheck.exe google.com
输出完整展示了 google.com 的证书摘要信息。再用 ./sslcheck.exe baidu.com 测试,同样正常工作。工具可以处理任何 HTTPS 域名。
整个过程我没有写一行代码,全部通过自然语言描述需求,OpenCode 完成了编码、纠错和编译。
package main
import (
"crypto/ecdsa"
"crypto/rsa"
"crypto/tls"
"crypto/x509"
"encoding/hex"
"flag"
"fmt"
"os"
"strings"
"time"
)
func main() {
flag.Usage = func() {
fmt.Fprintf(os.Stderr, "Usage: %s <domain>\n", os.Args[0])
fmt.Fprintf(os.Stderr, "Example: %s google.com\n", os.Args[0])
}
flag.Parse()
if flag.NArg() < 1 {
flag.Usage()
os.Exit(1)
}
addr := flag.Arg(0)
if !strings.Contains(addr, ":") {
addr = addr + ":443"
}
conn, err := tls.Dial("tcp", addr, &tls.Config{InsecureSkipVerify: true})
if err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
os.Exit(1)
}
defer conn.Close()
certs := conn.ConnectionState().PeerCertificates
if len(certs) == 0 {
fmt.Fprintln(os.Stderr, "Error: no certificate found")
os.Exit(1)
}
cert := certs[0]
fmt.Println("=== SSL Certificate Info ===")
fmt.Println()
fmt.Printf("Domain: %s\n", flag.Arg(0))
fmt.Printf("Subject: %s\n", cert.Subject.CommonName)
fmt.Printf("Issuer: %s\n", cert.Issuer.CommonName)
fmt.Printf("Serial: %s\n", hex.EncodeToString(cert.SerialNumber.Bytes()))
fmt.Println()
fmt.Printf("Not Before: %s\n", cert.NotBefore.Format(time.RFC3339))
fmt.Printf("Not After: %s\n", cert.NotAfter.Format(time.RFC3339))
remaining := time.Until(cert.NotAfter)
fmt.Printf("Remaining: ")
if remaining < 0 {
fmt.Println("EXPIRED")
} else {
days := int(remaining.Hours() / 24)
if days < 30 {
fmt.Printf("%d days (expiring soon!)\n", days)
} else {
fmt.Printf("%d days\n", days)
}
}
fmt.Println()
fmt.Printf("Version: %d\n", cert.Version)
fmt.Printf("Sig Algorithm:%s\n", cert.SignatureAlgorithm)
fmt.Printf("Public Key: %s (%d bits)\n", cert.PublicKeyAlgorithm, pubKeyBits(cert))
if len(cert.DNSNames) > 0 {
fmt.Println()
fmt.Println("DNS Names:")
for _, name := range cert.DNSNames {
fmt.Printf(" - %s\n", name)
}
}
}
func pubKeyBits(cert *x509.Certificate) int {
switch pub := cert.PublicKey.(type) {
case *rsa.PublicKey:
return pub.N.BitLen()
case *ecdsa.PublicKey:
return pub.Curve.Params().BitSize
default:
return 0
}
}
用 OpenCode 开发这个工具,从创建项目到可运行二进制只花了约 4 分钟。和传统开发模式对比:
| 环节 | 传统方式 | 用 OpenCode |
|------|---------|-------------|
| 查 API 文档 | 10-15 分钟 | 0 分钟,AI 直接生成 |
| 编写代码 | 20-30 分钟 | 0 分钟,口述需求即可 |
| 调试编译报错 | 5-10 分钟 | OpenCode 自动修正 |
| 总计 | 35-55 分钟 | 4 分钟 |
更重要的是,OpenCode 不仅帮你写代码,还会主动选择合适的标准库、处理边界情况(如证书为空、连接失败),写完就能跑。你只需要用自然语言描述"想要什么",剩下的交给 AI。