The first two patches here I wrote some years ago but never posted - sorry.
The third and fourth allow rpcbind to work with an abstract AF_UNIX
address as preferentially used by recent kernels.
NeilBrown
[PATCH 1/4] manpage: describe use of extra port for broadcast rpc
[PATCH 2/4] rpcbind: allow broadcast RPC to be disabled.
[PATCH 3/4] Listen on an AF_UNIX abstract address if supported.
[PATCH 4/4] rpcinfo: try connecting using abstract address.
From: NeilBrown <[email protected]>
Some people notice the extra privileged UDP port that
rpcbind creates, and wonder what it is for. So add
a section to the man page to explain it.
Signed-off-by: NeilBrown <[email protected]>
---
man/rpcbind.8 | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/man/rpcbind.8 b/man/rpcbind.8
index fbf0ace24b27..6ba318f5ff77 100644
--- a/man/rpcbind.8
+++ b/man/rpcbind.8
@@ -66,6 +66,25 @@ reports the condition and terminates.
The
.Nm
utility can only be started by the super-user.
+.Sh "BROADCAST RPC"
+.Nm
+supports a little-used part of the ONC-RPC specification known as
+Broadcast RPC.
+A client can send a UDP broadcast message to
+.Nm
+on every host on a local subnetwork, and each
+.Nm
+will forward the request to the local service if available.
+Should the service reply,
+.Nm
+will forward that reply back to the originator.
+To support this,
+.Nm
+creates an extra UDP socket bound to an arbitrary privileged port
+number, and uses it to forward requests to local services and to
+receive replies from them.
+When configuring a firewall, the "port 111" sockets may need to
+be accessible through the firewall, but the extra UDP socket does not.
.Sh OPTIONS
.Bl -tag -width indent
.It Fl a
--
2.43.0
From: NeilBrown <[email protected]>
Support for broadcast RPC involves binding a second privileged
port. It is possible that rpcbind might choose a port that some
other service will need, and that can cause problems.
Having this port open increases the attack surface of rpcbind. RPC
replies can be sent to it by any host, and they will only be rejected
once they have been parsed enough to determine that the xid doesn't
match.
Boardcast is not widely used. It is not used at all for NFS. For NIS
(previously yellow pages) it can be used to find a local NIS server,
though this can also be statically configured.
In cases where broadcast-RPC is not needed, it is best to disable the
port. This patch adds a new "-b" option to disable broadcast RPC.
Signed-off-by: NeilBrown <[email protected]>
---
man/rpcbind.8 | 5 +++++
src/rpcbind.c | 10 +++++++---
2 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/man/rpcbind.8 b/man/rpcbind.8
index 6ba318f5ff77..ba1b191b119d 100644
--- a/man/rpcbind.8
+++ b/man/rpcbind.8
@@ -103,6 +103,11 @@ With this option, the name-to-address translation consistency
checks are shown in detail.
.It Fl f
Do not fork and become a background process.
+.It Fl b
+Do not support broadcast RPC and do not bind the extra port.
+This is useful if
+.Nm
+inadvertently binds a port that some other service needs to use.
.It Fl h
Specify specific IP addresses to bind to for UDP requests.
This option may be specified multiple times and can be used to
diff --git a/src/rpcbind.c b/src/rpcbind.c
index ecebe97da435..4819d6e5ba41 100644
--- a/src/rpcbind.c
+++ b/src/rpcbind.c
@@ -87,6 +87,7 @@ int debugging = 0; /* Tell me what's going on */
int doabort = 0; /* When debugging, do an abort on errors */
int dofork = 1; /* fork? */
int createdsocket = 0; /* Did I create the socket or systemd did it for me? */
+int dobroadcast = 1; /* Support forwarding of broadcast RPC calls (CALLIT) */
rpcblist_ptr list_rbl; /* A list of version 3/4 rpcbind services */
@@ -801,7 +802,7 @@ got_socket:
/*
* rmtcall only supported on CLTS transports for now.
*/
- if (nconf->nc_semantics == NC_TPI_CLTS) {
+ if (dobroadcast && nconf->nc_semantics == NC_TPI_CLTS) {
status = create_rmtcall_fd(nconf);
#ifdef RPCBIND_DEBUG
if (debugging) {
@@ -886,7 +887,7 @@ parseargs(int argc, char *argv[])
{
int c;
oldstyle_local = 1;
- while ((c = getopt(argc, argv, "adh:ilswf")) != -1) {
+ while ((c = getopt(argc, argv, "adh:ilswfb")) != -1) {
switch (c) {
case 'a':
doabort = 1; /* when debugging, do an abort on */
@@ -921,8 +922,11 @@ parseargs(int argc, char *argv[])
warmstart = 1;
break;
#endif
+ case 'b':
+ dobroadcast = 0;
+ break;
default: /* error */
- fprintf(stderr, "usage: rpcbind [-adhilswf]\n");
+ fprintf(stderr, "usage: rpcbind [-adhilswfb]\n");
exit (1);
}
}
--
2.43.0
As RPC is primarily a network service it is best, on Linux, to use
network namespaces to isolate it. However contacting rpcbind via an
AF_UNIX socket allows escape from the network namespace.
If clients could use an abstract address, that would ensure clients
contact an rpcbind in the same network namespace.
systemd can pass in a listening abstract socket by providing an '@'
prefix. However with libtirpc 1.3.3 or earlier attempting this will
fail as the library mistakenly determines that the socket is not bound.
This generates unsightly error messages.
So it is best not to request the abstract address when it is not likely
to work.
A patch to fix this also proposes adding a define for
_PATH_RPCBINDSOCK_ABSTRACT to the header files. We can check for this
and only include the new ListenStream when that define is present.
Signed-off-by: NeilBrown <[email protected]>
---
configure.ac | 13 ++++++++++++-
systemd/{rpcbind.socket => rpcbind.socket.in} | 1 +
2 files changed, 13 insertions(+), 1 deletion(-)
rename systemd/{rpcbind.socket => rpcbind.socket.in} (88%)
diff --git a/configure.ac b/configure.ac
index c2069a2b3b0e..573e4fdf3a3e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -50,6 +50,17 @@ AC_SUBST([nss_modules], [$with_nss_modules])
PKG_CHECK_MODULES([TIRPC], [libtirpc])
+CPPFLAGS=$TIRPC_CFLAGS
+AC_MSG_CHECKING([for abstract socket support in libtirpc])
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([
+#include <rpc/rpc.h>
+],[
+char *path = _PATH_RPCBINDSOCK_ABSTRACT;
+])], [have_abstract=yes], [have_abstract=no])
+CPPFLAGS=
+AC_MSG_RESULT([$have_abstract])
+AM_CONDITIONAL(ABSTRACT, [ test "x$have_abstract" = "xyes" ])
+
PKG_PROG_PKG_CONFIG
AC_ARG_WITH([systemdsystemunitdir],
AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [Directory for systemd service files]),
@@ -76,4 +87,4 @@ AC_CHECK_HEADERS([nss.h])
AC_SUBST([_sbindir])
AC_CONFIG_COMMANDS_PRE([eval eval _sbindir=$sbindir])
-AC_OUTPUT([Makefile systemd/rpcbind.service])
+AC_OUTPUT([Makefile systemd/rpcbind.service systemd/rpcbind.socket])
diff --git a/systemd/rpcbind.socket b/systemd/rpcbind.socket.in
similarity index 88%
rename from systemd/rpcbind.socket
rename to systemd/rpcbind.socket.in
index 3b1a93694c21..5dd09a143e16 100644
--- a/systemd/rpcbind.socket
+++ b/systemd/rpcbind.socket.in
@@ -6,6 +6,7 @@ Before=rpcbind.target
[Socket]
ListenStream=/run/rpcbind.sock
+@ABSTRACT_TRUE@ListenStream=@/run/rpcbind.sock
# RPC netconfig can't handle ipv6/ipv4 dual sockets
BindIPv6Only=ipv6-only
--
2.43.0
rpcinfo doesn't use library calls to set up the address for rpcbind. So
to get to it try the new abstract address, we need to explicitly
teach it how.
Signed-off-by: NeilBrown <[email protected]>
---
src/rpcinfo.c | 24 +++++++++++++++++++++++-
1 file changed, 23 insertions(+), 1 deletion(-)
diff --git a/src/rpcinfo.c b/src/rpcinfo.c
index 0e14f78ad2de..4464cbc0941b 100644
--- a/src/rpcinfo.c
+++ b/src/rpcinfo.c
@@ -311,6 +311,13 @@ main (int argc, char **argv)
return (0);
}
+/* Evaluate to actual length of the `sockaddr_un' structure, whether
+ * abstract or not.
+ */
+#include <stddef.h>
+#define SUN_LEN_A(ptr) (offsetof(struct sockaddr_un, sun_path) \
+ + 1 + strlen((ptr)->sun_path + 1))
+
static CLIENT *
local_rpcb (rpcprog_t prog, rpcvers_t vers)
{
@@ -334,6 +341,7 @@ local_rpcb (rpcprog_t prog, rpcvers_t vers)
endnetconfig(localhandle);
return clnt;
#else
+ CLIENT *clnt;
struct netbuf nbuf;
struct sockaddr_un sun;
int sock;
@@ -344,12 +352,26 @@ local_rpcb (rpcprog_t prog, rpcvers_t vers)
return NULL;
sun.sun_family = AF_LOCAL;
+
+#ifdef _PATH_RPCBINDSOCK_ABSTRACT
+ memcpy(sun.sun_path, _PATH_RPCBINDSOCK_ABSTRACT,
+ sizeof(_PATH_RPCBINDSOCK_ABSTRACT));
+ nbuf.len = SUN_LEN_A (&sun);
+ nbuf.maxlen = sizeof (struct sockaddr_un);
+ nbuf.buf = &sun;
+
+ clnt = clnt_vc_create (sock, &nbuf, prog, vers, 0, 0);
+ if (clnt)
+ return clnt;
+#endif
+
strcpy (sun.sun_path, _PATH_RPCBINDSOCK);
nbuf.len = SUN_LEN (&sun);
nbuf.maxlen = sizeof (struct sockaddr_un);
nbuf.buf = &sun;
- return clnt_vc_create (sock, &nbuf, prog, vers, 0, 0);
+ clnt = clnt_vc_create (sock, &nbuf, prog, vers, 0, 0);
+ return clnt;
#endif
}
--
2.43.0
Hey Neil,
My apologies on addressing this...
Too much PTO :-)
On 2/25/24 6:53 PM, NeilBrown wrote:
> The first two patches here I wrote some years ago but never posted - sorry.
> The third and fourth allow rpcbind to work with an abstract AF_UNIX
> address as preferentially used by recent kernels.
>
> NeilBrown
>
>
> [PATCH 1/4] manpage: describe use of extra port for broadcast rpc
> [PATCH 2/4] rpcbind: allow broadcast RPC to be disabled.
You realize that the broadcast code is configured out by default
./configure --help | grep rmt
--enable-rmtcalls Enables Remote Calls [default=no]
So do we want to introduce a flag and man page section
for something that is off by default?
steved.
> [PATCH 3/4] Listen on an AF_UNIX abstract address if supported.
> [PATCH 4/4] rpcinfo: try connecting using abstract address.
>
Hi Neil, Steve,
> Hey Neil,
> My apologies on addressing this...
> Too much PTO :-)
> On 2/25/24 6:53 PM, NeilBrown wrote:
> > The first two patches here I wrote some years ago but never posted - sorry.
> > The third and fourth allow rpcbind to work with an abstract AF_UNIX
> > address as preferentially used by recent kernels.
> > NeilBrown
> > [PATCH 1/4] manpage: describe use of extra port for broadcast rpc
> > [PATCH 2/4] rpcbind: allow broadcast RPC to be disabled.
> You realize that the broadcast code is configured out by default
> ./configure --help | grep rmt
> --enable-rmtcalls Enables Remote Calls [default=no]
> So do we want to introduce a flag and man page section
> for something that is off by default?
I would say man page does not harm.
If I'm not mistaken, it's disabled in openSUSE and Debian/Ubuntu, maybe
disabling flag is really not needed.
Kind regards,
Petr
> steved.
> > [PATCH 3/4] Listen on an AF_UNIX abstract address if supported.
> > [PATCH 4/4] rpcinfo: try connecting using abstract address.
Hi Neil,
> From: NeilBrown <[email protected]>
> Support for broadcast RPC involves binding a second privileged
> port. It is possible that rpcbind might choose a port that some
> other service will need, and that can cause problems.
> Having this port open increases the attack surface of rpcbind. RPC
> replies can be sent to it by any host, and they will only be rejected
> once they have been parsed enough to determine that the xid doesn't
> match.
> Boardcast is not widely used. It is not used at all for NFS. For NIS
> (previously yellow pages) it can be used to find a local NIS server,
> though this can also be statically configured.
> In cases where broadcast-RPC is not needed, it is best to disable the
> port. This patch adds a new "-b" option to disable broadcast RPC.
If this feature is wanted, I would suggest "-B". "-b" is used in ping for
broadcast, therefore this option looks like *enabling* broadcast instead of
disabling.
Otherwise LGTM.
Reviewed-by: Petr Vorel <[email protected]>
Kind regards,
Petr
Hi Neil, Steve,
> As RPC is primarily a network service it is best, on Linux, to use
> network namespaces to isolate it. However contacting rpcbind via an
> AF_UNIX socket allows escape from the network namespace.
> If clients could use an abstract address, that would ensure clients
> contact an rpcbind in the same network namespace.
> systemd can pass in a listening abstract socket by providing an '@'
> prefix. However with libtirpc 1.3.3 or earlier attempting this will
> fail as the library mistakenly determines that the socket is not bound.
> This generates unsightly error messages.
> So it is best not to request the abstract address when it is not likely
> to work.
> A patch to fix this also proposes adding a define for
> _PATH_RPCBINDSOCK_ABSTRACT to the header files. We can check for this
> and only include the new ListenStream when that define is present.
> Signed-off-by: NeilBrown <[email protected]>
> ---
> configure.ac | 13 ++++++++++++-
> systemd/{rpcbind.socket => rpcbind.socket.in} | 1 +
> 2 files changed, 13 insertions(+), 1 deletion(-)
> rename systemd/{rpcbind.socket => rpcbind.socket.in} (88%)
NOTE: now systemd/rpcbind.socket should be in .gitignore.
The rest LGTM.
Reviewed-by: Petr Vorel <[email protected]>
Kind regards,
Petr
> diff --git a/configure.ac b/configure.ac
> index c2069a2b3b0e..573e4fdf3a3e 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -50,6 +50,17 @@ AC_SUBST([nss_modules], [$with_nss_modules])
> PKG_CHECK_MODULES([TIRPC], [libtirpc])
> +CPPFLAGS=$TIRPC_CFLAGS
> +AC_MSG_CHECKING([for abstract socket support in libtirpc])
> +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([
> +#include <rpc/rpc.h>
> +],[
> +char *path = _PATH_RPCBINDSOCK_ABSTRACT;
> +])], [have_abstract=yes], [have_abstract=no])
> +CPPFLAGS=
> +AC_MSG_RESULT([$have_abstract])
> +AM_CONDITIONAL(ABSTRACT, [ test "x$have_abstract" = "xyes" ])
> +
> PKG_PROG_PKG_CONFIG
> AC_ARG_WITH([systemdsystemunitdir],
> AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [Directory for systemd service files]),
> @@ -76,4 +87,4 @@ AC_CHECK_HEADERS([nss.h])
> AC_SUBST([_sbindir])
> AC_CONFIG_COMMANDS_PRE([eval eval _sbindir=$sbindir])
> -AC_OUTPUT([Makefile systemd/rpcbind.service])
> +AC_OUTPUT([Makefile systemd/rpcbind.service systemd/rpcbind.socket])
> diff --git a/systemd/rpcbind.socket b/systemd/rpcbind.socket.in
> similarity index 88%
> rename from systemd/rpcbind.socket
> rename to systemd/rpcbind.socket.in
> index 3b1a93694c21..5dd09a143e16 100644
> --- a/systemd/rpcbind.socket
> +++ b/systemd/rpcbind.socket.in
> @@ -6,6 +6,7 @@ Before=rpcbind.target
> [Socket]
> ListenStream=/run/rpcbind.sock
> +@ABSTRACT_TRUE@ListenStream=@/run/rpcbind.sock
> # RPC netconfig can't handle ipv6/ipv4 dual sockets
> BindIPv6Only=ipv6-only
Hi Neil, Steve,
...
> sun.sun_family = AF_LOCAL;
> +
> +#ifdef _PATH_RPCBINDSOCK_ABSTRACT
> + memcpy(sun.sun_path, _PATH_RPCBINDSOCK_ABSTRACT,
> + sizeof(_PATH_RPCBINDSOCK_ABSTRACT));
> + nbuf.len = SUN_LEN_A (&sun);
> + nbuf.maxlen = sizeof (struct sockaddr_un);
> + nbuf.buf = &sun;
> +
> + clnt = clnt_vc_create (sock, &nbuf, prog, vers, 0, 0);
> + if (clnt)
> + return clnt;
> +#endif
> +
> strcpy (sun.sun_path, _PATH_RPCBINDSOCK);
> nbuf.len = SUN_LEN (&sun);
> nbuf.maxlen = sizeof (struct sockaddr_un);
> nbuf.buf = &sun;
> - return clnt_vc_create (sock, &nbuf, prog, vers, 0, 0);
> + clnt = clnt_vc_create (sock, &nbuf, prog, vers, 0, 0);
> + return clnt;
nit: maybe keeping the original:
return clnt_vc_create (sock, &nbuf, prog, vers, 0, 0);
Otherwise LGTM.
Reviewed-by: Petr Vorel <[email protected]>
Also it might be worth to remove '#if 0' part.
Kind regards,
Petr
On Mon, Mar 4, 2024 at 7:32 PM Petr Vorel <[email protected]> wrote:
> > From: NeilBrown <[email protected]>
> > Support for broadcast RPC involves binding a second privileged
> > port. It is possible that rpcbind might choose a port that some
> > other service will need, and that can cause problems.
>
> > Having this port open increases the attack surface of rpcbind. RPC
> > replies can be sent to it by any host, and they will only be rejected
> > once they have been parsed enough to determine that the xid doesn't
> > match.
>
> > Boardcast is not widely used. It is not used at all for NFS. For NIS
> > (previously yellow pages) it can be used to find a local NIS server,
> > though this can also be statically configured.
>
> > In cases where broadcast-RPC is not needed, it is best to disable the
> > port. This patch adds a new "-b" option to disable broadcast RPC.
>
> If this feature is wanted, I would suggest "-B". "-b" is used in ping for
> broadcast, therefore this option looks like *enabling* broadcast instead of
> disabling.
I agree with Petr...
... could you please add the comment about NIS/YP in the manpage too ?
And what about NIS+ ?
----
Bye,
Roland
--
__ . . __
(o.\ \/ /.o) [email protected]
\__\/\/__/ MPEG specialist, C&&JAVA&&Sun&&Unix programmer
/O /==\ O\ TEL +49 641 3992797
(;O/ \/ \O;)
On 3/4/24 1:29 PM, Petr Vorel wrote:
> Hi Neil, Steve,
>
>> Hey Neil,
>
>> My apologies on addressing this...
>> Too much PTO :-)
>
>> On 2/25/24 6:53 PM, NeilBrown wrote:
>>> The first two patches here I wrote some years ago but never posted - sorry.
>>> The third and fourth allow rpcbind to work with an abstract AF_UNIX
>>> address as preferentially used by recent kernels.
>
>>> NeilBrown
>
>
>>> [PATCH 1/4] manpage: describe use of extra port for broadcast rpc
>>> [PATCH 2/4] rpcbind: allow broadcast RPC to be disabled.
>> You realize that the broadcast code is configured out by default
>> ./configure --help | grep rmt
>> --enable-rmtcalls Enables Remote Calls [default=no]
>
>> So do we want to introduce a flag and man page section
>> for something that is off by default?
>
> I would say man page does not harm.
>
> If I'm not mistaken, it's disabled in openSUSE and Debian/Ubuntu, maybe
> disabling flag is really not needed.
As well as RHEL but not Fedora.
steved.
>
> Kind regards,
> Petr
>
>> steved.
>>> [PATCH 3/4] Listen on an AF_UNIX abstract address if supported.
>>> [PATCH 4/4] rpcinfo: try connecting using abstract address.
>
>
On Tue, 05 Mar 2024, Steve Dickson wrote:
> Hey Neil,
>
> My apologies on addressing this...
> Too much PTO :-)
>
> On 2/25/24 6:53 PM, NeilBrown wrote:
> > The first two patches here I wrote some years ago but never posted - sorry.
> > The third and fourth allow rpcbind to work with an abstract AF_UNIX
> > address as preferentially used by recent kernels.
> >
> > NeilBrown
> >
> >
> > [PATCH 1/4] manpage: describe use of extra port for broadcast rpc
> > [PATCH 2/4] rpcbind: allow broadcast RPC to be disabled.
> You realize that the broadcast code is configured out by default
> ./configure --help | grep rmt
> --enable-rmtcalls Enables Remote Calls [default=no]
>
> So do we want to introduce a flag and man page section
> for something that is off by default?
>
Hmmm.... I guess I didn't know that when I wrote the patch - or forgot.
I wrote the patch a few years ago and found it when I was doing the
abstract address stuff and though I better submit it. I was wrong.
Please just ignore those first two patches.
Thanks,
NeilBrown
On 3/10/24 9:47 PM, NeilBrown wrote:
> On Tue, 05 Mar 2024, Steve Dickson wrote:
>> Hey Neil,
>>
>> My apologies on addressing this...
>> Too much PTO :-)
>>
>> On 2/25/24 6:53 PM, NeilBrown wrote:
>>> The first two patches here I wrote some years ago but never posted - sorry.
>>> The third and fourth allow rpcbind to work with an abstract AF_UNIX
>>> address as preferentially used by recent kernels.
>>>
>>> NeilBrown
>>>
>>>
>>> [PATCH 1/4] manpage: describe use of extra port for broadcast rpc
>>> [PATCH 2/4] rpcbind: allow broadcast RPC to be disabled.
>> You realize that the broadcast code is configured out by default
>> ./configure --help | grep rmt
>> --enable-rmtcalls Enables Remote Calls [default=no]
>>
>> So do we want to introduce a flag and man page section
>> for something that is off by default?
>>
>
> Hmmm.... I guess I didn't know that when I wrote the patch - or forgot.
>
> I wrote the patch a few years ago and found it when I was doing the
> abstract address stuff and though I better submit it. I was wrong.
>
> Please just ignore those first two patches.
Ignored... the last two patches were committed (tag: rpcbind-1_2_7-rc3)
steved.
>
> Thanks,
> NeilBrown
>