加密传输,代码优化

This commit is contained in:
刘河 2019-01-03 01:44:45 +08:00
parent 4dad726129
commit 1d89e7dae2
16 changed files with 725 additions and 208 deletions

View File

@ -1,12 +1,20 @@
appname = httpMonitor
#web管理端口
httpport = 8080
#启动模式dev|pro
runmode = dev
#web管理密码
password=123
#http监听端口
hostPort=8028
#basic auth认证用户名和密码
#basic auth认证用户名和密码为空则不验证
auth.user=test
auth.password=1234
auth.password=1234
#是否加密传输0|1
crypt=1

View File

@ -1,8 +1 @@
8021,tunnelServer,10.1.50.203:80,um80bbyvcaiw7n17,,,,1
8001,tunnelServer,10.1.50.101:22,h8vcpciko9lczxmb,,,gzip,0
8022,tunnelServer,10.1.50.196:4000,vcerzo01q16cdn9n,,,snappy,1
8002,udpServer,10.1.50.102:53,zcbsx5kp53cg5yqv,,,,0
8003,sock5Server,,9mq856pqq3jq05qv,,,snappy,1
8010,sock5Server,,0aj2xfec0mbkann5,test,test,gzip,0
8004,httpProxyServer,,y72zj8t074lslln0,,,gzip,0
0,hostServer,,o2430bnq22jgnmcl,,,,1
8001,tunnelServer,10.1.50.196:4000,jq5i7n0sjs1h0jje,,,,1,1

1 8021 8001 tunnelServer 10.1.50.203:80 10.1.50.196:4000 um80bbyvcaiw7n17 jq5i7n0sjs1h0jje 1 1
8001 tunnelServer 10.1.50.101:22 h8vcpciko9lczxmb gzip 0
8022 tunnelServer 10.1.50.196:4000 vcerzo01q16cdn9n snappy 1
8002 udpServer 10.1.50.102:53 zcbsx5kp53cg5yqv 0
8003 sock5Server 9mq856pqq3jq05qv snappy 1
8010 sock5Server 0aj2xfec0mbkann5 test test gzip 0
8004 httpProxyServer y72zj8t074lslln0 gzip 0
0 hostServer o2430bnq22jgnmcl 1

View File

@ -64,6 +64,7 @@ func (s *IndexController) Add() {
U: s.GetString("u"),
P: s.GetString("p"),
Compress: s.GetString("compress"),
Crypt: s.GetString("crypt"),
IsRun: 0,
}
lib.CsvDb.NewTask(t)
@ -96,6 +97,7 @@ func (s *IndexController) Edit() {
t.U = s.GetString("u")
t.P = s.GetString("p")
t.Compress = s.GetString("compress")
t.Crypt = s.GetString("crypt")
lib.CsvDb.UpdateTask(t)
lib.StopServer(t.VerifyKey)
lib.StartTask(t.VerifyKey)

View File

@ -86,10 +86,12 @@ func (s *TRPClient) dealChan() error {
//创建一个tcp连接
conn, err := net.Dial("tcp", s.svrAddr)
if err != nil {
log.Println("connect to ", s.svrAddr, "error:", err)
return err
}
//验证
if _, err := conn.Write([]byte(getverifyval(s.vKey))); err != nil {
log.Println("connect to ", s.svrAddr, "error:", err)
return err
}
//默认长连接保持
@ -98,25 +100,26 @@ func (s *TRPClient) dealChan() error {
//写标志
c.wChan()
//获取连接的host type(tcp or udp)
typeStr, host, en, de, err := c.GetHostFromConn()
typeStr, host, en, de, crypt, err := c.GetHostFromConn()
if err != nil {
log.Println("get host info error:", err)
return err
}
//与目标建立连接
server, err := net.Dial(typeStr, host)
if err != nil {
log.Println(err)
log.Println("connect to ", host, "error:", err)
return err
}
go relay(NewConn(server), c, de)
relay(c, NewConn(server), en)
go relay(NewConn(server), c, de, crypt)
relay(c, NewConn(server), en, crypt)
return nil
}
//http模式处理
func (s *TRPClient) dealHttp(c *Conn) error {
buf := make([]byte, 1024*32)
en, de := c.GetCompressTypeFromConn()
en, de, _ := c.GetConnInfoFromConn()
n, err := c.ReadFromCompress(buf, de)
if err != nil {
c.wError()

View File

@ -8,7 +8,6 @@ import (
"errors"
"fmt"
"github.com/golang/snappy"
"io"
"log"
"net"
"net/http"
@ -18,20 +17,76 @@ import (
"time"
)
type SnappyConn struct {
w *snappy.Writer
r *snappy.Reader
type CryptConn struct {
conn net.Conn
crypt bool
}
func NewSnappyConn(conn net.Conn) *SnappyConn {
func NewCryptConn(conn net.Conn, crypt bool) *CryptConn {
c := new(CryptConn)
c.conn = conn
c.crypt = crypt
return c
}
func (s *CryptConn) Write(b []byte) (n int, err error) {
n = len(b)
if s.crypt {
if b, err = AesEncrypt(b, []byte(cryptKey)); err != nil {
return
}
if b, err = GetLenBytes(b); err != nil {
return
}
}
_, err = s.conn.Write(b)
return
}
func (s *CryptConn) Read(b []byte) (n int, err error) {
if s.crypt {
var lens int
var buf, bs []byte
c := NewConn(s.conn)
if lens, err = c.GetLen(); err != nil {
return
}
if buf, err = c.ReadLen(lens); err != nil {
return
}
if bs, err = AesDecrypt(buf, []byte(cryptKey)); err != nil {
return
}
n = len(bs)
copy(b, bs)
return
}
return s.conn.Read(b)
}
type SnappyConn struct {
w *snappy.Writer
r *snappy.Reader
crypt bool
}
func NewSnappyConn(conn net.Conn, crypt bool) *SnappyConn {
c := new(SnappyConn)
c.w = snappy.NewBufferedWriter(conn)
c.r = snappy.NewReader(conn)
c.crypt = crypt
return c
}
func (s *SnappyConn) Write(b []byte) (n int, err error) {
if n, err = s.w.Write(b); err != nil {
n = len(b)
if s.crypt {
if b, err = AesEncrypt(b, []byte(cryptKey)); err != nil {
log.Println("encode crypt error:", err)
return
}
}
if _, err = s.w.Write(b); err != nil {
return
}
err = s.w.Flush()
@ -39,25 +94,42 @@ func (s *SnappyConn) Write(b []byte) (n int, err error) {
}
func (s *SnappyConn) Read(b []byte) (n int, err error) {
return s.r.Read(b)
if n, err = s.r.Read(b); err != nil {
return
}
if s.crypt {
var bs []byte
if bs, err = AesDecrypt(b[:n], []byte(cryptKey)); err != nil {
log.Println("decode crypt error:", err)
return
}
n = len(bs)
copy(b, bs)
}
return
}
type GzipConn struct {
w *gzip.Writer
r *gzip.Reader
w *gzip.Writer
r *gzip.Reader
crypt bool
}
func NewGzipConn(conn net.Conn) *GzipConn {
func NewGzipConn(conn net.Conn, crypt bool) *GzipConn {
c := new(GzipConn)
c.crypt = crypt
c.w = gzip.NewWriter(conn)
c.r, err = gzip.NewReader(conn)
fmt.Println("err", err)
//错误处理
return c
}
func (s *GzipConn) Write(b []byte) (n int, err error) {
if n, err = s.w.Write(b); err != nil || err == io.EOF {
err = s.w.Flush()
s.w.Close()
fmt.Println(string(b))
if n, err = s.w.Write(b); err != nil {
//err = s.w.Flush()
//s.w.Close()
return
}
err = s.w.Flush()
@ -65,7 +137,20 @@ func (s *GzipConn) Write(b []byte) (n int, err error) {
}
func (s *GzipConn) Read(b []byte) (n int, err error) {
return s.r.Read(b)
fmt.Println("read")
if n, err = s.r.Read(b); err != nil {
return
}
if s.crypt {
var bs []byte
if bs, err = AesDecrypt(b[:n], []byte(cryptKey)); err != nil {
log.Println("decode crypt error:", err)
return
}
n = len(bs)
copy(b, bs)
}
return
}
type Conn struct {
@ -80,72 +165,49 @@ func NewConn(conn net.Conn) *Conn {
//读取指定内容长度
func (s *Conn) ReadLen(len int) ([]byte, error) {
raw := make([]byte, 0)
buff := make([]byte, 1024)
c := 0
for {
clen, err := s.Read(buff)
if err != nil && err != io.EOF {
return raw, err
}
raw = append(raw, buff[:clen]...)
if c += clen; c >= len {
break
}
buf := make([]byte, len)
if n, err := s.Read(buf); err != nil || n != len {
return buf, errors.New("读取指定长度错误" + err.Error())
}
if c != len {
return raw, errors.New(fmt.Sprintf("已读取长度错误,已读取%dbyte需要读取%dbyte。", c, len))
}
return raw, nil
return buf, nil
}
//获取长度
func (s *Conn) GetLen() (int, error) {
val := make([]byte, 4)
_, err := s.Read(val)
if err != nil {
if _, err := s.Read(val); err != nil {
return 0, err
}
nlen := binary.LittleEndian.Uint32(val)
if nlen <= 0 {
return 0, errors.New("数据长度错误")
}
return int(nlen), nil
return GetLenByBytes(val)
}
//写入长度
func (s *Conn) WriteLen(buf []byte) (int, error) {
raw := bytes.NewBuffer([]byte{})
if err := binary.Write(raw, binary.LittleEndian, int32(len(buf))); err != nil {
log.Println(err)
var b []byte
if b, err = GetLenBytes(buf); err != nil {
return 0, err
}
if err = binary.Write(raw, binary.LittleEndian, buf); err != nil {
log.Println(err)
return 0, err
}
return s.Write(raw.Bytes())
return s.Write(b)
}
//读取flag
func (s *Conn) ReadFlag() (string, error) {
val := make([]byte, 4)
_, err := s.Read(val)
if err != nil {
if _, err := s.Read(val); err != nil {
return "", err
}
return string(val), err
}
//读取host 连接地址 压缩类型
func (s *Conn) GetHostFromConn() (typeStr string, host string, en, de int, err error) {
func (s *Conn) GetHostFromConn() (typeStr string, host string, en, de int, crypt bool, err error) {
retry:
ltype := make([]byte, 3)
if _, err = s.Read(ltype); err != nil {
return
}
if typeStr = string(ltype); typeStr == TEST_FLAG {
en, de = s.GetCompressTypeFromConn()
en, de, crypt = s.GetConnInfoFromConn()
goto retry
}
len, err := s.GetLen()
@ -209,16 +271,10 @@ func (s *Conn) GetHost() (method, address string, rb []byte, err error, r *http.
//压缩方式读
func (s *Conn) ReadFromCompress(b []byte, compress int) (int, error) {
switch compress {
case COMPRESS_GZIP_DECODE:
r, err := gzip.NewReader(s)
if err != nil {
return 0, err
}
return r.Read(b)
case COMPRESS_SNAPY_DECODE:
r := snappy.NewReader(s)
return r.Read(b)
case COMPRESS_NONE:
default:
return s.Read(b)
}
return 0, nil
@ -227,35 +283,30 @@ func (s *Conn) ReadFromCompress(b []byte, compress int) (int, error) {
//压缩方式写
func (s *Conn) WriteCompress(b []byte, compress int) (n int, err error) {
switch compress {
case COMPRESS_GZIP_ENCODE:
w := gzip.NewWriter(s)
if n, err = w.Write(b); err == nil {
w.Flush()
}
err = w.Close()
case COMPRESS_SNAPY_ENCODE:
w := snappy.NewBufferedWriter(s)
if n, err = w.Write(b); err == nil {
w.Flush()
}
err = w.Close()
case COMPRESS_NONE:
default:
n, err = s.Write(b)
}
return
}
//写压缩方式
func (s *Conn) WriteCompressType(en, de int) {
s.Write([]byte(strconv.Itoa(en) + strconv.Itoa(de)))
func (s *Conn) WriteConnInfo(en, de int, crypt bool) {
s.Write([]byte(strconv.Itoa(en) + strconv.Itoa(de) + GetStrByBool(crypt)))
}
//获取压缩方式
func (s *Conn) GetCompressTypeFromConn() (en, de int) {
buf := make([]byte, 2)
func (s *Conn) GetConnInfoFromConn() (en, de int, crypt bool) {
buf := make([]byte, 3)
s.Read(buf)
en, _ = strconv.Atoi(string(buf[0]))
de, _ = strconv.Atoi(string(buf[1]))
crypt = GetBoolByStr(string(buf[2]))
return
}
@ -290,3 +341,25 @@ func (s *Conn) wChan() (int, error) {
func (s *Conn) wTest() (int, error) {
return s.Write([]byte(TEST_FLAG))
}
//获取长度+内容
func GetLenBytes(buf []byte) (b []byte, err error) {
raw := bytes.NewBuffer([]byte{})
if err = binary.Write(raw, binary.LittleEndian, int32(len(buf))); err != nil {
return
}
if err = binary.Write(raw, binary.LittleEndian, buf); err != nil {
return
}
b = raw.Bytes()
return
}
//解析出长度
func GetLenByBytes(buf []byte) (int, error) {
nlen := binary.LittleEndian.Uint32(buf)
if nlen <= 0 {
return 0, errors.New("数据长度错误")
}
return int(nlen), nil
}

86
lib/crypt.go Normal file
View File

@ -0,0 +1,86 @@
package lib
import (
"bytes"
"crypto/aes"
"crypto/cipher"
"crypto/md5"
"encoding/hex"
"math/rand"
"time"
)
func AesEncrypt(origData, key []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
blockSize := block.BlockSize()
origData = PKCS5Padding(origData, blockSize)
// origData = ZeroPadding(origData, block.BlockSize())
blockMode := cipher.NewCBCEncrypter(block, key[:blockSize])
crypted := make([]byte, len(origData))
// 根据CryptBlocks方法的说明如下方式初始化crypted也可以
// crypted := origData
blockMode.CryptBlocks(crypted, origData)
return crypted, nil
}
func AesDecrypt(crypted, key []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
blockSize := block.BlockSize()
blockMode := cipher.NewCBCDecrypter(block, key[:blockSize])
origData := make([]byte, len(crypted))
// origData := crypted
blockMode.CryptBlocks(origData, crypted)
origData = PKCS5UnPadding(origData)
// origData = ZeroUnPadding(origData)
return origData, nil
}
func ZeroPadding(ciphertext []byte, blockSize int) []byte {
padding := blockSize - len(ciphertext)%blockSize
padtext := bytes.Repeat([]byte{0}, padding)
return append(ciphertext, padtext...)
}
func ZeroUnPadding(origData []byte) []byte {
length := len(origData)
unpadding := int(origData[length-1])
return origData[:(length - unpadding)]
}
func PKCS5Padding(ciphertext []byte, blockSize int) []byte {
padding := blockSize - len(ciphertext)%blockSize
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
return append(ciphertext, padtext...)
}
func PKCS5UnPadding(origData []byte) []byte {
length := len(origData)
// 去掉最后一个字节 unpadding 次
unpadding := int(origData[length-1])
return origData[:(length - unpadding)]
}
//生成32位md5字串
func Md5(s string) string {
h := md5.New()
h.Write([]byte(s))
return hex.EncodeToString(h.Sum(nil))
}
//生成随机验证密钥
func GetRandomString(l int) string {
str := "0123456789abcdefghijklmnopqrstuvwxyz"
bytes := []byte(str)
result := []byte{}
r := rand.New(rand.NewSource(time.Now().UnixNano()))
for i := 0; i < l; i++ {
result = append(result, bytes[r.Intn(len(bytes))])
}
return string(result)
}

318
lib/file.go Normal file
View File

@ -0,0 +1,318 @@
package lib
import (
"encoding/csv"
"encoding/json"
"errors"
"io/ioutil"
"log"
"os"
"strconv"
)
type TaskList struct {
TcpPort int //服务端与客户端通信端口
Mode string //启动方式
Target string //目标
VerifyKey string //flag
U string //socks5验证用户名
P string //socks5验证密码
Compress string //压缩方式
Start int //是否开启
IsRun int //是否在运行
ClientStatus int //客户端状态
Crypt string //是否加密
}
type HostList struct {
Vkey string //服务端与客户端通信端口
Host string //启动方式
Target string //目标
}
func NewCsv(path string, bridge *Tunnel, runList map[string]interface{}) *Csv {
c := new(Csv)
c.Path = path
c.Bridge = bridge
c.RunList = runList
return c
}
type Csv struct {
Tasks []*TaskList
Path string
Bridge *Tunnel
RunList map[string]interface{}
Hosts []*HostList //域名列表
}
func (s *Csv) Init() {
s.LoadTaskFromCsv()
s.LoadHostFromCsv()
}
func (s *Csv) StoreTasksToCsv() {
// 创建文件
csvFile, err := os.Create(s.Path + "tasks.csv")
if err != nil {
log.Fatalf(err.Error())
}
defer csvFile.Close()
writer := csv.NewWriter(csvFile)
for _, task := range s.Tasks {
record := []string{
strconv.Itoa(task.TcpPort),
task.Mode,
task.Target,
task.VerifyKey,
task.U,
task.P,
task.Compress,
strconv.Itoa(task.Start),
task.Crypt,
}
err := writer.Write(record)
if err != nil {
log.Fatalf(err.Error())
}
}
writer.Flush()
}
func (s *Csv) LoadTaskFromCsv() {
// 打开文件
file, err := os.Open(s.Path + "tasks.csv")
if err != nil {
panic(err)
}
defer file.Close()
// 获取csv的reader
reader := csv.NewReader(file)
// 设置FieldsPerRecord为-1
reader.FieldsPerRecord = -1
// 读取文件中所有行保存到slice中
records, err := reader.ReadAll()
if err != nil {
panic(err)
}
var tasks []*TaskList
// 将每一行数据保存到内存slice中
for _, item := range records {
tcpPort, _ := strconv.Atoi(item[0])
Start, _ := strconv.Atoi(item[7])
post := &TaskList{
TcpPort: tcpPort,
Mode: item[1],
Target: item[2],
VerifyKey: item[3],
U: item[4],
P: item[5],
Compress: item[6],
Start: Start,
Crypt: item[8],
}
tasks = append(tasks, post)
}
s.Tasks = tasks
}
func (s *Csv) StoreHostToCsv() {
// 创建文件
csvFile, err := os.Create(s.Path + "hosts.csv")
if err != nil {
panic(err)
}
defer csvFile.Close()
// 获取csv的Writer
writer := csv.NewWriter(csvFile)
// 将map中的Post转换成slice因为csv的Write需要slice参数
// 并写入csv文件
for _, host := range s.Hosts {
record := []string{
host.Host,
host.Target,
host.Vkey,
}
err1 := writer.Write(record)
if err1 != nil {
panic(err1)
}
}
// 确保所有内存数据刷到csv文件
writer.Flush()
}
func (s *Csv) LoadHostFromCsv() {
// 打开文件
file, err := os.Open(s.Path + "hosts.csv")
if err != nil {
panic(err)
}
defer file.Close()
// 获取csv的reader
reader := csv.NewReader(file)
// 设置FieldsPerRecord为-1
reader.FieldsPerRecord = -1
// 读取文件中所有行保存到slice中
records, err := reader.ReadAll()
if err != nil {
panic(err)
}
var hosts []*HostList
// 将每一行数据保存到内存slice中
for _, item := range records {
post := &HostList{
Vkey: item[2],
Host: item[0],
Target: item[1],
}
hosts = append(hosts, post)
}
s.Hosts = hosts
}
func (s *Csv) GetTaskList(start, length int, typeVal string) ([]*TaskList, int) {
list := make([]*TaskList, 0)
var cnt int
for _, v := range s.Tasks {
if v.Mode != typeVal {
continue
}
cnt++
if start--; start < 0 {
if length--; length > 0 {
if _, ok := s.RunList[v.VerifyKey]; ok {
v.IsRun = 1
} else {
v.IsRun = 0
}
if s, ok := s.Bridge.signalList[getverifyval(v.VerifyKey)]; ok {
if s.Len() > 0 {
v.ClientStatus = 1
} else {
v.ClientStatus = 0
}
} else {
v.ClientStatus = 0
}
list = append(list, v)
}
}
}
return list, cnt
}
func (s *Csv) NewTask(t *TaskList) {
s.Tasks = append(s.Tasks, t)
s.StoreTasksToCsv()
}
func (s *Csv) UpdateTask(t *TaskList) error {
for k, v := range s.Tasks {
if v.VerifyKey == t.VerifyKey {
s.Tasks = append(s.Tasks[:k], s.Tasks[k+1:]...)
s.Tasks = append(s.Tasks, t)
s.StoreTasksToCsv()
return nil
}
}
//TODO:待测试
return errors.New("不存在")
}
func (s *Csv) AddRunList(vKey string, svr interface{}) {
s.RunList[vKey] = svr
}
func (s *Csv) DelRunList(vKey string) {
delete(s.RunList, vKey)
}
func (s *Csv) DelTask(vKey string) error {
for k, v := range s.Tasks {
if v.VerifyKey == vKey {
s.Tasks = append(s.Tasks[:k], s.Tasks[k+1:]...)
s.StoreTasksToCsv()
return nil
}
}
return errors.New("不存在")
}
func (s *Csv) GetTask(vKey string) (v *TaskList, err error) {
for _, v = range s.Tasks {
if v.VerifyKey == vKey {
return
}
}
err = errors.New("未找到")
return
}
func (s *Csv) DelHost(host string) error {
for k, v := range s.Hosts {
if v.Host == host {
s.Hosts = append(s.Hosts[:k], s.Hosts[k+1:]...)
s.StoreHostToCsv()
return nil
}
}
return errors.New("不存在")
}
func (s *Csv) NewHost(t *HostList) {
s.Hosts = append(s.Hosts, t)
s.StoreHostToCsv()
}
func (s *Csv) GetHostList(start, length int, vKey string) ([]*HostList, int) {
list := make([]*HostList, 0)
var cnt int
for _, v := range s.Hosts {
if v.Vkey == vKey {
cnt++
if start--; start < 0 {
if length--; length > 0 {
list = append(list, v)
}
}
}
}
return list, cnt
}
type Site struct {
Host string
Url string
Port int
}
type Config struct {
SiteList []Site
Replace int
}
type JsonStruct struct {
}
func NewJsonStruct() *JsonStruct {
return &JsonStruct{}
}
func (jst *JsonStruct) Load(filename string) (Config, error) {
data, err := ioutil.ReadFile(filename)
config := Config{}
if err != nil {
return config, errors.New("配置文件打开错误")
}
err = json.Unmarshal(data, &config)
if err != nil {
return config, errors.New("配置文件解析错误")
}
return config, nil
}

View File

@ -21,13 +21,17 @@ var (
p = flag.String("p", "", "socks5验证密码")
compress = flag.String("compress", "", "数据压缩方式gzip|snappy")
serverAddr = flag.String("server", "", "服务器地址ip:端口")
crypt = flag.String("crypt", "", "是否加密(1|0)")
config Config
err error
RunList map[string]interface{} //运行中的任务
bridge *Tunnel
CsvDb *Csv
//crypt = GetBoolNoErrFromConfig("crypt")
)
const cryptKey = "1234567812345678"
func init() {
RunList = make(map[string]interface{})
}
@ -52,7 +56,7 @@ func InitMode() {
log.Fatalln("服务端开启失败", err)
}
log.Println("服务端启动监听tcp服务端端口", *TcpPort)
if svr := newMode(*rpMode, bridge, *httpPort, *tunnelTarget, *u, *p, en, de, *verifyKey); svr != nil {
if svr := newMode(*rpMode, bridge, *httpPort, *tunnelTarget, *u, *p, en, de, *verifyKey, *crypt); svr != nil {
reflect.ValueOf(svr).MethodByName("Start").Call(nil)
} else {
log.Fatalln("启动模式不正确")
@ -71,29 +75,33 @@ func InitFromCsv() {
}
}
func newMode(mode string, bridge *Tunnel, httpPort int, tunnelTarget string, u string, p string, enCompress int, deCompress int, vkey string) interface{} {
if u == "" || p == "" { //如果web管理中设置了用户名和密码,则覆盖配置文件
func newMode(mode string, bridge *Tunnel, httpPort int, tunnelTarget string, u string, p string, enCompress int, deCompress int, vkey string, crypt string) interface{} {
if u == "" || p == "" { //如果web管理或者命令中设置了用户名和密码,则覆盖配置文件
u = beego.AppConfig.String("auth.user")
p = beego.AppConfig.String("auth.password")
}
if crypt == "" { //如果web管理或者命令中设置了是否加密则覆盖配置文件
crypt = beego.AppConfig.String("crypt")
}
bCrypt := GetBoolByStr(crypt)
switch mode {
case "httpServer":
return NewHttpModeServer(httpPort, bridge, enCompress, deCompress, vkey)
return NewHttpModeServer(httpPort, bridge, enCompress, deCompress, vkey, bCrypt)
case "tunnelServer":
return NewTunnelModeServer(httpPort, tunnelTarget, ProcessTunnel, bridge, enCompress, deCompress, vkey, u, p)
return NewTunnelModeServer(httpPort, tunnelTarget, ProcessTunnel, bridge, enCompress, deCompress, vkey, u, p, bCrypt)
case "sock5Server":
return NewSock5ModeServer(httpPort, u, p, bridge, enCompress, deCompress, vkey)
return NewSock5ModeServer(httpPort, u, p, bridge, enCompress, deCompress, vkey, bCrypt)
case "httpProxyServer":
return NewTunnelModeServer(httpPort, tunnelTarget, ProcessHttp, bridge, enCompress, deCompress, vkey, u, p)
return NewTunnelModeServer(httpPort, tunnelTarget, ProcessHttp, bridge, enCompress, deCompress, vkey, u, p, bCrypt)
case "udpServer":
return NewUdpModeServer(httpPort, tunnelTarget, bridge, enCompress, deCompress, vkey)
return NewUdpModeServer(httpPort, tunnelTarget, bridge, enCompress, deCompress, vkey, bCrypt)
case "webServer":
InitCsvDb()
return NewWebServer(bridge)
case "hostServer":
return NewHostServer()
return NewHostServer(bCrypt)
case "httpHostServer":
return NewTunnelModeServer(httpPort, tunnelTarget, ProcessHost, bridge, enCompress, deCompress, vkey, u, p)
return NewTunnelModeServer(httpPort, tunnelTarget, ProcessHost, bridge, enCompress, deCompress, vkey, u, p, bCrypt)
}
return nil
}
@ -119,7 +127,7 @@ func StopServer(cFlag string) error {
func AddTask(t *TaskList) error {
de, en := getCompressType(t.Compress)
if svr := newMode(t.Mode, bridge, t.TcpPort, t.Target, t.U, t.P, en, de, t.VerifyKey); svr != nil {
if svr := newMode(t.Mode, bridge, t.TcpPort, t.Target, t.U, t.P, en, de, t.VerifyKey, t.Crypt); svr != nil {
RunList[t.VerifyKey] = svr
go func() {
err := reflect.ValueOf(svr).MethodByName("Start").Call(nil)[0]

View File

@ -36,15 +36,17 @@ type HttpModeServer struct {
enCompress int
deCompress int
vKey string
crypt bool
}
func NewHttpModeServer(httpPort int, bridge *Tunnel, enCompress int, deCompress int, vKey string) *HttpModeServer {
func NewHttpModeServer(httpPort int, bridge *Tunnel, enCompress int, deCompress int, vKey string, crypt bool) *HttpModeServer {
s := new(HttpModeServer)
s.bridge = bridge
s.httpPort = httpPort
s.enCompress = enCompress
s.deCompress = deCompress
s.vKey = vKey
s.crypt = crypt
return s
}
@ -90,7 +92,7 @@ func (s *HttpModeServer) writeRequest(r *http.Request, conn *Conn) error {
return err
}
conn.wSign()
conn.WriteCompressType(s.enCompress, s.deCompress)
conn.WriteConnInfo(s.enCompress, s.deCompress, s.crypt)
c, err := conn.WriteCompress(raw, s.enCompress)
if err != nil {
return err
@ -152,9 +154,10 @@ type TunnelModeServer struct {
basicUser string
basicPassword string
vKey string
crypt bool
}
func NewTunnelModeServer(httpPort int, tunnelTarget string, process process, bridge *Tunnel, enCompress, deCompress int, vKey, basicUser, basicPasswd string) *TunnelModeServer {
func NewTunnelModeServer(httpPort int, tunnelTarget string, process process, bridge *Tunnel, enCompress, deCompress int, vKey, basicUser, basicPasswd string, crypt bool) *TunnelModeServer {
s := new(TunnelModeServer)
s.httpPort = httpPort
s.bridge = bridge
@ -165,6 +168,7 @@ func NewTunnelModeServer(httpPort int, tunnelTarget string, process process, bri
s.vKey = vKey
s.basicUser = basicUser
s.basicPassword = basicPasswd
s.crypt = crypt
return s
}
@ -202,7 +206,7 @@ func (s *TunnelModeServer) Close() error {
//tcp隧道模式
func ProcessTunnel(c *Conn, s *TunnelModeServer) error {
link, err := s.bridge.GetTunnel(getverifyval(s.vKey), s.enCompress, s.deCompress)
link, err := s.bridge.GetTunnel(getverifyval(s.vKey), s.enCompress, s.deCompress, s.crypt)
if err != nil {
log.Println(err)
c.Close()
@ -214,8 +218,8 @@ func ProcessTunnel(c *Conn, s *TunnelModeServer) error {
log.Println(err)
return err
}
go relay(link, c, s.enCompress)
relay(c, link, s.deCompress)
go relay(link, c, s.enCompress, s.crypt)
relay(c, link, s.deCompress, s.crypt)
return nil
}
@ -229,7 +233,7 @@ func ProcessHttp(c *Conn, s *TunnelModeServer) error {
if err := s.auth(r, c); err != nil {
return err
}
link, err := s.bridge.GetTunnel(getverifyval(s.vKey), s.enCompress, s.deCompress)
link, err := s.bridge.GetTunnel(getverifyval(s.vKey), s.enCompress, s.deCompress, s.crypt)
if err != nil {
log.Println(err)
c.Close()
@ -246,8 +250,8 @@ func ProcessHttp(c *Conn, s *TunnelModeServer) error {
} else {
link.WriteCompress(rb, s.enCompress)
}
go relay(link, c, s.enCompress)
relay(c, link, s.deCompress)
go relay(link, c, s.enCompress, s.crypt)
relay(c, link, s.deCompress, s.crypt)
return nil
}
@ -267,7 +271,7 @@ func ProcessHost(c *Conn, s *TunnelModeServer) error {
return err
}
de, en := getCompressType(task.Compress)
link, err := s.bridge.GetTunnel(getverifyval(host.Vkey), en, de)
link, err := s.bridge.GetTunnel(getverifyval(host.Vkey), en, de, s.crypt)
if err != nil {
log.Println(err)
c.Close()
@ -284,8 +288,8 @@ func ProcessHost(c *Conn, s *TunnelModeServer) error {
} else {
link.WriteCompress(rb, en)
}
go relay(link, c, en)
relay(c, link, de)
go relay(link, c, en, s.crypt)
relay(c, link, de, s.crypt)
return nil
}
@ -324,6 +328,7 @@ func NewWebServer(bridge *Tunnel) *WebServer {
//host
type HostServer struct {
crypt bool
}
//开始
@ -331,9 +336,10 @@ func (s *HostServer) Start() error {
return nil
}
//TODOhost模式的客户端无需指定和监听端口等,此处有待优化
func NewHostServer() *HostServer {
//TODOhost模式的客户端无需指定和监听端口等
func NewHostServer(crypt bool) *HostServer {
s := new(HostServer)
s.crypt = crypt
return s
}

View File

@ -53,6 +53,7 @@ type Sock5ModeServer struct {
isVerify bool
listener net.Listener
vKey string
crypt bool
}
func (s *Sock5ModeServer) handleRequest(c net.Conn) {
@ -136,7 +137,7 @@ func (s *Sock5ModeServer) doConnect(c net.Conn, command uint8) (proxyConn *Conn,
binary.Read(c, binary.BigEndian, &port)
// connect to host
addr := net.JoinHostPort(host, strconv.Itoa(int(port)))
client, err := s.bridge.GetTunnel(getverifyval(s.vKey), s.enCompress, s.deCompress)
client, err := s.bridge.GetTunnel(getverifyval(s.vKey), s.enCompress, s.deCompress, s.crypt)
if err != nil {
log.Println(err)
client.Close()
@ -159,8 +160,8 @@ func (s *Sock5ModeServer) handleConnect(c net.Conn) {
log.Println(err)
c.Close()
} else {
go relay(proxyConn, NewConn(c), s.enCompress)
go relay(NewConn(c), proxyConn, s.deCompress)
go relay(proxyConn, NewConn(c), s.enCompress, s.crypt)
go relay(NewConn(c), proxyConn, s.deCompress, s.crypt)
}
}
@ -192,8 +193,8 @@ func (s *Sock5ModeServer) handleUDP(c net.Conn) {
if err != nil {
c.Close()
} else {
go relay(proxyConn, NewConn(c), s.enCompress)
go relay(NewConn(c), proxyConn, s.deCompress)
go relay(proxyConn, NewConn(c), s.enCompress, s.crypt)
go relay(NewConn(c), proxyConn, s.deCompress, s.crypt)
}
}
@ -290,7 +291,7 @@ func (s *Sock5ModeServer) Close() error {
return s.listener.Close()
}
func NewSock5ModeServer(httpPort int, u, p string, brige *Tunnel, enCompress int, deCompress int, vKey string) *Sock5ModeServer {
func NewSock5ModeServer(httpPort int, u, p string, brige *Tunnel, enCompress int, deCompress int, vKey string, crypt bool) *Sock5ModeServer {
s := new(Sock5ModeServer)
s.httpPort = httpPort
s.bridge = brige
@ -304,5 +305,6 @@ func NewSock5ModeServer(httpPort int, u, p string, brige *Tunnel, enCompress int
s.enCompress = enCompress
s.deCompress = deCompress
s.vKey = vKey
s.crypt = crypt
return s
}

View File

@ -141,7 +141,7 @@ retry:
}
//得到一个tcp隧道
func (s *Tunnel) GetTunnel(cFlag string, en, de int) (c *Conn, err error) {
func (s *Tunnel) GetTunnel(cFlag string, en, de int, crypt bool) (c *Conn, err error) {
if v, ok := s.tunnelList[cFlag]; !ok || v.Len() < 10 { //新建通道
go s.newChan(cFlag)
}
@ -154,7 +154,7 @@ retry:
c.Close()
goto retry
}
c.WriteCompressType(en, de)
c.WriteConnInfo(en, de, crypt)
return
}

View File

@ -18,9 +18,10 @@ type UdpModeServer struct {
enCompress int
deCompress int
vKey string
crypt bool
}
func NewUdpModeServer(udpPort int, tunnelTarget string, bridge *Tunnel, enCompress int, deCompress int, vKey string) *UdpModeServer {
func NewUdpModeServer(udpPort int, tunnelTarget string, bridge *Tunnel, enCompress int, deCompress int, vKey string, crypt bool) *UdpModeServer {
s := new(UdpModeServer)
s.udpPort = udpPort
s.tunnelTarget = tunnelTarget
@ -29,6 +30,7 @@ func NewUdpModeServer(udpPort int, tunnelTarget string, bridge *Tunnel, enCompre
s.enCompress = enCompress
s.deCompress = deCompress
s.vKey = vKey
s.crypt = crypt
return s
}
@ -57,7 +59,7 @@ func (s *UdpModeServer) Start() error {
func (s *UdpModeServer) process(addr *net.UDPAddr, data []byte) {
fmt.Println(addr.String())
fmt.Println(string(data))
conn, err := s.bridge.GetTunnel(getverifyval(s.vKey), s.enCompress, s.deCompress)
conn, err := s.bridge.GetTunnel(getverifyval(s.vKey), s.enCompress, s.deCompress, s.crypt)
if err != nil {
log.Println(err)
return

View File

@ -3,18 +3,12 @@ package lib
import (
"bufio"
"bytes"
"compress/gzip"
"crypto/md5"
"encoding/base64"
"encoding/binary"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"io"
"io/ioutil"
"log"
"math/rand"
"net"
"net/http"
"net/http/httputil"
@ -22,19 +16,25 @@ import (
"regexp"
"strconv"
"strings"
"time"
"sync"
)
var (
disabledRedirect = errors.New("disabled redirect.")
bufPool = &sync.Pool{
New: func() interface{} {
return make([]byte, 32*1024)
},
}
)
//pool 实现
type bufType [32 * 1024]byte
const (
COMPRESS_NONE = iota
COMPRESS_NONE_ENCODE = iota
COMPRESS_NONE_DECODE
COMPRESS_SNAPY_ENCODE
COMPRESS_SNAPY_DECODE
COMPRESS_GZIP_ENCODE
COMPRESS_GZIP_DECODE
)
func BadRequest(w http.ResponseWriter) {
@ -134,83 +134,36 @@ func replaceHost(resp []byte) []byte {
return []byte(str)
}
func relay(in, out *Conn, compressType int) {
buf := make([]byte, 32*1024)
func relay(in, out *Conn, compressType int, crypt bool) {
fmt.Println(crypt)
switch compressType {
case COMPRESS_GZIP_ENCODE:
//TODO:GZIP压缩存在问题有待解决
w := gzip.NewWriter(in)
for {
n, err := out.Read(buf)
if err != nil || err == io.EOF {
break
}
if _, err = w.Write(buf[:n]); err != nil {
break
}
if err = w.Flush(); err != nil {
log.Println(err)
break
}
}
w.Close()
case COMPRESS_SNAPY_ENCODE:
io.Copy(NewSnappyConn(in.conn), out)
case COMPRESS_GZIP_DECODE:
io.Copy(in, NewGzipConn(out.conn))
copyBuffer(NewSnappyConn(in.conn, crypt), out)
case COMPRESS_SNAPY_DECODE:
io.Copy(in, NewSnappyConn(out.conn))
default:
io.Copy(in, out)
copyBuffer(in, NewSnappyConn(out.conn, crypt))
case COMPRESS_NONE_ENCODE:
copyBuffer(NewCryptConn(in.conn, crypt), out)
case COMPRESS_NONE_DECODE:
copyBuffer(in, NewCryptConn(out.conn, crypt))
}
out.Close()
in.Close()
}
type Site struct {
Host string
Url string
Port int
}
type Config struct {
SiteList []Site
Replace int
}
type JsonStruct struct {
}
func NewJsonStruct() *JsonStruct {
return &JsonStruct{}
}
func (jst *JsonStruct) Load(filename string) (Config, error) {
data, err := ioutil.ReadFile(filename)
config := Config{}
if err != nil {
return config, errors.New("配置文件打开错误")
}
err = json.Unmarshal(data, &config)
if err != nil {
return config, errors.New("配置文件解析错误")
}
return config, nil
}
//判断压缩方式
func getCompressType(compress string) (int, int) {
switch compress {
case "":
return COMPRESS_NONE, COMPRESS_NONE
case "gzip":
return COMPRESS_GZIP_DECODE, COMPRESS_GZIP_ENCODE
return COMPRESS_NONE_DECODE, COMPRESS_NONE_ENCODE
case "snappy":
return COMPRESS_SNAPY_DECODE, COMPRESS_SNAPY_ENCODE
default:
log.Fatalln("数据压缩格式错误")
}
return COMPRESS_NONE, COMPRESS_NONE
return COMPRESS_NONE_DECODE, COMPRESS_NONE_ENCODE
}
// 简单的一个校验值
//简单的一个校验值
func getverifyval(vkey string) string {
//单客户端模式
if *verifyKey != "" {
@ -219,6 +172,7 @@ func getverifyval(vkey string) string {
return Md5(vkey)
}
//验证
func verify(verifyKeyMd5 string) bool {
if *verifyKey != "" && getverifyval(*verifyKey) == verifyKeyMd5 {
return true
@ -233,6 +187,7 @@ func verify(verifyKeyMd5 string) bool {
return false
}
//get key by host from x
func getKeyByHost(host string) (h *HostList, t *TaskList, err error) {
for _, v := range CsvDb.Hosts {
if strings.Contains(host, v.Host) {
@ -245,25 +200,6 @@ func getKeyByHost(host string) (h *HostList, t *TaskList, err error) {
return
}
//生成32位md5字串
func Md5(s string) string {
h := md5.New()
h.Write([]byte(s))
return hex.EncodeToString(h.Sum(nil))
}
//生成随机验证密钥
func GetRandomString(l int) string {
str := "0123456789abcdefghijklmnopqrstuvwxyz"
bytes := []byte(str)
result := []byte{}
r := rand.New(rand.NewSource(time.Now().UnixNano()))
for i := 0; i < l; i++ {
result = append(result, bytes[r.Intn(len(bytes))])
}
return string(result)
}
//通过host获取对应的ip地址
func Gethostbyname(hostname string) string {
if !DomainCheck(hostname) {
@ -310,3 +246,58 @@ func checkAuth(r *http.Request, user, passwd string) bool {
}
return pair[0] == user && pair[1] == passwd
}
//get bool by str
func GetBoolByStr(s string) bool {
switch s {
case "1", "true":
return true
}
return false
}
//get str by bool
func GetStrByBool(b bool) string {
if b {
return "1"
}
return "0"
}
// io.copy的优化版读取buffer长度原为32*1024与snappy不同导致读取出的内容存在差异不利于解密
func copyBuffer(dst io.Writer, src io.Reader) (written int64, err error) {
// If the reader has a WriteTo method, use it to do the copy.
// Avoids an allocation and a copy.
if wt, ok := src.(io.WriterTo); ok {
return wt.WriteTo(dst)
}
// Similarly, if the writer has a ReadFrom method, use it to do the copy.
if rt, ok := dst.(io.ReaderFrom); ok {
return rt.ReadFrom(src)
}
buf := make([]byte, 65535)
for {
nr, er := src.Read(buf)
if nr > 0 {
nw, ew := dst.Write(buf[0:nr])
if nw > 0 {
written += int64(nw)
}
if ew != nil {
err = ew
break
}
if nr != nw {
err = io.ErrShortWrite
break
}
}
if er != nil {
if er != io.EOF {
err = er
}
break
}
}
return written, err
}

View File

@ -34,10 +34,16 @@
<label class="control-label">数据压缩方式</label>
<select class="form-control" name="compress">
<option value="">不压缩</option>
<option value="gzip">gzip压缩</option>
<option value="snappy">snappy</option>
</select>
</div>
<div class="form-group" id="compress">
<label class="control-label">是否加密传输</label>
<select class="form-control" name="crypt">
<option value="0">不加密</option>
<option value="1">加密</option>
</select>
</div>
<div class="form-group" id="u">
<label class="control-label">验证用户名(socks5HTTP代理模式)</label>
<input class="form-control" type="text" name="u" placeholder="不填则无需验证">

View File

@ -7,7 +7,7 @@
<input type="hidden" name="vKey" value="{{.t.VerifyKey}}">
<div class="form-group">
<label class="control-label">模式</label>
<select class="form-control" name="type" id="type">
<select class="form-control" name="type" id="type">
<option {{if eq "tunnelServer" .t.Mode}}selected{{end}} value="tunnelServer">tcp隧道</option>
<option {{if eq "udpServer" .t.Mode}}selected{{end}} value="udpServer">udp隧道</option>
<option {{if eq "sock5Server" .t.Mode}}selected{{end}} value="sock5Server">socks5代理</option>
@ -29,10 +29,16 @@
<label class="control-label">数据压缩方式(所有模式均支持)</label>
<select class="form-control" name="compress">
<option {{if eq "" .t.Compress}}selected{{end}} value="">不压缩</option>
<option {{if eq "gzip" .t.Compress}}selected{{end}} value="gzip">gzip压缩</option>
<option {{if eq "snappy" .t.Compress}}selected{{end}} value="snappy">snappy压缩</option>
</select>
</div>
<div class="form-group" id="compress">
<label class="control-label">是否加密传输(所有模式均支持)</label>
<select class="form-control" name="crypt">
<option {{if eq "0" .t.Crypt}}selected{{end}} value="0">不加密</option>
<option {{if eq "1" .t.Crypt}}selected{{end}} value="1">加密</option>
</select>
</div>
<div class="form-group" id="u">
<label class="control-label">验证用户名(socks5HTTP代理模式)</label>
<input class="form-control" value="{{.t.U}}" type="text" name="u"
@ -56,7 +62,7 @@
</main>
<script>
var arr = []
arr["all"] = ["type", "port", "compress", "u", "p","target"]
arr["all"] = ["type", "port", "compress", "u", "p", "target"]
arr["tunnelServer"] = ["type", "port", "target", "compress"]
arr["udpServer"] = ["type", "port", "target", "compress"]
arr["sock5Server"] = ["type", "port", "compress", "u", "p"]
@ -72,6 +78,7 @@
$("#" + arr[o][i]).css("display", "block")
}
}
$(function () {
resetForm()
$("#type").on("change", function () {

View File

@ -10,6 +10,7 @@
<th>内网目标</th>
<th>多客户端模式客户端执行命令</th>
<th>压缩方式</th>
<th>加密传输</th>
<th>用户名</th>
<th>密码</th>
<th>客户端状态</th>
@ -106,6 +107,7 @@
{data: 'Target'},
{data: 'VerifyKey'},
{data: 'Compress'},
{data: 'Crypt'},
{data: 'U'},
{data: 'P'},
{data: 'ClientStatus'},
@ -146,6 +148,16 @@
}
}
},
{
targets: -6,
render: function (data, type, row, meta) {
if (data == "0") {
return "不加密"
} else {
return "加密"
}
}
},
{
targets: 2,
render: function (data, type, row, meta) {