tlsLayer

package
v1.2.4-beta.6 Latest Latest
Warning

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

Go to latest
Published: Nov 3, 2022 License: MIT Imports: 25 Imported by: 0

Documentation

Overview

Package tlsLayer provides facilities for tls, including uTls, sniffing and random certificate.

Sniffing can be a part of Tls Lazy Encrypt tech.

Index

Constants

This section is empty.

Variables

View Source
var ErrCAFileWrong = errors.New("ca file is somehow wrong")
View Source
var OnlyTest bool
View Source
var PDD bool //print tls detect detail

Functions

func GenerateRandomCertKeyFiles

func GenerateRandomCertKeyFiles(cfn, kfn string) error

会调用 GenerateRandomeCert_Key 来生成证书,并输出到文件

func GenerateRandomTLSCert

func GenerateRandomTLSCert() []tls.Certificate

会调用 GenerateRandomeCert_Key 来生成证书,并生成包含该证书的 []tls.Certificate

func GenerateRandomeCert_Key

func GenerateRandomeCert_Key() (certPEM []byte, keyPEM []byte)

使用 ecc p256 方式生成证书

func GetCertArrayFromFile

func GetCertArrayFromFile(certFile, keyFile string) (certArray []tls.Certificate, err error)

若 certFile, keyFile 有一项没给出,则会自动生成随机证书

func GetLastTlsRecordTailIndex

func GetLastTlsRecordTailIndex(p []byte) (last_cursor int, count int)

func GetMinVerFromExtra added in v1.2.3

func GetMinVerFromExtra(extra map[string]any) uint16

func GetTlsConfig added in v1.2.1

func GetTlsConfig(insecure, mustHasCert bool, alpn []string, host string, certConf *CertConf, minVer uint16) *tls.Config

func GetTlsRecordNextIndex

func GetTlsRecordNextIndex(p []byte) int

为-1表示 p长度不够长,无法获取到下一个tls记录

func GetUTlsConfig added in v1.2.1

func GetUTlsConfig(insecure bool, alpn []string, host string, certConf *CertConf, minVer uint16) utls.Config

func LoadCA added in v1.2.1

func LoadCA(caFile string) (cp *x509.CertPool, err error)

Types

type CertConf added in v1.2.1

type CertConf struct {
	CA                string
	CertFile, KeyFile string
}

type Client

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

func NewClient

func NewClient(host string, insecure bool, use_uTls bool, alpnList []string, certConf *CertConf, minver uint16) *Client

func (*Client) Handshake

func (c *Client) Handshake(underlay net.Conn) (tlsConn *Conn, err error)

type ComSniff

type ComSniff struct {
	IsTls            bool
	DefinitelyNotTLS bool

	SpecialCommandBytes []byte //目前规定,使用uuid作为special command

	Auther utils.UserAuther //为了在服务端能确认一串数据确实是有效的uuid,需要使用 UserHaser

	SniffedServerName string

	ShouldSniffAlpn bool
	SniffedAlpnList []string

	Isclient  bool //是否是tls拨号端
	Is_secure bool

	CantBeTLS13 bool //clienthello如果没有 supported_versions项,or 该项没有0304,则不可能协商出tls1.3。如果协商出了则是错误的;
	// contains filtered or unexported fields
}

func (*ComSniff) CommonDetect added in v1.2.2

func (cd *ComSniff) CommonDetect(p []byte, isRead bool, onlyForSni bool)

总之,如果读写都用同样的判断代码的话,客户端和服务端应该就能同步进行 相同的TLS判断。首包时p长度至少为1,非首包时p长度至少为3,否则会panic

func (*ComSniff) GetFailReason

func (c *ComSniff) GetFailReason() int

func (*ComSniff) HasHandshakePassed added in v1.2.2

func (c *ComSniff) HasHandshakePassed() bool

type Conn

type Conn struct {
	//*tls.Conn
	net.Conn
	// contains filtered or unexported fields
}

func (*Conn) GetAlpn

func (c *Conn) GetAlpn() string

return c.Conn.ConnectionState().NegotiatedProtocol

func (*Conn) GetRaw

func (c *Conn) GetRaw(tls_lazy_encrypt bool) *net.TCPConn

func (*Conn) GetSni

func (c *Conn) GetSni() string

func (*Conn) GetTeeConn

func (c *Conn) GetTeeConn() *TeeConn

直接获取TeeConn,仅用于已经确定肯定能获取到的情况

type DetectLazyWriter added in v1.2.2

type DetectLazyWriter struct {
	io.Writer
	ComSniff
}

DetectLazyWriter 对每个Read的数据进行分析,判断是否是tls流量, 并在合适时机写入lazy的特殊指令。

func (*DetectLazyWriter) SimpleWrite added in v1.2.2

func (dw *DetectLazyWriter) SimpleWrite(p []byte) (n int, err error)

直接写入,而不进行探测

func (*DetectLazyWriter) Write added in v1.2.2

func (dw *DetectLazyWriter) Write(p []byte) (n int, err error)

发现,数据基本就是 23 3 3, 22 3 3,22 3 1 , 20 3 3 一个首包不为23 3 3 的包往往会出现在 1184长度的包的后面,而且一般 1184长度的包 的开头是 22 3 3 0 122,且总是在Write里面发生. 所以可以直接推测这个就是握手包; 实测 22 3 3 0 122 开头的,无一例外都是 1184长度,且后面接多个 开头任意的 Write 也有一些特殊情况,比如 22 3 1 首部的包,往往是 517 长度,后面也会紧跟着一些首部不为 22/23 的 Write.

23 3 3 也是有可能 发生后面不为22/23的write,长度 不等. 我们和Read过滤一样,先过滤握手包,再找到 第一个23 3 1-3 的数据包.

总之,我们在客户端的 Write 操作,就是 外界试图使用我们的 Write 写入数据. 所以在socks5后面 使用的这个 Write, 应该是把 服务端的响应 写回 socks5,比如 serverhello 之类 服务端的 Write 操作,也是读 serverhello.

type DetectReader

type DetectReader struct {
	io.Reader

	ComSniff
}

DetectReader 对每个Read的数据进行分析,判断是否是tls流量

func (*DetectReader) Read

func (dr *DetectReader) Read(p []byte) (n int, err error)

总之,我们在客户端的 Read 操作,就是 我们试图使用 Read 读取客户的请求,然后试图发往 外界

 所以在socks5后面 使用的这个 Read,是读取客户端发送的请求,比如 clienthello之类
	服务端的 Read 操作,也是读 clienthello,因为我们总是判断客户传来的数据

type Recorder

type Recorder struct {
	Buflist []*bytes.Buffer
	// contains filtered or unexported fields
}

和TeeConn配合的是Recorder, 每次调用Write就会记录一个新Buffer

func NewRecorder

func NewRecorder() *Recorder

func (*Recorder) DigestAll

func (wr *Recorder) DigestAll()

打印内部所有包的前10字节

func (*Recorder) GetLast

func (wr *Recorder) GetLast() *bytes.Buffer

func (*Recorder) ReleaseBuffers

func (wr *Recorder) ReleaseBuffers()

调用时,要保证目前没有任何人 正在 Write,否则会报错

func (*Recorder) StartRecord

func (wr *Recorder) StartRecord()

StartRecord后,Recorder就会开始记录数据。默认Recorder就是开启状态;

所以此方法仅用于之前 Stop过

func (*Recorder) StopRecord

func (wr *Recorder) StopRecord()

停止记录后,Write方法将不产生任何开销

func (*Recorder) Write

func (wr *Recorder) Write(p []byte) (n int, err error)

每Write一遍, 就写入一个新的buffer, 使用 utils.GetBuf() 获取

type Server

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

func NewServer

func NewServer(host string, certConf *CertConf, isInsecure bool, alpnList []string, minver uint16) (*Server, error)

如 certFile, keyFile 有一项没给出,则会自动生成随机证书

func (*Server) Handshake

func (s *Server) Handshake(underlay net.Conn) (tlsConn *Conn, err error)

type SniffConn

type SniffConn struct {
	net.Conn //这个 Conn 在 SniffConn 中不会用到,只是为了能让 SniffConn 支持 net.Conn
	W        *DetectLazyWriter
	R        *DetectReader

	RawConn *net.TCPConn // 这个是为了让外界能够直接拿到底层的连接

}

用于 探测 承载数据是否使用了tls, 它先与 底层tcp连接 进行 数据传输,然后查看传输到内容

可以参考 https://www.baeldung.com/linux/tcpdump-capture-ssl-handshake

func NewSniffConn

func NewSniffConn(oldConn net.Conn, rw io.ReadWriter, isclient bool, is_secure bool, sniffedFirstPart *ComSniff) *SniffConn

可选两个参数传入,优先使用rw ,为nil的话 再使用oldConn,作为 SniffConn 的 Read 和Write的 具体调用的主体 is_secure 表示,是否使用更强的过滤手段(越强越浪费时间, 但是越安全)

func (*SniffConn) Read

func (cc *SniffConn) Read(p []byte) (int, error)

func (*SniffConn) ReadFrom

func (cc *SniffConn) ReadFrom(r io.Reader) (int64, error)

这个暂时没用到,先留着

func (*SniffConn) Write

func (cc *SniffConn) Write(p []byte) (int, error)

type TeeConn

type TeeConn struct {
	OldConn net.Conn

	TargetReader io.Reader
}

实现net.Conn,专门用于 tls 检测步骤 每次 Read TeeConn, 都会从OldConn进行Read,然后把Read到的数据同时写入 TargetWriter(NewTeeConn 的参数)

这个TeeConn设计时,专门用于 给 tls包一个 假的 net.Conn, 避免它 主动close我们的原Conn

tls的Read是我们要关心的,Write则没有必要套Tee

func NewTeeConn

func NewTeeConn(oldConn net.Conn, targetWriter io.Writer) *TeeConn

func (*TeeConn) Close

func (tc *TeeConn) Close() error

func (*TeeConn) LocalAddr

func (tc *TeeConn) LocalAddr() net.Addr

返回原Conn的地址

func (*TeeConn) Read

func (tc *TeeConn) Read(b []byte) (n int, err error)

使用我们的Tee功能进行Read

func (*TeeConn) RemoteAddr

func (tc *TeeConn) RemoteAddr() net.Addr

返回原Conn的地址

func (*TeeConn) SetDeadline

func (tc *TeeConn) SetDeadline(t time.Time) error

暂时先什么也不做。事实上,这里 如果deadline到期了 需要能够通知外界,

func (*TeeConn) SetReadDeadline

func (tc *TeeConn) SetReadDeadline(t time.Time) error

func (*TeeConn) SetWriteDeadline

func (tc *TeeConn) SetWriteDeadline(t time.Time) error

func (*TeeConn) Write

func (tc *TeeConn) Write(b []byte) (n int, err error)

直接使用原Conn发送

Jump to

Keyboard shortcuts

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