go-socks5: a SOCKS5 server package with pluggable auth, rules and resolver
socks5 server in pure Golang with much custom optional. Full TCP/UDP and IPv4/IPv6 support.
At a glance
- What is it?
- The things-go/go-socks5 package implements a SOCKS5 server in pure Go with TCP, UDP, IPv4 and IPv6 support, and exposes every part of the pipeline as an option: authentication, address limits, a ruleset for filtering commands, a custom resolver, a goroutine pool, a buffer pool and a logger.
- Who is it for?
- Adopt go-socks5 when you need a SOCKS5 server as a component inside a Go service, with per-client authentication, address restrictions and command filtering you control. Do not adopt it as a ready-to-run proxy for end users, since you are expected to write the main function and the operational surface around it.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 7 days ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A library, not a proxy binary
The repository provides a package named socks5 that implements SOCKS5, and the README is explicit about what SOCKS is for: it is used to route traffic between a client and server through an intermediate proxy layer, which can be used to bypass firewalls or NATs.
The important thing to notice is what the repository is not. There is no main package to run, no configuration file format, no service definition, no documentation of how to deploy it. The tree at the root is a Go library: auth.go, credentials.go, handle.go, logger.go, option.go, resolver.go, ruleset.go, server.go, a bufferpool/ package, a statute/ package, and a _example/ directory.
That means you are writing the entry point. The package gives you a server object, a set of options to configure it, and handlers you can plug in, and everything around that, the process lifecycle, the logging destination, the way it is exposed, is yours.
The primary language is Go, the go.mod declares go 1.18, and the only direct dependencies are golang.org/x/net and stretchr/testify for the tests. The licence is MIT, and the project credits two references: rfc1928 for the protocol and the original armon's go-socks5 library, which this is a fork of and an evolution of.
What the feature list actually covers
The feature list in the README is short and specific, and each item corresponds to a hook you can use.
There is support for a socks5 server, and support for TCP and UDP along with IPv4 and IPv6. Unit tests are present. There is a No Auth mode, and user and password authentication which is optional and can carry a user address limit. The CONNECT command is supported, and so is the ASSOCIATE command. There are rules to do granular filtering of commands, custom DNS resolution, a custom goroutine pool, a buffer pool design with an optional custom buffer pool, and a custom logger.
Two of these deserve unpacking because they are the difference between this being a demo and this being usable in production.
The ruleset is the command filter. Instead of accepting every CONNECT a client asks for, you can decide per command and per destination which connections are allowed, which means a SOCKS5 server on the open internet can be constrained to a fixed set of destinations rather than being a general purpose relay.
The optional user address limit in the authentication section is the other one. A credential that is bound to a source address means one account cannot be used from anywhere, which turns the server from a shared anonymous proxy into something with per-client accountability.
The custom resolver matters in a specific way too. If you control the DNS answers your clients receive, you can enforce split horizon resolution, block names, or point internal names at internal addresses, and the package lets you do that rather than delegating everything to the system resolver.
The example shows the whole startup path in twenty lines
The README gives a complete example, and it is short enough to read in one go, which is a good sign about the API surface.
The imports are the standard logging and os packages plus the socks5 package itself.
import (
"log"
"os"
"github.com/things-go/go-socks5"
)The main function creates the server with a logger option and then listens. The logger is constructed from a standard log.Logger writing to standard output with the prefix socks5: and the standard date and time flags.
func main() {
// Create a SOCKS5 server
server := socks5.NewServer(
socks5.WithLogger(socks5.NewLogger(log.New(os.Stdout, "socks5: ", log.LstdFlags))),
)
// Create SOCKS5 proxy on localhost port 8000
if err := server.ListenAndServe("tcp", ":8000"); err != nil {
panic(err)
}
}The shape is functional options. NewServer takes a variadic set of options, and WithLogger is one of them, so configuration is added rather than set through a struct or a config file.
The example binds to :8000, which is the wildcard address on all interfaces, and the comment describes it as a proxy on localhost port 8000. That mismatch is worth noticing: the code as written listens on every interface of the host, and it does so with no authentication configured, since no auth option is passed. Anyone embedding this needs to be deliberate about the bind address and about requiring credentials.
Installing it into a Go project
The installation path is the standard Go module one.
go get github.com/things-go/go-socks5Then the package is imported into your own code, which the README shows as a one-line import.
import "github.com/things-go/go-socks5"Since the go.mod declares go 1.18, that is the language version floor, and the module path is github.com/things-go/go-socks5, matching the import in the example.
What is worth noting is the direction of the dependency. The package does not pull in a web framework, a configuration library, a metrics exporter or a logging framework. It depends on golang.org/x/net and, for the tests, on testify. That means every decision about configuration, logging format, metrics, TLS termination and process supervision is one you make in your own code, and the library stays out of the way of all of it.
The practical consequence is that you are not adopting a proxy, you are adopting a set of building blocks, and the operational work of turning them into a service is entirely on you.
ASSOCIATE is there, BIND is not, and that has consequences
The TODO section is one line and it is worth reading before you commit to this package for a particular client population.
Support for the BIND command is still needed. Everything else on the command list is done, including the two commands that matter most in practice.
CONNECT is the ordinary case, where a client asks the server to open a TCP connection to a destination and then relays bytes over it. ASSOCIATE is the UDP case, where the client asks the server to set up a UDP relay, which is what the SOCKS5 spec uses for UDP traffic and what the feature list ties to the TCP and UDP support in the package.
BIND is the third command, used when the server is asked to listen on a specified address and port and report that back, typically for FTP-style active data connections. It is rare in modern client usage, and its absence is unlikely to bite you unless you are serving clients that issue it.
The second limitation is about the trust model. The package implements the protocol, not the policy. The ruleset gives you the mechanism to filter commands, and the address limit gives you a way to bind a credential to a source address, but neither is on by default, and the example enables neither. A server exposed with the example's configuration is an open relay that will be found and abused, which is the most common way a SOCKS5 deployment goes wrong.
How this compares with the alternatives
The realistic alternatives fall into two groups, and the difference in approach matters more than the feature list.
The first group is other Go SOCKS5 libraries, including the armon's go-socks5 that this project is credited as originating from. The difference here is the option surface. Where the original is a working server you can configure, this one is built around plugging in your own pieces: your own authentication decision, your own ruleset, your own resolver, your own goroutine and buffer pools, your own logger. If you need a SOCKS5 server that runs correctly and nothing more, the original is a smaller dependency. If you need the server's behaviour to be a policy decision that lives in your codebase, the option pattern is the point.
The second group is the system tools: the Dante server, or a general purpose proxy such as Squid, or a tunnel implementation such as WireGuard. The difference in approach is that those are complete network daemons with their own configuration language, their own authentication backends and their own operational model, and they usually run as a separate service. go-socks5 is a library you link into your own binary, so it shares the process, the lifecycle and the deployment of whatever it is embedded in.
The tradeoff is symmetric. A system daemon is something you deploy and configure, whereas this is something you compile into your service and own the failure modes of. A SOCKS5 server in the same process as your application can be brought down by an application bug, and a bug in your option handling can open an open relay.
Editorial conclusion
Adopt go-socks5 when you need a SOCKS5 server as a component inside a Go service, with per-client authentication, address restrictions and command filtering you control. Do not adopt it as a ready-to-run proxy for end users, since you are expected to write the main function and the operational surface around it. Before you build on it, check that the CONNECT and ASSOCIATE commands cover your clients' needs, since the BIND command is listed as still to be done, and note the last push was on 2026-10-15 with release v0.1.3 in August 2026.
Frequently asked questions
How do I install and use the go-socks5 package?
Run go get github.com/things-go/go-socks5 and import the package into your own code. You then create a server with socks5.NewServer, passing options such as WithLogger, and call ListenAndServe to bind it.
Does go-socks5 support UDP and IPv6?
Yes. The feature list states support for TCP and UDP along with IPv4 and IPv6, and the ASSOCIATE command is implemented, which is the UDP relay path in the SOCKS5 protocol. Support for the BIND command is still listed as needed.
Can I restrict which destinations a go-socks5 client may reach?
Yes. The package provides rules to do granular filtering of commands, so you can decide which commands and destinations are permitted rather than accepting every request, and the optional user and password authentication can carry a user address limit.
Is go-socks5 a runnable proxy or a library?
A library. The repository provides the socks5 package and an _example directory with a small main function, and you are expected to write the entry point and the surrounding operational surface yourself.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/things-go-go-socks5)