package auth import ( "fmt" "net" "proxy-server/gateway/app" "proxy-server/gateway/core" "proxy-server/gateway/env" "slices" "strconv" "time" "errors" ) type Protocol string const ( Socks5 = Protocol("socks5") Http = Protocol("http") ) func Protect(conn net.Conn, proto Protocol, username, password *string) (*core.AuthContext, error) { // 获取用户地址 remoteAddr := conn.RemoteAddr().String() remoteHost, _, err := net.SplitHostPort(remoteAddr) if err != nil { return nil, fmt.Errorf("无法获取连接信息: %w", err) } // 获取服务端口 localAddr := conn.LocalAddr().String() _, _localPort, err := net.SplitHostPort(localAddr) localPort, err := strconv.ParseUint(_localPort, 10, 16) if err != nil { return nil, fmt.Errorf("noAuth 认证失败: %w", err) } var id, _ = app.Assigns.Load(uint16(localPort)) // 检查全局白名单 var remoteIp = net.ParseIP(remoteHost) if remoteIp == nil { return nil, fmt.Errorf("无法解析 IP 地址: %s", remoteHost) } if slices.ContainsFunc(env.AuthWhitelist, func(ip net.IP) bool { return ip.Equal(remoteIp) }) { return &core.AuthContext{ Payload: core.Payload{ ID: id, }, }, nil } // 查找权限配置 var permit = app.LoadPermit(uint16(localPort)) if permit == nil { return nil, errors.New("没有权限") } // 检查是否过期 if permit.Expire.Before(time.Now()) { return nil, errors.New("权限已过期") } // 检查 IP 是否可用 if permit.Whitelists != nil && len(*permit.Whitelists) > 0 { var found = false for _, allowedHost := range *permit.Whitelists { var allowed = net.ParseIP(allowedHost) var remote = net.ParseIP(remoteHost) if remote.Equal(allowed) { found = true break } } if !found { return nil, errors.New("不在白名单内") } } if permit.Username != nil || permit.Password != nil { if *username != *permit.Username || *password != *permit.Password { return nil, errors.New("用户名或密码错误") } } return &core.AuthContext{ Payload: core.Payload{ ID: id, }, }, nil }