mirror of
https://github.com/SagerNet/sing-box.git
synced 2025-04-04 20:37:37 +03:00
mitm: Minor fixes
This commit is contained in:
parent
5361d2acec
commit
fb3007fa80
2 changed files with 54 additions and 38 deletions
|
@ -40,7 +40,7 @@ func getMobileConfig(ctx context.Context) http.HandlerFunc {
|
||||||
mobileConfig := map[string]interface{}{
|
mobileConfig := map[string]interface{}{
|
||||||
"PayloadContent": []interface{}{
|
"PayloadContent": []interface{}{
|
||||||
map[string]interface{}{
|
map[string]interface{}{
|
||||||
"PayloadCertificateFileName": "Certificate.cer",
|
"PayloadCertificateFileName": "Certificates.cer",
|
||||||
"PayloadContent": certificate.Raw,
|
"PayloadContent": certificate.Raw,
|
||||||
"PayloadDescription": "Adds a root certificate",
|
"PayloadDescription": "Adds a root certificate",
|
||||||
"PayloadDisplayName": certificate.Subject.CommonName,
|
"PayloadDisplayName": certificate.Subject.CommonName,
|
||||||
|
|
|
@ -26,6 +26,7 @@ import (
|
||||||
"github.com/sagernet/sing/common"
|
"github.com/sagernet/sing/common"
|
||||||
"github.com/sagernet/sing/common/atomic"
|
"github.com/sagernet/sing/common/atomic"
|
||||||
E "github.com/sagernet/sing/common/exceptions"
|
E "github.com/sagernet/sing/common/exceptions"
|
||||||
|
F "github.com/sagernet/sing/common/format"
|
||||||
"github.com/sagernet/sing/common/logger"
|
"github.com/sagernet/sing/common/logger"
|
||||||
M "github.com/sagernet/sing/common/metadata"
|
M "github.com/sagernet/sing/common/metadata"
|
||||||
N "github.com/sagernet/sing/common/network"
|
N "github.com/sagernet/sing/common/network"
|
||||||
|
@ -165,7 +166,7 @@ func (e *Engine) newTLS(ctx context.Context, this N.Dialer, conn net.Conn, metad
|
||||||
tlsConn := tls.Server(conn, tlsConfig)
|
tlsConn := tls.Server(conn, tlsConfig)
|
||||||
err := tlsConn.HandshakeContext(ctx)
|
err := tlsConn.HandshakeContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return E.Cause(err, "TLS handshake")
|
return E.Cause(err, "TLS handshake failed for ", metadata.ClientHello.ServerName, ", ", strings.Join(metadata.ClientHello.SupportedProtos, ", "))
|
||||||
}
|
}
|
||||||
if tlsConn.ConnectionState().NegotiatedProtocol == "h2" {
|
if tlsConn.ConnectionState().NegotiatedProtocol == "h2" {
|
||||||
return e.newHTTP2(ctx, this, tlsConn, tlsConfig, metadata, onClose)
|
return e.newHTTP2(ctx, this, tlsConn, tlsConfig, metadata, onClose)
|
||||||
|
@ -183,7 +184,11 @@ func (e *Engine) newHTTP1(ctx context.Context, this N.Dialer, conn net.Conn, tls
|
||||||
return E.Cause(err, "read HTTP request")
|
return E.Cause(err, "read HTTP request")
|
||||||
}
|
}
|
||||||
rawRequestURL := request.URL
|
rawRequestURL := request.URL
|
||||||
rawRequestURL.Scheme = "https"
|
if tlsConfig != nil {
|
||||||
|
rawRequestURL.Scheme = "https"
|
||||||
|
} else {
|
||||||
|
rawRequestURL.Scheme = "http"
|
||||||
|
}
|
||||||
if rawRequestURL.Host == "" {
|
if rawRequestURL.Host == "" {
|
||||||
rawRequestURL.Host = request.Host
|
rawRequestURL.Host = request.Host
|
||||||
}
|
}
|
||||||
|
@ -482,7 +487,7 @@ func (e *Engine) newHTTP1(ctx context.Context, this N.Dialer, conn net.Conn, tls
|
||||||
response.Body = io.NopCloser(bytes.NewReader(responseBody))
|
response.Body = io.NopCloser(bytes.NewReader(responseBody))
|
||||||
}
|
}
|
||||||
if options.Print {
|
if options.Print {
|
||||||
e.printResponse(ctx, response, responseBody)
|
e.printResponse(ctx, request, response, responseBody)
|
||||||
}
|
}
|
||||||
if responseScript != nil {
|
if responseScript != nil {
|
||||||
if responseBody == nil && responseScript.RequiresBody() && response.ContentLength > 0 && (responseScript.MaxSize() == 0 && response.ContentLength <= 131072 || response.ContentLength <= responseScript.MaxSize()) {
|
if responseBody == nil && responseScript.RequiresBody() && response.ContentLength > 0 && (responseScript.MaxSize() == 0 && response.ContentLength <= 131072 || response.ContentLength <= responseScript.MaxSize()) {
|
||||||
|
@ -578,6 +583,22 @@ func (e *Engine) newHTTP1(ctx context.Context, this N.Dialer, conn net.Conn, tls
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Engine) newHTTP2(ctx context.Context, this N.Dialer, conn net.Conn, tlsConfig *tls.Config, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) error {
|
func (e *Engine) newHTTP2(ctx context.Context, this N.Dialer, conn net.Conn, tlsConfig *tls.Config, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) error {
|
||||||
|
httpTransport := &http.Transport{
|
||||||
|
ForceAttemptHTTP2: true,
|
||||||
|
DialContext: func(ctx context.Context, network, address string) (net.Conn, error) {
|
||||||
|
ctx = adapter.WithContext(ctx, &metadata)
|
||||||
|
if len(metadata.DestinationAddresses) > 0 || metadata.Destination.IsIP() {
|
||||||
|
return dialer.DialSerialNetwork(ctx, this, N.NetworkTCP, metadata.Destination, metadata.DestinationAddresses, metadata.NetworkStrategy, metadata.NetworkType, metadata.FallbackNetworkType, metadata.FallbackDelay)
|
||||||
|
} else {
|
||||||
|
return this.DialContext(ctx, N.NetworkTCP, metadata.Destination)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
TLSClientConfig: tlsConfig,
|
||||||
|
}
|
||||||
|
err := http2.ConfigureTransport(httpTransport)
|
||||||
|
if err != nil {
|
||||||
|
return E.Cause(err, "configure HTTP/2 transport")
|
||||||
|
}
|
||||||
handler := &engineHandler{
|
handler := &engineHandler{
|
||||||
Engine: e,
|
Engine: e,
|
||||||
conn: conn,
|
conn: conn,
|
||||||
|
@ -585,27 +606,7 @@ func (e *Engine) newHTTP2(ctx context.Context, this N.Dialer, conn net.Conn, tls
|
||||||
dialer: this,
|
dialer: this,
|
||||||
metadata: metadata,
|
metadata: metadata,
|
||||||
httpClient: &http.Client{
|
httpClient: &http.Client{
|
||||||
Transport: &http2.Transport{
|
Transport: httpTransport,
|
||||||
AllowHTTP: true,
|
|
||||||
MaxReadFrameSize: math.MaxUint32,
|
|
||||||
DialTLSContext: func(ctx context.Context, network, addr string, cfg *tls.Config) (net.Conn, error) {
|
|
||||||
ctx = adapter.WithContext(ctx, &metadata)
|
|
||||||
var (
|
|
||||||
remoteConn net.Conn
|
|
||||||
err error
|
|
||||||
)
|
|
||||||
if len(metadata.DestinationAddresses) > 0 || metadata.Destination.IsIP() {
|
|
||||||
remoteConn, err = dialer.DialSerialNetwork(ctx, this, N.NetworkTCP, metadata.Destination, metadata.DestinationAddresses, metadata.NetworkStrategy, metadata.NetworkType, metadata.FallbackNetworkType, metadata.FallbackDelay)
|
|
||||||
} else {
|
|
||||||
remoteConn, err = this.DialContext(ctx, N.NetworkTCP, metadata.Destination)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return tls.Client(remoteConn, cfg), nil
|
|
||||||
},
|
|
||||||
TLSClientConfig: tlsConfig,
|
|
||||||
},
|
|
||||||
CheckRedirect: func(req *http.Request, via []*http.Request) error {
|
CheckRedirect: func(req *http.Request, via []*http.Request) error {
|
||||||
return http.ErrUseLastResponse
|
return http.ErrUseLastResponse
|
||||||
},
|
},
|
||||||
|
@ -635,7 +636,6 @@ type engineHandler struct {
|
||||||
func (e *engineHandler) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
|
func (e *engineHandler) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
|
||||||
err := e.serveHTTP(request.Context(), writer, request)
|
err := e.serveHTTP(request.Context(), writer, request)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
e.conn.Close()
|
|
||||||
if E.IsClosedOrCanceled(err) {
|
if E.IsClosedOrCanceled(err) {
|
||||||
e.logger.DebugContext(request.Context(), E.Cause(err, "connection closed"))
|
e.logger.DebugContext(request.Context(), E.Cause(err, "connection closed"))
|
||||||
} else {
|
} else {
|
||||||
|
@ -921,7 +921,7 @@ func (e *engineHandler) serveHTTP(ctx context.Context, writer http.ResponseWrite
|
||||||
response.Body = io.NopCloser(bytes.NewReader(responseBody))
|
response.Body = io.NopCloser(bytes.NewReader(responseBody))
|
||||||
}
|
}
|
||||||
if options.Print {
|
if options.Print {
|
||||||
e.printResponse(ctx, response, responseBody)
|
e.printResponse(ctx, request, response, responseBody)
|
||||||
}
|
}
|
||||||
if responseScript != nil {
|
if responseScript != nil {
|
||||||
if responseBody == nil && responseScript.RequiresBody() && response.ContentLength > 0 && (responseScript.MaxSize() == 0 && response.ContentLength <= 131072 || response.ContentLength <= responseScript.MaxSize()) {
|
if responseBody == nil && responseScript.RequiresBody() && response.ContentLength > 0 && (responseScript.MaxSize() == 0 && response.ContentLength <= 131072 || response.ContentLength <= responseScript.MaxSize()) {
|
||||||
|
@ -1021,42 +1021,58 @@ func (e *engineHandler) serveHTTP(ctx context.Context, writer http.ResponseWrite
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Engine) printRequest(ctx context.Context, request *http.Request, body []byte) {
|
func (e *Engine) printRequest(ctx context.Context, request *http.Request, body []byte) {
|
||||||
e.logger.TraceContext(ctx, "request: ", request.Proto, " ", request.Method, " ", request.URL.String())
|
var builder strings.Builder
|
||||||
|
builder.WriteString(F.ToString(request.Proto, " ", request.Method, " ", request.URL))
|
||||||
|
builder.WriteString("\n")
|
||||||
if request.URL.Hostname() != "" && request.URL.Hostname() != request.Host {
|
if request.URL.Hostname() != "" && request.URL.Hostname() != request.Host {
|
||||||
e.logger.TraceContext(ctx, "request: ", "Host: ", request.Host)
|
builder.WriteString("Host: ")
|
||||||
|
builder.WriteString(request.Host)
|
||||||
|
builder.WriteString("\n")
|
||||||
}
|
}
|
||||||
for key, values := range request.Header {
|
for key, values := range request.Header {
|
||||||
for _, value := range values {
|
for _, value := range values {
|
||||||
e.logger.TraceContext(ctx, "request: ", key, ": ", value)
|
builder.WriteString(key)
|
||||||
|
builder.WriteString(": ")
|
||||||
|
builder.WriteString(value)
|
||||||
|
builder.WriteString("\n")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(body) > 0 {
|
if len(body) > 0 {
|
||||||
|
builder.WriteString("\n")
|
||||||
if !bytes.ContainsFunc(body, func(r rune) bool {
|
if !bytes.ContainsFunc(body, func(r rune) bool {
|
||||||
return !unicode.IsPrint(r) && !unicode.IsSpace(r)
|
return !unicode.IsPrint(r) && !unicode.IsSpace(r)
|
||||||
}) {
|
}) {
|
||||||
e.logger.TraceContext(ctx, "request: body: ", string(body))
|
builder.Write(body)
|
||||||
} else {
|
} else {
|
||||||
e.logger.TraceContext(ctx, "request: body unprintable")
|
builder.WriteString("(body not printable)")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
e.logger.InfoContext(ctx, "request: ", builder.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Engine) printResponse(ctx context.Context, response *http.Response, body []byte) {
|
func (e *Engine) printResponse(ctx context.Context, request *http.Request, response *http.Response, body []byte) {
|
||||||
e.logger.TraceContext(ctx, "response: ", response.Proto, " ", response.Status)
|
var builder strings.Builder
|
||||||
|
builder.WriteString(F.ToString(response.Proto, " ", response.Status, " ", request.URL))
|
||||||
|
builder.WriteString("\n")
|
||||||
for key, values := range response.Header {
|
for key, values := range response.Header {
|
||||||
for _, value := range values {
|
for _, value := range values {
|
||||||
e.logger.TraceContext(ctx, "response: ", key, ": ", value)
|
builder.WriteString(key)
|
||||||
|
builder.WriteString(": ")
|
||||||
|
builder.WriteString(value)
|
||||||
|
builder.WriteString("\n")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(body) > 0 {
|
if len(body) > 0 {
|
||||||
|
builder.WriteString("\n")
|
||||||
if !bytes.ContainsFunc(body, func(r rune) bool {
|
if !bytes.ContainsFunc(body, func(r rune) bool {
|
||||||
return !unicode.IsPrint(r) && !unicode.IsSpace(r)
|
return !unicode.IsPrint(r) && !unicode.IsSpace(r)
|
||||||
}) {
|
}) {
|
||||||
e.logger.TraceContext(ctx, "response: ", string(body))
|
builder.Write(body)
|
||||||
|
} else {
|
||||||
|
builder.WriteString("(body not printable)")
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
e.logger.TraceContext(ctx, "response: body unprintable")
|
|
||||||
}
|
}
|
||||||
|
e.logger.InfoContext(ctx, "response: ", builder.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
type simpleResponseWriter struct {
|
type simpleResponseWriter struct {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue