From f835632eab24f43a2493f102a948c8d03ee77407 Mon Sep 17 00:00:00 2001 From: Weii Wang Date: Mon, 5 Jan 2026 13:20:09 +0800 Subject: [PATCH 1/7] Fall back to original destination IP if no SNI in the TLS handshake --- .github/workflows/integration-tests.yaml | 6 ++++++ aproxy.go | 6 +++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.github/workflows/integration-tests.yaml b/.github/workflows/integration-tests.yaml index 4dd0054..470a6e1 100644 --- a/.github/workflows/integration-tests.yaml +++ b/.github/workflows/integration-tests.yaml @@ -75,6 +75,12 @@ jobs: sudo apt install -y socat timeout 60 socat /dev/null TCP4:tcpbin.com:4242 + - name: Test No SNI + run: | + HOST_IP=$(dig +short example.com) + timeout 60 curl "https://$HOST_IP:443" -v + sudo snap logs aproxy.aproxy | grep -Fq "$HOST_IP:443" + - name: Test Access Logs run: | sudo snap logs aproxy.aproxy | grep -Fq "example.com:80" diff --git a/aproxy.go b/aproxy.go index 2ca9b14..4b5009a 100644 --- a/aproxy.go +++ b/aproxy.go @@ -16,6 +16,7 @@ import ( "net/url" "os" "os/signal" + "strconv" "strings" "sync" "sync/atomic" @@ -357,7 +358,10 @@ func HandleConn(conn net.Conn, proxy string) { logger.Error("failed to preread SNI from connection", "error", err) return } else { - host := fmt.Sprintf("%s:%d", sni, dst.Port) + if sni == "" { + sni = dst.IP.String() + } + host := net.JoinHostPort(sni, strconv.Itoa(dst.Port)) logger = logger.With("host", host) proxyConn, err := DialProxyConnect(proxy, host) if err != nil { From 52e77d4be1ddbe3d74a72cab97e39e77cf51ee85 Mon Sep 17 00:00:00 2001 From: Weii Wang Date: Mon, 5 Jan 2026 13:29:27 +0800 Subject: [PATCH 2/7] Fix test --- .github/workflows/integration-tests.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/integration-tests.yaml b/.github/workflows/integration-tests.yaml index 470a6e1..fc81fae 100644 --- a/.github/workflows/integration-tests.yaml +++ b/.github/workflows/integration-tests.yaml @@ -77,7 +77,7 @@ jobs: - name: Test No SNI run: | - HOST_IP=$(dig +short example.com) + HOST_IP=$(dig +short example.com | head -n1) timeout 60 curl "https://$HOST_IP:443" -v sudo snap logs aproxy.aproxy | grep -Fq "$HOST_IP:443" From 57efe83f98c54ac57f2deaf98c2c94efd24f4e34 Mon Sep 17 00:00:00 2001 From: Weii Wang Date: Mon, 5 Jan 2026 13:43:12 +0800 Subject: [PATCH 3/7] Fix test --- .github/workflows/integration-tests.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/integration-tests.yaml b/.github/workflows/integration-tests.yaml index fc81fae..0c04210 100644 --- a/.github/workflows/integration-tests.yaml +++ b/.github/workflows/integration-tests.yaml @@ -77,7 +77,7 @@ jobs: - name: Test No SNI run: | - HOST_IP=$(dig +short example.com | head -n1) + HOST_IP=$(dig +short ubuntu.com | head -n1) timeout 60 curl "https://$HOST_IP:443" -v sudo snap logs aproxy.aproxy | grep -Fq "$HOST_IP:443" From 37634b738153db2a12cefcf01512047c7954bea4 Mon Sep 17 00:00:00 2001 From: Weii Wang Date: Mon, 5 Jan 2026 14:17:15 +0800 Subject: [PATCH 4/7] Fix test --- .github/workflows/integration-tests.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/integration-tests.yaml b/.github/workflows/integration-tests.yaml index 0c04210..f778303 100644 --- a/.github/workflows/integration-tests.yaml +++ b/.github/workflows/integration-tests.yaml @@ -78,8 +78,8 @@ jobs: - name: Test No SNI run: | HOST_IP=$(dig +short ubuntu.com | head -n1) - timeout 60 curl "https://$HOST_IP:443" -v - sudo snap logs aproxy.aproxy | grep -Fq "$HOST_IP:443" + timeout 60 curl "https://$HOST_IP:443" -v || : + sudo snap logs aproxy.aproxy | grep -Fq host=\"$HOST_IP:443\" - name: Test Access Logs run: | From 074ee5aee58ddcb32eafd4406f671f1de57fea9f Mon Sep 17 00:00:00 2001 From: Weii Wang Date: Mon, 5 Jan 2026 14:25:22 +0800 Subject: [PATCH 5/7] Fix test --- .github/workflows/integration-tests.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/integration-tests.yaml b/.github/workflows/integration-tests.yaml index f778303..ae34f24 100644 --- a/.github/workflows/integration-tests.yaml +++ b/.github/workflows/integration-tests.yaml @@ -78,7 +78,7 @@ jobs: - name: Test No SNI run: | HOST_IP=$(dig +short ubuntu.com | head -n1) - timeout 60 curl "https://$HOST_IP:443" -v || : + curl "https://$HOST_IP:443" -v || : sudo snap logs aproxy.aproxy | grep -Fq host=\"$HOST_IP:443\" - name: Test Access Logs From 01511de0f22071990fbb5761c8094753874cf3cb Mon Sep 17 00:00:00 2001 From: Weii Wang Date: Mon, 5 Jan 2026 14:32:52 +0800 Subject: [PATCH 6/7] Fix test --- .github/workflows/integration-tests.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/integration-tests.yaml b/.github/workflows/integration-tests.yaml index ae34f24..e21ab4c 100644 --- a/.github/workflows/integration-tests.yaml +++ b/.github/workflows/integration-tests.yaml @@ -78,8 +78,8 @@ jobs: - name: Test No SNI run: | HOST_IP=$(dig +short ubuntu.com | head -n1) - curl "https://$HOST_IP:443" -v || : - sudo snap logs aproxy.aproxy | grep -Fq host=\"$HOST_IP:443\" + timeout 60 curl "https://$HOST_IP:443" -v || : + sudo snap logs aproxy.aproxy | grep -Fq host=$HOST_IP:443 - name: Test Access Logs run: | From 2fab5c3cc99f9640233e88645c9aacd870fd0548 Mon Sep 17 00:00:00 2001 From: Weii Wang Date: Mon, 5 Jan 2026 16:57:02 +0800 Subject: [PATCH 7/7] Apply suggestions from review comments --- aproxy.go | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/aproxy.go b/aproxy.go index 4b5009a..d5392fc 100644 --- a/aproxy.go +++ b/aproxy.go @@ -357,20 +357,20 @@ func HandleConn(conn net.Conn, proxy string) { if err != nil { logger.Error("failed to preread SNI from connection", "error", err) return - } else { - if sni == "" { - sni = dst.IP.String() - } - host := net.JoinHostPort(sni, strconv.Itoa(dst.Port)) - logger = logger.With("host", host) - proxyConn, err := DialProxyConnect(proxy, host) - if err != nil { - logger.Error("failed to connect to http proxy", "error", err) - return - } - logger.Info("relay TLS connection to proxy") - RelayTCP(consigned, proxyConn, logger) } + hostname := sni + if hostname == "" { + hostname = dst.IP.String() + } + host := net.JoinHostPort(hostname, strconv.Itoa(dst.Port)) + logger = logger.With("host", host) + proxyConn, err := DialProxyConnect(proxy, host) + if err != nil { + logger.Error("failed to connect to http proxy", "error", err) + return + } + logger.Info("relay TLS connection to proxy") + RelayTCP(consigned, proxyConn, logger) case 80, 11371: host, err := PrereadHttpHost(consigned) if err != nil {