tlsLayer

package
v1.2.5 Latest Latest
Warning

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

Go to latest
Published: Dec 28, 2022 License: MIT Imports: 27 Imported by: 0

Documentation

Overview

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

Sniffing can be a part of Tls Lazy Encrypt tech.

Index

Constants

View Source
const (
	Tls_t = iota
	UTls_t
	ShadowTls_t
	ShadowTls2_t
)

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 CopyTls12Handshake added in v1.2.5

func CopyTls12Handshake(isSrcClient bool, dst, src net.Conn) error

isSrcClient is only for debug logging.

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 GetTlsConfig added in v1.2.1

func GetTlsConfig(mustHasCert bool, conf Conf) *tls.Config

func GetTlsRecordNextIndex

func GetTlsRecordNextIndex(p []byte) int

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

func GetUTlsConfig added in v1.2.1

func GetUTlsConfig(conf Conf) utls.Config

func LoadCA added in v1.2.1

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

func StrToCipherSuite added in v1.2.5

func StrToCipherSuite(str string) uint16

0 means illegal string

func StrToType added in v1.2.5

func StrToType(str string) int

func TypeToStr added in v1.2.5

func TypeToStr(t int) string

func WriteAppData added in v1.2.5

func WriteAppData(conn io.Writer, buf *bytes.Buffer, d []byte) (n int, err error)

func WriteAppDataHeader added in v1.2.5

func WriteAppDataHeader(w io.Writer, len int) (err error)

func WriteAppDataNoBuf added in v1.2.5

func WriteAppDataNoBuf(w io.Writer, d []byte) (n int, err error)

一般conn直接为tcp连接,而它是有系统缓存的,因此我们一般不需要特地创建一个缓存 写两遍之后在发出

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(conf Conf) *Client

func (*Client) Handshake

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

utls和tls时返回tlsLayer.Conn, shadowTls1时返回underlay, shadowTls2时返回 普通 net.Conn

type ComSniff

type ComSniff struct {
	IsTls            bool
	DefinitelyNotTLS bool

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

	Auther utils.UserAuthenticator //为了在服务端能确认一串数据确实是有效的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 Conf added in v1.2.5

type Conf struct {
	Host     string
	Insecure bool
	Minver   uint16
	Maxver   uint16
	AlpnList []string
	CertConf *CertConf

	Tls_type int

	RejectUnknownSni bool //only server
	CipherSuites     []uint16

	Extra map[string]any //用于shadowTls
}

func (Conf) IsShadowTls added in v1.2.5

func (tConf Conf) IsShadowTls() bool

type Conn

type Conn interface {
	net.Conn
	GetRaw(tls_lazy_encrypt bool) *net.TCPConn
	GetTeeConn() *TeeConn
	GetAlpn() string
	GetSni() string
}

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 FakeAppDataConn added in v1.2.5

type FakeAppDataConn struct {
	net.Conn

	OptionalReader          io.Reader
	OptionalReaderRemainLen int
	// contains filtered or unexported fields
}

读写都按tls application data 的格式走,其实就是加个包头. 实现 utils.MultiWriter

func (*FakeAppDataConn) Read added in v1.2.5

func (c *FakeAppDataConn) Read(p []byte) (n int, err error)

func (*FakeAppDataConn) Upstream added in v1.2.5

func (c *FakeAppDataConn) Upstream() any

func (*FakeAppDataConn) Write added in v1.2.5

func (c *FakeAppDataConn) Write(p []byte) (n int, err error)

func (*FakeAppDataConn) WriteBuffers added in v1.2.5

func (c *FakeAppDataConn) WriteBuffers(bss [][]byte) (int64, error)

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(conf Conf) (*Server, error)

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

func (*Server) Handshake

func (s *Server) Handshake(clientConn net.Conn) (result net.Conn, err error)

tls时返回 tlsLayer.Conn, shadowTls1时返回原 clientConn, shadowTls2时返回 FakeAppDataConn

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