diff --git a/Dockerfile b/Dockerfile index 4696548..c39ffa6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,4 +8,5 @@ RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -ldflags '-s' -o ./s FROM gcr.io/distroless/static:nonroot COPY --from=builder /go/src/github.com/serjs/socks5/socks5 / + ENTRYPOINT ["/socks5"] diff --git a/README.md b/README.md index 79bfca0..5e3a1fe 100644 --- a/README.md +++ b/README.md @@ -9,26 +9,31 @@ Simple socks5 server using go-socks5 with authentication, allowed ips list and d - Run docker container using default container port 1080 and expose it to world using host port 1080, with auth creds - ```docker run -d --name socks5 -p 1080:1080 -e PROXY_USER= -e PROXY_PASSWORD= serjs/go-socks5-proxy``` + `docker run -d --name socks5 -p 1080:1080 -e PROXY_USER= -e PROXY_PASSWORD= serjs/go-socks5-proxy` - - Leave `PROXY_USER` and `PROXY_PASSWORD` empty for skip authentication options while running socks5 server, see example below + - Leave `PROXY_USER` and `PROXY_PASSWORD` empty for skip authentication options while running socks5 server, see example below - Run docker container using specifit container port and expose it to host port 1090, without auth creds - ```docker run -d --name socks5 -p 1090:9090 -e PROXY_PORT=9090 serjs/go-socks5-proxy``` + `docker run -d --name socks5 -p 1090:9090 -e PROXY_PORT=9090 serjs/go-socks5-proxy` -# List of supported config parameters +- Run docker container using default container port 1080 and expose it to world using host port 1080, with PROXY_CREDENTIALS multi-user authentication + + `docker run -d --name socks5 -p 1080:1080 -e PROXY_CREDENTIALS='[{"username":"TEST_USERNAME","password":"password123"}]' serjs/go-socks5-proxy` -|ENV variable|Type|Default|Description| -|------------|----|-------|-----------| -|PROXY_USER|String|EMPTY|Set proxy user (also required existed PROXY_PASS)| -|PROXY_PASSWORD|String|EMPTY|Set proxy password for auth, used with PROXY_USER| -|PROXY_PORT|String|1080|Set listen port for application inside docker container| -|ALLOWED_DEST_FQDN|String|EMPTY|Allowed destination address regular expression pattern. Default allows all.| -|ALLOWED_IPS|String|Empty|Set allowed IP's that can connect to proxy, separator `,`| +# List of supported config parameters +| ENV variable | Type | Default | Description | +| ----------------- | ----------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| PROXY_CREDENTIALS | Json Object | EMPTY | Provide a JSON stringified object representing a list of allowed user/password credential pairs. The form of this object is `{ password: string, username: string }[]`. See | +| PROXY_USER | String | EMPTY | Set proxy user (also required existed PROXY_PASS) | +| PROXY_PASSWORD | String | EMPTY | Set proxy password for auth, used with PROXY_USER | +| PROXY_PORT | String | 1080 | Set listen port for application inside docker container | +| ALLOWED_DEST_FQDN | String | EMPTY | Allowed destination address regular expression pattern. Default allows all. | +| ALLOWED_IPS | String | Empty | Set allowed IP's that can connect to proxy, separator `,` | # Build your own image: + `docker-compose -f docker-compose.build.yml up -d`\ Just don't forget to set parameters in the `.env` file. @@ -38,22 +43,22 @@ Assuming that you are using container on 1080 host docker port ## Without authentication -```curl --socks5 :1080 https://ifcfg.co``` - result must show docker host ip (for bridged network) +`curl --socks5 :1080 https://ifcfg.co` - result must show docker host ip (for bridged network) or -```docker run --rm curlimages/curl:7.65.3 -s --socks5 :1080 https://ifcfg.co``` +`docker run --rm curlimages/curl:7.65.3 -s --socks5 :1080 https://ifcfg.co` ## With authentication -```curl --socks5 :1080 -U : http://ifcfg.co``` +`curl --socks5 :1080 -U : http://ifcfg.co` or -```docker run --rm curlimages/curl:7.65.3 -s --socks5 :@:1080 http://ifcfg.co``` +`docker run --rm curlimages/curl:7.65.3 -s --socks5 :@:1080 http://ifcfg.co` # Authors -* **Sergey Bogayrets** +- **Sergey Bogayrets** See also the list of [contributors](https://github.com/serjs/socks5-server/graphs/contributors) who participated in this project. diff --git a/credentials.go b/credentials.go new file mode 100644 index 0000000..de889ca --- /dev/null +++ b/credentials.go @@ -0,0 +1,34 @@ +package main + +import ( + "encoding/json" + + "github.com/armon/go-socks5" +) + +type Credentials struct { + Username string `json:"username"` + Password string `json:"password"` +} + +func getCredentials(params params) (socks5.StaticCredentials, error) { + var creds socks5.StaticCredentials = make(socks5.StaticCredentials) + + if params.Creds != "" { + var parsed_env_creds []Credentials + err := json.Unmarshal([]byte(params.Creds), &parsed_env_creds) + if err != nil { + return nil, err + } + + for _, kv := range parsed_env_creds { + creds[kv.Username] = kv.Password + } + } + + if params.User+params.Password != "" { + creds[params.User] = params.Password + } + + return creds, nil +} diff --git a/server.go b/server.go index 921f1ac..3a01fae 100644 --- a/server.go +++ b/server.go @@ -10,11 +10,12 @@ import ( ) type params struct { - User string `env:"PROXY_USER" envDefault:""` - Password string `env:"PROXY_PASSWORD" envDefault:""` - Port string `env:"PROXY_PORT" envDefault:"1080"` - AllowedDestFqdn string `env:"ALLOWED_DEST_FQDN" envDefault:""` - AllowedIPs []string `env:"ALLOWED_IPS" envSeparator:"," envDefault:""` + Creds string `env:"PROXY_CREDENTIALS" envDefault:""` + User string `env:"PROXY_USER" envDefault:""` + Password string `env:"PROXY_PASSWORD" envDefault:""` + Port string `env:"PROXY_PORT" envDefault:"1080"` + AllowedDestFqdn string `env:"ALLOWED_DEST_FQDN" envDefault:""` + AllowedIPs []string `env:"ALLOWED_IPS" envSeparator:"," envDefault:""` } func main() { @@ -30,10 +31,11 @@ func main() { Logger: log.New(os.Stdout, "", log.LstdFlags), } - if cfg.User+cfg.Password != "" { - creds := socks5.StaticCredentials{ - os.Getenv("PROXY_USER"): os.Getenv("PROXY_PASSWORD"), - } + log.Printf(cfg.Creds) + + creds, err := getCredentials(cfg) + + if len(creds) > 0 { cator := socks5.UserPassAuthenticator{Credentials: creds} socks5conf.AuthMethods = []socks5.Authenticator{cator} }