Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 0 additions & 9 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion README_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`。 |


正在开发中的功能:
Expand Down Expand Up @@ -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`

## 感谢
一些代码引用自:
Expand Down
2 changes: 2 additions & 0 deletions cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ var (
socks5User string
socks5Pass string
proto string
noDNS53 bool
)

var rootCmd = &cobra.Command{
Expand Down Expand Up @@ -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")
}
17 changes: 17 additions & 0 deletions cmd/udpProxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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) {
Expand Down
Loading