From d248b59b932bb15d94395ade5364861a31f446ac Mon Sep 17 00:00:00 2001 From: Rene Date: Tue, 23 May 2023 18:33:26 -0600 Subject: [PATCH] Added users file for authenticating --- README.md | 17 ++++++++++++++++- cmd/run.go | 11 ++++++----- models/authentication.go | 16 +++------------- models/requestcontext.go | 3 +-- models/server.go | 21 +++++++++++---------- 5 files changed, 37 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index 5c9445b..46de64e 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ Download binary: ```shell -wget https://github.com/reneManqueros/moxxiproxy/releases/download/v1.3.5/moxxiproxy_1.3.5_Linux_x86_64.tar.gz && tar xf moxxiproxy_1.3.5_Linux_x86_64.tar.gz +wget https://github.com/reneManqueros/moxxiproxy/releases/download/v1.3.6/moxxiproxy_1.3.6_Linux_x86_64.tar.gz && tar xf moxxiproxy_1.3.6_Linux_x86_64.tar.gz ``` Or download source and compile: @@ -40,6 +40,7 @@ git clone https://github.com/reneManqueros/moxxiproxy.git && cd moxxiproxy && ma | address | Set the listen address | 0.0.0.0:1989 | | exitnodes | Path to config file | ./exitNodes.yml | | auth | user/password for authentication | | +| usersfile | Path to list of authenticated users, requires auth to be empty | | | whitelist | IP's to allow to use, allows all if blank | | | timeout | default timeout seconds for backen connection, 0 for infinite | 0 | | upstream | set upstream mode, uses upstream instead of interface on exitNodes file | | @@ -185,6 +186,20 @@ curl -kxhttp://testuser_session-1234:@0.0.0.0:1989 http://page.com This will create a session under ID: 1234 and any request with that ID will use the same exit node + +#### Sample users file: + +```yaml +user1: password1 +user2: password2 +``` + +Service ran as [path can be anything]: + +```shell +moxxiproxy run --usersfile=users.yml +``` + ## Containers The Dockerfile.example should serve as a guideline for those inclined to run moxxiproxy as a Docker container. diff --git a/cmd/run.go b/cmd/run.go index 0515234..c67c52a 100644 --- a/cmd/run.go +++ b/cmd/run.go @@ -25,6 +25,7 @@ var runCmd = &cobra.Command{ prettyLogs, _ := cmd.Flags().GetBool("prettylogs") metricsLogger, _ := cmd.Flags().GetString("metrics") promaddress, _ := cmd.Flags().GetString("promaddress") + usersfile, _ := cmd.Flags().GetString("usersfile") if prettyLogs == true { log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}) } @@ -46,11 +47,10 @@ var runCmd = &cobra.Command{ if authParts := strings.Split(auth, ":"); len(authParts) > 1 { username = authParts[0] password = authParts[1] - models.UserMap = make(map[string]models.User) - models.UserMap[username] = models.User{ - UserID: username, - AuthToken: password, - } + models.UserMap = make(map[string]string) + models.UserMap[username] = password + } else if usersfile != "" { + models.Users{}.Load(usersfile) } s := models.Proxy{ @@ -92,6 +92,7 @@ func init() { runCmd.PersistentFlags().String("auth", "", "--auth=user:pass") runCmd.PersistentFlags().String("whitelist", "", "--whitelist=1.2.3.4,5.6.7.8") runCmd.PersistentFlags().String("loglevel", "info", "--loglevel=info") + runCmd.PersistentFlags().String("usersfile", "./users.yml", "--usersfile=./users.yml") runCmd.PersistentFlags().Bool("upstream", false, "--upstream=false") runCmd.PersistentFlags().Bool("authupstream", false, "--authupstream=false") runCmd.PersistentFlags().Bool("prettylogs", false, "--prettylogs=true") diff --git a/models/authentication.go b/models/authentication.go index 7e6df27..226f0f4 100644 --- a/models/authentication.go +++ b/models/authentication.go @@ -6,29 +6,19 @@ import ( "os" ) -type User struct { - UserID string `yaml:"user_id"` - AuthToken string `yaml:"auth_token"` -} - type Users struct{} -var UserMap map[string]User +var UserMap map[string]string func (u Users) Load(filename string) { data, err := os.ReadFile(filename) if err != nil { - log.Err(err).Str("filename", filename).Msg("Users.Load") + log.Fatal().Err(err).Str("filename", filename).Msg("Users.Load") return } err = yaml.Unmarshal(data, &UserMap) if err != nil { - log.Err(err).Str("filename", filename).Msg("Users.Load.Unmarshall") + log.Fatal().Err(err).Str("filename", filename).Msg("Users.Load.Unmarshall") } } - -func (u Users) ByID(userID string) (User, bool) { - user, ok := UserMap[userID] - return user, ok -} diff --git a/models/requestcontext.go b/models/requestcontext.go index 2c51d57..c553c6e 100644 --- a/models/requestcontext.go +++ b/models/requestcontext.go @@ -36,8 +36,7 @@ func (rc *RequestContext) FromRequest(request *http.Request) { rc.RawUsername = userParts[0] authToken := userParts[1] rc.ParseUsername(rc.RawUsername) - thisUser, userExists := Users{}.ByID(rc.UserID) - if userExists == true && thisUser.UserID == rc.UserID && thisUser.AuthToken == authToken { + if password, ok := UserMap[rc.UserID]; ok == true && authToken == password { rc.Authenticated = true } } diff --git a/models/server.go b/models/server.go index ff0b934..28b8fd9 100644 --- a/models/server.go +++ b/models/server.go @@ -23,16 +23,17 @@ const HTTP200 = "HTTP/1.1 200 Connection Established\r\n\r\n" const HTTP407 = "407 Proxy Authentication Required" type Proxy struct { - PrometheusAddress string - MetricsLogger string - ExitNodesFile string - ListenAddress string - Username string - Password string - Whitelist string - Backends []string - Sessions map[string]ExitNode - ExitNodes struct { + PrometheusAddress string + MetricsLogger string + ExitNodesFile string + AuthenticatedUsersFile string + ListenAddress string + Username string + Password string + Whitelist string + Backends []string + Sessions map[string]ExitNode + ExitNodes struct { All []ExitNode ByRegion map[string][]ExitNode ByInstanceID map[string]ExitNode