From 3e351e37e6f478f4dcd5053f96b578e0142934d4 Mon Sep 17 00:00:00 2001 From: Dream95 Date: Sat, 2 May 2026 09:24:50 +0000 Subject: [PATCH] feat: rewrite dns Signed-off-by: Dream95 --- .github/workflows/build.yml | 9 --------- README.md | 3 ++- README_CN.md | 3 ++- cmd/cmd.go | 2 ++ cmd/udpProxy.go | 17 +++++++++++++++++ 5 files changed, 23 insertions(+), 11 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5eacc7d..c1ef89c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -34,15 +34,6 @@ jobs: if: matrix.arch == 'arm64' run: make clean && make build-bpf && GOOS=linux GOARCH=arm64 go build -o gotproxy ./cmd - - name: Set DNS to 1.1.1.1 (avoid 127.0.0.53) - if: matrix.arch == 'amd64' - run: | - set -e - sudo rm -f /etc/resolv.conf - printf "nameserver 1.1.1.1\nnameserver 1.0.0.1\noptions timeout:1 attempts:2\n" | sudo tee /etc/resolv.conf >/dev/null - echo "[INFO] /etc/resolv.conf:" - cat /etc/resolv.conf - - name: Run proxy tests if: matrix.arch == 'amd64' run: sudo ./scripts/test_proxy.sh diff --git a/README.md b/README.md index e19873d..238819b 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,7 @@ sudo ./gotproxy [flags] | **--socks5-user** | SOCKS5 username (RFC1929). Must be set together with `--socks5-pass`. | | **--socks5-pass** | SOCKS5 password (RFC1929). Must be set together with `--socks5-user`. | | **--proto** | Proxy protocol selection: `both` (default) / `tcp` / `udp`. When set to `tcp`, only TCP traffic will be redirected; when set to `udp`, only UDP traffic will be redirected. | +| **--no-dns53** | Disable automatic UDP DNS rewrite from `127.0.0.53:53` to `1.1.1.1:53` (enabled by default). | Features Under Development: IPv6 support @@ -95,7 +96,7 @@ When multiple process/container filters are specified (such as `--container-name * The current implementation of UDP proxy is not perfect, and there may be issues in certain scenarios. -* If your distro uses `127.0.0.53` for DNS, switch to a real upstream DNS , otherwise DNS may fail. +* By default, UDP DNS destination `127.0.0.53:53` is automatically rewritten to `1.1.1.1:53`; set `--no-dns53` to turn this off. ## Thanks Some code is referenced from diff --git a/README_CN.md b/README_CN.md index e2437fe..620f664 100644 --- a/README_CN.md +++ b/README_CN.md @@ -44,6 +44,7 @@ sudo ./gotproxy [flags] | **--socks5-user** | socks5 账号(RFC1929)。需要同时设置 `--socks5-pass`。 | | **--socks5-pass** | socks5 密码(RFC1929)。需要同时设置 `--socks5-user`。 | | **--proto** | 代理协议选择:`both`(默认)/ `tcp` / `udp`。当设置为 `tcp` 时只重定向 TCP 流量;设置为 `udp` 时只重定向 UDP 流量。 | +| **--no-dns53** | 关闭 UDP DNS 对 `127.0.0.53:53` 的自动改写。默认会自动改写为 `1.1.1.1:53`。 | 正在开发中的功能: @@ -96,7 +97,7 @@ sudo ./gotproxy --container-name curl-test --pids 1234 * 理论上应该根据5元组确定一个连接,但是考虑大多数情况目前只根据协议类型和源端口进行连接映射。 * 在根据进程名称进行代理的场景中,如果进程启动了子进程并使用了execve执行一个新命令,会无法进行代理。 * 目前的udp代理实现并不完善,某些场景下可能存在问题。 -* 如果你的 Linux 发行版使用 `127.0.0.53` 作为 DNS 需要将 DNS 指向真实的上游服务器,否则可能出现域名解析异常。 +* 默认会将 UDP DNS 目标 `127.0.0.53:53` 自动改写为 `1.1.1.1:53`;如需关闭可设置 `--no-dns53`。 ## 感谢 一些代码引用自: diff --git a/cmd/cmd.go b/cmd/cmd.go index 7a76932..73ee01d 100644 --- a/cmd/cmd.go +++ b/cmd/cmd.go @@ -21,6 +21,7 @@ var ( socks5User string socks5Pass string proto string + noDNS53 bool ) var rootCmd = &cobra.Command{ @@ -101,4 +102,5 @@ func init() { rootCmd.PersistentFlags().StringVar(&socks5User, "socks5-user", "", "The SOCKS5 username. Requires --socks5-pass.") rootCmd.PersistentFlags().StringVar(&socks5Pass, "socks5-pass", "", "The SOCKS5 password. Requires --socks5-user.") rootCmd.PersistentFlags().StringVar(&proto, "proto", "both", "Proxy protocol: both|tcp|udp") + rootCmd.PersistentFlags().BoolVar(&noDNS53, "no-dns53", false, "Disable UDP DNS destination rewrite from 127.0.0.53:53 to 1.1.1.1:53") } diff --git a/cmd/udpProxy.go b/cmd/udpProxy.go index d5905d3..e6cdf62 100644 --- a/cmd/udpProxy.go +++ b/cmd/udpProxy.go @@ -15,6 +15,11 @@ import ( const udpReadTimeout = 5 * time.Second +const ( + localDNSStubAddr = "127.0.0.53:53" + publicDNSAddr = "1.1.1.1:53" +) + // StartUDPProxy listens on addr (UDP) and forwards packets to original destinations // looked up from the BPF map (key = client addr, value = original dst ip:port). func StartUDPProxy(addr string, udpMap *ebpf.Map) { @@ -55,6 +60,7 @@ func handleUDPPacket(proxyConn *net.UDPConn, clientAddr *net.UDPAddr, payload [] log.Printf("UDP proxy: lookup original dest for %s: %v", clientAddr, err) return } + targetAddr = maybeRewriteLocalDNSStub(targetAddr) fmt.Printf("UDP Original destination: %s\n", targetAddr) var remoteConn net.Conn @@ -94,6 +100,17 @@ func handleUDPPacket(proxyConn *net.UDPConn, clientAddr *net.UDPAddr, payload [] } } +func maybeRewriteLocalDNSStub(targetAddr string) string { + if noDNS53 { + return targetAddr + } + if targetAddr != localDNSStubAddr { + return targetAddr + } + log.Printf("UDP proxy: rewrite DNS destination %s -> %s", localDNSStubAddr, publicDNSAddr) + return publicDNSAddr +} + // getUDPOriginalDest looks up the BPF map with key (clientIP, clientPort) and returns "ip:port". // BPF stores: key src_ip (network order), src_port (host); value dst_ip (network order), dst_port (host). func getUDPOriginalDest(clientAddr *net.UDPAddr, udpMap *ebpf.Map) (string, error) {