From 44a236ed33569eaa5de00cc2ca8bc80b3d09eb93 Mon Sep 17 00:00:00 2001 From: xishang0128 Date: Sat, 3 Aug 2024 20:14:23 +0800 Subject: [PATCH] Merge remote-tracking branch 'origin/Alpha' into mitm-test --- adapter/inbound/mitm.go | 2 +- config/config.go | 3 +++ listener/mitm/client.go | 4 ++-- listener/mitm/proxy.go | 18 ++++++++++-------- listener/mitm/server.go | 30 +++++++++++++++++++++++------- 5 files changed, 39 insertions(+), 18 deletions(-) diff --git a/adapter/inbound/mitm.go b/adapter/inbound/mitm.go index b83e971033..44774851f6 100644 --- a/adapter/inbound/mitm.go +++ b/adapter/inbound/mitm.go @@ -8,7 +8,7 @@ import ( ) // NewMitm receive mitm request and return MitmContext -func NewMitm(target socks5.Addr, srcConn net.Conn, userAgent string, Url string, conn net.Conn, additions ...Addition) (net.Conn, *C.Metadata) { +func NewMitm(target socks5.Addr, srcConn net.Conn, userAgent string, Url string, conn net.Conn, additions []Addition) (net.Conn, *C.Metadata) { metadata := parseSocksAddr(target) metadata.NetWork = C.TCP metadata.Type = C.MITM diff --git a/config/config.go b/config/config.go index 8400cc84f8..5bf746701d 100644 --- a/config/config.go +++ b/config/config.go @@ -773,6 +773,9 @@ func parseProxies(cfg *RawConfig) (proxies map[string]C.Proxy, providersMap map[ proxyList = append(proxyList, "DIRECT", "REJECT") if cfg.MITM.Port != 0 { + if cfg.MitmPort == 0 { + cfg.MitmPort = cfg.MITM.Port + } proxies["MITM"] = adapter.NewProxy(outbound.NewMitm(fmt.Sprintf("127.0.0.1:%d", cfg.MITM.Port))) proxyList = append(proxyList, "MITM") } else if cfg.MitmPort != 0 { diff --git a/listener/mitm/client.go b/listener/mitm/client.go index a3ab7af39b..69948e578d 100644 --- a/listener/mitm/client.go +++ b/listener/mitm/client.go @@ -12,7 +12,7 @@ import ( "github.com/metacubex/mihomo/transport/socks5" ) -func getServerConn(serverConn *N.BufferedConn, srcConn net.Conn, request *http.Request, tunnel C.Tunnel, additions ...inbound.Addition) (*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 } @@ -33,7 +33,7 @@ func getServerConn(serverConn *N.BufferedConn, srcConn net.Conn, request *http.R left, right := net.Pipe() - go tunnel.HandleTCPConn(inbound.NewMitm(dstAddr, srcConn, request.Header.Get("User-Agent"), request.URL.String(), right, additions...)) + go tunnel.HandleTCPConn(inbound.NewMitm(dstAddr, srcConn, request.Header.Get("User-Agent"), request.URL.String(), right, additions)) if request.TLS != nil { tlsConn := tls.Client(left, &tls.Config{ diff --git a/listener/mitm/proxy.go b/listener/mitm/proxy.go index acb9cb8717..941c4a62b9 100644 --- a/listener/mitm/proxy.go +++ b/listener/mitm/proxy.go @@ -28,6 +28,7 @@ func HandleConn(c net.Conn, opt *Option, tunnel C.Tunnel, authenticator auth.Aut sourceAddr net.Addr serverConn *N.BufferedConn connState *tls.ConnectionState + user string ) defer func() { @@ -38,6 +39,9 @@ func HandleConn(c net.Conn, opt *Option, tunnel C.Tunnel, authenticator auth.Aut conn := N.NewBufferedConn(c) + additions = append(additions, inbound.Placeholder) + inUserIdx := len(additions) - 1 + trusted := authenticator == nil // disable authenticate if cache is nil if !trusted { trusted = clientIP.IsLoopback() || clientIP.IsUnspecified() @@ -62,11 +66,9 @@ readLoop: sourceAddr = parseSourceAddress(session.request, conn.RemoteAddr(), sourceAddr) session.request.RemoteAddr = sourceAddr.String() - if !trusted { - session.response, _ = H.Authenticate(session.request, authenticator) - - trusted = session.response == nil - } + session.response, user = H.Authenticate(session.request, authenticator) + additions[inUserIdx] = inbound.WithInUser(user) + trusted = session.response == nil if trusted { if session.request.Method == http.MethodConnect { @@ -133,7 +135,7 @@ readLoop: session.request.TLS = connState } - serverConn, err = getServerConn(serverConn, c, session.request, tunnel, additions...) + serverConn, err = getServerConn(serverConn, c, session.request, tunnel, additions) if err != nil { break } @@ -161,7 +163,7 @@ readLoop: // forward websocket if isWebsocketRequest(request) { - serverConn, err = getServerConn(serverConn, c, session.request, tunnel, additions...) + serverConn, err = getServerConn(serverConn, c, session.request, tunnel, additions) if err != nil { break } @@ -196,7 +198,7 @@ readLoop: if session.request.URL.Host == "" { session.response = session.NewErrorResponse(ErrInvalidURL) } else { - serverConn, err = getServerConn(serverConn, c, session.request, tunnel, additions...) + serverConn, err = getServerConn(serverConn, c, session.request, tunnel, additions) if err != nil { break } diff --git a/listener/mitm/server.go b/listener/mitm/server.go index 0350c30331..2fb6ea6056 100644 --- a/listener/mitm/server.go +++ b/listener/mitm/server.go @@ -5,6 +5,7 @@ import ( "net" "net/http" + "github.com/metacubex/mihomo/adapter/inbound" "github.com/metacubex/mihomo/common/cert" "github.com/metacubex/mihomo/component/auth" C "github.com/metacubex/mihomo/constant" @@ -53,12 +54,21 @@ func (l *Listener) Close() error { } // New the MITM proxy actually is a type of HTTP proxy -func New(option *Option, tunnel C.Tunnel) (*Listener, error) { - return NewWithAuthenticate(option, tunnel, authStore.Authenticator()) +func New(option *Option, tunnel C.Tunnel, additions ...inbound.Addition) (*Listener, error) { + return NewWithAuthenticate(option, tunnel, authStore.Authenticator(), additions...) } -func NewWithAuthenticate(option *Option, tunnel C.Tunnel, authenticator auth.Authenticator) (*Listener, error) { - l, err := net.Listen("tcp", option.Addr) +func NewWithAuthenticate(option *Option, tunnel C.Tunnel, authenticator auth.Authenticator, additions ...inbound.Addition) (*Listener, error) { + isDefault := false + if len(additions) == 0 { + isDefault = true + additions = []inbound.Addition{ + inbound.WithInName("DEFAULT-HTTP"), + inbound.WithSpecialRules(""), + } + } + + l, err := inbound.Listen("tcp", option.Addr) if err != nil { return nil, err } @@ -70,14 +80,20 @@ func NewWithAuthenticate(option *Option, tunnel C.Tunnel, authenticator auth.Aut } go func() { for { - conn, err1 := hl.listener.Accept() - if err1 != nil { + conn, err := hl.listener.Accept() + if err != nil { if hl.closed { break } continue } - go HandleConn(conn, option, tunnel, authenticator) + if isDefault { // only apply on default listener + if !inbound.IsRemoteAddrDisAllowed(conn.RemoteAddr()) { + _ = conn.Close() + continue + } + } + go HandleConn(conn, option, tunnel, authenticator, additions...) } }()