Skip to content

feat(socks5): add SOCKS5 proxy support with configuration and logging.#3333

Closed
adjscent wants to merge 1 commit into
passteque:masterfrom
devhako:socks5-support
Closed

feat(socks5): add SOCKS5 proxy support with configuration and logging.#3333
adjscent wants to merge 1 commit into
passteque:masterfrom
devhako:socks5-support

Conversation

@adjscent
Copy link
Copy Markdown

@adjscent adjscent commented May 17, 2026

Working for me. Added SOCKS5 support with authentication.

Shadowsocks is good but it breaks a lot of socks5 clients.

Copilot AI review requested due to automatic review settings May 17, 2026 13:30
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a built-in SOCKS5 proxy server to Gluetun, including configuration via environment variables/secret files, container port exposure, and startup integration alongside existing proxy components.

Changes:

  • Introduces a new internal/socks5 package implementing a SOCKS5 server with optional user/password auth and optional logging.
  • Adds SOCKS5 settings to the global configuration model and settings summary output.
  • Wires the SOCKS5 loop into cmd/gluetun/main.go, and exposes port/env defaults in the Dockerfile + README.

Reviewed changes

Copilot reviewed 12 out of 13 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
README.md Documents SOCKS5 support and docker-compose port mapping.
internal/socks5/state.go Adds status/settings state management for the SOCKS5 loop.
internal/socks5/server.go Implements SOCKS5 server creation, auth config, and logging adapter.
internal/socks5/server_test.go Adds basic handshake tests for no-auth and user/pass auth.
internal/socks5/loop.go Adds the long-running loop supervising the SOCKS5 server lifecycle.
internal/socks5/logger.go Defines the logger interface for the SOCKS5 component.
internal/configuration/settings/socks5.go Adds SOCKS5 settings parsing/defaults/validation/string formatting.
internal/configuration/settings/settings.go Plumbs SOCKS5 into global settings (read/default/validate/copy/string).
internal/configuration/settings/settings_test.go Updates settings string snapshot to include SOCKS5 section.
go.mod Adds dependency on github.com/armon/go-socks5.
go.sum Adds checksums for the new SOCKS5 dependency.
Dockerfile Adds SOCKS5 env defaults + secretfile envs and exposes port 1080/tcp.
cmd/gluetun/main.go Starts the SOCKS5 loop and includes it in shutdown handling.
Comments suppressed due to low confidence (1)

internal/socks5/loop.go:133

  • The timer drain logic if !isStableTimer.Stop() { <-isStableTimer.C } can block if the timer already fired and its value was already received earlier (so Stop() returns false but the channel is empty). Use a non-blocking drain (e.g. select { case <-isStableTimer.C: default: }) to avoid deadlocks on restart/shutdown paths that exit the inner loop after the stable timer already fired.
		if !isStableTimer.Stop() {
			<-isStableTimer.C
		}

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread internal/socks5/loop.go
l.logger.Info("stopping")
_ = listener.Close()
<-waitError
close(waitError)
Comment thread internal/socks5/loop.go
Comment on lines +89 to +107
isStableTimer := time.NewTimer(time.Second)

stayHere := true
for stayHere {
select {
case <-ctx.Done():
_ = listener.Close()
<-waitError
close(waitError)
return
case <-isStableTimer.C:
if !crashed {
l.running <- constants.Running
crashed = false
} else {
l.backoffTime = defaultBackoffTime
l.state.setStatusWithLock(constants.Running)
}
case <-l.start:
Comment thread internal/socks5/loop.go
Comment on lines +99 to +106
case <-isStableTimer.C:
if !crashed {
l.running <- constants.Running
crashed = false
} else {
l.backoffTime = defaultBackoffTime
l.state.setStatusWithLock(constants.Running)
}
Comment thread internal/socks5/state.go
}
l.state.statusMu.Lock()
l.state.status = newStatus
return status.String(), nil
@qdm12
Copy link
Copy Markdown
Member

qdm12 commented May 21, 2026

closed in favor of no-dependency #3336

@qdm12 qdm12 closed this May 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants