socks5lb

package module
v0.0.0-...-1ed0320 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 24, 2023 License: MIT Imports: 18 Imported by: 0

README

socks5lb,简单的 Socks5 代理负载均衡

socks5lb

有时候我们在使用 Socks5 Proxy 无法联通的情况,这有可能是因为网络或者线路的调整和波动,这时候往往需要我们自己手工的切换节点,非常的麻烦。

这个工具就是为了解决上述问题而编写的,它简单的说就是个针对 Socks5 Proxy 的前置负载均衡,能够提供经过检验的稳定可靠的 Socks Proxy 节点。

如果是针对 Linux 系统下同时能够提供透明代理以及针对 Socks5 协议的转换,而且方便搭配 ipset 以及 iptables 使用。

目前实现的部分特性有:

  • 能够提供 Socks5 Proxy 的负载均衡(轮询机制)同时提供健康检查;
  • 针对 Linux 提供透明代理以及 Socks5 的协议转换;
  • 使用 Golang 编写,跨平台部署(例如部署到各种路由器上)和配置方便。

更新记录

  • 20220716 修复部分链接的性能问题,增加 HTTP 管理接口
  • 20220706 完成针对 Linux 的透明网关功能
  • 20220620 完成基本功能

编译

建议使用 docker-compose 编译生成镜像文件,直接执行 docker-compose build 即可。

配置

首先是针对 socks5lb 的基本配置,例如以下的配置配置了三个 Socks5 Proxy 同时暴露到本地的 1080 端口,针对 Linux 的透明代理暴露在 8848 端口。

server:
  http:
    addr: ":8080"
  socks5:
    addr: ":1080"
  tproxy:
    addr: ":8848"
backends:
  - addr: 192.168.100.254:1086
    check_config:
      check_url: https://www.google.com/robots.txt
      initial_alive: true
      timeout: 3
  - addr: 10.1.0.254:1086
    check_config:
      check_url: https://www.google.com/robots.txt
      initial_alive: false
      timeout: 30
  - addr: 172.16.100.254:1086
    check_config:
      check_url: https://www.google.com/robots.txt
      initial_alive: true
      timeout: 3
环境变量
  • SELECT_TIME_INTERVAL 自动切换代理的时间,单位为秒(默认 300 秒,五分钟)
  • CHECK_TIME_INTERVAL 健康检查的轮询时间,单位为秒(默认一分钟、60 秒)
  • DEBUG 是否打开 debug 模式
部署

首先,以下是 docker-compose 相关的配置,建议使用 network_mode: 'host' 方式,防止 DOCK 的 iptables 造成网络联通错误

version: "3"
services:
  socks5lb:
    image: ghcr.io/mingcheng/socks5lb:latest
    restart: always
    dns:
      - 8.8.8.8
      - 8.8.4.4
    environment:
      TZ: "Asia/Shanghai"
      CHECK_TIME_INTERVAL: 3600
    network_mode: "host"
    privileged: true
    volumes:
      - ./socks5lb.yml:/etc/socks5lb.yml:ro

然后配置(供参考)iptable 参数,将所有的流量都通过 8848 代理端口转发(注意 redrock 链没有定义,请自行配置)。

iptables -t nat -I PREROUTING -p tcp -m set --match-set redrock dst -j REDIRECT --to-ports 8848
iptables -t nat -I OUTPUT -p tcp -m set --match-set redrock dst -j REDIRECT --to-ports 8848
Web 管理

自 1.1.0 版本实现了个简单的 Web 管理接口,用于动态的添加和删除代理服务器的配置,简单的说明如下:

GET /version

目前运行的版本、编译时间以及运行时间

GET /api/all

显示目前配置的代理服务器列表,如果加 healthy=true 参数,则只显示目前健康的代理节点

PUT /api/add

增加代理,这里说明下 Put 的 Body 为 JSON 数组,同时配置和代理的配置对应,例如

[
  {
    "addr": "192.168.1.254:1086",
    "check_config": {
      "check_url": "https://www.taobao.com/robots.txt"
    }
  },
  {
    "addr": "192.168.1.254:1087",
    "check_config": {
      "initial_alive": true
    }
  }
]

然后返回的是已经加入的代理节点数量(整型数)。如果已经有配置的代理节点,则需要先删除以后再加入。

示例 CURL 如下:

curl -X "PUT" "<your-address>/api/add" \
     -H 'Content-Type: text/plain; charset=utf-8' \
     -d $'[
  {
    "addr": "192.168.1.1:1086",
    "check_config": {
      "check_url": "https://www.taobao.com/robots.txt"
    }
  }
]'
DELETE /api/delete

删除指定的代理地址,参数 addr 指定参数名称。

curl -X "DELETE" "http://localhost:8080/api/delete?addr=192.168.1.1:1086"

常见问题

如果我不想针对某个节点健康检查呢(强制使用)?

那么可以配置节点 check_url 参数为空,然后默认 initial_alivetrue 即可,例如:

backends:
  - addr: 127.0.0.1:10860
    check_config:
      initial_alive: true
在其他非 Linux 系统下可以使用 tproxy_listen 这个配置吗?

不好意思,透明代理只针对 Linux 平台,所以如果是非 Linux 平台,请留空对应的配置。

有没有类似功能的项目?

Documentation

Index

Constants

View Source
const AppName = "socks5lb"

Variables

View Source
var (
	Version     = "n/a"
	BuildCommit = "n/a"
	BuildDate   = "n/a"

	DebugMode = false
	StartTime time.Time
)

Functions

func GetEnv

func GetEnv(name, def string) string

GetEnv to get the environment variables from system is not provided return default values

func SecFromEnv

func SecFromEnv(name string, defVal uint64) time.Duration

SecFromEnv to get the seconds duration from system environment

Types

type Backend

type Backend struct {
	Addr        string             `yaml:"addr" json:"addr" binding:"required"`
	UserName    string             `yaml:"username" json:"username"`
	Password    string             `yaml:"password" json:"password"`
	CheckConfig BackendCheckConfig `yaml:"check_config" json:"check_config"`
	// contains filtered or unexported fields
}

func NewBackend

func NewBackend(addr string, config BackendCheckConfig) (backend *Backend)

NewBackend creates a new Backend instance

func (*Backend) Alive

func (b *Backend) Alive() bool

Alive returns backend status

func (*Backend) Check

func (b *Backend) Check() (err error)

Check function to check the node healthy by given url

func (*Backend) Socks5Conn

func (b *Backend) Socks5Conn(network, addr string, timeout int) (cc net.Conn, err error)

Socks5Conn to create a connection by specific params

type BackendCheckConfig

type BackendCheckConfig struct {
	CheckURL     string `yaml:"check_url" json:"check_url"`
	InitialAlive bool   `yaml:"initial_alive" json:"initial_alive"`
	Timeout      uint   `yaml:"timeout" json:"timeout"`
}

type Configure

type Configure struct {
	ServerConfig ServerConfig `yaml:"server"`
	Backends     []Backend    `yaml:"backends"`
}

type Pool

type Pool struct {
	// contains filtered or unexported fields
}

func NewPool

func NewPool(backends ...[]Backend) *Pool

NewPool instance for a new Pools instance

func (*Pool) Add

func (b *Pool) Add(backend *Backend) (err error)

Add add a backend to the pool

func (*Pool) All

func (b *Pool) All() (backends []*Backend)

All returns all backends

func (*Pool) AllHealthy

func (b *Pool) AllHealthy() (backends []*Backend)

AllHealthy returns all healthy backends

func (*Pool) Check

func (b *Pool) Check()

Check if we have an alive backend

func (*Pool) Next

func (b *Pool) Next() *Backend

Next returns the next index in the pool if there is one available Only supports round-robin operations by default

func (*Pool) NextIndex

func (b *Pool) NextIndex() int

NextIndex returns the next index for loadbalancer interface

func (*Pool) Remove

func (b *Pool) Remove(addr string) (err error)

Remove remove a backend from the pool

type Server

type Server struct {
	Pool   *Pool
	Config *ServerConfig
	// contains filtered or unexported fields
}

func NewServer

func NewServer(pool *Pool, config ServerConfig) (*Server, error)

func (*Server) AddBackend

func (s *Server) AddBackend() error

func (*Server) Engine

func (s *Server) Engine() *gin.Engine

Engine returns the main http engine for testing purposes

func (*Server) ListenHTTPAdmin

func (s *Server) ListenHTTPAdmin(addr string) (err error)

ListenHTTPAdmin is not implemented by default

func (*Server) ListenSocks5

func (s *Server) ListenSocks5(addr string) (err error)

ListenSocks5 to listen on a specific address

func (*Server) ListenTProxy

func (s *Server) ListenTProxy(addr string) (err error)

ListenTProxy is listening the local tcp port on the given address Deprecated: this feature will be disabled in the future

func (*Server) Start

func (s *Server) Start() (err error)

func (*Server) Stop

func (s *Server) Stop() (e error)

func (*Server) Transport

func (s *Server) Transport(dst, src io.ReadWriter) (err error)

Transport is used to connect to the server and client each other

type ServerConfig

type ServerConfig struct {
	HTTP struct {
		Addr string `yaml:"addr"`
	} `yaml:"http"`

	TProxy struct {
		Addr string `yaml:"addr"`
	} `yaml:"tproxy"`

	Sock5 struct {
		Addr string `yaml:"addr"`
	} `yaml:"socks5"`
}

type Status

type Status struct {
	OutBytes, InBytes uint
	LastOnline        time.Time
	LastFailed        time.Time
	FailedTimes       uint
}

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL