Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/shikanon/socks5proxy
Browse files Browse the repository at this point in the history
  • Loading branch information
shikanon committed Oct 5, 2019
2 parents 53681b8 + e0c2e13 commit 30cea31
Show file tree
Hide file tree
Showing 12 changed files with 295 additions and 67 deletions.
25 changes: 25 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
language: go
sudo: false
go:
- 1.10.x
- 1.11.x
- master

matrix:
fast_finish: true
include:
- go: 1.11.x
env: GO111MODULE=on


before_install:
- if [[ "${GO111MODULE}" = "on" ]]; then mkdir "${HOME}/go"; export GOPATH="${HOME}/go"; fi
- if [[ "${GO111MODULE}" = "on" ]]; then export PATH="${GOPATH}/bin:${GOROOT}/bin:${PATH}"; fi

install:
- go get github.com/stretchr/testify

go_import_path: github.com/shikanon/socks5proxy

script:
- go test -cover
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# Socks5 Proxy
------

用golang 实现了一个简单的socks5协议来实现代理转发。
用golang 实现了一个简单的socks5协议来实现代理转发,主要应用场景是給公司内部做VPN登陆,提供内网访问。
(声明:由于采用的是原始的socks5协议,并没有对协议做改造加工,并不一定能防范GFW的主动探测,请勿用于非法用途)

文件结构
```
Expand All @@ -16,6 +17,7 @@ cmd/client/main.go `客户端主启动程`

- [SOCKS5协议介绍](./docs/socks5.md)
- [加密算法介绍](./docs/cryptogram.md)
- [软件下载及版本说明](./docs/release.md)

#### 使用说明

Expand Down Expand Up @@ -44,5 +46,6 @@ cmd/client/main.go `客户端主启动程`
```

## TODO
* [*] 混淆加密
* [*] 客户端

* [ * ] 混淆加密
* [ * ] 客户端
17 changes: 11 additions & 6 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ type TcpClient struct{
server *net.TCPAddr
}

func handleProxyRequest(localClient *net.TCPConn,serverAddr *net.TCPAddr, auth *socks5Auth){
func handleProxyRequest(localClient *net.TCPConn,serverAddr *net.TCPAddr, auth socks5Auth){

// 远程连接IO
dstServer, err := net.DialTCP("tcp", nil, serverAddr)
defer dstServer.Close()
if err != nil {
log.Print("远程服务器地址连接错误!!!")
log.Print(err)
return
}
Expand All @@ -27,21 +27,26 @@ func handleProxyRequest(localClient *net.TCPConn,serverAddr *net.TCPAddr, auth *
SecureCopy(dstServer, localClient, auth.Decrypt)
}

func Client(listenAddrString string, serverAddrString string, passwd string){
func Client(listenAddrString string, serverAddrString string, encrytype string, passwd string){
//所有客户服务端的流都加密,
auth := CreateAuth(passwd)
log.Printf("你的密码是:%s ,请保管好你的密码", passwd)
auth,err := CreateAuth(encrytype, passwd)
if err != nil {
log.Fatal(err)
}
log.Printf("你的密码是: %s ,请保管好你的密码", passwd)

// proxy地址
serverAddr, err := net.ResolveTCPAddr("tcp", serverAddrString)
if err != nil {
log.Fatal(err)
}
log.Printf("连接远程服务器: %s ....", serverAddrString)

listenAddr, err := net.ResolveTCPAddr("tcp", listenAddrString)
if err != nil {
log.Fatal(err)
}
}
log.Printf("监听本地端口: %s ", listenAddrString)

listener, err := net.ListenTCP("tcp", listenAddr)
if err != nil {
Expand Down
4 changes: 3 additions & 1 deletion cmd/client/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@ func main(){
listenAddr := flag.String("local", ":8888", "Input server listen address(Default 8888):")
serverAddr := flag.String("server", "", "Input server listen address:")
passwd := flag.String("passwd", "123456", "Input server proxy password:")
encrytype := flag.String("type", "random", "Input encryption type:")
flag.Parse()
if *serverAddr == ""{
log.Fatal("请输入正确的远程地址")
}
socks5proxy.Client(*listenAddr, *serverAddr, *passwd)
log.Println("客户端正在启动...")
socks5proxy.Client(*listenAddr, *serverAddr, *encrytype, *passwd)
}
5 changes: 4 additions & 1 deletion cmd/server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@ package main
import(
"flag"
"github.com/shikanon/socks5proxy"
"log"
)

func main(){
listenAddr := flag.String("local", ":18888", "Input server listen address(Default 8888):")
passwd := flag.String("passwd", "123456", "Input server proxy password:")
encrytype := flag.String("type", "random", "Input encryption type:")
flag.Parse()
socks5proxy.Server(*listenAddr, *passwd)
log.Println("服务器正在启动...")
socks5proxy.Server(*listenAddr, *encrytype, *passwd)
}
117 changes: 88 additions & 29 deletions cryptogram.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,32 @@ package socks5proxy

import (
"io"
"net"
"errors"
)

type socks5Auth struct {
KeyMoved int // 移动位数
const(
RANDOM_A = 13
RANDOM_B = 7
RANDOM_M = 256
)

type socks5Auth interface{
Encrypt([]byte) error
Decrypt([]byte) error
EncodeWrite(io.ReadWriter, []byte) (int, error)
DecodeRead(io.ReadWriter, []byte) (int, error)
}

type DefaultAuth struct {
Encode *[256]byte //编码表
Decode *[256]byte //解码表
}

/**
加密方法:根据编码表将字符串进行编码
**/
func (s *socks5Auth) Encrypt(b []byte) error{

func (s *DefaultAuth) Encrypt(b []byte) error{
for i,v := range b {
// 编码
if int(v) >= len(s.Encode){
Expand All @@ -26,7 +38,7 @@ func (s *socks5Auth) Encrypt(b []byte) error{
return nil
}

func (s *socks5Auth) Decrypt(b []byte) error{
func (s *DefaultAuth) Decrypt(b []byte) error{
for i,v := range b {
// 编码
if int(v) >= len(s.Encode){
Expand All @@ -37,10 +49,35 @@ func (s *socks5Auth) Decrypt(b []byte) error{
return nil
}

// 创建认证证书
func CreateAuth(passwd string) *socks5Auth{
func (s *DefaultAuth)EncodeWrite(c io.ReadWriter, b []byte) (int, error) {
// 编码
err := s.Encrypt(b)
if err != nil{
return 0, err
}
return c.Write(b)
}

func (s *DefaultAuth)DecodeRead(c io.ReadWriter, b []byte) (int, error) {
// 解码
n,err := c.Read(b)
if err != nil{
return 0, err
}
err = s.Decrypt(b)
if err != nil{
return 0, err
}
return n, err
}

func CreateSimpleCipher(passwd string) (*DefaultAuth, error){
var s *DefaultAuth
// 采用最简单的凯撒位移法
sumint := 0
if len(passwd) == 0 {
return nil, errors.New("密码不能为空")
}
for v := range passwd {
sumint += int(v)
}
Expand All @@ -51,41 +88,63 @@ func CreateAuth(passwd string) *socks5Auth{
encodeString[i] = byte((i+sumint)%256)
decodeString[i] = byte((i-sumint+256)%256)
}
return &socks5Auth{
KeyMoved: sumint,
s = &DefaultAuth{
Encode: &encodeString,
Decode: &decodeString,
}
return s, nil
}

// 加密安全连接,组合了net.conn接口和socks5Auth结构体
type SecureConn struct{
net.Conn
Auth *socks5Auth
}

func (c *SecureConn)EncodeWrite(b []byte) (int, error) {
// 编码
err := c.Auth.Encrypt(b)
if err != nil{
return 0, err
func CreateRandomCipher(passwd string) (*DefaultAuth, error){
var s *DefaultAuth
// 采用随机编码表进行加密
sumint := 0
if len(passwd) == 0 {
return nil, errors.New("密码不能为空")
}
return c.Write(b)
for v := range passwd {
sumint += int(v)
}
var encodeString [256]byte
var decodeString [256]byte
// 创建随机数 (a*x + b) mod m
for i := 0; i < 256; i++{
encodeString[i] = byte((RANDOM_A*sumint+RANDOM_B)%RANDOM_M)
decodeString[(RANDOM_A*sumint+RANDOM_B)%RANDOM_M] = byte(i)
sumint = (RANDOM_A*sumint+RANDOM_B)%RANDOM_M
}
s = &DefaultAuth{
Encode: &encodeString,
Decode: &decodeString,
}
return s, nil
}

func (c *SecureConn)DecodeRead(b []byte) (int, error) {
// 解码
n,err := c.Read(b)
if err != nil{
return 0, err
// 创建认证证书
func CreateAuth(encrytype string, passwd string) (socks5Auth, error){
if len(passwd) == 0 {
return nil, errors.New("密码不能为空")
}
err = c.Auth.Decrypt(b)
if err != nil{
return 0, err
var s socks5Auth
var err error
switch encrytype{
case "simple":
s, err = CreateSimpleCipher(passwd)

case "random":
s, err = CreateRandomCipher(passwd)
default:
return nil, errors.New("错误加密方法类型!")
}
return n, err

if err != nil {
return nil, err
}
return s, nil
}


func SecureCopy(src io.ReadWriteCloser, dst io.ReadWriteCloser, secure func(b []byte) error) (written int64, err error) {
size := 1024
buf := make([]byte, size)
Expand Down
43 changes: 33 additions & 10 deletions cryptogram_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,50 @@ package socks5proxy
import (
"testing"
"github.com/stretchr/testify/assert"
// "log"
"log"
)

func TestCreateAuth(t *testing.T){
auth := CreateAuth("abc")
assert.Equal(t, int(auth.Encode[0]), auth.KeyMoved)
}

func TestSocks5Auth(t *testing.T){
auth := CreateAuth("abc")
func TestSampleCipher(t *testing.T){
auth, err := CreateSimpleCipher("abc")
if err != nil{
log.Panic(err)
}
b := []byte{0x05,0x01,0x04}
c := []byte{0x05,0x01,0x04}
// 加密
err := auth.Encrypt(b)
err = auth.Encrypt(b)
if err != nil{
log.Panic(err)
}
// 解密
err = auth.Decrypt(b)
if err != nil{
log.Panic(err)
}
assert.Equal(t, b, c)
}

func TestRandomCipher(t *testing.T){
auth,err := CreateRandomCipher("123456")
if err != nil{
log.Panic(err)
}
var b []byte
var c []byte
for i:=0;i<256; i++{
b = append(b, byte(i))
c = append(c,byte(i))
}
// 加密
err = auth.Encrypt(b)
if err != nil{
panic(err)
log.Panic(err)
}
// 解密
err = auth.Decrypt(b)
if err != nil{
panic(err)
log.Panic(err)
}
assert.Equal(t, b, c)
}
Loading

0 comments on commit 30cea31

Please sign in to comment.