首页 > 其他分享 >golang 实现 socks5 正向代理服务器

golang 实现 socks5 正向代理服务器

时间:2023-09-20 17:49:13浏览次数:44  
标签:errors return nil err 代理服务器 golang socks5 client buf

socks5proxy.go

package main

import (
    "encoding/binary"
    "errors"
    "flag"
    "fmt"
    "io"
    "net"
    "strconv"
)

var port int

func main() {
    flag.IntVar(&port, "p", 1080, "端口号")
    flag.Parse()
    port_str := strconv.Itoa(port)
    server, err := net.Listen("tcp", ":" + port_str)
    if err != nil {
        fmt.Printf("Listen failed: %v\n", err)
        return
    }
    fmt.Println("Socks5 create success")
    fmt.Println("Listen port: " + port_str)

    for {
        client, err := server.Accept()
        if err != nil {
            fmt.Printf("Accept failed: %v", err)
            continue
        }
        go process(client)
    }
}

func process(client net.Conn) {
    if err := Socks5Auth(client); err != nil {
        fmt.Println("auth error:", err)
        client.Close()
        return
    }

    target, err := Socks5Connect(client)
    if err != nil {
        fmt.Println("connect error:", err)
        client.Close()
        return
    }

    Socks5Forward(client, target)
}

func Socks5Auth(client net.Conn) (err error) {
    buf := make([]byte, 256)

    // 读取 VER 和 NMETHODS
    n, err := io.ReadFull(client, buf[:2])
    if n != 2 {
        return errors.New("reading header: " + err.Error())
    }

    ver, nMethods := int(buf[0]), int(buf[1])
    if ver != 5 {
        return errors.New("invalid version")
    }

    // 读取 METHODS 列表
    n, err = io.ReadFull(client, buf[:nMethods])
    if n != nMethods {
        return errors.New("reading methods: " + err.Error())
    }
    // 通知客户端无需认证
    n, err = client.Write([]byte{0x05, 0x00})
    if n != 2 || err != nil {
        return errors.New("write rsp err: " + err.Error())
    }
    return nil

}

func Socks5Connect(client net.Conn) (net.Conn, error) {
    buf := make([]byte, 256)
    n, err := io.ReadFull(client, buf[:4])
    if n != 4 {
        return nil, errors.New("read header: " + err.Error())
    }
    
    ver, cmd, _, atyp := buf[0], buf[1], buf[2], buf[3]
    if ver != 5 || cmd != 1 {
        return nil, errors.New("invalid ver/cmd")
    }
    addr := ""
    switch atyp {
    case 1:
        n, err = io.ReadFull(client, buf[:4])
        if n != 4 {
            return nil, errors.New("invalid IPv4: " + err.Error())
        }
        addr = fmt.Sprintf("%d.%d.%d.%d", buf[0], buf[1], buf[2], buf[3])

    case 3:
        n, err = io.ReadFull(client, buf[:1])
        if n != 1 {
            return nil, errors.New("invalid hostname: " + err.Error())
        }
        addrLen := int(buf[0])

        n, err = io.ReadFull(client, buf[:addrLen])
        if n != addrLen {
            return nil, errors.New("invalid hostname: " + err.Error())
        }
        addr = string(buf[:addrLen])

    case 4:
        return nil, errors.New("IPv6: no supported yet")

    default:

        return nil, errors.New("invalid atyp")
    }
    n, err = io.ReadFull(client, buf[:2])
    if n != 2 {
        return nil, errors.New("read port: " + err.Error())
    }
    port := binary.BigEndian.Uint16(buf[:2])
    destAddrPort := fmt.Sprintf("%s:%d", addr, port)
    dest, err := net.Dial("tcp", destAddrPort)
    if err != nil {
        return nil, errors.New("dial dst: " + err.Error())
    }
    n, err = client.Write([]byte{0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0, 0})
    if err != nil {
        dest.Close()
        return nil, errors.New("write rsp: " + err.Error())
    }

    return dest, nil

}

// socks转发
func Socks5Forward(client, target net.Conn) {
    forward := func(src, dest net.Conn) {
        defer src.Close()
        defer dest.Close()
        io.Copy(src, dest)
    }
    go forward(client, target)
    go forward(target, client)
}

 

via:https://blog.hsm.cool/index.php/archives/821/

 

标签:errors,return,nil,err,代理服务器,golang,socks5,client,buf
From: https://www.cnblogs.com/nihaorz/p/17717920.html

相关文章

  • GOLANG:调用delphi7编写的dll
    0. delphi对winapi有很强的封装,使其更易用。1.delphi声明dll内函数需要尽量以此方式: proceduretest(data:pchar;count:integer);stdcall;2.golang调用方法:str:=[]byte("abcdedf")printTextDll:=syscall.NewLazyDLL("demo.dll")printBytes:=p......
  • golang fyne 添加系统托盘
    环境:gofyne 要求:电脑右下方添加系统托盘,点击图标显示托盘菜单效果:实现:1packagemain23import(4"fyne.io/fyne/v2"5"fyne.io/fyne/v2/app"6"fyne.io/fyne/v2/widget"7"fyne.io/fyne/v2/driver/desktop"8&......
  • 代理IP与Socks5代理:跨界电商智能爬虫的引擎与安全壁垒
    摘要:随着跨界电商的蓬勃发展,数据采集和隐私保护成为企业的关键挑战。本文将深入探讨代理IP和Socks5代理在跨界电商中的应用,以及它们在智能爬虫技术中的关键作用,为企业提供数据引擎和安全防护的解决方案。第一部分:背景介绍跨界电商已成为全球贸易的重要组成部分,为企业提供了巨大的市......
  • 代理IP与Socks5代理:跨界电商智能爬虫的引擎与安全壁垒
    摘要:随着跨界电商的蓬勃发展,数据采集和隐私保护成为企业的关键挑战。本文将深入探讨代理IP和Socks5代理在跨界电商中的应用,以及它们在智能爬虫技术中的关键作用,为企业提供数据引擎和安全防护的解决方案。第一部分:背景介绍跨界电商已成为全球贸易的重要组成部分,为企业提供了巨大的市......
  • golang fyne 创建两个窗口,窗口居中。点击按钮显示第二个窗口 myApp.NewWindow("new")
    环境:gofyne实现:在窗口的按钮中,点击按钮弹出第二窗口,并且窗口居中注意:创建的第一个窗口和第二个窗口必须是通过同一个myApp:=app.New()创建出来的效果:实现:1packagemain23import(4"fmt"56"fyne.io/fyne/v2"7"fyne.io/fyne/v2/app"8......
  • Socks5代理、IP代理与网络安全:保护你的爬虫和隐私
    在数字时代,数据是黄金,网络安全成为至关重要的问题。无论是保护个人隐私还是进行爬虫数据采集,代理技术已经成为网络工程师的必备工具。本文将深入探讨Socks5代理、IP代理以及它们在网络安全和爬虫应用中的重要性。1.了解Socks5代理Socks5代理是一种网络协议,允许应用程序通过中间服......
  • 代理IP和Socks5代理:跨界电商与爬虫的智能引擎
    跨界电商,作为全球市场的一部分,对数据的需求越来越大。同时,随着互联网的发展,爬虫技术也在不断演进,成为了跨界电商的关键工具之一。然而,随之而来的是网站的反爬虫机制和网络安全风险。在这种情况下,代理IP和Socks5代理应运而生,为企业提供了数据采集的解决方案和网络安全的保护。本文将......
  • 代理IP和Socks5代理:跨界电商与爬虫的智能引擎
    跨界电商,作为全球市场的一部分,对数据的需求越来越大。同时,随着互联网的发展,爬虫技术也在不断演进,成为了跨界电商的关键工具之一。然而,随之而来的是网站的反爬虫机制和网络安全风险。在这种情况下,代理IP和Socks5代理应运而生,为企业提供了数据采集的解决方案和网络安全的保护。本文将......
  • golang项目搭建笔记-cobra
    cobra介绍GitHub地址cobra中,一个命令主要概念为command,arguement,flag,可以理解为谓语、宾语、状语格式为APPNAMECOMMANDARG--FLAG,例如:gitcloneURL--bare项目搭建cobra提供了非常方便的工具cobra-cli,可以快速添加命令,参考官方文档新建项目#进入项目目录gomodin......
  • Golang 基础语法的使用
    1packagecustomer23import(4"encoding/json"5"fmt"6"os"7)89typecustomerstruct{10Namestring11Sexstring12Ageint13Phonestring14......