Skip to content

Commit 49b889b

Browse files
committed
Deprecate -F, --rules-data and --rules-file args
Since we already have a pretty concise rule specification format, there really is no need to specify YAML or JSON *inline* via the -F/--rules-data argument, since the -r argument is superior in every way, given that YAML is whitespace/newline-sensitive. Another point is that the --rules-file argument always sounded a bit weird (is it "rules file" or "rule file"?) and just calling it --file is much less awkward and also unambiguous since all that can be passed via file are rules, similar to patterns for grep and its -f/--file option. Right now, the -f/--file option still reads YAML and doesn't yet recognise a newline separated list of rules. The implementation will be a little bit trickier, since we want to keep the same command line argument but allow for both formats to coexist and simply display a deprecation warning for YAML. The reason why I decided to remove YAML entirely is because when using ip2unix in practice, I did not have even *one* occasion where such a rule file would be helpful and instead just used the -r arguments. Since the rule file was implemented first, the option names are still unchanged to date, but when introducing the -r command line option, I decided to go for shorter names instead. This however is a bit confusing if you're used to -r and suddenly have to use entirely different option names for the rule files, so it's just one additional reason to remove it entirely. Signed-off-by: aszlig <[email protected]>
1 parent b54905a commit 49b889b

File tree

5 files changed

+144
-199
lines changed

5 files changed

+144
-199
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog], and this project adheres to
55
[Semantic Versioning].
66

7+
## [Unreleased]
8+
9+
### Added
10+
- Deprecation warnings if rules are specified in YAML format.
11+
712
## [2.1.3] - 2020-06-01
813

914
### Fixed
@@ -93,6 +98,7 @@ The format is based on [Keep a Changelog], and this project adheres to
9398
- The initial release, which evolved from an early prototype specific to a
9499
certain use case into a more generic command line tool.
95100

101+
[Unreleased]: https://github.com/nixcloud/ip2unix/compare/v2.1.3...HEAD
96102
[2.1.3]: https://github.com/nixcloud/ip2unix/compare/v2.1.2...v2.1.3
97103
[2.1.2]: https://github.com/nixcloud/ip2unix/compare/v2.1.1...v2.1.2
98104
[2.1.1]: https://github.com/nixcloud/ip2unix/compare/v2.1.0...v2.1.1

README.adoc

Lines changed: 58 additions & 173 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,8 @@ ip2unix - Turn IP sockets into Unix domain sockets
1919

2020
[verse]
2121
*ip2unix* [*-v*...] [*-p*] *-f* 'RULES_FILE' 'PROGRAM' ['ARGS'...]
22-
*ip2unix* [*-v*...] [*-p*] *-F* 'RULES_DATA' 'PROGRAM' ['ARGS'...]
2322
*ip2unix* [*-v*...] [*-p*] *-r* 'RULE' [*-r* 'RULE']... 'PROGRAM' ['ARGS'...]
2423
*ip2unix* [*-v*...] [*-p*] *-c* *-f* 'RULES_FILE'
25-
*ip2unix* [*-v*...] [*-p*] *-c* *-F* 'RULES_DATA'
2624
*ip2unix* [*-v*...] [*-p*] *-c* *-r* 'RULE' [*-r* 'RULE']...
2725
*ip2unix* *-h*
2826
*ip2unix* *--version*
@@ -87,8 +85,8 @@ Executes a program and converts IP to Unix domain sockets at runtime based on a
8785
list of rules, either given via short command line options (see {rulespec}) or
8886
via a file with a list of rules (see {rulefileformat}). The first matching rule
8987
causes *ip2unix* to replace the current IP socket with a Unix domain socket
90-
based on the options given. For example if a <<rule-socket-path,*socketPath*>>
91-
is specified, the Unix domain socket will bind or listen to the given path.
88+
based on the options given. For example if a <<rule-socket-path,*path*>> is
89+
specified, the Unix domain socket will bind or listen to the file given.
9290

9391
ifndef::manmanual[]
9492

@@ -149,6 +147,8 @@ endif::[]
149147
* https://mesonbuild.com/[Meson], at least version 0.46.0.
150148
* https://ninja-build.org/[Ninja], at least version 1.5.
151149
* https://github.com/jbeder/yaml-cpp[yaml-cpp], at least version 0.5.0
150+
Requirement will be removed in *ip2unix* version 3, since the YAML rule file
151+
format is deprecated.
152152
* {cpp} compiler supporting {cpp}17 (https://gcc.gnu.org/[GNU G++] version 7.0
153153
onwards).
154154
* https://www.python.org/[Python] 3, at least version 3.6 is needed for running
@@ -368,12 +368,9 @@ ifdef::manmanual[]
368368
A single rule for one particular socket to match, can be used several times
369369
to specify a set of rules similar to the sequence of the rule file.
370370

371-
*-f, --rules-file*='RULES_FILE'::
372-
Specifies a YAML or JSON file consisting of a sequence of rules.
373-
374-
*-F, --rules-data*='RULES_DATA'::
375-
Similar to *-f*, but instead of specifying a file, directly pass the contents
376-
as an argument.
371+
*-f, --file*='FILE'::
372+
Read rules from 'FILE', which contains a newline-separated list of rules as
373+
specified via `-r`.
377374

378375
*-v, --verbose*::
379376
Increases the level of verbosity, according to the following table:
@@ -403,18 +400,21 @@ just use two consecutive backslashes instead.
403400
The following flags are available:
404401

405402
*in* | *out*::
406-
Corresponds to the <<rule-opt-direction,*direction*>> rule file option and
407-
if it is not set, both incoming and outgoing connections are matched.
403+
Whether this rule applies to a server-side socket (`in`), a client-side
404+
socket (`out`) or both if neither `in` nor `out` is specified.
408405

409406
*tcp* | *udp*::
410-
Either match TCP or UDP sockets or both if none of these flags are set
411-
(<<rule-opt-type,*type*>> rule file option).
407+
Specifies the IP type, which currently is either `tcp` for TCP sockets, `udp`
408+
for UDP sockets or if it is not defined it matches both UDP and TCP sockets.
412409

413410
ifndef::without-systemd[]
414411
*systemd*[='FD_NAME']::
415-
Enable systemd socket activation
416-
(see <<rule-opt-socket-activation,*socketActivation*>> below), optionally
417-
specifying a file descriptior name (<<rule-opt-fdname,*fdName*>>).
412+
Use the socket passed along via file descriptor by systemd instead of
413+
creating one.
414+
+
415+
An optional file descriptor name ('FD_NAME') can be specified to
416+
distinguish between several socket units. This corresponds to the {fdname}
417+
systemd socket option.
418418
endif::[]
419419

420420
*reject*[='ERRNO']::
@@ -427,153 +427,48 @@ endif::[]
427427
without the application noticing.
428428

429429
*ignore*::
430-
Don't handle the socket matching this rule, see the corresponding rule file
431-
option <<rule-opt-ignore,*ignore>>.
430+
Prevents a socket from being converted to a Unix domain socket if this is
431+
set. This is useful to exempt specific sockets from being matched when
432+
another rule matches a broad scope.
432433

433434
These options are available:
434435

435436
*addr*[*ess*]='ADDRESS'::
436-
Optional, specifies an IPv4 or IPv6 address, see
437-
<<rule-opt-address,*address*>> rule file option.
437+
The IP address to match, which can be either an IPv4 or an IPv6 address.
438438

439439
*port*='PORT'[-'PORT_END']::
440-
Optional, specifies a port to match, see the <<rule-opt-port,*port*>> and
441-
optionally the <<rule-opt-port-end,*portEnd*>> rule file option if you want
442-
to specify a port range.
443-
444-
*path*='SOCKET_PATH'::
445-
The path to the socket file to either bind or connect to, which is similar to
446-
the <<rule-socket-path,*socketPath*>> rule file option but also allows
447-
relative paths.
448-
449-
== Rule file format
450-
451-
The rule file (specified via *-f* is a YAML file (or JSON, as it is a subset of
452-
YAML), consisting of an array of objects.
453-
454-
Each object consists of keys/values which define which IP sockets to match
455-
and which Unix domain sockets to assign them to.
456-
457-
=== Rule file options
458-
459-
[[rule-opt-direction]]*direction*::
460-
461-
Whether this rule applies to a server-side socket (`incoming`), a client-side
462-
socket (`outgoing`) or both if not defined.
463-
464-
[[rule-opt-type]]*type*::
465-
466-
Specifies the IP type, which currently is either `tcp` for TCP sockets, `udp`
467-
for UDP sockets or if it is not defined it matches both UDP and TCP sockets.
468-
469-
[[rule-opt-address]]*address*::
470-
471-
The IP address to match, which can be either an IPv4 or an IPv6 address.
472-
473-
[[rule-opt-port]]*port*::
474-
475-
UDP or TCP port number (depending on which <<rule-opt-type,*type*>> is set),
476-
which for outgoing connections specifies the target port and for incomping
477-
connections the port that the socket is bound to.
478-
479-
[[rule-opt-port-end]]*portEnd*::
480-
481-
Optionally specifies the end of a port range to match, so for example if
482-
<<rule-opt-port,*port*>> is `2000` and *portEnd* is `3000` all ports in the
483-
range from 2000 to 3000 (inclusive) are matched.
484-
485-
[[rule-socket-path]]*socketPath*::
440+
UDP or TCP port number which for outgoing connections specifies the target
441+
port and for incomping connections the port that the socket is bound to.
442+
+
443+
If a range is specified by separating two port numbers via `-`, the given
444+
range is matched instead of just a single port. The range is inclusive, so if
445+
`2000-3000` is specified, both port 2000 and port 3000 are matched as well.
486446

487-
The path to the socket file to use for either binding or connecting to
488-
depending on whether the above options apply for a particular IP socket.
447+
[[rule-socket-path]]*path*='SOCKET_PATH'::
448+
The path to the socket file to either bind or connect to.
489449
+
490-
Placeholders are allowed here and those are substituted accordingly:
450+
Placeholders are allowed here and are substituted accordingly:
491451
+
492452
[horizontal]
493453
*%p*;; port number
494454
*%a*;; IP address or `unknown`
495455
*%t*;; socket type (`tcp`, `udp` or `unknown`)
496456
*%%*;; verbatim `%`
497457

498-
ifndef::without-systemd[]
499-
[[rule-opt-socket-activation]]*socketActivation*::
500-
ifndef::manmanual[]
501-
If *ip2unix* is compiled with systemd support, whether to use socket activation
502-
endif::[]
503-
ifdef::manmanual[]
504-
Whether to use systemd socket activation
505-
endif::[]
506-
instead of a <<rule-socket-path,*socketPath*>>. See {systemd_socket}.
507-
508-
[[rule-opt-fdname]]*fdName*::
509-
An optional file descriptor name for socket activation which can be used to
510-
distinguish between several socket units. This corresponds to the {fdname}
511-
systemd socket option.
512-
endif::[]
513-
514-
[[rule-reject]]*reject*::
515-
If true, reject calls to *connect* and *bind* with `EACCES`.
516-
517-
*rejectError*::
518-
Specifies an alternative error code to be returned by
519-
<<rule-reject,*reject*>> instead of `EACCES`. This can be either a string
520-
such as `EADDRINUSE` (case does not matter) or an integer.
521-
522-
*blackhole*::
523-
If true, a temporary file system path is used and unlinked shortly
524-
thereafter, so the socket is effectively deactivated in a way that the
525-
application should not recognize. Only valid if
526-
<<rule-opt-direction,*direction*>> is `incoming`.
527-
528-
[[rule-opt-ignore]]*ignore*::
529-
Prevents a socket from being converted to a Unix domain socket if this is
530-
true. This is useful to exempt specific sockets from being matched when
531-
another rule matches a broad scope.
532-
533458
== Examples
534459

535460
=== Simple HTTP client/server
536461

537-
On the server side with the rule file `rules-server.yaml`:
538-
539-
[source,yaml]
540-
---------------------------------------------------------------------
541-
- direction: incoming
542-
socketPath: /tmp/test.socket
543-
---------------------------------------------------------------------
544-
545462
The following command spawns a small test web server listening on
546463
`/tmp/test.socket`:
547464

548-
[source,sh-session]
549-
---------------------------------------------------------------------
550-
$ ip2unix -f rules-server.yaml python3 -m http.server 8000
551-
---------------------------------------------------------------------
552-
553-
The same can be achieved using *-r*:
554-
555465
[source,sh-session]
556466
---------------------------------------------------------------------
557467
$ ip2unix -r in,path=/tmp/test.socket python3 -m http.server 8000
558468
---------------------------------------------------------------------
559469

560-
On the client side with `rules-client.yaml`:
561-
562-
[source,yaml]
563-
---------------------------------------------------------------------
564-
- direction: outgoing
565-
socketPath: /tmp/test.socket
566-
---------------------------------------------------------------------
567-
568-
This connects to the test server listening on `/tmp/test.socket`
569-
and should show the directory listing:
570-
571-
[source,sh-session]
572-
---------------------------------------------------------------------
573-
$ ip2unix -f rules-client.yaml curl http://1.2.3.4/
574-
---------------------------------------------------------------------
575-
576-
With the *-r* option:
470+
This connects to the above test server listening on `/tmp/test.socket` and
471+
should show a directory listing:
577472

578473
[source,sh-session]
579474
---------------------------------------------------------------------
@@ -582,48 +477,37 @@ $ ip2unix -r out,path=/tmp/test.socket curl http://1.2.3.4/
582477

583478
=== More complicated example
584479

585-
[source,yaml]
480+
For example the following could be put into a file given by the *-f* command
481+
line argument:
482+
586483
--------------------------------------------
587-
- direction: outgoing ## <1>
588-
port: 53
589-
ignore: true
590-
- direction: outgoing ## <2>
591-
type: tcp
592-
socketPath: /run/some.socket
593-
- direction: incoming ## <3>
594-
address: 1.2.3.4
595-
socketPath: /run/another.socket
596-
- direction: incoming ## <4>
597-
port: 80
598-
address: abcd::1
599-
blackhole: true
600-
- direction: incoming ## <5>
601-
port: 80
602-
reject: true
603-
rejectError: EADDRINUSE
484+
out,port=53,ignore
485+
out,tcp,path=/run/some.socket
486+
in,addr=1.2.3.4,path=/run/another.socket
487+
in,port=80,address=abcd::1,blackhole
488+
in,port=80,reject=EADDRINUSE
604489
ifndef::without-systemd[]
605-
- direction: incoming ## <6>
606-
type: tcp
607-
port: 22
608-
socketActivation: true
609-
fdName: ssh
490+
in,tcp,port=22,systemd=ssh
610491
endif::without-systemd[]
611492
--------------------------------------------
612493

613-
<1> All outgoing connections to port 53 (no matter if it's TCP or UDP) will not
614-
be converted into Unix domain sockets.
615-
<2> This rule will redirect all TCP connections except to port 53 (see above)
616-
to use the Unix domain socket at `/run/some.socket`.
617-
<3> Matches the socket that listens to any port on the IPv4 address `1.2.3.4`
618-
and instead binds it to the Unix domain socket at `/run/another.socket`.
619-
<4> The application may bind to the IPv6 address `abcd::1` on port 80 but it
620-
will not receive any connections, because no socket path exists.
621-
<5> Trying to bind to port 80 on addresses other than `abcd::1` will result
622-
in an `EADDRINUSE` error.
494+
Each line corresponds to a single rule, that is processed in order of
495+
appearance and the above example would result in the following:
496+
497+
. All outgoing connections to port 53 (no matter if it's TCP or UDP) will not
498+
be converted into Unix domain sockets.
499+
. This rule will redirect all TCP connections except to port 53 (see above) to
500+
use the Unix domain socket at `/run/some.socket`.
501+
. Matches the socket that listens to any port on the IPv4 address `1.2.3.4` and
502+
instead binds it to the Unix domain socket at `/run/another.socket`.
503+
. The application may bind to the IPv6 address `abcd::1` on port 80 but it will
504+
not receive any connections, because no socket path exists.
505+
. Trying to bind to port 80 on addresses other than `abcd::1` will result in an
506+
`EADDRINUSE` error.
623507
ifndef::without-systemd[]
624-
<6> Will prevent the TCP socket that would listen on port 22 to not listen at
625-
all and instead use the systemd-provided file descriptor named `ssh` for
626-
operations like {syscall_accept}.
508+
. Will prevent the TCP socket that would listen on port 22 to not listen at all
509+
and instead use the systemd-provided file descriptor named `ssh` for
510+
operations like {syscall_accept}.
627511
endif::[]
628512

629513
The same can be achieved solely using *-r* commandline arguments:
@@ -634,6 +518,7 @@ The same can be achieved solely using *-r* commandline arguments:
634518
$ ip2unix -r out,port=53,ignore \
635519
-r out,tcp,path=/run/some.socket \
636520
-r in,addr=1.2.3.4,path=/run/another.socket \
521+
-r in,port=80,address=abcd::1,blackhole \
637522
-r in,port=80,reject=EADDRINUSE {systemd_backslash}
638523
ifndef::without-systemd[]
639524
-r in,tcp,port=22,systemd=ssh

0 commit comments

Comments
 (0)