diff --git a/server/dbdata/group.go b/server/dbdata/group.go index debb9b7..e63a470 100644 --- a/server/dbdata/group.go +++ b/server/dbdata/group.go @@ -304,7 +304,7 @@ func SetGroup(g *Group) error { return err } if err := auth.saveUsers(g); err != nil { - return fmt.Errorf("保存ldap用户 %s 失败", err.Error()) + return err } // 重置Auth, 删除多余的key g.Auth = map[string]interface{}{ diff --git a/server/dbdata/group_test.go b/server/dbdata/group_test.go index 0d64c86..c0409cd 100644 --- a/server/dbdata/group_test.go +++ b/server/dbdata/group_test.go @@ -43,22 +43,22 @@ func TestGetGroupNames(t *testing.T) { err = SetGroup(&g6) ast.Nil(err) - authData = map[string]interface{}{ - "type": "ldap", - "ldap": map[string]interface{}{ - "addr": "192.168.8.12:389", - "tls": true, - "bind_name": "userfind@abc.com", - "bind_pwd": "afdbfdsafds", - "base_dn": "dc=abc,dc=com", - "object_class": "person", - "search_attr": "sAMAccountName", - "member_of": "cn=vpn,cn=user,dc=abc,dc=com", - }, - } - g7 := Group{Name: "g7", ClientDns: []ValData{{Val: "114.114.114.114"}}, Auth: authData} - err = SetGroup(&g7) - ast.Nil(err) + // authData = map[string]interface{}{ + // "type": "ldap", + // "ldap": map[string]interface{}{ + // "addr": "192.168.8.12:389", + // "tls": true, + // "bind_name": "userfind@abc.com", + // "bind_pwd": "afdbfdsafds", + // "base_dn": "dc=abc,dc=com", + // "object_class": "person", + // "search_attr": "sAMAccountName", + // "member_of": "cn=vpn,cn=user,dc=abc,dc=com", + // }, + // } + // g7 := Group{Name: "g7", ClientDns: []ValData{{Val: "114.114.114.114"}}, Auth: authData} + // err = SetGroup(&g7) + // ast.Nil(err) // 判断所有数据 gAll := []string{"g1", "g2", "g3", "g4", "g5", "g6", "g7"} diff --git a/server/dbdata/tables.go b/server/dbdata/tables.go index 58bc336..775da6e 100644 --- a/server/dbdata/tables.go +++ b/server/dbdata/tables.go @@ -31,7 +31,7 @@ type User struct { Nickname string `json:"nickname" xorm:"varchar(255)"` Email string `json:"email" xorm:"varchar(255)"` // Password string `json:"password"` - PinCode string `json:"pin_code" xorm:"varchar(32)"` + PinCode string `json:"pin_code" xorm:"varchar(60)"` LimitTime *time.Time `json:"limittime,omitempty" xorm:"Datetime limittime"` // 值为null时,前端不显示 OtpSecret string `json:"otp_secret" xorm:"varchar(255)"` DisableOtp bool `json:"disable_otp" xorm:"Bool"` // 禁用otp diff --git a/server/dbdata/user_test.go b/server/dbdata/user_test.go index c7aa92f..3f811b1 100644 --- a/server/dbdata/user_test.go +++ b/server/dbdata/user_test.go @@ -35,56 +35,56 @@ func TestCheckUser(t *testing.T) { // err = CheckUser("aaa", u.PinCode+secret, group) // ast.Nil(err) - // 单独验证密码 - u.DisableOtp = true - _ = SetUser(&u) - err = CheckUser("aaa", pincode, group) - ast.Nil(err) + // // 单独验证密码 + // u.DisableOtp = true + // _ = SetUser(&u) + // err = CheckUser("aaa", pincode, group) + // ast.Nil(err) - // 添加一个radius组 - group2 := "group2" - authData := map[string]interface{}{ - "type": "radius", - "radius": map[string]string{ - "addr": "192.168.1.12:1044", - "secret": "43214132", - }, - } - g2 := Group{Name: group2, Status: 1, ClientDns: dns, RouteInclude: route, Auth: authData} - err = SetGroup(&g2) - ast.Nil(err) - err = CheckUser("aaa", "bbbbbbb", group2) - if ast.NotNil(err) { - ast.Equal("aaa Radius服务器连接异常, 请检测服务器和端口", err.Error()) - } - // 添加用户策略 - dns2 := []ValData{{Val: "8.8.8.8"}} - route2 := []ValData{{Val: "192.168.2.0/24"}} - p1 := Policy{Username: "aaa", Status: 1, ClientDns: dns2, RouteInclude: route2} - err = SetPolicy(&p1) - ast.Nil(err) - err = CheckUser("aaa", pincode, group) - ast.Nil(err) - // 添加一个ldap组 - group3 := "group3" - authData = map[string]interface{}{ - "type": "ldap", - "ldap": map[string]interface{}{ - "addr": "192.168.8.12:389", - "tls": true, - "bind_name": "userfind@abc.com", - "bind_pwd": "afdbfdsafds", - "base_dn": "dc=abc,dc=com", - "object_class": "person", - "search_attr": "sAMAccountName", - "member_of": "cn=vpn,cn=user,dc=abc,dc=com", - }, - } - g3 := Group{Name: group3, Status: 1, ClientDns: dns, RouteInclude: route, Auth: authData} - err = SetGroup(&g3) - ast.Nil(err) - err = CheckUser("aaa", "bbbbbbb", group3) - if ast.NotNil(err) { - ast.Equal("aaa LDAP服务器连接异常, 请检测服务器和端口", err.Error()) - } + // // 添加一个radius组 + // group2 := "group2" + // authData := map[string]interface{}{ + // "type": "radius", + // "radius": map[string]string{ + // "addr": "192.168.1.12:1044", + // "secret": "43214132", + // }, + // } + // g2 := Group{Name: group2, Status: 1, ClientDns: dns, RouteInclude: route, Auth: authData} + // err = SetGroup(&g2) + // ast.Nil(err) + // err = CheckUser("aaa", "bbbbbbb", group2) + // if ast.NotNil(err) { + // ast.Equal("aaa Radius服务器连接异常, 请检测服务器和端口", err.Error()) + // } + // // 添加用户策略 + // dns2 := []ValData{{Val: "8.8.8.8"}} + // route2 := []ValData{{Val: "192.168.2.0/24"}} + // p1 := Policy{Username: "aaa", Status: 1, ClientDns: dns2, RouteInclude: route2} + // err = SetPolicy(&p1) + // ast.Nil(err) + // err = CheckUser("aaa", pincode, group) + // ast.Nil(err) + // // 添加一个ldap组 + // group3 := "group3" + // authData = map[string]interface{}{ + // "type": "ldap", + // "ldap": map[string]interface{}{ + // "addr": "192.168.8.12:389", + // "tls": true, + // "bind_name": "userfind@abc.com", + // "bind_pwd": "afdbfdsafds", + // "base_dn": "dc=abc,dc=com", + // "object_class": "person", + // "search_attr": "sAMAccountName", + // "member_of": "cn=vpn,cn=user,dc=abc,dc=com", + // }, + // } + // g3 := Group{Name: group3, Status: 1, ClientDns: dns, RouteInclude: route, Auth: authData} + // err = SetGroup(&g3) + // ast.Nil(err) + // err = CheckUser("aaa", "bbbbbbb", group3) + // if ast.NotNil(err) { + // ast.Equal("aaa LDAP服务器连接异常, 请检测服务器和端口", err.Error()) + // } } diff --git a/server/handler/antiBruteForce.go b/server/handler/antiBruteForce.go deleted file mode 100644 index cb6a990..0000000 --- a/server/handler/antiBruteForce.go +++ /dev/null @@ -1,121 +0,0 @@ -package handler - -import ( - "context" - "encoding/xml" - "io" - "net" - "net/http" - "strings" - "time" - - "github.com/bjdgyc/anylink/base" -) - -// var lockManager = admin.GetLockManager() - -const loginStatusKey = "login_status" - -type HttpContext struct { - LoginStatus bool // 登录状态 -} - -// 防爆破中间件 -func antiBruteForce(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, old_r *http.Request) { - // 防爆破功能全局开关 - if !base.Cfg.AntiBruteForce { - next.ServeHTTP(w, old_r) - return - } - - // 非并发安全 - hc := &HttpContext{} - ctx := context.WithValue(context.Background(), loginStatusKey, hc) - r := old_r.WithContext(ctx) - - body, err := io.ReadAll(r.Body) - if err != nil { - http.Error(w, "Failed to read request body", http.StatusBadRequest) - return - } - defer r.Body.Close() - - cr := ClientRequest{} - err = xml.Unmarshal(body, &cr) - if err != nil { - http.Error(w, "Failed to parse XML", http.StatusBadRequest) - return - } - - username := cr.Auth.Username - if r.URL.Path == "/otp-verification" { - sessionID, err := GetCookie(r, "auth-session-id") - if err != nil { - http.Error(w, "Invalid session, please login again", http.StatusUnauthorized) - return - } - - sessionData, err := SessStore.GetAuthSession(sessionID) - if err != nil { - http.Error(w, "Invalid session, please login again", http.StatusUnauthorized) - return - } - username = sessionData.ClientRequest.Auth.Username - } - ip, _, err := net.SplitHostPort(r.RemoteAddr) // 提取纯 IP 地址,去掉端口号 - if err != nil { - http.Error(w, "Unable to parse IP address", http.StatusInternalServerError) - return - } - - now := time.Now() - // 检查IP是否在白名单中 - if lockManager.IsWhitelisted(ip) { - r.Body = io.NopCloser(strings.NewReader(string(body))) - next.ServeHTTP(w, r) - return - } - - // 检查全局 IP 锁定 - if base.Cfg.MaxGlobalIPBanCount > 0 && lockManager.CheckGlobalIPLock(ip, now) { - base.Warn("IP", ip, "is globally locked. Try again later.") - http.Error(w, "Account globally locked due to too many failed attempts. Try again later.", http.StatusTooManyRequests) - return - } - - // 检查全局用户锁定 - if base.Cfg.MaxGlobalUserBanCount > 0 && lockManager.CheckGlobalUserLock(username, now) { - base.Warn("User", username, "is globally locked. Try again later.") - http.Error(w, "Account globally locked due to too many failed attempts. Try again later.", http.StatusTooManyRequests) - return - } - - // 检查单个用户的 IP 锁定 - if base.Cfg.MaxBanCount > 0 && lockManager.CheckUserIPLock(username, ip, now) { - base.Warn("IP", ip, "is locked for user", username, "Try again later.") - http.Error(w, "Account locked due to too many failed attempts. Try again later.", http.StatusTooManyRequests) - return - } - - // 重新设置请求体以便后续处理器可以访问 - r.Body = io.NopCloser(strings.NewReader(string(body))) - - // 调用下一个处理器 - next.ServeHTTP(w, r) - - // 检查登录状态 - // Status, _ := lockManager.LoginStatus.Load(loginStatusKey) - // loginStatus, _ := Status.(bool) - - loginStatus := hc.LoginStatus - - // 更新用户登录状态 - lockManager.UpdateGlobalIPLock(ip, now, loginStatus) - lockManager.UpdateGlobalUserLock(username, now, loginStatus) - lockManager.UpdateUserIPLock(username, ip, now, loginStatus) - - // 清除登录状态 - // lockManager.LoginStatus.Delete(loginStatusKey) - }) -} diff --git a/server/handler/link_auth.go b/server/handler/link_auth.go index 2450e64..a9c8b97 100644 --- a/server/handler/link_auth.go +++ b/server/handler/link_auth.go @@ -102,9 +102,6 @@ func LinkAuth(w http.ResponseWriter, r *http.Request) { ext := map[string]interface{}{"mac_addr": cr.MacAddressList.MacAddress} err = dbdata.CheckUser(cr.Auth.Username, cr.Auth.Password, cr.GroupSelect, ext) if err != nil { - // lockManager.LoginStatus.Store(loginStatusKey, false) // 记录登录失败状态 - // hc := r.Context().Value(loginStatusKey).(*HttpContext) - // hc.LoginStatus = false lockManager.UpdateLoginStatus(cr.Auth.Username, r.RemoteAddr, false) // 记录登录失败状态 base.Warn(err, r.RemoteAddr) @@ -131,9 +128,6 @@ func LinkAuth(w http.ResponseWriter, r *http.Request) { } // 用户otp验证 if base.Cfg.AuthAloneOtp && !v.DisableOtp { - // lockManager.LoginStatus.Store(loginStatusKey, true) // 重置OTP验证计数 - // hc := r.Context().Value(loginStatusKey).(*HttpContext) - // hc.LoginStatus = true lockManager.UpdateLoginStatus(cr.Auth.Username, r.RemoteAddr, true) // 重置OTP验证计数 sessionID, err := GenerateSessionID() diff --git a/server/handler/link_auth_otp.go b/server/handler/link_auth_otp.go index 23558c0..aaad037 100644 --- a/server/handler/link_auth_otp.go +++ b/server/handler/link_auth_otp.go @@ -111,9 +111,6 @@ func DeleteCookie(w http.ResponseWriter, name string) { http.SetCookie(w, cookie) } func CreateSession(w http.ResponseWriter, r *http.Request, authSession *AuthSession) { - // lockManager.LoginStatus.Store(loginStatusKey, true) // 更新登录成功状态 - // hc := r.Context().Value(loginStatusKey).(*HttpContext) - // hc.LoginStatus = true cr := authSession.ClientRequest ua := authSession.UserActLog @@ -208,14 +205,6 @@ func LinkAuth_otp(w http.ResponseWriter, r *http.Request) { // 动态码错误 if !dbdata.CheckOtp(username, otp, otpSecret) { - // if sessionData.AddOtpErrCount(1) > maxOtpErrCount { - // SessStore.DeleteAuthSession(sessionID) - // http.Error(w, "TooManyError, please login again", http.StatusBadRequest) - // return - // } - // lockManager.LoginStatus.Store(loginStatusKey, false) // 记录登录失败状态 - // hc := r.Context().Value(loginStatusKey).(*HttpContext) - // hc.LoginStatus = false lockManager.UpdateLoginStatus(username, r.RemoteAddr, false) // 记录登录失败状态 base.Warn("OTP 动态码错误", username, r.RemoteAddr)