Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for UDP proxying #154

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

VastBlast
Copy link

@VastBlast VastBlast commented Jan 1, 2025

This PR adds support for a proxying a UDP server through Wireguard. It can listen on IPv4 while tunneling to an IPv6 address or vice versa.

When sending, it goes through BindAddress -> Wireguard -> Target and the opposite when receiving.

For example, if you wanted to proxy Cloudflare's DNS server, an example config would be:

[Interface]
...

[Peer]
...

[UDPProxyTunnel]
BindAddress = 127.0.0.1:53

#Target = [2606:4700:4700::1111]:53
Target = 1.1.1.1:53

# If its set to 0, it will never timeout
InactivityTimeout = 30

@cob-web-corner
Copy link

cob-web-corner commented Jan 3, 2025

To comply with current architecture this also needs a landlock config rules section

func lockNetwork(sections []wireproxy.RoutineSpawner, infoAddr *string) {
var rules []landlock.Rule
if infoAddr != nil && *infoAddr != "" {
rules = append(rules, landlock.BindTCP(extractPort(*infoAddr)))
}
for _, section := range sections {
switch section := section.(type) {
case *wireproxy.TCPServerTunnelConfig:
rules = append(rules, landlock.ConnectTCP(extractPort(section.Target)))
case *wireproxy.HTTPConfig:
rules = append(rules, landlock.BindTCP(extractPort(section.BindAddress)))
case *wireproxy.TCPClientTunnelConfig:
rules = append(rules, landlock.ConnectTCP(uint16(section.BindAddress.Port)))
case *wireproxy.Socks5Config:
rules = append(rules, landlock.BindTCP(extractPort(section.BindAddress)))
}
}
panicIfError(landlock.V4.BestEffort().RestrictNet(rules...))
}

@VastBlast
Copy link
Author

To comply with current architecture this also needs a landlock config rules section

func lockNetwork(sections []wireproxy.RoutineSpawner, infoAddr *string) {
var rules []landlock.Rule
if infoAddr != nil && *infoAddr != "" {
rules = append(rules, landlock.BindTCP(extractPort(*infoAddr)))
}
for _, section := range sections {
switch section := section.(type) {
case *wireproxy.TCPServerTunnelConfig:
rules = append(rules, landlock.ConnectTCP(extractPort(section.Target)))
case *wireproxy.HTTPConfig:
rules = append(rules, landlock.BindTCP(extractPort(section.BindAddress)))
case *wireproxy.TCPClientTunnelConfig:
rules = append(rules, landlock.ConnectTCP(uint16(section.BindAddress.Port)))
case *wireproxy.Socks5Config:
rules = append(rules, landlock.BindTCP(extractPort(section.BindAddress)))
}
}
panicIfError(landlock.V4.BestEffort().RestrictNet(rules...))
}

I looked into this but there seems to be no specific method for restricting UDP bindings/connects similar to TCP. As of right now go-landlock only has TCP.

@cob-web-corner
Copy link

cob-web-corner commented Jan 4, 2025

Ah sorry I thought this already hit kernel, it appears it did not.

https://lore.kernel.org/all/[email protected]/
landlock-lsm/linux#10

Latest dec 24th
https://lwn.net/Articles/1002224/

There was plans to follow up in landlock with udp support.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants