IP2UNIX(1) | IP2Unix Manual | IP2UNIX(1) |
NAME¶
ip2unix - Turn IP sockets into Unix domain sockets
SYNOPSIS¶
ip2unix [-v...] [-p] {-r RULE | -f FILE} [-r RULE | -f FILE]... PROGRAM [ARGS...] ip2unix [-v...] [-p] -c {-r RULE | -f FILE} [-r RULE | -f FILE]... ip2unix -h ip2unix --version
DESCRIPTION¶
Executes a program and converts IP to Unix domain sockets at runtime via LD_PRELOAD (see ld.so(8)) based on a list of rules, either given via short command line options (see RULE SPECIFICATION) or via a file containing a list of rules separated via newline. The first matching rule causes ip2unix to replace the current IP socket with a Unix domain socket based on the options given. For example if a path is specified, the Unix domain socket will bind or listen to the file given.
OPTIONS¶
-c, --check
-h, --help
--version
-p, --print
-r, --rule=RULE
-f, --file=FILE
-v, --verbose
FATAL (default)
ERROR (-v)
WARNING (-vv)
INFO (-vvv)
DEBUG (-vvvv)
TRACE (-vvvvv)
RULE SPECIFICATION¶
Arguments specified via -r contain a comma-separated list of matches and a single action of what to do when a match is found. If a value contains a comma (,), it has to be escaped using a backslash (\) character. If you want to have a verbatim backslash character just use two consecutive backslashes instead.
Matches¶
The following matches are available:
in | out
tcp | udp | stream | d[ata]gram
addr[ess]=ADDRESS
port=PORT[-PORT_END]
If a range is specified by separating two port numbers via -, the given range is matched instead of just a single port. The range is inclusive, so if 2000-3000 is specified, both port 2000 and port 3000 are matched as well.
from-unix=PATTERN
The syntax for PATTERN is similar to glob(7) and allows the following wildcards:
? | Match any single character except / |
* | Match zero or more characters except / |
** | Match zero or more path components, eg. a/**/z matches a/z, a/b/z, a/b/cde/z, a/b/c/c/d/z and so on |
[...] | Match a single character via a series of either verbatim characters or ranges, eg. [a-cijq-s] matches either a, b, c, i, j, q, r or s |
[!...] | Same as above, but negates the match |
\X | Remove the special meaning of the character X, eg. \? literally matches ? |
from-abstract=PATTERN
Actions¶
reject[=ERRNO]
blackhole
Technically, this means that we bind to a Unix socket using a temporary file system path and unlink it shortly thereafter.
ignore
path=SOCKET_PATH
Placeholders are allowed here and are substituted accordingly:
%p | port number or unknown if not an IP socket |
%a | IP address or unknown if not an IP socket |
%t | socket type (tcp, udp or unknown if it’s neither a stream nor datagram socket) |
%% | verbatim % |
noremove
This works around an issue with more complex programs that spawn subprocesses or threads without sharing memory or cloning the file descriptor table. In some scenarios ip2unix might be unable to correctly track sockets and might accidentally remove the socket file too early.
abstract=NAME
The placeholders supported in path are also supported here.
systemd[=FD_NAME]
An optional file descriptor name (FD_NAME) can be specified to distinguish between several socket units. This corresponds to the FileDescriptorName (see systemd.socket(5)) systemd socket option.
RULE MATCHING BEHAVIOUR¶
Each rule is matched in the specified order and the first socket (regardless of specificity) that matches is either turned into a Unix domain socket, blackholed, rejected or ignored depending on the action specified.
If a listening socket is matched by the same rule multiple times, subsequent sockets are automatically blackholed (that is, deactivated without the application noticing). The reason for doing this is that it requires fewer rules for common things, such as for example handling services that bind to both IPv4 and IPv6 addresses.
Let’s say we have someprogram, which binds to 127.0.0.1:1234 and [::1]:1234 in that order. All we need to do here is match on port 1234 and only the first (127.0.0.1:1234) socket will actually bind to /foo/bar, the second ([::1]:1234) will be blackholed and is not reachable:
$ ip2unix -r in,port=1234,path=/foo/bar someprogram
Note that this is only the case if both end up using the same socket path. If instead something like this is used, none of the two sockets is blackholed:
$ ip2unix -r in,port=1234,path=/foo/bar-%a someprogram
This will result in two sockets:
The reason we blackhole subsequent sockets that lead to the same part is to make the common case less verbose to express.
If we would not blackhole the socket and the matcher would simply fall through to the next rule, the following would be required to achieve the same behaviour that we have in the first example:
$ ip2unix -r in,port=1234,path=/foo/bar -r in,port=1234,blackhole someprogram
EXAMPLES¶
Simple HTTP client/server¶
The following command spawns a small test web server listening on /tmp/test.socket:
$ ip2unix -r in,path=/tmp/test.socket python3 -m http.server 8000
This connects to the above test server listening on /tmp/test.socket and should show a directory listing:
$ ip2unix -r out,path=/tmp/test.socket curl http://1.2.3.4/
More complicated example¶
For example the following could be put into a file given by the -f command line argument:
out,port=53,ignore out,tcp,path=/run/some.socket in,addr=1.2.3.4,path=/run/another.socket in,port=80,address=abcd::1,blackhole in,port=80,reject=EADDRINUSE in,tcp,port=22,systemd=ssh
Each line corresponds to a single rule, that is processed in order of appearance and the above example would result in the following:
The same can be achieved solely using -r commandline arguments:
$ ip2unix -r out,port=53,ignore \
-r out,tcp,path=/run/some.socket \
-r in,addr=1.2.3.4,path=/run/another.socket \
-r in,port=80,address=abcd::1,blackhole \
-r in,port=80,reject=EADDRINUSE \
-r in,tcp,port=22,systemd=ssh
LIMITATIONS¶
However, if this really is an issue to you, the recommended workaround is either to use ip2unix to wrap the client (if it supports IP sockets) or fix the server to natively use Unix domain sockets.
SEE ALSO¶
accept(2), bind(2), connect(2), listen(2), recvfrom(2), recvmsg(2), sendmsg(2), sendto(2), socket(2), glob(7), unix(7), systemd.socket(5)
AUTHOR¶
Written by aszlig <aszlig@nix.build>
COPYRIGHT¶
Copyright (C) 2018 aszlig. License LGPLv3: GNU LGPL version 3 only https://www.gnu.org/licenses/lgpl-3.0.html.
This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law.
November 2018 | IP2Unix 2.2.1 |