284 lines
8.0 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Package variable 提供 SSL/TLS 相关变量。
//
// 该文件包含 mTLS 客户端证书变量,用于日志和访问控制:
// - $ssl_client_verify: 客户端证书验证结果
// - $ssl_client_serial: 客户端证书序列号
// - $ssl_client_subject: 客户端证书主题
// - $ssl_client_issuer: 客户端证书颁发者
// - $ssl_client_fingerprint: 客户端证书指纹
// - $ssl_client_notbefore: 证书生效时间
// - $ssl_client_notafter: 证书过期时间
//
// 作者xfy
package variable
import (
"github.com/valyala/fasthttp"
)
// SSL 变量常量
const (
// VarSSLClientVerify SSL 客户端证书验证结果变量。
VarSSLClientVerify = "ssl_client_verify"
// VarSSLClientSerial SSL 客户端证书序列号变量。
VarSSLClientSerial = "ssl_client_serial"
// VarSSLClientSubject SSL 客户端证书主题变量。
VarSSLClientSubject = "ssl_client_subject"
// VarSSLClientIssuer SSL 客户端证书颁发者变量。
VarSSLClientIssuer = "ssl_client_issuer"
// VarSSLClientFingerprint SSL 客户端证书指纹变量。
VarSSLClientFingerprint = "ssl_client_fingerprint"
// VarSSLClientNotBefore SSL 客户端证书生效时间变量。
VarSSLClientNotBefore = "ssl_client_notbefore"
// VarSSLClientNotAfter SSL 客户端证书过期时间变量。
VarSSLClientNotAfter = "ssl_client_notafter"
// VarSSLClientDNS SSL 客户端证书主题 DN 变量。
VarSSLClientDNS = "ssl_client_s_dn"
// VarSSLClientEmail SSL 客户端证书邮箱变量。
VarSSLClientEmail = "ssl_client_email"
sslProtocolNone = "NONE"
)
// init 注册 SSL 变量
func init() {
// $ssl_client_verify - 客户端证书验证结果
RegisterBuiltin(&BuiltinVariable{
Name: VarSSLClientVerify,
Description: "客户端证书验证结果 (SUCCESS/FAIL/NONE)",
Getter: func(ctx *fasthttp.RequestCtx) string {
return GetSSLClientVerify(ctx)
},
})
// $ssl_client_serial - 客户端证书序列号
RegisterBuiltin(&BuiltinVariable{
Name: VarSSLClientSerial,
Description: "客户端证书序列号",
Getter: func(ctx *fasthttp.RequestCtx) string {
return GetSSLClientSerial(ctx)
},
})
// $ssl_client_subject - 客户端证书主题
RegisterBuiltin(&BuiltinVariable{
Name: VarSSLClientSubject,
Description: "客户端证书主题 (DN)",
Getter: func(ctx *fasthttp.RequestCtx) string {
return GetSSLClientSubject(ctx)
},
})
// $ssl_client_issuer - 客户端证书颁发者
RegisterBuiltin(&BuiltinVariable{
Name: VarSSLClientIssuer,
Description: "客户端证书颁发者 (DN)",
Getter: func(ctx *fasthttp.RequestCtx) string {
return GetSSLClientIssuer(ctx)
},
})
// $ssl_client_fingerprint - 客户端证书指纹
RegisterBuiltin(&BuiltinVariable{
Name: VarSSLClientFingerprint,
Description: "客户端证书 SHA1 指纹",
Getter: func(ctx *fasthttp.RequestCtx) string {
return GetSSLClientFingerprint(ctx)
},
})
// $ssl_client_notbefore - 证书生效时间
RegisterBuiltin(&BuiltinVariable{
Name: VarSSLClientNotBefore,
Description: "客户端证书生效时间 (ISO8601)",
Getter: func(ctx *fasthttp.RequestCtx) string {
return GetSSLClientNotBefore(ctx)
},
})
// $ssl_client_notafter - 证书过期时间
RegisterBuiltin(&BuiltinVariable{
Name: VarSSLClientNotAfter,
Description: "客户端证书过期时间 (ISO8601)",
Getter: func(ctx *fasthttp.RequestCtx) string {
return GetSSLClientNotAfter(ctx)
},
})
// $ssl_client_s_dn - 客户端证书主题 DN
RegisterBuiltin(&BuiltinVariable{
Name: VarSSLClientDNS,
Description: "客户端证书主题 DN (RFC2253 格式)",
Getter: func(ctx *fasthttp.RequestCtx) string {
return GetSSLClientSubject(ctx)
},
})
// $ssl_client_email - 客户端证书邮箱
RegisterBuiltin(&BuiltinVariable{
Name: VarSSLClientEmail,
Description: "客户端证书中的邮箱地址",
Getter: func(ctx *fasthttp.RequestCtx) string {
return GetSSLClientEmail(ctx)
},
})
}
// GetSSLClientVerify 获取客户端证书验证结果。
//
// 返回值:
// - "SUCCESS": 验证成功
// - "FAIL": 验证失败
// - "NONE": 未提供证书
func GetSSLClientVerify(ctx *fasthttp.RequestCtx) string {
if ctx == nil {
return sslProtocolNone
}
// 检查是否有 TLS 连接信息
if !ctx.IsTLS() {
return sslProtocolNone
}
// 从 UserValue 获取验证状态(由连接处理器设置)
if v := ctx.UserValue(VarSSLClientVerify); v != nil {
if s, ok := v.(string); ok {
return s
}
}
// 检查是否提供了证书
if ctx.UserValue("tls_peer_cert_present") != nil {
return "SUCCESS"
}
return sslProtocolNone
}
// GetSSLClientSerial 获取客户端证书序列号。
//
// 从请求上下文中读取 mTLS 客户端证书的序列号。
// 证书信息由连接处理器通过 SetSSLClientInfoInContext 预先设置。
//
// 参数:
// - ctx: fasthttp 请求上下文
//
// 返回值:
// - string: 证书序列号字符串,未提供证书时返回空字符串
func GetSSLClientSerial(ctx *fasthttp.RequestCtx) string {
if v := ctx.UserValue(VarSSLClientSerial); v != nil {
if s, ok := v.(string); ok {
return s
}
}
return ""
}
// GetSSLClientSubject 获取客户端证书主题。
//
// 从请求上下文中读取 mTLS 客户端证书的主题Distinguished Name
//
// 参数:
// - ctx: fasthttp 请求上下文
//
// 返回值:
// - string: 证书主题字符串,未提供证书时返回空字符串
func GetSSLClientSubject(ctx *fasthttp.RequestCtx) string {
if v := ctx.UserValue(VarSSLClientSubject); v != nil {
if s, ok := v.(string); ok {
return s
}
}
return ""
}
// GetSSLClientIssuer 获取客户端证书颁发者。
//
// 从请求上下文中读取 mTLS 客户端证书的颁发者Distinguished Name
//
// 参数:
// - ctx: fasthttp 请求上下文
//
// 返回值:
// - string: 证书颁发者字符串,未提供证书时返回空字符串
func GetSSLClientIssuer(ctx *fasthttp.RequestCtx) string {
if v := ctx.UserValue(VarSSLClientIssuer); v != nil {
if s, ok := v.(string); ok {
return s
}
}
return ""
}
// GetSSLClientFingerprint 获取客户端证书指纹。
//
// 从请求上下文中读取 mTLS 客户端证书的 SHA1 指纹。
//
// 参数:
// - ctx: fasthttp 请求上下文
//
// 返回值:
// - string: 证书 SHA1 指纹(十六进制大写),未提供证书时返回空字符串
func GetSSLClientFingerprint(ctx *fasthttp.RequestCtx) string {
if v := ctx.UserValue(VarSSLClientFingerprint); v != nil {
if s, ok := v.(string); ok {
return s
}
}
return ""
}
// GetSSLClientNotBefore 获取客户端证书生效时间。
//
// 从请求上下文中读取 mTLS 客户端证书的生效时间ISO8601 格式)。
//
// 参数:
// - ctx: fasthttp 请求上下文
//
// 返回值:
// - string: 证书生效时间,格式为 "2006-01-02T15:04:05Z",未提供证书时返回空字符串
func GetSSLClientNotBefore(ctx *fasthttp.RequestCtx) string {
if v := ctx.UserValue(VarSSLClientNotBefore); v != nil {
if s, ok := v.(string); ok {
return s
}
}
return ""
}
// GetSSLClientNotAfter 获取客户端证书过期时间。
//
// 从请求上下文中读取 mTLS 客户端证书的过期时间ISO8601 格式)。
//
// 参数:
// - ctx: fasthttp 请求上下文
//
// 返回值:
// - string: 证书过期时间,格式为 "2006-01-02T15:04:05Z",未提供证书时返回空字符串
func GetSSLClientNotAfter(ctx *fasthttp.RequestCtx) string {
if v := ctx.UserValue(VarSSLClientNotAfter); v != nil {
if s, ok := v.(string); ok {
return s
}
}
return ""
}
// GetSSLClientEmail 获取客户端证书邮箱。
//
// 从请求上下文中读取 mTLS 客户端证书中包含的邮箱地址。
//
// 参数:
// - ctx: fasthttp 请求上下文
//
// 返回值:
// - string: 证书中的第一个邮箱地址,未提供证书或无邮箱时返回空字符串
func GetSSLClientEmail(ctx *fasthttp.RequestCtx) string {
if v := ctx.UserValue(VarSSLClientEmail); v != nil {
if s, ok := v.(string); ok {
return s
}
}
return ""
}