Gin HTTPS与证书配置
HTTPS 是 Web 安全的基础,Gin 框架支持多种证书配置方式。
基本HTTPS启动
使用证书文件
Go
func main() {
r := gin.Default()
// 配置路由
r.GET("/", func(c *gin.Context) {
c.String(200, "HTTPS OK")
})
// 启动 HTTPS
r.RunTLS(":443", "server.crt", "server.key")
}
同时支持 HTTP 和 HTTPS
Go
func main() {
r := gin.Default()
r.GET("/", func(c *gin.Context) {
c.String(200, "Hello")
})
// HTTP 重定向到 HTTPS
go func() {
http.ListenAndServe(":80", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, "https://"+r.Host+r.URL.String(), http.StatusMovedPermanently)
}))
}()
// HTTPS 服务
r.RunTLS(":443", "server.crt", "server.key")
}
自签名证书生成
使用 OpenSSL
Bash
# 生成私钥
openssl genrsa -out server.key 2048
# 生成证书签名请求(CSR)
openssl req -new -key server.key -out server.csr
# 生成自签名证书(有效期365天)
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
# 或者一步生成
openssl req -x509 -newkey rsa:2048 -nodes -keyout server.key -out server.crt -days 365 -subj "/CN=localhost"
代码中生成证书
Go
import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"math/big"
"os"
"time"
)
func generateSelfSignedCert() error {
// 生成私钥
priv, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
return err
}
// 设置证书模板
template := x509.Certificate{
SerialNumber: big.NewInt(1),
Subject: pkix.Name{
Organization: []string{"My Company"},
},
NotBefore: time.Now(),
NotAfter: time.Now().Add(365 * 24 * time.Hour),
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
ExtKeyUsage: []x509.ExtKeyUsage{
x509.ExtKeyUsageServerAuth,
},
DNSNames: []string{"localhost"},
}
// 生成证书
derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv)
if err != nil {
return err
}
// 保存证书
certOut, _ := os.Create("server.crt")
pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
certOut.Close()
// 保存私钥
keyOut, _ := os.Create("server.key")
pem.Encode(keyOut, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)})
keyOut.Close()
return nil
}
Let's Encrypt 自动证书
使用 autocert
Go
import (
"golang.org/x/crypto/acme/autocert"
)
func main() {
r := gin.Default()
// 配置自动证书管理
m := &autocert.Manager{
Prompt: autocert.AcceptTOS,
HostPolicy: autocert.HostWhitelist("example.com", "www.example.com"),
Cache: autocert.DirCache("certs"),
}
// HTTPS 服务器
s := &http.Server{
Addr: ":443",
Handler: r,
TLSConfig: m.TLSConfig(),
}
// HTTP 重定向
go http.ListenAndServe(":80", m.HTTPHandler(nil))
s.ListenAndServeTLS("", "")
}
Gin 中使用 autocert
Go
func main() {
r := gin.Default()
r.GET("/", func(c *gin.Context) {
c.String(200, "HTTPS with Let's Encrypt")
})
m := autocert.Manager{
Prompt: autocert.AcceptTOS,
HostPolicy: autocert.HostWhitelist("yourdomain.com"),
Cache: autocert.DirCache("/var/www/.cache"),
}
server := &http.Server{
Addr: ":443",
Handler: r,
TLSConfig: m.TLSConfig(),
}
server.ListenAndServeTLS("", "")
}
TLS 配置优化
Go
import (
"crypto/tls"
"net/http"
)
func main() {
r := gin.Default()
// 自定义 TLS 配置
tlsConfig := &tls.Config{
MinVersion: tls.VersionTLS12, // 最低 TLS 1.2
CipherSuites: []uint16{
tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
},
PreferServerCipherSuites: true,
}
server := &http.Server{
Addr: ":443",
Handler: r,
TLSConfig: tlsConfig,
}
server.ListenAndServeTLS("server.crt", "server.key")
}
HTTPS 安全中间件
Go
func TLSMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
// 强制 HTTPS
if c.Request.TLS == nil {
target := "https://" + c.Request.Host + c.Request.URL.String()
c.Redirect(http.StatusMovedPermanently, target)
c.Abort()
return
}
c.Next()
}
}
func SecurityHeaders() gin.HandlerFunc {
return func(c *gin.Context) {
c.Header("Strict-Transport-Security", "max-age=31536000; includeSubDomains")
c.Next()
}
}
func main() {
r := gin.Default()
r.Use(TLSMiddleware())
r.Use(SecurityHeaders())
r.RunTLS(":443", "server.crt", "server.key")
}
配置方式对比
| 方式 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| 自签名证书 | 开发测试 | 快速生成 | 浏览器警告 |
| Let's Encrypt | 生产环境 | 免费、自动续期 | 需公网访问 |
| 商业证书 | 企业应用 | 受信任、有保障 | 需付费 |
注意:生产环境推荐使用 Let's Encrypt 或商业证书,自签名仅用于开发测试。
要点总结
- 开发环境:使用 OpenSSL 生成自签名证书
- 生产环境:使用 autocert 自动管理 Let's Encrypt 证书
- 安全配置:设置 MinVersion TLS 1.2,选择安全加密套件
- HTTP 重定向:将 HTTP 流量重定向到 HTTPS
- HSTS 头:启用 Strict-Transport-Security 强制 HTTPS
📝 发现内容有误?点击此处直接编辑