分享
  1. 首页
  2. 文章

用golang写socks5代理服务器2-ssh远程代理

myml · · 3803 次点击 · · 开始浏览
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

上次用golang来实现本地socks5代理,然而使用代理当然是为了和谐上网,所以这次来介绍用ssh来实现远程代理,用到官方ssh包

golang.org/x/crypto/ssh

用golang连接ssh并不难

读取密钥,设置配置,连接服务器就ok了(不建议用用户名+密码方式连接ssh)

	b, err := ioutil.ReadFile("/home/myml/.ssh/id_rsa")
	if err != nil {
		log.Println(err)
		return
	}
	pKey, err := ssh.ParsePrivateKey(b)
	if err != nil {
		log.Println(err)
		return
	}
	config := ssh.ClientConfig{
		User: "userName",
		Auth: []ssh.AuthMethod{
			ssh.PublicKeys(pKey),
		},
	}
	client, err = ssh.Dial("tcp", "Host:22", &config)
	if err != nil {
		log.Println(err)
		return
	}
	log.Println("连接服务器成功")
	defer client.Close()

这样你就得到了一个client,它有个Dial()函数用来创建socket连接,这个是在服务器上创建的,也就可以突破网络限制了,加上上次的sock5代理,把net.Dial改为client.Dial,就能让服务器来代理访问了

	server, err := client.Dial("tcp", addr)
	if err != nil {
		log.Println(err)
		return
	}
	conn.Write([]byte{0x05, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})
	go io.Copy(server, conn)
	io.Copy(conn, server)

下面是能成功运行并进行远程代理的代码(在Chrome和proxychains测试),ssh服务器和配置信息要修改为自己的

// socks5ProxyProxy project main.go
package main
import (
	"bytes"
	"encoding/binary"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net"
	"golang.org/x/crypto/ssh"
)
func socks5Proxy(conn net.Conn) {
	defer conn.Close()
	var b [1024]byte
	n, err := conn.Read(b[:])
	if err != nil {
		log.Println(err)
		return
	}
	log.Printf("% x", b[:n])
	conn.Write([]byte{0x05, 0x00})
	n, err = conn.Read(b[:])
	if err != nil {
		log.Println(err)
		return
	}
	log.Printf("% x", b[:n])
	var addr string
	switch b[3] {
	case 0x01:
		sip := sockIP{}
		if err := binary.Read(bytes.NewReader(b[4:n]), binary.BigEndian, &sip); err != nil {
			log.Println("请求解析错误")
			return
		}
		addr = sip.toAddr()
	case 0x03:
		host := string(b[5 : n-2])
		var port uint16
		err = binary.Read(bytes.NewReader(b[n-2:n]), binary.BigEndian, &port)
		if err != nil {
			log.Println(err)
			return
		}
		addr = fmt.Sprintf("%s:%d", host, port)
	}
	server, err := client.Dial("tcp", addr)
	if err != nil {
		log.Println(err)
		return
	}
	conn.Write([]byte{0x05, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})
	go io.Copy(server, conn)
	io.Copy(conn, server)
}
type sockIP struct {
	A, B, C, D byte
	PORT uint16
}
func (ip sockIP) toAddr() string {
	return fmt.Sprintf("%d.%d.%d.%d:%d", ip.A, ip.B, ip.C, ip.D, ip.PORT)
}
func socks5ProxyStart() {
	log.SetFlags(log.Ltime | log.Lshortfile)
	server, err := net.Listen("tcp", ":8080")
	if err != nil {
		log.Panic(err)
	}
	defer server.Close()
	log.Println("开始接受连接")
	for {
		client, err := server.Accept()
		if err != nil {
			log.Println(err)
			return
		}
		log.Println("一个新连接")
		go socks5Proxy(client)
	}
}
var client *ssh.Client
func main() {
	b, err := ioutil.ReadFile("/home/myml/.ssh/id_rsa")
	if err != nil {
		log.Println(err)
		return
	}
	pKey, err := ssh.ParsePrivateKey(b)
	if err != nil {
		log.Println(err)
		return
	}
	config := ssh.ClientConfig{
		User: "user",
		Auth: []ssh.AuthMethod{
			ssh.PublicKeys(pKey),
		},
	}
	client, err = ssh.Dial("tcp", "host:22", &config)
	if err != nil {
		log.Println(err)
		return
	}
	log.Println("连接服务器成功")
	defer client.Close()
	client.Dial()
	socks5ProxyStart()
	return
}

有疑问加站长微信联系(非本文作者)

本文来自:开源中国博客

感谢作者:myml

查看原文:用golang写socks5代理服务器2-ssh远程代理

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

关注微信
3803 次点击
暂无回复
添加一条新回复 (您需要 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传

用户登录

没有账号?注册
(追記) (追記ここまで)

今日阅读排行

    加载中
(追記) (追記ここまで)

一周阅读排行

    加载中

关注我

  • 扫码关注领全套学习资料 关注微信公众号
  • 加入 QQ 群:
    • 192706294(已满)
    • 731990104(已满)
    • 798786647(已满)
    • 729884609(已满)
    • 977810755(已满)
    • 815126783(已满)
    • 812540095(已满)
    • 1006366459(已满)
    • 692541889

  • 关注微信公众号
  • 加入微信群:liuxiaoyan-s,备注入群
  • 也欢迎加入知识星球 Go粉丝们(免费)

给该专栏投稿 写篇新文章

每篇文章有总共有 5 次投稿机会

收入到我管理的专栏 新建专栏