
Show HN: ip2unix – Turn IP sockets into Unix domain sockets - aszlig
https://github.com/nixcloud/ip2unix
======
Tepix
This is very clever. Last time i ran benchmarks (several years ago), UNIX
domain sockets were twice as fast as IP sockets so that's another reason to
use them.

~~~
easytiger
Isn't a TCP socket fastpathed on loopback ranges anyway?

~~~
aszlig
There was a patch[1] a few years ago, but apparently it didn't make it into
mainline. At least looking in net/ipv4/tcp.c I haven't found any traces
related to that.

However, I could have sworn that I've seen a similar patch in recent years,
but either my memories are serving me wrong or I simply can't find it anymore.

Nevertheless, I didn't benchmark whether this is the case, nor was performance
the main goal for writing ip2unix. So if performance is a concern, maybe
benchmark with your specific workload?

[https://www.spinics.net/lists/netdev/msg210741.html](https://www.spinics.net/lists/netdev/msg210741.html)

~~~
easytiger
Interesting. Thanks

------
steigr
I do not see an advantage over socat, which can listen on _TCP_-sockets (among
20 other „socket“ inputs) and forward them into unix-sockets. Please tell me?
:-/

~~~
aszlig
As others have mentioned, socat acts more like a router between different
socket types/protocols but it doesn't change the behaviour of the program in
question.

So for example if you have a service listening to TCP port 1234, you could do
something like this:

socat UNIX-LISTEN:foo.sock TCP:localhost:1234

Now the service will _still_ listen to port 1234 and you now have _another_
socket that redirects to the other. This not only comes with a bit of
overhead, but port 1234 is still reachable.

While using packet filtering on that port might lower the attack surface a
bit, this won't prevent other (possibly compromised) services/users on the
system to access port 1234.

Sure you could also filter based on uid, but IMHO it's better if that port
isn't accessible in the first place.

------
floatboth
Very nice!

// "LD_PRELOAD" should've been in the submission title to avoid the "socat"
questions

~~~
aszlig
Thanks a lot for the suggestion. While I can't change the title here on HN,
the README now mentions LD_PRELOAD in the first paragraph and I also added a
small FAQ[1] section about socat.

[1]:
[https://github.com/nixcloud/ip2unix/tree/d7d297ed68cdadc65dc...](https://github.com/nixcloud/ip2unix/tree/d7d297ed68cdadc65dc684ddccc0b32cc5f3b1cc#frequently-
asked-questions)

------
kevincox
This is really cool. I run a lot of different services on my home server and
don't trust them to the internet. Everything is accessed via a reverse proxy
with authentication that I trust.

While listening on localhost is some level of security it still means that
lateral movement is possible if one of the services is compromised. It also
means that if I give give someone else a user account or similarly run any
less trusted code then they can access all of the services without
authentication.

I'm going to look into this an apply this so that these services aren't
accessible by other users.

------
forty
very interesting. A docker integration would be fun too (something like
"docker run -p /tmp/socket:8080 ...") :)

~~~
aszlig
I'm not very familiar with Docker, but wouldn't something like "docker run
some_image ip2unix -r /tmp/socket:8080 ..." work?

~~~
forty
You could but it means: \- you need to add ip2unix in your images, which is
not always convenient \- you still need to expose the socket outside the
container (which is doable with volumes, but permissions can be a mess,
especially if you use user namespaces)

------
tenebrisalietum
So how do I access a unix socket in my browser? Be nice if
"unix://file/path.html" worked.

~~~
aszlig
You could map different ports to specific socket file names and use a dummy
address, eg. like this:

ip2unix -r out,addr=127.1.1.1,path=foo-%p.sock firefox --new-instance

Whenever you then head over to something like
[http://127.1.1.1:9000/](http://127.1.1.1:9000/), the browser will try to
connect to foo-9000.sock.

------
caf
Do any programs get confused when they call getsockname() and the result is an
AF_UNIX they weren't expecting?

~~~
aszlig
If programs call getsockname() the result is _not_ a sockaddr_un, but instead
sockaddr_in(6) is used from the original call to bind(). If the socket was
implicitly bound, a random[1] address is generated.

Things are a bit trickier if it gets to getpeername(), since we want to have
somewhat stable addresses. This is done by querying SO_PEERCRED and
encoding[2] the pid for IPv4 or pid, uid and gid for IPv6 into the address.

In summary: Programs shouldn't get confused, but if they do, it's certainly a
bug in ip2unix. Feel free to open an issue :-)

[1]:
[https://github.com/nixcloud/ip2unix/blob/d7d297ed68cdadc65dc...](https://github.com/nixcloud/ip2unix/blob/d7d297ed68cdadc65dc684ddccc0b32cc5f3b1cc/src/sockaddr.cc#L133-L152)

[2]:
[https://github.com/nixcloud/ip2unix/blob/d7d297ed68cdadc65dc...](https://github.com/nixcloud/ip2unix/blob/d7d297ed68cdadc65dc684ddccc0b32cc5f3b1cc/src/sockaddr.cc#L110-L131)

------
noobquestion81
This is kinda awesome... Only request is a ptrace version, that will work on
all binaries.

~~~
aszlig
[https://github.com/nixcloud/ip2unix/commit/00dddf228a70ad230...](https://github.com/nixcloud/ip2unix/commit/00dddf228a70ad2309879eef202698ed33a6e1b6)

That's what I had in mind someday™. Unfortunately, this has to wait for
version 4.x maybe :-/

------
lykr0n
Now that's cool. Functional and simple to use.

------
eiro
is there a benefit over socat?

~~~
Mic92
It is faster because socat creates additional copies/context switches when
forwarding data. This tool changes the bind syscall so it becomes a unix
socket in the first place.

