Skip to content

Commit

Permalink
feature: MITM
Browse files Browse the repository at this point in the history
  • Loading branch information
xishang0128 committed Apr 3, 2024
1 parent e150b7d commit d2cb220
Show file tree
Hide file tree
Showing 21 changed files with 60 additions and 70 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ API.
## Credits
- [Dreamacro/clash](https://github.com/Dreamacro/clash)
- [metacubex/mihomo](https://github.com/metacubex/mihomo)
- [SagerNet/sing-box](https://github.com/SagerNet/sing-box)
- [riobard/go-shadowsocks2](https://github.com/riobard/go-shadowsocks2)
- [v2ray/v2ray-core](https://github.com/v2ray/v2ray-core)
Expand Down
17 changes: 8 additions & 9 deletions adapter/inbound/mitm.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,19 @@ package inbound
import (
"net"

C "github.com/Dreamacro/clash/constant"
"github.com/Dreamacro/clash/context"
"github.com/Dreamacro/clash/transport/socks5"
C "github.com/metacubex/mihomo/constant"
"github.com/metacubex/mihomo/transport/socks5"
)

// NewMitm receive mitm request and return MitmContext
func NewMitm(target socks5.Addr, source net.Addr, userAgent string, conn net.Conn) *context.ConnContext {
func NewMitm(target socks5.Addr, srcConn net.Conn, userAgent string, conn net.Conn, additions ...Addition) (net.Conn, *C.Metadata) {
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)
metadata.RawSrcAddr = srcConn.RemoteAddr()
metadata.RawDstAddr = srcConn.LocalAddr()
ApplyAdditions(metadata, WithSrcAddr(srcConn.RemoteAddr()), WithInAddr(conn.LocalAddr()))
ApplyAdditions(metadata, additions...)
return conn, metadata
}
4 changes: 2 additions & 2 deletions adapter/outbound/mitm.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import (
"net"
"time"

"github.com/Dreamacro/clash/component/dialer"
C "github.com/Dreamacro/clash/constant"
"github.com/metacubex/mihomo/component/dialer"
C "github.com/metacubex/mihomo/constant"
)

type Mitm struct {
Expand Down
2 changes: 1 addition & 1 deletion common/cert/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package cert
import (
"crypto/tls"

"github.com/Dreamacro/clash/component/trie"
"github.com/metacubex/mihomo/component/trie"
)

// DomainTrieCertsStorage cache wildcard certificates
Expand Down
2 changes: 1 addition & 1 deletion config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
"strings"
"time"

rewrites "github.com/Dreamacro/clash/rewrite"
rewrites "github.com/metacubex/mihomo/rewrite"
"github.com/metacubex/mihomo/adapter"
"github.com/metacubex/mihomo/adapter/outbound"
"github.com/metacubex/mihomo/adapter/outboundgroup"
Expand Down
6 changes: 2 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ require (
github.com/go-chi/chi/v5 v5.0.12
github.com/go-chi/cors v1.2.1
github.com/go-chi/render v1.0.3
github.com/gofrs/uuid v4.4.0+incompatible
github.com/gobwas/ws v1.3.2
github.com/gofrs/uuid v4.4.0+incompatible
github.com/gofrs/uuid/v5 v5.0.0
github.com/insomniacslk/dhcp v0.0.0-20240227161007-c728f5dd21c8
github.com/klauspost/cpuid/v2 v2.2.7
Expand Down Expand Up @@ -46,15 +46,14 @@ require (
github.com/stretchr/testify v1.9.0
github.com/wk8/go-ordered-map/v2 v2.1.8
github.com/zhangyunhao116/fastrand v0.3.0
go.etcd.io/bbolt v1.3.7
go.uber.org/automaxprocs v1.5.3
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba
golang.org/x/crypto v0.21.0
golang.org/x/exp v0.0.0-20240222234643-814bf88cf225
golang.org/x/net v0.22.0
golang.org/x/sync v0.6.0
golang.org/x/sys v0.18.0
golang.org/x/text v0.12.0
golang.org/x/text v0.14.0
google.golang.org/protobuf v1.33.0
gopkg.in/yaml.v3 v3.0.1
lukechampine.com/blake3 v1.2.1
Expand Down Expand Up @@ -108,7 +107,6 @@ require (
gitlab.com/yawning/bsaes.git v0.0.0-20190805113838-0a714cd429ec // indirect
go.uber.org/mock v0.4.0 // indirect
golang.org/x/mod v0.15.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/time v0.5.0 // indirect
golang.org/x/tools v0.18.0 // indirect
)
Expand Down
3 changes: 2 additions & 1 deletion hub/executor/executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ func updateListeners(general *config.General, listeners map[string]C.InboundList
bindAddress := general.BindAddress
listener.SetBindAddress(bindAddress)
listener.ReCreateHTTP(general.Port, tunnel.Tunnel)
listener.ReCreateMitm(general.MitmPort, tunnel.Tunnel)
listener.ReCreateSocks(general.SocksPort, tunnel.Tunnel)
listener.ReCreateRedir(general.RedirPort, tunnel.Tunnel)
if !features.CMFA {
Expand Down Expand Up @@ -521,7 +522,7 @@ func updateIPTables(cfg *config.Config) {
}

func updateMitm(mitm *config.Mitm) {
listener.ReCreateMitm(mitm.Port, tunnel.TCPIn())
listener.ReCreateMitm(mitm.Port, tunnel.Tunnel)
tunnel.UpdateRewrites(mitm.Rules)
}

Expand Down
2 changes: 1 addition & 1 deletion hub/route/configs.go
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ func patchConfigs(w http.ResponseWriter, r *http.Request) {
P.ReCreateShadowSocks(pointerOrDefaultString(general.ShadowSocksConfig, ports.ShadowSocksConfig), tunnel.Tunnel)
P.ReCreateVmess(pointerOrDefaultString(general.VmessConfig, ports.VmessConfig), tunnel.Tunnel)
P.ReCreateTuic(pointerOrDefaultTuicServer(general.TuicServer, P.LastTuicConf), tunnel.Tunnel)
P.ReCreateMitm(pointerOrDefault(general.MitmPort, ports.MitmPort), tcpIn)
P.ReCreateMitm(pointerOrDefault(general.MitmPort, ports.MitmPort), tunnel.Tunnel)

if general.Mode != nil {
tunnel.SetMode(*general.Mode)
Expand Down
2 changes: 1 addition & 1 deletion listener/http/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ func HandleConn(c net.Conn, tunnel C.Tunnel, cache *lru.LruCache[string, bool],
_ = conn.Close()
}

func authenticate(request *http.Request, cache *lru.LruCache[string, bool]) *http.Response {
func Authenticate(request *http.Request, cache *lru.LruCache[string, bool]) *http.Response {
authenticator := authStore.Authenticator()
if inbound.SkipAuthRemoteAddress(request.RemoteAddr) {
authenticator = nil
Expand Down
4 changes: 2 additions & 2 deletions listener/http/upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ func handleUpgrade(conn net.Conn, request *http.Request, tunnel C.Tunnel, additi
}
}

func HandleUpgradeY(localConn net.Conn, serverConn *N.BufferedConn, request *http.Request, in chan<- C.ConnContext) (resp *http.Response) {
func HandleUpgradeY(localConn net.Conn, serverConn *N.BufferedConn, request *http.Request, tunnel C.Tunnel, additions ...inbound.Addition) (resp *http.Response) {
removeProxyHeaders(request.Header)
RemoveExtraHTTPHostPort(request)

Expand All @@ -110,7 +110,7 @@ func HandleUpgradeY(localConn net.Conn, serverConn *N.BufferedConn, request *htt

left, right := net.Pipe()

in <- inbound.NewHTTP(dstAddr, localConn.RemoteAddr(), right)
go tunnel.HandleTCPConn(inbound.NewHTTP(dstAddr, localConn, right, additions...))

serverConn = N.NewBufferedConn(left)

Expand Down
9 changes: 5 additions & 4 deletions listener/listener.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,13 @@ import (

"golang.org/x/exp/slices"

"github.com/Dreamacro/clash/listener/mitm"
"github.com/metacubex/mihomo/common/cert"
"github.com/metacubex/mihomo/component/ebpf"
C "github.com/metacubex/mihomo/constant"
"github.com/metacubex/mihomo/listener/autoredir"
LC "github.com/metacubex/mihomo/listener/config"
"github.com/metacubex/mihomo/listener/http"
"github.com/metacubex/mihomo/listener/mitm"
"github.com/metacubex/mihomo/listener/mixed"
"github.com/metacubex/mihomo/listener/redir"
embedSS "github.com/metacubex/mihomo/listener/shadowsocks"
Expand All @@ -33,7 +34,7 @@ import (
LT "github.com/metacubex/mihomo/listener/tunnel"
"github.com/metacubex/mihomo/log"

rewrites "github.com/Dreamacro/clash/rewrite"
rewrites "github.com/metacubex/mihomo/rewrite"
"github.com/samber/lo"
)

Expand Down Expand Up @@ -758,7 +759,7 @@ func PatchInboundListeners(newListenerMap map[string]C.InboundListener, tunnel C
}
}

func ReCreateMitm(port int, tcpIn chan<- C.ConnContext) {
func ReCreateMitm(port int, tunnel C.Tunnel) {
mitmMux.Lock()
defer mitmMux.Unlock()

Expand Down Expand Up @@ -823,7 +824,7 @@ func ReCreateMitm(port int, tcpIn chan<- C.ConnContext) {
Handler: &rewrites.RewriteHandler{},
}

mitmListener, err = mitm.New(opt, tcpIn)
mitmListener, err = mitm.New(opt, tunnel)
if err != nil {
return
}
Expand Down
12 changes: 6 additions & 6 deletions listener/mitm/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ import (
"net"
"net/http"

"github.com/Dreamacro/clash/adapter/inbound"
N "github.com/Dreamacro/clash/common/net"
C "github.com/Dreamacro/clash/constant"
"github.com/Dreamacro/clash/transport/socks5"
"github.com/metacubex/mihomo/adapter/inbound"
N "github.com/metacubex/mihomo/common/net"
C "github.com/metacubex/mihomo/constant"
"github.com/metacubex/mihomo/transport/socks5"
)

func getServerConn(serverConn *N.BufferedConn, request *http.Request, srcAddr net.Addr, in chan<- C.ConnContext) (*N.BufferedConn, error) {
func getServerConn(serverConn *N.BufferedConn, srcConn net.Conn, request *http.Request, tunnel C.Tunnel, additions ...inbound.Addition) (*N.BufferedConn, error) {
if serverConn != nil {
return serverConn, nil
}
Expand All @@ -33,7 +33,7 @@ func getServerConn(serverConn *N.BufferedConn, request *http.Request, srcAddr ne

left, right := net.Pipe()

in <- inbound.NewMitm(dstAddr, srcAddr, request.Header.Get("User-Agent"), right)
go tunnel.HandleTCPConn(inbound.NewMitm(dstAddr, srcConn, request.Header.Get("User-Agent"), right, additions...))

if request.TLS != nil {
tlsConn := tls.Client(left, &tls.Config{
Expand Down
19 changes: 10 additions & 9 deletions listener/mitm/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,14 @@ import (
"strings"
"time"

"github.com/Dreamacro/clash/common/cache"
N "github.com/Dreamacro/clash/common/net"
C "github.com/Dreamacro/clash/constant"
H "github.com/Dreamacro/clash/listener/http"
"github.com/metacubex/mihomo/adapter/inbound"
"github.com/metacubex/mihomo/common/lru"
N "github.com/metacubex/mihomo/common/net"
C "github.com/metacubex/mihomo/constant"
H "github.com/metacubex/mihomo/listener/http"
)

func HandleConn(c net.Conn, opt *Option, in chan<- C.ConnContext, cache *cache.LruCache[string, bool]) {
func HandleConn(c net.Conn, opt *Option, tunnel C.Tunnel, cache *lru.LruCache[string, bool], additions ...inbound.Addition) {
var (
clientIP = netip.MustParseAddrPort(c.RemoteAddr().String()).Addr()
sourceAddr net.Addr
Expand Down Expand Up @@ -132,7 +133,7 @@ readLoop:
session.request.TLS = connState
}

serverConn, err = getServerConn(serverConn, session.request, sourceAddr, in)
serverConn, err = getServerConn(serverConn, c, session.request, tunnel, additions...)
if err != nil {
break
}
Expand Down Expand Up @@ -160,13 +161,13 @@ readLoop:

// forward websocket
if isWebsocketRequest(request) {
serverConn, err = getServerConn(serverConn, session.request, sourceAddr, in)
serverConn, err = getServerConn(serverConn, c, session.request, tunnel, additions...)
if err != nil {
break
}

session.request.RequestURI = ""
if session.response = H.HandleUpgradeY(conn, serverConn, request, in); session.response == nil {
if session.response = H.HandleUpgradeY(conn, serverConn, request, tunnel); session.response == nil {
return // hijack connection
}
}
Expand Down Expand Up @@ -195,7 +196,7 @@ readLoop:
if session.request.URL.Host == "" {
session.response = session.NewErrorResponse(ErrInvalidURL)
} else {
serverConn, err = getServerConn(serverConn, session.request, sourceAddr, in)
serverConn, err = getServerConn(serverConn, c, session.request, tunnel, additions...)
if err != nil {
break
}
Expand Down
19 changes: 10 additions & 9 deletions listener/mitm/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ package mitm

import (
"crypto/tls"
"github.com/Dreamacro/clash/common/cache"
"github.com/Dreamacro/clash/common/cert"
C "github.com/Dreamacro/clash/constant"
"net"
"net/http"

"github.com/metacubex/mihomo/common/cert"
"github.com/metacubex/mihomo/common/lru"
C "github.com/metacubex/mihomo/constant"
)

type Handler interface {
Expand Down Expand Up @@ -51,19 +52,19 @@ func (l *Listener) Close() error {
}

// New the MITM proxy actually is a type of HTTP proxy
func New(option *Option, in chan<- C.ConnContext) (*Listener, error) {
return NewWithAuthenticate(option, in, true)
func New(option *Option, tunnel C.Tunnel) (*Listener, error) {
return NewWithAuthenticate(option, tunnel, true)
}

func NewWithAuthenticate(option *Option, in chan<- C.ConnContext, authenticate bool) (*Listener, error) {
func NewWithAuthenticate(option *Option, tunnel C.Tunnel, authenticate bool) (*Listener, error) {
l, err := net.Listen("tcp", option.Addr)
if err != nil {
return nil, err
}

var c *cache.LruCache[string, bool]
var c *lru.LruCache[string, bool]
if authenticate {
c = cache.New[string, bool](cache.WithAge[string, bool](90))
c = lru.New[string, bool](lru.WithAge[string, bool](90))
}

hl := &Listener{
Expand All @@ -80,7 +81,7 @@ func NewWithAuthenticate(option *Option, in chan<- C.ConnContext, authenticate b
}
continue
}
go HandleConn(conn, option, in, c)
go HandleConn(conn, option, tunnel, c)
}
}()

Expand Down
2 changes: 1 addition & 1 deletion rewrite/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"io"
"io/ioutil"

C "github.com/Dreamacro/clash/constant"
C "github.com/metacubex/mihomo/constant"
)

var (
Expand Down
6 changes: 3 additions & 3 deletions rewrite/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ import (
"strconv"
"strings"

C "github.com/Dreamacro/clash/constant"
"github.com/Dreamacro/clash/listener/mitm"
"github.com/Dreamacro/clash/tunnel"
C "github.com/metacubex/mihomo/constant"
"github.com/metacubex/mihomo/listener/mitm"
"github.com/metacubex/mihomo/tunnel"
)

var _ mitm.Handler = (*RewriteHandler)(nil)
Expand Down
2 changes: 1 addition & 1 deletion rewrite/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"regexp"
"strings"

C "github.com/Dreamacro/clash/constant"
C "github.com/metacubex/mihomo/constant"
)

func ParseRewrite(line string) (C.Rewrite, error) {
Expand Down
2 changes: 1 addition & 1 deletion rewrite/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
"regexp"
"testing"

"github.com/Dreamacro/clash/constant"
"github.com/metacubex/mihomo/constant"

"github.com/stretchr/testify/assert"
)
Expand Down
2 changes: 1 addition & 1 deletion rewrite/rewrite.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"strconv"
"strings"

C "github.com/Dreamacro/clash/constant"
C "github.com/metacubex/mihomo/constant"

"github.com/gofrs/uuid"
)
Expand Down
2 changes: 1 addition & 1 deletion rules/common/user_gent.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package common
import (
"strings"

C "github.com/Dreamacro/clash/constant"
C "github.com/metacubex/mihomo/constant"
)

type UserAgent struct {
Expand Down
Loading

0 comments on commit d2cb220

Please sign in to comment.