feature: MITM
This commit is contained in:
22
adapter/inbound/mitm.go
Normal file
22
adapter/inbound/mitm.go
Normal file
@ -0,0 +1,22 @@
|
||||
package inbound
|
||||
|
||||
import (
|
||||
"net"
|
||||
|
||||
C "github.com/Dreamacro/clash/constant"
|
||||
"github.com/Dreamacro/clash/context"
|
||||
"github.com/Dreamacro/clash/transport/socks5"
|
||||
)
|
||||
|
||||
// NewMitm receive mitm request and return MitmContext
|
||||
func NewMitm(target socks5.Addr, source net.Addr, userAgent string, conn net.Conn) *context.ConnContext {
|
||||
metadata := parseSocksAddr(target)
|
||||
metadata.NetWork = C.TCP
|
||||
metadata.Type = C.MITM
|
||||
metadata.UserAgent = userAgent
|
||||
if ip, port, err := parseAddr(source); err == nil {
|
||||
metadata.SrcIP = ip
|
||||
metadata.SrcPort = port
|
||||
}
|
||||
return context.NewConnContext(conn, metadata)
|
||||
}
|
@ -113,6 +113,10 @@ func (h *Http) shakeHand(metadata *C.Metadata, rw io.ReadWriter) error {
|
||||
tempHeaders["Proxy-Authorization"] = "Basic " + base64.StdEncoding.EncodeToString([]byte(auth))
|
||||
}
|
||||
|
||||
if metadata.Type == C.MITM {
|
||||
tempHeaders["Origin-Request-Source-Address"] = metadata.SourceAddress()
|
||||
}
|
||||
|
||||
for key, value := range tempHeaders {
|
||||
HeaderString += key + ": " + value + "\r\n"
|
||||
}
|
||||
|
50
adapter/outbound/mitm.go
Normal file
50
adapter/outbound/mitm.go
Normal file
@ -0,0 +1,50 @@
|
||||
package outbound
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/Dreamacro/clash/component/dialer"
|
||||
C "github.com/Dreamacro/clash/constant"
|
||||
)
|
||||
|
||||
type Mitm struct {
|
||||
*Base
|
||||
serverAddr *net.TCPAddr
|
||||
httpProxyClient *Http
|
||||
}
|
||||
|
||||
// DialContext implements C.ProxyAdapter
|
||||
func (m *Mitm) DialContext(ctx context.Context, metadata *C.Metadata, _ ...dialer.Option) (C.Conn, error) {
|
||||
c, err := net.DialTCP("tcp", nil, m.serverAddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
_ = c.SetKeepAlive(true)
|
||||
_ = c.SetKeepAlivePeriod(60 * time.Second)
|
||||
|
||||
metadata.Type = C.MITM
|
||||
|
||||
hc, err := m.httpProxyClient.StreamConnContext(ctx, c, metadata)
|
||||
if err != nil {
|
||||
_ = c.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewConn(hc, m), nil
|
||||
}
|
||||
|
||||
func NewMitm(serverAddr string) *Mitm {
|
||||
tcpAddr, _ := net.ResolveTCPAddr("tcp", serverAddr)
|
||||
http, _ := NewHttp(HttpOption{})
|
||||
return &Mitm{
|
||||
Base: &Base{
|
||||
name: "Mitm",
|
||||
tp: C.Mitm,
|
||||
},
|
||||
serverAddr: tcpAddr,
|
||||
httpProxyClient: http,
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user