Linux Golang 日志安全审计落地方案
一 核心原则与采集范围
二 Go 代码落地示例
package main
import (
"context"
"fmt"
"io"
"net/http"
"os"
"strings"
"time"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)
// AuditEvent 审计事件模型(可按需扩展)
type AuditEvent struct {
Timestamp time.Time `json:"ts"`
UserID string `json:"uid,omitempty"`
Username string `json:"user,omitempty"`
IP string `json:"ip"`
Method string `json:"method"`
Path string `json:"path"`
Status int `json:"status"`
UA string `json:"ua,omitempty"`
Err string `json:"err,omitempty"`
Latency time.Duration `json:"latency_ms"`
Extra map[string]interface{} `json:"extra,omitempty"`
}
var auditLogger *zap.Logger
func initLogger(logPath string) error {
// 生产环境建议使用 JSON 编码
encCfg := zap.NewProductionEncoderConfig()
encCfg.TimeKey = "ts"
encCfg.EncodeTime = zapcore.ISO8601TimeEncoder
cfg := zap.NewProductionConfig()
cfg.OutputPaths = []string{logPath}
cfg.EncoderConfig = encCfg
l, err := cfg.Build()
if err != nil {
return err
}
auditLogger = l.Named("audit")
return nil
}
// Mask 对敏感字段做掩码
func Mask(s string) string {
if len(s) <= 6 {
return strings.Repeat("*", len(s))
}
return s[:3] + strings.Repeat("*", len(s)-6) + s[len(s)-3:]
}
// WriteAudit 写入审计事件
func WriteAudit(ctx context.Context, ev AuditEvent) {
fields := []zap.Field{
zap.Time("ts", ev.Timestamp),
zap.String("uid", ev.UserID),
zap.String("user", ev.Username),
zap.String("ip", ev.IP),
zap.String("method", ev.Method),
zap.String("path", ev.Path),
zap.Int("status", ev.Status),
zap.String("ua", ev.UA),
zap.Duration("latency_ms", ev.Latency),
}
if ev.Err != "" {
fields = append(fields, zap.String("err", ev.Err))
}
if len(ev.Extra) > 0 {
fields = append(fields, zap.Any("extra", ev.Extra))
}
auditLogger.Info("audit", fields...)
}
// AuditMiddleware HTTP 审计中间件
func AuditMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
ww := &responseWriter{ResponseWriter: w, status: http.StatusOK}
defer func() {
ev := AuditEvent{
Timestamp: start,
IP: r.RemoteAddr,
Method: r.Method,
Path: r.URL.Path,
Status: ww.status,
UA: r.UserAgent(),
Latency: time.Since(start),
}
// 示例:从请求头或上下文获取用户(实际项目替换为你的鉴权逻辑)
if uid := r.Header.Get("X-User-Id"); uid != "" {
ev.UserID = uid
}
if user := r.Header.Get("X-User-Name"); user != "" {
ev.Username = Mask(user) // 脱敏
}
WriteAudit(r.Context(), ev)
}()
next.ServeHTTP(ww, r)
})
}
type responseWriter struct {
http.ResponseWriter
status int
}
func (rw *responseWriter) WriteHeader(code int) {
rw.status = code
rw.ResponseWriter.WriteHeader(code)
}
func main() {
if err := initLogger("/var/log/myapp/audit.log"); err != nil {
panic(err)
}
defer auditLogger.Sync() // 尽量确保落盘
mux := http.NewServeMux()
mux.HandleFunc("/login", func(w http.ResponseWriter, r *http.Request) {
// 示例登录逻辑
user := r.FormValue("user")
pass := r.FormValue("pass")
// 校验省略
w.WriteHeader(http.StatusOK)
fmt.Fprintf(w, "ok")
})
handler := AuditMiddleware(mux)
http.ListenAndServe(":8080", handler)
}
三 Linux 侧安全与合规配置
/var/log/myapp/audit.log {
daily
missingok
rotate 30
compress
delaycompress
notifempty
create 640 myapp myapp
size 100M
postrotate
systemctl reload myapp >/dev/null 2>&1 || true
endscript
}
四 集中化、监控与合规