Great little tool!
I use it to selectively proxy Firefox tabs using multi-account containers to a home router that speaks Wireguard (but no application-layer proxying protocol or SSH).
Great little tool!
I use it to selectively proxy Firefox tabs using multi-account containers to a home router that speaks Wireguard (but no application-layer proxying protocol or SSH).
Is there completely userspace server implementation? Without tun/tap devices, etc. I guess some kind of userspace IP stack is necessary for that, although not sure.
I believe it uses the latter, but the missing piece is a userspace TCP/IP stack, since otherwise you'd need TUN device permissions to bridge over the impendence mismatch of sockets and IP packets containing TCP/UDP segments/datagrams.
It uses gVisor for that.
Ugh, now this is driving me crazy. So I'm 99% sure that that exists, but I cannot for the life of me find the link. There's a CDN / edge compute company that gets published on HN semi-regularly that has this sweet client that... does a lot of things, but among them is connecting to your serverless containers by actually instantiating an entire TCP/IP stack in the application that's hooked up to the remote end over a wireguard proxy that's also in-application...
https://github.com/noisysockets/noisysockets
With that, you can replace a Dialer in Go that connects sockets, effectively wrapping sockets with Wireguard. Since it does that in userspace, you get no tun/tap. This is all open-sourced by @dpeckett
With those things, he also built a userspace wireguard gateway that includes DNS resolution. https://github.com/noisysockets/gateway
Upstream WireGuard (golang) has had this capability for a few years now: https://github.com/WireGuard/wireguard-go/tree/master/tun/ne...
Yep noisysockets is based originally off wireguard-go but is an attempt to simplify and make things a lot more idiomatic for library use. Filling in the gaps etc and improving the ergonomics. Hoping to build a bit of an ecosystem of supporting projects around it, eg. I'm currently working on a STUN server implementation based on the approach described in https://nordsecurity.com/blog/reaching-beyond-1gbps
One of the recent feature divergences from upstream is support for network exit nodes / gateways.
It's really completely in userspace and doesn't need any kernel modules or even superuser permissions for managing TUN/TAP devices (like e.g. OpenSSH's TUN device mode does)!
It uses a userspace TCP/IP stack by Google, as far as I understand.
How's the performance? My memory is that "vanilla" SOCKS is really easy to do (just run ssh with the right option and tell your application to use it) but really slow. I suspect this is mostly for cases where you don't have a normal SOCKS/ssh server, but I'm curious if it offers a benefit there too.
What do you mean by "vanilla" SOCKS, i.e. as opposed to what other type of SOCKS implementation?
For me, SOCKS over SSH has always been pretty performant, unlike e.g. OpenSSH's TUN mode (since that ends up doing TCP over TCP).
By vanilla, I mean `ssh -D`, as opposed to anything else that can offer a SOCKS port without actually transporting over ssh (ex. this project). Last time I compared, that was noticeably slower than wireguard, which yeah I attributed to TCP over TCP being kinda awful.
I'm curious why you refer to 'ssh -D' as 'vanilla SOCKS'?
SOCKS existed before SSH did, and there are SOCKS server implementations that don't rely on SSH.
Ah, well that's quite simple: I'm dumb:) Or ignorant rather. But seriously, until reading your comment it never once occurred to me that it wasn't invented by (open)ssh; I assumed one of the "S"s stood for SSH (probably "SOCKets over Ssh"). And better yet, because that made sense, it never crossed my mind to question it. So, uh, thanks:)
`ssh -D` isn't TCP over TCP, though!
It does multiplex multiple TCP sockets over a single underlying connection though, which can cause increased latency depending on how SSH schedules sends for each individual buffer. (Too fine-grained and you waste a lot of overhead on headers and framing; too coarse and you get head-of-line blocking.)
There are also TCP fairness concerns: In a bottleneck, like a congested home Internet connection's uplink serving n total TCP connections, traffic generally splits equally across TCP flows; if you're multiplexing m SOCKS connections over one SSH connection, all those together seize only 1/n of the bottleneck capacity, i.e. each individual one gets 1/(m*n). An (UDP-based) VPN though would get 1/n of the bandwidth per tunneled TCP flow, i.e. m/n in total.
In a way, `ssh -D` is a bit like HTTP/2 that way, while this tool is more like HTTP/3 / QUIC.
It would be great to compare both. Currently I connect to WireGuard and then create a socks proxy using SSH. And it works surprisingly well. But I'm very interested in this solution.
https://github.com/dariost/soks works better for what I needed to do with wireguard. It does more or less the same thing but it reuses an existing wireguard interface. I detailed my use in this blog post https://www.nicoco.fr/blog/2023/09/10/wireguard/ (yes, shameless plug).
WTF is _this_
Thanks for insightful comment.
(was there a question in it?)
Out of curiosity, why does this work better for you?
I used to do a similar thing using a Docker container on a Raspberry Pi, but being able to run this on any OS and with a guarantee that it won’t accidentally mess up the host’s routing table makes the user space solution a much better choice in my view.
It worked better for me because with some software (eg qbittorrent) you can directly choose the network interface to use, so having a 'standard' wg0 interface is great.
Now I also wanted to re-use this interface for some websites I visited, and the easy way to do that was to configure rules in foxyproxy to use a socks proxy for that, which is where soks come into play.
I don't doubt that wireproxy is useful to many!
This is very different. wireproxy seems to contain a userspace implementation of TCP and Wireguard. soks looks like an IP router than can only handle TCP, replacing routing tables as the control mechanism with something that decides to use or not use a SOCKS5 proxy.
I didn't mean to dismiss wireproxy, I was just sharing where my findings lead me when I set up wireguards tunnel for myself. Apologies if this didn't come out right.
Nice! I was just thinking it would be sweet to have something like this to proxy all my Thunderbird email connections through my Tailscale exit node, without having to direct all my traffic through the exit node.
You can use the tailscale cli as a socks proxy. https://tailscale.com/kb/1113/aws-lambda
If you slap that into a container image and expose the socks port tailscale listens on, bada bing, bada proxy!
Tailscale has app connectors now. You can send all your traffic through certain exit nodes without doing any of this too!
Oh I'll have to try that thanks!
You can also install 3proxy or squid proxy on the machine running the exit node and any machine that is on the tailnet can see use it
Several multi-protocol proxy clients support this functionality, some notable open-source examples include:
- [sing-box](https://github.com/SagerNet/sing-box)
- [clash-meta](https://github.com/muink/Clash.Meta) and other clash-based clients
- [xray](https://github.com/xtls/xray-core)
Close-sourced client include [Surge Mac/iOS](https://nssurge.com/).For people that care, clash + v2ray seems to be the only thing that reliably works in China. While most big VPN providers claim that they work, they don’t. I haven’t spent a lot of time figuring out how it works, but I do like the concept of rule groups to decide which domains the vpn should proxy.
Was about to say this. Those multiprotocol proxies (presumably build to climb the Great Firewall) are an interesting microcosm. Tons of possibilities for obscure traffic routing. Also have android implementations. Used them just to open up a hotspot on a non hotspot SIM and non-rooted android a time ago. I am always wondering how trustworthy they are because they are packing tons of code taken from all over the net and have a quite interesting developer community for obvious reasons.
In the closed-source world, cloudflare's warp can also work in proxy mode. Even the free accounts can work this way after converting the warp config to plain wireguard.
Isn't this already easily achievable with ssh? with 'ssh -D[port] foo@somehost' ssh will act as a SOCKS server.
That's fine if you control the endpoint and want to expose ssh on it, but WireGuard endpoints are also commonly available from VPN providers who don't provide shell access.
That is the situation that lead to me to wireproxy; I had a need to use Cloudflare Warp, and no desire to entrust their apt repository with updates to my system.
Added to that their official client has heaps of functionality I have no use for, and wireproxy does everything I want for this usecase with a comparatively tiny amount of code(5MB vs 400MB built). I started the evening with a wg-quick generated config that required root, and ended it using a simple unprivileged daemon that I can toggle easily.
This hybrid approach addresses a significant user pain point - the ease of routing specific traffic through VPN tunnels. However, while Wireproxy's utility in personal and small-scale deployments is evident, its scalability and security in larger, enterprise-level applications warrant further scrutiny. The reliance on user-space operation, though advantageous for certain aspects of performance and compatibility, introduces potential bottlenecks and security concerns
GPT comment
There really are two completely different uses for VPNs.
One is a connection allowing you access to a private network for whatever purposes, which is what this feature enables.
The other is routing ALL your networking through it to disguise where you're located.
Confusing and confounding the two leads to disaster.
Does it support OpenVPN?
... Um.. what? It's wireguard. It does the wireguard. Are you looking for tunsocks?
tunsocks would work, there also seems to be an openvpn fork with that functionality built in: https://github.com/bendlas/openvpn-tuna
Otherwise you may be able to use SSH's SOCKS proxy mode if you can directly SSH, e.g. ssh -D 3128 user@host .. will listen on port 3128 as a SOCKS proxy.
Neat!
If you want something like this specifically for Mullvad VPN, I've had a good experience with https://github.com/imiric/mullvad-proxy (not my project, just forked it for some updates). What I like is that it embeds the Mullvad CLI tool, so switching servers is trivial, and it's all isolated from the host machine. It's also "just" nginx and some scripts, so it should have good SOCKS5 support.
You can download the "all" config from Mullvad and upload that into stock wireguard. Every Mullvad location becomes available via a huge dropdown in wireguard.
https://mullvad.net/en/blog/wireguard-configuration-tool-has...
Neat! This is a great replacement for my SSH tunnels when I need a different IP.
Somewhat related tool: pproxy, can, among many other things, "convert" different tunnel protocols into each other. Also features routing capabilities. I used it to turn an SSH SOCKS5 into an HTTP proxy. https://github.com/moreati/pproxy
I set up something similar using network namespaces with Wireguard and tinyproxy. But performance wasn't stellar. Interested how this performs.
I was thinking “hey, I bet it would be pretty easy to write something like this in Go”. And of course it’s written in Go!
There's also onetun. https://github.com/aramperes/onetun
I'd really like to see an application level VPN that plays well with Go to `Dial` a `net.Conn` or `Listen` for a `net.Listener` in my Go application.
Would this work for watching video via an Apple TV? Apparently it’s possible to configure the ATV to use SOCKS, but the wireproxy implementation notes mention lack of UDP at the moment. So that would preclude video streaming, correct?
Just a note: sing-box can do the same thing too. (https://sing-box.sagernet.org/configuration/outbound/wiregua...)
TIL multi-account containers allow per-container proxy settings!
Am I correct in thinking it needs a separate extension to set that up, like this one? https://addons.mozilla.org/en-GB/firefox/addon/container-pro...
Edit: I was not correct, which is apparently grounds for downvotes now.
No separate extension needed; it’s right there in the container settings now!
Somebody has the detailed steps in a sibling comment.
Do you mean Firefox has created a version that routes container traffic through proxies without the use of the the Container proxy addon?
Yes! I believe this happened when they made containers natively compatible with “Mozilla VPN”.
They do advertise their own service, but there’s an option to use a custom proxy instead.
You can be downvoted for anything. Walk it off :)
You've misread my intention. I just think the downvotes are funny, and I know such edits attract more :P
It used to, but now I think they added it to the 'main' one.
Would you happen to have any good resources explaining how such a setup could be configured?
I've been using Sidebery and this for container specific proxy configuration and it works fine https://addons.mozilla.org/it/firefox/addon/container-proxy/
I had a socks server running in docker that turned Forticlient, the worst corporate vpn solution ever, into socks so then I could use access the internal urls in one container, still have fast internet elsewhere, and not expose my computer's entire network traffic to Forticrap.
Thanks!
I've done this in the past to assign a different exit node in Mullvad to a given Firefox container.
1. You click the Multi-Account Containers extension icon
2. Select "Manage Containers"
3. Select the container that you want to use for this purpose
4. Click "Advanced proxy settings"
5. Enter the address. For example, `socks://us-nyc-wg-socks5-301.relays.mullvad.net:1080` if I'm using one of Mullvad's NYC servers
This supposes you're already connected to one of Mullvad's wireguard servers.
You can also use the FoxyProxy extension [0] for finer-control or extend this behavior across all tabs.
[0]: https://addons.mozilla.org/en-US/firefox/addon/foxyproxy-sta...
Thank you for the explanation!