lolly/internal/config/security_config.go
xfy911 65aaba4e59 docs(config): add package comments for config module
- Add package documentation for cache, monitoring, performance, proxy,
  security, server, ssl, and variable config files
- Include author attribution (xfy)
2026-06-03 15:28:53 +08:00

352 lines
11 KiB
Go
Raw 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 config 提供 YAML 配置文件的解析、验证和默认配置生成功能。
//
// 包含安全配置相关的结构体,用于配置访问控制、限流、认证和安全头部。
//
// 作者xfy
package config
import "time"
// SecurityConfig 安全配置,包含访问控制、限流、认证和安全头部。
//
// 用于保护服务器免受各种网络攻击和滥用。
//
// 注意事项:
// - Access 配置 IP 黑白名单控制访问来源
// - RateLimit 配置请求频率限制防止 DDoS 攻击
// - Auth 配置 HTTP Basic 认证保护敏感资源
// - Headers 配置安全响应头部增强浏览器安全
// - 各项配置可以组合使用,增强安全性
//
// 使用示例:
//
// security:
// access:
// allow: ["192.168.1.0/24"]
// deny: ["10.0.0.0/8"]
// rate_limit:
// request_rate: 100
// burst: 150
// auth:
// type: "basic"
// users:
// - name: "admin"
// password: "$2y$10$..."
// headers:
// x_frame_options: "DENY"
type SecurityConfig struct {
Headers SecurityHeaders `yaml:"headers"`
Access AccessConfig `yaml:"access"`
ErrorPage ErrorPageConfig `yaml:"error_page"`
Auth AuthConfig `yaml:"auth"`
AuthRequest AuthRequestConfig `yaml:"auth_request"`
RateLimit RateLimitConfig `yaml:"rate_limit"`
}
// AccessConfig IP 访问控制配置。
//
// 通过 IP 地址或 CIDR 范围控制访问权限,支持基于 GeoIP 的国家代码访问控制。
//
// 注意事项:
// - Allow 和 Deny 列表按配置顺序匹配
// - Default 指定未匹配时的默认动作
// - TrustedProxies 用于正确获取客户端真实 IP
// - GeoIP 配置启用后,会基于国家代码进行二次检查
// - 支持 IPv4 和 IPv6 地址格式
//
// 使用示例:
//
// access:
// allow: ["192.168.1.0/24", "10.0.0.0/8"]
// deny: ["192.168.1.100"]
// default: "deny"
// trusted_proxies: ["172.16.0.0/16"]
// geoip:
// enabled: true
// database: "/var/lib/geoip/GeoIP2-Country.mmdb"
// allow_countries: ["US", "JP", "GB"]
// deny_countries: ["CN", "RU"]
// default: "deny"
// cache_size: 10000
// cache_ttl: 1h
// private_ip_behavior: "allow"
type AccessConfig struct {
// Allow 允许的 IP/CIDR 列表
// 配置允许访问的 IP 地址或网段
Allow []string `yaml:"allow"`
// Deny 拒绝的 IP/CIDR 列表
// 配置拒绝访问的 IP 地址或网段
Deny []string `yaml:"deny"`
// TrustedProxies 可信代理 CIDR 列表
// 用于正确解析 X-Forwarded-For 头部获取真实客户端 IP
TrustedProxies []string `yaml:"trusted_proxies"`
// Default 默认动作
// 未匹配任何规则时的处理方式allow 或 deny
Default string `yaml:"default"`
// GeoIP GeoIP 国家代码访问控制配置
GeoIP GeoIPConfig `yaml:"geoip"`
}
// GeoIPConfig GeoIP 访问控制配置。
//
// 通过 MaxMind GeoIP2 数据库查询 IP 所属国家,实现基于国家代码的访问控制。
//
// 注意事项:
// - Database 为 GeoIP2 数据库文件路径(.mmdb 格式)
// - AllowCountries 和 DenyCountries 使用 ISO 3166-1 alpha-2 国家代码
// - CacheSize 设置 LRU 缓存最大条目数0 表示使用默认值 10000
// - CacheTTL 设置缓存有效期0 表示使用默认值 1 小时
// - PrivateIPBehavior 控制私有 IP 的处理策略
//
// 使用示例:
//
// geoip:
// enabled: true
// database: "/var/lib/geoip/GeoIP2-Country.mmdb"
// allow_countries: ["US", "JP", "GB"]
// deny_countries: ["CN", "RU"]
// default: "deny"
// cache_size: 10000
// cache_ttl: 1h
// private_ip_behavior: "allow"
type GeoIPConfig struct {
Database string `yaml:"database"`
Default string `yaml:"default"`
PrivateIPBehavior string `yaml:"private_ip_behavior"`
AllowCountries []string `yaml:"allow_countries"`
DenyCountries []string `yaml:"deny_countries"`
CacheSize int `yaml:"cache_size"`
CacheTTL time.Duration `yaml:"cache_ttl"`
Enabled bool `yaml:"enabled"`
}
// RateLimitConfig 速率限制配置。
//
// 限制请求频率防止 DDoS 攻击和资源滥用。
//
// 注意事项:
// - RequestRate 为每秒允许的最大请求数
// - Burst 为突发流量允许的最大请求数
// - ConnLimit 为单个 IP 的最大并发连接数
// - Algorithm 支持 token_bucket 和 sliding_window 两种算法
// - SlidingWindow 仅在 sliding_window 算法下生效
//
// 使用示例:
//
// rate_limit:
// request_rate: 100
// burst: 150
// conn_limit: 50
// algorithm: "token_bucket"
// key: "ip"
type RateLimitConfig struct {
Key string `yaml:"key"`
Algorithm string `yaml:"algorithm"`
SlidingWindowMode string `yaml:"sliding_window_mode"`
RequestRate int `yaml:"request_rate"`
Burst int `yaml:"burst"`
ConnLimit int `yaml:"conn_limit"`
SlidingWindow int `yaml:"sliding_window"`
}
// LimitRateConfig 响应速率限制配置。
//
// 控制响应数据的发送速率,防止单个连接占用过多带宽。
//
// 注意事项:
// - Rate 为每秒发送的字节数0 表示不限速
// - Burst 为突发流量允许的字节数
// - LargeFileThreshold 为大文件阈值,超过此大小的文件采用特殊策略
// - LargeFileStrategy 为大文件策略skip跳过限速或 coarse粗粒度限速
//
// 使用示例:
//
// limit_rate:
// rate: 1048576 # 1MB/s
// burst: 524288 # 512KB 突发
// large_file_threshold: 10485760 # 10MB
// large_file_strategy: "skip"
type LimitRateConfig struct {
// Rate 字节/秒0 表示不限速
Rate int64 `yaml:"rate"`
// Burst 突发流量字节数
Burst int64 `yaml:"burst"`
// LargeFileThreshold 大文件阈值(字节),默认 10MB
LargeFileThreshold int64 `yaml:"large_file_threshold"`
// LargeFileStrategy 大文件策略skip跳过限速或 coarse粗粒度限速
LargeFileStrategy string `yaml:"large_file_strategy"`
}
// AuthConfig 认证配置。
//
// 配置 HTTP Basic 认证保护敏感资源。
//
// 注意事项:
// - Type 目前仅支持 basic
// - RequireTLS 默认为 true强制 HTTPS 传输
// - Algorithm 支持 bcrypt 和 argon2id
// - Users 中 Password 字段存储的是密码哈希而非明文
// - MinPasswordLength 控制密码最小长度要求
//
// 使用示例:
//
// auth:
// type: "basic"
// require_tls: true
// algorithm: "bcrypt"
// realm: "Secure Area"
// min_password_length: 8
// users:
// - name: "admin"
// password: "$2y$10$..."
type AuthConfig struct {
Type string `yaml:"type"`
Algorithm string `yaml:"algorithm"`
Realm string `yaml:"realm"`
Users []User `yaml:"users"`
MinPasswordLength int `yaml:"min_password_length"`
RequireTLS bool `yaml:"require_tls"`
}
// User 认证用户配置。
//
// 定义单个认证用户的凭据。
//
// 注意事项:
// - Name 为用户标识,区分大小写
// - Password 存储的是哈希值而非明文密码
// - 支持的哈希格式取决于 Algorithm 设置
//
// 使用示例:
//
// users:
// - name: "admin"
// password: "$2y$10$N9qo8uLOickgx2ZMRZoMy..."
type User struct {
// Name 用户名
// 认证时使用的用户标识
Name string `yaml:"name"`
// Password 密码哈希
// bcrypt 或 argon2id 哈希值,非明文密码
Password string `yaml:"password"`
}
// SecurityHeaders 安全头部配置。
//
// 配置 HTTP 安全响应头部增强浏览器安全。
//
// 注意事项:
// - XFrameOptions 防止点击劫持攻击
// - XContentTypeOptions 防止 MIME 类型嗅探
// - ContentSecurityPolicy 控制资源加载策略
// - ReferrerPolicy 控制 Referer 头发送策略
// - PermissionsPolicy 控制浏览器功能权限
//
// 使用示例:
//
// headers:
// x_frame_options: "DENY"
// x_content_type_options: "nosniff"
// content_security_policy: "default-src 'self'"
// referrer_policy: "strict-origin-when-cross-origin"
type SecurityHeaders struct {
// XFrameOptions X-Frame-Options 头部
// 可选值DENY、SAMEORIGIN防止页面被嵌入 iframe
XFrameOptions string `yaml:"x_frame_options"`
// XContentTypeOptions X-Content-Type-Options 头部
// 建议值nosniff防止浏览器 MIME 类型嗅探
XContentTypeOptions string `yaml:"x_content_type_options"`
// ContentSecurityPolicy Content-Security-Policy 头部
// 控制页面可以加载的资源来源
ContentSecurityPolicy string `yaml:"content_security_policy"`
// ReferrerPolicy Referrer-Policy 头部
// 控制 Referer 头的发送策略
ReferrerPolicy string `yaml:"referrer_policy"`
// PermissionsPolicy Permissions-Policy 头部
// 控制浏览器功能权限(原 Feature-Policy
PermissionsPolicy string `yaml:"permissions_policy"`
}
// ErrorPageConfig 自定义错误页面配置。
//
// 允许为特定 HTTP 状态码配置自定义错误页面。
// 错误页面文件在启动时预加载到内存中,运行时不进行文件 I/O。
//
// 注意事项:
// - 错误页面文件路径可以是相对路径或绝对路径
// - 所有错误页面加载失败时会阻止服务器启动
// - 部分错误页面加载失败会记录警告但允许启动
// - 支持可选的响应状态码覆盖
//
// 使用示例:
//
// error_page:
// pages:
// 404: "/var/www/errors/404.html"
// 500: "/var/www/errors/500.html"
// 503: "/var/www/errors/503.html"
// default: "/var/www/errors/error.html"
// response_code: 200 # 可选:覆盖响应状态码
type ErrorPageConfig struct {
// Pages 状态码到错误页面文件的映射
// key 为 HTTP 状态码(如 404, 500value 为文件路径
Pages map[int]string `yaml:"pages"`
// Default 默认错误页面
// 当特定状态码没有配置时使用
Default string `yaml:"default"`
// ResponseCode 响应状态码覆盖
// 如果不为 0所有错误页面响应将使用此状态码
// 例如设置为 200 时,即使发生错误也返回 200 OK
ResponseCode int `yaml:"response_code"`
}
// AuthRequestConfig 外部认证子请求配置。
//
// 将认证委托给外部服务,根据子请求的响应状态码决定是否允许原请求继续。
// 适用于需要复杂认证逻辑或与现有认证系统集成的场景。
//
// 行为规则:
// - 2xx 响应:认证通过,原请求继续处理
// - 401/403 响应:认证失败,返回相应状态码
// - 其他响应或超时:返回 500 内部服务器错误
// - 认证服务不可用时:返回 500 内部服务器错误
//
// 注意事项:
// - 认证请求使用独立的连接池,避免影响主服务
// - 支持变量展开(如 $host, $uri, $request_uri
// - 建议配置合理的超时时间,避免长时间阻塞
// - 认证请求会携带原请求的头信息(如 Cookie, Authorization
//
// 使用示例:
//
// security:
// auth_request:
// uri: /auth
// method: GET
// auth_timeout: 5s
// headers:
// X-Original-Uri: $request_uri
// X-Original-Host: $host
type AuthRequestConfig struct {
Headers map[string]string `yaml:"headers"`
URI string `yaml:"uri"`
Method string `yaml:"method"`
ForwardHeaders []string `yaml:"forward_headers"`
Timeout time.Duration `yaml:"auth_timeout"`
Enabled bool `yaml:"enabled"`
}