Hacker News new | past | comments | ask | show | jobs | submit login

Every connection you make to a remote service "exfiltrates data". Modern TLS is just as opaque to middleboxes as WireGuard is, unless you add security telemetry directly to endpoints --- and then you don't care about the network anyways, so just monitor the endpoint.

The reason you'd use WireGuard rather than TLS is that it allows you to talk directly to multiple services, using multiple protocols (most notably, things like Postgres and Redis) without having to build custom serverside "gateways" for each of those protocols.




Adding your own network stack to bypass limitations like this works exactly until the point where someone notices that your userspace stack needs to fulfill the same requirements that the host stack does.

And then you're suddenly in a whole world of pain because all of this is driven by a stack of byzantine certifications (half of which, as usual, are bogus, but that doesn't help you), and your network stack has none of them.

(Written from first-hand experience.)


Any tips I'm a beginner


I think the point was more that doing this as a way to avoid the red tape of getting permission to open a new connection is odd?


I understand the impulse, but I think it misconstrues the "red tape" this method avoids. It's sidestepping a quirky OS limitation, which dates back to an era of "privileged ports" and multi-user machines. It's not really sidestepping any sort of modern policy boundary. For instance: you could do the exact same thing with WebSockets (and people do).


I was thinking websockets; though, I thought those largely hit the same criticisms? That is, tons of things moved to them specifically to avoid any firewall rules about what they were allowed to send over a network.

I'll fully grant that that seems to be the norm for everything browser related. Policies got difficult to install new software, just point your browser to this url and call it a day.


I was thinking websockets; though, I thought those largely hit the same criticisms? That is, tons of things moved to them specifically to avoid any firewall rules about what they were allowed to send over a network.

Arguably, this basic phenomenon has been going on for 20+ years. A lot of people by 2005-2007 or so had come to belive (and probably correctly) that a lot of the impetus for adopting SOAP based web-services over the preceding few years was simply because everything ran over ports 80 and 443 which were already open in the firewall. So deploying a remote service this way was more tractable than submitting a request to allow access to yet another port in firewall, and deal with the inevitable bureaucratic nightmare of getting that approved.


You can also sidestep that "quirky OS limitation" by just setting the first unprivileged port to 0(ip_unprivileged_port_start), no need for an new stack.

https://www.kernel.org/doc/Documentation/networking/ip-sysct...


You can do that. Random programs cannot. Our CLI, which also does user-mode WireGuard and TCP/IP, doesn't even want to run under sudo. You're seeing the point, now: you want to build interesting network features that work the same way everywhere without demanding that your users be system administrators. Hence: user-mode TCP/IP.


I'm still not seeing the point sadly.

If you're running on a system you don't administrate that has ports under 1024 set as privileged, there's no way(with or without your cli) to have a userspace program receive TCP or UDP packets coming into the kernel from external devices for these ports(unless I'm completely mistaken).

What can you accomplish with "user-mode TCP/IP" that you can't from userspace with system calls?


You are completely mistaken. You can do literally anything you want with TCP/IP provided you can talk UDP on any port, by running a user-mode TCP/IP stack over WireGuard on that port.


I don't think you understand, and based on your reply it doesn't sound like I'm mistaken.

With this CLI I am able to listen for external packets to port 80 from userspace without any elevated permissions and intercept traffic that's going to an application that's bound to that port on the OS?

Edit: I think I understand what you're trying to do, but if I do then traffic is going from the kernel UDP stack to the userland TCP stack, back to the UDP kernel stack. Not sure how that avoids sending the packet to the kernel. If it's to get around the port restrictions, why can you not just use unprivileged ports?


I'm not sure I can make this any simpler for you or easier to get your head around. If it helps: the idea here is giving an invocation of your program its own IP address. It can then do whatever it likes with TCP/IP for that address; its own routing, arbitrary protocols, whatever. The Go standard library makes it extremely easy to integrate. To the OS, it's all just ordinary socket code.


> the idea here is giving an invocation of your program its own IP address

I understand that, I just don't understand any case where that's desirable...

We have 2^32 ports available to applications(and a special `0` port that can be used to request any port) on a single IP(which is usually shared between multiple machines). I have never heard of a case where 2^32 ports is not enough ports for the number of applications that need to be listening.

> To the OS, it's all just ordinary socket code.

Which is what I don't understand. Why not just use ordinary socket code without all of these additional LoC in between that open you up to more bugs(security and functionality).


I think it is a valid question on why not use unprivileged ports, though? Or am I also missing something?


"Unprivileged ports" is just a case in point for everything you would need privileges to do, from binding arbitrary ports to adding arbitrary addresses and running local servers on them, etc, etc, etc. The point is: turning "complicated" network features that require privilege into simple unprivileged socket code.


Right, per my other thread below, my understanding was the "privileged" ports were mainly ones that were allowed for off machine communication by standard policy/convention long time ago. As such, using higher number ports should be just as easy in the code as using lower ports, outside of the discovery that was implied by following the other conventions. But, introducing new network addresses seems to have already side stepped the discovery affordances?

I'll offer the same caveat here, btw, I am not trying to torpedo the idea of trying this. I'm genuinely curious why you would need to do this. Not necessarily why you would want to.


We did it because we run WireGuard gateways to the public cloud we operate, and our CLI wants to talk to things on customer networks (like remote Docker server instances to build new versions of apps). Our options were:

* Do user-mode WireGuard (and thus TCP/IP) and talk "natively" to the infrastructure deployed on our platform.

* Write case-by-case application gateways for each of those pieces of infrastructure tunneled somehow through HTTP.


Number one reason is if you can't. Number two is if you don't want to.

You can't if your organization prevents you to, for example.

You don't want to if you follow strict rules which are not enforced by the OS, again for example.


I'm curious why you couldn't?

And if you don't want to, that feels misguided?

Granted, my old recollection was largely that the "privileged" ports were that way because they were blessed by the routing tables, at the time. The entire point was that the lower ports were expected to be connectable to external machines. Not shocking if I am out of date there.


Both reasons have nothing to do with technical capability and everything with organisational policies.


Right... but that just seems to imply that this is getting around policies by the letter?

I should hasten to add that I am not offering this as reason this shouldn't be done.


I know this is subtle but if you take a step back, user-mode TCP/IP moots the policies we're talking about; it doesn't subvert them. There are no security or policy implications to e.g. binding a low-numbered port on an IP address unrelated to your physical computer that is allocated directly to a running instance of your program. There are (archaic) implications to binding that port on an actual interface of your machine, because that binding (archaically) stood in for an assertion of identity/authority back in the 1990s.


Sorta? If it renders them moot, why not attack the policies? For that matter, if there are no implications to the number of the port, I'm again forced to ask why not just use the higher numbers? Wouldn't that have let you use the "simplicity of standard socket code" with no extra effort?

(This is also a new use of "moot" to me? You seem to be offering it as a synonym of obsolete? But a "moot" debate is one that is closer to "overcome by events" than one that is not relevant. Right?)


You get that these are just people shipping a program that random people are going to run on random computers, right? If your go-to-market involves "reversing longstanding Unix network policy rules", you have problems.

Respectfully, if at this point the situation hasn't been made clear to you, I don't think there's much more to productively discuss.


Amusingly, I would do an appeal to a word you already used. :D I was treating this as a bit of a moot debate. Discussing it as much for interests in the general discussion.

My impression from something said elsewhere was that this was largely for internal tools. I'm not sure why I got that impression, though.

I think it is fair, btw, that I would be pushing for both paths, at this point? If a long standing network policy rule has become obsolete from advance, it is worth considering dropping it? Is that not something people are looking at?

(I will also note that I will not be at all offended if you drop out from lack of interest here. Apologies if you feel I was wasting your time!)


Doesn't this program need to bind a UDP port on your machine? If policies prevent you binding ports I don't see how you'd be able to use this software...


I have no idea what you're talking about. We're talking about essentially fictitious IP addresses on synthetic machines. I think everyone's talking past each other here.


I don't really think people are talking past eachother, I think we're all trying to understand the point of this, and the article(and marketing on the website) doesn't make it clear at all.

Some potential options for "what is it for" come up, and others bring up reasons why they don't make sense.

It seems this is a solution to a very specific problem that nobody seems to have, which is why when people are trying to figure out what problem it solves they're coming up with 10 better solutions.


When they're talking about classified defense networks, the actual restrictions they mean is least privilege and separation of duties. Devs are not admins. They don't get root privilege on their machines. They can't create virtual network interfaces and they also can't change kernel settings. But if you put a full TCP/IP stack in userspace, well, they can run that and do whatever they want with it.

To answer the upstream question about why arbitary outbound connections are allowed, they're not. This is connecting to a cloud development environment, and I would have to assume this service can be self-hosted, because on a classified network, the "cloud" isn't the cloud as Hacker News readers know it. Amazon et all run private data centers on US military installations that only the military and the IC can access and they're airgapped from the Internet. If you're on a workstation that can access this environment, that's all it can access. The only place you can exfiltrate data to is other military-controlled servers.


If you're talking about developer machines, isn't the best(and easiest) solution to just run a VM that you administer so you can create virtual networks?

If you're talking about production machines, a userspace application wouldn't be able to sniff privileged ports without elevated permissions, so I fail to see how this application would let you get around that limitation.


No, because VMs are expensive and require some base level of system administration to operate, booting them usually requires privilege, and if the only problem you're trying to solve is reliably running (e.g.) Postgres and Redis protocol between your CLI and a server somewhere, it's extreme overkill.


VMs are free and can be run by any semi-competent developer wanting to host a test server on their development machine.

Postgres and Redis can use non-privileged ports, so I don't understand why this would matter.


"Just use a VM" instead of running a Unix command that drives a UDP socket is... a take.


imo a bit milder of a take than "just maintain a second TCP stack instead of hosting on a non-privileged port".

Also are we just ignoring that you pretended VMs were expensive to run? Most of your responses sound devoid of a lot of fundamental computer knowledge(networking and otherwise).


Getting that change onto the system sounds like "at best a big delay and at worst a nonstarter".




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: